From a3d73b0945d8e01cd437fbec55a33929d2d4c44e Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 11 Feb 2018 16:33:24 +0800 Subject: [PATCH 01/73] Setting up a skycoin_crypto tools project for hardware-wallet --- hardware-wallet/Makefile | 45 ++++++++++++++ hardware-wallet/README.md | 31 ++++++++++ hardware-wallet/skycoin_crypto.c | 85 ++++++++++++++++++++++++++ hardware-wallet/skycoin_crypto.h | 19 ++++++ hardware-wallet/test_skycoin_crypto.c | 86 +++++++++++++++++++++++++++ 5 files changed, 266 insertions(+) create mode 100644 hardware-wallet/Makefile create mode 100644 hardware-wallet/README.md create mode 100644 hardware-wallet/skycoin_crypto.c create mode 100644 hardware-wallet/skycoin_crypto.h create mode 100644 hardware-wallet/test_skycoin_crypto.c diff --git a/hardware-wallet/Makefile b/hardware-wallet/Makefile new file mode 100644 index 00000000..8618771d --- /dev/null +++ b/hardware-wallet/Makefile @@ -0,0 +1,45 @@ +CC ?= gcc + +OPTFLAGS ?= -O3 -g + +CFLAGS += $(OPTFLAGS) \ + -std=gnu99 \ + -W \ + -Wall \ + -Wextra \ + -Wimplicit-function-declaration \ + -Wredundant-decls \ + -Wstrict-prototypes \ + -Wundef \ + -Wshadow \ + -Wpointer-arith \ + -Wformat \ + -Wreturn-type \ + -Wsign-compare \ + -Wmultichar \ + -Wformat-nonliteral \ + -Winit-self \ + -Wuninitialized \ + -Wformat-security \ + -Werror + + +INC=-I$(TREZOR_CRYPTO_PATH) +CFLAGS += -I. $(INC) + +SRCS += skycoin_crypto.c + +OBJS = $(SRCS:.c=.o) + +TESTLIBS = -lcheck -L$(TREZOR_CRYPTO_PATH) -lTrezorCrypto + +all: test_skycoin_crypto + + +test_skycoin_crypto: test_skycoin_crypto.o skycoin_crypto.o $(OBJS) + $(CC) test_skycoin_crypto.o $(OBJS) $(TESTLIBS) -o test_skycoin_crypto + + + +clean: + rm -f *.o test_skycoin_crypto diff --git a/hardware-wallet/README.md b/hardware-wallet/README.md new file mode 100644 index 00000000..5c820894 --- /dev/null +++ b/hardware-wallet/README.md @@ -0,0 +1,31 @@ +Tools to imitate the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher). + + +# Compilation + +This repository includes header files coming from [Trezor-crypto](https://github.com/trezor/trezor-crypto/) repository. + +Download the repository + + git clone git@github.com:trezor/trezor-crypto.git + +Then setup the TREZOR_CRYPTO_PATH environment variable: + + export TREZOR_CRYPTO_PATH=$PWD/trezor-crypto + +# Dependencies + +## Test library "check" + +The source code necessary to compile libcheck.a can be downloaded from [this repository](https://github.com/libcheck/check) + + git clone git@github.com:libcheck/check.git + +## Recompile the static library libTrezorCrypto.a + +The dependancy libTrezorCrypto.a can be recompiled from sources +Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" +Then run : + + make + ar rcs libTrezorCrypto.a $(find -name "*.o") diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c new file mode 100644 index 00000000..ff0a4b6b --- /dev/null +++ b/hardware-wallet/skycoin_crypto.c @@ -0,0 +1,85 @@ +#include "skycoin_crypto.h" + +extern void bn_print(const bignum256 *a); + +void create_node(const char* seed_str, HDNode* node) +{ + const char* curve_name = SECP256K1_NAME; + + hdnode_from_seed((const uint8_t *)seed_str, strlen(seed_str), curve_name, node); + hdnode_fill_public_key(node); + + printf("Pub key: "); + for (int i = 0; i < 33; ++i) + { + printf("%02x", node->public_key[i]); + } + printf("\n"); + + + printf("Sec key: "); + for (int i = 0; i < 32; ++i) + { + printf("%02x", node->private_key[i]); + } + printf("\n"); +} + + +void generate_shared_key(const char *seed_str) { + + HDNode alice; + // shared key variables + int res, key_size; + uint8_t session_key1[65] = {0}; + + create_node(seed_str, &alice); + + res = hdnode_get_shared_key(&alice, alice.public_key, session_key1, &key_size); + + + printf("Shared key (status: %d, key_size: %d): \n", res, key_size); + for (int i = 0; i < key_size; ++i) + { + printf("%02x", session_key1[i]); + } + + bignum256 bigshared; + bn_read_be(session_key1, &bigshared); + printf("\nbignum sharedkey : \n"); + bn_print(&bigshared); + printf("\ncurve prime : \n"); + bn_print(&alice.curve->params->order); + + printf("\nbignum sharedkey after mod : \n"); + bn_fast_mod(&bigshared, &alice.curve->params->order); + bn_print(&bigshared); + printf("\n"); + + uint8_t digest[SHA256_DIGEST_LENGTH]= {0}; + compute_sha256sum((const char*) session_key1, digest, sizeof(session_key1)); + + printf("\nSha256 of output: \n"); + for(uint i=0;i +#include +#include + +#include "sha2.h" + +#include "bip32.h" +#include "curves.h" + +#include "bignum.h" + +void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); +void generate_shared_key(const char *seed_str); +void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey); + +#endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c new file mode 100644 index 00000000..e716b26a --- /dev/null +++ b/hardware-wallet/test_skycoin_crypto.c @@ -0,0 +1,86 @@ +#include "check.h" + +#include "skycoin_crypto.h" + + +#define FROMHEX_MAXLEN 512 + +const uint8_t *fromhex(const char *str) +{ + static uint8_t buf[FROMHEX_MAXLEN]; + size_t len = strlen(str) / 2; + if (len > FROMHEX_MAXLEN) len = FROMHEX_MAXLEN; + for (size_t i = 0; i < len; i++) { + uint8_t c = 0; + if (str[i * 2] >= '0' && str[i*2] <= '9') c += (str[i * 2] - '0') << 4; + if ((str[i * 2] & ~0x20) >= 'A' && (str[i*2] & ~0x20) <= 'F') c += (10 + (str[i * 2] & ~0x20) - 'A') << 4; + if (str[i * 2 + 1] >= '0' && str[i * 2 + 1] <= '9') c += (str[i * 2 + 1] - '0'); + if ((str[i * 2 + 1] & ~0x20) >= 'A' && (str[i * 2 + 1] & ~0x20) <= 'F') c += (10 + (str[i * 2 + 1] & ~0x20) - 'A'); + buf[i] = c; + } + return buf; +} + +START_TEST(test_genereate_deterministic_key_pair_seckey) +{ + char seed[256] = "seed"; + uint8_t seckey_digest[SHA256_DIGEST_LENGTH] = {0}; + genereate_deterministic_key_pair_seckey(seed, seckey_digest); + ck_assert_mem_eq(seckey_digest, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), 32); +} +END_TEST + +START_TEST(test_compute_sha256sum) +{ + char seed[256] = "seed"; + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + compute_sha256sum(seed, digest, strlen(seed)); + + ck_assert_mem_eq(digest, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b"), 32); + + strcpy(seed, "random_seed"); + memset(digest, 0, SHA256_DIGEST_LENGTH); + compute_sha256sum(seed, digest, strlen(seed)); + + ck_assert_mem_eq(digest, fromhex("7b491face15c5be43df3affe42e6e4aab48522a3b564043de464e8de50184a5d"), 32); +} +END_TEST + +START_TEST(test_compute_ecdh) +{ + char seed[256] = "seed"; + generate_shared_key(seed); + ck_assert_int_eq(1, 1); +} +END_TEST + +// define test suite and cases +Suite *test_suite(void) +{ + Suite *s = suite_create("skycoin_crypto"); + TCase *tc; + + tc = tcase_create("checksums"); + tcase_add_test(tc, test_genereate_deterministic_key_pair_seckey); + tcase_add_test(tc, test_compute_sha256sum); + tcase_add_test(tc, test_compute_ecdh); + suite_add_tcase(s, tc); + + return s; +} + + +// run suite +int main(void) +{ + int number_failed; + Suite *s = test_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + if (number_failed == 0) { + printf("PASSED ALL TESTS\n"); + } + return number_failed; +} From a419e3e34b6be2795ca443cd65b23cde7b344ffc Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 11 Feb 2018 17:00:13 +0800 Subject: [PATCH 02/73] Correcting typos in README.md --- hardware-wallet/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hardware-wallet/README.md b/hardware-wallet/README.md index 5c820894..d774b427 100644 --- a/hardware-wallet/README.md +++ b/hardware-wallet/README.md @@ -13,6 +13,11 @@ Then setup the TREZOR_CRYPTO_PATH environment variable: export TREZOR_CRYPTO_PATH=$PWD/trezor-crypto +Finally: + + make + ./test_skycoin_crypto + # Dependencies ## Test library "check" @@ -23,7 +28,8 @@ The source code necessary to compile libcheck.a can be downloaded from [this rep ## Recompile the static library libTrezorCrypto.a -The dependancy libTrezorCrypto.a can be recompiled from sources +The dependancy libTrezorCrypto.a can be recompiled from sources. + Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" Then run : From d46a1a00df0e915ec8fa1cff06261fbe2ec403fe Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 11 Feb 2018 17:01:05 +0800 Subject: [PATCH 03/73] Renaming test_genereate_deterministic_key_pair_seckey to test_generate_deterministic_key_pair_seckey (typo mistake) --- hardware-wallet/test_skycoin_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index e716b26a..156bc823 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -21,7 +21,7 @@ const uint8_t *fromhex(const char *str) return buf; } -START_TEST(test_genereate_deterministic_key_pair_seckey) +START_TEST(test_generate_deterministic_key_pair_seckey) { char seed[256] = "seed"; uint8_t seckey_digest[SHA256_DIGEST_LENGTH] = {0}; @@ -61,7 +61,7 @@ Suite *test_suite(void) TCase *tc; tc = tcase_create("checksums"); - tcase_add_test(tc, test_genereate_deterministic_key_pair_seckey); + tcase_add_test(tc, test_generate_deterministic_key_pair_seckey); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From b7cb929fb666b59a847e46220d1cf9bc9759d8c3 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 11 Feb 2018 17:13:52 +0800 Subject: [PATCH 04/73] Testing shared key generation (ECDH) --- hardware-wallet/skycoin_crypto.c | 60 +-------------------------- hardware-wallet/skycoin_crypto.h | 2 +- hardware-wallet/test_skycoin_crypto.c | 17 +++++++- 3 files changed, 17 insertions(+), 62 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index ff0a4b6b..7cb3f27e 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -4,69 +4,11 @@ extern void bn_print(const bignum256 *a); void create_node(const char* seed_str, HDNode* node) { - const char* curve_name = SECP256K1_NAME; - + const char* curve_name = SECP256K1_NAME; hdnode_from_seed((const uint8_t *)seed_str, strlen(seed_str), curve_name, node); hdnode_fill_public_key(node); - - printf("Pub key: "); - for (int i = 0; i < 33; ++i) - { - printf("%02x", node->public_key[i]); - } - printf("\n"); - - - printf("Sec key: "); - for (int i = 0; i < 32; ++i) - { - printf("%02x", node->private_key[i]); - } - printf("\n"); } - -void generate_shared_key(const char *seed_str) { - - HDNode alice; - // shared key variables - int res, key_size; - uint8_t session_key1[65] = {0}; - - create_node(seed_str, &alice); - - res = hdnode_get_shared_key(&alice, alice.public_key, session_key1, &key_size); - - - printf("Shared key (status: %d, key_size: %d): \n", res, key_size); - for (int i = 0; i < key_size; ++i) - { - printf("%02x", session_key1[i]); - } - - bignum256 bigshared; - bn_read_be(session_key1, &bigshared); - printf("\nbignum sharedkey : \n"); - bn_print(&bigshared); - printf("\ncurve prime : \n"); - bn_print(&alice.curve->params->order); - - printf("\nbignum sharedkey after mod : \n"); - bn_fast_mod(&bigshared, &alice.curve->params->order); - bn_print(&bigshared); - printf("\n"); - - uint8_t digest[SHA256_DIGEST_LENGTH]= {0}; - compute_sha256sum((const char*) session_key1, digest, sizeof(session_key1)); - - printf("\nSha256 of output: \n"); - for(uint i=0;i Date: Sun, 11 Feb 2018 17:54:08 +0800 Subject: [PATCH 05/73] Fixing compilation steps: adding dependancy to libcheck was not perfectly set up --- hardware-wallet/Makefile | 7 +++++-- hardware-wallet/README.md | 24 ++++++++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/hardware-wallet/Makefile b/hardware-wallet/Makefile index 8618771d..e00b1624 100644 --- a/hardware-wallet/Makefile +++ b/hardware-wallet/Makefile @@ -24,14 +24,17 @@ CFLAGS += $(OPTFLAGS) \ -Werror -INC=-I$(TREZOR_CRYPTO_PATH) +INC=-I$(TREZOR_CRYPTO_PATH) -I$(CHECK_PATH)/src CFLAGS += -I. $(INC) SRCS += skycoin_crypto.c OBJS = $(SRCS:.c=.o) -TESTLIBS = -lcheck -L$(TREZOR_CRYPTO_PATH) -lTrezorCrypto +%.o: %.c %.h + $(CC) $(CFLAGS) -o $@ -c $< + +TESTLIBS = -L/usr/local/lib/ -lm -lrt -L$(CHECK_PATH)/src -lcheck -L$(TREZOR_CRYPTO_PATH) -lTrezorCrypto all: test_skycoin_crypto diff --git a/hardware-wallet/README.md b/hardware-wallet/README.md index d774b427..452fb710 100644 --- a/hardware-wallet/README.md +++ b/hardware-wallet/README.md @@ -3,6 +3,8 @@ Tools to imitate the cipher library from [this repository](https://github.com/sk # Compilation +## Trezor-crypto + This repository includes header files coming from [Trezor-crypto](https://github.com/trezor/trezor-crypto/) repository. Download the repository @@ -13,24 +15,30 @@ Then setup the TREZOR_CRYPTO_PATH environment variable: export TREZOR_CRYPTO_PATH=$PWD/trezor-crypto -Finally: - make - ./test_skycoin_crypto +## Check -# Dependencies +The source code necessary to compile libcheck.a can be downloaded from [this repository](https://github.com/libcheck/check) +Download the repository -## Test library "check" + git clone git@github.com:libcheck/check.git -The source code necessary to compile libcheck.a can be downloaded from [this repository](https://github.com/libcheck/check) +Then setup the TREZOR_CRYPTO_PATH environment variable: - git clone git@github.com:libcheck/check.git + export CHECK_PATH=$PWD/check -## Recompile the static library libTrezorCrypto.a +## Make and run ! + + make + ./test_skycoin_crypto + + +# Self compile libTrezorCrypto.a The dependancy libTrezorCrypto.a can be recompiled from sources. Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" + Then run : make From 44c3cd933646d0f9290e3142fe3dbe13cdccc9de Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 11 Feb 2018 18:22:51 +0800 Subject: [PATCH 06/73] Adding .gitignore --- hardware-wallet/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 hardware-wallet/.gitignore diff --git a/hardware-wallet/.gitignore b/hardware-wallet/.gitignore new file mode 100644 index 00000000..19e76831 --- /dev/null +++ b/hardware-wallet/.gitignore @@ -0,0 +1,2 @@ +*.o +test_skycoin_crypto From 756b77b024d479936219eeefcea9fae7791edc51 Mon Sep 17 00:00:00 2001 From: mpsido Date: Mon, 12 Feb 2018 15:01:19 +0800 Subject: [PATCH 07/73] Moving includes into source file --- hardware-wallet/skycoin_crypto.c | 4 ++++ hardware-wallet/skycoin_crypto.h | 5 ----- hardware-wallet/test_skycoin_crypto.c | 8 ++++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 7cb3f27e..0634efd0 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -1,5 +1,9 @@ #include "skycoin_crypto.h" +#include + +#include "curves.h" + extern void bn_print(const bignum256 *a); void create_node(const char* seed_str, HDNode* node) diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 3e2d55c3..ae109edf 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -1,16 +1,11 @@ #ifndef SKYCOIN_CRYPTO_H #define SKYCOIN_CRYPTO_H -#include #include -#include #include "sha2.h" #include "bip32.h" -#include "curves.h" - -#include "bignum.h" void create_node(const char* seed_str, HDNode* node); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 1c057823..3006df54 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -1,7 +1,11 @@ -#include "check.h" - #include "skycoin_crypto.h" +#include +#include + +#include "check.h" + +#include "ecdsa.h" #define FROMHEX_MAXLEN 512 From 659719d8613f00e95186cab0197162d78797b459 Mon Sep 17 00:00:00 2001 From: mpsido Date: Mon, 12 Feb 2018 17:04:30 +0800 Subject: [PATCH 08/73] Add tohex function, and try different functions to compute ECDH --- hardware-wallet/test_skycoin_crypto.c | 34 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 3006df54..33039475 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -6,9 +6,19 @@ #include "check.h" #include "ecdsa.h" +#include "curves.h" #define FROMHEX_MAXLEN 512 +void tohex(char * str, const uint8_t* buffer, int bufferLength) +{ + int i; + for (i = 0; i < bufferLength; ++i) + { + sprintf(&str[2*i], "%02x", buffer[i]); + } +} + const uint8_t *fromhex(const char *str) { static uint8_t buf[FROMHEX_MAXLEN]; @@ -54,20 +64,34 @@ START_TEST(test_compute_ecdh) { char seed_str[256] = "seed"; HDNode alice; - int key_size; - uint8_t session_key1[65] = {0}; + uint8_t session_key1[32] = {0}; create_node(seed_str, &alice); ck_assert_mem_eq(alice.public_key, fromhex("03008fa0a5668a567cb28ab45e4b6747f5592690c1d519c860f748f6762fa13103"), 33); ck_assert_mem_eq(alice.private_key, fromhex("8f609a12bdfc8572590c66763bb05ce609cc0fdcd0c563067e91c06bfd5f1027"), 32); - hdnode_get_shared_key(&alice, alice.public_key, session_key1, &key_size); + char pubkey[66] = {0}; + tohex(pubkey, alice.public_key, 33); + printf("pub key: %s\n", pubkey); + + // ecdh_multiply(alice.curve->params, alice.private_key, alice.public_key, session_key1); //65 - ck_assert_mem_eq(session_key1, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), 32); + curve25519_scalarmult(session_key1, alice.private_key, alice.public_key); // 32 + // int key_size; + // hdnode_get_shared_key(&alice, alice.public_key, session_key1, &key_size); //65 + + char key[64] = {0}; + tohex(key, session_key1, 32); + printf("ECDH key: %s\n", key); + + ck_assert_mem_eq(session_key1, fromhex("024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"), 32); + + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + compute_sha256sum(key, digest, 32); - ck_assert_int_eq(1, 1); + ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), 32); } END_TEST From f201ff79f997ede794c3e801343f9d7de8cffb9d Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 22 Feb 2018 14:31:52 +0800 Subject: [PATCH 09/73] ECDH multipy succeeded ! --- hardware-wallet/test_skycoin_crypto.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 33039475..c792f8cc 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -76,12 +76,22 @@ START_TEST(test_compute_ecdh) printf("pub key: %s\n", pubkey); - // ecdh_multiply(alice.curve->params, alice.private_key, alice.public_key, session_key1); //65 - - curve25519_scalarmult(session_key1, alice.private_key, alice.public_key); // 32 - // int key_size; - // hdnode_get_shared_key(&alice, alice.public_key, session_key1, &key_size); //65 - + uint8_t mult[65] = {0}; + char key_m[128] = {0}; + ecdh_multiply(alice.curve->params, alice.private_key, alice.public_key, mult); //65 + + tohex(key_m, mult, 65); + printf("ECDH key_mult: %s\n", key_m); + memcpy(&session_key1[1], &mult[1], 31); + if (mult[64] % 2 == 0) + { + session_key1[0] = 0x02; + } + else + { + session_key1[0] = 0x03; + } + char key[64] = {0}; tohex(key, session_key1, 32); printf("ECDH key: %s\n", key); @@ -89,7 +99,7 @@ START_TEST(test_compute_ecdh) ck_assert_mem_eq(session_key1, fromhex("024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"), 32); uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - compute_sha256sum(key, digest, 32); + compute_sha256sum(key, digest, 64); ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), 32); } From de72db6727102e4a3a7c343bd99531b7a68facfe Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 22 Feb 2018 15:05:46 +0800 Subject: [PATCH 10/73] Improvements on sha256 computing syntax --- hardware-wallet/test_skycoin_crypto.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index c792f8cc..f698a0e2 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -40,7 +40,7 @@ START_TEST(test_generate_deterministic_key_pair_seckey) char seed[256] = "seed"; uint8_t seckey_digest[SHA256_DIGEST_LENGTH] = {0}; genereate_deterministic_key_pair_seckey(seed, seckey_digest); - ck_assert_mem_eq(seckey_digest, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), 32); + ck_assert_mem_eq(seckey_digest, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); } END_TEST @@ -50,13 +50,20 @@ START_TEST(test_compute_sha256sum) uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; compute_sha256sum(seed, digest, strlen(seed)); - ck_assert_mem_eq(digest, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b"), 32); + ck_assert_mem_eq(digest, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b"), SHA256_DIGEST_LENGTH); strcpy(seed, "random_seed"); memset(digest, 0, SHA256_DIGEST_LENGTH); compute_sha256sum(seed, digest, strlen(seed)); - ck_assert_mem_eq(digest, fromhex("7b491face15c5be43df3affe42e6e4aab48522a3b564043de464e8de50184a5d"), 32); + ck_assert_mem_eq(digest, fromhex("7b491face15c5be43df3affe42e6e4aab48522a3b564043de464e8de50184a5d"), SHA256_DIGEST_LENGTH); + + + strcpy(seed, "024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"); + memset(digest, 0, SHA256_DIGEST_LENGTH); + compute_sha256sum(seed, digest, strlen(seed)); + + ck_assert_mem_eq(digest, fromhex("a5daa8c9d03a9ec500088bdf0123a9d865725b03895b1291f25500737298e0a9"), SHA256_DIGEST_LENGTH); } END_TEST @@ -99,9 +106,9 @@ START_TEST(test_compute_ecdh) ck_assert_mem_eq(session_key1, fromhex("024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"), 32); uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - compute_sha256sum(key, digest, 64); + compute_sha256sum(key, digest, strlen(key)); - ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), 32); + ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), SHA256_DIGEST_LENGTH); } END_TEST From f7abdf59fb5ab940bb04a1272f2804e616647f71 Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 23 Feb 2018 16:53:53 +0800 Subject: [PATCH 11/73] Making test_compute_ecdh pass --- hardware-wallet/test_skycoin_crypto.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index f698a0e2..16beae7e 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -71,7 +71,7 @@ START_TEST(test_compute_ecdh) { char seed_str[256] = "seed"; HDNode alice; - uint8_t session_key1[32] = {0}; + uint8_t session_key1[33] = {0}; create_node(seed_str, &alice); ck_assert_mem_eq(alice.public_key, fromhex("03008fa0a5668a567cb28ab45e4b6747f5592690c1d519c860f748f6762fa13103"), 33); @@ -89,7 +89,7 @@ START_TEST(test_compute_ecdh) tohex(key_m, mult, 65); printf("ECDH key_mult: %s\n", key_m); - memcpy(&session_key1[1], &mult[1], 31); + memcpy(&session_key1[1], &mult[1], 32); if (mult[64] % 2 == 0) { session_key1[0] = 0x02; @@ -99,14 +99,10 @@ START_TEST(test_compute_ecdh) session_key1[0] = 0x03; } - char key[64] = {0}; - tohex(key, session_key1, 32); - printf("ECDH key: %s\n", key); - ck_assert_mem_eq(session_key1, fromhex("024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"), 32); uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - compute_sha256sum(key, digest, strlen(key)); + compute_sha256sum((char*)(session_key1), digest, 33); ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), SHA256_DIGEST_LENGTH); } From 14658713ed9e229455ef110d2472c2cdc4395ecf Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 23 Feb 2018 17:38:36 +0800 Subject: [PATCH 12/73] Moving the computation of ECDH shared secret into a ecdh_shared_secret function and improving the test with more test cases --- hardware-wallet/skycoin_crypto.c | 20 +++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 59 +++++++++++++-------------- 3 files changed, 49 insertions(+), 31 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 0634efd0..169046ab 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -21,6 +21,26 @@ void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey) compute_sha256sum((const char * )digest, seckey, SHA256_DIGEST_LENGTH); } +void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/) +{ + uint8_t session_key1[33] = {0}; + uint8_t mult[65] = {0}; + char seed_str[256] = "dummy seed"; + HDNode dummy_node; + create_node(seed_str, &dummy_node); + ecdh_multiply(dummy_node.curve->params, secret_key, remote_public_key, mult); //65 + memcpy(&session_key1[1], &mult[1], 32); + if (mult[64] % 2 == 0) + { + session_key1[0] = 0x02; + } + else + { + session_key1[0] = 0x03; + } + compute_sha256sum((char*)(session_key1), shared_secret, 33); +} + void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght) { diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index ae109edf..2ad1ac50 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -8,6 +8,7 @@ #include "bip32.h" void create_node(const char* seed_str, HDNode* node); +void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey); diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 16beae7e..43440db1 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -69,42 +69,39 @@ END_TEST START_TEST(test_compute_ecdh) { - char seed_str[256] = "seed"; - HDNode alice; - uint8_t session_key1[33] = {0}; - - create_node(seed_str, &alice); - ck_assert_mem_eq(alice.public_key, fromhex("03008fa0a5668a567cb28ab45e4b6747f5592690c1d519c860f748f6762fa13103"), 33); - ck_assert_mem_eq(alice.private_key, fromhex("8f609a12bdfc8572590c66763bb05ce609cc0fdcd0c563067e91c06bfd5f1027"), 32); - - - char pubkey[66] = {0}; - tohex(pubkey, alice.public_key, 33); - printf("pub key: %s\n", pubkey); + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + uint8_t remote_pubkey[33]; + uint8_t my_seckey[32]; + memcpy(my_seckey, fromhex("8f609a12bdfc8572590c66763bb05ce609cc0fdcd0c563067e91c06bfd5f1027"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("03008fa0a5668a567cb28ab45e4b6747f5592690c1d519c860f748f6762fa13103"), sizeof(remote_pubkey)); + memset(digest, 0, SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), SHA256_DIGEST_LENGTH); - uint8_t mult[65] = {0}; - char key_m[128] = {0}; - ecdh_multiply(alice.curve->params, alice.private_key, alice.public_key, mult); //65 + memcpy(my_seckey, fromhex("ec4c3702ae8dc5d3aaabc230d362f1ccc1ad2222353d006a057969bf2cc749c1"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("03b5d8432d20e55590b3e1e74a86f4689a5c1f5e25cc58840741fe1ac044d5e65c"), sizeof(remote_pubkey)); + memset(digest, 0, SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("c59b456353d0fbceadc06d7794c42ebf413ab952b29ecf6052d30c7c1a50acda"), SHA256_DIGEST_LENGTH); - tohex(key_m, mult, 65); - printf("ECDH key_mult: %s\n", key_m); - memcpy(&session_key1[1], &mult[1], 32); - if (mult[64] % 2 == 0) - { - session_key1[0] = 0x02; - } - else - { - session_key1[0] = 0x03; - } - - ck_assert_mem_eq(session_key1, fromhex("024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"), 32); + memcpy(my_seckey, fromhex("19adca686f1ca7befc30af65765597a4d033ac7479850e79cef3ce5cb5b95da4"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("0328bd053c69d9c3dd1e864098e503de9839e990c63c48d8a4d6011c423658c4a9"), sizeof(remote_pubkey)); + memset(digest, 0, SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("1fd2c655bcf19202ee004a3e0ae8f5c64ad1c0ce3b69f32ba18da188bb4d1eea"), SHA256_DIGEST_LENGTH); - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - compute_sha256sum((char*)(session_key1), digest, 33); + memcpy(my_seckey, fromhex("085d62c27a37889e02a183ee29962d5f4377831b4a70834ccea24a209e201404"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("030684d74471053ac6395ef74a86f88daa25f501329734c837c8c79c600423b220"), sizeof(remote_pubkey)); + memset(digest, 0, SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("4225281b8498f05e0eaac02be79ce72471c2ddd8c127908b1f717bf64177b287"), SHA256_DIGEST_LENGTH); - ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), SHA256_DIGEST_LENGTH); + memcpy(my_seckey, fromhex("3c4289a9d884f74bd05c352fa1c08ce0d65955b59b24a572f46e02807dd42e62"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("0223496e9caa207e0f8cc283e970b85f2831732d5e0be2bcf9fa366f7e064a25dd"), sizeof(remote_pubkey)); + memset(digest, 0, SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("70e5d568b31ed601fcb7f3144888d0633938817ae85417de1fbd0d52e29b5d7c"), SHA256_DIGEST_LENGTH); } END_TEST From 02ba0830db20127c1cfa2dd19635edb48dab16fb Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 09:20:35 +0800 Subject: [PATCH 13/73] Create generate_pubkey_from_seckey function --- hardware-wallet/skycoin_crypto.c | 8 ++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 14 ++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 169046ab..a0e43a60 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -21,6 +21,14 @@ void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey) compute_sha256sum((const char * )digest, seckey, SHA256_DIGEST_LENGTH); } +void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey) +{ + char seed_str[256] = "dummy seed"; + HDNode dummy_node; + create_node(seed_str, &dummy_node); + ecdsa_get_public_key33(dummy_node.curve->params, seckey, pubkey); +} + void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/) { uint8_t session_key1[33] = {0}; diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 2ad1ac50..4abc9f3f 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -11,5 +11,6 @@ void create_node(const char* seed_str, HDNode* node); void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey); +void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 43440db1..22e54f29 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -44,6 +44,19 @@ START_TEST(test_generate_deterministic_key_pair_seckey) } END_TEST + +START_TEST(test_generate_public_key_from_seckey) +{ + uint8_t seckey[32] = {0}; + uint8_t pubkey[33] = {0}; + + memcpy(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), sizeof(seckey)); + generate_pubkey_from_seckey(seckey, pubkey); + + ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); +} +END_TEST + START_TEST(test_compute_sha256sum) { char seed[256] = "seed"; @@ -113,6 +126,7 @@ Suite *test_suite(void) tc = tcase_create("checksums"); tcase_add_test(tc, test_generate_deterministic_key_pair_seckey); + tcase_add_test(tc, test_generate_public_key_from_seckey); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From bcf744d329ee483ebfd6a37e93bc7e81e52ba6ae Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 10:36:56 +0800 Subject: [PATCH 14/73] genereate_deterministic_key_pair function --- hardware-wallet/skycoin_crypto.c | 6 ++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index a0e43a60..e18ce8f1 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -29,6 +29,12 @@ void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey) ecdsa_get_public_key33(dummy_node.curve->params, seckey, pubkey); } +void genereate_deterministic_key_pair(const char* seed, uint8_t* seckey, uint8_t* pubkey) +{ + genereate_deterministic_key_pair_seckey(seed, seckey); + generate_pubkey_from_seckey(seckey, pubkey); +} + void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/) { uint8_t session_key1[33] = {0}; diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 4abc9f3f..37898891 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -12,5 +12,6 @@ void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_ void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); +void genereate_deterministic_key_pair(const char* seed, uint8_t* seckey, uint8_t* pubkey); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 22e54f29..3e68f12f 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -57,6 +57,19 @@ START_TEST(test_generate_public_key_from_seckey) } END_TEST +START_TEST(test_generate_key_pair_from_seed) +{ + char seed[256] = "seed"; + uint8_t seckey[32] = {0}; + uint8_t pubkey[33] = {0}; + + genereate_deterministic_key_pair(seed, seckey, pubkey); + + ck_assert_mem_eq(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); + ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); +} +END_TEST + START_TEST(test_compute_sha256sum) { char seed[256] = "seed"; @@ -127,6 +140,7 @@ Suite *test_suite(void) tc = tcase_create("checksums"); tcase_add_test(tc, test_generate_deterministic_key_pair_seckey); tcase_add_test(tc, test_generate_public_key_from_seckey); + tcase_add_test(tc, test_generate_key_pair_from_seed); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From 0c62366c18568915a387b8ef4a49b04691530769 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 11:56:00 +0800 Subject: [PATCH 15/73] Removing generate_deterministic_key_pair_seckey function, it is just a sha256 computation --- hardware-wallet/skycoin_crypto.c | 12 ++---------- hardware-wallet/skycoin_crypto.h | 3 +-- hardware-wallet/test_skycoin_crypto.c | 25 +++++++------------------ 3 files changed, 10 insertions(+), 30 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index e18ce8f1..c26b8f14 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -13,14 +13,6 @@ void create_node(const char* seed_str, HDNode* node) hdnode_fill_public_key(node); } -void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey) -{ - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - compute_sha256sum(seed, digest, strlen(seed)); - - compute_sha256sum((const char * )digest, seckey, SHA256_DIGEST_LENGTH); -} - void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey) { char seed_str[256] = "dummy seed"; @@ -29,9 +21,9 @@ void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey) ecdsa_get_public_key33(dummy_node.curve->params, seckey, pubkey); } -void genereate_deterministic_key_pair(const char* seed, uint8_t* seckey, uint8_t* pubkey) +void genereate_deterministic_key_pair(const uint8_t* seed, uint8_t* seckey, uint8_t* pubkey) { - genereate_deterministic_key_pair_seckey(seed, seckey); + compute_sha256sum((const char * )seed, seckey, SHA256_DIGEST_LENGTH); generate_pubkey_from_seckey(seckey, pubkey); } diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 37898891..bc0a8089 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -10,8 +10,7 @@ void create_node(const char* seed_str, HDNode* node); void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); -void genereate_deterministic_key_pair_seckey(const char* seed, uint8_t* seckey); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); -void genereate_deterministic_key_pair(const char* seed, uint8_t* seckey, uint8_t* pubkey); +void genereate_deterministic_key_pair(const uint8_t* seed, uint8_t* seckey, uint8_t* pubkey); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 3e68f12f..f5510e6d 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -35,16 +35,6 @@ const uint8_t *fromhex(const char *str) return buf; } -START_TEST(test_generate_deterministic_key_pair_seckey) -{ - char seed[256] = "seed"; - uint8_t seckey_digest[SHA256_DIGEST_LENGTH] = {0}; - genereate_deterministic_key_pair_seckey(seed, seckey_digest); - ck_assert_mem_eq(seckey_digest, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); -} -END_TEST - - START_TEST(test_generate_public_key_from_seckey) { uint8_t seckey[32] = {0}; @@ -60,13 +50,13 @@ END_TEST START_TEST(test_generate_key_pair_from_seed) { char seed[256] = "seed"; - uint8_t seckey[32] = {0}; - uint8_t pubkey[33] = {0}; - - genereate_deterministic_key_pair(seed, seckey, pubkey); - - ck_assert_mem_eq(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); - ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); + uint8_t seckey[32] = {0}; + uint8_t pubkey[33] = {0}; + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + compute_sha256sum((char *)seed, digest, strlen(seed)); + genereate_deterministic_key_pair(digest, seckey, pubkey); + ck_assert_mem_eq(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); + ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); } END_TEST @@ -138,7 +128,6 @@ Suite *test_suite(void) TCase *tc; tc = tcase_create("checksums"); - tcase_add_test(tc, test_generate_deterministic_key_pair_seckey); tcase_add_test(tc, test_generate_public_key_from_seckey); tcase_add_test(tc, test_generate_key_pair_from_seed); tcase_add_test(tc, test_compute_sha256sum); From 8140eebc8311648b4e93be687810cf3a42e9edfe Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 12:52:53 +0800 Subject: [PATCH 16/73] Separating ecdh and ecdh + hash256 --- hardware-wallet/skycoin_crypto.c | 17 +++++++++++------ hardware-wallet/skycoin_crypto.h | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index c26b8f14..abdf2e01 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -27,24 +27,29 @@ void genereate_deterministic_key_pair(const uint8_t* seed, uint8_t* seckey, uint generate_pubkey_from_seckey(seckey, pubkey); } -void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/) +void ecdh(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* ecdh_key/*should be size SHA256_DIGEST_LENGTH*/) { - uint8_t session_key1[33] = {0}; uint8_t mult[65] = {0}; char seed_str[256] = "dummy seed"; HDNode dummy_node; create_node(seed_str, &dummy_node); ecdh_multiply(dummy_node.curve->params, secret_key, remote_public_key, mult); //65 - memcpy(&session_key1[1], &mult[1], 32); + memcpy(&ecdh_key[1], &mult[1], 32); if (mult[64] % 2 == 0) { - session_key1[0] = 0x02; + ecdh_key[0] = 0x02; } else { - session_key1[0] = 0x03; + ecdh_key[0] = 0x03; } - compute_sha256sum((char*)(session_key1), shared_secret, 33); +} + +void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/) +{ + uint8_t ecdh_key[33] = {0}; + ecdh(secret_key, remote_public_key, ecdh_key); + compute_sha256sum((char*)(ecdh_key), shared_secret, 33); } diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index bc0a8089..57ae0180 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -8,6 +8,7 @@ #include "bip32.h" void create_node(const char* seed_str, HDNode* node); +void ecdh(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* ecdh_key /*should be size SHA256_DIGEST_LENGTH*/); void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); From 27743fa06371d50d3b304e00c2d72e8d846d37bf Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 12:53:13 +0800 Subject: [PATCH 17/73] Computing test_secp256k1Hash inside test --- hardware-wallet/test_skycoin_crypto.c | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index f5510e6d..ae762a35 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -60,6 +60,36 @@ START_TEST(test_generate_key_pair_from_seed) } END_TEST +START_TEST(test_secp256k1Hash) +{ + char seed[256] = "seed"; + uint8_t seckey[32] = {0}; + uint8_t dummy_seckey[32] = {0}; + uint8_t pubkey[33] = {0}; + uint8_t hash[SHA256_DIGEST_LENGTH] = {0}; + uint8_t hash2[SHA256_DIGEST_LENGTH] = {0}; + uint8_t ecdh_key[33] = {0}; + uint8_t secp256k1Hash[SHA256_DIGEST_LENGTH + 33] = {0}; + uint8_t secp256k1Hash_digest[SHA256_DIGEST_LENGTH] = {0}; + + compute_sha256sum(seed, hash, strlen(seed)); + ck_assert_mem_eq(hash, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b"), SHA256_DIGEST_LENGTH); + compute_sha256sum((const char*)hash, seckey, sizeof(hash)); + ck_assert_mem_eq(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); + compute_sha256sum((const char*)hash, hash2, sizeof(hash)); + genereate_deterministic_key_pair(hash2, dummy_seckey, pubkey); + ck_assert_mem_eq(pubkey, fromhex("02683e90daa5b0dd195b69e01386390284d3b3723121ce213771d9a0815d12b86c"), SHA256_DIGEST_LENGTH); + ecdh(seckey, pubkey, ecdh_key); + ck_assert_mem_eq(ecdh_key, fromhex("03d2d25cd412f6e45081a42a44d1f4398d18799e6ff45a09956adb366154966c46"), SHA256_DIGEST_LENGTH); + memcpy(secp256k1Hash, hash, sizeof(hash)); + memcpy(&secp256k1Hash[SHA256_DIGEST_LENGTH], ecdh_key, sizeof(ecdh_key)); + ck_assert_mem_eq(secp256k1Hash, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b03d2d25cd412f6e45081a42a44d1f4398d18799e6ff45a09956adb366154966c46"), sizeof(secp256k1Hash)); + compute_sha256sum((const char *)secp256k1Hash, secp256k1Hash_digest, sizeof(secp256k1Hash)); + ck_assert_mem_eq(secp256k1Hash_digest, fromhex("c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), SHA256_DIGEST_LENGTH); + +} +END_TEST + START_TEST(test_compute_sha256sum) { char seed[256] = "seed"; @@ -118,6 +148,12 @@ START_TEST(test_compute_ecdh) memset(digest, 0, SHA256_DIGEST_LENGTH); ecdh_shared_secret(my_seckey, remote_pubkey, digest); ck_assert_mem_eq(digest, fromhex("70e5d568b31ed601fcb7f3144888d0633938817ae85417de1fbd0d52e29b5d7c"), SHA256_DIGEST_LENGTH); + + memcpy(my_seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("02683e90daa5b0dd195b69e01386390284d3b3723121ce213771d9a0815d12b86c"), sizeof(remote_pubkey)); + memset(digest, 0, SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("9ab65c0e99605712aac66be1eccccb6dacb867ebaf2b1ebf96d3d92524f247fd"), SHA256_DIGEST_LENGTH); } END_TEST @@ -130,6 +166,7 @@ Suite *test_suite(void) tc = tcase_create("checksums"); tcase_add_test(tc, test_generate_public_key_from_seckey); tcase_add_test(tc, test_generate_key_pair_from_seed); + tcase_add_test(tc, test_secp256k1Hash); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From 42f4e049bd2f122bdb1c76e3efbce6d4bdb4d76c Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 13:21:48 +0800 Subject: [PATCH 18/73] Moving secp256k1Hash into a standalone function --- hardware-wallet/skycoin_crypto.c | 18 ++++++++++++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 23 +---------------------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index abdf2e01..e7e4c4c0 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -52,6 +52,24 @@ void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_ compute_sha256sum((char*)(ecdh_key), shared_secret, 33); } +void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest) +{ + uint8_t seckey[32] = {0}; + uint8_t dummy_seckey[32] = {0}; + uint8_t pubkey[33] = {0}; + uint8_t hash[SHA256_DIGEST_LENGTH] = {0}; + uint8_t hash2[SHA256_DIGEST_LENGTH] = {0}; + uint8_t ecdh_key[33] = {0}; + uint8_t secp256k1Hash[SHA256_DIGEST_LENGTH + 33] = {0}; + compute_sha256sum(seed, hash, strlen(seed)); + compute_sha256sum((const char*)hash, seckey, sizeof(hash)); + compute_sha256sum((const char*)hash, hash2, sizeof(hash)); + genereate_deterministic_key_pair(hash2, dummy_seckey, pubkey); + ecdh(seckey, pubkey, ecdh_key); + memcpy(secp256k1Hash, hash, sizeof(hash)); + memcpy(&secp256k1Hash[SHA256_DIGEST_LENGTH], ecdh_key, sizeof(ecdh_key)); + compute_sha256sum((const char *)secp256k1Hash, secp256k1Hash_digest, sizeof(secp256k1Hash)); +} void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght) { diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 57ae0180..5c5d9481 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -10,6 +10,7 @@ void create_node(const char* seed_str, HDNode* node); void ecdh(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* ecdh_key /*should be size SHA256_DIGEST_LENGTH*/); void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); +void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); void genereate_deterministic_key_pair(const uint8_t* seed, uint8_t* seckey, uint8_t* pubkey); diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index ae762a35..995b2154 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -63,30 +63,9 @@ END_TEST START_TEST(test_secp256k1Hash) { char seed[256] = "seed"; - uint8_t seckey[32] = {0}; - uint8_t dummy_seckey[32] = {0}; - uint8_t pubkey[33] = {0}; - uint8_t hash[SHA256_DIGEST_LENGTH] = {0}; - uint8_t hash2[SHA256_DIGEST_LENGTH] = {0}; - uint8_t ecdh_key[33] = {0}; - uint8_t secp256k1Hash[SHA256_DIGEST_LENGTH + 33] = {0}; uint8_t secp256k1Hash_digest[SHA256_DIGEST_LENGTH] = {0}; - - compute_sha256sum(seed, hash, strlen(seed)); - ck_assert_mem_eq(hash, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b"), SHA256_DIGEST_LENGTH); - compute_sha256sum((const char*)hash, seckey, sizeof(hash)); - ck_assert_mem_eq(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); - compute_sha256sum((const char*)hash, hash2, sizeof(hash)); - genereate_deterministic_key_pair(hash2, dummy_seckey, pubkey); - ck_assert_mem_eq(pubkey, fromhex("02683e90daa5b0dd195b69e01386390284d3b3723121ce213771d9a0815d12b86c"), SHA256_DIGEST_LENGTH); - ecdh(seckey, pubkey, ecdh_key); - ck_assert_mem_eq(ecdh_key, fromhex("03d2d25cd412f6e45081a42a44d1f4398d18799e6ff45a09956adb366154966c46"), SHA256_DIGEST_LENGTH); - memcpy(secp256k1Hash, hash, sizeof(hash)); - memcpy(&secp256k1Hash[SHA256_DIGEST_LENGTH], ecdh_key, sizeof(ecdh_key)); - ck_assert_mem_eq(secp256k1Hash, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b03d2d25cd412f6e45081a42a44d1f4398d18799e6ff45a09956adb366154966c46"), sizeof(secp256k1Hash)); - compute_sha256sum((const char *)secp256k1Hash, secp256k1Hash_digest, sizeof(secp256k1Hash)); + secp256k1Hash(seed, secp256k1Hash_digest); ck_assert_mem_eq(secp256k1Hash_digest, fromhex("c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), SHA256_DIGEST_LENGTH); - } END_TEST From 5637bfb29ba88e003a4f48cdcc9f0491942903ef Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 13:28:22 +0800 Subject: [PATCH 19/73] Adding few more test cases to test_secp256k1Hash --- hardware-wallet/test_skycoin_crypto.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 995b2154..3f9527c2 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -66,6 +66,17 @@ START_TEST(test_secp256k1Hash) uint8_t secp256k1Hash_digest[SHA256_DIGEST_LENGTH] = {0}; secp256k1Hash(seed, secp256k1Hash_digest); ck_assert_mem_eq(secp256k1Hash_digest, fromhex("c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), SHA256_DIGEST_LENGTH); + + strcpy(seed, "random_seed"); + memset(secp256k1Hash_digest, 0, SHA256_DIGEST_LENGTH); + secp256k1Hash(seed, secp256k1Hash_digest); + ck_assert_mem_eq(secp256k1Hash_digest, fromhex("5e81d46f56767496bc05ed177c5237cd4fe5013e617c726af43e1cba884f17d1"), SHA256_DIGEST_LENGTH); + + strcpy(seed, "024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"); + memset(secp256k1Hash_digest, 0, SHA256_DIGEST_LENGTH); + secp256k1Hash(seed, secp256k1Hash_digest); + ck_assert_mem_eq(secp256k1Hash_digest, fromhex("022750e4611d328f280b5256b3fdf8baf545072db6fcb0547b1472835cd32727"), SHA256_DIGEST_LENGTH); + } END_TEST From 6f75c29684438290082c9154ad0b594e4767a5f3 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 14:24:32 +0800 Subject: [PATCH 20/73] test_generate_deterministic_key_pair_iterator --- hardware-wallet/skycoin_crypto.c | 6 ++--- hardware-wallet/skycoin_crypto.h | 2 +- hardware-wallet/test_skycoin_crypto.c | 32 ++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index e7e4c4c0..362b298a 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -21,9 +21,9 @@ void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey) ecdsa_get_public_key33(dummy_node.curve->params, seckey, pubkey); } -void genereate_deterministic_key_pair(const uint8_t* seed, uint8_t* seckey, uint8_t* pubkey) +void genereate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey) { - compute_sha256sum((const char * )seed, seckey, SHA256_DIGEST_LENGTH); + compute_sha256sum((const char * )seed, seckey, seed_length); generate_pubkey_from_seckey(seckey, pubkey); } @@ -64,7 +64,7 @@ void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest) compute_sha256sum(seed, hash, strlen(seed)); compute_sha256sum((const char*)hash, seckey, sizeof(hash)); compute_sha256sum((const char*)hash, hash2, sizeof(hash)); - genereate_deterministic_key_pair(hash2, dummy_seckey, pubkey); + genereate_deterministic_key_pair(hash2, SHA256_DIGEST_LENGTH, dummy_seckey, pubkey); ecdh(seckey, pubkey, ecdh_key); memcpy(secp256k1Hash, hash, sizeof(hash)); memcpy(&secp256k1Hash[SHA256_DIGEST_LENGTH], ecdh_key, sizeof(ecdh_key)); diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 5c5d9481..b04d2d76 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -13,6 +13,6 @@ void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_ void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); -void genereate_deterministic_key_pair(const uint8_t* seed, uint8_t* seckey, uint8_t* pubkey); +void genereate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 3f9527c2..41b4d647 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -54,7 +54,7 @@ START_TEST(test_generate_key_pair_from_seed) uint8_t pubkey[33] = {0}; uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; compute_sha256sum((char *)seed, digest, strlen(seed)); - genereate_deterministic_key_pair(digest, seckey, pubkey); + genereate_deterministic_key_pair(digest, SHA256_DIGEST_LENGTH, seckey, pubkey); ck_assert_mem_eq(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); } @@ -72,10 +72,35 @@ START_TEST(test_secp256k1Hash) secp256k1Hash(seed, secp256k1Hash_digest); ck_assert_mem_eq(secp256k1Hash_digest, fromhex("5e81d46f56767496bc05ed177c5237cd4fe5013e617c726af43e1cba884f17d1"), SHA256_DIGEST_LENGTH); - strcpy(seed, "024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"); + strcpy(seed, "random_seed"); memset(secp256k1Hash_digest, 0, SHA256_DIGEST_LENGTH); secp256k1Hash(seed, secp256k1Hash_digest); - ck_assert_mem_eq(secp256k1Hash_digest, fromhex("022750e4611d328f280b5256b3fdf8baf545072db6fcb0547b1472835cd32727"), SHA256_DIGEST_LENGTH); + ck_assert_mem_eq(secp256k1Hash_digest, fromhex("5e81d46f56767496bc05ed177c5237cd4fe5013e617c726af43e1cba884f17d1"), SHA256_DIGEST_LENGTH); + +} +END_TEST + +START_TEST(test_generate_deterministic_key_pair_iterator) +{ + char seed[256] = "seed"; + size_t seed_length = 0; + uint8_t seed1[SHA256_DIGEST_LENGTH] = {0}; + uint8_t seed2[SHA256_DIGEST_LENGTH] = {0}; + char keypair_seed[256] = {0}; + uint8_t seckey[32] = {0}; + uint8_t pubkey[33] = {0}; + + secp256k1Hash(seed, seed1); + ck_assert_mem_eq(seed1, fromhex("c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), SHA256_DIGEST_LENGTH); + seed_length = strlen(seed); + memcpy(keypair_seed, seed, seed_length); + memcpy(&keypair_seed[seed_length], seed1, sizeof(seed1)); + ck_assert_mem_eq(keypair_seed, fromhex("73656564c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), seed_length + sizeof(seed1)); + compute_sha256sum(keypair_seed, seed2, seed_length + sizeof(seed1)); + ck_assert_mem_eq(seed2, fromhex("bf394b8b1c00aa245de6b55f6687d0e49f9884a5052d9071d4d90093454e5632"), SHA256_DIGEST_LENGTH); + genereate_deterministic_key_pair(seed2, SHA256_DIGEST_LENGTH, seckey, pubkey); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + ck_assert_mem_eq(seckey, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); } END_TEST @@ -157,6 +182,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_generate_public_key_from_seckey); tcase_add_test(tc, test_generate_key_pair_from_seed); tcase_add_test(tc, test_secp256k1Hash); + tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From b40b3c83d4e8404685f7202982897d5af052ea07 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 14:33:22 +0800 Subject: [PATCH 21/73] Move generate_deterministic_key_pair_iterator into a standalone function --- hardware-wallet/skycoin_crypto.c | 14 ++++++++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 28 +++++++++++++-------------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 362b298a..e0bb72e1 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -71,6 +71,20 @@ void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest) compute_sha256sum((const char *)secp256k1Hash, secp256k1Hash_digest, sizeof(secp256k1Hash)); } +void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, uint8_t* pubkey) +{ + size_t seed_length = 0; + uint8_t seed1[SHA256_DIGEST_LENGTH] = {0}; + uint8_t seed2[SHA256_DIGEST_LENGTH] = {0}; + char keypair_seed[256] = {0}; + secp256k1Hash(seed, seed1); + seed_length = strlen(seed); + memcpy(keypair_seed, seed, seed_length); + memcpy(&keypair_seed[seed_length], seed1, sizeof(seed1)); + compute_sha256sum(keypair_seed, seed2, seed_length + sizeof(seed1)); + genereate_deterministic_key_pair(seed2, SHA256_DIGEST_LENGTH, seckey, pubkey); +} + void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght) { SHA256_CTX ctx; diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index b04d2d76..77a694b8 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -11,6 +11,7 @@ void create_node(const char* seed_str, HDNode* node); void ecdh(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* ecdh_key /*should be size SHA256_DIGEST_LENGTH*/); void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest); +void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, uint8_t* pubkey); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); void genereate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 41b4d647..a0f91614 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -83,25 +83,25 @@ END_TEST START_TEST(test_generate_deterministic_key_pair_iterator) { char seed[256] = "seed"; - size_t seed_length = 0; - uint8_t seed1[SHA256_DIGEST_LENGTH] = {0}; - uint8_t seed2[SHA256_DIGEST_LENGTH] = {0}; - char keypair_seed[256] = {0}; uint8_t seckey[32] = {0}; uint8_t pubkey[33] = {0}; - - secp256k1Hash(seed, seed1); - ck_assert_mem_eq(seed1, fromhex("c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), SHA256_DIGEST_LENGTH); - seed_length = strlen(seed); - memcpy(keypair_seed, seed, seed_length); - memcpy(&keypair_seed[seed_length], seed1, sizeof(seed1)); - ck_assert_mem_eq(keypair_seed, fromhex("73656564c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), seed_length + sizeof(seed1)); - compute_sha256sum(keypair_seed, seed2, seed_length + sizeof(seed1)); - ck_assert_mem_eq(seed2, fromhex("bf394b8b1c00aa245de6b55f6687d0e49f9884a5052d9071d4d90093454e5632"), SHA256_DIGEST_LENGTH); - genereate_deterministic_key_pair(seed2, SHA256_DIGEST_LENGTH, seckey, pubkey); + generate_deterministic_key_pair_iterator(seed, seckey, pubkey); ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); ck_assert_mem_eq(seckey, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); + strcpy(seed, "random_seed"); + memset(pubkey, 0, sizeof(pubkey)); + memset(seckey, 0, sizeof(seckey)); + generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + ck_assert_mem_eq(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); + ck_assert_mem_eq(seckey, fromhex("ff671860c58aad3f765d8add25046412dabf641186472e1553435e6e3c4a6fb0"), 32); + + strcpy(seed, "hello seed"); + memset(pubkey, 0, sizeof(pubkey)); + memset(seckey, 0, sizeof(seckey)); + generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + ck_assert_mem_eq(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); + ck_assert_mem_eq(seckey, fromhex("84fdc649964bf299a787cb78cd975910e197dbddd7db776ece544f41c44b3056"), 32); } END_TEST From 98871f4d2beb02d74cf531ad0542824947933abe Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 24 Feb 2018 16:22:50 +0800 Subject: [PATCH 22/73] test_to_address_hash --- hardware-wallet/test_skycoin_crypto.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index a0f91614..da9cfec4 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -7,6 +7,7 @@ #include "ecdsa.h" #include "curves.h" +#include "ripemd160.h" #define FROMHEX_MAXLEN 512 @@ -105,6 +106,21 @@ START_TEST(test_generate_deterministic_key_pair_iterator) } END_TEST +START_TEST(test_to_address_hash) +{ + uint8_t pubkey[33] = {0}; + uint8_t pubkey_hash[33] = {0}; + uint8_t r1[SHA256_DIGEST_LENGTH] = {0}; + uint8_t r2[SHA256_DIGEST_LENGTH] = {0}; + memcpy(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + compute_sha256sum((char *)pubkey, r1, sizeof(pubkey)); + compute_sha256sum((char *)r1, r2, sizeof(r1)); + ck_assert_mem_eq(r2, fromhex("5229c51b89c130b72e1c58fb3bd9a5ac07084fed08920b4587668849c7806e25"), SHA256_DIGEST_LENGTH); + ripemd160(r2, SHA256_DIGEST_LENGTH, pubkey_hash); + ck_assert_mem_eq(pubkey_hash, fromhex("b1aa8dd3e68d1d9b130c67ea1339ac9250b7d845"), 20); +} +END_TEST + START_TEST(test_compute_sha256sum) { char seed[256] = "seed"; @@ -183,6 +199,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_generate_key_pair_from_seed); tcase_add_test(tc, test_secp256k1Hash); tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); + tcase_add_test(tc, test_to_address_hash); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From da045f933bae60adf848c5fc6afac9d84676565f Mon Sep 17 00:00:00 2001 From: mpsido Date: Mon, 26 Feb 2018 14:17:26 +0800 Subject: [PATCH 23/73] Compute base58 address --- hardware-wallet/test_skycoin_crypto.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index da9cfec4..3b95e6aa 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -8,6 +8,7 @@ #include "ecdsa.h" #include "curves.h" #include "ripemd160.h" +#include "base58.h" #define FROMHEX_MAXLEN 512 @@ -109,7 +110,7 @@ END_TEST START_TEST(test_to_address_hash) { uint8_t pubkey[33] = {0}; - uint8_t pubkey_hash[33] = {0}; + uint8_t pubkey_hash[20] = {0}; uint8_t r1[SHA256_DIGEST_LENGTH] = {0}; uint8_t r2[SHA256_DIGEST_LENGTH] = {0}; memcpy(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); @@ -117,7 +118,18 @@ START_TEST(test_to_address_hash) compute_sha256sum((char *)r1, r2, sizeof(r1)); ck_assert_mem_eq(r2, fromhex("5229c51b89c130b72e1c58fb3bd9a5ac07084fed08920b4587668849c7806e25"), SHA256_DIGEST_LENGTH); ripemd160(r2, SHA256_DIGEST_LENGTH, pubkey_hash); - ck_assert_mem_eq(pubkey_hash, fromhex("b1aa8dd3e68d1d9b130c67ea1339ac9250b7d845"), 20); + ck_assert_mem_eq(pubkey_hash, fromhex("b1aa8dd3e68d1d9b130c67ea1339ac9250b7d845"), sizeof(pubkey_hash)); + // compute base58 address + char address[256] = {0}; + size_t size_address = sizeof(address); + uint8_t byte_address[25]; + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + memcpy(byte_address, pubkey_hash, sizeof(pubkey_hash)); + byte_address[20] = 0; + compute_sha256sum((char *)byte_address, digest, 21); + memcpy(&byte_address[21], digest, 4); + b58enc(address, &size_address, byte_address, sizeof(byte_address)); + ck_assert_str_eq(address, "2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"); } END_TEST From 2d135dfb1dbfc18398cb8df0e21d5eb1cfa170fd Mon Sep 17 00:00:00 2001 From: mpsido Date: Mon, 26 Feb 2018 14:21:51 +0800 Subject: [PATCH 24/73] Moving includes at their right place --- hardware-wallet/skycoin_crypto.c | 3 +++ hardware-wallet/skycoin_crypto.h | 6 +----- hardware-wallet/test_skycoin_crypto.c | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index e0bb72e1..a4ddafdc 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -2,9 +2,12 @@ #include +#include "sha2.h" +#include "bip32.h" #include "curves.h" extern void bn_print(const bignum256 *a); +void create_node(const char* seed_str, HDNode* node); void create_node(const char* seed_str, HDNode* node) { diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 77a694b8..550c6fce 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -2,12 +2,8 @@ #define SKYCOIN_CRYPTO_H #include +#include -#include "sha2.h" - -#include "bip32.h" - -void create_node(const char* seed_str, HDNode* node); void ecdh(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* ecdh_key /*should be size SHA256_DIGEST_LENGTH*/); void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest); diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 3b95e6aa..fc96f2b2 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -4,9 +4,8 @@ #include #include "check.h" +#include "sha2.h" //SHA256_DIGEST_LENGTH -#include "ecdsa.h" -#include "curves.h" #include "ripemd160.h" #include "base58.h" From 5a87b000715e1b7b5e113ef9f8f34e8fbc1d0c5d Mon Sep 17 00:00:00 2001 From: mpsido Date: Mon, 26 Feb 2018 14:44:14 +0800 Subject: [PATCH 25/73] Moving generate_base58_address_from_pubkey into a standalone function --- hardware-wallet/skycoin_crypto.c | 19 +++++++++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 34 ++++++++++----------------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index a4ddafdc..0dbca709 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -5,6 +5,8 @@ #include "sha2.h" #include "bip32.h" #include "curves.h" +#include "ripemd160.h" +#include "base58.h" extern void bn_print(const bignum256 *a); void create_node(const char* seed_str, HDNode* node); @@ -95,3 +97,20 @@ void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LE sha256_Update(&ctx, (const uint8_t*) seed, seed_lenght); sha256_Final(&ctx, digest); } + +// address_size is the size of the allocated address buffer, it will be overwritten by the computed address size +void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address) +{ + uint8_t pubkey_hash[25] = {0}; + uint8_t r1[SHA256_DIGEST_LENGTH] = {0}; + uint8_t r2[SHA256_DIGEST_LENGTH] = {0}; + compute_sha256sum((char *)pubkey, r1, 33); + compute_sha256sum((char *)r1, r2, sizeof(r1)); + ripemd160(r2, SHA256_DIGEST_LENGTH, pubkey_hash); + // compute base58 address + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + pubkey_hash[20] = 0; + compute_sha256sum((char *)pubkey_hash, digest, 21); + memcpy(&pubkey_hash[21], digest, 4); + b58enc(address, size_address, pubkey_hash, sizeof(pubkey_hash)); +} diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 550c6fce..c459b356 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -11,5 +11,6 @@ void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); void genereate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); +void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index fc96f2b2..2e876c0e 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -6,9 +6,6 @@ #include "check.h" #include "sha2.h" //SHA256_DIGEST_LENGTH -#include "ripemd160.h" -#include "base58.h" - #define FROMHEX_MAXLEN 512 void tohex(char * str, const uint8_t* buffer, int bufferLength) @@ -106,29 +103,22 @@ START_TEST(test_generate_deterministic_key_pair_iterator) } END_TEST -START_TEST(test_to_address_hash) +START_TEST(test_base58_address_from_pubkey) { uint8_t pubkey[33] = {0}; - uint8_t pubkey_hash[20] = {0}; - uint8_t r1[SHA256_DIGEST_LENGTH] = {0}; - uint8_t r2[SHA256_DIGEST_LENGTH] = {0}; - memcpy(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); - compute_sha256sum((char *)pubkey, r1, sizeof(pubkey)); - compute_sha256sum((char *)r1, r2, sizeof(r1)); - ck_assert_mem_eq(r2, fromhex("5229c51b89c130b72e1c58fb3bd9a5ac07084fed08920b4587668849c7806e25"), SHA256_DIGEST_LENGTH); - ripemd160(r2, SHA256_DIGEST_LENGTH, pubkey_hash); - ck_assert_mem_eq(pubkey_hash, fromhex("b1aa8dd3e68d1d9b130c67ea1339ac9250b7d845"), sizeof(pubkey_hash)); - // compute base58 address char address[256] = {0}; size_t size_address = sizeof(address); - uint8_t byte_address[25]; - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - memcpy(byte_address, pubkey_hash, sizeof(pubkey_hash)); - byte_address[20] = 0; - compute_sha256sum((char *)byte_address, digest, 21); - memcpy(&byte_address[21], digest, 4); - b58enc(address, &size_address, byte_address, sizeof(byte_address)); + memcpy(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + generate_base58_address_from_pubkey(pubkey, address, &size_address); ck_assert_str_eq(address, "2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"); + + memcpy(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); + generate_base58_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "2EKq1QXRmfe7jsWzNdYsmyoz8q3VkwkLsDJ"); + + memcpy(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); + generate_base58_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "5UgkXRHrf5XRk41BFq1DVyeFZHTQXirhUu"); } END_TEST @@ -210,7 +200,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_generate_key_pair_from_seed); tcase_add_test(tc, test_secp256k1Hash); tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); - tcase_add_test(tc, test_to_address_hash); + tcase_add_test(tc, test_base58_address_from_pubkey); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From a4ee143112d7aacf93a38a79aaa45202450b2dfa Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 28 Feb 2018 12:32:49 +0800 Subject: [PATCH 26/73] Replace tabs by four spaces and correcting typos --- hardware-wallet/skycoin_crypto.c | 52 +++---- hardware-wallet/skycoin_crypto.h | 2 +- hardware-wallet/test_skycoin_crypto.c | 202 +++++++++++++------------- 3 files changed, 128 insertions(+), 128 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 0dbca709..964842e0 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -21,12 +21,12 @@ void create_node(const char* seed_str, HDNode* node) void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey) { char seed_str[256] = "dummy seed"; - HDNode dummy_node; + HDNode dummy_node; create_node(seed_str, &dummy_node); - ecdsa_get_public_key33(dummy_node.curve->params, seckey, pubkey); + ecdsa_get_public_key33(dummy_node.curve->params, seckey, pubkey); } -void genereate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey) +void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey) { compute_sha256sum((const char * )seed, seckey, seed_length); generate_pubkey_from_seckey(seckey, pubkey); @@ -36,18 +36,18 @@ void ecdh(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* { uint8_t mult[65] = {0}; char seed_str[256] = "dummy seed"; - HDNode dummy_node; + HDNode dummy_node; create_node(seed_str, &dummy_node); - ecdh_multiply(dummy_node.curve->params, secret_key, remote_public_key, mult); //65 - memcpy(&ecdh_key[1], &mult[1], 32); - if (mult[64] % 2 == 0) - { - ecdh_key[0] = 0x02; - } - else - { - ecdh_key[0] = 0x03; - } + ecdh_multiply(dummy_node.curve->params, secret_key, remote_public_key, mult); //65 + memcpy(&ecdh_key[1], &mult[1], 32); + if (mult[64] % 2 == 0) + { + ecdh_key[0] = 0x02; + } + else + { + ecdh_key[0] = 0x03; + } } void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/) @@ -69,7 +69,7 @@ void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest) compute_sha256sum(seed, hash, strlen(seed)); compute_sha256sum((const char*)hash, seckey, sizeof(hash)); compute_sha256sum((const char*)hash, hash2, sizeof(hash)); - genereate_deterministic_key_pair(hash2, SHA256_DIGEST_LENGTH, dummy_seckey, pubkey); + generate_deterministic_key_pair(hash2, SHA256_DIGEST_LENGTH, dummy_seckey, pubkey); ecdh(seckey, pubkey, ecdh_key); memcpy(secp256k1Hash, hash, sizeof(hash)); memcpy(&secp256k1Hash[SHA256_DIGEST_LENGTH], ecdh_key, sizeof(ecdh_key)); @@ -78,16 +78,16 @@ void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest) void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, uint8_t* pubkey) { - size_t seed_length = 0; + size_t seed_length = 0; uint8_t seed1[SHA256_DIGEST_LENGTH] = {0}; uint8_t seed2[SHA256_DIGEST_LENGTH] = {0}; char keypair_seed[256] = {0}; - secp256k1Hash(seed, seed1); - seed_length = strlen(seed); + secp256k1Hash(seed, seed1); + seed_length = strlen(seed); memcpy(keypair_seed, seed, seed_length); memcpy(&keypair_seed[seed_length], seed1, sizeof(seed1)); compute_sha256sum(keypair_seed, seed2, seed_length + sizeof(seed1)); - genereate_deterministic_key_pair(seed2, SHA256_DIGEST_LENGTH, seckey, pubkey); + generate_deterministic_key_pair(seed2, SHA256_DIGEST_LENGTH, seckey, pubkey); } void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght) @@ -105,12 +105,12 @@ void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, s uint8_t r1[SHA256_DIGEST_LENGTH] = {0}; uint8_t r2[SHA256_DIGEST_LENGTH] = {0}; compute_sha256sum((char *)pubkey, r1, 33); - compute_sha256sum((char *)r1, r2, sizeof(r1)); - ripemd160(r2, SHA256_DIGEST_LENGTH, pubkey_hash); - // compute base58 address + compute_sha256sum((char *)r1, r2, sizeof(r1)); + ripemd160(r2, SHA256_DIGEST_LENGTH, pubkey_hash); + // compute base58 address uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - pubkey_hash[20] = 0; - compute_sha256sum((char *)pubkey_hash, digest, 21); - memcpy(&pubkey_hash[21], digest, 4); - b58enc(address, size_address, pubkey_hash, sizeof(pubkey_hash)); + pubkey_hash[20] = 0; + compute_sha256sum((char *)pubkey_hash, digest, 21); + memcpy(&pubkey_hash[21], digest, 4); + b58enc(address, size_address, pubkey_hash, sizeof(pubkey_hash)); } diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index c459b356..b535c3af 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -10,7 +10,7 @@ void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest); void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, uint8_t* pubkey); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); -void genereate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); +void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 2e876c0e..982cdc65 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -10,38 +10,38 @@ void tohex(char * str, const uint8_t* buffer, int bufferLength) { - int i; - for (i = 0; i < bufferLength; ++i) - { - sprintf(&str[2*i], "%02x", buffer[i]); - } + int i; + for (i = 0; i < bufferLength; ++i) + { + sprintf(&str[2*i], "%02x", buffer[i]); + } } const uint8_t *fromhex(const char *str) { - static uint8_t buf[FROMHEX_MAXLEN]; - size_t len = strlen(str) / 2; - if (len > FROMHEX_MAXLEN) len = FROMHEX_MAXLEN; - for (size_t i = 0; i < len; i++) { - uint8_t c = 0; - if (str[i * 2] >= '0' && str[i*2] <= '9') c += (str[i * 2] - '0') << 4; - if ((str[i * 2] & ~0x20) >= 'A' && (str[i*2] & ~0x20) <= 'F') c += (10 + (str[i * 2] & ~0x20) - 'A') << 4; - if (str[i * 2 + 1] >= '0' && str[i * 2 + 1] <= '9') c += (str[i * 2 + 1] - '0'); - if ((str[i * 2 + 1] & ~0x20) >= 'A' && (str[i * 2 + 1] & ~0x20) <= 'F') c += (10 + (str[i * 2 + 1] & ~0x20) - 'A'); - buf[i] = c; - } - return buf; + static uint8_t buf[FROMHEX_MAXLEN]; + size_t len = strlen(str) / 2; + if (len > FROMHEX_MAXLEN) len = FROMHEX_MAXLEN; + for (size_t i = 0; i < len; i++) { + uint8_t c = 0; + if (str[i * 2] >= '0' && str[i*2] <= '9') c += (str[i * 2] - '0') << 4; + if ((str[i * 2] & ~0x20) >= 'A' && (str[i*2] & ~0x20) <= 'F') c += (10 + (str[i * 2] & ~0x20) - 'A') << 4; + if (str[i * 2 + 1] >= '0' && str[i * 2 + 1] <= '9') c += (str[i * 2 + 1] - '0'); + if ((str[i * 2 + 1] & ~0x20) >= 'A' && (str[i * 2 + 1] & ~0x20) <= 'F') c += (10 + (str[i * 2 + 1] & ~0x20) - 'A'); + buf[i] = c; + } + return buf; } START_TEST(test_generate_public_key_from_seckey) { - uint8_t seckey[32] = {0}; - uint8_t pubkey[33] = {0}; + uint8_t seckey[32] = {0}; + uint8_t pubkey[33] = {0}; - memcpy(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), sizeof(seckey)); + memcpy(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), sizeof(seckey)); generate_pubkey_from_seckey(seckey, pubkey); - ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); + ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); } END_TEST @@ -52,7 +52,7 @@ START_TEST(test_generate_key_pair_from_seed) uint8_t pubkey[33] = {0}; uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; compute_sha256sum((char *)seed, digest, strlen(seed)); - genereate_deterministic_key_pair(digest, SHA256_DIGEST_LENGTH, seckey, pubkey); + generate_deterministic_key_pair(digest, SHA256_DIGEST_LENGTH, seckey, pubkey); ck_assert_mem_eq(seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), SHA256_DIGEST_LENGTH); ck_assert_mem_eq(pubkey, fromhex("0244350faa76799fec03de2f324acd077fd1b686c3a89babc0ef47096ccc5a13fa"), SHA256_DIGEST_LENGTH); } @@ -62,17 +62,17 @@ START_TEST(test_secp256k1Hash) { char seed[256] = "seed"; uint8_t secp256k1Hash_digest[SHA256_DIGEST_LENGTH] = {0}; - secp256k1Hash(seed, secp256k1Hash_digest); + secp256k1Hash(seed, secp256k1Hash_digest); ck_assert_mem_eq(secp256k1Hash_digest, fromhex("c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), SHA256_DIGEST_LENGTH); strcpy(seed, "random_seed"); memset(secp256k1Hash_digest, 0, SHA256_DIGEST_LENGTH); - secp256k1Hash(seed, secp256k1Hash_digest); + secp256k1Hash(seed, secp256k1Hash_digest); ck_assert_mem_eq(secp256k1Hash_digest, fromhex("5e81d46f56767496bc05ed177c5237cd4fe5013e617c726af43e1cba884f17d1"), SHA256_DIGEST_LENGTH); strcpy(seed, "random_seed"); memset(secp256k1Hash_digest, 0, SHA256_DIGEST_LENGTH); - secp256k1Hash(seed, secp256k1Hash_digest); + secp256k1Hash(seed, secp256k1Hash_digest); ck_assert_mem_eq(secp256k1Hash_digest, fromhex("5e81d46f56767496bc05ed177c5237cd4fe5013e617c726af43e1cba884f17d1"), SHA256_DIGEST_LENGTH); } @@ -83,42 +83,42 @@ START_TEST(test_generate_deterministic_key_pair_iterator) char seed[256] = "seed"; uint8_t seckey[32] = {0}; uint8_t pubkey[33] = {0}; - generate_deterministic_key_pair_iterator(seed, seckey, pubkey); - ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); - ck_assert_mem_eq(seckey, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); + generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + ck_assert_mem_eq(seckey, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); strcpy(seed, "random_seed"); - memset(pubkey, 0, sizeof(pubkey)); - memset(seckey, 0, sizeof(seckey)); - generate_deterministic_key_pair_iterator(seed, seckey, pubkey); - ck_assert_mem_eq(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); - ck_assert_mem_eq(seckey, fromhex("ff671860c58aad3f765d8add25046412dabf641186472e1553435e6e3c4a6fb0"), 32); + memset(pubkey, 0, sizeof(pubkey)); + memset(seckey, 0, sizeof(seckey)); + generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + ck_assert_mem_eq(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); + ck_assert_mem_eq(seckey, fromhex("ff671860c58aad3f765d8add25046412dabf641186472e1553435e6e3c4a6fb0"), 32); strcpy(seed, "hello seed"); - memset(pubkey, 0, sizeof(pubkey)); - memset(seckey, 0, sizeof(seckey)); - generate_deterministic_key_pair_iterator(seed, seckey, pubkey); - ck_assert_mem_eq(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); - ck_assert_mem_eq(seckey, fromhex("84fdc649964bf299a787cb78cd975910e197dbddd7db776ece544f41c44b3056"), 32); + memset(pubkey, 0, sizeof(pubkey)); + memset(seckey, 0, sizeof(seckey)); + generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + ck_assert_mem_eq(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); + ck_assert_mem_eq(seckey, fromhex("84fdc649964bf299a787cb78cd975910e197dbddd7db776ece544f41c44b3056"), 32); } END_TEST START_TEST(test_base58_address_from_pubkey) { uint8_t pubkey[33] = {0}; - char address[256] = {0}; - size_t size_address = sizeof(address); - memcpy(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); - generate_base58_address_from_pubkey(pubkey, address, &size_address); - ck_assert_str_eq(address, "2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"); - - memcpy(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); - generate_base58_address_from_pubkey(pubkey, address, &size_address); - ck_assert_str_eq(address, "2EKq1QXRmfe7jsWzNdYsmyoz8q3VkwkLsDJ"); - - memcpy(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); - generate_base58_address_from_pubkey(pubkey, address, &size_address); - ck_assert_str_eq(address, "5UgkXRHrf5XRk41BFq1DVyeFZHTQXirhUu"); + char address[256] = {0}; + size_t size_address = sizeof(address); + memcpy(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + generate_base58_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"); + + memcpy(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); + generate_base58_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "2EKq1QXRmfe7jsWzNdYsmyoz8q3VkwkLsDJ"); + + memcpy(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); + generate_base58_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "5UgkXRHrf5XRk41BFq1DVyeFZHTQXirhUu"); } END_TEST @@ -128,98 +128,98 @@ START_TEST(test_compute_sha256sum) uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; compute_sha256sum(seed, digest, strlen(seed)); - ck_assert_mem_eq(digest, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b"), SHA256_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("19b25856e1c150ca834cffc8b59b23adbd0ec0389e58eb22b3b64768098d002b"), SHA256_DIGEST_LENGTH); strcpy(seed, "random_seed"); memset(digest, 0, SHA256_DIGEST_LENGTH); compute_sha256sum(seed, digest, strlen(seed)); - ck_assert_mem_eq(digest, fromhex("7b491face15c5be43df3affe42e6e4aab48522a3b564043de464e8de50184a5d"), SHA256_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("7b491face15c5be43df3affe42e6e4aab48522a3b564043de464e8de50184a5d"), SHA256_DIGEST_LENGTH); strcpy(seed, "024f7fd15da6c7fc7d0410d184073ef702104f82452da9b3e3792db01a8b7907c3"); memset(digest, 0, SHA256_DIGEST_LENGTH); compute_sha256sum(seed, digest, strlen(seed)); - ck_assert_mem_eq(digest, fromhex("a5daa8c9d03a9ec500088bdf0123a9d865725b03895b1291f25500737298e0a9"), SHA256_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("a5daa8c9d03a9ec500088bdf0123a9d865725b03895b1291f25500737298e0a9"), SHA256_DIGEST_LENGTH); } END_TEST START_TEST(test_compute_ecdh) { uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - uint8_t remote_pubkey[33]; - uint8_t my_seckey[32]; + uint8_t remote_pubkey[33]; + uint8_t my_seckey[32]; - memcpy(my_seckey, fromhex("8f609a12bdfc8572590c66763bb05ce609cc0fdcd0c563067e91c06bfd5f1027"), sizeof(my_seckey)); - memcpy(remote_pubkey, fromhex("03008fa0a5668a567cb28ab45e4b6747f5592690c1d519c860f748f6762fa13103"), sizeof(remote_pubkey)); + memcpy(my_seckey, fromhex("8f609a12bdfc8572590c66763bb05ce609cc0fdcd0c563067e91c06bfd5f1027"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("03008fa0a5668a567cb28ab45e4b6747f5592690c1d519c860f748f6762fa13103"), sizeof(remote_pubkey)); memset(digest, 0, SHA256_DIGEST_LENGTH); - ecdh_shared_secret(my_seckey, remote_pubkey, digest); - ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("907d3c524abb561a80644cdb0cf48e6c71ce33ed6a2d5eed40a771bcf86bd081"), SHA256_DIGEST_LENGTH); - memcpy(my_seckey, fromhex("ec4c3702ae8dc5d3aaabc230d362f1ccc1ad2222353d006a057969bf2cc749c1"), sizeof(my_seckey)); - memcpy(remote_pubkey, fromhex("03b5d8432d20e55590b3e1e74a86f4689a5c1f5e25cc58840741fe1ac044d5e65c"), sizeof(remote_pubkey)); + memcpy(my_seckey, fromhex("ec4c3702ae8dc5d3aaabc230d362f1ccc1ad2222353d006a057969bf2cc749c1"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("03b5d8432d20e55590b3e1e74a86f4689a5c1f5e25cc58840741fe1ac044d5e65c"), sizeof(remote_pubkey)); memset(digest, 0, SHA256_DIGEST_LENGTH); - ecdh_shared_secret(my_seckey, remote_pubkey, digest); - ck_assert_mem_eq(digest, fromhex("c59b456353d0fbceadc06d7794c42ebf413ab952b29ecf6052d30c7c1a50acda"), SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("c59b456353d0fbceadc06d7794c42ebf413ab952b29ecf6052d30c7c1a50acda"), SHA256_DIGEST_LENGTH); - memcpy(my_seckey, fromhex("19adca686f1ca7befc30af65765597a4d033ac7479850e79cef3ce5cb5b95da4"), sizeof(my_seckey)); - memcpy(remote_pubkey, fromhex("0328bd053c69d9c3dd1e864098e503de9839e990c63c48d8a4d6011c423658c4a9"), sizeof(remote_pubkey)); + memcpy(my_seckey, fromhex("19adca686f1ca7befc30af65765597a4d033ac7479850e79cef3ce5cb5b95da4"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("0328bd053c69d9c3dd1e864098e503de9839e990c63c48d8a4d6011c423658c4a9"), sizeof(remote_pubkey)); memset(digest, 0, SHA256_DIGEST_LENGTH); - ecdh_shared_secret(my_seckey, remote_pubkey, digest); - ck_assert_mem_eq(digest, fromhex("1fd2c655bcf19202ee004a3e0ae8f5c64ad1c0ce3b69f32ba18da188bb4d1eea"), SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("1fd2c655bcf19202ee004a3e0ae8f5c64ad1c0ce3b69f32ba18da188bb4d1eea"), SHA256_DIGEST_LENGTH); - memcpy(my_seckey, fromhex("085d62c27a37889e02a183ee29962d5f4377831b4a70834ccea24a209e201404"), sizeof(my_seckey)); - memcpy(remote_pubkey, fromhex("030684d74471053ac6395ef74a86f88daa25f501329734c837c8c79c600423b220"), sizeof(remote_pubkey)); + memcpy(my_seckey, fromhex("085d62c27a37889e02a183ee29962d5f4377831b4a70834ccea24a209e201404"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("030684d74471053ac6395ef74a86f88daa25f501329734c837c8c79c600423b220"), sizeof(remote_pubkey)); memset(digest, 0, SHA256_DIGEST_LENGTH); - ecdh_shared_secret(my_seckey, remote_pubkey, digest); - ck_assert_mem_eq(digest, fromhex("4225281b8498f05e0eaac02be79ce72471c2ddd8c127908b1f717bf64177b287"), SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("4225281b8498f05e0eaac02be79ce72471c2ddd8c127908b1f717bf64177b287"), SHA256_DIGEST_LENGTH); - memcpy(my_seckey, fromhex("3c4289a9d884f74bd05c352fa1c08ce0d65955b59b24a572f46e02807dd42e62"), sizeof(my_seckey)); - memcpy(remote_pubkey, fromhex("0223496e9caa207e0f8cc283e970b85f2831732d5e0be2bcf9fa366f7e064a25dd"), sizeof(remote_pubkey)); + memcpy(my_seckey, fromhex("3c4289a9d884f74bd05c352fa1c08ce0d65955b59b24a572f46e02807dd42e62"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("0223496e9caa207e0f8cc283e970b85f2831732d5e0be2bcf9fa366f7e064a25dd"), sizeof(remote_pubkey)); memset(digest, 0, SHA256_DIGEST_LENGTH); - ecdh_shared_secret(my_seckey, remote_pubkey, digest); - ck_assert_mem_eq(digest, fromhex("70e5d568b31ed601fcb7f3144888d0633938817ae85417de1fbd0d52e29b5d7c"), SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("70e5d568b31ed601fcb7f3144888d0633938817ae85417de1fbd0d52e29b5d7c"), SHA256_DIGEST_LENGTH); - memcpy(my_seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), sizeof(my_seckey)); - memcpy(remote_pubkey, fromhex("02683e90daa5b0dd195b69e01386390284d3b3723121ce213771d9a0815d12b86c"), sizeof(remote_pubkey)); + memcpy(my_seckey, fromhex("a7e130694166cdb95b1e1bbce3f21e4dbd63f46df42b48c5a1f8295033d57d04"), sizeof(my_seckey)); + memcpy(remote_pubkey, fromhex("02683e90daa5b0dd195b69e01386390284d3b3723121ce213771d9a0815d12b86c"), sizeof(remote_pubkey)); memset(digest, 0, SHA256_DIGEST_LENGTH); - ecdh_shared_secret(my_seckey, remote_pubkey, digest); - ck_assert_mem_eq(digest, fromhex("9ab65c0e99605712aac66be1eccccb6dacb867ebaf2b1ebf96d3d92524f247fd"), SHA256_DIGEST_LENGTH); + ecdh_shared_secret(my_seckey, remote_pubkey, digest); + ck_assert_mem_eq(digest, fromhex("9ab65c0e99605712aac66be1eccccb6dacb867ebaf2b1ebf96d3d92524f247fd"), SHA256_DIGEST_LENGTH); } END_TEST // define test suite and cases Suite *test_suite(void) { - Suite *s = suite_create("skycoin_crypto"); - TCase *tc; + Suite *s = suite_create("skycoin_crypto"); + TCase *tc; - tc = tcase_create("checksums"); - tcase_add_test(tc, test_generate_public_key_from_seckey); - tcase_add_test(tc, test_generate_key_pair_from_seed); + tc = tcase_create("checksums"); + tcase_add_test(tc, test_generate_public_key_from_seckey); + tcase_add_test(tc, test_generate_key_pair_from_seed); tcase_add_test(tc, test_secp256k1Hash); - tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); - tcase_add_test(tc, test_base58_address_from_pubkey); - tcase_add_test(tc, test_compute_sha256sum); - tcase_add_test(tc, test_compute_ecdh); - suite_add_tcase(s, tc); + tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); + tcase_add_test(tc, test_base58_address_from_pubkey); + tcase_add_test(tc, test_compute_sha256sum); + tcase_add_test(tc, test_compute_ecdh); + suite_add_tcase(s, tc); - return s; + return s; } // run suite int main(void) { - int number_failed; - Suite *s = test_suite(); - SRunner *sr = srunner_create(s); - srunner_run_all(sr, CK_VERBOSE); - number_failed = srunner_ntests_failed(sr); - srunner_free(sr); - if (number_failed == 0) { - printf("PASSED ALL TESTS\n"); - } - return number_failed; + int number_failed; + Suite *s = test_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + if (number_failed == 0) { + printf("PASSED ALL TESTS\n"); + } + return number_failed; } From f78caf3da2933efea411220c17437cdec7658826 Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 1 Mar 2018 16:08:29 +0800 Subject: [PATCH 27/73] generate_bitcoin_address_from_pubkey function --- hardware-wallet/skycoin_crypto.c | 14 ++++++++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 964842e0..ad0924d1 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -114,3 +114,17 @@ void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, s memcpy(&pubkey_hash[21], digest, 4); b58enc(address, size_address, pubkey_hash, sizeof(pubkey_hash)); } + +void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address) +{ + uint8_t b1[SHA256_DIGEST_LENGTH] = {0}; + uint8_t b2[25] = {0}; + uint8_t h1[SHA256_DIGEST_LENGTH] = {0}; + uint8_t b4[SHA256_DIGEST_LENGTH] = {0}; + compute_sha256sum((char *)pubkey, b1, 33); + ripemd160(b1, SHA256_DIGEST_LENGTH, &b2[1]); + compute_sha256sum((char *)b2, h1, 21); + compute_sha256sum((char *)h1, b4, SHA256_DIGEST_LENGTH); + memcpy(&b2[21], b4, 4); + b58enc(address, size_address, b2, sizeof(b2)); +} diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index b535c3af..f50dbf56 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -12,5 +12,6 @@ void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LE void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); +void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 982cdc65..af9bb461 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -122,6 +122,26 @@ START_TEST(test_base58_address_from_pubkey) } END_TEST + +START_TEST(test_bitcoin_address_from_pubkey) +{ + uint8_t pubkey[33] = {0}; + char address[256] = {0}; + size_t size_address = sizeof(address); + memcpy(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + generate_bitcoin_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "1CN7JTzTTpmh1dsHeUSosXmNL2GLTwt78g"); + + memcpy(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); + generate_bitcoin_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "1DkKGd1YV9nhBKHWT9Aa2JzbEus98y6oU9"); + + memcpy(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); + generate_bitcoin_address_from_pubkey(pubkey, address, &size_address); + ck_assert_str_eq(address, "1Ba2hpHH2o6H1NSrFpJTz5AbxdB2BdK5L2"); +} +END_TEST + START_TEST(test_compute_sha256sum) { char seed[256] = "seed"; @@ -201,6 +221,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_secp256k1Hash); tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); tcase_add_test(tc, test_base58_address_from_pubkey); + tcase_add_test(tc, test_bitcoin_address_from_pubkey); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From 96abd79ca2bdf0acd7da0f64fa4409f28b7a15ea Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 1 Mar 2018 16:34:11 +0800 Subject: [PATCH 28/73] generate_bitcoin_private_address_from_pubkey function --- hardware-wallet/skycoin_crypto.c | 15 +++++++++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 21 +++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index ad0924d1..2b01d7d7 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -128,3 +128,18 @@ void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, memcpy(&b2[21], b4, 4); b58enc(address, size_address, b2, sizeof(b2)); } + + +void generate_bitcoin_private_address_from_pubkey(const uint8_t* seckey, char* address, size_t *size_address) +{ + uint8_t b2[38] = {0}; + uint8_t h1[SHA256_DIGEST_LENGTH] = {0}; + uint8_t b3[SHA256_DIGEST_LENGTH] = {0}; + memcpy(&b2[1], seckey, 32); + b2[0] = 0x80; + b2[33] = 0x01; + compute_sha256sum((char *)b2, h1, 34); + compute_sha256sum((char *)h1, b3, SHA256_DIGEST_LENGTH); + memcpy(&b2[34], b3, 4); + b58enc(address, size_address, b2, sizeof(b2)); +} \ No newline at end of file diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index f50dbf56..4d2528e5 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -13,5 +13,6 @@ void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); +void generate_bitcoin_private_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index af9bb461..b50056cb 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -142,6 +142,26 @@ START_TEST(test_bitcoin_address_from_pubkey) } END_TEST + +START_TEST(test_bitcoin_private_address_from_pubkey) +{ + uint8_t seckey[32] = {0}; + char address[256] = {0}; + size_t size_address = sizeof(address); + memcpy(seckey, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); + generate_bitcoin_private_address_from_pubkey(seckey, address, &size_address); + ck_assert_str_eq(address, "KwDuvkABDqb4WQiwc92DpXtBBiEywuKv46ZUvz5Gi5Xyn9gbcTJt"); + + memcpy(seckey, fromhex("ff671860c58aad3f765d8add25046412dabf641186472e1553435e6e3c4a6fb0"), 32); + generate_bitcoin_private_address_from_pubkey(seckey, address, &size_address); + ck_assert_str_eq(address, "L5nBR59QkW6kyXFvyqNbncWo2jPMoBXSH9fGUkh3n2RQn5Mj3vfY"); + + memcpy(seckey, fromhex("84fdc649964bf299a787cb78cd975910e197dbddd7db776ece544f41c44b3056"), 32); + generate_bitcoin_private_address_from_pubkey(seckey, address, &size_address); + ck_assert_str_eq(address, "L1gEDGuLTpMjybHnsJ24bUHhueocDrrKVdM3rj1rqXFHfyM2WtwD"); +} +END_TEST + START_TEST(test_compute_sha256sum) { char seed[256] = "seed"; @@ -222,6 +242,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); tcase_add_test(tc, test_base58_address_from_pubkey); tcase_add_test(tc, test_bitcoin_address_from_pubkey); + tcase_add_test(tc, test_bitcoin_private_address_from_pubkey); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); suite_add_tcase(s, tc); From fb74a8f6588999a42b367a3e60c77aed7ef4dc46 Mon Sep 17 00:00:00 2001 From: mpsido Date: Tue, 13 Mar 2018 17:54:53 +0800 Subject: [PATCH 29/73] Commit temporary not cleaned code for pubkey generation from signature --- hardware-wallet/skycoin_crypto.c | 284 +++++++++++++++++++++++++- hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 18 ++ 3 files changed, 302 insertions(+), 1 deletion(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 2b01d7d7..85fd9a9c 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -1,6 +1,7 @@ #include "skycoin_crypto.h" #include +#include #include "sha2.h" #include "bip32.h" @@ -8,6 +9,9 @@ #include "ripemd160.h" #include "base58.h" +#include "ecdsa.h" +// #include "secp256k1.h" + extern void bn_print(const bignum256 *a); void create_node(const char* seed_str, HDNode* node); @@ -142,4 +146,282 @@ void generate_bitcoin_private_address_from_pubkey(const uint8_t* seckey, char* a compute_sha256sum((char *)h1, b3, SHA256_DIGEST_LENGTH); memcpy(&b2[34], b3, 4); b58enc(address, size_address, b2, sizeof(b2)); -} \ No newline at end of file +} + +void SetB32(const uint8_t* input, uint32_t* output) +{ + uint32_t v = 0; + uint8_t i,j,limb,shift; + for (i = 0; i < 32; i++) { + for (j = 0; j < 4; j++) { + limb = (8*i + 2*j) / 26; + shift = (8*i + 2*j) % 26; + v = (uint32_t)((input[31-i] >> (2*j)) & 0x3) << shift; + output[limb] |= v; + } + } +} + +// Compute public key from signature and recovery id. +// returns 0 if verification succeeded +int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest, int recid) +{ + bignum256 r, s, e; + curve_point cp, cp2; + uint32_t fx[10] = {0}; + // uint32_t ifx[10] = {0}; + + // read r and s + bn_read_be(sig, &r); + bn_read_be(sig + 32, &s); + if (!bn_is_less(&r, &curve->order) || bn_is_zero(&r)) { + return 1; + } + if (!bn_is_less(&s, &curve->order) || bn_is_zero(&s)) { + return 1; + } + uint8_t get_back_r[32] = {0}; + bn_write_be(&r, get_back_r); + SetB32(get_back_r, fx); + /* + printf("fx= "); + for (int i = 0; i < 10;++i) + { + printf("%x ", fx[i]); + ifx[9-i] = fx[i]; + } + printf("\n"); + printf("ifx= "); + for (int i = 0; i < 10; ++i) + { + printf("%x ", ifx[i]); + } + printf("\n"); + */ + + // cp = R = k * G (k is secret nonce when signing) + if (recid & 2) { + bn_add(&r, &curve->order); + if (!bn_is_less(&r, &curve->prime)) { + return 1; + } + } + + // bn_read_be((uint8_t*)fx, &cp.x); + // memcpy(&cp.x, ifx, sizeof(bignum256)); + memcpy(&cp.x, &r, sizeof(bignum256)); + /* + uint8_t get_back_x[32] = {0}; + bn_write_be(&cp.x, get_back_x); + printf("get_back_x= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", get_back_x[i]); + } + printf("\n"); +*/ + // compute y from x + uncompress_coords(curve, recid & 1, &cp.x, &cp.y); + if (!ecdsa_validate_pubkey(curve, &cp)) { + return 1; + } + /* + uint8_t get_back_y[32] = {0}; + bn_write_be(&cp.y, get_back_y); + printf("get_back_y= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", get_back_y[i]); + } + printf("\n"); +*/ + + + // r := r^-1 + bn_inverse(&r, &curve->order); + /* + uint8_t get_back_rn[288] = {0}; + bn_write_be(&r, get_back_rn); + printf("get_back_rn= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", get_back_rn[i]); + } + printf("\n"); + + + uint8_t curve_order[288] = {0}; + bn_write_be(&curve->order, curve_order); + printf("curve_order= "); + for (int i = 0; i < 32;++i) + { + printf("%02x", curve_order[i]); + } + printf("\n"); +*/ + uint8_t bn1[256] = {0}; + // e = -digest + bn_read_be(digest, &e); + while (! (uint8_t)e.val[0]) + { + for (int i = 0; i < 8; ++i) + { + bn_rshift(&e); + } + } + bn_write_be(&e, bn1); + printf("e= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", bn1[i]); + } + printf("\n"); + + bn_multiply(&r, &e, &curve->order); + bn_write_be(&e, bn1); + printf("bn1= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", bn1[i]); + } + printf("\n"); + bn_subtractmod(&curve->order, &e, &e, &curve->order); + bn_fast_mod(&e, &curve->order); + bn_mod(&e, &curve->order); + bn_write_be(&e, bn1); + printf("bn1= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", bn1[i]); + } + printf("\n"); + + uint8_t bn2[33] = {0}; + bn_multiply(&r, &s, &curve->order); + bn_write_be(&s, bn2); + printf("bn2= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", bn2[i]); + } + printf("\n"); + + // cp := s * R = s * k *G + point_multiply(curve, &s, &cp, &cp); + // cp2 := -digest * G + scalar_multiply(curve, &e, &cp2); + + // cp := (s * k - digest) * G = (r*priv) * G = r * Pub + point_add(curve, &cp2, &cp); + // cp := r^{-1} * r * Pub = Pub + // point_multiply(curve, &r, &cp, &cp); + pub_key[0] = 0x04; + bn_write_be(&cp.x, pub_key + 1); + bn_write_be(&cp.y, pub_key + 33); + + return 0; +} + +/*signature: 65 bytes, +message 32 bytes, +pubkey 33 bytes +returns 0 if signature matches and 5 if it does not*/ +int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, uint8_t* pubkey) +{ + int res = -1; + HDNode dummy_node; + char seed_str[256] = "dummy seed"; + uint8_t long_pubkey[65]; + create_node(seed_str, &dummy_node); +/* + printf("message= "); + for (int i = 0;i < 66;++i) + { + printf("%02x", (uint8_t)message[i]); + } + printf("\n"); + + printf("sign= "); + for (int i = 0;i < 65;++i) + { + printf("%02x", signature[i]); + } + printf("\n"); + */ + bignum256 r, s; + bn_read_be(signature, &r); + bn_read_be(signature + 32, &s); + uint8_t get_back_r[288] = {0}; + uint8_t get_back_s[288] = {0}; + bn_write_be(&r, get_back_r); + bn_write_be(&s, get_back_s); +/* + printf("r= "); + for (int i = 0;i < 9;++i) + { + printf("%08x", r.val[i]); + } + printf("\n"); + printf("get_back_r= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", get_back_r[i]); + } + printf("\n"); + printf("s= "); + for (int i = 0;i < 9;++i) + { + printf("%08x", s.val[i]); + } + printf("\n"); + printf("get_back_s= "); + for (int i = 0;i < 32;++i) + { + printf("%02x", get_back_s[i]); + } + printf("\n"); + +*/ + // var recid = int(sig[64]) + res = verify_digest_recover(dummy_node.curve->params, long_pubkey, signature, (uint8_t*)message, 0); + // res = ecdsa_verify_digest(dummy_node.curve->params, long_pubkey, signature, (uint8_t*)message); + memcpy(&pubkey[1], &long_pubkey[1], 32); + if (long_pubkey[64] % 2 == 0) + { + pubkey[0] = 0x02; + } + else + { + pubkey[0] = 0x03; + } + return res; +} + +#if 0 +int recover_pubkey_from_signed_message_bread_board(char* message, const uint8_t* signature, uint8_t* pubkey) +{ + secp256k1_pubkey long_pubkey; + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + + bignum256 r, s; + bn_read_be(signature, &r); + bn_read_be(signature + 32, &s); + + secp256k1_ecdsa_signature sign; + bn_write_be(&r, &sign.data[0]); + bn_write_be(&s, &sign.data[32]); + + int res = secp256k1_ecdsa_verify(ctx, &sign, (uint8_t *)message, &long_pubkey); + memcpy(&pubkey[1], &long_pubkey.data[1], 32); + if (long_pubkey.data[63] % 2 == 0) + { + pubkey[0] = 0x02; + } + else + { + pubkey[0] = 0x03; + } + return res; +} +#endif \ No newline at end of file diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 4d2528e5..3e3a9f90 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -14,5 +14,6 @@ void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_leng void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_private_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); +int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, uint8_t* pubkey); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index b50056cb..112d78a6 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -229,6 +229,23 @@ START_TEST(test_compute_ecdh) } END_TEST + +START_TEST(test_recover_pubkey_from_signed_message) +{ + int res; + // uint8_t message[32]; + char message[256] = "Hello World!"; + uint8_t signature[65]; + uint8_t pubkey[33]; + // memcpy(message, fromhex("5dfbea13c81c48f7261994c148a7a39b9b51107d22b57bfd4613dce02dee46ee"), 32); + memcpy(signature, fromhex("abc30130e2d9561fa8eb9871b75b13100689937dfc41c98d611b985ca25258c960be25c0b45874e1255f053863f6e175300d7e788d8b93d6dcfa9377120e4d3500"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + +} +END_TEST + // define test suite and cases Suite *test_suite(void) { @@ -245,6 +262,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_bitcoin_private_address_from_pubkey); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); + tcase_add_test(tc, test_recover_pubkey_from_signed_message); suite_add_tcase(s, tc); return s; From 5d1c54ed06770926403e9908b717da68d4b7f956 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 14 Mar 2018 14:45:55 +0800 Subject: [PATCH 30/73] Correcting recid, cleaning code and adding more tests in test_recover_pubkey_from_signed_message --- hardware-wallet/skycoin_crypto.c | 195 +------------------------- hardware-wallet/test_skycoin_crypto.c | 60 ++++++++ 2 files changed, 65 insertions(+), 190 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 85fd9a9c..48727bb9 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -1,7 +1,6 @@ #include "skycoin_crypto.h" #include -#include #include "sha2.h" #include "bip32.h" @@ -10,7 +9,6 @@ #include "base58.h" #include "ecdsa.h" -// #include "secp256k1.h" extern void bn_print(const bignum256 *a); void create_node(const char* seed_str, HDNode* node); @@ -148,28 +146,12 @@ void generate_bitcoin_private_address_from_pubkey(const uint8_t* seckey, char* a b58enc(address, size_address, b2, sizeof(b2)); } -void SetB32(const uint8_t* input, uint32_t* output) -{ - uint32_t v = 0; - uint8_t i,j,limb,shift; - for (i = 0; i < 32; i++) { - for (j = 0; j < 4; j++) { - limb = (8*i + 2*j) / 26; - shift = (8*i + 2*j) % 26; - v = (uint32_t)((input[31-i] >> (2*j)) & 0x3) << shift; - output[limb] |= v; - } - } -} - // Compute public key from signature and recovery id. // returns 0 if verification succeeded -int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest, int recid) +int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest) { bignum256 r, s, e; curve_point cp, cp2; - uint32_t fx[10] = {0}; - // uint32_t ifx[10] = {0}; // read r and s bn_read_be(sig, &r); @@ -180,24 +162,7 @@ int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint if (!bn_is_less(&s, &curve->order) || bn_is_zero(&s)) { return 1; } - uint8_t get_back_r[32] = {0}; - bn_write_be(&r, get_back_r); - SetB32(get_back_r, fx); - /* - printf("fx= "); - for (int i = 0; i < 10;++i) - { - printf("%x ", fx[i]); - ifx[9-i] = fx[i]; - } - printf("\n"); - printf("ifx= "); - for (int i = 0; i < 10; ++i) - { - printf("%x ", ifx[i]); - } - printf("\n"); - */ + uint8_t recid = sig[64]; // cp = R = k * G (k is secret nonce when signing) if (recid & 2) { @@ -207,59 +172,15 @@ int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint } } - // bn_read_be((uint8_t*)fx, &cp.x); - // memcpy(&cp.x, ifx, sizeof(bignum256)); memcpy(&cp.x, &r, sizeof(bignum256)); - /* - uint8_t get_back_x[32] = {0}; - bn_write_be(&cp.x, get_back_x); - printf("get_back_x= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", get_back_x[i]); - } - printf("\n"); -*/ // compute y from x uncompress_coords(curve, recid & 1, &cp.x, &cp.y); if (!ecdsa_validate_pubkey(curve, &cp)) { return 1; } - /* - uint8_t get_back_y[32] = {0}; - bn_write_be(&cp.y, get_back_y); - printf("get_back_y= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", get_back_y[i]); - } - printf("\n"); -*/ - - // r := r^-1 bn_inverse(&r, &curve->order); - /* - uint8_t get_back_rn[288] = {0}; - bn_write_be(&r, get_back_rn); - printf("get_back_rn= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", get_back_rn[i]); - } - printf("\n"); - - - uint8_t curve_order[288] = {0}; - bn_write_be(&curve->order, curve_order); - printf("curve_order= "); - for (int i = 0; i < 32;++i) - { - printf("%02x", curve_order[i]); - } - printf("\n"); -*/ - uint8_t bn1[256] = {0}; + // e = -digest bn_read_be(digest, &e); while (! (uint8_t)e.val[0]) @@ -269,42 +190,13 @@ int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint bn_rshift(&e); } } - bn_write_be(&e, bn1); - printf("e= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", bn1[i]); - } - printf("\n"); bn_multiply(&r, &e, &curve->order); - bn_write_be(&e, bn1); - printf("bn1= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", bn1[i]); - } - printf("\n"); bn_subtractmod(&curve->order, &e, &e, &curve->order); bn_fast_mod(&e, &curve->order); bn_mod(&e, &curve->order); - bn_write_be(&e, bn1); - printf("bn1= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", bn1[i]); - } - printf("\n"); - - uint8_t bn2[33] = {0}; + bn_multiply(&r, &s, &curve->order); - bn_write_be(&s, bn2); - printf("bn2= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", bn2[i]); - } - printf("\n"); // cp := s * R = s * k *G point_multiply(curve, &s, &cp, &cp); @@ -313,8 +205,6 @@ int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint // cp := (s * k - digest) * G = (r*priv) * G = r * Pub point_add(curve, &cp2, &cp); - // cp := r^{-1} * r * Pub = Pub - // point_multiply(curve, &r, &cp, &cp); pub_key[0] = 0x04; bn_write_be(&cp.x, pub_key + 1); bn_write_be(&cp.y, pub_key + 33); @@ -333,58 +223,12 @@ int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, char seed_str[256] = "dummy seed"; uint8_t long_pubkey[65]; create_node(seed_str, &dummy_node); -/* - printf("message= "); - for (int i = 0;i < 66;++i) - { - printf("%02x", (uint8_t)message[i]); - } - printf("\n"); - printf("sign= "); - for (int i = 0;i < 65;++i) - { - printf("%02x", signature[i]); - } - printf("\n"); - */ bignum256 r, s; bn_read_be(signature, &r); bn_read_be(signature + 32, &s); - uint8_t get_back_r[288] = {0}; - uint8_t get_back_s[288] = {0}; - bn_write_be(&r, get_back_r); - bn_write_be(&s, get_back_s); -/* - printf("r= "); - for (int i = 0;i < 9;++i) - { - printf("%08x", r.val[i]); - } - printf("\n"); - printf("get_back_r= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", get_back_r[i]); - } - printf("\n"); - printf("s= "); - for (int i = 0;i < 9;++i) - { - printf("%08x", s.val[i]); - } - printf("\n"); - printf("get_back_s= "); - for (int i = 0;i < 32;++i) - { - printf("%02x", get_back_s[i]); - } - printf("\n"); -*/ - // var recid = int(sig[64]) - res = verify_digest_recover(dummy_node.curve->params, long_pubkey, signature, (uint8_t*)message, 0); - // res = ecdsa_verify_digest(dummy_node.curve->params, long_pubkey, signature, (uint8_t*)message); + res = verify_digest_recover(dummy_node.curve->params, long_pubkey, signature, (uint8_t*)message); memcpy(&pubkey[1], &long_pubkey[1], 32); if (long_pubkey[64] % 2 == 0) { @@ -396,32 +240,3 @@ int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, } return res; } - -#if 0 -int recover_pubkey_from_signed_message_bread_board(char* message, const uint8_t* signature, uint8_t* pubkey) -{ - secp256k1_pubkey long_pubkey; - secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - - bignum256 r, s; - bn_read_be(signature, &r); - bn_read_be(signature + 32, &s); - - secp256k1_ecdsa_signature sign; - bn_write_be(&r, &sign.data[0]); - bn_write_be(&s, &sign.data[32]); - - int res = secp256k1_ecdsa_verify(ctx, &sign, (uint8_t *)message, &long_pubkey); - memcpy(&pubkey[1], &long_pubkey.data[1], 32); - if (long_pubkey.data[63] % 2 == 0) - { - pubkey[0] = 0x02; - } - else - { - pubkey[0] = 0x03; - } - return res; -} -#endif \ No newline at end of file diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 112d78a6..54b590d0 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -243,6 +243,66 @@ START_TEST(test_recover_pubkey_from_signed_message) ck_assert_int_eq(res, 0); ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + sprintf(message, "Hello World, it's me!"); + memcpy(signature, fromhex("54d7572cf5066225f349d89ad6d19e19e64d14711083f6607258b37407e5f0d26c6328d7c3ecb31eb4132f6b983f8ec33cdf3664c1df617526bbac140cdac75b01"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + + memcpy(signature, fromhex("00b0dbb50c8b8f6c5be2bdee786a658a0ea22872ce90b21fbc0eb4f1d1018a043f93216a6af467acfb44aef9ab07e0a65621128504f3a61dfa0014b1cdd6d9c701"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + + // sign with a different key pair + // the seed for key pair generation was 'different' + memcpy(signature, fromhex("5feef64dd9b9465e0f66ac21c5078cee4504f15ad407093b58908b69bc717d1c456901b4dbf9dde3eb170bd7aaf4e7a62f260e6194cc9884037affbfda250f3501"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + sprintf(message, "The seed was 'different'"); + memcpy(signature, fromhex("b8a91946af3cfe42139c853f09d1bc087db3bea0ab8bb20ab13790f4ba08aa4c327a4f614c61b2c532c2bab3852817ecd17b1c607f52f52c9c561ddbb2e4418e01"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + memcpy(signature, fromhex("f2e863beed0c026d0c631712dbe5ecb7ed95166275586271b77181ee3e68502b24c7a5c32b26ca5424fadfd8488285ad6e3ff3b86ed6c5449102d3198712f57b00"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + sprintf(message, "This msg has 24 letters."); + memcpy(signature, fromhex("eff089c10e4c8d3c7244a8bc75d5657153ec7b42ed6d01bcc75cd08271a4aa7c19d1bd3b60330c909600238c1f18d99f06d2573c27cb4f2dfb0f65666a5a523200"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + sprintf(message, "This msg has 31 characters: ok!"); + memcpy(signature, fromhex("3dc77d17eeed0d3fd3d34ca05e8a9e84fbf73529b96bde7548080ac35d81470a60d5b8b37f2bb2500cf6a9745cd1c6edb81ebb5419e4f4fda9271794c8daf54200"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + // testing message maximal length + sprintf(message, "This msg has 32 characters: max."); + memcpy(signature, fromhex("e092ce21dda29349bd1e4e8b7a26d701542ac972b4e319a60bd887b6e51853622300e4e847f01a9aff4f51caa969759f717a6e5439b6bc4a5305b10bab9b5cb201"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + sprintf(message, "This msg has 32 characters: max.."); + memcpy(signature, fromhex("e092ce21dda29349bd1e4e8b7a26d701542ac972b4e319a60bd887b6e51853622300e4e847f01a9aff4f51caa969759f717a6e5439b6bc4a5305b10bab9b5cb201"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + sprintf(message, "This msg has 32 characters: max... What ever I write here is ignored."); + memcpy(signature, fromhex("e092ce21dda29349bd1e4e8b7a26d701542ac972b4e319a60bd887b6e51853622300e4e847f01a9aff4f51caa969759f717a6e5439b6bc4a5305b10bab9b5cb201"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + } END_TEST From a95cd23efefd62098d9799797fefcce5a3035277 Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 15 Mar 2018 10:45:30 +0800 Subject: [PATCH 31/73] Correcting indent, writing 4 spaces instead of tab --- hardware-wallet/test_skycoin_crypto.c | 76 +++++++++++++-------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 54b590d0..34cfceee 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -232,76 +232,76 @@ END_TEST START_TEST(test_recover_pubkey_from_signed_message) { - int res; - // uint8_t message[32]; + int res; + // uint8_t message[32]; char message[256] = "Hello World!"; - uint8_t signature[65]; - uint8_t pubkey[33]; - // memcpy(message, fromhex("5dfbea13c81c48f7261994c148a7a39b9b51107d22b57bfd4613dce02dee46ee"), 32); + uint8_t signature[65]; + uint8_t pubkey[33]; + // memcpy(message, fromhex("5dfbea13c81c48f7261994c148a7a39b9b51107d22b57bfd4613dce02dee46ee"), 32); memcpy(signature, fromhex("abc30130e2d9561fa8eb9871b75b13100689937dfc41c98d611b985ca25258c960be25c0b45874e1255f053863f6e175300d7e788d8b93d6dcfa9377120e4d3500"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); sprintf(message, "Hello World, it's me!"); memcpy(signature, fromhex("54d7572cf5066225f349d89ad6d19e19e64d14711083f6607258b37407e5f0d26c6328d7c3ecb31eb4132f6b983f8ec33cdf3664c1df617526bbac140cdac75b01"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); memcpy(signature, fromhex("00b0dbb50c8b8f6c5be2bdee786a658a0ea22872ce90b21fbc0eb4f1d1018a043f93216a6af467acfb44aef9ab07e0a65621128504f3a61dfa0014b1cdd6d9c701"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); // sign with a different key pair // the seed for key pair generation was 'different' memcpy(signature, fromhex("5feef64dd9b9465e0f66ac21c5078cee4504f15ad407093b58908b69bc717d1c456901b4dbf9dde3eb170bd7aaf4e7a62f260e6194cc9884037affbfda250f3501"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); sprintf(message, "The seed was 'different'"); memcpy(signature, fromhex("b8a91946af3cfe42139c853f09d1bc087db3bea0ab8bb20ab13790f4ba08aa4c327a4f614c61b2c532c2bab3852817ecd17b1c607f52f52c9c561ddbb2e4418e01"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); memcpy(signature, fromhex("f2e863beed0c026d0c631712dbe5ecb7ed95166275586271b77181ee3e68502b24c7a5c32b26ca5424fadfd8488285ad6e3ff3b86ed6c5449102d3198712f57b00"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); sprintf(message, "This msg has 24 letters."); memcpy(signature, fromhex("eff089c10e4c8d3c7244a8bc75d5657153ec7b42ed6d01bcc75cd08271a4aa7c19d1bd3b60330c909600238c1f18d99f06d2573c27cb4f2dfb0f65666a5a523200"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); sprintf(message, "This msg has 31 characters: ok!"); memcpy(signature, fromhex("3dc77d17eeed0d3fd3d34ca05e8a9e84fbf73529b96bde7548080ac35d81470a60d5b8b37f2bb2500cf6a9745cd1c6edb81ebb5419e4f4fda9271794c8daf54200"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); // testing message maximal length sprintf(message, "This msg has 32 characters: max."); memcpy(signature, fromhex("e092ce21dda29349bd1e4e8b7a26d701542ac972b4e319a60bd887b6e51853622300e4e847f01a9aff4f51caa969759f717a6e5439b6bc4a5305b10bab9b5cb201"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); sprintf(message, "This msg has 32 characters: max.."); memcpy(signature, fromhex("e092ce21dda29349bd1e4e8b7a26d701542ac972b4e319a60bd887b6e51853622300e4e847f01a9aff4f51caa969759f717a6e5439b6bc4a5305b10bab9b5cb201"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); sprintf(message, "This msg has 32 characters: max... What ever I write here is ignored."); memcpy(signature, fromhex("e092ce21dda29349bd1e4e8b7a26d701542ac972b4e319a60bd887b6e51853622300e4e847f01a9aff4f51caa969759f717a6e5439b6bc4a5305b10bab9b5cb201"), 65); - res = recover_pubkey_from_signed_message(message, signature, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); } END_TEST From 3dff41546267880fab207642ae98c0a40173a94e Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 21 Mar 2018 15:35:30 +0800 Subject: [PATCH 32/73] Making a dynamic library out of skycoin-crypto --- hardware-wallet/Makefile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hardware-wallet/Makefile b/hardware-wallet/Makefile index e00b1624..db7c3b3d 100644 --- a/hardware-wallet/Makefile +++ b/hardware-wallet/Makefile @@ -1,6 +1,6 @@ CC ?= gcc -OPTFLAGS ?= -O3 -g +OPTFLAGS ?= -O3 -g -fPIC CFLAGS += $(OPTFLAGS) \ -std=gnu99 \ @@ -34,15 +34,19 @@ OBJS = $(SRCS:.c=.o) %.o: %.c %.h $(CC) $(CFLAGS) -o $@ -c $< -TESTLIBS = -L/usr/local/lib/ -lm -lrt -L$(CHECK_PATH)/src -lcheck -L$(TREZOR_CRYPTO_PATH) -lTrezorCrypto +TESTLIBS = -L/usr/local/lib/ -lm -lrt -L$(CHECK_PATH)/src -lcheck +CRYPTOLIBS = -L$(TREZOR_CRYPTO_PATH) -ltrezor-crypto all: test_skycoin_crypto +skycoin-crypto: skycoin_crypto.o $(OBJS) + $(CC) -rdynamic -shared $(CFLAGS) $(OBJS) $(CRYPTOLIBS) -o libskycoin-crypto.so -test_skycoin_crypto: test_skycoin_crypto.o skycoin_crypto.o $(OBJS) - $(CC) test_skycoin_crypto.o $(OBJS) $(TESTLIBS) -o test_skycoin_crypto +test_skycoin_crypto: test_skycoin_crypto.o skycoin-crypto + $(CC) test_skycoin_crypto.o $(OBJS) -L. -lskycoin-crypto $(TESTLIBS) $(CRYPTOLIBS) -o test_skycoin_crypto clean: rm -f *.o test_skycoin_crypto + rm -f *.so From e9b0a0a71d45ccb9281f1383215f24e2234146a8 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 21 Mar 2018 16:07:28 +0800 Subject: [PATCH 33/73] Moving tohex function in skycoin_crypto.c --- hardware-wallet/skycoin_crypto.c | 14 ++++++++++++-- hardware-wallet/skycoin_crypto.h | 2 +- hardware-wallet/test_skycoin_crypto.c | 9 --------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 48727bb9..3ba0e9ea 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -1,17 +1,17 @@ #include "skycoin_crypto.h" #include +#include //sprintf #include "sha2.h" #include "bip32.h" #include "curves.h" #include "ripemd160.h" #include "base58.h" - #include "ecdsa.h" extern void bn_print(const bignum256 *a); -void create_node(const char* seed_str, HDNode* node); +static void create_node(const char* seed_str, HDNode* node); void create_node(const char* seed_str, HDNode* node) { @@ -20,6 +20,16 @@ void create_node(const char* seed_str, HDNode* node) hdnode_fill_public_key(node); } +void tohex(char * str, const uint8_t* buffer, int bufferLength) +{ + int i; + for (i = 0; i < bufferLength; ++i) + { + sprintf(&str[2*i], "%02x", buffer[i]); + } +} + + void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey) { char seed_str[256] = "dummy seed"; diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 3e3a9f90..e1e13ce4 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -15,5 +15,5 @@ void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, s void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_private_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, uint8_t* pubkey); - +void tohex(char * str, const uint8_t* buffer, int bufferLength); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 34cfceee..0ae08578 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -8,15 +8,6 @@ #define FROMHEX_MAXLEN 512 -void tohex(char * str, const uint8_t* buffer, int bufferLength) -{ - int i; - for (i = 0; i < bufferLength; ++i) - { - sprintf(&str[2*i], "%02x", buffer[i]); - } -} - const uint8_t *fromhex(const char *str) { static uint8_t buf[FROMHEX_MAXLEN]; From b5ebbd4d176833535883ce85077a6a396dfd94cb Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 21 Mar 2018 18:06:54 +0800 Subject: [PATCH 34/73] Readme file --- hardware-wallet/README.md | 133 ++++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 14 deletions(-) diff --git a/hardware-wallet/README.md b/hardware-wallet/README.md index 452fb710..e073b049 100644 --- a/hardware-wallet/README.md +++ b/hardware-wallet/README.md @@ -1,7 +1,113 @@ -Tools to imitate the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher). +Even though this repo is pushed here it is (for now) intended to be a submodule of [trezor-mcu repository](https://github.com/trezor/trezor-mcu). +Trezor-mcu contains firmware and bootloader code example for STM32 hardware. -# Compilation +This code aims at tranforming the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher) into firmware for the STM32 hardware. + + +# How to compile for firmware + +## 1. Clone trezor-mcu from this github account + + git clone https://github.com/mpsido/trezor-skycoin.git + cd trezor-skycoin + +You should be on a branch called skycoin + +## 2. Prepare environment + +#### Download GNU ARM Embedded Toolchain + + wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 + +#### Extract crosscompiler and add it to your path + + tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 + export PATH="gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH" + +## 3. Compile the sources + +The steps are the following, you can create a make_firmware.sh file with this content. + + #this option is important, it prevents the bootloader from locking the firmware in case its signature is wrong + export MEMORY_PROTECT=0 + make -C vendor/libopencm3/ + make -C vendor/nanopb/generator/proto/ + make -C firmware/protob/ + make -C vendor/skycoin-crypto/ + make + #Merge the bootloader and the firmware into one file + make -C bootloader/ align + make -C firmware/ sign + cp bootloader/bootloader.bin bootloader/combine/bl.bin + cp firmware/trezor.bin bootloader/combine/fw.bin + pushd bootloader/combine/ && ./prepare.py + popd; + +The output binary file is combined.bin located in bootloader/combine + + +# How to burn the firmware in the device + +## 1. Install ST-LINK + +Follow the steps [here](https://github.com/texane/stlink/blob/master/doc/compiling.md). + +## 2. Use ST-LINK to burn the device + +You can check the device is seen by your ST-LINK using this command: + + st-info --probe + +To flash the device on a microcontroller of STM32f2xx family the command is: + + st-flash write combined.bin 0x08000000; + +# Communicate with the device using the command line + +## 1. Download the python-trezor repository + + cd .. + git clone https://github.com/mpsido/python-trezor.git + cd python-trezor + +## 2. Install dependencies + +You need superuser priviledges for this step. + + sudo apt-get -y install python-dev cython libusb-1.0-0-dev libudev-dev (note: required for python-trezor testing) + +## 3. Configure your usb module + +We need to tell your kernel to use the [hidraw module](https://www.kernel.org/doc/Documentation/hid/hidraw.txt) to communicate with the hardware device. If you don't your kernel will treat the device as a mouse or a keyboard. + +Create a file named 99-dev-kit.rules in your /etc/udev/rules.d/ folder and write this content in that file (super user priviledges are required for this step). + + # 0483:df11 STMicroelectronics STM Device in DFU Mode + SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", MODE="0666" + # 0483:3748 STMicroelectronics ST-LINK/V2 + SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", MODE="0666" + # 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) + SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374b", MODE="0666" + # 534c:0001 SatoshiLabs Bitcoin Wallet [TREZOR] + SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0666" + KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0666" + # 1209:53c0 SatoshiLabs TREZOR v2 Bootloader + SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c0", MODE="0666" + KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c0", MODE="0666" + # 1209:53c1 SatoshiLabs TREZOR v2 + SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c1", MODE="0666" + KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", MODE="0666" + +Restart your machine or force your udev kernel module to [reload the rules](https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot). + +If when you plug the device your OS is not seeing the device, skip the warning on device's screen saying that the signature is wrong and then try [this](https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line). + +## 4. Generate a skycoin address from seed + + ./trezorctl skycoin_address seed + +# How to compile and run tests ## Trezor-crypto @@ -14,7 +120,17 @@ Download the repository Then setup the TREZOR_CRYPTO_PATH environment variable: export TREZOR_CRYPTO_PATH=$PWD/trezor-crypto + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TREZOR_CRYPTO_PATH + + +The dependancy libTrezorCrypto.a can be recompiled from sources. +Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" + +Then run : + + make + ar rcs libTrezorCrypto.a $(find -name "*.o") ## Check @@ -26,20 +142,9 @@ Download the repository Then setup the TREZOR_CRYPTO_PATH environment variable: export CHECK_PATH=$PWD/check + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CHECK_PATH ## Make and run ! make ./test_skycoin_crypto - - -# Self compile libTrezorCrypto.a - -The dependancy libTrezorCrypto.a can be recompiled from sources. - -Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" - -Then run : - - make - ar rcs libTrezorCrypto.a $(find -name "*.o") From 45b3ebbc8f45b8799e789a0a171ca34945c77915 Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 22 Mar 2018 11:01:41 +0800 Subject: [PATCH 35/73] Renaming function generate_bitcoin_private_address_from_pubkey to generate_bitcoin_private_address_from_seckey, because that is what it does --- hardware-wallet/skycoin_crypto.c | 2 +- hardware-wallet/skycoin_crypto.h | 2 +- hardware-wallet/test_skycoin_crypto.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 3ba0e9ea..0b62d5b4 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -142,7 +142,7 @@ void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, } -void generate_bitcoin_private_address_from_pubkey(const uint8_t* seckey, char* address, size_t *size_address) +void generate_bitcoin_private_address_from_seckey(const uint8_t* seckey, char* address, size_t *size_address) { uint8_t b2[38] = {0}; uint8_t h1[SHA256_DIGEST_LENGTH] = {0}; diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index e1e13ce4..4473624e 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -13,7 +13,7 @@ void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); -void generate_bitcoin_private_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); +void generate_bitcoin_private_address_from_seckey(const uint8_t* pubkey, char* address, size_t *size_address); int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, uint8_t* pubkey); void tohex(char * str, const uint8_t* buffer, int bufferLength); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 0ae08578..a5c51998 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -140,15 +140,15 @@ START_TEST(test_bitcoin_private_address_from_pubkey) char address[256] = {0}; size_t size_address = sizeof(address); memcpy(seckey, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); - generate_bitcoin_private_address_from_pubkey(seckey, address, &size_address); + generate_bitcoin_private_address_from_seckey(seckey, address, &size_address); ck_assert_str_eq(address, "KwDuvkABDqb4WQiwc92DpXtBBiEywuKv46ZUvz5Gi5Xyn9gbcTJt"); memcpy(seckey, fromhex("ff671860c58aad3f765d8add25046412dabf641186472e1553435e6e3c4a6fb0"), 32); - generate_bitcoin_private_address_from_pubkey(seckey, address, &size_address); + generate_bitcoin_private_address_from_seckey(seckey, address, &size_address); ck_assert_str_eq(address, "L5nBR59QkW6kyXFvyqNbncWo2jPMoBXSH9fGUkh3n2RQn5Mj3vfY"); memcpy(seckey, fromhex("84fdc649964bf299a787cb78cd975910e197dbddd7db776ece544f41c44b3056"), 32); - generate_bitcoin_private_address_from_pubkey(seckey, address, &size_address); + generate_bitcoin_private_address_from_seckey(seckey, address, &size_address); ck_assert_str_eq(address, "L1gEDGuLTpMjybHnsJ24bUHhueocDrrKVdM3rj1rqXFHfyM2WtwD"); } END_TEST From 9519675237a0f4212f9c058eeba015fb14b44610 Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 22 Mar 2018 11:01:41 +0800 Subject: [PATCH 36/73] Renaming function generate_bitcoin_private_address_from_pubkey to generate_bitcoin_private_address_from_seckey, because that is what it does --- hardware-wallet/test_skycoin_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index a5c51998..c0b4b5f0 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -134,7 +134,7 @@ START_TEST(test_bitcoin_address_from_pubkey) END_TEST -START_TEST(test_bitcoin_private_address_from_pubkey) +START_TEST(test_bitcoin_private_address_from_seckey) { uint8_t seckey[32] = {0}; char address[256] = {0}; @@ -310,7 +310,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_generate_deterministic_key_pair_iterator); tcase_add_test(tc, test_base58_address_from_pubkey); tcase_add_test(tc, test_bitcoin_address_from_pubkey); - tcase_add_test(tc, test_bitcoin_private_address_from_pubkey); + tcase_add_test(tc, test_bitcoin_private_address_from_seckey); tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); tcase_add_test(tc, test_recover_pubkey_from_signed_message); From ddd00c649977068fbc218798f19e8b342bc0453e Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 23 Mar 2018 16:04:55 +0800 Subject: [PATCH 37/73] Reading base58 inputs --- hardware-wallet/test_skycoin_crypto.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index c0b4b5f0..daa2bba6 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -5,6 +5,7 @@ #include "check.h" #include "sha2.h" //SHA256_DIGEST_LENGTH +#include "base58.h" #define FROMHEX_MAXLEN 512 @@ -24,6 +25,26 @@ const uint8_t *fromhex(const char *str) return buf; } +START_TEST(test_base58_decode) +{ + uint8_t addrhex[25] = {0}; + uint8_t signhex[65] = {0}; + char address[36] = "2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"; + char signature[90] = "GA82nXSwVEPV5soMjCiQkJb4oLEAo6FMK8CAE2n2YBTm7xjhAknUxtZrhs3RPVMfQsEoLwkJCEgvGj8a2vzthBQ1M"; + + size_t sz = sizeof(signhex); + b58tobin(signhex, &sz, signature); + ck_assert_int_eq(sz, 65); + ck_assert_mem_eq(signhex , fromhex("abc30130e2d9561fa8eb9871b75b13100689937dfc41c98d611b985ca25258c960be25c0b45874e1255f053863f6e175300d7e788d8b93d6dcfa9377120e4d3500"), sz); + + sz = sizeof(addrhex); + b58tobin(addrhex, &sz, address); + ck_assert_int_eq(sz, 25); + ck_assert_mem_eq(addrhex , fromhex("b1aa8dd3e68d1d9b130c67ea1339ac9250b7d845002437a5a0"), sz); + +} +END_TEST + START_TEST(test_generate_public_key_from_seckey) { uint8_t seckey[32] = {0}; @@ -314,6 +335,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_compute_sha256sum); tcase_add_test(tc, test_compute_ecdh); tcase_add_test(tc, test_recover_pubkey_from_signed_message); + tcase_add_test(tc, test_base58_decode); suite_add_tcase(s, tc); return s; From 83f4632d547d548dcc4371243464b7211c25de18 Mon Sep 17 00:00:00 2001 From: mpsido Date: Mon, 26 Mar 2018 14:25:28 +0800 Subject: [PATCH 38/73] pass message as const pointer to recover_pubkey_from_signed_message function --- hardware-wallet/skycoin_crypto.c | 2 +- hardware-wallet/skycoin_crypto.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 0b62d5b4..06565867 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -226,7 +226,7 @@ int verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint message 32 bytes, pubkey 33 bytes returns 0 if signature matches and 5 if it does not*/ -int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, uint8_t* pubkey) +int recover_pubkey_from_signed_message(const char* message, const uint8_t* signature, uint8_t* pubkey) { int res = -1; HDNode dummy_node; diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 4473624e..e16ec7cd 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -14,6 +14,6 @@ void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_leng void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_private_address_from_seckey(const uint8_t* pubkey, char* address, size_t *size_address); -int recover_pubkey_from_signed_message(char* message, const uint8_t* signature, uint8_t* pubkey); +int recover_pubkey_from_signed_message(const char* message, const uint8_t* signature, uint8_t* pubkey); void tohex(char * str, const uint8_t* buffer, int bufferLength); #endif From 60b1c36bb84dc23e1717df1da88d4565a345342f Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 6 Apr 2018 13:25:29 +0900 Subject: [PATCH 39/73] Creating API to communicate with trezor device --- .../protob/messages.options | 208 ++ .../protob/messages.proto | 1073 ++++++ .../protob/types.options | 74 + go-api-for-hardware-wallet/protob/types.proto | 446 +++ go-api-for-hardware-wallet/trezor.go | 69 + go-api-for-hardware-wallet/usb/bus.go | 71 + go-api-for-hardware-wallet/usb/hidapi.go | 140 + go-api-for-hardware-wallet/usb/udp.go | 174 + go-api-for-hardware-wallet/usb/webusb.go | 227 ++ go-api-for-hardware-wallet/usbhid/.gitignore | 1 + go-api-for-hardware-wallet/usbhid/.travis.yml | 28 + go-api-for-hardware-wallet/usbhid/README.md | 17 + .../usbhid/c/hidapi/AUTHORS.txt | 16 + .../usbhid/c/hidapi/LICENSE-bsd.txt | 26 + .../usbhid/c/hidapi/LICENSE-gpl3.txt | 674 ++++ .../usbhid/c/hidapi/LICENSE-orig.txt | 9 + .../usbhid/c/hidapi/LICENSE.txt | 13 + .../usbhid/c/hidapi/README.txt | 339 ++ .../usbhid/c/hidapi/hidapi/hidapi.h | 391 ++ .../usbhid/c/hidapi/linux/hid.c | 1520 ++++++++ .../usbhid/c/hidapi/mac/hid.c | 1110 ++++++ .../usbhid/c/hidapi/windows/hid.c | 944 +++++ .../usbhid/c/libusb/AUTHORS | 89 + .../usbhid/c/libusb/COPYING | 504 +++ .../usbhid/c/libusb/config.h | 3 + .../usbhid/c/libusb/core.c | 2523 +++++++++++++ .../usbhid/c/libusb/descriptor.c | 1191 ++++++ .../usbhid/c/libusb/hotplug.c | 350 ++ .../usbhid/c/libusb/hotplug.h | 90 + .../usbhid/c/libusb/io.c | 2819 +++++++++++++++ .../usbhid/c/libusb/libusb.h | 2008 +++++++++++ .../usbhid/c/libusb/libusbi.h | 1149 ++++++ .../usbhid/c/libusb/os/darwin_usb.c | 2094 +++++++++++ .../usbhid/c/libusb/os/darwin_usb.h | 164 + .../usbhid/c/libusb/os/haiku_pollfs.cpp | 367 ++ .../usbhid/c/libusb/os/haiku_usb.h | 112 + .../usbhid/c/libusb/os/haiku_usb_backend.cpp | 517 +++ .../usbhid/c/libusb/os/haiku_usb_raw.cpp | 250 ++ .../usbhid/c/libusb/os/haiku_usb_raw.h | 180 + .../usbhid/c/libusb/os/linux_netlink.c | 400 +++ .../usbhid/c/libusb/os/linux_udev.c | 311 ++ .../usbhid/c/libusb/os/linux_usbfs.c | 2738 ++++++++++++++ .../usbhid/c/libusb/os/linux_usbfs.h | 193 + .../usbhid/c/libusb/os/netbsd_usb.c | 677 ++++ .../usbhid/c/libusb/os/openbsd_usb.c | 771 ++++ .../usbhid/c/libusb/os/poll_posix.c | 53 + .../usbhid/c/libusb/os/poll_posix.h | 11 + .../usbhid/c/libusb/os/poll_windows.c | 728 ++++ .../usbhid/c/libusb/os/poll_windows.h | 131 + .../usbhid/c/libusb/os/sunos_usb.c | 1292 +++++++ .../usbhid/c/libusb/os/sunos_usb.h | 74 + .../usbhid/c/libusb/os/threads_posix.c | 79 + .../usbhid/c/libusb/os/threads_posix.h | 55 + .../usbhid/c/libusb/os/threads_windows.c | 268 ++ .../usbhid/c/libusb/os/threads_windows.h | 76 + .../usbhid/c/libusb/os/wince_usb.c | 899 +++++ .../usbhid/c/libusb/os/wince_usb.h | 126 + .../usbhid/c/libusb/os/windows_common.h | 124 + .../usbhid/c/libusb/os/windows_nt_common.c | 591 +++ .../usbhid/c/libusb/os/windows_nt_common.h | 63 + .../usbhid/c/libusb/os/windows_usbdk.c | 905 +++++ .../usbhid/c/libusb/os/windows_usbdk.h | 146 + .../usbhid/c/libusb/os/windows_winusb.c | 3182 +++++++++++++++++ .../usbhid/c/libusb/os/windows_winusb.h | 833 +++++ .../usbhid/c/libusb/strerror.c | 202 ++ .../usbhid/c/libusb/sync.c | 327 ++ .../usbhid/c/libusb/version.h | 18 + .../usbhid/c/libusb/version_nano.h | 1 + go-api-for-hardware-wallet/usbhid/hid.go | 270 ++ go-api-for-hardware-wallet/usbhid/libusb.go | 1361 +++++++ go-api-for-hardware-wallet/usbhid/wchar.go | 227 ++ 71 files changed, 39112 insertions(+) create mode 100644 go-api-for-hardware-wallet/protob/messages.options create mode 100644 go-api-for-hardware-wallet/protob/messages.proto create mode 100644 go-api-for-hardware-wallet/protob/types.options create mode 100644 go-api-for-hardware-wallet/protob/types.proto create mode 100644 go-api-for-hardware-wallet/trezor.go create mode 100644 go-api-for-hardware-wallet/usb/bus.go create mode 100644 go-api-for-hardware-wallet/usb/hidapi.go create mode 100644 go-api-for-hardware-wallet/usb/udp.go create mode 100644 go-api-for-hardware-wallet/usb/webusb.go create mode 100644 go-api-for-hardware-wallet/usbhid/.gitignore create mode 100644 go-api-for-hardware-wallet/usbhid/.travis.yml create mode 100644 go-api-for-hardware-wallet/usbhid/README.md create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/AUTHORS.txt create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-bsd.txt create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-gpl3.txt create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-orig.txt create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE.txt create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/README.txt create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/hidapi/hidapi.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/linux/hid.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/hidapi/mac/hid.c create mode 100755 go-api-for-hardware-wallet/usbhid/c/hidapi/windows/hid.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/AUTHORS create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/COPYING create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/config.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/core.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/descriptor.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/io.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/libusb.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/libusbi.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_pollfs.cpp create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_backend.cpp create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.cpp create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_netlink.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_udev.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/netbsd_usb.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/openbsd_usb.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_common.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/strerror.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/sync.c create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/version.h create mode 100644 go-api-for-hardware-wallet/usbhid/c/libusb/version_nano.h create mode 100644 go-api-for-hardware-wallet/usbhid/hid.go create mode 100644 go-api-for-hardware-wallet/usbhid/libusb.go create mode 100644 go-api-for-hardware-wallet/usbhid/wchar.go diff --git a/go-api-for-hardware-wallet/protob/messages.options b/go-api-for-hardware-wallet/protob/messages.options new file mode 100644 index 00000000..687d5c50 --- /dev/null +++ b/go-api-for-hardware-wallet/protob/messages.options @@ -0,0 +1,208 @@ +Initialize.state max_size:64 + +Features.vendor max_size:33 +Features.device_id max_size:25 +Features.language max_size:17 +Features.label max_size:33 +Features.coins max_count:16 +Features.revision max_size:20 +Features.bootloader_hash max_size:32 +Features.model max_size:17 +Features.fw_vendor max_size:256 +Features.fw_vendor_keys max_size:32 + +ApplySettings.language max_size:17 +ApplySettings.label max_size:33 +ApplySettings.homescreen max_size:1024 + +Ping.message max_size:256 + +SkycoinAddress.seed max_size:256 +SkycoinCheckMessageSignature.address max_size:36 +SkycoinCheckMessageSignature.message max_size:256 +SkycoinCheckMessageSignature.signature max_size:90 + +Success.message max_size:256 + +Failure.message max_size:256 + +ButtonRequest.data max_size:256 + +PinMatrixAck.pin max_size:10 + +PassphraseAck.passphrase max_size:51 +PassphraseAck.state max_size:64 + +PassphraseStateRequest.state max_size:64 + +Entropy.entropy max_size:1024 + +GetPublicKey.address_n max_count:8 +GetPublicKey.ecdsa_curve_name max_size:32 +GetPublicKey.coin_name max_size:21 + +PublicKey.xpub max_size:113 + +GetAddress.address_n max_count:8 +GetAddress.coin_name max_size:21 + +Address.address max_size:76 + +EthereumGetAddress.address_n max_count:8 +EthereumAddress.address max_size:20 + +LoadDevice.mnemonic max_size:241 +LoadDevice.pin max_size:10 +LoadDevice.language max_size:17 +LoadDevice.label max_size:33 + +ResetDevice.language max_size:17 +ResetDevice.label max_size:33 + +EntropyAck.entropy max_size:128 + +RecoveryDevice.language max_size:17 +RecoveryDevice.label max_size:33 + +WordAck.word max_size:12 + +SignMessage.address_n max_count:8 +SignMessage.message max_size:1024 +SignMessage.coin_name max_size:21 + +VerifyMessage.address max_size:76 +VerifyMessage.signature max_size:65 +VerifyMessage.message max_size:1024 +VerifyMessage.coin_name max_size:21 + +MessageSignature.address max_size:76 +MessageSignature.signature max_size:65 + +EthereumSignMessage.address_n max_count:8 +EthereumSignMessage.message max_size:1024 + +EthereumVerifyMessage.address max_size:20 +EthereumVerifyMessage.signature max_size:65 +EthereumVerifyMessage.message max_size:1024 + +EthereumMessageSignature.address max_size:20 +EthereumMessageSignature.signature max_size:65 + +# deprecated +EncryptMessage skip_message:true +# EncryptMessage.pubkey max_size:33 +# EncryptMessage.message max_size:1024 +# EncryptMessage.address_n max_count:8 +# EncryptMessage.coin_name max_size:21 + +# deprecated +EncryptedMessage skip_message:true +# EncryptedMessage.nonce max_size:33 +# EncryptedMessage.message max_size:1120 +# EncryptedMessage.hmac max_size:8 + +# deprecated +DecryptMessage skip_message:true +# DecryptMessage.address_n max_count:8 +# DecryptMessage.nonce max_size:33 +# DecryptMessage.message max_size:1120 # 1 + 9 + 1024 + 21 + 65 +# DecryptMessage.hmac max_size:8 + +# deprecated +DecryptedMessage skip_message:true +# DecryptedMessage.address max_size:76 +# DecryptedMessage.message max_size:1024 + +CipherKeyValue.address_n max_count:8 +CipherKeyValue.key max_size:256 +CipherKeyValue.value max_size:1024 +CipherKeyValue.iv max_size:16 + +CipheredKeyValue.value max_size:1024 + +# deprecated +EstimateTxSize skip_message:true +# EstimateTxSize.coin_name max_size:21 + +# deprecated +TxSize skip_message:true + +SignTx.coin_name max_size:21 + +EthereumSignTx.address_n max_count:8 +EthereumSignTx.nonce max_size:32 +EthereumSignTx.gas_price max_size:32 +EthereumSignTx.gas_limit max_size:32 +EthereumSignTx.to max_size:20 +EthereumSignTx.value max_size:32 +EthereumSignTx.data_initial_chunk max_size:1024 + +EthereumTxRequest.signature_r max_size:32 +EthereumTxRequest.signature_s max_size:32 + +EthereumTxAck.data_chunk max_size:1024 + +SignIdentity.challenge_hidden max_size:256 +SignIdentity.challenge_visual max_size:256 +SignIdentity.ecdsa_curve_name max_size:32 + +SignedIdentity.address max_size:76 +SignedIdentity.public_key max_size:33 +SignedIdentity.signature max_size:65 + +GetECDHSessionKey.peer_public_key max_size:65 +GetECDHSessionKey.ecdsa_curve_name max_size:32 + +ECDHSessionKey.session_key max_size:65 + +NEMGetAddress.address_n max_count:8 + +NEMAddress.address max_size:41 + +NEMSignedTx.data max_size:2048 +NEMSignedTx.signature max_size:64 + +NEMDecryptMessage.address_n max_count:8 +NEMDecryptMessage.public_key max_size:32 +NEMDecryptMessage.payload max_size:1072 + +NEMDecryptedMessage.payload max_size:1024 + +CosiCommit.address_n max_count:8 +CosiCommit.data max_size:32 + +CosiCommitment.commitment max_size:32 +CosiCommitment.pubkey max_size:32 + +CosiSign.address_n max_count:8 +CosiSign.data max_size:32 +CosiSign.global_commitment max_size:32 +CosiSign.global_pubkey max_size:32 + +CosiSignature.signature max_size:32 + +# deprecated +SimpleSignTx skip_message:true + +# not used in firmware, just in bootloader + +FirmwareErase skip_message:true +FirmwareRequest skip_message:true +FirmwareUpload skip_message:true +SelfTest skip_message:true + +# used only in debug firmware + +DebugLinkState.layout max_size:1024 +DebugLinkState.pin max_size:10 +DebugLinkState.matrix max_size:10 +DebugLinkState.mnemonic max_size:241 +DebugLinkState.reset_word max_size:12 +DebugLinkState.reset_entropy max_size:128 +DebugLinkState.recovery_fake_word max_size:12 + +DebugLinkLog.bucket max_size:33 +DebugLinkLog.text max_size:256 + +DebugLinkMemory.memory max_size:1024 +DebugLinkMemoryWrite.memory max_size:1024 diff --git a/go-api-for-hardware-wallet/protob/messages.proto b/go-api-for-hardware-wallet/protob/messages.proto new file mode 100644 index 00000000..2768282f --- /dev/null +++ b/go-api-for-hardware-wallet/protob/messages.proto @@ -0,0 +1,1073 @@ +syntax = "proto2"; + +/** + * Messages for TREZOR communication + */ + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessage"; + +import "types.proto"; + +/** + * Mapping between Trezor wire identifier (uint) and a protobuf message + */ +enum MessageType { + MessageType_Initialize = 0 [(wire_in) = true]; + MessageType_Ping = 1 [(wire_in) = true]; + MessageType_Success = 2 [(wire_out) = true]; + MessageType_Failure = 3 [(wire_out) = true]; + MessageType_ChangePin = 4 [(wire_in) = true]; + MessageType_WipeDevice = 5 [(wire_in) = true]; + MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true]; + MessageType_GetEntropy = 9 [(wire_in) = true]; + MessageType_Entropy = 10 [(wire_out) = true]; + MessageType_GetPublicKey = 11 [(wire_in) = true]; + MessageType_PublicKey = 12 [(wire_out) = true]; + MessageType_LoadDevice = 13 [(wire_in) = true]; + MessageType_ResetDevice = 14 [(wire_in) = true]; + MessageType_SignTx = 15 [(wire_in) = true]; + MessageType_SimpleSignTx = 16 [(wire_in) = true, deprecated = true]; + MessageType_Features = 17 [(wire_out) = true]; + MessageType_PinMatrixRequest = 18 [(wire_out) = true]; + MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true]; + MessageType_Cancel = 20 [(wire_in) = true]; + MessageType_TxRequest = 21 [(wire_out) = true]; + MessageType_TxAck = 22 [(wire_in) = true]; + MessageType_CipherKeyValue = 23 [(wire_in) = true]; + MessageType_ClearSession = 24 [(wire_in) = true]; + MessageType_ApplySettings = 25 [(wire_in) = true]; + MessageType_ButtonRequest = 26 [(wire_out) = true]; + MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true]; + MessageType_ApplyFlags = 28 [(wire_in) = true]; + MessageType_GetAddress = 29 [(wire_in) = true]; + MessageType_Address = 30 [(wire_out) = true]; + MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_BackupDevice = 34 [(wire_in) = true]; + MessageType_EntropyRequest = 35 [(wire_out) = true]; + MessageType_EntropyAck = 36 [(wire_in) = true]; + MessageType_SignMessage = 38 [(wire_in) = true]; + MessageType_VerifyMessage = 39 [(wire_in) = true]; + MessageType_MessageSignature = 40 [(wire_out) = true]; + MessageType_PassphraseRequest = 41 [(wire_out) = true]; + MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true]; + MessageType_PassphraseStateRequest = 77 [(wire_out) = true]; + MessageType_PassphraseStateAck = 78 [(wire_in) = true, (wire_tiny) = true]; + MessageType_EstimateTxSize = 43 [(wire_in) = true, deprecated = true]; + MessageType_TxSize = 44 [(wire_out) = true, deprecated = true]; + MessageType_RecoveryDevice = 45 [(wire_in) = true]; + MessageType_WordRequest = 46 [(wire_out) = true]; + MessageType_WordAck = 47 [(wire_in) = true]; + MessageType_CipheredKeyValue = 48 [(wire_out) = true]; + MessageType_EncryptMessage = 49 [(wire_in) = true, deprecated = true]; + MessageType_EncryptedMessage = 50 [(wire_out) = true, deprecated = true]; + MessageType_DecryptMessage = 51 [(wire_in) = true, deprecated = true]; + MessageType_DecryptedMessage = 52 [(wire_out) = true, deprecated = true]; + MessageType_SignIdentity = 53 [(wire_in) = true]; + MessageType_SignedIdentity = 54 [(wire_out) = true]; + MessageType_GetFeatures = 55 [(wire_in) = true]; + MessageType_EthereumGetAddress = 56 [(wire_in) = true]; + MessageType_EthereumAddress = 57 [(wire_out) = true]; + MessageType_EthereumSignTx = 58 [(wire_in) = true]; + MessageType_EthereumTxRequest = 59 [(wire_out) = true]; + MessageType_EthereumTxAck = 60 [(wire_in) = true]; + MessageType_GetECDHSessionKey = 61 [(wire_in) = true]; + MessageType_ECDHSessionKey = 62 [(wire_out) = true]; + MessageType_SetU2FCounter = 63 [(wire_in) = true]; + MessageType_EthereumSignMessage = 64 [(wire_in) = true]; + MessageType_EthereumVerifyMessage = 65 [(wire_in) = true]; + MessageType_EthereumMessageSignature = 66 [(wire_out) = true]; + MessageType_NEMGetAddress = 67 [(wire_in) = true]; + MessageType_NEMAddress = 68 [(wire_out) = true]; + MessageType_NEMSignTx = 69 [(wire_in) = true]; + MessageType_NEMSignedTx = 70 [(wire_out) = true]; + MessageType_CosiCommit = 71 [(wire_in) = true]; + MessageType_CosiCommitment = 72 [(wire_out) = true]; + MessageType_CosiSign = 73 [(wire_in) = true]; + MessageType_CosiSignature = 74 [(wire_out) = true]; + MessageType_NEMDecryptMessage = 75 [(wire_in) = true]; + MessageType_NEMDecryptedMessage = 76 [(wire_out) = true]; + MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true]; + MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true]; + MessageType_DebugLinkState = 102 [(wire_debug_out) = true]; + MessageType_DebugLinkStop = 103 [(wire_debug_in) = true]; + MessageType_DebugLinkLog = 104 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true]; + MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; + MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; + MessageType_SkycoinAddress = 114 [(wire_in) = true]; + MessageType_SkycoinCheckMessageSignature = 115 [(wire_in) = true]; +} + +//////////////////// +// Basic messages // +//////////////////// + +/** + * Request: Reset device to default state and ask for device details + * @next Features + */ +message Initialize { + optional bytes state = 1; // assumed device state, clear session if set and different +} + +/** + * Request: Ask for device details (no device reset) + * @next Features + */ +message GetFeatures { +} + +/** + * Response: Reports various information about the device + * @prev Initialize + * @prev GetFeatures + */ +message Features { + optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" + optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 + optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 + optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 + optional bool bootloader_mode = 5; // is device in bootloader mode? + optional string device_id = 6; // device's unique identifier + optional bool pin_protection = 7; // is device protected by PIN? + optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? + optional string language = 9; // device language + optional string label = 10; // device description label + repeated CoinType coins = 11; // supported coins + optional bool initialized = 12; // does device contain seed? + optional bytes revision = 13; // SCM revision of firmware + optional bytes bootloader_hash = 14; // hash of the bootloader + optional bool imported = 15; // was storage imported from an external source? + optional bool pin_cached = 16; // is PIN already cached in session? + optional bool passphrase_cached = 17; // is passphrase already cached in session? + optional bool firmware_present = 18; // is valid firmware loaded? + optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) + optional uint32 flags = 20; // device flags (equals to Storage.flags) + optional string model = 21; // device hardware model + optional uint32 fw_major = 22; // reported firmware version if in bootloader mode + optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode + optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode + optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode + optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash) +} + +/** + * Request: clear session (removes cached PIN, passphrase, etc). + * @next Success + */ +message ClearSession { +} + +/** + * Request: change language and/or label of the device + * @next Success + * @next Failure + * @next ButtonRequest + * @next PinMatrixRequest + */ +message ApplySettings { + optional string language = 1; + optional string label = 2; + optional bool use_passphrase = 3; + optional bytes homescreen = 4; +} + +/** + * Request: set flags of the device + * @next Success + * @next Failure + */ +message ApplyFlags { + optional uint32 flags = 1; // bitmask, can only set bits, not unset +} + +/** + * Request: Starts workflow for setting/changing/removing the PIN + * @next ButtonRequest + * @next PinMatrixRequest + */ +message ChangePin { + optional bool remove = 1; // is PIN removal requested? +} + +/** + * Request: Generate a Skycoin or a Bitcoin address from a seed, device sends back the address in a Success message + * @next Success + */ +message SkycoinAddress { + required string seed = 1; // seed used to generate address + optional SkycoinAddressType address_type = 2; +} + + +/** + * Request: Check a message signature matches the given address. + * @next Success + */ +message SkycoinCheckMessageSignature { + required string address = 1; //address that was supposedly used to produce the signature + required string message = 2; //message that was signed + required string signature = 3; //electronic signature of the message +} + +/** + * Request: Test if the device is alive, device sends back the message in Success response + * @next Success + */ +message Ping { + optional string message = 1; // message to send back in Success message + optional bool button_protection = 2; // ask for button press + optional bool pin_protection = 3; // ask for PIN if set in device + optional bool passphrase_protection = 4; // ask for passphrase if set in device +} + +/** + * Response: Success of the previous request + */ +message Success { + optional string message = 1; // human readable description of action or request-specific payload +} + +/** + * Response: Failure of the previous request + */ +message Failure { + optional FailureType code = 1; // computer-readable definition of the error state + optional string message = 2; // human-readable message of the error state +} + +/** + * Response: Device is waiting for HW button press. + * @next ButtonAck + * @next Cancel + */ +message ButtonRequest { + optional ButtonRequestType code = 1; + optional string data = 2; +} + +/** + * Request: Computer agrees to wait for HW button press + * @prev ButtonRequest + */ +message ButtonAck { +} + +/** + * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme + * @next PinMatrixAck + * @next Cancel + */ +message PinMatrixRequest { + optional PinMatrixRequestType type = 1; +} + +/** + * Request: Computer responds with encoded PIN + * @prev PinMatrixRequest + */ +message PinMatrixAck { + required string pin = 1; // matrix encoded PIN entered by user +} + +/** + * Request: Abort last operation that required user interaction + * @prev ButtonRequest + * @prev PinMatrixRequest + * @prev PassphraseRequest + */ +message Cancel { +} + +/** + * Response: Device awaits encryption passphrase + * @next PassphraseAck + * @next Cancel + */ +message PassphraseRequest { + optional bool on_device = 1; // passphrase is being entered on the device +} + +/** + * Request: Send passphrase back + * @prev PassphraseRequest + * @next PassphraseStateRequest + */ +message PassphraseAck { + optional string passphrase = 1; + optional bytes state = 2; // expected device state +} + +/** + * @prev PassphraseAck + * @next PassphraseStateAck + */ +message PassphraseStateRequest { + optional bytes state = 1; // actual device state +} + +/** + * @prev PassphraseStateRequest + */ +message PassphraseStateAck { +} + +/** + * Request: Request a sample of random data generated by hardware RNG. May be used for testing. + * @next ButtonRequest + * @next Entropy + * @next Failure + */ +message GetEntropy { + required uint32 size = 1; // size of requested entropy +} + +/** + * Response: Reply with random data generated by internal RNG + * @prev GetEntropy + */ +message Entropy { + required bytes entropy = 1; // stream of random generated bytes +} + +/** + * Request: Ask device for public key corresponding to address_n path + * @next PassphraseRequest + * @next PublicKey + * @next Failure + */ +message GetPublicKey { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string ecdsa_curve_name = 2; // ECDSA curve name to use + optional bool show_display = 3; // optionally show on display before sending the result + optional string coin_name = 4 [default='Bitcoin']; +} + +/** + * Response: Contains public key derived from device private seed + * @prev GetPublicKey + */ +message PublicKey { + required HDNodeType node = 1; // BIP32 public node + optional string xpub = 2; // serialized form of public node +} + +/** + * Request: Ask device for address corresponding to address_n path + * @next PassphraseRequest + * @next Address + * @next Failure + */ +message GetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Bitcoin']; + optional bool show_display = 3 ; // optionally show on display before sending the result + optional MultisigRedeemScriptType multisig = 4; // filled if we are showing a multisig address + optional InputScriptType script_type = 5 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) +} + +/** + * Request: Ask device for Ethereum address corresponding to address_n path + * @next PassphraseRequest + * @next EthereumAddress + * @next Failure + */ +message EthereumGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // optionally show on display before sending the result +} + +/** + * Response: Contains address derived from device private seed + * @prev GetAddress + */ +message Address { + required string address = 1; // Coin address in Base58 encoding +} + +/** + * Response: Contains an Ethereum address derived from device private seed + * @prev EthereumGetAddress + */ +message EthereumAddress { + required bytes address = 1; // Coin address as an Ethereum 160 bit hash +} + +/** + * Request: Request device to wipe all sensitive data and settings + * @next ButtonRequest + */ +message WipeDevice { +} + +/** + * Request: Load seed and related internal settings from the computer + * @next ButtonRequest + * @next Success + * @next Failure + */ +message LoadDevice { + optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) + optional HDNodeType node = 2; // BIP-32 node + optional string pin = 3; // set PIN protection + optional bool passphrase_protection = 4; // enable master node encryption using passphrase + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum + optional uint32 u2f_counter = 8; // U2F counter +} + +/** + * Request: Ask device to do initialization involving user interaction + * @next EntropyRequest + * @next Failure + */ +message ResetDevice { + optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy + optional uint32 strength = 2 [default=256]; // strength of seed in bits + optional bool passphrase_protection = 3; // enable master node encryption using passphrase + optional bool pin_protection = 4; // enable PIN protection + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional uint32 u2f_counter = 7; // U2F counter + optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow +} + +/** + * Request: Perform backup of the device seed if not backed up using ResetDevice + * @next ButtonRequest + */ +message BackupDevice { +} + +/** + * Response: Ask for additional entropy from host computer + * @prev ResetDevice + * @next EntropyAck + */ +message EntropyRequest { +} + +/** + * Request: Provide additional entropy for seed generation function + * @prev EntropyRequest + * @next ButtonRequest + */ +message EntropyAck { + optional bytes entropy = 1; // 256 bits (32 bytes) of random data +} + +/** + * Request: Start recovery workflow asking user for specific words of mnemonic + * Used to recovery device safely even on untrusted computer. + * @next WordRequest + */ +message RecoveryDevice { + optional uint32 word_count = 1; // number of words in BIP-39 mnemonic + optional bool passphrase_protection = 2; // enable master node encryption using passphrase + optional bool pin_protection = 3; // enable PIN protection + optional string language = 4 [default='english']; // device language + optional string label = 5; // device label + optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process + // 7 reserved for unused recovery method + optional uint32 type = 8; // supported recovery type (see RecoveryType) + optional uint32 u2f_counter = 9; // U2F counter + optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) +} + +/** + * Response: Device is waiting for user to enter word of the mnemonic + * Its position is shown only on device's internal display. + * @prev RecoveryDevice + * @prev WordAck + */ +message WordRequest { + optional WordRequestType type = 1; +} + +/** + * Request: Computer replies with word from the mnemonic + * @prev WordRequest + * @next WordRequest + * @next Success + * @next Failure + */ +message WordAck { + required string word = 1; // one word of mnemonic on asked position +} + +////////////////////////////// +// Message signing messages // +////////////////////////////// + +/** + * Request: Ask device to sign message + * @next MessageSignature + * @next Failure + */ +message SignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + required bytes message = 2; // message to be signed + optional string coin_name = 3 [default='Bitcoin']; // coin to use for signing + optional InputScriptType script_type = 4 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) +} + +/** + * Request: Ask device to verify message + * @next Success + * @next Failure + */ +message VerifyMessage { + optional string address = 1; // address to verify + optional bytes signature = 2; // signature to verify + optional bytes message = 3; // message to verify + optional string coin_name = 4 [default='Bitcoin']; // coin to use for verifying +} + +/** + * Response: Signed message + * @prev SignMessage + */ +message MessageSignature { + optional string address = 1; // address used to sign the message + optional bytes signature = 2; // signature of the message +} + +/////////////////////////// +// Encryption/decryption // +/////////////////////////// + +/** + * Request: Ask device to encrypt message + * @next EncryptedMessage + * @next Failure + */ +message EncryptMessage { + optional bytes pubkey = 1; // public key + optional bytes message = 2; // message to encrypt + optional bool display_only = 3; // show just on display? (don't send back via wire) + repeated uint32 address_n = 4; // BIP-32 path to derive the signing key from master node + optional string coin_name = 5 [default='Bitcoin']; // coin to use for signing +} + +/** + * Response: Encrypted message + * @prev EncryptMessage + */ +message EncryptedMessage { + optional bytes nonce = 1; // nonce used during encryption + optional bytes message = 2; // encrypted message + optional bytes hmac = 3; // message hmac +} + +/** + * Request: Ask device to decrypt message + * @next Success + * @next Failure + */ +message DecryptMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the decryption key from master node + optional bytes nonce = 2; // nonce used during encryption + optional bytes message = 3; // message to decrypt + optional bytes hmac = 4; // message hmac +} + +/** + * Response: Decrypted message + * @prev DecryptedMessage + */ +message DecryptedMessage { + optional bytes message = 1; // decrypted message + optional string address = 2; // address used to sign the message (if used) +} + +/** + * Request: Ask device to encrypt or decrypt value of given key + * @next CipheredKeyValue + * @next Failure + */ +message CipherKeyValue { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string key = 2; // key component of key:value + optional bytes value = 3; // value component of key:value + optional bool encrypt = 4; // are we encrypting (True) or decrypting (False)? + optional bool ask_on_encrypt = 5; // should we ask on encrypt operation? + optional bool ask_on_decrypt = 6; // should we ask on decrypt operation? + optional bytes iv = 7; // initialization vector (will be computed if not set) +} + +/** + * Response: Return ciphered/deciphered value + * @prev CipherKeyValue + */ +message CipheredKeyValue { + optional bytes value = 1; // ciphered/deciphered value +} + +////////////////////////////////// +// Transaction signing messages // +////////////////////////////////// + +/** + * Request: Estimated size of the transaction + * This behaves exactly like SignTx, which means that it can ask using TxRequest + * This call is non-blocking (except possible PassphraseRequest to unlock the seed) + * @next TxSize + * @next Failure + */ +message EstimateTxSize { + required uint32 outputs_count = 1; // number of transaction outputs + required uint32 inputs_count = 2; // number of transaction inputs + optional string coin_name = 3 [default='Bitcoin']; // coin to use +} + +/** + * Response: Estimated size of the transaction + * @prev EstimateTxSize + */ +message TxSize { + optional uint32 tx_size = 1; // estimated size of transaction in bytes +} + +/** + * Request: Ask device to sign transaction + * @next PassphraseRequest + * @next PinMatrixRequest + * @next TxRequest + * @next Failure + */ +message SignTx { + required uint32 outputs_count = 1; // number of transaction outputs + required uint32 inputs_count = 2; // number of transaction inputs + optional string coin_name = 3 [default='Bitcoin']; // coin to use + optional uint32 version = 4 [default=1]; // transaction version + optional uint32 lock_time = 5 [default=0]; // transaction lock_time + optional uint32 decred_expiry = 6; +} + +/** + * Request: Simplified transaction signing + * This method doesn't support streaming, so there are hardware limits in number of inputs and outputs. + * In case of success, the result is returned using TxRequest message. + * @next PassphraseRequest + * @next PinMatrixRequest + * @next TxRequest + * @next Failure + */ +message SimpleSignTx { + repeated TxInputType inputs = 1; // transaction inputs + repeated TxOutputType outputs = 2; // transaction outputs + repeated TransactionType transactions = 3; // transactions whose outputs are used to build current inputs + optional string coin_name = 4 [default='Bitcoin']; // coin to use + optional uint32 version = 5 [default=1]; // transaction version + optional uint32 lock_time = 6 [default=0]; // transaction lock_time +} + +/** + * Response: Device asks for information for signing transaction or returns the last result + * If request_index is set, device awaits TxAck message (with fields filled in according to request_type) + * If signature_index is set, 'signature' contains signed input of signature_index's input + * @prev SignTx + * @prev SimpleSignTx + * @prev TxAck + */ +message TxRequest { + optional RequestType request_type = 1; // what should be filled in TxAck message? + optional TxRequestDetailsType details = 2; // request for tx details + optional TxRequestSerializedType serialized = 3; // serialized data and request for next +} + +/** + * Request: Reported transaction data + * @prev TxRequest + * @next TxRequest + */ +message TxAck { + optional TransactionType tx = 1; +} + +/** + * Request: Ask device to sign transaction + * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. + * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. + * @next PassphraseRequest + * @next PinMatrixRequest + * @next EthereumTxRequest + * @next Failure + */ +message EthereumSignTx { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes nonce = 2; // <=256 bit unsigned big endian + optional bytes gas_price = 3; // <=256 bit unsigned big endian (in wei) + optional bytes gas_limit = 4; // <=256 bit unsigned big endian + optional bytes to = 5; // 160 bit address hash + optional bytes value = 6; // <=256 bit unsigned big endian (in wei) + optional bytes data_initial_chunk = 7; // The initial data chunk (<= 1024 bytes) + optional uint32 data_length = 8; // Length of transaction payload + optional uint32 chain_id = 9; // Chain Id for EIP 155 +} + +/** + * Response: Device asks for more data from transaction payload, or returns the signature. + * If data_length is set, device awaits that many more bytes of payload. + * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. + * @prev EthereumSignTx + * @next EthereumTxAck + */ +message EthereumTxRequest { + optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) + optional uint32 signature_v = 2; // Computed signature (recovery parameter, limited to 27 or 28) + optional bytes signature_r = 3; // Computed signature R component (256 bit) + optional bytes signature_s = 4; // Computed signature S component (256 bit) +} + +/** + * Request: Transaction payload data. + * @prev EthereumTxRequest + * @next EthereumTxRequest + */ +message EthereumTxAck { + optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) +} + +//////////////////////////////////////// +// Ethereum: Message signing messages // +//////////////////////////////////////// + +/** + * Request: Ask device to sign message + * @next EthereumMessageSignature + * @next Failure + */ +message EthereumSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + required bytes message = 2; // message to be signed +} + +/** + * Request: Ask device to verify message + * @next Success + * @next Failure + */ +message EthereumVerifyMessage { + optional bytes address = 1; // address to verify + optional bytes signature = 2; // signature to verify + optional bytes message = 3; // message to verify +} + +/** + * Response: Signed message + * @prev EthereumSignMessage + */ +message EthereumMessageSignature { + optional bytes address = 1; // address used to sign the message + optional bytes signature = 2; // signature of the message +} + +/////////////////////// +// Identity messages // +/////////////////////// + +/** + * Request: Ask device to sign identity + * @next SignedIdentity + * @next Failure + */ +message SignIdentity { + optional IdentityType identity = 1; // identity + optional bytes challenge_hidden = 2; // non-visible challenge + optional string challenge_visual = 3; // challenge shown on display (e.g. date+time) + optional string ecdsa_curve_name = 4; // ECDSA curve name to use +} + +/** + * Response: Device provides signed identity + * @prev SignIdentity + */ +message SignedIdentity { + optional string address = 1; // identity address + optional bytes public_key = 2; // identity public key + optional bytes signature = 3; // signature of the identity data +} + +/////////////////// +// ECDH messages // +/////////////////// + +/** + * Request: Ask device to generate ECDH session key + * @next ECDHSessionKey + * @next Failure + */ +message GetECDHSessionKey { + optional IdentityType identity = 1; // identity + optional bytes peer_public_key = 2; // peer's public key + optional string ecdsa_curve_name = 3; // ECDSA curve name to use +} + +/** + * Response: Device provides ECDH session key + * @prev GetECDHSessionKey + */ +message ECDHSessionKey { + optional bytes session_key = 1; // ECDH session key +} + +/////////////////// +// U2F messages // +/////////////////// + +/** + * Request: Set U2F counter + * @next Success + */ +message SetU2FCounter { + optional uint32 u2f_counter = 1; // counter +} + +///////////////////////// +// Bootloader messages // +///////////////////////// + +/** + * Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload) + * @next Success + * @next FirmwareRequest + * @next Failure + */ +message FirmwareErase { + optional uint32 length = 1; // length of new firmware +} + +/** + * Response: Ask for firmware chunk + * @next FirmwareUpload + */ +message FirmwareRequest { + optional uint32 offset = 1; // offset of requested firmware chunk + optional uint32 length = 2; // length of requested firmware chunk +} + +/** + * Request: Send firmware in binary form to the device + * @next Success + * @next Failure + */ +message FirmwareUpload { + required bytes payload = 1; // firmware to be loaded into device + optional bytes hash = 2; // hash of the payload +} + + +/** + * Request: Perform a device self-test + * @next Success + * @next Failure + */ +message SelfTest { + optional bytes payload = 1; // payload to be used in self-test +} + +////////////////// +// NEM messages // +////////////////// + +/** + * Request: Ask device for NEM address corresponding to address_n path + * @next PassphraseRequest + * @next NEMAddress + * @next Failure + */ +message NEMGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) + optional bool show_display = 3; // Optionally show on display before sending the result +} + +/** + * Response: Contains NEM address derived from device private seed + * @prev NEMGetAddress + */ +message NEMAddress { + required string address = 1; // NEM address in Base32 encoding +} + +/** + * Request: Ask device to sign transaction + * @next NEMSignedTx + * @next Failure + */ +message NEMSignTx { + optional NEMTransactionCommon transaction = 1; // Common part of transaction + optional NEMTransactionCommon multisig = 2; // Common part of inner transaction for multisig transactions + optional NEMTransfer transfer = 3; // Transfer transaction part + optional bool cosigning = 4; // Whether cosigning or initiating the multisig transaction + optional NEMProvisionNamespace provision_namespace = 5; // Provision namespace part + optional NEMMosaicCreation mosaic_creation = 6; // Mosaic definition creation part + optional NEMMosaicSupplyChange supply_change = 7; // Mosaic supply change part + optional NEMAggregateModification aggregate_modification = 8; // Aggregate modification part + optional NEMImportanceTransfer importance_transfer = 9; // Importance transfer part +} + +/** + * Response: Contains NEM transaction data and signature + * @prev NEMSignTx + */ +message NEMSignedTx { + optional bytes data = 1; // Transaction data + optional bytes signature = 2; // Signature for the transaction +} + +/** + * Request: Ask device to decrypt NEM transaction payload + * @next NEMDecryptedMessage + * @next Failure + */ +message NEMDecryptMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) + optional bytes public_key = 3; // Public key of the other party + optional bytes payload = 4; // Actual message data (encrypted) +} + +/** + * Response: Contains decrypted NEM transaction payload + * @prev NEMDecryptMessage + */ +message NEMDecryptedMessage { + optional bytes payload = 1; // Actual message data (unencrypted) +} + +/////////////////// +// CoSi messages // +/////////////////// + +/** + * Request: Ask device to commit to CoSi signing + * @next CosiCommitment + * @next Failure + */ +message CosiCommit { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes data = 2; // Data to be signed +} + +/** + * Response: Contains a CoSi commitment + * @prev CosiCommit + */ +message CosiCommitment { + optional bytes commitment = 1; // Commitment + optional bytes pubkey = 2; // Public key +} + +/** + * Request: Ask device to sign using CoSi + * @next CosiSignature + * @next Failure + */ +message CosiSign { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes data = 2; // Data to be signed + optional bytes global_commitment = 3; // Aggregated commitment + optional bytes global_pubkey = 4; // Aggregated public key +} + +/** + * Response: Contains a CoSi signature + * @prev CosiSign + */ +message CosiSignature { + optional bytes signature = 1; // Signature +} + +///////////////////////////////////////////////////////////// +// Debug messages (only available if DebugLink is enabled) // +///////////////////////////////////////////////////////////// + +/** + * Request: "Press" the button on the device + * @next Success + */ +message DebugLinkDecision { + required bool yes_no = 1; // true for "Confirm", false for "Cancel" +} + +/** + * Request: Computer asks for device state + * @next DebugLinkState + */ +message DebugLinkGetState { +} + +/** + * Response: Device current state + * @prev DebugLinkGetState + */ +message DebugLinkState { + optional bytes layout = 1; // raw buffer of display + optional string pin = 2; // current PIN, blank if PIN is not set/enabled + optional string matrix = 3; // current PIN matrix + optional string mnemonic = 4; // current BIP-39 mnemonic + optional HDNodeType node = 5; // current BIP-32 node + optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase? + optional string reset_word = 7; // word on device display during ResetDevice workflow + optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow + optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow + optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow +} + +/** + * Request: Ask device to restart + */ +message DebugLinkStop { +} + +/** + * Response: Device wants host to log event + */ +message DebugLinkLog { + optional uint32 level = 1; + optional string bucket = 2; + optional string text = 3; +} + +/** + * Request: Read memory from device + * @next DebugLinkMemory + */ +message DebugLinkMemoryRead { + optional uint32 address = 1; + optional uint32 length = 2; +} + +/** + * Response: Device sends memory back + * @prev DebugLinkMemoryRead + */ +message DebugLinkMemory { + optional bytes memory = 1; +} + +/** + * Request: Write memory to device. + * WARNING: Writing to the wrong location can irreparably break the device. + */ +message DebugLinkMemoryWrite { + optional uint32 address = 1; + optional bytes memory = 2; + optional bool flash = 3; +} + +/** + * Request: Erase block of flash on device + * WARNING: Writing to the wrong location can irreparably break the device. + */ +message DebugLinkFlashErase { + optional uint32 sector = 1; +} diff --git a/go-api-for-hardware-wallet/protob/types.options b/go-api-for-hardware-wallet/protob/types.options new file mode 100644 index 00000000..e087cb07 --- /dev/null +++ b/go-api-for-hardware-wallet/protob/types.options @@ -0,0 +1,74 @@ +HDNodeType.chain_code max_size:32 +HDNodeType.private_key max_size:32 +HDNodeType.public_key max_size:33 + +HDNodePathType.address_n max_count:8 + +CoinType.coin_name max_size:17 +CoinType.coin_shortcut max_size:9 +CoinType.signed_message_header max_size:32 + +TxInputType.address_n max_count:8 +TxInputType.prev_hash max_size:32 +TxInputType.script_sig max_size:1650 + +TxOutputType.address max_size:76 +TxOutputType.address_n max_count:8 +TxOutputType.op_return_data max_size:80 + +TxOutputBinType.script_pubkey max_size:520 + +TransactionType.inputs max_count:1 +TransactionType.bin_outputs max_count:1 +TransactionType.outputs max_count:1 +TransactionType.extra_data max_size:1024 + +TxRequestDetailsType.tx_hash max_size:32 + +TxRequestSerializedType.signature max_size:73 +TxRequestSerializedType.serialized_tx max_size:2048 + +MultisigRedeemScriptType.pubkeys max_count:15 +MultisigRedeemScriptType.signatures max_count:15 max_size:73 + +IdentityType.proto max_size:9 +IdentityType.user max_size:64 +IdentityType.host max_size:64 +IdentityType.port max_size:6 +IdentityType.path max_size:256 + +NEMTransactionCommon.address_n max_count:8 +NEMTransactionCommon.signer max_size:32 + +NEMTransfer.recipient max_size:41 +NEMTransfer.public_key max_size:32 +NEMTransfer.payload max_size:1024 +NEMTransfer.mosaics max_count:16 + +NEMMosaic.namespace max_size:145 +NEMMosaic.mosaic max_size:33 + +NEMProvisionNamespace.namespace max_size:65 +NEMProvisionNamespace.parent max_size:81 +NEMProvisionNamespace.sink max_size:41 + +NEMMosaicCreation.sink max_size:41 + +NEMMosaicDefinition.name max_size:32 +NEMMosaicDefinition.ticker max_size:16 +NEMMosaicDefinition.namespace max_size:145 +NEMMosaicDefinition.mosaic max_size:33 +NEMMosaicDefinition.levy_address max_size:41 +NEMMosaicDefinition.levy_namespace max_size:145 +NEMMosaicDefinition.levy_mosaic max_size:33 +NEMMosaicDefinition.description max_size:513 +NEMMosaicDefinition.networks max_count:8 + +NEMMosaicSupplyChange.namespace max_size:145 +NEMMosaicSupplyChange.mosaic max_size:33 + +NEMAggregateModification.modifications max_count:16 + +NEMCosignatoryModification.public_key max_size:32 + +NEMImportanceTransfer.public_key max_size:32 diff --git a/go-api-for-hardware-wallet/protob/types.proto b/go-api-for-hardware-wallet/protob/types.proto new file mode 100644 index 00000000..6aaaefec --- /dev/null +++ b/go-api-for-hardware-wallet/protob/types.proto @@ -0,0 +1,446 @@ +syntax = "proto2"; + +/** + * Types for TREZOR communication + * + * @author Marek Palatinus + * @version 1.2 + */ + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorType"; +option go_package = "messages"; + +import "google/protobuf/descriptor.proto"; + +/** + * Options for specifying message direction and type of wire (normal/debug) + */ +extend google.protobuf.EnumValueOptions { + optional bool wire_in = 50002; // message can be transmitted via wire from PC to TREZOR + optional bool wire_out = 50003; // message can be transmitted via wire from TREZOR to PC + optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to TREZOR + optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from TREZOR to PC + optional bool wire_tiny = 50006; // message is handled by TREZOR when the USB stack is in tiny mode + optional bool wire_bootloader = 50007; // message is only handled by TREZOR Bootloader +} + +/** + * Type of failures returned by Failure message + * @used_in Failure + */ +enum FailureType { + Failure_UnexpectedMessage = 1; + Failure_ButtonExpected = 2; + Failure_DataError = 3; + Failure_ActionCancelled = 4; + Failure_PinExpected = 5; + Failure_PinCancelled = 6; + Failure_PinInvalid = 7; + Failure_InvalidSignature = 8; + Failure_ProcessError = 9; + Failure_NotEnoughFunds = 10; + Failure_NotInitialized = 11; + Failure_PinMismatch = 12; + Failure_FirmwareError = 99; +} + +/** + * Type of script which will be used for transaction output + * @used_in TxOutputType + */ +enum OutputScriptType { + PAYTOADDRESS = 0; // used for all addresses (bitcoin, p2sh, witness) + PAYTOSCRIPTHASH = 1; // p2sh address (deprecated; use PAYTOADDRESS) + PAYTOMULTISIG = 2; // only for change output + PAYTOOPRETURN = 3; // op_return + PAYTOWITNESS = 4; // only for change output + PAYTOP2SHWITNESS = 5; // only for change output +} + +/** + * Type of script which will be used for transaction output + * @used_in TxInputType + */ +enum InputScriptType { + SPENDADDRESS = 0; // standard p2pkh address + SPENDMULTISIG = 1; // p2sh multisig address + EXTERNAL = 2; // reserved for external inputs (coinjoin) + SPENDWITNESS = 3; // native segwit + SPENDP2SHWITNESS = 4; // segwit over p2sh (backward compatible) +} + +/** + * Type of information required by transaction signing process + * @used_in TxRequest + */ +enum RequestType { + TXINPUT = 0; + TXOUTPUT = 1; + TXMETA = 2; + TXFINISHED = 3; + TXEXTRADATA = 4; +} + +/** + * Type of button request + * @used_in ButtonRequest + */ +enum ButtonRequestType { + ButtonRequest_Other = 1; + ButtonRequest_FeeOverThreshold = 2; + ButtonRequest_ConfirmOutput = 3; + ButtonRequest_ResetDevice = 4; + ButtonRequest_ConfirmWord = 5; + ButtonRequest_WipeDevice = 6; + ButtonRequest_ProtectCall = 7; + ButtonRequest_SignTx = 8; + ButtonRequest_FirmwareCheck = 9; + ButtonRequest_Address = 10; + ButtonRequest_PublicKey = 11; + ButtonRequest_MnemonicWordCount = 12; + ButtonRequest_MnemonicInput = 13; + ButtonRequest_PassphraseType = 14; +} + +/** + * Type of PIN request + * @used_in PinMatrixRequest + */ +enum PinMatrixRequestType { + PinMatrixRequestType_Current = 1; + PinMatrixRequestType_NewFirst = 2; + PinMatrixRequestType_NewSecond = 3; +} + +/** + * Type of recovery procedure. These should be used as bitmask, e.g., + * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` + * listing every method supported by the host computer. + * + * Note that ScrambledWords must be supported by every implementation + * for backward compatibility; there is no way to not support it. + * + * @used_in RecoveryDevice + */ +enum RecoveryDeviceType { + // use powers of two when extending this field + RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order + RecoveryDeviceType_Matrix = 1; // matrix recovery type +} + +/** + * Type of Recovery Word request + * @used_in WordRequest + */ +enum WordRequestType { + WordRequestType_Plain = 0; + WordRequestType_Matrix9 = 1; + WordRequestType_Matrix6 = 2; +} + +/** + * Structure representing BIP32 (hierarchical deterministic) node + * Used for imports of private key into the device and exporting public key out of device + * @used_in PublicKey + * @used_in LoadDevice + * @used_in DebugLinkState + * @used_in Storage + */ +message HDNodeType { + required uint32 depth = 1; + required uint32 fingerprint = 2; + required uint32 child_num = 3; + required bytes chain_code = 4; + optional bytes private_key = 5; + optional bytes public_key = 6; +} + +message HDNodePathType { + required HDNodeType node = 1; // BIP-32 node in deserialized form + repeated uint32 address_n = 2; // BIP-32 path to derive the key from node +} + +/** + * Structure representing Coin + * @used_in Features + */ +message CoinType { + optional string coin_name = 1; + optional string coin_shortcut = 2; + optional uint32 address_type = 3 [default=0]; + optional uint64 maxfee_kb = 4; + optional uint32 address_type_p2sh = 5 [default=5]; + optional string signed_message_header = 8; + optional uint32 xpub_magic = 9 [default=76067358]; // default=0x0488b21e + optional uint32 xprv_magic = 10 [default=76066276]; // default=0x0488ade4 + optional bool segwit = 11; + optional uint32 forkid = 12; + optional bool force_bip143 = 13; +} + +/** + * Type of redeem script used in input + * @used_in TxInputType + */ +message MultisigRedeemScriptType { + repeated HDNodePathType pubkeys = 1; // pubkeys from multisig address (sorted lexicographically) + repeated bytes signatures = 2; // existing signatures for partially signed input + optional uint32 m = 3; // "m" from n, how many valid signatures is necessary for spending +} + +/** + * Structure representing transaction input + * @used_in SimpleSignTx + * @used_in TransactionType + */ +message TxInputType { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + required bytes prev_hash = 2; // hash of previous transaction output to spend by this input + required uint32 prev_index = 3; // index of previous output to spend + optional bytes script_sig = 4; // script signature, unset for tx to sign + optional uint32 sequence = 5 [default=4294967295]; // sequence (default=0xffffffff) + optional InputScriptType script_type = 6 [default=SPENDADDRESS]; // defines template of input script + optional MultisigRedeemScriptType multisig = 7; // Filled if input is going to spend multisig tx + optional uint64 amount = 8; // amount of previous transaction output (for segwit only) + optional uint32 decred_tree = 9; + optional uint32 decred_script_version = 10; +} + +/** + * Structure representing transaction output + * @used_in SimpleSignTx + * @used_in TransactionType + */ +message TxOutputType { + optional string address = 1; // target coin address in Base58 encoding + repeated uint32 address_n = 2; // BIP-32 path to derive the key from master node; has higher priority than "address" + required uint64 amount = 3; // amount to spend in satoshis + required OutputScriptType script_type = 4; // output script type + optional MultisigRedeemScriptType multisig = 5; // defines multisig address; script_type must be PAYTOMULTISIG + optional bytes op_return_data = 6; // defines op_return data; script_type must be PAYTOOPRETURN, amount must be 0 + optional uint32 decred_script_version = 7; +} + +/** + * Structure representing compiled transaction output + * @used_in TransactionType + */ +message TxOutputBinType { + required uint64 amount = 1; + required bytes script_pubkey = 2; + optional uint32 decred_script_version = 3; +} + +/** + * Structure representing transaction + * @used_in SimpleSignTx + */ +message TransactionType { + optional uint32 version = 1; + repeated TxInputType inputs = 2; + repeated TxOutputBinType bin_outputs = 3; + repeated TxOutputType outputs = 5; + optional uint32 lock_time = 4; + optional uint32 inputs_cnt = 6; + optional uint32 outputs_cnt = 7; + optional bytes extra_data = 8; + optional uint32 extra_data_len = 9; + optional uint32 decred_expiry = 10; +} + +/** + * Structure representing request details + * @used_in TxRequest + */ +message TxRequestDetailsType { + optional uint32 request_index = 1; // device expects TxAck message from the computer + optional bytes tx_hash = 2; // tx_hash of requested transaction + optional uint32 extra_data_len = 3; // length of requested extra data + optional uint32 extra_data_offset = 4; // offset of requested extra data +} + +/** + * Structure representing serialized data + * @used_in TxRequest + */ +message TxRequestSerializedType { + optional uint32 signature_index = 1; // 'signature' field contains signed input of this index + optional bytes signature = 2; // signature of the signature_index input + optional bytes serialized_tx = 3; // part of serialized and signed transaction +} + +/** + * Structure representing identity data + * @used_in IdentityType + */ +message IdentityType { + optional string proto = 1; // proto part of URI + optional string user = 2; // user part of URI + optional string host = 3; // host part of URI + optional string port = 4; // port part of URI + optional string path = 5; // path part of URI + optional uint32 index = 6 [default=0]; // identity index +} + +/** + * Structure representing the common part for NEM transactions + * @used_in NEMSignTx + */ +message NEMTransactionCommon { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) + optional uint32 timestamp = 3; // Number of seconds elapsed since the creation of the nemesis block + optional uint64 fee = 4; // Fee for the transaction + optional uint32 deadline = 5; // Deadline of the transaction + optional bytes signer = 6; // Public key of the account (for multisig transactions) +} + +/** + * Structure representing the transfer transaction part for NEM transactions + * @used_in NEMSignTx + */ +message NEMTransfer { + optional string recipient = 1; // Address of the recipient + optional uint64 amount = 2; // Amount of micro NEM that is transferred + optional bytes payload = 3; // Actual message data (unencrypted) + optional bytes public_key = 4; // Public key of the recipient (for encrypted payloads) + repeated NEMMosaic mosaics = 5; // Attached mosaics +} + +/** + * Structure representing the mosaic attachment for NEM transfer transactions + * @used_in NEMTransfer + */ +message NEMMosaic { + optional string namespace = 1; // Fully qualified name of the namespace + optional string mosaic = 2; // Name of the mosaic definition + optional uint64 quantity = 3; // Mosaic quantity, always given in smallest units +} + +/** + * Structure representing the provision namespace part for NEM transactions + * @used_in NEMSignTx + */ +message NEMProvisionNamespace { + optional string namespace = 1; // New part concatenated to the parent + optional string parent = 2; // Parent namespace (for child namespaces) + optional string sink = 3; // Rental fee sink address + optional uint64 fee = 4; // Rental fee +} + +/** + * Type of levy which will be used for mosaic + * @used_in NEMMosaicDefinition + */ +enum NEMMosaicLevy { + MosaicLevy_Absolute = 1; + MosaicLevy_Percentile = 2; +} + +/** + * Structure representing the mosaic definition creation part for NEM transactions + * @used_in NEMSignTx + */ +message NEMMosaicCreation { + optional NEMMosaicDefinition definition = 1; // Mosaic definition + optional string sink = 2; // Creation fee sink address + optional uint64 fee = 3; // Creation fee +} + +/** + * Structure representing a mosaic definition + * @used_in NEMMosaicCreation + */ +message NEMMosaicDefinition { + optional string name = 1; // User-friendly name of the mosaic (for whitelisted mosaics) + optional string ticker = 2; // Ticker of the mosaic (for whitelisted mosaics) + optional string namespace = 3; // Fully qualified name of the namespace + optional string mosaic = 4; // Name of the mosaic definition + optional uint32 divisibility = 5; // Number of decimal places that a mosaic can be divided into + optional NEMMosaicLevy levy = 6; // Levy type + optional uint64 fee = 7; // Levy fee (interpretation depends on levy type) + optional string levy_address = 8; // Levy address + optional string levy_namespace = 9; // Fully qualified name of the namespace of the levy mosaic + optional string levy_mosaic = 10; // Name of the levy mosaic + optional uint64 supply = 11; // Initial supply to create, always given in entire units + optional bool mutable_supply = 12; // Mutable supply + optional bool transferable = 13; // Mosaic allows transfers among accounts other than the creator + optional string description = 14; // Mosaic description + repeated uint32 networks = 15; // Networks that the mosaic is valid on (for whitelisted mosaics) +} + +/** + * Structure representing the mosaic supply change part for NEM transactions + * @used_in NEMSignTx + */ +message NEMMosaicSupplyChange { + optional string namespace = 1; // Fully qualified name of the namespace + optional string mosaic = 2; // Name of the mosaic definition + optional NEMSupplyChangeType type = 3; // Type of supply change + optional uint64 delta = 4; // Supply delta +} + +/** + * Type of supply change which will be applied to mosaic + * @used_in NEMMosaicSupplyChange + */ +enum NEMSupplyChangeType { + SupplyChange_Increase = 1; + SupplyChange_Decrease = 2; +} + +/** + * Structure representing the aggregate modification part for NEM transactions + * @used_in NEMSignTx + */ +message NEMAggregateModification { + repeated NEMCosignatoryModification modifications = 1; // Cosignatory modifications + optional sint32 relative_change = 2; // Relative change of the minimum cosignatories +} + +/** + * Structure representing the cosignatory modification for aggregate modification transactions + * @used_in NEMAggregateMdofiication + */ +message NEMCosignatoryModification { + optional NEMModificationType type = 1; // Type of cosignatory modification + optional bytes public_key = 2; // Public key of the cosignatory +} + +/** + * Type of cosignatory modification + * @used_in NEMCosignatoryModification + */ +enum NEMModificationType { + CosignatoryModification_Add = 1; + CosignatoryModification_Delete = 2; +} + +/** + * Structure representing the importance transfer part for NEM transactions + * @used_in NEMSignTx + */ +message NEMImportanceTransfer { + optional NEMImportanceTransferMode mode = 1; // Mode of importance transfer + optional bytes public_key = 2; // Public key of the remote account +} + +/** + * Mode of importance transfer + * @used_in NEMModificationType + */ +enum NEMImportanceTransferMode { + ImportanceTransfer_Activate = 1; + ImportanceTransfer_Deactivate = 2; +} + +/** + * Ask trezor to generate a skycoin address + * @used_in SkycoinAddress{ + */ +enum SkycoinAddressType { + AddressTypeSkycoin = 1; + AddressTypeBitcoin = 2; +} diff --git a/go-api-for-hardware-wallet/trezor.go b/go-api-for-hardware-wallet/trezor.go new file mode 100644 index 00000000..1ba7e452 --- /dev/null +++ b/go-api-for-hardware-wallet/trezor.go @@ -0,0 +1,69 @@ +package harwareWallet + +import ( + "bytes" + "encoding/binary" + "fmt" + "log" + "time" + + "github.com/skycoin/skycoin/src/hardware-wallet/usb" + + messages "github.com/skycoin/skycoin/protob" +) + +func GetTrezorDevice() (usb.Device, error) { + w, err := usb.InitWebUSB() + if err != nil { + log.Fatalf("webusb: %s", err) + } + h, err := usb.InitHIDAPI() + if err != nil { + log.Fatalf("hidapi: %s", err) + } + b := usb.Init(w, h) + + var infos []usb.Info + infos, _ = b.Enumerate() + + tries := 0 + dev, err := b.Connect(infos[0].Path) + if err != nil { + fmt.Printf(err.Error()) + if tries < 3 { + tries++ + time.Sleep(100 * time.Millisecond) + } + } + return dev, err +} +func MakeTrezorHeader(data []byte, msgID messages.MessageType) []byte { + header := new(bytes.Buffer) + binary.Write(header, binary.BigEndian, []byte("?##")) + binary.Write(header, binary.BigEndian, uint16(msgID)) + binary.Write(header, binary.BigEndian, uint32(len(data))) + binary.Write(header, binary.BigEndian, []byte("\n")) + return header.Bytes() +} + +func MakeTrezorMessage(data []byte, msgID messages.MessageType) [][64]byte { + message := new(bytes.Buffer) + binary.Write(message, binary.BigEndian, []byte("##")) + binary.Write(message, binary.BigEndian, uint16(msgID)) + binary.Write(message, binary.BigEndian, uint32(len(data))) + binary.Write(message, binary.BigEndian, []byte("\n")) + binary.Write(message, binary.BigEndian, data[1:]) + + messageLen := message.Len() + var chunks [][64]byte + i := 0 + for messageLen > 0 { + var chunk [64]byte + chunk[0] = '?' + copy(chunk[1:], message.Bytes()[63*i:63*(i+1)]) + chunks = append(chunks, chunk) + messageLen -= 63 + i = i + 1 + } + return chunks +} diff --git a/go-api-for-hardware-wallet/usb/bus.go b/go-api-for-hardware-wallet/usb/bus.go new file mode 100644 index 00000000..d2d0f558 --- /dev/null +++ b/go-api-for-hardware-wallet/usb/bus.go @@ -0,0 +1,71 @@ +package usb + +import ( + "errors" + "fmt" + "io" +) + +const ( + vendorT1 = 0x534c + productT1Bootloader = 0x0000 + productT1Firmware = 0x0001 + vendorT2 = 0x1209 + productT2Bootloader = 0x53C0 + productT2Firmware = 0x53C1 +) + +var ( + ErrNotFound = fmt.Errorf("device not found") +) + +type Info struct { + Path string + VendorID int + ProductID int +} + +type Device interface { + io.ReadWriteCloser +} + +type Bus interface { + Enumerate() ([]Info, error) + Connect(path string) (Device, error) + Has(path string) bool +} + +type USB struct { + buses []Bus +} + +func Init(buses ...Bus) *USB { + return &USB{ + buses: buses, + } +} + +func (b *USB) Enumerate() ([]Info, error) { + var infos []Info + + for _, b := range b.buses { + l, err := b.Enumerate() + if err != nil { + return nil, err + } + infos = append(infos, l...) + } + return infos, nil +} + +func (b *USB) Connect(path string) (Device, error) { + for _, b := range b.buses { + if b.Has(path) { + return b.Connect(path) + } + } + return nil, ErrNotFound +} + +var disconnectError = errors.New("Device disconnected during action") +var closedDeviceError = errors.New("Closed device") diff --git a/go-api-for-hardware-wallet/usb/hidapi.go b/go-api-for-hardware-wallet/usb/hidapi.go new file mode 100644 index 00000000..01370af1 --- /dev/null +++ b/go-api-for-hardware-wallet/usb/hidapi.go @@ -0,0 +1,140 @@ +package usb + +import ( + "crypto/sha256" + "encoding/hex" + "errors" + "strings" + + "github.com/usbhid" +) + +const ( + hidapiPrefix = "hid" + hidIfaceNum = 0 + hidUsagePage = 0xFF00 +) + +type HIDAPI struct { +} + +func InitHIDAPI() (*HIDAPI, error) { + return &HIDAPI{}, nil +} + +func (b *HIDAPI) Enumerate() ([]Info, error) { + var infos []Info + + for _, dev := range usbhid.HidEnumerate(0, 0) { // enumerate all devices + if b.match(&dev) { + infos = append(infos, Info{ + Path: b.identify(&dev), + VendorID: int(dev.VendorID), + ProductID: int(dev.ProductID), + }) + } + } + return infos, nil +} + +func (b *HIDAPI) Has(path string) bool { + return strings.HasPrefix(path, hidapiPrefix) +} + +func (b *HIDAPI) Connect(path string) (Device, error) { + for _, dev := range usbhid.HidEnumerate(0, 0) { // enumerate all devices + if b.match(&dev) && b.identify(&dev) == path { + d, err := dev.Open() + if err != nil { + return nil, err + } + prepend, err := detectPrepend(d) + if err != nil { + return nil, err + } + return &HID{ + dev: d, + prepend: prepend, + }, nil + } + } + return nil, ErrNotFound +} + +func (b *HIDAPI) match(d *usbhid.HidDeviceInfo) bool { + vid := d.VendorID + pid := d.ProductID + trezor1 := vid == vendorT1 && (pid == productT1Firmware || pid == productT1Bootloader) + trezor2 := vid == vendorT2 && (pid == productT2Firmware || pid == productT2Bootloader) + return (trezor1 || trezor2) && (d.Interface == hidIfaceNum || d.UsagePage == hidUsagePage) +} + +func (b *HIDAPI) identify(dev *usbhid.HidDeviceInfo) string { + path := []byte(dev.Path) + digest := sha256.Sum256(path) + return hidapiPrefix + hex.EncodeToString(digest[:]) +} + +type HID struct { + dev *usbhid.HidDevice + prepend bool // on windows, see detectPrepend +} + +func (d *HID) Close() error { + return d.dev.Close() +} + +var unknownErrorMessage = "hidapi: unknown failure" + +// This will write a useless buffer to trezor +// to test whether it is an older HID version on reportid 63 +// or a newer one that is on id 0. +// The older one does not need prepending, the newer one does +// This makes difference only on windows +func detectPrepend(dev *usbhid.HidDevice) (bool, error) { + buf := []byte{63} + for i := 0; i < 63; i++ { + buf = append(buf, 0xff) + } + + // first test newer version + w, _ := dev.Write(buf, true) + if w == 65 { + return true, nil + } + + // then test older version + w, err := dev.Write(buf, false) + if err != nil { + return false, err + } + if w == 64 { + return false, nil + } + + return false, errors.New("Unknown HID version") +} + +func (d *HID) readWrite(buf []byte, read bool) (int, error) { + var w int + var err error + + if read { + w, err = d.dev.Read(buf) + } else { + w, err = d.dev.Write(buf, d.prepend) + } + + if err != nil && err.Error() == unknownErrorMessage { + return 0, disconnectError + } + return w, err +} + +func (d *HID) Write(buf []byte) (int, error) { + return d.readWrite(buf, false) +} + +func (d *HID) Read(buf []byte) (int, error) { + return d.readWrite(buf, true) +} diff --git a/go-api-for-hardware-wallet/usb/udp.go b/go-api-for-hardware-wallet/usb/udp.go new file mode 100644 index 00000000..c4ba9c14 --- /dev/null +++ b/go-api-for-hardware-wallet/usb/udp.go @@ -0,0 +1,174 @@ +package usb + +import ( + "bytes" + "io" + "net" + "strconv" + "strings" + "sync/atomic" + "time" +) + +var emulatorPing = []byte("PINGPING") +var emulatorPong = []byte("PONGPONG") + +const ( + emulatorPrefix = "emulator" + emulatorAddress = "127.0.0.1" + emulatorPingTimeout = 700 * time.Millisecond +) + +type UDP struct { + ports []int + + pings map[int](chan []byte) + datas map[int](chan []byte) + writers map[int](io.Writer) +} + +func listen(conn net.Conn) (chan []byte, chan []byte) { + ping := make(chan []byte, 1) + data := make(chan []byte, 100) + go func() { + for { + buffer := make([]byte, 64) + _, err := conn.Read(buffer) + if err == nil { + first := buffer[0] + if first == '?' { + data <- buffer + } + if first == 'P' { + copied := make([]byte, 8) + copy(copied, buffer) + ping <- copied + } + } + } + }() + return ping, data +} + +func InitUDP(ports []int) (*UDP, error) { + udp := UDP{ + ports: ports, + + pings: make(map[int](chan []byte)), + datas: make(map[int](chan []byte)), + writers: make(map[int](io.Writer)), + } + for _, port := range ports { + address := emulatorAddress + ":" + strconv.Itoa(port) + + connection, err := net.Dial("udp", address) + if err != nil { + return nil, err + } + + ping, data := listen(connection) + udp.pings[port] = ping + udp.datas[port] = data + udp.writers[port] = connection + } + return &udp, nil +} + +func checkPort(ping chan []byte, w io.Writer) (bool, error) { + _, err := w.Write(emulatorPing) + if err != nil { + return false, err + } + select { + case response := <-ping: + return bytes.Equal(response, emulatorPong), nil + case <-time.After(emulatorPingTimeout): + return false, nil + } +} + +func (u *UDP) Enumerate() ([]Info, error) { + var infos []Info + + for _, port := range u.ports { + ping := u.pings[port] + w := u.writers[port] + present, err := checkPort(ping, w) + if err != nil { + return nil, err + } + if present { + infos = append(infos, Info{ + Path: emulatorPrefix + strconv.Itoa(port), + VendorID: 0, + ProductID: 0, + }) + } + } + return infos, nil +} + +func (u *UDP) Has(path string) bool { + return strings.HasPrefix(path, emulatorPrefix) +} + +func (u *UDP) Connect(path string) (Device, error) { + i, err := strconv.Atoi(strings.TrimPrefix(path, emulatorPrefix)) + if err != nil { + return nil, err + } + return &UDPDevice{ + ping: u.pings[i], + data: u.datas[i], + writer: u.writers[i], + closed: 0, + }, nil +} + +type UDPDevice struct { + ping chan []byte + data chan []byte + writer io.Writer + + closed int32 // atomic +} + +func (d *UDPDevice) Close() error { + atomic.StoreInt32(&d.closed, 1) + return nil +} + +func (d *UDPDevice) readWrite(buf []byte, read bool) (int, error) { + for { + closed := (atomic.LoadInt32(&d.closed)) == 1 + if closed { + return 0, closedDeviceError + } + check, err := checkPort(d.ping, d.writer) + if err != nil { + return 0, err + } + if !check { + return 0, disconnectError + } + if !read { + return d.writer.Write(buf) + } else { + select { + case response := <-d.data: + copy(buf, response) + return len(response), nil + case <-time.After(emulatorPingTimeout): + // timeout, continue for cycle + } + } + } +} + +func (d *UDPDevice) Write(buf []byte) (int, error) { + return d.readWrite(buf, false) +} + +func (d *UDPDevice) Read(buf []byte) (int, error) { + return d.readWrite(buf, true) +} diff --git a/go-api-for-hardware-wallet/usb/webusb.go b/go-api-for-hardware-wallet/usb/webusb.go new file mode 100644 index 00000000..9311f3d1 --- /dev/null +++ b/go-api-for-hardware-wallet/usb/webusb.go @@ -0,0 +1,227 @@ +package usb + +import ( + "encoding/hex" + "strings" + "sync" + "sync/atomic" + + "github.com/usbhid" +) + +const ( + webusbPrefix = "web" + webConfigNum = 1 + webIfaceNum = 0 + webAltSetting = 0 + webEpIn = 0x81 + webEpOut = 0x01 + usbTimeout = 5000 +) + +type WebUSB struct { + usb usbhid.Context +} + +func InitWebUSB() (*WebUSB, error) { + var usb usbhid.Context + err := usbhid.Init(&usb) + if err != nil { + return nil, err + } + usbhid.Set_Debug(usb, usbhid.LOG_LEVEL_NONE) + + return &WebUSB{ + usb: usb, + }, nil +} + +func (b *WebUSB) Close() { + usbhid.Exit(b.usb) +} + +func (b *WebUSB) Enumerate() ([]Info, error) { + list, err := usbhid.Get_Device_List(b.usb) + if err != nil { + return nil, err + } + defer usbhid.Free_Device_List(list, 1) // unlink devices + + var infos []Info + + // There is a bug in either Trezor T or libusb that makes + // device appear twice with the same path + paths := make(map[string]bool) + + for _, dev := range list { + if b.match(dev) { + dd, err := usbhid.Get_Device_Descriptor(dev) + if err != nil { + continue + } + path := b.identify(dev) + inset := paths[path] + if !inset { + infos = append(infos, Info{ + Path: path, + VendorID: int(dd.IdVendor), + ProductID: int(dd.IdProduct), + }) + paths[path] = true + } + } + } + return infos, nil +} + +func (b *WebUSB) Has(path string) bool { + return strings.HasPrefix(path, webusbPrefix) +} + +func (b *WebUSB) Connect(path string) (Device, error) { + list, err := usbhid.Get_Device_List(b.usb) + if err != nil { + return nil, err + } + defer usbhid.Free_Device_List(list, 1) // unlink devices + + // There is a bug in either Trezor T or libusb that makes + // device appear twice with the same path + + // We try both and return the first that works + + mydevs := make([]usbhid.Device, 0) + for _, dev := range list { + if b.match(dev) && b.identify(dev) == path { + mydevs = append(mydevs, dev) + } + } + + err = ErrNotFound + for _, dev := range mydevs { + res, err := b.connect(dev) + if err == nil { + return res, nil + } + } + return nil, err +} + +func (b *WebUSB) connect(dev usbhid.Device) (*WUD, error) { + d, err := usbhid.Open(dev) + if err != nil { + return nil, err + } + err = usbhid.Reset_Device(d) + if err != nil { + // don't abort if reset fails + // usbhid.Close(d) + // return nil, err + } + err = usbhid.Set_Configuration(d, webConfigNum) + if err != nil { + // don't abort if set configuration fails + // usbhid.Close(d) + // return nil, err + } + err = usbhid.Claim_Interface(d, webIfaceNum) + if err != nil { + usbhid.Close(d) + return nil, err + } + return &WUD{ + dev: d, + closed: 0, + }, nil +} + +func (b *WebUSB) match(dev usbhid.Device) bool { + dd, err := usbhid.Get_Device_Descriptor(dev) + if err != nil { + return false + } + vid := dd.IdVendor + pid := dd.IdProduct + trezor1 := vid == vendorT1 && (pid == productT1Firmware || pid == productT1Bootloader) + trezor2 := vid == vendorT2 && (pid == productT2Firmware || pid == productT2Bootloader) + if !trezor1 && !trezor2 { + return false + } + c, err := usbhid.Get_Active_Config_Descriptor(dev) + if err != nil { + return false + } + return (c.BNumInterfaces > webIfaceNum && + c.Interface[webIfaceNum].Num_altsetting > webAltSetting && + c.Interface[webIfaceNum].Altsetting[webAltSetting].BInterfaceClass == usbhid.CLASS_VENDOR_SPEC) +} + +func (b *WebUSB) identify(dev usbhid.Device) string { + var ports [8]byte + p, err := usbhid.Get_Port_Numbers(dev, ports[:]) + if err != nil { + return "" + } + return webusbPrefix + hex.EncodeToString(p) +} + +type WUD struct { + dev usbhid.Device_Handle + + closed int32 // atomic + + transferMutex sync.Mutex + // closing cannot happen while interrupt_transfer is hapenning, + // otherwise interrupt_transfer hangs forever +} + +func (d *WUD) Close() error { + atomic.StoreInt32(&d.closed, 1) + + d.transferMutex.Lock() + usbhid.Close(d.dev) + d.transferMutex.Unlock() + + return nil +} + +func (d *WUD) readWrite(buf []byte, endpoint uint8) (int, error) { + for { + closed := (atomic.LoadInt32(&d.closed)) == 1 + if closed { + return 0, closedDeviceError + } + + d.transferMutex.Lock() + p, err := usbhid.Interrupt_Transfer(d.dev, endpoint, buf, usbTimeout) + d.transferMutex.Unlock() + + if err == nil { + // sometimes, empty report is read, skip it + if len(p) > 0 { + return len(p), err + } + } + + if err != nil { + if err.Error() == usbhid.Error_Name(usbhid.ERROR_IO) || + err.Error() == usbhid.Error_Name(usbhid.ERROR_NO_DEVICE) { + return 0, disconnectError + } + + if err.Error() != usbhid.Error_Name(usbhid.ERROR_TIMEOUT) { + return 0, err + } + } + + // continue the for cycle + } +} + +func (d *WUD) Write(buf []byte) (int, error) { + return d.readWrite(buf, webEpOut) +} + +func (d *WUD) Read(buf []byte) (int, error) { + return d.readWrite(buf, webEpIn) +} diff --git a/go-api-for-hardware-wallet/usbhid/.gitignore b/go-api-for-hardware-wallet/usbhid/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/go-api-for-hardware-wallet/usbhid/.travis.yml b/go-api-for-hardware-wallet/usbhid/.travis.yml new file mode 100644 index 00000000..a1693d99 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/.travis.yml @@ -0,0 +1,28 @@ +language: go + +matrix: + include: + - os: linux + dist: trusty + go: 1.5.x + - os: linux + dist: trusty + go: 1.6.x + - os: linux + dist: trusty + go: 1.7.x + - os: linux + dist: trusty + go: 1.8.x + - os: linux + dist: trusty + go: 1.9.x + - os: linux + dist: precise + go: 1.9.x + - os: osx + go: 1.9.x + +script: + - go install ./... + - go test -v ./... diff --git a/go-api-for-hardware-wallet/usbhid/README.md b/go-api-for-hardware-wallet/usbhid/README.md new file mode 100644 index 00000000..33bb7be4 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/README.md @@ -0,0 +1,17 @@ +# libusb + hidapi go wrapper + +This is a go wrapper around libusb and hidapi. + +We have devices that can work either with libusb or hidapi, so we needed to make a go package that can talk with both. + +Note that this is necessary only because of macOS; on Linux, hidapi is using libusb; and on Windows, libusb talks to hid devices using the same hid.dll as hidapi. In theory it would be cleaner to add HID API to libusb on macOS, but making this go package was quicker. + +The code is mostly copied from https://github.com/karalabe/hid and https://github.com/deadsy/libusb + +## License + +Code is under GNU LGPL 2.1. + +* (C) Karel Bilek 2017 +* (c) 2017 Jason T. Harris (also see https://github.com/deadsy/libusb for comprehensive list) +* (C) 2017 Péter Szilágyi (also see https://github.com/karalabe/hid for comprehensive list) diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/AUTHORS.txt b/go-api-for-hardware-wallet/usbhid/c/hidapi/AUTHORS.txt new file mode 100644 index 00000000..7acafd78 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/AUTHORS.txt @@ -0,0 +1,16 @@ + +HIDAPI Authors: + +Alan Ott : + Original Author and Maintainer + Linux, Windows, and Mac implementations + +Ludovic Rousseau : + Formatting for Doxygen documentation + Bug fixes + Correctness fixes + + +For a comprehensive list of contributions, see the commit list at github: + http://github.com/signal11/hidapi/commits/master + diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-bsd.txt b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-bsd.txt new file mode 100644 index 00000000..538cdf95 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-bsd.txt @@ -0,0 +1,26 @@ +Copyright (c) 2010, Alan Ott, Signal 11 Software +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 Signal 11 Software 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. diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-gpl3.txt b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-gpl3.txt new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-gpl3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-orig.txt b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-orig.txt new file mode 100644 index 00000000..e3f33808 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-orig.txt @@ -0,0 +1,9 @@ + HIDAPI - Multi-Platform library for + communication with HID devices. + + Copyright 2009, Alan Ott, Signal 11 Software. + All Rights Reserved. + + This software may be used by anyone for any reason so + long as the copyright notice in the source files + remains intact. diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE.txt b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE.txt new file mode 100644 index 00000000..e1676d4c --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE.txt @@ -0,0 +1,13 @@ +HIDAPI can be used under one of three licenses. + +1. The GNU General Public License, version 3.0, in LICENSE-gpl3.txt +2. A BSD-Style License, in LICENSE-bsd.txt. +3. The more liberal original HIDAPI license. LICENSE-orig.txt + +The license chosen is at the discretion of the user of HIDAPI. For example: +1. An author of GPL software would likely use HIDAPI under the terms of the +GPL. + +2. An author of commercial closed-source software would likely use HIDAPI +under the terms of the BSD-style license or the original HIDAPI license. + diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/README.txt b/go-api-for-hardware-wallet/usbhid/c/hidapi/README.txt new file mode 100644 index 00000000..f19dae4a --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/README.txt @@ -0,0 +1,339 @@ + HIDAPI library for Windows, Linux, FreeBSD and Mac OS X + ========================================================= + +About +====== + +HIDAPI is a multi-platform library which allows an application to interface +with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and Mac +OS X. HIDAPI can be either built as a shared library (.so or .dll) or +can be embedded directly into a target application by adding a single source +file (per platform) and a single header. + +HIDAPI has four back-ends: + * Windows (using hid.dll) + * Linux/hidraw (using the Kernel's hidraw driver) + * Linux/libusb (using libusb-1.0) + * FreeBSD (using libusb-1.0) + * Mac (using IOHidManager) + +On Linux, either the hidraw or the libusb back-end can be used. There are +tradeoffs, and the functionality supported is slightly different. + +Linux/hidraw (linux/hid.c): +This back-end uses the hidraw interface in the Linux kernel. While this +back-end will support both USB and Bluetooth, it has some limitations on +kernels prior to 2.6.39, including the inability to send or receive feature +reports. In addition, it will only communicate with devices which have +hidraw nodes associated with them. Keyboards, mice, and some other devices +which are blacklisted from having hidraw nodes will not work. Fortunately, +for nearly all the uses of hidraw, this is not a problem. + +Linux/FreeBSD/libusb (libusb/hid.c): +This back-end uses libusb-1.0 to communicate directly to a USB device. This +back-end will of course not work with Bluetooth devices. + +HIDAPI also comes with a Test GUI. The Test GUI is cross-platform and uses +Fox Toolkit (http://www.fox-toolkit.org). It will build on every platform +which HIDAPI supports. Since it relies on a 3rd party library, building it +is optional but recommended because it is so useful when debugging hardware. + +What Does the API Look Like? +============================= +The API provides the the most commonly used HID functions including sending +and receiving of input, output, and feature reports. The sample program, +which communicates with a heavily hacked up version of the Microchip USB +Generic HID sample looks like this (with error checking removed for +simplicity): + +#ifdef WIN32 +#include +#endif +#include +#include +#include "hidapi.h" + +#define MAX_STR 255 + +int main(int argc, char* argv[]) +{ + int res; + unsigned char buf[65]; + wchar_t wstr[MAX_STR]; + hid_device *handle; + int i; + + // Initialize the hidapi library + res = hid_init(); + + // Open the device using the VID, PID, + // and optionally the Serial number. + handle = hid_open(0x4d8, 0x3f, NULL); + + // Read the Manufacturer String + res = hid_get_manufacturer_string(handle, wstr, MAX_STR); + wprintf(L"Manufacturer String: %s\n", wstr); + + // Read the Product String + res = hid_get_product_string(handle, wstr, MAX_STR); + wprintf(L"Product String: %s\n", wstr); + + // Read the Serial Number String + res = hid_get_serial_number_string(handle, wstr, MAX_STR); + wprintf(L"Serial Number String: (%d) %s\n", wstr[0], wstr); + + // Read Indexed String 1 + res = hid_get_indexed_string(handle, 1, wstr, MAX_STR); + wprintf(L"Indexed String 1: %s\n", wstr); + + // Toggle LED (cmd 0x80). The first byte is the report number (0x0). + buf[0] = 0x0; + buf[1] = 0x80; + res = hid_write(handle, buf, 65); + + // Request state (cmd 0x81). The first byte is the report number (0x0). + buf[0] = 0x0; + buf[1] = 0x81; + res = hid_write(handle, buf, 65); + + // Read requested state + res = hid_read(handle, buf, 65); + + // Print out the returned buffer. + for (i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + + // Finalize the hidapi library + res = hid_exit(); + + return 0; +} + +If you have your own simple test programs which communicate with standard +hardware development boards (such as those from Microchip, TI, Atmel, +FreeScale and others), please consider sending me something like the above +for inclusion into the HIDAPI source. This will help others who have the +same hardware as you do. + +License +======== +HIDAPI may be used by one of three licenses as outlined in LICENSE.txt. + +Download +========= +HIDAPI can be downloaded from github + git clone git://github.com/signal11/hidapi.git + +Build Instructions +=================== + +This section is long. Don't be put off by this. It's not long because it's +complicated to build HIDAPI; it's quite the opposite. This section is long +because of the flexibility of HIDAPI and the large number of ways in which +it can be built and used. You will likely pick a single build method. + +HIDAPI can be built in several different ways. If you elect to build a +shared library, you will need to build it from the HIDAPI source +distribution. If you choose instead to embed HIDAPI directly into your +application, you can skip the building and look at the provided platform +Makefiles for guidance. These platform Makefiles are located in linux/ +libusb/ mac/ and windows/ and are called Makefile-manual. In addition, +Visual Studio projects are provided. Even if you're going to embed HIDAPI +into your project, it is still beneficial to build the example programs. + + +Prerequisites: +--------------- + + Linux: + ------- + On Linux, you will need to install development packages for libudev, + libusb and optionally Fox-toolkit (for the test GUI). On + Debian/Ubuntu systems these can be installed by running: + sudo apt-get install libudev-dev libusb-1.0-0-dev libfox-1.6-dev + + If you downloaded the source directly from the git repository (using + git clone), you'll need Autotools: + sudo apt-get install autotools-dev autoconf automake libtool + + FreeBSD: + --------- + On FreeBSD you will need to install GNU make, libiconv, and + optionally Fox-Toolkit (for the test GUI). This is done by running + the following: + pkg_add -r gmake libiconv fox16 + + If you downloaded the source directly from the git repository (using + git clone), you'll need Autotools: + pkg_add -r autotools + + Mac: + ----- + On Mac, you will need to install Fox-Toolkit if you wish to build + the Test GUI. There are two ways to do this, and each has a slight + complication. Which method you use depends on your use case. + + If you wish to build the Test GUI just for your own testing on your + own computer, then the easiest method is to install Fox-Toolkit + using ports: + sudo port install fox + + If you wish to build the TestGUI app bundle to redistribute to + others, you will need to install Fox-toolkit from source. This is + because the version of fox that gets installed using ports uses the + ports X11 libraries which are not compatible with the Apple X11 + libraries. If you install Fox with ports and then try to distribute + your built app bundle, it will simply fail to run on other systems. + To install Fox-Toolkit manually, download the source package from + http://www.fox-toolkit.org, extract it, and run the following from + within the extracted source: + ./configure && make && make install + + Windows: + --------- + On Windows, if you want to build the test GUI, you will need to get + the hidapi-externals.zip package from the download site. This + contains pre-built binaries for Fox-toolkit. Extract + hidapi-externals.zip just outside of hidapi, so that + hidapi-externals and hidapi are on the same level, as shown: + + Parent_Folder + | + +hidapi + +hidapi-externals + + Again, this step is not required if you do not wish to build the + test GUI. + + +Building HIDAPI into a shared library on Unix Platforms: +--------------------------------------------------------- + +On Unix-like systems such as Linux, FreeBSD, Mac, and even Windows, using +Mingw or Cygwin, the easiest way to build a standard system-installed shared +library is to use the GNU Autotools build system. If you checked out the +source from the git repository, run the following: + + ./bootstrap + ./configure + make + make install <----- as root, or using sudo + +If you downloaded a source package (ie: if you did not run git clone), you +can skip the ./bootstrap step. + +./configure can take several arguments which control the build. The two most +likely to be used are: + --enable-testgui + Enable build of the Test GUI. This requires Fox toolkit to + be installed. Instructions for installing Fox-Toolkit on + each platform are in the Prerequisites section above. + + --prefix=/usr + Specify where you want the output headers and libraries to + be installed. The example above will put the headers in + /usr/include and the binaries in /usr/lib. The default is to + install into /usr/local which is fine on most systems. + +Building the manual way on Unix platforms: +------------------------------------------- + +Manual Makefiles are provided mostly to give the user and idea what it takes +to build a program which embeds HIDAPI directly inside of it. These should +really be used as examples only. If you want to build a system-wide shared +library, use the Autotools method described above. + + To build HIDAPI using the manual makefiles, change to the directory + of your platform and run make. For example, on Linux run: + cd linux/ + make -f Makefile-manual + + To build the Test GUI using the manual makefiles: + cd testgui/ + make -f Makefile-manual + +Building on Windows: +--------------------- + +To build the HIDAPI DLL on Windows using Visual Studio, build the .sln file +in the windows/ directory. + +To build the Test GUI on windows using Visual Studio, build the .sln file in +the testgui/ directory. + +To build HIDAPI using MinGW or Cygwin using Autotools, use the instructions +in the section titled "Building HIDAPI into a shared library on Unix +Platforms" above. Note that building the Test GUI with MinGW or Cygwin will +require the Windows procedure in the Prerequisites section above (ie: +hidapi-externals.zip). + +To build HIDAPI using MinGW using the Manual Makefiles, see the section +"Building the manual way on Unix platforms" above. + +HIDAPI can also be built using the Windows DDK (now also called the Windows +Driver Kit or WDK). This method was originally required for the HIDAPI build +but not anymore. However, some users still prefer this method. It is not as +well supported anymore but should still work. Patches are welcome if it does +not. To build using the DDK: + + 1. Install the Windows Driver Kit (WDK) from Microsoft. + 2. From the Start menu, in the Windows Driver Kits folder, select Build + Environments, then your operating system, then the x86 Free Build + Environment (or one that is appropriate for your system). + 3. From the console, change directory to the windows/ddk_build/ directory, + which is part of the HIDAPI distribution. + 4. Type build. + 5. You can find the output files (DLL and LIB) in a subdirectory created + by the build system which is appropriate for your environment. On + Windows XP, this directory is objfre_wxp_x86/i386. + +Cross Compiling +================ + +This section talks about cross compiling HIDAPI for Linux using autotools. +This is useful for using HIDAPI on embedded Linux targets. These +instructions assume the most raw kind of embedded Linux build, where all +prerequisites will need to be built first. This process will of course vary +based on your embedded Linux build system if you are using one, such as +OpenEmbedded or Buildroot. + +For the purpose of this section, it will be assumed that the following +environment variables are exported. + + $ export STAGING=$HOME/out + $ export HOST=arm-linux + +STAGING and HOST can be modified to suit your setup. + +Prerequisites +-------------- + +Note that the build of libudev is the very basic configuration. + +Build Libusb. From the libusb source directory, run: + ./configure --host=$HOST --prefix=$STAGING + make + make install + +Build libudev. From the libudev source directory, run: + ./configure --disable-gudev --disable-introspection --disable-hwdb \ + --host=$HOST --prefix=$STAGING + make + make install + +Building HIDAPI +---------------- + +Build HIDAPI: + + PKG_CONFIG_DIR= \ + PKG_CONFIG_LIBDIR=$STAGING/lib/pkgconfig:$STAGING/share/pkgconfig \ + PKG_CONFIG_SYSROOT_DIR=$STAGING \ + ./configure --host=$HOST --prefix=$STAGING + + +Signal 11 Software - 2010-04-11 + 2010-07-28 + 2011-09-10 + 2012-05-01 + 2012-07-03 diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/hidapi/hidapi.h b/go-api-for-hardware-wallet/usbhid/c/hidapi/hidapi/hidapi.h new file mode 100644 index 00000000..e5bc2dc4 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/hidapi/hidapi.h @@ -0,0 +1,391 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_H__ +#define HIDAPI_H__ + +#include + +#ifdef _WIN32 + #define HID_API_EXPORT __declspec(dllexport) + #define HID_API_CALL +#else + #define HID_API_EXPORT /**< API export macro */ + #define HID_API_CALL /**< API call macro */ +#endif + +#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ + +#ifdef __cplusplus +extern "C" { +#endif + struct hid_device_; + typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + + /** hidapi info structure */ + struct hid_device_info { + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. Valid on both Linux implementations + in all cases, and valid on the Windows implementation + only if the device contains more than one interface. */ + int interface_number; + + /** Pointer to the next device */ + struct hid_device_info *next; + }; + + + /** @brief Initialize the HIDAPI library. + + This function initializes the HIDAPI library. Calling it is not + strictly necessary, as it will be called automatically by + hid_enumerate() and any of the hid_open_*() functions if it is + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_init(void); + + /** @brief Finalize the HIDAPI library. + + This function frees all of the static data associated with + HIDAPI. It should be called at the end of execution to avoid + memory leaks. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_exit(void); + + /** @brief Enumerate the HID Devices. + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. + If @p vendor_id is set to 0 then any vendor matches. + If @p product_id is set to 0 then any product matches. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the types of device + to open. + @param product_id The Product ID (PID) of the types of + device to open. + + @returns + This function returns a pointer to a linked list of type + struct #hid_device, containing information about the HID devices + attached to the system, or NULL in the case of failure. Free + this linked list by calling hid_free_enumeration(). + */ + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); + + /** @brief Free an enumeration Linked List + + This function frees a linked list created by hid_enumerate(). + + @ingroup API + @param devs Pointer to a list of struct_device returned from + hid_enumerate(). + */ + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); + + /** @brief Open a HID device using a Vendor ID (VID), Product ID + (PID) and optionally a serial number. + + If @p serial_number is NULL, the first device with the + specified VID and PID is opened. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the device to open. + @param product_id The Product ID (PID) of the device to open. + @param serial_number The Serial Number of the device to open + (Optionally NULL). + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + + The path name be determined by calling hid_enumerate(), or a + platform-specific path name can be used (eg: /dev/hidraw0 on + Linux). + + @ingroup API + @param path The path name of the device to open + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); + + /** @brief Write an Output report to a HID device. + + The first byte of @p data[] must contain the Report ID. For + devices which only support a single report, this must be set + to 0x0. The remaining bytes contain the report data. Since + the Report ID is mandatory, calls to hid_write() will always + contain one more byte than the report contains. For example, + if a hid report is 16 bytes long, 17 bytes must be passed to + hid_write(), the Report ID (or 0x0, for devices with a + single report), followed by the report data (16 bytes). In + this example, the length passed in would be 17. + + hid_write() will send the data on the first OUT endpoint, if + one exists. If it does not, it will send the data through + the Control Endpoint (Endpoint 0). + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); + + /** @brief Read an Input report from a HID device with timeout. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + @param milliseconds timeout in milliseconds or -1 for blocking wait. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read within + the timeout period, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + + /** @brief Read an Input report from a HID device. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read and + the handle is in non-blocking mode, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + + /** @brief Set the device handle to be non-blocking. + + In non-blocking mode calls to hid_read() will return + immediately with a value of 0 if there is no data to be + read. In blocking mode, hid_read() will wait (block) until + there is data to read before returning. + + Nonblocking can be turned on and off at any time. + + @ingroup API + @param device A device handle returned from hid_open(). + @param nonblock enable or not the nonblocking reads + - 1 to enable nonblocking + - 0 to disable nonblocking. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); + + /** @brief Send a Feature report to the device. + + Feature reports are sent over the Control endpoint as a + Set_Report transfer. The first byte of @p data[] must + contain the Report ID. For devices which only support a + single report, this must be set to 0x0. The remaining bytes + contain the report data. Since the Report ID is mandatory, + calls to hid_send_feature_report() will always contain one + more byte than the report contains. For example, if a hid + report is 16 bytes long, 17 bytes must be passed to + hid_send_feature_report(): the Report ID (or 0x0, for + devices which do not use numbered reports), followed by the + report data (16 bytes). In this example, the length passed + in would be 17. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send, including + the report number. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); + + /** @brief Get a feature report from a HID device. + + Set the first byte of @p data[] to the Report ID of the + report to be read. Make sure to allow space for this + extra byte in @p data[]. Upon return, the first byte will + still contain the Report ID, and the report data will + start in data[1]. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read, or set it to zero + if your device does not use numbered reports. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read plus + one for the report ID (which is still in the first + byte), or -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + + /** @brief Close a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + */ + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); + + /** @brief Get The Manufacturer String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Product String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Serial Number String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get a string from a HID device, based on its string index. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string_index The index of the string to get. + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); + + /** @brief Get a string describing the last error which occurred. + + @ingroup API + @param device A device handle returned from hid_open(). + + @returns + This function returns a string containing the last error + which occurred or NULL if none has occurred. + */ + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/linux/hid.c b/go-api-for-hardware-wallet/usbhid/c/hidapi/linux/hid.c new file mode 100644 index 00000000..b34f0cd6 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/linux/hid.c @@ -0,0 +1,1520 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + Linux Version - 6/2/2010 + Libusb Version - 8/13/2010 + FreeBSD Version - 11/1/2011 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/* C */ +#include +#include +#include +#include +#include +#include + +/* Unix */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* GNU / LibUSB */ +#include +#ifndef __ANDROID__ +#include +#endif + +#include "hidapi/hidapi.h" + +#ifdef __ANDROID__ + +/* Barrier implementation because Android/Bionic don't have pthread_barrier. + This implementation came from Brent Priddy and was posted on + StackOverflow. It is used with his permission. */ +typedef int pthread_barrierattr_t; +typedef struct pthread_barrier { + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; + int trip_count; +} pthread_barrier_t; + +static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) +{ + if(count == 0) { + errno = EINVAL; + return -1; + } + + if(pthread_mutex_init(&barrier->mutex, 0) < 0) { + return -1; + } + if(pthread_cond_init(&barrier->cond, 0) < 0) { + pthread_mutex_destroy(&barrier->mutex); + return -1; + } + barrier->trip_count = count; + barrier->count = 0; + + return 0; +} + +static int pthread_barrier_destroy(pthread_barrier_t *barrier) +{ + pthread_cond_destroy(&barrier->cond); + pthread_mutex_destroy(&barrier->mutex); + return 0; +} + +static int pthread_barrier_wait(pthread_barrier_t *barrier) +{ + pthread_mutex_lock(&barrier->mutex); + ++(barrier->count); + if(barrier->count >= barrier->trip_count) + { + barrier->count = 0; + pthread_cond_broadcast(&barrier->cond); + pthread_mutex_unlock(&barrier->mutex); + return 1; + } + else + { + pthread_cond_wait(&barrier->cond, &(barrier->mutex)); + pthread_mutex_unlock(&barrier->mutex); + return 0; + } +} + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEBUG_PRINTF +#define LOG(...) fprintf(stderr, __VA_ARGS__) +#else +#define LOG(...) do {} while (0) +#endif + +#ifndef __FreeBSD__ +#define DETACH_KERNEL_DRIVER +#endif + +/* Uncomment to enable the retrieval of Usage and Usage Page in +hid_enumerate(). Warning, on platforms different from FreeBSD +this is very invasive as it requires the detach +and re-attach of the kernel driver. See comments inside hid_enumerate(). +libusb HIDAPI programs are encouraged to use the interface number +instead to differentiate between interfaces on a composite HID device. */ +/*#define INVASIVE_GET_USAGE*/ + +/* Linked List of input reports received from the device. */ +struct input_report { + uint8_t *data; + size_t len; + struct input_report *next; +}; + + +struct hid_device_ { + /* Handle to the actual device. */ + libusb_device_handle *device_handle; + + /* Endpoint information */ + int input_endpoint; + int output_endpoint; + int input_ep_max_packet_size; + + /* The interface number of the HID */ + int interface; + + /* Indexes of Strings */ + int manufacturer_index; + int product_index; + int serial_index; + + /* Whether blocking reads are used */ + int blocking; /* boolean */ + + /* Read thread objects */ + pthread_t thread; + pthread_mutex_t mutex; /* Protects input_reports */ + pthread_cond_t condition; + pthread_barrier_t barrier; /* Ensures correct startup sequence */ + int shutdown_thread; + int cancelled; + struct libusb_transfer *transfer; + + /* List of received input reports. */ + struct input_report *input_reports; +}; + +static libusb_context *usb_context = NULL; + +uint16_t get_usb_code_for_current_locale(void); +static int return_data(hid_device *dev, unsigned char *data, size_t length); + +static hid_device *new_hid_device(void) +{ + hid_device *dev = calloc(1, sizeof(hid_device)); + dev->blocking = 1; + + pthread_mutex_init(&dev->mutex, NULL); + pthread_cond_init(&dev->condition, NULL); + pthread_barrier_init(&dev->barrier, NULL, 2); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + /* Clean up the thread objects */ + pthread_barrier_destroy(&dev->barrier); + pthread_cond_destroy(&dev->condition); + pthread_mutex_destroy(&dev->mutex); + + /* Free the device itself */ + free(dev); +} + +#if 0 +/*TODO: Implement this funciton on hidapi/libusb.. */ +static void register_error(hid_device *device, const char *op) +{ + +} +#endif + +#ifdef INVASIVE_GET_USAGE +/* Get bytes from a HID Report Descriptor. + Only call with a num_bytes of 0, 1, 2, or 4. */ +static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur) +{ + /* Return if there aren't enough bytes. */ + if (cur + num_bytes >= len) + return 0; + + if (num_bytes == 0) + return 0; + else if (num_bytes == 1) { + return rpt[cur+1]; + } + else if (num_bytes == 2) { + return (rpt[cur+2] * 256 + rpt[cur+1]); + } + else if (num_bytes == 4) { + return (rpt[cur+4] * 0x01000000 + + rpt[cur+3] * 0x00010000 + + rpt[cur+2] * 0x00000100 + + rpt[cur+1] * 0x00000001); + } + else + return 0; +} + +/* Retrieves the device's Usage Page and Usage from the report + descriptor. The algorithm is simple, as it just returns the first + Usage and Usage Page that it finds in the descriptor. + The return value is 0 on success and -1 on failure. */ +static int get_usage(uint8_t *report_descriptor, size_t size, + unsigned short *usage_page, unsigned short *usage) +{ + unsigned int i = 0; + int size_code; + int data_len, key_size; + int usage_found = 0, usage_page_found = 0; + + while (i < size) { + int key = report_descriptor[i]; + int key_cmd = key & 0xfc; + + //printf("key: %02hhx\n", key); + + if ((key & 0xf0) == 0xf0) { + /* This is a Long Item. The next byte contains the + length of the data section (value) for this key. + See the HID specification, version 1.11, section + 6.2.2.3, titled "Long Items." */ + if (i+1 < size) + data_len = report_descriptor[i+1]; + else + data_len = 0; /* malformed report */ + key_size = 3; + } + else { + /* This is a Short Item. The bottom two bits of the + key contain the size code for the data section + (value) for this key. Refer to the HID + specification, version 1.11, section 6.2.2.2, + titled "Short Items." */ + size_code = key & 0x3; + switch (size_code) { + case 0: + case 1: + case 2: + data_len = size_code; + break; + case 3: + data_len = 4; + break; + default: + /* Can't ever happen since size_code is & 0x3 */ + data_len = 0; + break; + }; + key_size = 1; + } + + if (key_cmd == 0x4) { + *usage_page = get_bytes(report_descriptor, size, data_len, i); + usage_page_found = 1; + //printf("Usage Page: %x\n", (uint32_t)*usage_page); + } + if (key_cmd == 0x8) { + *usage = get_bytes(report_descriptor, size, data_len, i); + usage_found = 1; + //printf("Usage: %x\n", (uint32_t)*usage); + } + + if (usage_page_found && usage_found) + return 0; /* success */ + + /* Skip over this key and it's associated data */ + i += data_len + key_size; + } + + return -1; /* failure */ +} +#endif /* INVASIVE_GET_USAGE */ + +#if defined(__FreeBSD__) && __FreeBSD__ < 10 +/* The libusb version included in FreeBSD < 10 doesn't have this function. In + mainline libusb, it's inlined in libusb.h. This function will bear a striking + resemblance to that one, because there's about one way to code it. + + Note that the data parameter is Unicode in UTF-16LE encoding. + Return value is the number of bytes in data, or LIBUSB_ERROR_*. + */ +static inline int libusb_get_string_descriptor(libusb_device_handle *dev, + uint8_t descriptor_index, uint16_t lang_id, + unsigned char *data, int length) +{ + return libusb_control_transfer(dev, + LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */ + LIBUSB_REQUEST_GET_DESCRIPTOR, + (LIBUSB_DT_STRING << 8) | descriptor_index, + lang_id, data, (uint16_t) length, 1000); +} + +#endif + + +/* Get the first language the device says it reports. This comes from + USB string #0. */ +static uint16_t get_first_language(libusb_device_handle *dev) +{ + uint16_t buf[32]; + int len; + + /* Get the string from libusb. */ + len = libusb_get_string_descriptor(dev, + 0x0, /* String ID */ + 0x0, /* Language */ + (unsigned char*)buf, + sizeof(buf)); + if (len < 4) + return 0x0; + + return buf[1]; /* First two bytes are len and descriptor type. */ +} + +static int is_language_supported(libusb_device_handle *dev, uint16_t lang) +{ + uint16_t buf[32]; + int len; + int i; + + /* Get the string from libusb. */ + len = libusb_get_string_descriptor(dev, + 0x0, /* String ID */ + 0x0, /* Language */ + (unsigned char*)buf, + sizeof(buf)); + if (len < 4) + return 0x0; + + + len /= 2; /* language IDs are two-bytes each. */ + /* Start at index 1 because there are two bytes of protocol data. */ + for (i = 1; i < len; i++) { + if (buf[i] == lang) + return 1; + } + + return 0; +} + + +/* This function returns a newly allocated wide string containing the USB + device string numbered by the index. The returned string must be freed + by using free(). */ +static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) +{ + char buf[512]; + int len; + wchar_t *str = NULL; + +#ifndef __ANDROID__ /* we don't use iconv on Android */ + wchar_t wbuf[256]; + /* iconv variables */ + iconv_t ic; + size_t inbytes; + size_t outbytes; + size_t res; +#ifdef __FreeBSD__ + const char *inptr; +#else + char *inptr; +#endif + char *outptr; +#endif + + /* Determine which language to use. */ + uint16_t lang; + lang = get_usb_code_for_current_locale(); + if (!is_language_supported(dev, lang)) + lang = get_first_language(dev); + + /* Get the string from libusb. */ + len = libusb_get_string_descriptor(dev, + idx, + lang, + (unsigned char*)buf, + sizeof(buf)); + if (len < 0) + return NULL; + +#ifdef __ANDROID__ + + /* Bionic does not have iconv support nor wcsdup() function, so it + has to be done manually. The following code will only work for + code points that can be represented as a single UTF-16 character, + and will incorrectly convert any code points which require more + than one UTF-16 character. + + Skip over the first character (2-bytes). */ + len -= 2; + str = malloc((len / 2 + 1) * sizeof(wchar_t)); + int i; + for (i = 0; i < len / 2; i++) { + str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); + } + str[len / 2] = 0x00000000; + +#else + + /* buf does not need to be explicitly NULL-terminated because + it is only passed into iconv() which does not need it. */ + + /* Initialize iconv. */ + ic = iconv_open("WCHAR_T", "UTF-16LE"); + if (ic == (iconv_t)-1) { + LOG("iconv_open() failed\n"); + return NULL; + } + + /* Convert to native wchar_t (UTF-32 on glibc/BSD systems). + Skip the first character (2-bytes). */ + inptr = buf+2; + inbytes = len-2; + outptr = (char*) wbuf; + outbytes = sizeof(wbuf); + res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes); + if (res == (size_t)-1) { + LOG("iconv() failed\n"); + goto err; + } + + /* Write the terminating NULL. */ + wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; + if (outbytes >= sizeof(wbuf[0])) + *((wchar_t*)outptr) = 0x00000000; + + /* Allocate and copy the string. */ + str = wcsdup(wbuf); + +err: + iconv_close(ic); + +#endif + + return str; +} + +static char *make_path(libusb_device *dev, int interface_number) +{ + char str[64]; + snprintf(str, sizeof(str), "%04x:%04x:%02x", + libusb_get_bus_number(dev), + libusb_get_device_address(dev), + interface_number); + str[sizeof(str)-1] = '\0'; + + return strdup(str); +} + + +int HID_API_EXPORT hid_init(void) +{ + if (!usb_context) { + const char *locale; + + /* Init Libusb */ + if (libusb_init(&usb_context)) + return -1; + + /* Set the locale if it's not set. */ + locale = setlocale(LC_CTYPE, NULL); + if (!locale) + setlocale(LC_CTYPE, ""); + } + + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ + if (usb_context) { + libusb_exit(usb_context); + usb_context = NULL; + } + + return 0; +} + +struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + libusb_device **devs; + libusb_device *dev; + libusb_device_handle *handle; + ssize_t num_devs; + int i = 0; + + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + + if(hid_init() < 0) + return NULL; + + num_devs = libusb_get_device_list(usb_context, &devs); + if (num_devs < 0) + return NULL; + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + struct libusb_config_descriptor *conf_desc = NULL; + int j, k; + int interface_num = 0; + + int res = libusb_get_device_descriptor(dev, &desc); + unsigned short dev_vid = desc.idVendor; + unsigned short dev_pid = desc.idProduct; + + res = libusb_get_active_config_descriptor(dev, &conf_desc); + if (res < 0) + libusb_get_config_descriptor(dev, 0, &conf_desc); + if (conf_desc) { + for (j = 0; j < conf_desc->bNumInterfaces; j++) { + const struct libusb_interface *intf = &conf_desc->interface[j]; + for (k = 0; k < intf->num_altsetting; k++) { + const struct libusb_interface_descriptor *intf_desc; + intf_desc = &intf->altsetting[k]; + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { + interface_num = intf_desc->bInterfaceNumber; + + /* Check the VID/PID against the arguments */ + if ((vendor_id == 0x0 || vendor_id == dev_vid) && + (product_id == 0x0 || product_id == dev_pid)) { + struct hid_device_info *tmp; + + /* VID/PID match. Create the record. */ + tmp = calloc(1, sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Fill out the record */ + cur_dev->next = NULL; + cur_dev->path = make_path(dev, interface_num); +#ifdef GET_INFO_STRINGS + /* + Lookup of device details like serial number and + manufacturer/product strings causes lock-ups in + highly concurrent conditions. Enable + GET_INFO_STRINGS to report back the string + details. */ + res = libusb_open(dev, &handle); + + if (res >= 0) { + /* Serial Number */ + if (desc.iSerialNumber > 0) + cur_dev->serial_number = + get_usb_string(handle, desc.iSerialNumber); + + /* Manufacturer and Product strings */ + if (desc.iManufacturer > 0) + cur_dev->manufacturer_string = + get_usb_string(handle, desc.iManufacturer); + if (desc.iProduct > 0) + cur_dev->product_string = + get_usb_string(handle, desc.iProduct); + +#ifdef INVASIVE_GET_USAGE +{ + /* + This section is removed because it is too + invasive on the system. Getting a Usage Page + and Usage requires parsing the HID Report + descriptor. Getting a HID Report descriptor + involves claiming the interface. Claiming the + interface involves detaching the kernel driver. + Detaching the kernel driver is hard on the system + because it will unclaim interfaces (if another + app has them claimed) and the re-attachment of + the driver will sometimes change /dev entry names. + It is for these reasons that this section is + #if 0. For composite devices, use the interface + field in the hid_device_info struct to distinguish + between interfaces. */ + unsigned char data[256]; +#ifdef DETACH_KERNEL_DRIVER + int detached = 0; + /* Usage Page and Usage */ + res = libusb_kernel_driver_active(handle, interface_num); + if (res == 1) { + res = libusb_detach_kernel_driver(handle, interface_num); + if (res < 0) + LOG("Couldn't detach kernel driver, even though a kernel driver was attached."); + else + detached = 1; + } +#endif + res = libusb_claim_interface(handle, interface_num); + if (res >= 0) { + /* Get the HID Report Descriptor. */ + res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000); + if (res >= 0) { + unsigned short page=0, usage=0; + /* Parse the usage and usage page + out of the report descriptor. */ + get_usage(data, res, &page, &usage); + cur_dev->usage_page = page; + cur_dev->usage = usage; + } + else + LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res); + + /* Release the interface */ + res = libusb_release_interface(handle, interface_num); + if (res < 0) + LOG("Can't release the interface.\n"); + } + else + LOG("Can't claim interface %d\n", res); +#ifdef DETACH_KERNEL_DRIVER + /* Re-attach kernel driver if necessary. */ + if (detached) { + res = libusb_attach_kernel_driver(handle, interface_num); + if (res < 0) + LOG("Couldn't re-attach kernel driver.\n"); + } +#endif +} +#endif /* INVASIVE_GET_USAGE */ + + libusb_close(handle); + } +#endif /* GET_INFO_STRINGS */ + + /* VID/PID */ + cur_dev->vendor_id = dev_vid; + cur_dev->product_id = dev_pid; + + /* Release Number */ + cur_dev->release_number = desc.bcdDevice; + + /* Interface Number */ + cur_dev->interface_number = interface_num; + } + } + } /* altsettings */ + } /* interfaces */ + libusb_free_config_descriptor(conf_desc); + } + } + + libusb_free_device_list(devs, 1); + + return root; +} + +void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) +{ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + +hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device *handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (cur_dev->serial_number && + wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open); + } + + hid_free_enumeration(devs); + + return handle; +} + +static void read_callback(struct libusb_transfer *transfer) +{ + hid_device *dev = transfer->user_data; + int res; + + if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { + + struct input_report *rpt = malloc(sizeof(*rpt)); + rpt->data = malloc(transfer->actual_length); + memcpy(rpt->data, transfer->buffer, transfer->actual_length); + rpt->len = transfer->actual_length; + rpt->next = NULL; + + pthread_mutex_lock(&dev->mutex); + + /* Attach the new report object to the end of the list. */ + if (dev->input_reports == NULL) { + /* The list is empty. Put it at the root. */ + dev->input_reports = rpt; + pthread_cond_signal(&dev->condition); + } + else { + /* Find the end of the list and attach. */ + struct input_report *cur = dev->input_reports; + int num_queued = 0; + while (cur->next != NULL) { + cur = cur->next; + num_queued++; + } + cur->next = rpt; + + /* Pop one off if we've reached 30 in the queue. This + way we don't grow forever if the user never reads + anything from the device. */ + if (num_queued > 30) { + return_data(dev, NULL, 0); + } + } + pthread_mutex_unlock(&dev->mutex); + } + else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { + dev->shutdown_thread = 1; + dev->cancelled = 1; + return; + } + else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { + dev->shutdown_thread = 1; + dev->cancelled = 1; + return; + } + else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) { + //LOG("Timeout (normal)\n"); + } + else { + LOG("Unknown transfer code: %d\n", transfer->status); + } + + /* Re-submit the transfer object. */ + res = libusb_submit_transfer(transfer); + if (res != 0) { + LOG("Unable to submit URB. libusb error code: %d\n", res); + dev->shutdown_thread = 1; + dev->cancelled = 1; + } +} + + +static void *read_thread(void *param) +{ + hid_device *dev = param; + unsigned char *buf; + const size_t length = dev->input_ep_max_packet_size; + + /* Set up the transfer object. */ + buf = malloc(length); + dev->transfer = libusb_alloc_transfer(0); + libusb_fill_interrupt_transfer(dev->transfer, + dev->device_handle, + dev->input_endpoint, + buf, + length, + read_callback, + dev, + 5000/*timeout*/); + + /* Make the first submission. Further submissions are made + from inside read_callback() */ + libusb_submit_transfer(dev->transfer); + + /* Notify the main thread that the read thread is up and running. */ + pthread_barrier_wait(&dev->barrier); + + /* Handle all the events. */ + while (!dev->shutdown_thread) { + int res; + res = libusb_handle_events(usb_context); + if (res < 0) { + /* There was an error. */ + LOG("read_thread(): libusb reports error # %d\n", res); + + /* Break out of this loop only on fatal error.*/ + if (res != LIBUSB_ERROR_BUSY && + res != LIBUSB_ERROR_TIMEOUT && + res != LIBUSB_ERROR_OVERFLOW && + res != LIBUSB_ERROR_INTERRUPTED) { + break; + } + } + } + + /* Cancel any transfer that may be pending. This call will fail + if no transfers are pending, but that's OK. */ + libusb_cancel_transfer(dev->transfer); + + while (!dev->cancelled) + libusb_handle_events_completed(usb_context, &dev->cancelled); + + /* Now that the read thread is stopping, Wake any threads which are + waiting on data (in hid_read_timeout()). Do this under a mutex to + make sure that a thread which is about to go to sleep waiting on + the condition actually will go to sleep before the condition is + signaled. */ + pthread_mutex_lock(&dev->mutex); + pthread_cond_broadcast(&dev->condition); + pthread_mutex_unlock(&dev->mutex); + + /* The dev->transfer->buffer and dev->transfer objects are cleaned up + in hid_close(). They are not cleaned up here because this thread + could end either due to a disconnect or due to a user + call to hid_close(). In both cases the objects can be safely + cleaned up after the call to pthread_join() (in hid_close()), but + since hid_close() calls libusb_cancel_transfer(), on these objects, + they can not be cleaned up here. */ + + return NULL; +} + + +hid_device * HID_API_EXPORT hid_open_path(const char *path) +{ + hid_device *dev = NULL; + + libusb_device **devs; + libusb_device *usb_dev; + int res; + int d = 0; + int good_open = 0; + + if(hid_init() < 0) + return NULL; + + dev = new_hid_device(); + + libusb_get_device_list(usb_context, &devs); + while ((usb_dev = devs[d++]) != NULL) { + struct libusb_device_descriptor desc; + struct libusb_config_descriptor *conf_desc = NULL; + int i,j,k; + libusb_get_device_descriptor(usb_dev, &desc); + + if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0) + continue; + for (j = 0; j < conf_desc->bNumInterfaces; j++) { + const struct libusb_interface *intf = &conf_desc->interface[j]; + for (k = 0; k < intf->num_altsetting; k++) { + const struct libusb_interface_descriptor *intf_desc; + intf_desc = &intf->altsetting[k]; + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { + char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber); + if (!strcmp(dev_path, path)) { + /* Matched Paths. Open this device */ + + /* OPEN HERE */ + res = libusb_open(usb_dev, &dev->device_handle); + if (res < 0) { + LOG("can't open device\n"); + free(dev_path); + break; + } + good_open = 1; +#ifdef DETACH_KERNEL_DRIVER + /* Detach the kernel driver, but only if the + device is managed by the kernel */ + if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) { + res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber); + if (res < 0) { + libusb_close(dev->device_handle); + LOG("Unable to detach Kernel Driver\n"); + free(dev_path); + good_open = 0; + break; + } + } +#endif + res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber); + if (res < 0) { + LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); + free(dev_path); + libusb_close(dev->device_handle); + good_open = 0; + break; + } + + /* Store off the string descriptor indexes */ + dev->manufacturer_index = desc.iManufacturer; + dev->product_index = desc.iProduct; + dev->serial_index = desc.iSerialNumber; + + /* Store off the interface number */ + dev->interface = intf_desc->bInterfaceNumber; + + /* Find the INPUT and OUTPUT endpoints. An + OUTPUT endpoint is not required. */ + for (i = 0; i < intf_desc->bNumEndpoints; i++) { + const struct libusb_endpoint_descriptor *ep + = &intf_desc->endpoint[i]; + + /* Determine the type and direction of this + endpoint. */ + int is_interrupt = + (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) + == LIBUSB_TRANSFER_TYPE_INTERRUPT; + int is_output = + (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_OUT; + int is_input = + (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_IN; + + /* Decide whether to use it for input or output. */ + if (dev->input_endpoint == 0 && + is_interrupt && is_input) { + /* Use this endpoint for INPUT */ + dev->input_endpoint = ep->bEndpointAddress; + dev->input_ep_max_packet_size = ep->wMaxPacketSize; + } + if (dev->output_endpoint == 0 && + is_interrupt && is_output) { + /* Use this endpoint for OUTPUT */ + dev->output_endpoint = ep->bEndpointAddress; + } + } + + pthread_create(&dev->thread, NULL, read_thread, dev); + + /* Wait here for the read thread to be initialized. */ + pthread_barrier_wait(&dev->barrier); + + } + free(dev_path); + } + } + } + libusb_free_config_descriptor(conf_desc); + + } + + libusb_free_device_list(devs, 1); + + /* If we have a good handle, return it. */ + if (good_open) { + return dev; + } + else { + /* Unable to open any devices. */ + free_hid_device(dev); + return NULL; + } +} + + +int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + int res; + int report_number = data[0]; + int skipped_report_id = 0; + + if (report_number == 0x0) { + data++; + length--; + skipped_report_id = 1; + } + + + if (dev->output_endpoint <= 0) { + /* No interrupt out endpoint. Use the Control Endpoint */ + res = libusb_control_transfer(dev->device_handle, + LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, + 0x09/*HID Set_Report*/, + (2/*HID output*/ << 8) | report_number, + dev->interface, + (unsigned char *)data, length, + 1000/*timeout millis*/); + + if (res < 0) + return -1; + + if (skipped_report_id) + length++; + + return length; + } + else { + /* Use the interrupt out endpoint */ + int actual_length; + res = libusb_interrupt_transfer(dev->device_handle, + dev->output_endpoint, + (unsigned char*)data, + length, + &actual_length, 1000); + + if (res < 0) + return -1; + + if (skipped_report_id) + actual_length++; + + return actual_length; + } +} + +/* Helper function, to simplify hid_read(). + This should be called with dev->mutex locked. */ +static int return_data(hid_device *dev, unsigned char *data, size_t length) +{ + /* Copy the data out of the linked list item (rpt) into the + return buffer (data), and delete the liked list item. */ + struct input_report *rpt = dev->input_reports; + size_t len = (length < rpt->len)? length: rpt->len; + if (len > 0) + memcpy(data, rpt->data, len); + dev->input_reports = rpt->next; + free(rpt->data); + free(rpt); + return len; +} + +static void cleanup_mutex(void *param) +{ + hid_device *dev = param; + pthread_mutex_unlock(&dev->mutex); +} + + +int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + int bytes_read = -1; + +#if 0 + int transferred; + int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); + LOG("transferred: %d\n", transferred); + return transferred; +#endif + + pthread_mutex_lock(&dev->mutex); + pthread_cleanup_push(&cleanup_mutex, dev); + + /* There's an input report queued up. Return it. */ + if (dev->input_reports) { + /* Return the first one */ + bytes_read = return_data(dev, data, length); + goto ret; + } + + if (dev->shutdown_thread) { + /* This means the device has been disconnected. + An error code of -1 should be returned. */ + bytes_read = -1; + goto ret; + } + + if (milliseconds == -1) { + /* Blocking */ + while (!dev->input_reports && !dev->shutdown_thread) { + pthread_cond_wait(&dev->condition, &dev->mutex); + } + if (dev->input_reports) { + bytes_read = return_data(dev, data, length); + } + } + else if (milliseconds > 0) { + /* Non-blocking, but called with timeout. */ + int res; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += milliseconds / 1000; + ts.tv_nsec += (milliseconds % 1000) * 1000000; + if (ts.tv_nsec >= 1000000000L) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000L; + } + + while (!dev->input_reports && !dev->shutdown_thread) { + res = pthread_cond_timedwait(&dev->condition, &dev->mutex, &ts); + if (res == 0) { + if (dev->input_reports) { + bytes_read = return_data(dev, data, length); + break; + } + + /* If we're here, there was a spurious wake up + or the read thread was shutdown. Run the + loop again (ie: don't break). */ + } + else if (res == ETIMEDOUT) { + /* Timed out. */ + bytes_read = 0; + break; + } + else { + /* Error. */ + bytes_read = -1; + break; + } + } + } + else { + /* Purely non-blocking */ + bytes_read = 0; + } + +ret: + pthread_mutex_unlock(&dev->mutex); + pthread_cleanup_pop(0); + + return bytes_read; +} + +int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, dev->blocking ? -1 : 0); +} + +int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) +{ + dev->blocking = !nonblock; + + return 0; +} + + +int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + int res = -1; + int skipped_report_id = 0; + int report_number = data[0]; + + if (report_number == 0x0) { + data++; + length--; + skipped_report_id = 1; + } + + res = libusb_control_transfer(dev->device_handle, + LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, + 0x09/*HID set_report*/, + (3/*HID feature*/ << 8) | report_number, + dev->interface, + (unsigned char *)data, length, + 1000/*timeout millis*/); + + if (res < 0) + return -1; + + /* Account for the report ID */ + if (skipped_report_id) + length++; + + return length; +} + +int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + int res = -1; + int skipped_report_id = 0; + int report_number = data[0]; + + if (report_number == 0x0) { + /* Offset the return buffer by 1, so that the report ID + will remain in byte 0. */ + data++; + length--; + skipped_report_id = 1; + } + res = libusb_control_transfer(dev->device_handle, + LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, + 0x01/*HID get_report*/, + (3/*HID feature*/ << 8) | report_number, + dev->interface, + (unsigned char *)data, length, + 1000/*timeout millis*/); + + if (res < 0) + return -1; + + if (skipped_report_id) + res++; + + return res; +} + + +void HID_API_EXPORT hid_close(hid_device *dev) +{ + if (!dev) + return; + + /* Cause read_thread() to stop. */ + dev->shutdown_thread = 1; + libusb_cancel_transfer(dev->transfer); + + /* Wait for read_thread() to end. */ + pthread_join(dev->thread, NULL); + + /* Clean up the Transfer objects allocated in read_thread(). */ + free(dev->transfer->buffer); + libusb_free_transfer(dev->transfer); + + /* release the interface */ + libusb_release_interface(dev->device_handle, dev->interface); + + /* Close the handle */ + libusb_close(dev->device_handle); + + /* Clear out the queue of received reports. */ + pthread_mutex_lock(&dev->mutex); + while (dev->input_reports) { + return_data(dev, NULL, 0); + } + pthread_mutex_unlock(&dev->mutex); + + free_hid_device(dev); +} + + +int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return hid_get_indexed_string(dev, dev->product_index, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return hid_get_indexed_string(dev, dev->serial_index, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + wchar_t *str; + + str = get_usb_string(dev->device_handle, string_index); + if (str) { + wcsncpy(string, str, maxlen); + string[maxlen-1] = L'\0'; + free(str); + return 0; + } + else + return -1; +} + + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + return NULL; +} + + +struct lang_map_entry { + const char *name; + const char *string_code; + uint16_t usb_code; +}; + +#define LANG(name,code,usb_code) { name, code, usb_code } +static struct lang_map_entry lang_map[] = { + LANG("Afrikaans", "af", 0x0436), + LANG("Albanian", "sq", 0x041C), + LANG("Arabic - United Arab Emirates", "ar_ae", 0x3801), + LANG("Arabic - Bahrain", "ar_bh", 0x3C01), + LANG("Arabic - Algeria", "ar_dz", 0x1401), + LANG("Arabic - Egypt", "ar_eg", 0x0C01), + LANG("Arabic - Iraq", "ar_iq", 0x0801), + LANG("Arabic - Jordan", "ar_jo", 0x2C01), + LANG("Arabic - Kuwait", "ar_kw", 0x3401), + LANG("Arabic - Lebanon", "ar_lb", 0x3001), + LANG("Arabic - Libya", "ar_ly", 0x1001), + LANG("Arabic - Morocco", "ar_ma", 0x1801), + LANG("Arabic - Oman", "ar_om", 0x2001), + LANG("Arabic - Qatar", "ar_qa", 0x4001), + LANG("Arabic - Saudi Arabia", "ar_sa", 0x0401), + LANG("Arabic - Syria", "ar_sy", 0x2801), + LANG("Arabic - Tunisia", "ar_tn", 0x1C01), + LANG("Arabic - Yemen", "ar_ye", 0x2401), + LANG("Armenian", "hy", 0x042B), + LANG("Azeri - Latin", "az_az", 0x042C), + LANG("Azeri - Cyrillic", "az_az", 0x082C), + LANG("Basque", "eu", 0x042D), + LANG("Belarusian", "be", 0x0423), + LANG("Bulgarian", "bg", 0x0402), + LANG("Catalan", "ca", 0x0403), + LANG("Chinese - China", "zh_cn", 0x0804), + LANG("Chinese - Hong Kong SAR", "zh_hk", 0x0C04), + LANG("Chinese - Macau SAR", "zh_mo", 0x1404), + LANG("Chinese - Singapore", "zh_sg", 0x1004), + LANG("Chinese - Taiwan", "zh_tw", 0x0404), + LANG("Croatian", "hr", 0x041A), + LANG("Czech", "cs", 0x0405), + LANG("Danish", "da", 0x0406), + LANG("Dutch - Netherlands", "nl_nl", 0x0413), + LANG("Dutch - Belgium", "nl_be", 0x0813), + LANG("English - Australia", "en_au", 0x0C09), + LANG("English - Belize", "en_bz", 0x2809), + LANG("English - Canada", "en_ca", 0x1009), + LANG("English - Caribbean", "en_cb", 0x2409), + LANG("English - Ireland", "en_ie", 0x1809), + LANG("English - Jamaica", "en_jm", 0x2009), + LANG("English - New Zealand", "en_nz", 0x1409), + LANG("English - Phillippines", "en_ph", 0x3409), + LANG("English - Southern Africa", "en_za", 0x1C09), + LANG("English - Trinidad", "en_tt", 0x2C09), + LANG("English - Great Britain", "en_gb", 0x0809), + LANG("English - United States", "en_us", 0x0409), + LANG("Estonian", "et", 0x0425), + LANG("Farsi", "fa", 0x0429), + LANG("Finnish", "fi", 0x040B), + LANG("Faroese", "fo", 0x0438), + LANG("French - France", "fr_fr", 0x040C), + LANG("French - Belgium", "fr_be", 0x080C), + LANG("French - Canada", "fr_ca", 0x0C0C), + LANG("French - Luxembourg", "fr_lu", 0x140C), + LANG("French - Switzerland", "fr_ch", 0x100C), + LANG("Gaelic - Ireland", "gd_ie", 0x083C), + LANG("Gaelic - Scotland", "gd", 0x043C), + LANG("German - Germany", "de_de", 0x0407), + LANG("German - Austria", "de_at", 0x0C07), + LANG("German - Liechtenstein", "de_li", 0x1407), + LANG("German - Luxembourg", "de_lu", 0x1007), + LANG("German - Switzerland", "de_ch", 0x0807), + LANG("Greek", "el", 0x0408), + LANG("Hebrew", "he", 0x040D), + LANG("Hindi", "hi", 0x0439), + LANG("Hungarian", "hu", 0x040E), + LANG("Icelandic", "is", 0x040F), + LANG("Indonesian", "id", 0x0421), + LANG("Italian - Italy", "it_it", 0x0410), + LANG("Italian - Switzerland", "it_ch", 0x0810), + LANG("Japanese", "ja", 0x0411), + LANG("Korean", "ko", 0x0412), + LANG("Latvian", "lv", 0x0426), + LANG("Lithuanian", "lt", 0x0427), + LANG("F.Y.R.O. Macedonia", "mk", 0x042F), + LANG("Malay - Malaysia", "ms_my", 0x043E), + LANG("Malay – Brunei", "ms_bn", 0x083E), + LANG("Maltese", "mt", 0x043A), + LANG("Marathi", "mr", 0x044E), + LANG("Norwegian - Bokml", "no_no", 0x0414), + LANG("Norwegian - Nynorsk", "no_no", 0x0814), + LANG("Polish", "pl", 0x0415), + LANG("Portuguese - Portugal", "pt_pt", 0x0816), + LANG("Portuguese - Brazil", "pt_br", 0x0416), + LANG("Raeto-Romance", "rm", 0x0417), + LANG("Romanian - Romania", "ro", 0x0418), + LANG("Romanian - Republic of Moldova", "ro_mo", 0x0818), + LANG("Russian", "ru", 0x0419), + LANG("Russian - Republic of Moldova", "ru_mo", 0x0819), + LANG("Sanskrit", "sa", 0x044F), + LANG("Serbian - Cyrillic", "sr_sp", 0x0C1A), + LANG("Serbian - Latin", "sr_sp", 0x081A), + LANG("Setsuana", "tn", 0x0432), + LANG("Slovenian", "sl", 0x0424), + LANG("Slovak", "sk", 0x041B), + LANG("Sorbian", "sb", 0x042E), + LANG("Spanish - Spain (Traditional)", "es_es", 0x040A), + LANG("Spanish - Argentina", "es_ar", 0x2C0A), + LANG("Spanish - Bolivia", "es_bo", 0x400A), + LANG("Spanish - Chile", "es_cl", 0x340A), + LANG("Spanish - Colombia", "es_co", 0x240A), + LANG("Spanish - Costa Rica", "es_cr", 0x140A), + LANG("Spanish - Dominican Republic", "es_do", 0x1C0A), + LANG("Spanish - Ecuador", "es_ec", 0x300A), + LANG("Spanish - Guatemala", "es_gt", 0x100A), + LANG("Spanish - Honduras", "es_hn", 0x480A), + LANG("Spanish - Mexico", "es_mx", 0x080A), + LANG("Spanish - Nicaragua", "es_ni", 0x4C0A), + LANG("Spanish - Panama", "es_pa", 0x180A), + LANG("Spanish - Peru", "es_pe", 0x280A), + LANG("Spanish - Puerto Rico", "es_pr", 0x500A), + LANG("Spanish - Paraguay", "es_py", 0x3C0A), + LANG("Spanish - El Salvador", "es_sv", 0x440A), + LANG("Spanish - Uruguay", "es_uy", 0x380A), + LANG("Spanish - Venezuela", "es_ve", 0x200A), + LANG("Southern Sotho", "st", 0x0430), + LANG("Swahili", "sw", 0x0441), + LANG("Swedish - Sweden", "sv_se", 0x041D), + LANG("Swedish - Finland", "sv_fi", 0x081D), + LANG("Tamil", "ta", 0x0449), + LANG("Tatar", "tt", 0X0444), + LANG("Thai", "th", 0x041E), + LANG("Turkish", "tr", 0x041F), + LANG("Tsonga", "ts", 0x0431), + LANG("Ukrainian", "uk", 0x0422), + LANG("Urdu", "ur", 0x0420), + LANG("Uzbek - Cyrillic", "uz_uz", 0x0843), + LANG("Uzbek – Latin", "uz_uz", 0x0443), + LANG("Vietnamese", "vi", 0x042A), + LANG("Xhosa", "xh", 0x0434), + LANG("Yiddish", "yi", 0x043D), + LANG("Zulu", "zu", 0x0435), + LANG(NULL, NULL, 0x0), +}; + +uint16_t get_usb_code_for_current_locale(void) +{ + char *locale; + char search_string[64]; + char *ptr; + struct lang_map_entry *lang; + + /* Get the current locale. */ + locale = setlocale(0, NULL); + if (!locale) + return 0x0; + + /* Make a copy of the current locale string. */ + strncpy(search_string, locale, sizeof(search_string)); + search_string[sizeof(search_string)-1] = '\0'; + + /* Chop off the encoding part, and make it lower case. */ + ptr = search_string; + while (*ptr) { + *ptr = tolower(*ptr); + if (*ptr == '.') { + *ptr = '\0'; + break; + } + ptr++; + } + + /* Find the entry which matches the string code of our locale. */ + lang = lang_map; + while (lang->string_code) { + if (!strcmp(lang->string_code, search_string)) { + return lang->usb_code; + } + lang++; + } + + /* There was no match. Find with just the language only. */ + /* Chop off the variant. Chop it off at the '_'. */ + ptr = search_string; + while (*ptr) { + *ptr = tolower(*ptr); + if (*ptr == '_') { + *ptr = '\0'; + break; + } + ptr++; + } + +#if 0 /* TODO: Do we need this? */ + /* Find the entry which matches the string code of our language. */ + lang = lang_map; + while (lang->string_code) { + if (!strcmp(lang->string_code, search_string)) { + return lang->usb_code; + } + lang++; + } +#endif + + /* Found nothing. */ + return 0x0; +} + +#ifdef __cplusplus +} +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/mac/hid.c b/go-api-for-hardware-wallet/usbhid/c/hidapi/mac/hid.c new file mode 100644 index 00000000..3178182e --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/mac/hid.c @@ -0,0 +1,1110 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 2010-07-03 + + Copyright 2010, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/* See Apple Technical Note TN2187 for details on IOHidManager. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hidapi/hidapi.h" + +/* Barrier implementation because Mac OSX doesn't have pthread_barrier. + It also doesn't have clock_gettime(). So much for POSIX and SUSv2. + This implementation came from Brent Priddy and was posted on + StackOverflow. It is used with his permission. */ +typedef int pthread_barrierattr_t; +typedef struct pthread_barrier { + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; + int trip_count; +} pthread_barrier_t; + +static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) +{ + if(count == 0) { + errno = EINVAL; + return -1; + } + + if(pthread_mutex_init(&barrier->mutex, 0) < 0) { + return -1; + } + if(pthread_cond_init(&barrier->cond, 0) < 0) { + pthread_mutex_destroy(&barrier->mutex); + return -1; + } + barrier->trip_count = count; + barrier->count = 0; + + return 0; +} + +static int pthread_barrier_destroy(pthread_barrier_t *barrier) +{ + pthread_cond_destroy(&barrier->cond); + pthread_mutex_destroy(&barrier->mutex); + return 0; +} + +static int pthread_barrier_wait(pthread_barrier_t *barrier) +{ + pthread_mutex_lock(&barrier->mutex); + ++(barrier->count); + if(barrier->count >= barrier->trip_count) + { + barrier->count = 0; + pthread_cond_broadcast(&barrier->cond); + pthread_mutex_unlock(&barrier->mutex); + return 1; + } + else + { + pthread_cond_wait(&barrier->cond, &(barrier->mutex)); + pthread_mutex_unlock(&barrier->mutex); + return 0; + } +} + +static int return_data(hid_device *dev, unsigned char *data, size_t length); + +/* Linked List of input reports received from the device. */ +struct input_report { + uint8_t *data; + size_t len; + struct input_report *next; +}; + +struct hid_device_ { + IOHIDDeviceRef device_handle; + int blocking; + int uses_numbered_reports; + int disconnected; + CFStringRef run_loop_mode; + CFRunLoopRef run_loop; + CFRunLoopSourceRef source; + uint8_t *input_report_buf; + CFIndex max_input_report_len; + struct input_report *input_reports; + + pthread_t thread; + pthread_mutex_t mutex; /* Protects input_reports */ + pthread_cond_t condition; + pthread_barrier_t barrier; /* Ensures correct startup sequence */ + pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */ + int shutdown_thread; +}; + +static hid_device *new_hid_device(void) +{ + hid_device *dev = calloc(1, sizeof(hid_device)); + dev->device_handle = NULL; + dev->blocking = 1; + dev->uses_numbered_reports = 0; + dev->disconnected = 0; + dev->run_loop_mode = NULL; + dev->run_loop = NULL; + dev->source = NULL; + dev->input_report_buf = NULL; + dev->input_reports = NULL; + dev->shutdown_thread = 0; + + /* Thread objects */ + pthread_mutex_init(&dev->mutex, NULL); + pthread_cond_init(&dev->condition, NULL); + pthread_barrier_init(&dev->barrier, NULL, 2); + pthread_barrier_init(&dev->shutdown_barrier, NULL, 2); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + if (!dev) + return; + + /* Delete any input reports still left over. */ + struct input_report *rpt = dev->input_reports; + while (rpt) { + struct input_report *next = rpt->next; + free(rpt->data); + free(rpt); + rpt = next; + } + + /* Free the string and the report buffer. The check for NULL + is necessary here as CFRelease() doesn't handle NULL like + free() and others do. */ + if (dev->run_loop_mode) + CFRelease(dev->run_loop_mode); + if (dev->source) + CFRelease(dev->source); + free(dev->input_report_buf); + + /* Clean up the thread objects */ + pthread_barrier_destroy(&dev->shutdown_barrier); + pthread_barrier_destroy(&dev->barrier); + pthread_cond_destroy(&dev->condition); + pthread_mutex_destroy(&dev->mutex); + + /* Free the structure itself. */ + free(dev); +} + +static IOHIDManagerRef hid_mgr = 0x0; + + +#if 0 +static void register_error(hid_device *device, const char *op) +{ + +} +#endif + + +static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key) +{ + CFTypeRef ref; + int32_t value; + + ref = IOHIDDeviceGetProperty(device, key); + if (ref) { + if (CFGetTypeID(ref) == CFNumberGetTypeID()) { + CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &value); + return value; + } + } + return 0; +} + +static unsigned short get_vendor_id(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDVendorIDKey)); +} + +static unsigned short get_product_id(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDProductIDKey)); +} + +static int32_t get_max_report_length(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey)); +} + +static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len) +{ + CFStringRef str; + + if (!len) + return 0; + + str = IOHIDDeviceGetProperty(device, prop); + + buf[0] = 0; + + if (str) { + CFIndex str_len = CFStringGetLength(str); + CFRange range; + CFIndex used_buf_len; + CFIndex chars_copied; + + len --; + + range.location = 0; + range.length = ((size_t)str_len > len)? len: (size_t)str_len; + chars_copied = CFStringGetBytes(str, + range, + kCFStringEncodingUTF32LE, + (char)'?', + FALSE, + (UInt8*)buf, + len * sizeof(wchar_t), + &used_buf_len); + + if (chars_copied == len) + buf[len] = 0; /* len is decremented above */ + else + buf[chars_copied] = 0; + + return 0; + } + else + return -1; + +} + +static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len); +} + +static int get_manufacturer_string(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDManufacturerKey), buf, len); +} + +static int get_product_string(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDProductKey), buf, len); +} + + +/* Implementation of wcsdup() for Mac. */ +static wchar_t *dup_wcs(const wchar_t *s) +{ + size_t len = wcslen(s); + wchar_t *ret = malloc((len+1)*sizeof(wchar_t)); + wcscpy(ret, s); + + return ret; +} + +/* hidapi_IOHIDDeviceGetService() + * + * Return the io_service_t corresponding to a given IOHIDDeviceRef, either by: + * - on OS X 10.6 and above, calling IOHIDDeviceGetService() + * - on OS X 10.5, extract it from the IOHIDDevice struct + */ +static io_service_t hidapi_IOHIDDeviceGetService(IOHIDDeviceRef device) +{ + static void *iokit_framework = NULL; + static io_service_t (*dynamic_IOHIDDeviceGetService)(IOHIDDeviceRef device) = NULL; + + /* Use dlopen()/dlsym() to get a pointer to IOHIDDeviceGetService() if it exists. + * If any of these steps fail, dynamic_IOHIDDeviceGetService will be left NULL + * and the fallback method will be used. + */ + if (iokit_framework == NULL) { + iokit_framework = dlopen("/System/Library/IOKit.framework/IOKit", RTLD_LAZY); + + if (iokit_framework != NULL) + dynamic_IOHIDDeviceGetService = dlsym(iokit_framework, "IOHIDDeviceGetService"); + } + + if (dynamic_IOHIDDeviceGetService != NULL) { + /* Running on OS X 10.6 and above: IOHIDDeviceGetService() exists */ + return dynamic_IOHIDDeviceGetService(device); + } + else + { + /* Running on OS X 10.5: IOHIDDeviceGetService() doesn't exist. + * + * Be naughty and pull the service out of the IOHIDDevice. + * IOHIDDevice is an opaque struct not exposed to applications, but its + * layout is stable through all available versions of OS X. + * Tested and working on OS X 10.5.8 i386, x86_64, and ppc. + */ + struct IOHIDDevice_internal { + /* The first field of the IOHIDDevice struct is a + * CFRuntimeBase (which is a private CF struct). + * + * a, b, and c are the 3 fields that make up a CFRuntimeBase. + * See http://opensource.apple.com/source/CF/CF-476.18/CFRuntime.h + * + * The second field of the IOHIDDevice is the io_service_t we're looking for. + */ + uintptr_t a; + uint8_t b[4]; +#if __LP64__ + uint32_t c; +#endif + io_service_t service; + }; + struct IOHIDDevice_internal *tmp = (struct IOHIDDevice_internal *)device; + + return tmp->service; + } +} + +/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */ +static int init_hid_manager(void) +{ + /* Initialize all the HID Manager Objects */ + hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + if (hid_mgr) { + IOHIDManagerSetDeviceMatching(hid_mgr, NULL); + IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + return 0; + } + + return -1; +} + +/* Initialize the IOHIDManager if necessary. This is the public function, and + it is safe to call this function repeatedly. Return 0 for success and -1 + for failure. */ +int HID_API_EXPORT hid_init(void) +{ + if (!hid_mgr) { + return init_hid_manager(); + } + + /* Already initialized. */ + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ + if (hid_mgr) { + /* Close the HID manager. */ + IOHIDManagerClose(hid_mgr, kIOHIDOptionsTypeNone); + CFRelease(hid_mgr); + hid_mgr = NULL; + } + + return 0; +} + +static void process_pending_events(void) { + SInt32 res; + do { + res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE); + } while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut); +} + +struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + CFIndex num_devices; + int i; + + /* Set up the HID Manager if it hasn't been done */ + if (hid_init() < 0) + return NULL; + + /* give the IOHIDManager a chance to update itself */ + process_pending_events(); + + /* Get a list of the Devices */ + IOHIDManagerSetDeviceMatching(hid_mgr, NULL); + CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); + + /* Convert the list into a C array so we can iterate easily. */ + num_devices = CFSetGetCount(device_set); + IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); + CFSetGetValues(device_set, (const void **) device_array); + + /* Iterate over each device, making an entry for it. */ + for (i = 0; i < num_devices; i++) { + unsigned short dev_vid; + unsigned short dev_pid; + #define BUF_LEN 256 + wchar_t buf[BUF_LEN]; + + IOHIDDeviceRef dev = device_array[i]; + + if (!dev) { + continue; + } + dev_vid = get_vendor_id(dev); + dev_pid = get_product_id(dev); + + /* Check the VID/PID against the arguments */ + if ((vendor_id == 0x0 || vendor_id == dev_vid) && + (product_id == 0x0 || product_id == dev_pid)) { + struct hid_device_info *tmp; + io_object_t iokit_dev; + kern_return_t res; + io_string_t path; + + /* VID/PID match. Create the record. */ + tmp = malloc(sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Get the Usage Page and Usage for this device. */ + cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey)); + cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey)); + + /* Fill out the record */ + cur_dev->next = NULL; + + /* Fill in the path (IOService plane) */ + iokit_dev = hidapi_IOHIDDeviceGetService(dev); + res = IORegistryEntryGetPath(iokit_dev, kIOServicePlane, path); + if (res == KERN_SUCCESS) + cur_dev->path = strdup(path); + else + cur_dev->path = strdup(""); + + /* Serial Number */ + get_serial_number(dev, buf, BUF_LEN); + cur_dev->serial_number = dup_wcs(buf); + + /* Manufacturer and Product strings */ + get_manufacturer_string(dev, buf, BUF_LEN); + cur_dev->manufacturer_string = dup_wcs(buf); + get_product_string(dev, buf, BUF_LEN); + cur_dev->product_string = dup_wcs(buf); + + /* VID/PID */ + cur_dev->vendor_id = dev_vid; + cur_dev->product_id = dev_pid; + + /* Release Number */ + cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey)); + + /* Interface Number (Unsupported on Mac)*/ + cur_dev->interface_number = -1; + } + } + + free(device_array); + CFRelease(device_set); + + return root; +} + +void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) +{ + /* This function is identical to the Linux version. Platform independent. */ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + +hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + /* This function is identical to the Linux version. Platform independent. */ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device * handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open); + } + + hid_free_enumeration(devs); + + return handle; +} + +static void hid_device_removal_callback(void *context, IOReturn result, + void *sender) +{ + /* Stop the Run Loop for this device. */ + hid_device *d = context; + + d->disconnected = 1; + CFRunLoopStop(d->run_loop); +} + +/* The Run Loop calls this function for each input report received. + This function puts the data into a linked list to be picked up by + hid_read(). */ +static void hid_report_callback(void *context, IOReturn result, void *sender, + IOHIDReportType report_type, uint32_t report_id, + uint8_t *report, CFIndex report_length) +{ + struct input_report *rpt; + hid_device *dev = context; + + /* Make a new Input Report object */ + rpt = calloc(1, sizeof(struct input_report)); + rpt->data = calloc(1, report_length); + memcpy(rpt->data, report, report_length); + rpt->len = report_length; + rpt->next = NULL; + + /* Lock this section */ + pthread_mutex_lock(&dev->mutex); + + /* Attach the new report object to the end of the list. */ + if (dev->input_reports == NULL) { + /* The list is empty. Put it at the root. */ + dev->input_reports = rpt; + } + else { + /* Find the end of the list and attach. */ + struct input_report *cur = dev->input_reports; + int num_queued = 0; + while (cur->next != NULL) { + cur = cur->next; + num_queued++; + } + cur->next = rpt; + + /* Pop one off if we've reached 30 in the queue. This + way we don't grow forever if the user never reads + anything from the device. */ + if (num_queued > 30) { + return_data(dev, NULL, 0); + } + } + + /* Signal a waiting thread that there is data. */ + pthread_cond_signal(&dev->condition); + + /* Unlock */ + pthread_mutex_unlock(&dev->mutex); + +} + +/* This gets called when the read_thread's run loop gets signaled by + hid_close(), and serves to stop the read_thread's run loop. */ +static void perform_signal_callback(void *context) +{ + hid_device *dev = context; + CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/ +} + +static void *read_thread(void *param) +{ + hid_device *dev = param; + SInt32 code; + + /* Move the device's run loop to this thread. */ + IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode); + + /* Create the RunLoopSource which is used to signal the + event loop to stop when hid_close() is called. */ + CFRunLoopSourceContext ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.version = 0; + ctx.info = dev; + ctx.perform = &perform_signal_callback; + dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx); + CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode); + + /* Store off the Run Loop so it can be stopped from hid_close() + and on device disconnection. */ + dev->run_loop = CFRunLoopGetCurrent(); + + /* Notify the main thread that the read thread is up and running. */ + pthread_barrier_wait(&dev->barrier); + + /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input + reports into the hid_report_callback(). */ + while (!dev->shutdown_thread && !dev->disconnected) { + code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE); + /* Return if the device has been disconnected */ + if (code == kCFRunLoopRunFinished) { + dev->disconnected = 1; + break; + } + + + /* Break if The Run Loop returns Finished or Stopped. */ + if (code != kCFRunLoopRunTimedOut && + code != kCFRunLoopRunHandledSource) { + /* There was some kind of error. Setting + shutdown seems to make sense, but + there may be something else more appropriate */ + dev->shutdown_thread = 1; + break; + } + } + + /* Now that the read thread is stopping, Wake any threads which are + waiting on data (in hid_read_timeout()). Do this under a mutex to + make sure that a thread which is about to go to sleep waiting on + the condition actually will go to sleep before the condition is + signaled. */ + pthread_mutex_lock(&dev->mutex); + pthread_cond_broadcast(&dev->condition); + pthread_mutex_unlock(&dev->mutex); + + /* Wait here until hid_close() is called and makes it past + the call to CFRunLoopWakeUp(). This thread still needs to + be valid when that function is called on the other thread. */ + pthread_barrier_wait(&dev->shutdown_barrier); + + return NULL; +} + +/* hid_open_path() + * + * path must be a valid path to an IOHIDDevice in the IOService plane + * Example: "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/EHC1@1D,7/AppleUSBEHCI/PLAYSTATION(R)3 Controller@fd120000/IOUSBInterface@0/IOUSBHIDDriver" + */ +hid_device * HID_API_EXPORT hid_open_path(const char *path) +{ + hid_device *dev = NULL; + io_registry_entry_t entry = MACH_PORT_NULL; + + dev = new_hid_device(); + + /* Set up the HID Manager if it hasn't been done */ + if (hid_init() < 0) + return NULL; + + /* Get the IORegistry entry for the given path */ + entry = IORegistryEntryFromPath(kIOMasterPortDefault, path); + if (entry == MACH_PORT_NULL) { + /* Path wasn't valid (maybe device was removed?) */ + goto return_error; + } + + /* Create an IOHIDDevice for the entry */ + dev->device_handle = IOHIDDeviceCreate(kCFAllocatorDefault, entry); + if (dev->device_handle == NULL) { + /* Error creating the HID device */ + goto return_error; + } + + /* Open the IOHIDDevice */ + IOReturn ret = IOHIDDeviceOpen(dev->device_handle, kIOHIDOptionsTypeSeizeDevice); + if (ret == kIOReturnSuccess) { + char str[32]; + + /* Create the buffers for receiving data */ + dev->max_input_report_len = (CFIndex) get_max_report_length(dev->device_handle); + dev->input_report_buf = calloc(dev->max_input_report_len, sizeof(uint8_t)); + + /* Create the Run Loop Mode for this device. + printing the reference seems to work. */ + sprintf(str, "HIDAPI_%p", dev->device_handle); + dev->run_loop_mode = + CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); + + /* Attach the device to a Run Loop */ + IOHIDDeviceRegisterInputReportCallback( + dev->device_handle, dev->input_report_buf, dev->max_input_report_len, + &hid_report_callback, dev); + IOHIDDeviceRegisterRemovalCallback(dev->device_handle, hid_device_removal_callback, dev); + + /* Start the read thread */ + pthread_create(&dev->thread, NULL, read_thread, dev); + + /* Wait here for the read thread to be initialized. */ + pthread_barrier_wait(&dev->barrier); + + IOObjectRelease(entry); + return dev; + } + else { + goto return_error; + } + +return_error: + if (dev->device_handle != NULL) + CFRelease(dev->device_handle); + + if (entry != MACH_PORT_NULL) + IOObjectRelease(entry); + + free_hid_device(dev); + return NULL; +} + +static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char *data, size_t length) +{ + const unsigned char *data_to_send; + size_t length_to_send; + IOReturn res; + + /* Return if the device has been disconnected. */ + if (dev->disconnected) + return -1; + + if (data[0] == 0x0) { + /* Not using numbered Reports. + Don't send the report number. */ + data_to_send = data+1; + length_to_send = length-1; + } + else { + /* Using numbered Reports. + Send the Report Number */ + data_to_send = data; + length_to_send = length; + } + + if (!dev->disconnected) { + res = IOHIDDeviceSetReport(dev->device_handle, + type, + data[0], /* Report ID*/ + data_to_send, length_to_send); + + if (res == kIOReturnSuccess) { + return length; + } + else + return -1; + } + + return -1; +} + +int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + return set_report(dev, kIOHIDReportTypeOutput, data, length); +} + +/* Helper function, so that this isn't duplicated in hid_read(). */ +static int return_data(hid_device *dev, unsigned char *data, size_t length) +{ + /* Copy the data out of the linked list item (rpt) into the + return buffer (data), and delete the liked list item. */ + struct input_report *rpt = dev->input_reports; + size_t len = (length < rpt->len)? length: rpt->len; + memcpy(data, rpt->data, len); + dev->input_reports = rpt->next; + free(rpt->data); + free(rpt); + return len; +} + +static int cond_wait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + while (!dev->input_reports) { + int res = pthread_cond_wait(cond, mutex); + if (res != 0) + return res; + + /* A res of 0 means we may have been signaled or it may + be a spurious wakeup. Check to see that there's acutally + data in the queue before returning, and if not, go back + to sleep. See the pthread_cond_timedwait() man page for + details. */ + + if (dev->shutdown_thread || dev->disconnected) + return -1; + } + + return 0; +} + +static int cond_timedwait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) +{ + while (!dev->input_reports) { + int res = pthread_cond_timedwait(cond, mutex, abstime); + if (res != 0) + return res; + + /* A res of 0 means we may have been signaled or it may + be a spurious wakeup. Check to see that there's acutally + data in the queue before returning, and if not, go back + to sleep. See the pthread_cond_timedwait() man page for + details. */ + + if (dev->shutdown_thread || dev->disconnected) + return -1; + } + + return 0; + +} + +int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + int bytes_read = -1; + + /* Lock the access to the report list. */ + pthread_mutex_lock(&dev->mutex); + + /* There's an input report queued up. Return it. */ + if (dev->input_reports) { + /* Return the first one */ + bytes_read = return_data(dev, data, length); + goto ret; + } + + /* Return if the device has been disconnected. */ + if (dev->disconnected) { + bytes_read = -1; + goto ret; + } + + if (dev->shutdown_thread) { + /* This means the device has been closed (or there + has been an error. An error code of -1 should + be returned. */ + bytes_read = -1; + goto ret; + } + + /* There is no data. Go to sleep and wait for data. */ + + if (milliseconds == -1) { + /* Blocking */ + int res; + res = cond_wait(dev, &dev->condition, &dev->mutex); + if (res == 0) + bytes_read = return_data(dev, data, length); + else { + /* There was an error, or a device disconnection. */ + bytes_read = -1; + } + } + else if (milliseconds > 0) { + /* Non-blocking, but called with timeout. */ + int res; + struct timespec ts; + struct timeval tv; + gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, &ts); + ts.tv_sec += milliseconds / 1000; + ts.tv_nsec += (milliseconds % 1000) * 1000000; + if (ts.tv_nsec >= 1000000000L) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000L; + } + + res = cond_timedwait(dev, &dev->condition, &dev->mutex, &ts); + if (res == 0) + bytes_read = return_data(dev, data, length); + else if (res == ETIMEDOUT) + bytes_read = 0; + else + bytes_read = -1; + } + else { + /* Purely non-blocking */ + bytes_read = 0; + } + +ret: + /* Unlock */ + pthread_mutex_unlock(&dev->mutex); + return bytes_read; +} + +int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0); +} + +int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) +{ + /* All Nonblocking operation is handled by the library. */ + dev->blocking = !nonblock; + + return 0; +} + +int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + return set_report(dev, kIOHIDReportTypeFeature, data, length); +} + +int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + CFIndex len = length; + IOReturn res; + + /* Return if the device has been unplugged. */ + if (dev->disconnected) + return -1; + + res = IOHIDDeviceGetReport(dev->device_handle, + kIOHIDReportTypeFeature, + data[0], /* Report ID */ + data, &len); + if (res == kIOReturnSuccess) + return len; + else + return -1; +} + + +void HID_API_EXPORT hid_close(hid_device *dev) +{ + if (!dev) + return; + + /* Disconnect the report callback before close. */ + if (!dev->disconnected) { + IOHIDDeviceRegisterInputReportCallback( + dev->device_handle, dev->input_report_buf, dev->max_input_report_len, + NULL, dev); + IOHIDDeviceRegisterRemovalCallback(dev->device_handle, NULL, dev); + IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode); + IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode); + } + + /* Cause read_thread() to stop. */ + dev->shutdown_thread = 1; + + /* Wake up the run thread's event loop so that the thread can exit. */ + CFRunLoopSourceSignal(dev->source); + CFRunLoopWakeUp(dev->run_loop); + + /* Notify the read thread that it can shut down now. */ + pthread_barrier_wait(&dev->shutdown_barrier); + + /* Wait for read_thread() to end. */ + pthread_join(dev->thread, NULL); + + /* Close the OS handle to the device, but only if it's not + been unplugged. If it's been unplugged, then calling + IOHIDDeviceClose() will crash. */ + if (!dev->disconnected) { + IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeSeizeDevice); + } + + /* Clear out the queue of received reports. */ + pthread_mutex_lock(&dev->mutex); + while (dev->input_reports) { + return_data(dev, NULL, 0); + } + pthread_mutex_unlock(&dev->mutex); + CFRelease(dev->device_handle); + + free_hid_device(dev); +} + +int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return get_manufacturer_string(dev->device_handle, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return get_product_string(dev->device_handle, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return get_serial_number(dev->device_handle, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + /* TODO: */ + + return 0; +} + + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + /* TODO: */ + + return NULL; +} + + + + + + + +#if 0 +static int32_t get_location_id(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDLocationIDKey)); +} + +static int32_t get_usage(IOHIDDeviceRef device) +{ + int32_t res; + res = get_int_property(device, CFSTR(kIOHIDDeviceUsageKey)); + if (!res) + res = get_int_property(device, CFSTR(kIOHIDPrimaryUsageKey)); + return res; +} + +static int32_t get_usage_page(IOHIDDeviceRef device) +{ + int32_t res; + res = get_int_property(device, CFSTR(kIOHIDDeviceUsagePageKey)); + if (!res) + res = get_int_property(device, CFSTR(kIOHIDPrimaryUsagePageKey)); + return res; +} + +static int get_transport(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDTransportKey), buf, len); +} + + +int main(void) +{ + IOHIDManagerRef mgr; + int i; + + mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + IOHIDManagerSetDeviceMatching(mgr, NULL); + IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone); + + CFSetRef device_set = IOHIDManagerCopyDevices(mgr); + + CFIndex num_devices = CFSetGetCount(device_set); + IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); + CFSetGetValues(device_set, (const void **) device_array); + + for (i = 0; i < num_devices; i++) { + IOHIDDeviceRef dev = device_array[i]; + printf("Device: %p\n", dev); + printf(" %04hx %04hx\n", get_vendor_id(dev), get_product_id(dev)); + + wchar_t serial[256], buf[256]; + char cbuf[256]; + get_serial_number(dev, serial, 256); + + + printf(" Serial: %ls\n", serial); + printf(" Loc: %ld\n", get_location_id(dev)); + get_transport(dev, buf, 256); + printf(" Trans: %ls\n", buf); + make_path(dev, cbuf, 256); + printf(" Path: %s\n", cbuf); + + } + + return 0; +} +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/windows/hid.c b/go-api-for-hardware-wallet/usbhid/c/hidapi/windows/hid.c new file mode 100755 index 00000000..a25c63ab --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/hidapi/windows/hid.c @@ -0,0 +1,944 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +#include + +#ifndef _NTDEF_ +typedef LONG NTSTATUS; +#endif + +#ifdef __MINGW32__ +#include +#include +#endif + +#ifdef __CYGWIN__ +#include +#define _wcsdup wcsdup +#endif + +/* The maximum number of characters that can be passed into the + HidD_Get*String() functions without it failing.*/ +#define MAX_STRING_WCHARS 0xFFF + +/*#define HIDAPI_USE_DDK*/ + +#ifdef __cplusplus +extern "C" { +#endif + #include + #include + #ifdef HIDAPI_USE_DDK + #include + #endif + + /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */ + #define HID_OUT_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include +#include + + +#include "hidapi/hidapi.h" + +#undef MIN +#define MIN(x,y) ((x) < (y)? (x): (y)) + +#ifdef _MSC_VER + /* Thanks Microsoft, but I know how to use strncpy(). */ + #pragma warning(disable:4996) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HIDAPI_USE_DDK + /* Since we're not building with the DDK, and the HID header + files aren't part of the SDK, we have to define all this + stuff here. In lookup_functions(), the function pointers + defined below are set. */ + typedef struct _HIDD_ATTRIBUTES{ + ULONG Size; + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; + } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + + typedef USHORT USAGE; + typedef struct _HIDP_CAPS { + USAGE Usage; + USAGE UsagePage; + USHORT InputReportByteLength; + USHORT OutputReportByteLength; + USHORT FeatureReportByteLength; + USHORT Reserved[17]; + USHORT fields_not_used_by_hidapi[10]; + } HIDP_CAPS, *PHIDP_CAPS; + typedef void* PHIDP_PREPARSED_DATA; + #define HIDP_STATUS_SUCCESS 0x110000 + + typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib); + typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data); + typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data); + typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps); + typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers); + + static HidD_GetAttributes_ HidD_GetAttributes; + static HidD_GetSerialNumberString_ HidD_GetSerialNumberString; + static HidD_GetManufacturerString_ HidD_GetManufacturerString; + static HidD_GetProductString_ HidD_GetProductString; + static HidD_SetFeature_ HidD_SetFeature; + static HidD_GetFeature_ HidD_GetFeature; + static HidD_GetIndexedString_ HidD_GetIndexedString; + static HidD_GetPreparsedData_ HidD_GetPreparsedData; + static HidD_FreePreparsedData_ HidD_FreePreparsedData; + static HidP_GetCaps_ HidP_GetCaps; + static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers; + + static HMODULE lib_handle = NULL; + static BOOLEAN initialized = FALSE; +#endif /* HIDAPI_USE_DDK */ + +struct hid_device_ { + HANDLE device_handle; + BOOL blocking; + USHORT output_report_length; + size_t input_report_length; + void *last_error_str; + DWORD last_error_num; + BOOL read_pending; + char *read_buf; + OVERLAPPED ol; +}; + +static hid_device *new_hid_device() +{ + hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); + dev->device_handle = INVALID_HANDLE_VALUE; + dev->blocking = TRUE; + dev->output_report_length = 0; + dev->input_report_length = 0; + dev->last_error_str = NULL; + dev->last_error_num = 0; + dev->read_pending = FALSE; + dev->read_buf = NULL; + memset(&dev->ol, 0, sizeof(dev->ol)); + dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + CloseHandle(dev->ol.hEvent); + CloseHandle(dev->device_handle); + LocalFree(dev->last_error_str); + free(dev->read_buf); + free(dev); +} + +static void register_error(hid_device *device, const char *op) +{ + WCHAR *ptr, *msg; + + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPVOID)&msg, 0/*sz*/, + NULL); + + /* Get rid of the CR and LF that FormatMessage() sticks at the + end of the message. Thanks Microsoft! */ + ptr = msg; + while (*ptr) { + if (*ptr == '\r') { + *ptr = 0x0000; + break; + } + ptr++; + } + + /* Store the message off in the Device entry so that + the hid_error() function can pick it up. */ + LocalFree(device->last_error_str); + device->last_error_str = msg; +} + +#ifndef HIDAPI_USE_DDK +static int lookup_functions() +{ + lib_handle = LoadLibraryA("hid.dll"); + if (lib_handle) { +#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1; + RESOLVE(HidD_GetAttributes); + RESOLVE(HidD_GetSerialNumberString); + RESOLVE(HidD_GetManufacturerString); + RESOLVE(HidD_GetProductString); + RESOLVE(HidD_SetFeature); + RESOLVE(HidD_GetFeature); + RESOLVE(HidD_GetIndexedString); + RESOLVE(HidD_GetPreparsedData); + RESOLVE(HidD_FreePreparsedData); + RESOLVE(HidP_GetCaps); + RESOLVE(HidD_SetNumInputBuffers); +#undef RESOLVE + } + else + return -1; + + return 0; +} +#endif + +static HANDLE open_device(const char *path, BOOL enumerate) +{ + HANDLE handle; + DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ); + DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; + + handle = CreateFileA(path, + desired_access, + share_mode, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/ + 0); + + return handle; +} + +int HID_API_EXPORT hid_init(void) +{ +#ifndef HIDAPI_USE_DDK + if (!initialized) { + if (lookup_functions() < 0) { + hid_exit(); + return -1; + } + initialized = TRUE; + } +#endif + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ +#ifndef HIDAPI_USE_DDK + if (lib_handle) + FreeLibrary(lib_handle); + lib_handle = NULL; + initialized = FALSE; +#endif + return 0; +} + +struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + BOOL res; + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + + /* Windows objects for interacting with the driver. */ + GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; + SP_DEVINFO_DATA devinfo_data; + SP_DEVICE_INTERFACE_DATA device_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; + HDEVINFO device_info_set = INVALID_HANDLE_VALUE; + int device_index = 0; + int i; + + if (hid_init() < 0) + return NULL; + + /* Initialize the Windows objects. */ + memset(&devinfo_data, 0x0, sizeof(devinfo_data)); + devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); + device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + /* Get information for all the devices belonging to the HID class. */ + device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + + /* Iterate over each device in the HID class, looking for the right one. */ + + for (;;) { + HANDLE write_handle = INVALID_HANDLE_VALUE; + DWORD required_size = 0; + HIDD_ATTRIBUTES attrib; + + res = SetupDiEnumDeviceInterfaces(device_info_set, + NULL, + &InterfaceClassGuid, + device_index, + &device_interface_data); + + if (!res) { + /* A return of FALSE from this function means that + there are no more devices. */ + break; + } + + /* Call with 0-sized detail size, and let the function + tell us how long the detail struct needs to be. The + size is put in &required_size. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + NULL, + 0, + &required_size, + NULL); + + /* Allocate a long enough structure for device_interface_detail_data. */ + device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); + device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + + /* Get the detailed data for this device. The detail data gives us + the device path for this device, which is then passed into + CreateFile() to get a handle to the device. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + device_interface_detail_data, + required_size, + NULL, + NULL); + + if (!res) { + /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); + Continue to the next device. */ + goto cont; + } + + /* Make sure this device is of Setup Class "HIDClass" and has a + driver bound to it. */ + for (i = 0; ; i++) { + char driver_name[256]; + + /* Populate devinfo_data. This function will return failure + when there are no more interfaces left. */ + res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data); + if (!res) + goto cont; + + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (!res) + goto cont; + + if (strcmp(driver_name, "HIDClass") == 0) { + /* See if there's a driver bound. */ + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (res) + break; + } + } + + //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); + + /* Open a handle to the device */ + write_handle = open_device(device_interface_detail_data->DevicePath, TRUE); + + /* Check validity of write_handle. */ + if (write_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device. */ + //register_error(dev, "CreateFile"); + goto cont_close; + } + + + /* Get the Vendor ID and Product ID for this device. */ + attrib.Size = sizeof(HIDD_ATTRIBUTES); + HidD_GetAttributes(write_handle, &attrib); + //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); + + /* Check the VID/PID to see if we should add this + device to the enumeration list. */ + if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && + (product_id == 0x0 || attrib.ProductID == product_id)) { + + #define WSTR_LEN 512 + const char *str; + struct hid_device_info *tmp; + PHIDP_PREPARSED_DATA pp_data = NULL; + HIDP_CAPS caps; + BOOLEAN res; + NTSTATUS nt_res; + wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ + size_t len; + + /* VID/PID match. Create the record. */ + tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Get the Usage Page and Usage for this device. */ + res = HidD_GetPreparsedData(write_handle, &pp_data); + if (res) { + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res == HIDP_STATUS_SUCCESS) { + cur_dev->usage_page = caps.UsagePage; + cur_dev->usage = caps.Usage; + } + + HidD_FreePreparsedData(pp_data); + } + + /* Fill out the record */ + cur_dev->next = NULL; + str = device_interface_detail_data->DevicePath; + if (str) { + len = strlen(str); + cur_dev->path = (char*) calloc(len+1, sizeof(char)); + strncpy(cur_dev->path, str, len+1); + cur_dev->path[len] = '\0'; + } + else + cur_dev->path = NULL; + + /* Serial Number */ + res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->serial_number = _wcsdup(wstr); + } + + /* Manufacturer String */ + res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->manufacturer_string = _wcsdup(wstr); + } + + /* Product String */ + res = HidD_GetProductString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->product_string = _wcsdup(wstr); + } + + /* VID/PID */ + cur_dev->vendor_id = attrib.VendorID; + cur_dev->product_id = attrib.ProductID; + + /* Release Number */ + cur_dev->release_number = attrib.VersionNumber; + + /* Interface Number. It can sometimes be parsed out of the path + on Windows if a device has multiple interfaces. See + http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or + search for "Hardware IDs for HID Devices" at MSDN. If it's not + in the path, it's set to -1. */ + cur_dev->interface_number = -1; + if (cur_dev->path) { + char *interface_component = strstr(cur_dev->path, "&mi_"); + if (interface_component) { + char *hex_str = interface_component + 4; + char *endptr = NULL; + cur_dev->interface_number = strtol(hex_str, &endptr, 16); + if (endptr == hex_str) { + /* The parsing failed. Set interface_number to -1. */ + cur_dev->interface_number = -1; + } + } + } + } + +cont_close: + CloseHandle(write_handle); +cont: + /* We no longer need the detail data. It can be freed */ + free(device_interface_detail_data); + + device_index++; + + } + + /* Close the device information handle. */ + SetupDiDestroyDeviceInfoList(device_info_set); + + return root; + +} + +void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) +{ + /* TODO: Merge this with the Linux version. This function is platform-independent. */ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + + +HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + /* TODO: Merge this functions with the Linux version. This function should be platform independent. */ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device *handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open); + } + + hid_free_enumeration(devs); + + return handle; +} + +HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) +{ + hid_device *dev; + HIDP_CAPS caps; + PHIDP_PREPARSED_DATA pp_data = NULL; + BOOLEAN res; + NTSTATUS nt_res; + + if (hid_init() < 0) { + return NULL; + } + + dev = new_hid_device(); + + /* Open a handle to the device */ + dev->device_handle = open_device(path, FALSE); + + /* Check validity of write_handle. */ + if (dev->device_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device. */ + register_error(dev, "CreateFile"); + goto err; + } + + /* Set the Input Report buffer size to 64 reports. */ + res = HidD_SetNumInputBuffers(dev->device_handle, 64); + if (!res) { + register_error(dev, "HidD_SetNumInputBuffers"); + goto err; + } + + /* Get the Input Report length for the device. */ + res = HidD_GetPreparsedData(dev->device_handle, &pp_data); + if (!res) { + register_error(dev, "HidD_GetPreparsedData"); + goto err; + } + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res != HIDP_STATUS_SUCCESS) { + register_error(dev, "HidP_GetCaps"); + goto err_pp_data; + } + dev->output_report_length = caps.OutputReportByteLength; + dev->input_report_length = caps.InputReportByteLength; + HidD_FreePreparsedData(pp_data); + + dev->read_buf = (char*) malloc(dev->input_report_length); + + return dev; + +err_pp_data: + HidD_FreePreparsedData(pp_data); +err: + free_hid_device(dev); + return NULL; +} + +int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + DWORD bytes_written; + BOOL res; + + OVERLAPPED ol; + unsigned char *buf; + memset(&ol, 0, sizeof(ol)); + + /* Make sure the right number of bytes are passed to WriteFile. Windows + expects the number of bytes which are in the _longest_ report (plus + one for the report number) bytes even if the data is a report + which is shorter than that. Windows gives us this value in + caps.OutputReportByteLength. If a user passes in fewer bytes than this, + create a temporary buffer which is the proper size. */ + if (length >= dev->output_report_length) { + /* The user passed the right number of bytes. Use the buffer as-is. */ + buf = (unsigned char *) data; + } else { + /* Create a temporary buffer and copy the user's data + into it, padding the rest with zeros. */ + buf = (unsigned char *) malloc(dev->output_report_length); + memcpy(buf, data, length); + memset(buf + length, 0, dev->output_report_length - length); + length = dev->output_report_length; + } + + res = WriteFile(dev->device_handle, buf, length, NULL, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* WriteFile() failed. Return error. */ + register_error(dev, "WriteFile"); + bytes_written = -1; + goto end_of_function; + } + } + + /* Wait here until the write is done. This makes + hid_write() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/); + if (!res) { + /* The Write operation failed. */ + register_error(dev, "WriteFile"); + bytes_written = -1; + goto end_of_function; + } + +end_of_function: + if (buf != data) + free(buf); + + return bytes_written; +} + + +int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + DWORD bytes_read = 0; + size_t copy_len = 0; + BOOL res; + + /* Copy the handle for convenience. */ + HANDLE ev = dev->ol.hEvent; + + if (!dev->read_pending) { + /* Start an Overlapped I/O read. */ + dev->read_pending = TRUE; + memset(dev->read_buf, 0, dev->input_report_length); + ResetEvent(ev); + res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* ReadFile() has failed. + Clean up and return error. */ + CancelIo(dev->device_handle); + dev->read_pending = FALSE; + goto end_of_function; + } + } + } + + if (milliseconds >= 0) { + /* See if there is any data yet. */ + res = WaitForSingleObject(ev, milliseconds); + if (res != WAIT_OBJECT_0) { + /* There was no data this time. Return zero bytes available, + but leave the Overlapped I/O running. */ + return 0; + } + } + + /* Either WaitForSingleObject() told us that ReadFile has completed, or + we are in non-blocking mode. Get the number of bytes read. The actual + data has been copied to the data[] array which was passed to ReadFile(). */ + res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + + /* Set pending back to false, even if GetOverlappedResult() returned error. */ + dev->read_pending = FALSE; + + if (res && bytes_read > 0) { + if (dev->read_buf[0] == 0x0) { + /* If report numbers aren't being used, but Windows sticks a report + number (0x0) on the beginning of the report anyway. To make this + work like the other platforms, and to make it work more like the + HID spec, we'll skip over this byte. */ + bytes_read--; + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf+1, copy_len); + } + else { + /* Copy the whole buffer, report number and all. */ + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf, copy_len); + } + } + +end_of_function: + if (!res) { + register_error(dev, "GetOverlappedResult"); + return -1; + } + + return copy_len; +} + +int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0); +} + +int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock) +{ + dev->blocking = !nonblock; + return 0; /* Success */ +} + +int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, length); + if (!res) { + register_error(dev, "HidD_SetFeature"); + return -1; + } + + return length; +} + + +int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + BOOL res; +#if 0 + res = HidD_GetFeature(dev->device_handle, data, length); + if (!res) { + register_error(dev, "HidD_GetFeature"); + return -1; + } + return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */ +#else + DWORD bytes_returned; + + OVERLAPPED ol; + memset(&ol, 0, sizeof(ol)); + + res = DeviceIoControl(dev->device_handle, + IOCTL_HID_GET_FEATURE, + data, length, + data, length, + &bytes_returned, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* DeviceIoControl() failed. Return error. */ + register_error(dev, "Send Feature Report DeviceIoControl"); + return -1; + } + } + + /* Wait here until the write is done. This makes + hid_get_feature_report() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/); + if (!res) { + /* The operation failed. */ + register_error(dev, "Send Feature Report GetOverLappedResult"); + return -1; + } + + /* bytes_returned does not include the first byte which contains the + report ID. The data buffer actually contains one more byte than + bytes_returned. */ + bytes_returned++; + + return bytes_returned; +#endif +} + +void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) +{ + if (!dev) + return; + CancelIo(dev->device_handle); + free_hid_device(dev); +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetManufacturerString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetProductString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetSerialNumberString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetSerialNumberString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetIndexedString"); + return -1; + } + + return 0; +} + + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + return (wchar_t*)dev->last_error_str; +} + + +/*#define PICPGM*/ +/*#define S11*/ +#define P32 +#ifdef S11 + unsigned short VendorID = 0xa0a0; + unsigned short ProductID = 0x0001; +#endif + +#ifdef P32 + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x3f; +#endif + + +#ifdef PICPGM + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x0033; +#endif + + +#if 0 +int __cdecl main(int argc, char* argv[]) +{ + int res; + unsigned char buf[65]; + + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + /* Set up the command buffer. */ + memset(buf,0x00,sizeof(buf)); + buf[0] = 0; + buf[1] = 0x81; + + + /* Open the device. */ + int handle = open(VendorID, ProductID, L"12345"); + if (handle < 0) + printf("unable to open device\n"); + + + /* Toggle LED (cmd 0x80) */ + buf[1] = 0x80; + res = write(handle, buf, 65); + if (res < 0) + printf("Unable to write()\n"); + + /* Request state (cmd 0x81) */ + buf[1] = 0x81; + write(handle, buf, 65); + if (res < 0) + printf("Unable to write() (2)\n"); + + /* Read requested state */ + read(handle, buf, 65); + if (res < 0) + printf("Unable to read()\n"); + + /* Print out the returned buffer. */ + for (int i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + + return 0; +} +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/AUTHORS b/go-api-for-hardware-wallet/usbhid/c/libusb/AUTHORS new file mode 100644 index 00000000..70d407bd --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/AUTHORS @@ -0,0 +1,89 @@ +Copyright © 2001 Johannes Erdfelt +Copyright © 2007-2009 Daniel Drake +Copyright © 2010-2012 Peter Stuge +Copyright © 2008-2016 Nathan Hjelm +Copyright © 2009-2013 Pete Batard +Copyright © 2009-2013 Ludovic Rousseau +Copyright © 2010-2012 Michael Plante +Copyright © 2011-2013 Hans de Goede +Copyright © 2012-2013 Martin Pieuchot +Copyright © 2012-2013 Toby Gray +Copyright © 2013-2015 Chris Dickens + +Other contributors: +Akshay Jaggi +Alan Ott +Alan Stern +Alex Vatchenko +Andrew Fernandes +Anthony Clay +Antonio Ospite +Artem Egorkine +Aurelien Jarno +Bastien Nocera +Bei Zhang +Benjamin Dobell +Carl Karsten +Colin Walters +Dave Camarillo +David Engraf +David Moore +Davidlohr Bueso +Federico Manzan +Felipe Balbi +Florian Albrechtskirchinger +Francesco Montorsi +Francisco Facioni +Gaurav Gupta +Graeme Gill +Gustavo Zacarias +Hans Ulrich Niedermann +Hector Martin +Hoi-Ho Chan +Ilya Konstantinov +James Hanko +John Sheu +Joshua Blake +Justin Bischoff +Karsten Koenig +Konrad Rzepecki +Kuangye Guo +Lars Kanis +Lars Wirzenius +Luca Longinotti +Marcus Meissner +Markus Heidelberg +Martin Ettl +Martin Koegler +Matthias Bolte +Mike Frysinger +Mikhail Gusarov +Moritz Fischer +Ларионов Даниил +Nicholas Corgan +Omri Iluz +Orin Eman +Paul Fertser +Pekka Nikander +Rob Walker +Sean McBride +Sebastian Pipping +Simon Haggett +Simon Newton +Thomas Röfer +Tim Hutt +Tim Roberts +Tobias Klauser +Toby Peterson +Tormod Volden +Trygve Laugstøl +Uri Lublin +Vasily Khoruzhick +Vegard Storheil Eriksen +Venkatesh Shukla +Vitali Lovich +Xiaofan Chen +Zoltán Kovács +Роман Донченко +parafin +xantares diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/COPYING b/go-api-for-hardware-wallet/usbhid/c/libusb/COPYING new file mode 100644 index 00000000..5ab7695a --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/config.h b/go-api-for-hardware-wallet/usbhid/c/libusb/config.h new file mode 100644 index 00000000..e004f03c --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/config.h @@ -0,0 +1,3 @@ +#ifndef CONFIG_H +#define CONFIG_H +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/core.c b/go-api-for-hardware-wallet/usbhid/c/libusb/core.c new file mode 100644 index 00000000..d45bfe17 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/core.c @@ -0,0 +1,2523 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Core functions for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2007-2008 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYSLOG_H +#include +#endif + +#ifdef __ANDROID__ +#include +#endif + +#include "libusbi.h" +#include "hotplug.h" + +#if defined(OS_LINUX) +const struct usbi_os_backend * const usbi_backend = &linux_usbfs_backend; +#elif defined(OS_DARWIN) +const struct usbi_os_backend * const usbi_backend = &darwin_backend; +#elif defined(OS_OPENBSD) +const struct usbi_os_backend * const usbi_backend = &openbsd_backend; +#elif defined(OS_NETBSD) +const struct usbi_os_backend * const usbi_backend = &netbsd_backend; +#elif defined(OS_WINDOWS) + +#if defined(USE_USBDK) +const struct usbi_os_backend * const usbi_backend = &usbdk_backend; +#else +const struct usbi_os_backend * const usbi_backend = &windows_backend; +#endif + +#elif defined(OS_WINCE) +const struct usbi_os_backend * const usbi_backend = &wince_backend; +#elif defined(OS_HAIKU) +const struct usbi_os_backend * const usbi_backend = &haiku_usb_raw_backend; +#elif defined (OS_SUNOS) +const struct usbi_os_backend * const usbi_backend = &sunos_backend; +#else +#error "Unsupported OS" +#endif + +struct libusb_context *usbi_default_context = NULL; +static const struct libusb_version libusb_version_internal = + { LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO, + LIBUSB_RC, "http://libusb.info" }; +static int default_context_refcnt = 0; +static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER; +static struct timespec timestamp_origin = { 0, 0 }; + +usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER; +struct list_head active_contexts_list; + +/** + * \mainpage libusb-1.0 API Reference + * + * \section intro Introduction + * + * libusb is an open source library that allows you to communicate with USB + * devices from userspace. For more info, see the + * libusb homepage. + * + * This documentation is aimed at application developers wishing to + * communicate with USB peripherals from their own software. After reviewing + * this documentation, feedback and questions can be sent to the + * libusb-devel mailing list. + * + * This documentation assumes knowledge of how to operate USB devices from + * a software standpoint (descriptors, configurations, interfaces, endpoints, + * control/bulk/interrupt/isochronous transfers, etc). Full information + * can be found in the USB 3.0 + * Specification which is available for free download. You can probably + * find less verbose introductions by searching the web. + * + * \section API Application Programming Interface (API) + * + * See the \ref libusb_api page for a complete list of the libusb functions. + * + * \section features Library features + * + * - All transfer types supported (control/bulk/interrupt/isochronous) + * - 2 transfer interfaces: + * -# Synchronous (simple) + * -# Asynchronous (more complicated, but more powerful) + * - Thread safe (although the asynchronous interface means that you + * usually won't need to thread) + * - Lightweight with lean API + * - Compatible with libusb-0.1 through the libusb-compat-0.1 translation layer + * - Hotplug support (on some platforms). See \ref libusb_hotplug. + * + * \section gettingstarted Getting Started + * + * To begin reading the API documentation, start with the Modules page which + * links to the different categories of libusb's functionality. + * + * One decision you will have to make is whether to use the synchronous + * or the asynchronous data transfer interface. The \ref libusb_io documentation + * provides some insight into this topic. + * + * Some example programs can be found in the libusb source distribution under + * the "examples" subdirectory. The libusb homepage includes a list of + * real-life project examples which use libusb. + * + * \section errorhandling Error handling + * + * libusb functions typically return 0 on success or a negative error code + * on failure. These negative error codes relate to LIBUSB_ERROR constants + * which are listed on the \ref libusb_misc "miscellaneous" documentation page. + * + * \section msglog Debug message logging + * + * libusb uses stderr for all logging. By default, logging is set to NONE, + * which means that no output will be produced. However, unless the library + * has been compiled with logging disabled, then any application calls to + * libusb_set_debug(), or the setting of the environmental variable + * LIBUSB_DEBUG outside of the application, can result in logging being + * produced. Your application should therefore not close stderr, but instead + * direct it to the null device if its output is undesirable. + * + * The libusb_set_debug() function can be used to enable logging of certain + * messages. Under standard configuration, libusb doesn't really log much + * so you are advised to use this function to enable all error/warning/ + * informational messages. It will help debug problems with your software. + * + * The logged messages are unstructured. There is no one-to-one correspondence + * between messages being logged and success or failure return codes from + * libusb functions. There is no format to the messages, so you should not + * try to capture or parse them. They are not and will not be localized. + * These messages are not intended to being passed to your application user; + * instead, you should interpret the error codes returned from libusb functions + * and provide appropriate notification to the user. The messages are simply + * there to aid you as a programmer, and if you're confused because you're + * getting a strange error code from a libusb function, enabling message + * logging may give you a suitable explanation. + * + * The LIBUSB_DEBUG environment variable can be used to enable message logging + * at run-time. This environment variable should be set to a log level number, + * which is interpreted the same as the libusb_set_debug() parameter. When this + * environment variable is set, the message logging verbosity level is fixed + * and libusb_set_debug() effectively does nothing. + * + * libusb can be compiled without any logging functions, useful for embedded + * systems. In this case, libusb_set_debug() and the LIBUSB_DEBUG environment + * variable have no effects. + * + * libusb can also be compiled with verbose debugging messages always. When + * the library is compiled in this way, all messages of all verbosities are + * always logged. libusb_set_debug() and the LIBUSB_DEBUG environment variable + * have no effects. + * + * \section remarks Other remarks + * + * libusb does have imperfections. The \ref libusb_caveats "caveats" page attempts + * to document these. + */ + +/** + * \page libusb_caveats Caveats + * + * \section devresets Device resets + * + * The libusb_reset_device() function allows you to reset a device. If your + * program has to call such a function, it should obviously be aware that + * the reset will cause device state to change (e.g. register values may be + * reset). + * + * The problem is that any other program could reset the device your program + * is working with, at any time. libusb does not offer a mechanism to inform + * you when this has happened, so if someone else resets your device it will + * not be clear to your own program why the device state has changed. + * + * Ultimately, this is a limitation of writing drivers in userspace. + * Separation from the USB stack in the underlying kernel makes it difficult + * for the operating system to deliver such notifications to your program. + * The Linux kernel USB stack allows such reset notifications to be delivered + * to in-kernel USB drivers, but it is not clear how such notifications could + * be delivered to second-class drivers that live in userspace. + * + * \section blockonly Blocking-only functionality + * + * The functionality listed below is only available through synchronous, + * blocking functions. There are no asynchronous/non-blocking alternatives, + * and no clear ways of implementing these. + * + * - Configuration activation (libusb_set_configuration()) + * - Interface/alternate setting activation (libusb_set_interface_alt_setting()) + * - Releasing of interfaces (libusb_release_interface()) + * - Clearing of halt/stall condition (libusb_clear_halt()) + * - Device resets (libusb_reset_device()) + * + * \section configsel Configuration selection and handling + * + * When libusb presents a device handle to an application, there is a chance + * that the corresponding device may be in unconfigured state. For devices + * with multiple configurations, there is also a chance that the configuration + * currently selected is not the one that the application wants to use. + * + * The obvious solution is to add a call to libusb_set_configuration() early + * on during your device initialization routines, but there are caveats to + * be aware of: + * -# If the device is already in the desired configuration, calling + * libusb_set_configuration() using the same configuration value will cause + * a lightweight device reset. This may not be desirable behaviour. + * -# In the case where the desired configuration is already active, libusb + * may not even be able to perform a lightweight device reset. For example, + * take my USB keyboard with fingerprint reader: I'm interested in driving + * the fingerprint reader interface through libusb, but the kernel's + * USB-HID driver will almost always have claimed the keyboard interface. + * Because the kernel has claimed an interface, it is not even possible to + * perform the lightweight device reset, so libusb_set_configuration() will + * fail. (Luckily the device in question only has a single configuration.) + * -# libusb will be unable to set a configuration if other programs or + * drivers have claimed interfaces. In particular, this means that kernel + * drivers must be detached from all the interfaces before + * libusb_set_configuration() may succeed. + * + * One solution to some of the above problems is to consider the currently + * active configuration. If the configuration we want is already active, then + * we don't have to select any configuration: +\code +cfg = -1; +libusb_get_configuration(dev, &cfg); +if (cfg != desired) + libusb_set_configuration(dev, desired); +\endcode + * + * This is probably suitable for most scenarios, but is inherently racy: + * another application or driver may change the selected configuration + * after the libusb_get_configuration() call. + * + * Even in cases where libusb_set_configuration() succeeds, consider that other + * applications or drivers may change configuration after your application + * calls libusb_set_configuration(). + * + * One possible way to lock your device into a specific configuration is as + * follows: + * -# Set the desired configuration (or use the logic above to realise that + * it is already in the desired configuration) + * -# Claim the interface that you wish to use + * -# Check that the currently active configuration is the one that you want + * to use. + * + * The above method works because once an interface is claimed, no application + * or driver is able to select another configuration. + * + * \section earlycomp Early transfer completion + * + * NOTE: This section is currently Linux-centric. I am not sure if any of these + * considerations apply to Darwin or other platforms. + * + * When a transfer completes early (i.e. when less data is received/sent in + * any one packet than the transfer buffer allows for) then libusb is designed + * to terminate the transfer immediately, not transferring or receiving any + * more data unless other transfers have been queued by the user. + * + * On legacy platforms, libusb is unable to do this in all situations. After + * the incomplete packet occurs, "surplus" data may be transferred. For recent + * versions of libusb, this information is kept (the data length of the + * transfer is updated) and, for device-to-host transfers, any surplus data was + * added to the buffer. Still, this is not a nice solution because it loses the + * information about the end of the short packet, and the user probably wanted + * that surplus data to arrive in the next logical transfer. + * + * + * \section zlp Zero length packets + * + * - libusb is able to send a packet of zero length to an endpoint simply by + * submitting a transfer of zero length. + * - The \ref libusb_transfer_flags::LIBUSB_TRANSFER_ADD_ZERO_PACKET + * "LIBUSB_TRANSFER_ADD_ZERO_PACKET" flag is currently only supported on Linux. + */ + +/** + * \page libusb_contexts Contexts + * + * It is possible that libusb may be used simultaneously from two independent + * libraries linked into the same executable. For example, if your application + * has a plugin-like system which allows the user to dynamically load a range + * of modules into your program, it is feasible that two independently + * developed modules may both use libusb. + * + * libusb is written to allow for these multiple user scenarios. The two + * "instances" of libusb will not interfere: libusb_set_debug() calls + * from one user will not affect the same settings for other users, other + * users can continue using libusb after one of them calls libusb_exit(), etc. + * + * This is made possible through libusb's context concept. When you + * call libusb_init(), you are (optionally) given a context. You can then pass + * this context pointer back into future libusb functions. + * + * In order to keep things simple for more simplistic applications, it is + * legal to pass NULL to all functions requiring a context pointer (as long as + * you're sure no other code will attempt to use libusb from the same process). + * When you pass NULL, the default context will be used. The default context + * is created the first time a process calls libusb_init() when no other + * context is alive. Contexts are destroyed during libusb_exit(). + * + * The default context is reference-counted and can be shared. That means that + * if libusb_init(NULL) is called twice within the same process, the two + * users end up sharing the same context. The deinitialization and freeing of + * the default context will only happen when the last user calls libusb_exit(). + * In other words, the default context is created and initialized when its + * reference count goes from 0 to 1, and is deinitialized and destroyed when + * its reference count goes from 1 to 0. + * + * You may be wondering why only a subset of libusb functions require a + * context pointer in their function definition. Internally, libusb stores + * context pointers in other objects (e.g. libusb_device instances) and hence + * can infer the context from those objects. + */ + + /** + * \page libusb_api Application Programming Interface + * + * This is the complete list of libusb functions, structures and + * enumerations in alphabetical order. + * + * \section Functions + * - libusb_alloc_streams() + * - libusb_alloc_transfer() + * - libusb_attach_kernel_driver() + * - libusb_bulk_transfer() + * - libusb_cancel_transfer() + * - libusb_claim_interface() + * - libusb_clear_halt() + * - libusb_close() + * - libusb_control_transfer() + * - libusb_control_transfer_get_data() + * - libusb_control_transfer_get_setup() + * - libusb_cpu_to_le16() + * - libusb_detach_kernel_driver() + * - libusb_dev_mem_alloc() + * - libusb_dev_mem_free() + * - libusb_error_name() + * - libusb_event_handler_active() + * - libusb_event_handling_ok() + * - libusb_exit() + * - libusb_fill_bulk_stream_transfer() + * - libusb_fill_bulk_transfer() + * - libusb_fill_control_setup() + * - libusb_fill_control_transfer() + * - libusb_fill_interrupt_transfer() + * - libusb_fill_iso_transfer() + * - libusb_free_bos_descriptor() + * - libusb_free_config_descriptor() + * - libusb_free_container_id_descriptor() + * - libusb_free_device_list() + * - libusb_free_pollfds() + * - libusb_free_ss_endpoint_companion_descriptor() + * - libusb_free_ss_usb_device_capability_descriptor() + * - libusb_free_streams() + * - libusb_free_transfer() + * - libusb_free_usb_2_0_extension_descriptor() + * - libusb_get_active_config_descriptor() + * - libusb_get_bos_descriptor() + * - libusb_get_bus_number() + * - libusb_get_config_descriptor() + * - libusb_get_config_descriptor_by_value() + * - libusb_get_configuration() + * - libusb_get_container_id_descriptor() + * - libusb_get_descriptor() + * - libusb_get_device() + * - libusb_get_device_address() + * - libusb_get_device_descriptor() + * - libusb_get_device_list() + * - libusb_get_device_speed() + * - libusb_get_iso_packet_buffer() + * - libusb_get_iso_packet_buffer_simple() + * - libusb_get_max_iso_packet_size() + * - libusb_get_max_packet_size() + * - libusb_get_next_timeout() + * - libusb_get_parent() + * - libusb_get_pollfds() + * - libusb_get_port_number() + * - libusb_get_port_numbers() + * - libusb_get_port_path() + * - libusb_get_ss_endpoint_companion_descriptor() + * - libusb_get_ss_usb_device_capability_descriptor() + * - libusb_get_string_descriptor() + * - libusb_get_string_descriptor_ascii() + * - libusb_get_usb_2_0_extension_descriptor() + * - libusb_get_version() + * - libusb_handle_events() + * - libusb_handle_events_completed() + * - libusb_handle_events_locked() + * - libusb_handle_events_timeout() + * - libusb_handle_events_timeout_completed() + * - libusb_has_capability() + * - libusb_hotplug_deregister_callback() + * - libusb_hotplug_register_callback() + * - libusb_init() + * - libusb_interrupt_event_handler() + * - libusb_interrupt_transfer() + * - libusb_kernel_driver_active() + * - libusb_lock_events() + * - libusb_lock_event_waiters() + * - libusb_open() + * - libusb_open_device_with_vid_pid() + * - libusb_pollfds_handle_timeouts() + * - libusb_ref_device() + * - libusb_release_interface() + * - libusb_reset_device() + * - libusb_set_auto_detach_kernel_driver() + * - libusb_set_configuration() + * - libusb_set_debug() + * - libusb_set_interface_alt_setting() + * - libusb_set_iso_packet_lengths() + * - libusb_setlocale() + * - libusb_set_pollfd_notifiers() + * - libusb_strerror() + * - libusb_submit_transfer() + * - libusb_transfer_get_stream_id() + * - libusb_transfer_set_stream_id() + * - libusb_try_lock_events() + * - libusb_unlock_events() + * - libusb_unlock_event_waiters() + * - libusb_unref_device() + * - libusb_wait_for_event() + * + * \section Structures + * - libusb_bos_descriptor + * - libusb_bos_dev_capability_descriptor + * - libusb_config_descriptor + * - libusb_container_id_descriptor + * - \ref libusb_context + * - libusb_control_setup + * - \ref libusb_device + * - libusb_device_descriptor + * - \ref libusb_device_handle + * - libusb_endpoint_descriptor + * - libusb_interface + * - libusb_interface_descriptor + * - libusb_iso_packet_descriptor + * - libusb_pollfd + * - libusb_ss_endpoint_companion_descriptor + * - libusb_ss_usb_device_capability_descriptor + * - libusb_transfer + * - libusb_usb_2_0_extension_descriptor + * - libusb_version + * + * \section Enums + * - \ref libusb_bos_type + * - \ref libusb_capability + * - \ref libusb_class_code + * - \ref libusb_descriptor_type + * - \ref libusb_endpoint_direction + * - \ref libusb_error + * - \ref libusb_iso_sync_type + * - \ref libusb_iso_usage_type + * - \ref libusb_log_level + * - \ref libusb_request_recipient + * - \ref libusb_request_type + * - \ref libusb_speed + * - \ref libusb_ss_usb_device_capability_attributes + * - \ref libusb_standard_request + * - \ref libusb_supported_speed + * - \ref libusb_transfer_flags + * - \ref libusb_transfer_status + * - \ref libusb_transfer_type + * - \ref libusb_usb_2_0_extension_attributes + */ + +/** + * @defgroup libusb_lib Library initialization/deinitialization + * This page details how to initialize and deinitialize libusb. Initialization + * must be performed before using any libusb functionality, and similarly you + * must not call any libusb functions after deinitialization. + */ + +/** + * @defgroup libusb_dev Device handling and enumeration + * The functionality documented below is designed to help with the following + * operations: + * - Enumerating the USB devices currently attached to the system + * - Choosing a device to operate from your software + * - Opening and closing the chosen device + * + * \section nutshell In a nutshell... + * + * The description below really makes things sound more complicated than they + * actually are. The following sequence of function calls will be suitable + * for almost all scenarios and does not require you to have such a deep + * understanding of the resource management issues: + * \code +// discover devices +libusb_device **list; +libusb_device *found = NULL; +ssize_t cnt = libusb_get_device_list(NULL, &list); +ssize_t i = 0; +int err = 0; +if (cnt < 0) + error(); + +for (i = 0; i < cnt; i++) { + libusb_device *device = list[i]; + if (is_interesting(device)) { + found = device; + break; + } +} + +if (found) { + libusb_device_handle *handle; + + err = libusb_open(found, &handle); + if (err) + error(); + // etc +} + +libusb_free_device_list(list, 1); +\endcode + * + * The two important points: + * - You asked libusb_free_device_list() to unreference the devices (2nd + * parameter) + * - You opened the device before freeing the list and unreferencing the + * devices + * + * If you ended up with a handle, you can now proceed to perform I/O on the + * device. + * + * \section devshandles Devices and device handles + * libusb has a concept of a USB device, represented by the + * \ref libusb_device opaque type. A device represents a USB device that + * is currently or was previously connected to the system. Using a reference + * to a device, you can determine certain information about the device (e.g. + * you can read the descriptor data). + * + * The libusb_get_device_list() function can be used to obtain a list of + * devices currently connected to the system. This is known as device + * discovery. + * + * Just because you have a reference to a device does not mean it is + * necessarily usable. The device may have been unplugged, you may not have + * permission to operate such device, or another program or driver may be + * using the device. + * + * When you've found a device that you'd like to operate, you must ask + * libusb to open the device using the libusb_open() function. Assuming + * success, libusb then returns you a device handle + * (a \ref libusb_device_handle pointer). All "real" I/O operations then + * operate on the handle rather than the original device pointer. + * + * \section devref Device discovery and reference counting + * + * Device discovery (i.e. calling libusb_get_device_list()) returns a + * freshly-allocated list of devices. The list itself must be freed when + * you are done with it. libusb also needs to know when it is OK to free + * the contents of the list - the devices themselves. + * + * To handle these issues, libusb provides you with two separate items: + * - A function to free the list itself + * - A reference counting system for the devices inside + * + * New devices presented by the libusb_get_device_list() function all have a + * reference count of 1. You can increase and decrease reference count using + * libusb_ref_device() and libusb_unref_device(). A device is destroyed when + * its reference count reaches 0. + * + * With the above information in mind, the process of opening a device can + * be viewed as follows: + * -# Discover devices using libusb_get_device_list(). + * -# Choose the device that you want to operate, and call libusb_open(). + * -# Unref all devices in the discovered device list. + * -# Free the discovered device list. + * + * The order is important - you must not unreference the device before + * attempting to open it, because unreferencing it may destroy the device. + * + * For convenience, the libusb_free_device_list() function includes a + * parameter to optionally unreference all the devices in the list before + * freeing the list itself. This combines steps 3 and 4 above. + * + * As an implementation detail, libusb_open() actually adds a reference to + * the device in question. This is because the device remains available + * through the handle via libusb_get_device(). The reference is deleted during + * libusb_close(). + */ + +/** @defgroup libusb_misc Miscellaneous */ + +/* we traverse usbfs without knowing how many devices we are going to find. + * so we create this discovered_devs model which is similar to a linked-list + * which grows when required. it can be freed once discovery has completed, + * eliminating the need for a list node in the libusb_device structure + * itself. */ +#define DISCOVERED_DEVICES_SIZE_STEP 8 + +static struct discovered_devs *discovered_devs_alloc(void) +{ + struct discovered_devs *ret = + malloc(sizeof(*ret) + (sizeof(void *) * DISCOVERED_DEVICES_SIZE_STEP)); + + if (ret) { + ret->len = 0; + ret->capacity = DISCOVERED_DEVICES_SIZE_STEP; + } + return ret; +} + +static void discovered_devs_free(struct discovered_devs *discdevs) +{ + size_t i; + + for (i = 0; i < discdevs->len; i++) + libusb_unref_device(discdevs->devices[i]); + + free(discdevs); +} + +/* append a device to the discovered devices collection. may realloc itself, + * returning new discdevs. returns NULL on realloc failure. */ +struct discovered_devs *discovered_devs_append( + struct discovered_devs *discdevs, struct libusb_device *dev) +{ + size_t len = discdevs->len; + size_t capacity; + struct discovered_devs *new_discdevs; + + /* if there is space, just append the device */ + if (len < discdevs->capacity) { + discdevs->devices[len] = libusb_ref_device(dev); + discdevs->len++; + return discdevs; + } + + /* exceeded capacity, need to grow */ + usbi_dbg("need to increase capacity"); + capacity = discdevs->capacity + DISCOVERED_DEVICES_SIZE_STEP; + /* can't use usbi_reallocf here because in failure cases it would + * free the existing discdevs without unreferencing its devices. */ + new_discdevs = realloc(discdevs, + sizeof(*discdevs) + (sizeof(void *) * capacity)); + if (!new_discdevs) { + discovered_devs_free(discdevs); + return NULL; + } + + discdevs = new_discdevs; + discdevs->capacity = capacity; + discdevs->devices[len] = libusb_ref_device(dev); + discdevs->len++; + + return discdevs; +} + +/* Allocate a new device with a specific session ID. The returned device has + * a reference count of 1. */ +struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, + unsigned long session_id) +{ + size_t priv_size = usbi_backend->device_priv_size; + struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size); + int r; + + if (!dev) + return NULL; + + r = usbi_mutex_init(&dev->lock); + if (r) { + free(dev); + return NULL; + } + + dev->ctx = ctx; + dev->refcnt = 1; + dev->session_data = session_id; + dev->speed = LIBUSB_SPEED_UNKNOWN; + + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + usbi_connect_device (dev); + } + + return dev; +} + +void usbi_connect_device(struct libusb_device *dev) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + + dev->attached = 1; + + usbi_mutex_lock(&dev->ctx->usb_devs_lock); + list_add(&dev->list, &dev->ctx->usb_devs); + usbi_mutex_unlock(&dev->ctx->usb_devs_lock); + + /* Signal that an event has occurred for this device if we support hotplug AND + * the hotplug message list is ready. This prevents an event from getting raised + * during initial enumeration. */ + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) { + usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED); + } +} + +void usbi_disconnect_device(struct libusb_device *dev) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + + usbi_mutex_lock(&dev->lock); + dev->attached = 0; + usbi_mutex_unlock(&dev->lock); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_del(&dev->list); + usbi_mutex_unlock(&ctx->usb_devs_lock); + + /* Signal that an event has occurred for this device if we support hotplug AND + * the hotplug message list is ready. This prevents an event from getting raised + * during initial enumeration. libusb_handle_events will take care of dereferencing + * the device. */ + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) { + usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT); + } +} + +/* Perform some final sanity checks on a newly discovered device. If this + * function fails (negative return code), the device should not be added + * to the discovered device list. */ +int usbi_sanitize_device(struct libusb_device *dev) +{ + int r; + uint8_t num_configurations; + + r = usbi_device_cache_descriptor(dev); + if (r < 0) + return r; + + num_configurations = dev->device_descriptor.bNumConfigurations; + if (num_configurations > USB_MAXCONFIG) { + usbi_err(DEVICE_CTX(dev), "too many configurations"); + return LIBUSB_ERROR_IO; + } else if (0 == num_configurations) + usbi_dbg("zero configurations, maybe an unauthorized device"); + + dev->num_configurations = num_configurations; + return 0; +} + +/* Examine libusb's internal list of known devices, looking for one with + * a specific session ID. Returns the matching device if it was found, and + * NULL otherwise. */ +struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, + unsigned long session_id) +{ + struct libusb_device *dev; + struct libusb_device *ret = NULL; + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) + if (dev->session_data == session_id) { + ret = libusb_ref_device(dev); + break; + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + return ret; +} + +/** @ingroup libusb_dev + * Returns a list of USB devices currently attached to the system. This is + * your entry point into finding a USB device to operate. + * + * You are expected to unreference all the devices when you are done with + * them, and then free the list with libusb_free_device_list(). Note that + * libusb_free_device_list() can unref all the devices for you. Be careful + * not to unreference a device you are about to open until after you have + * opened it. + * + * This return value of this function indicates the number of devices in + * the resultant list. The list is actually one element larger, as it is + * NULL-terminated. + * + * \param ctx the context to operate on, or NULL for the default context + * \param list output location for a list of devices. Must be later freed with + * libusb_free_device_list(). + * \returns the number of devices in the outputted list, or any + * \ref libusb_error according to errors encountered by the backend. + */ +ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx, + libusb_device ***list) +{ + struct discovered_devs *discdevs = discovered_devs_alloc(); + struct libusb_device **ret; + int r = 0; + ssize_t i, len; + USBI_GET_CONTEXT(ctx); + usbi_dbg(""); + + if (!discdevs) + return LIBUSB_ERROR_NO_MEM; + + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + /* backend provides hotplug support */ + struct libusb_device *dev; + + if (usbi_backend->hotplug_poll) + usbi_backend->hotplug_poll(); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) { + discdevs = discovered_devs_append(discdevs, dev); + + if (!discdevs) { + r = LIBUSB_ERROR_NO_MEM; + break; + } + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + } else { + /* backend does not provide hotplug support */ + r = usbi_backend->get_device_list(ctx, &discdevs); + } + + if (r < 0) { + len = r; + goto out; + } + + /* convert discovered_devs into a list */ + len = discdevs->len; + ret = calloc(len + 1, sizeof(struct libusb_device *)); + if (!ret) { + len = LIBUSB_ERROR_NO_MEM; + goto out; + } + + ret[len] = NULL; + for (i = 0; i < len; i++) { + struct libusb_device *dev = discdevs->devices[i]; + ret[i] = libusb_ref_device(dev); + } + *list = ret; + +out: + if (discdevs) + discovered_devs_free(discdevs); + return len; +} + +/** \ingroup libusb_dev + * Frees a list of devices previously discovered using + * libusb_get_device_list(). If the unref_devices parameter is set, the + * reference count of each device in the list is decremented by 1. + * \param list the list to free + * \param unref_devices whether to unref the devices in the list + */ +void API_EXPORTED libusb_free_device_list(libusb_device **list, + int unref_devices) +{ + if (!list) + return; + + if (unref_devices) { + int i = 0; + struct libusb_device *dev; + + while ((dev = list[i++]) != NULL) + libusb_unref_device(dev); + } + free(list); +} + +/** \ingroup libusb_dev + * Get the number of the bus that a device is connected to. + * \param dev a device + * \returns the bus number + */ +uint8_t API_EXPORTED libusb_get_bus_number(libusb_device *dev) +{ + return dev->bus_number; +} + +/** \ingroup libusb_dev + * Get the number of the port that a device is connected to. + * Unless the OS does something funky, or you are hot-plugging USB extension cards, + * the port number returned by this call is usually guaranteed to be uniquely tied + * to a physical port, meaning that different devices plugged on the same physical + * port should return the same port number. + * + * But outside of this, there is no guarantee that the port number returned by this + * call will remain the same, or even match the order in which ports have been + * numbered by the HUB/HCD manufacturer. + * + * \param dev a device + * \returns the port number (0 if not available) + */ +uint8_t API_EXPORTED libusb_get_port_number(libusb_device *dev) +{ + return dev->port_number; +} + +/** \ingroup libusb_dev + * Get the list of all port numbers from root for the specified device + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * \param dev a device + * \param port_numbers the array that should contain the port numbers + * \param port_numbers_len the maximum length of the array. As per the USB 3.0 + * specs, the current maximum limit for the depth is 7. + * \returns the number of elements filled + * \returns LIBUSB_ERROR_OVERFLOW if the array is too small + */ +int API_EXPORTED libusb_get_port_numbers(libusb_device *dev, + uint8_t* port_numbers, int port_numbers_len) +{ + int i = port_numbers_len; + struct libusb_context *ctx = DEVICE_CTX(dev); + + if (port_numbers_len <= 0) + return LIBUSB_ERROR_INVALID_PARAM; + + // HCDs can be listed as devices with port #0 + while((dev) && (dev->port_number != 0)) { + if (--i < 0) { + usbi_warn(ctx, "port numbers array is too small"); + return LIBUSB_ERROR_OVERFLOW; + } + port_numbers[i] = dev->port_number; + dev = dev->parent_dev; + } + if (i < port_numbers_len) + memmove(port_numbers, &port_numbers[i], port_numbers_len - i); + return port_numbers_len - i; +} + +/** \ingroup libusb_dev + * Deprecated please use libusb_get_port_numbers instead. + */ +int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev, + uint8_t* port_numbers, uint8_t port_numbers_len) +{ + UNUSED(ctx); + + return libusb_get_port_numbers(dev, port_numbers, port_numbers_len); +} + +/** \ingroup libusb_dev + * Get the the parent from the specified device. + * \param dev a device + * \returns the device parent or NULL if not available + * You should issue a \ref libusb_get_device_list() before calling this + * function and make sure that you only access the parent before issuing + * \ref libusb_free_device_list(). The reason is that libusb currently does + * not maintain a permanent list of device instances, and therefore can + * only guarantee that parents are fully instantiated within a + * libusb_get_device_list() - libusb_free_device_list() block. + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev) +{ + return dev->parent_dev; +} + +/** \ingroup libusb_dev + * Get the address of the device on the bus it is connected to. + * \param dev a device + * \returns the device address + */ +uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev) +{ + return dev->device_address; +} + +/** \ingroup libusb_dev + * Get the negotiated connection speed for a device. + * \param dev a device + * \returns a \ref libusb_speed code, where LIBUSB_SPEED_UNKNOWN means that + * the OS doesn't know or doesn't support returning the negotiated speed. + */ +int API_EXPORTED libusb_get_device_speed(libusb_device *dev) +{ + return dev->speed; +} + +static const struct libusb_endpoint_descriptor *find_endpoint( + struct libusb_config_descriptor *config, unsigned char endpoint) +{ + int iface_idx; + for (iface_idx = 0; iface_idx < config->bNumInterfaces; iface_idx++) { + const struct libusb_interface *iface = &config->interface[iface_idx]; + int altsetting_idx; + + for (altsetting_idx = 0; altsetting_idx < iface->num_altsetting; + altsetting_idx++) { + const struct libusb_interface_descriptor *altsetting + = &iface->altsetting[altsetting_idx]; + int ep_idx; + + for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) { + const struct libusb_endpoint_descriptor *ep = + &altsetting->endpoint[ep_idx]; + if (ep->bEndpointAddress == endpoint) + return ep; + } + } + } + return NULL; +} + +/** \ingroup libusb_dev + * Convenience function to retrieve the wMaxPacketSize value for a particular + * endpoint in the active device configuration. + * + * This function was originally intended to be of assistance when setting up + * isochronous transfers, but a design mistake resulted in this function + * instead. It simply returns the wMaxPacketSize value without considering + * its contents. If you're dealing with isochronous transfers, you probably + * want libusb_get_max_iso_packet_size() instead. + * + * \param dev a device + * \param endpoint address of the endpoint in question + * \returns the wMaxPacketSize value + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_OTHER on other failure + */ +int API_EXPORTED libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint) +{ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *ep; + int r; + + r = libusb_get_active_config_descriptor(dev, &config); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "could not retrieve active config descriptor"); + return LIBUSB_ERROR_OTHER; + } + + ep = find_endpoint(config, endpoint); + if (!ep) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + r = ep->wMaxPacketSize; + +out: + libusb_free_config_descriptor(config); + return r; +} + +/** \ingroup libusb_dev + * Calculate the maximum packet size which a specific endpoint is capable is + * sending or receiving in the duration of 1 microframe + * + * Only the active configuration is examined. The calculation is based on the + * wMaxPacketSize field in the endpoint descriptor as described in section + * 9.6.6 in the USB 2.0 specifications. + * + * If acting on an isochronous or interrupt endpoint, this function will + * multiply the value found in bits 0:10 by the number of transactions per + * microframe (determined by bits 11:12). Otherwise, this function just + * returns the numeric value found in bits 0:10. + * + * This function is useful for setting up isochronous transfers, for example + * you might pass the return value from this function to + * libusb_set_iso_packet_lengths() in order to set the length field of every + * isochronous packet in a transfer. + * + * Since v1.0.3. + * + * \param dev a device + * \param endpoint address of the endpoint in question + * \returns the maximum packet size which can be sent/received on this endpoint + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_OTHER on other failure + */ +int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint) +{ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *ep; + enum libusb_transfer_type ep_type; + uint16_t val; + int r; + + r = libusb_get_active_config_descriptor(dev, &config); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "could not retrieve active config descriptor"); + return LIBUSB_ERROR_OTHER; + } + + ep = find_endpoint(config, endpoint); + if (!ep) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + val = ep->wMaxPacketSize; + ep_type = (enum libusb_transfer_type) (ep->bmAttributes & 0x3); + + r = val & 0x07ff; + if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS + || ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) + r *= (1 + ((val >> 11) & 3)); + +out: + libusb_free_config_descriptor(config); + return r; +} + +/** \ingroup libusb_dev + * Increment the reference count of a device. + * \param dev the device to reference + * \returns the same device + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev) +{ + usbi_mutex_lock(&dev->lock); + dev->refcnt++; + usbi_mutex_unlock(&dev->lock); + return dev; +} + +/** \ingroup libusb_dev + * Decrement the reference count of a device. If the decrement operation + * causes the reference count to reach zero, the device shall be destroyed. + * \param dev the device to unreference + */ +void API_EXPORTED libusb_unref_device(libusb_device *dev) +{ + int refcnt; + + if (!dev) + return; + + usbi_mutex_lock(&dev->lock); + refcnt = --dev->refcnt; + usbi_mutex_unlock(&dev->lock); + + if (refcnt == 0) { + usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address); + + libusb_unref_device(dev->parent_dev); + + if (usbi_backend->destroy_device) + usbi_backend->destroy_device(dev); + + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + /* backend does not support hotplug */ + usbi_disconnect_device(dev); + } + + usbi_mutex_destroy(&dev->lock); + free(dev); + } +} + +/* + * Signal the event pipe so that the event handling thread will be + * interrupted to process an internal event. + */ +int usbi_signal_event(struct libusb_context *ctx) +{ + unsigned char dummy = 1; + ssize_t r; + + /* write some data on event pipe to interrupt event handlers */ + r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy)); + if (r != sizeof(dummy)) { + usbi_warn(ctx, "internal signalling write failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/* + * Clear the event pipe so that the event handling will no longer be + * interrupted. + */ +int usbi_clear_event(struct libusb_context *ctx) +{ + unsigned char dummy; + ssize_t r; + + /* read some data on event pipe to clear it */ + r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy)); + if (r != sizeof(dummy)) { + usbi_warn(ctx, "internal signalling read failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/** \ingroup libusb_dev + * Open a device and obtain a device handle. A handle allows you to perform + * I/O on the device in question. + * + * Internally, this function adds a reference to the device and makes it + * available to you through libusb_get_device(). This reference is removed + * during libusb_close(). + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev the device to open + * \param dev_handle output location for the returned device handle pointer. Only + * populated when the return code is 0. + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_MEM on memory allocation failure + * \returns LIBUSB_ERROR_ACCESS if the user has insufficient permissions + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_open(libusb_device *dev, + libusb_device_handle **dev_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct libusb_device_handle *_dev_handle; + size_t priv_size = usbi_backend->device_handle_priv_size; + int r; + usbi_dbg("open %d.%d", dev->bus_number, dev->device_address); + + if (!dev->attached) { + return LIBUSB_ERROR_NO_DEVICE; + } + + _dev_handle = malloc(sizeof(*_dev_handle) + priv_size); + if (!_dev_handle) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_mutex_init(&_dev_handle->lock); + if (r) { + free(_dev_handle); + return LIBUSB_ERROR_OTHER; + } + + _dev_handle->dev = libusb_ref_device(dev); + _dev_handle->auto_detach_kernel_driver = 0; + _dev_handle->claimed_interfaces = 0; + memset(&_dev_handle->os_priv, 0, priv_size); + + r = usbi_backend->open(_dev_handle); + if (r < 0) { + usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r); + libusb_unref_device(dev); + usbi_mutex_destroy(&_dev_handle->lock); + free(_dev_handle); + return r; + } + + usbi_mutex_lock(&ctx->open_devs_lock); + list_add(&_dev_handle->list, &ctx->open_devs); + usbi_mutex_unlock(&ctx->open_devs_lock); + *dev_handle = _dev_handle; + + return 0; +} + +/** \ingroup libusb_dev + * Convenience function for finding a device with a particular + * idVendor/idProduct combination. This function is intended + * for those scenarios where you are using libusb to knock up a quick test + * application - it allows you to avoid calling libusb_get_device_list() and + * worrying about traversing/freeing the list. + * + * This function has limitations and is hence not intended for use in real + * applications: if multiple devices have the same IDs it will only + * give you the first one, etc. + * + * \param ctx the context to operate on, or NULL for the default context + * \param vendor_id the idVendor value to search for + * \param product_id the idProduct value to search for + * \returns a device handle for the first found device, or NULL on error + * or if the device could not be found. */ +DEFAULT_VISIBILITY +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id) +{ + struct libusb_device **devs; + struct libusb_device *found = NULL; + struct libusb_device *dev; + struct libusb_device_handle *dev_handle = NULL; + size_t i = 0; + int r; + + if (libusb_get_device_list(ctx, &devs) < 0) + return NULL; + + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + r = libusb_get_device_descriptor(dev, &desc); + if (r < 0) + goto out; + if (desc.idVendor == vendor_id && desc.idProduct == product_id) { + found = dev; + break; + } + } + + if (found) { + r = libusb_open(found, &dev_handle); + if (r < 0) + dev_handle = NULL; + } + +out: + libusb_free_device_list(devs, 1); + return dev_handle; +} + +static void do_close(struct libusb_context *ctx, + struct libusb_device_handle *dev_handle) +{ + struct usbi_transfer *itransfer; + struct usbi_transfer *tmp; + + /* remove any transfers in flight that are for this device */ + usbi_mutex_lock(&ctx->flying_transfers_lock); + + /* safe iteration because transfers may be being deleted */ + list_for_each_entry_safe(itransfer, tmp, &ctx->flying_transfers, list, struct usbi_transfer) { + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + if (transfer->dev_handle != dev_handle) + continue; + + usbi_mutex_lock(&itransfer->lock); + if (!(itransfer->state_flags & USBI_TRANSFER_DEVICE_DISAPPEARED)) { + usbi_err(ctx, "Device handle closed while transfer was still being processed, but the device is still connected as far as we know"); + + if (itransfer->state_flags & USBI_TRANSFER_CANCELLING) + usbi_warn(ctx, "A cancellation for an in-flight transfer hasn't completed but closing the device handle"); + else + usbi_err(ctx, "A cancellation hasn't even been scheduled on the transfer for which the device is closing"); + } + usbi_mutex_unlock(&itransfer->lock); + + /* remove from the list of in-flight transfers and make sure + * we don't accidentally use the device handle in the future + * (or that such accesses will be easily caught and identified as a crash) + */ + list_del(&itransfer->list); + transfer->dev_handle = NULL; + + /* it is up to the user to free up the actual transfer struct. this is + * just making sure that we don't attempt to process the transfer after + * the device handle is invalid + */ + usbi_dbg("Removed transfer %p from the in-flight list because device handle %p closed", + transfer, dev_handle); + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + usbi_mutex_lock(&ctx->open_devs_lock); + list_del(&dev_handle->list); + usbi_mutex_unlock(&ctx->open_devs_lock); + + usbi_backend->close(dev_handle); + libusb_unref_device(dev_handle->dev); + usbi_mutex_destroy(&dev_handle->lock); + free(dev_handle); +} + +/** \ingroup libusb_dev + * Close a device handle. Should be called on all open handles before your + * application exits. + * + * Internally, this function destroys the reference that was added by + * libusb_open() on the given device. + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev_handle the device handle to close + */ +void API_EXPORTED libusb_close(libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx; + int handling_events; + int pending_events; + + if (!dev_handle) + return; + usbi_dbg(""); + + ctx = HANDLE_CTX(dev_handle); + handling_events = usbi_handling_events(ctx); + + /* Similarly to libusb_open(), we want to interrupt all event handlers + * at this point. More importantly, we want to perform the actual close of + * the device while holding the event handling lock (preventing any other + * thread from doing event handling) because we will be removing a file + * descriptor from the polling loop. If this is being called by the current + * event handler, we can bypass the interruption code because we already + * hold the event handling lock. */ + + if (!handling_events) { + /* Record that we are closing a device. + * Only signal an event if there are no prior pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + ctx->device_close++; + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + /* take event handling lock */ + libusb_lock_events(ctx); + } + + /* Close the device */ + do_close(ctx, dev_handle); + + if (!handling_events) { + /* We're done with closing this device. + * Clear the event pipe if there are no further pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + ctx->device_close--; + pending_events = usbi_pending_events(ctx); + if (!pending_events) + usbi_clear_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + /* Release event handling lock and wake up event waiters */ + libusb_unlock_events(ctx); + } +} + +/** \ingroup libusb_dev + * Get the underlying device for a device handle. This function does not modify + * the reference count of the returned device, so do not feel compelled to + * unreference it when you are done. + * \param dev_handle a device handle + * \returns the underlying device + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle) +{ + return dev_handle->dev; +} + +/** \ingroup libusb_dev + * Determine the bConfigurationValue of the currently active configuration. + * + * You could formulate your own control request to obtain this information, + * but this function has the advantage that it may be able to retrieve the + * information from operating system caches (no I/O involved). + * + * If the OS does not cache this information, then this function will block + * while a control transfer is submitted to retrieve the information. + * + * This function will return a value of 0 in the config output + * parameter if the device is in unconfigured state. + * + * \param dev_handle a device handle + * \param config output location for the bConfigurationValue of the active + * configuration (only valid for return code 0) + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev_handle, + int *config) +{ + int r = LIBUSB_ERROR_NOT_SUPPORTED; + + usbi_dbg(""); + if (usbi_backend->get_configuration) + r = usbi_backend->get_configuration(dev_handle, config); + + if (r == LIBUSB_ERROR_NOT_SUPPORTED) { + uint8_t tmp = 0; + usbi_dbg("falling back to control message"); + r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &tmp, 1, 1000); + if (r == 0) { + usbi_err(HANDLE_CTX(dev_handle), "zero bytes returned in ctrl transfer?"); + r = LIBUSB_ERROR_IO; + } else if (r == 1) { + r = 0; + *config = tmp; + } else { + usbi_dbg("control failed, error %d", r); + } + } + + if (r == 0) + usbi_dbg("active config %d", *config); + + return r; +} + +/** \ingroup libusb_dev + * Set the active configuration for a device. + * + * The operating system may or may not have already set an active + * configuration on the device. It is up to your application to ensure the + * correct configuration is selected before you attempt to claim interfaces + * and perform other operations. + * + * If you call this function on a device already configured with the selected + * configuration, then this function will act as a lightweight device reset: + * it will issue a SET_CONFIGURATION request using the current configuration, + * causing most USB-related device state to be reset (altsetting reset to zero, + * endpoint halts cleared, toggles reset). + * + * You cannot change/reset configuration if your application has claimed + * interfaces. It is advised to set the desired configuration before claiming + * interfaces. + * + * Alternatively you can call libusb_release_interface() first. Note if you + * do things this way you must ensure that auto_detach_kernel_driver for + * dev is 0, otherwise the kernel driver will be re-attached when you + * release the interface(s). + * + * You cannot change/reset configuration if other applications or drivers have + * claimed interfaces. + * + * A configuration value of -1 will put the device in unconfigured state. + * The USB specifications state that a configuration value of 0 does this, + * however buggy devices exist which actually have a configuration 0. + * + * You should always use this function rather than formulating your own + * SET_CONFIGURATION control request. This is because the underlying operating + * system needs to know when such changes happen. + * + * This is a blocking function. + * + * \param dev_handle a device handle + * \param configuration the bConfigurationValue of the configuration you + * wish to activate, or -1 if you wish to put the device in an unconfigured + * state + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist + * \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev_handle, + int configuration) +{ + usbi_dbg("configuration %d", configuration); + return usbi_backend->set_configuration(dev_handle, configuration); +} + +/** \ingroup libusb_dev + * Claim an interface on a given device handle. You must claim the interface + * you wish to use before you can perform I/O on any of its endpoints. + * + * It is legal to attempt to claim an already-claimed interface, in which + * case libusb just returns 0 without doing anything. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel driver + * will be detached if necessary, on failure the detach error is returned. + * + * Claiming of interfaces is a purely logical operation; it does not cause + * any requests to be sent over the bus. Interface claiming is used to + * instruct the underlying operating system that your application wishes + * to take ownership of the interface. + * + * This is a non-blocking function. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the interface you + * wish to claim + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the requested interface does not exist + * \returns LIBUSB_ERROR_BUSY if another program or driver has claimed the + * interface + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns a LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle, + int interface_number) +{ + int r = 0; + + usbi_dbg("interface %d", interface_number); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_mutex_lock(&dev_handle->lock); + if (dev_handle->claimed_interfaces & (1 << interface_number)) + goto out; + + r = usbi_backend->claim_interface(dev_handle, interface_number); + if (r == 0) + dev_handle->claimed_interfaces |= 1 << interface_number; + +out: + usbi_mutex_unlock(&dev_handle->lock); + return r; +} + +/** \ingroup libusb_dev + * Release an interface previously claimed with libusb_claim_interface(). You + * should release all claimed interfaces before closing a device handle. + * + * This is a blocking function. A SET_INTERFACE control request will be sent + * to the device, resetting interface state to the first alternate setting. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel + * driver will be re-attached after releasing the interface. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the + * previously-claimed interface + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle, + int interface_number) +{ + int r; + + usbi_dbg("interface %d", interface_number); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + usbi_mutex_lock(&dev_handle->lock); + if (!(dev_handle->claimed_interfaces & (1 << interface_number))) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + r = usbi_backend->release_interface(dev_handle, interface_number); + if (r == 0) + dev_handle->claimed_interfaces &= ~(1 << interface_number); + +out: + usbi_mutex_unlock(&dev_handle->lock); + return r; +} + +/** \ingroup libusb_dev + * Activate an alternate setting for an interface. The interface must have + * been previously claimed with libusb_claim_interface(). + * + * You should always use this function rather than formulating your own + * SET_INTERFACE control request. This is because the underlying operating + * system needs to know when such changes happen. + * + * This is a blocking function. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the + * previously-claimed interface + * \param alternate_setting the bAlternateSetting of the alternate + * setting to activate + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed, or the + * requested alternate setting does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev_handle, + int interface_number, int alternate_setting) +{ + usbi_dbg("interface %d altsetting %d", + interface_number, alternate_setting); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + usbi_mutex_lock(&dev_handle->lock); + if (!dev_handle->dev->attached) { + usbi_mutex_unlock(&dev_handle->lock); + return LIBUSB_ERROR_NO_DEVICE; + } + + if (!(dev_handle->claimed_interfaces & (1 << interface_number))) { + usbi_mutex_unlock(&dev_handle->lock); + return LIBUSB_ERROR_NOT_FOUND; + } + usbi_mutex_unlock(&dev_handle->lock); + + return usbi_backend->set_interface_altsetting(dev_handle, interface_number, + alternate_setting); +} + +/** \ingroup libusb_dev + * Clear the halt/stall condition for an endpoint. Endpoints with halt status + * are unable to receive or transmit data until the halt condition is stalled. + * + * You should cancel all pending transfers before attempting to clear the halt + * condition. + * + * This is a blocking function. + * + * \param dev_handle a device handle + * \param endpoint the endpoint to clear halt status + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev_handle, + unsigned char endpoint) +{ + usbi_dbg("endpoint %x", endpoint); + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + return usbi_backend->clear_halt(dev_handle, endpoint); +} + +/** \ingroup libusb_dev + * Perform a USB port reset to reinitialize a device. The system will attempt + * to restore the previous configuration and alternate settings after the + * reset has completed. + * + * If the reset fails, the descriptors change, or the previous state cannot be + * restored, the device will appear to be disconnected and reconnected. This + * means that the device handle is no longer valid (you should close it) and + * rediscover the device. A return code of LIBUSB_ERROR_NOT_FOUND indicates + * when this is the case. + * + * This is a blocking function which usually incurs a noticeable delay. + * + * \param dev_handle a handle of the device to reset + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the + * device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_reset_device(libusb_device_handle *dev_handle) +{ + usbi_dbg(""); + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + return usbi_backend->reset_device(dev_handle); +} + +/** \ingroup libusb_asyncio + * Allocate up to num_streams usb bulk streams on the specified endpoints. This + * function takes an array of endpoints rather then a single endpoint because + * some protocols require that endpoints are setup with similar stream ids. + * All endpoints passed in must belong to the same interface. + * + * Note this function may return less streams then requested. Also note that the + * same number of streams are allocated for each endpoint in the endpoint array. + * + * Stream id 0 is reserved, and should not be used to communicate with devices. + * If libusb_alloc_streams() returns with a value of N, you may use stream ids + * 1 to N. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param dev_handle a device handle + * \param num_streams number of streams to try to allocate + * \param endpoints array of endpoints to allocate streams on + * \param num_endpoints length of the endpoints array + * \returns number of streams allocated, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev_handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + usbi_dbg("streams %u eps %d", (unsigned) num_streams, num_endpoints); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->alloc_streams) + return usbi_backend->alloc_streams(dev_handle, num_streams, endpoints, + num_endpoints); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_asyncio + * Free usb bulk streams allocated with libusb_alloc_streams(). + * + * Note streams are automatically free-ed when releasing an interface. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param dev_handle a device handle + * \param endpoints array of endpoints to free streams on + * \param num_endpoints length of the endpoints array + * \returns LIBUSB_SUCCESS, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_free_streams(libusb_device_handle *dev_handle, + unsigned char *endpoints, int num_endpoints) +{ + usbi_dbg("eps %d", num_endpoints); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->free_streams) + return usbi_backend->free_streams(dev_handle, endpoints, + num_endpoints); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_asyncio + * Attempts to allocate a block of persistent DMA memory suitable for transfers + * against the given device. If successful, will return a block of memory + * that is suitable for use as "buffer" in \ref libusb_transfer against this + * device. Using this memory instead of regular memory means that the host + * controller can use DMA directly into the buffer to increase performance, and + * also that transfers can no longer fail due to kernel memory fragmentation. + * + * Note that this means you should not modify this memory (or even data on + * the same cache lines) when a transfer is in progress, although it is legal + * to have several transfers going on within the same memory block. + * + * Will return NULL on failure. Many systems do not support such zerocopy + * and will always return NULL. Memory allocated with this function must be + * freed with \ref libusb_dev_mem_free. Specifically, this means that the + * flag \ref LIBUSB_TRANSFER_FREE_BUFFER cannot be used to free memory allocated + * with this function. + * + * Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105 + * + * \param dev_handle a device handle + * \param length size of desired data buffer + * \returns a pointer to the newly allocated memory, or NULL on failure + */ +DEFAULT_VISIBILITY +unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle, + size_t length) +{ + if (!dev_handle->dev->attached) + return NULL; + + if (usbi_backend->dev_mem_alloc) + return usbi_backend->dev_mem_alloc(dev_handle, length); + else + return NULL; +} + +/** \ingroup libusb_asyncio + * Free device memory allocated with libusb_dev_mem_alloc(). + * + * \param dev_handle a device handle + * \param buffer pointer to the previously allocated memory + * \param length size of previously allocated memory + * \returns LIBUSB_SUCCESS, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_dev_mem_free(libusb_device_handle *dev_handle, + unsigned char *buffer, size_t length) +{ + if (usbi_backend->dev_mem_free) + return usbi_backend->dev_mem_free(dev_handle, buffer, length); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Determine if a kernel driver is active on an interface. If a kernel driver + * is active, you cannot claim the interface, and libusb will be unable to + * perform I/O. + * + * This functionality is not available on Windows. + * + * \param dev_handle a device handle + * \param interface_number the interface to check + * \returns 0 if no kernel driver is active + * \returns 1 if a kernel driver is active + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_detach_kernel_driver() + */ +int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->kernel_driver_active) + return usbi_backend->kernel_driver_active(dev_handle, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Detach a kernel driver from an interface. If successful, you will then be + * able to claim the interface and perform I/O. + * + * This functionality is not available on Darwin or Windows. + * + * Note that libusb itself also talks to the device through a special kernel + * driver, if this driver is already attached to the device, this call will + * not detach it and return LIBUSB_ERROR_NOT_FOUND. + * + * \param dev_handle a device handle + * \param interface_number the interface to detach the driver from + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_kernel_driver_active() + */ +int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->detach_kernel_driver) + return usbi_backend->detach_kernel_driver(dev_handle, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Re-attach an interface's kernel driver, which was previously detached + * using libusb_detach_kernel_driver(). This call is only effective on + * Linux and returns LIBUSB_ERROR_NOT_SUPPORTED on all other platforms. + * + * This functionality is not available on Darwin or Windows. + * + * \param dev_handle a device handle + * \param interface_number the interface to attach the driver from + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns LIBUSB_ERROR_BUSY if the driver cannot be attached because the + * interface is claimed by a program or driver + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_kernel_driver_active() + */ +int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->attach_kernel_driver) + return usbi_backend->attach_kernel_driver(dev_handle, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Enable/disable libusb's automatic kernel driver detachment. When this is + * enabled libusb will automatically detach the kernel driver on an interface + * when claiming the interface, and attach it when releasing the interface. + * + * Automatic kernel driver detachment is disabled on newly opened device + * handles by default. + * + * On platforms which do not have LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER + * this function will return LIBUSB_ERROR_NOT_SUPPORTED, and libusb will + * continue as if this function was never called. + * + * \param dev_handle a device handle + * \param enable whether to enable or disable auto kernel driver detachment + * + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \see libusb_claim_interface() + * \see libusb_release_interface() + * \see libusb_set_configuration() + */ +int API_EXPORTED libusb_set_auto_detach_kernel_driver( + libusb_device_handle *dev_handle, int enable) +{ + if (!(usbi_backend->caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)) + return LIBUSB_ERROR_NOT_SUPPORTED; + + dev_handle->auto_detach_kernel_driver = enable; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_lib + * Set log message verbosity. + * + * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever + * printed. If you choose to increase the message verbosity level, ensure + * that your application does not close the stdout/stderr file descriptors. + * + * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative + * with its message logging and most of the time, will only log messages that + * explain error conditions and other oddities. This will help you debug + * your software. + * + * If the LIBUSB_DEBUG environment variable was set when libusb was + * initialized, this function does nothing: the message verbosity is fixed + * to the value in the environment variable. + * + * If libusb was compiled without any message logging, this function does + * nothing: you'll never get any messages. + * + * If libusb was compiled with verbose debug message logging, this function + * does nothing: you'll always get messages from all levels. + * + * \param ctx the context to operate on, or NULL for the default context + * \param level debug level to set + */ +void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level) +{ + USBI_GET_CONTEXT(ctx); + if (!ctx->debug_fixed) + ctx->debug = level; +} + +/** \ingroup libusb_lib + * Initialize libusb. This function must be called before calling any other + * libusb function. + * + * If you do not provide an output location for a context pointer, a default + * context will be created. If there was already a default context, it will + * be reused (and nothing will be initialized/reinitialized). + * + * \param context Optional output location for context pointer. + * Only valid on return code 0. + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \see libusb_contexts + */ +int API_EXPORTED libusb_init(libusb_context **context) +{ + struct libusb_device *dev, *next; + char *dbg = getenv("LIBUSB_DEBUG"); + struct libusb_context *ctx; + static int first_init = 1; + int r = 0; + + usbi_mutex_static_lock(&default_context_lock); + + if (!timestamp_origin.tv_sec) { + usbi_backend->clock_gettime(USBI_CLOCK_REALTIME, ×tamp_origin); + } + + if (!context && usbi_default_context) { + usbi_dbg("reusing default context"); + default_context_refcnt++; + usbi_mutex_static_unlock(&default_context_lock); + return 0; + } + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + r = LIBUSB_ERROR_NO_MEM; + goto err_unlock; + } + +#ifdef ENABLE_DEBUG_LOGGING + ctx->debug = LIBUSB_LOG_LEVEL_DEBUG; +#endif + + if (dbg) { + ctx->debug = atoi(dbg); + if (ctx->debug) + ctx->debug_fixed = 1; + } + + /* default context should be initialized before calling usbi_dbg */ + if (!usbi_default_context) { + usbi_default_context = ctx; + default_context_refcnt++; + usbi_dbg("created default context"); + } + + usbi_dbg("libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor, + libusb_version_internal.micro, libusb_version_internal.nano, libusb_version_internal.rc); + + usbi_mutex_init(&ctx->usb_devs_lock); + usbi_mutex_init(&ctx->open_devs_lock); + usbi_mutex_init(&ctx->hotplug_cbs_lock); + list_init(&ctx->usb_devs); + list_init(&ctx->open_devs); + list_init(&ctx->hotplug_cbs); + + usbi_mutex_static_lock(&active_contexts_lock); + if (first_init) { + first_init = 0; + list_init (&active_contexts_list); + } + list_add (&ctx->list, &active_contexts_list); + usbi_mutex_static_unlock(&active_contexts_lock); + + if (usbi_backend->init) { + r = usbi_backend->init(ctx); + if (r) + goto err_free_ctx; + } + + r = usbi_io_init(ctx); + if (r < 0) + goto err_backend_exit; + + usbi_mutex_static_unlock(&default_context_lock); + + if (context) + *context = ctx; + + return 0; + +err_backend_exit: + if (usbi_backend->exit) + usbi_backend->exit(); +err_free_ctx: + if (ctx == usbi_default_context) { + usbi_default_context = NULL; + default_context_refcnt--; + } + + usbi_mutex_static_lock(&active_contexts_lock); + list_del (&ctx->list); + usbi_mutex_static_unlock(&active_contexts_lock); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) { + list_del(&dev->list); + libusb_unref_device(dev); + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + usbi_mutex_destroy(&ctx->open_devs_lock); + usbi_mutex_destroy(&ctx->usb_devs_lock); + usbi_mutex_destroy(&ctx->hotplug_cbs_lock); + + free(ctx); +err_unlock: + usbi_mutex_static_unlock(&default_context_lock); + return r; +} + +/** \ingroup libusb_lib + * Deinitialize libusb. Should be called after closing all open devices and + * before your application terminates. + * \param ctx the context to deinitialize, or NULL for the default context + */ +void API_EXPORTED libusb_exit(struct libusb_context *ctx) +{ + struct libusb_device *dev, *next; + struct timeval tv = { 0, 0 }; + + usbi_dbg(""); + USBI_GET_CONTEXT(ctx); + + /* if working with default context, only actually do the deinitialization + * if we're the last user */ + usbi_mutex_static_lock(&default_context_lock); + if (ctx == usbi_default_context) { + if (--default_context_refcnt > 0) { + usbi_dbg("not destroying default context"); + usbi_mutex_static_unlock(&default_context_lock); + return; + } + usbi_dbg("destroying default context"); + usbi_default_context = NULL; + } + usbi_mutex_static_unlock(&default_context_lock); + + usbi_mutex_static_lock(&active_contexts_lock); + list_del (&ctx->list); + usbi_mutex_static_unlock(&active_contexts_lock); + + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + usbi_hotplug_deregister_all(ctx); + + /* + * Ensure any pending unplug events are read from the hotplug + * pipe. The usb_device-s hold in the events are no longer part + * of usb_devs, but the events still hold a reference! + * + * Note we don't do this if the application has left devices + * open (which implies a buggy app) to avoid packet completion + * handlers running when the app does not expect them to run. + */ + if (list_empty(&ctx->open_devs)) + libusb_handle_events_timeout(ctx, &tv); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) { + list_del(&dev->list); + libusb_unref_device(dev); + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + } + + /* a few sanity checks. don't bother with locking because unless + * there is an application bug, nobody will be accessing these. */ + if (!list_empty(&ctx->usb_devs)) + usbi_warn(ctx, "some libusb_devices were leaked"); + if (!list_empty(&ctx->open_devs)) + usbi_warn(ctx, "application left some devices open"); + + usbi_io_exit(ctx); + if (usbi_backend->exit) + usbi_backend->exit(); + + usbi_mutex_destroy(&ctx->open_devs_lock); + usbi_mutex_destroy(&ctx->usb_devs_lock); + usbi_mutex_destroy(&ctx->hotplug_cbs_lock); + free(ctx); +} + +/** \ingroup libusb_misc + * Check at runtime if the loaded library has a given capability. + * This call should be performed after \ref libusb_init(), to ensure the + * backend has updated its capability set. + * + * \param capability the \ref libusb_capability to check for + * \returns nonzero if the running library has the capability, 0 otherwise + */ +int API_EXPORTED libusb_has_capability(uint32_t capability) +{ + switch (capability) { + case LIBUSB_CAP_HAS_CAPABILITY: + return 1; + case LIBUSB_CAP_HAS_HOTPLUG: + return !(usbi_backend->get_device_list); + case LIBUSB_CAP_HAS_HID_ACCESS: + return (usbi_backend->caps & USBI_CAP_HAS_HID_ACCESS); + case LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER: + return (usbi_backend->caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER); + } + return 0; +} + +/* this is defined in libusbi.h if needed */ +#ifdef LIBUSB_PRINTF_WIN32 +/* + * Prior to VS2015, Microsoft did not provide the snprintf() function and + * provided a vsnprintf() that did not guarantee NULL-terminated output. + * Microsoft did provide a _snprintf() function, but again it did not + * guarantee NULL-terminated output. + * + * The below implementations guarantee NULL-terminated output and are + * C99 compliant. + */ + +int usbi_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = usbi_vsnprintf(str, size, format, ap); + va_end(ap); + + return ret; +} + +int usbi_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + int ret; + + ret = _vsnprintf(str, size, format, ap); + if (ret < 0 || ret == (int)size) { + /* Output is truncated, ensure buffer is NULL-terminated and + * determine how many characters would have been written. */ + str[size - 1] = '\0'; + if (ret < 0) + ret = _vsnprintf(NULL, 0, format, ap); + } + + return ret; +} +#endif + +static void usbi_log_str(struct libusb_context *ctx, + enum libusb_log_level level, const char * str) +{ +#if defined(USE_SYSTEM_LOGGING_FACILITY) +#if defined(OS_WINDOWS) + OutputDebugString(str); +#elif defined(OS_WINCE) + /* Windows CE only supports the Unicode version of OutputDebugString. */ + WCHAR wbuf[USBI_MAX_LOG_LEN]; + MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuf, sizeof(wbuf)); + OutputDebugStringW(wbuf); +#elif defined(__ANDROID__) + int priority = ANDROID_LOG_UNKNOWN; + switch (level) { + case LIBUSB_LOG_LEVEL_INFO: priority = ANDROID_LOG_INFO; break; + case LIBUSB_LOG_LEVEL_WARNING: priority = ANDROID_LOG_WARN; break; + case LIBUSB_LOG_LEVEL_ERROR: priority = ANDROID_LOG_ERROR; break; + case LIBUSB_LOG_LEVEL_DEBUG: priority = ANDROID_LOG_DEBUG; break; + } + __android_log_write(priority, "libusb", str); +#elif defined(HAVE_SYSLOG_FUNC) + int syslog_level = LOG_INFO; + switch (level) { + case LIBUSB_LOG_LEVEL_INFO: syslog_level = LOG_INFO; break; + case LIBUSB_LOG_LEVEL_WARNING: syslog_level = LOG_WARNING; break; + case LIBUSB_LOG_LEVEL_ERROR: syslog_level = LOG_ERR; break; + case LIBUSB_LOG_LEVEL_DEBUG: syslog_level = LOG_DEBUG; break; + } + syslog(syslog_level, "%s", str); +#else /* All of gcc, Clang, XCode seem to use #warning */ +#warning System logging is not supported on this platform. Logging to stderr will be used instead. + fputs(str, stderr); +#endif +#else + fputs(str, stderr); +#endif /* USE_SYSTEM_LOGGING_FACILITY */ + UNUSED(ctx); + UNUSED(level); +} + +void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, va_list args) +{ + const char *prefix = ""; + char buf[USBI_MAX_LOG_LEN]; + struct timespec now; + int global_debug, header_len, text_len; + static int has_debug_header_been_displayed = 0; + +#ifdef ENABLE_DEBUG_LOGGING + global_debug = 1; + UNUSED(ctx); +#else + int ctx_level = 0; + + USBI_GET_CONTEXT(ctx); + if (ctx) { + ctx_level = ctx->debug; + } else { + char *dbg = getenv("LIBUSB_DEBUG"); + if (dbg) + ctx_level = atoi(dbg); + } + global_debug = (ctx_level == LIBUSB_LOG_LEVEL_DEBUG); + if (!ctx_level) + return; + if (level == LIBUSB_LOG_LEVEL_WARNING && ctx_level < LIBUSB_LOG_LEVEL_WARNING) + return; + if (level == LIBUSB_LOG_LEVEL_INFO && ctx_level < LIBUSB_LOG_LEVEL_INFO) + return; + if (level == LIBUSB_LOG_LEVEL_DEBUG && ctx_level < LIBUSB_LOG_LEVEL_DEBUG) + return; +#endif + + usbi_backend->clock_gettime(USBI_CLOCK_REALTIME, &now); + if ((global_debug) && (!has_debug_header_been_displayed)) { + has_debug_header_been_displayed = 1; + usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] " USBI_LOG_LINE_END); + usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------" USBI_LOG_LINE_END); + } + if (now.tv_nsec < timestamp_origin.tv_nsec) { + now.tv_sec--; + now.tv_nsec += 1000000000L; + } + now.tv_sec -= timestamp_origin.tv_sec; + now.tv_nsec -= timestamp_origin.tv_nsec; + + switch (level) { + case LIBUSB_LOG_LEVEL_INFO: + prefix = "info"; + break; + case LIBUSB_LOG_LEVEL_WARNING: + prefix = "warning"; + break; + case LIBUSB_LOG_LEVEL_ERROR: + prefix = "error"; + break; + case LIBUSB_LOG_LEVEL_DEBUG: + prefix = "debug"; + break; + case LIBUSB_LOG_LEVEL_NONE: + return; + default: + prefix = "unknown"; + break; + } + + if (global_debug) { + header_len = snprintf(buf, sizeof(buf), + "[%2d.%06d] [%08x] libusb: %s [%s] ", + (int)now.tv_sec, (int)(now.tv_nsec / 1000L), usbi_get_tid(), prefix, function); + } else { + header_len = snprintf(buf, sizeof(buf), + "libusb: %s [%s] ", prefix, function); + } + + if (header_len < 0 || header_len >= (int)sizeof(buf)) { + /* Somehow snprintf failed to write to the buffer, + * remove the header so something useful is output. */ + header_len = 0; + } + /* Make sure buffer is NUL terminated */ + buf[header_len] = '\0'; + text_len = vsnprintf(buf + header_len, sizeof(buf) - header_len, + format, args); + if (text_len < 0 || text_len + header_len >= (int)sizeof(buf)) { + /* Truncated log output. On some platforms a -1 return value means + * that the output was truncated. */ + text_len = sizeof(buf) - header_len; + } + if (header_len + text_len + sizeof(USBI_LOG_LINE_END) >= sizeof(buf)) { + /* Need to truncate the text slightly to fit on the terminator. */ + text_len -= (header_len + text_len + sizeof(USBI_LOG_LINE_END)) - sizeof(buf); + } + strcpy(buf + header_len + text_len, USBI_LOG_LINE_END); + + usbi_log_str(ctx, level, buf); +} + +void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, ...) +{ + va_list args; + + va_start (args, format); + usbi_log_v(ctx, level, function, format, args); + va_end (args); +} + +/** \ingroup libusb_misc + * Returns a constant NULL-terminated string with the ASCII name of a libusb + * error or transfer status code. The caller must not free() the returned + * string. + * + * \param error_code The \ref libusb_error or libusb_transfer_status code to + * return the name of. + * \returns The error name, or the string **UNKNOWN** if the value of + * error_code is not a known error / status code. + */ +DEFAULT_VISIBILITY const char * LIBUSB_CALL libusb_error_name(int error_code) +{ + switch (error_code) { + case LIBUSB_ERROR_IO: + return "LIBUSB_ERROR_IO"; + case LIBUSB_ERROR_INVALID_PARAM: + return "LIBUSB_ERROR_INVALID_PARAM"; + case LIBUSB_ERROR_ACCESS: + return "LIBUSB_ERROR_ACCESS"; + case LIBUSB_ERROR_NO_DEVICE: + return "LIBUSB_ERROR_NO_DEVICE"; + case LIBUSB_ERROR_NOT_FOUND: + return "LIBUSB_ERROR_NOT_FOUND"; + case LIBUSB_ERROR_BUSY: + return "LIBUSB_ERROR_BUSY"; + case LIBUSB_ERROR_TIMEOUT: + return "LIBUSB_ERROR_TIMEOUT"; + case LIBUSB_ERROR_OVERFLOW: + return "LIBUSB_ERROR_OVERFLOW"; + case LIBUSB_ERROR_PIPE: + return "LIBUSB_ERROR_PIPE"; + case LIBUSB_ERROR_INTERRUPTED: + return "LIBUSB_ERROR_INTERRUPTED"; + case LIBUSB_ERROR_NO_MEM: + return "LIBUSB_ERROR_NO_MEM"; + case LIBUSB_ERROR_NOT_SUPPORTED: + return "LIBUSB_ERROR_NOT_SUPPORTED"; + case LIBUSB_ERROR_OTHER: + return "LIBUSB_ERROR_OTHER"; + + case LIBUSB_TRANSFER_ERROR: + return "LIBUSB_TRANSFER_ERROR"; + case LIBUSB_TRANSFER_TIMED_OUT: + return "LIBUSB_TRANSFER_TIMED_OUT"; + case LIBUSB_TRANSFER_CANCELLED: + return "LIBUSB_TRANSFER_CANCELLED"; + case LIBUSB_TRANSFER_STALL: + return "LIBUSB_TRANSFER_STALL"; + case LIBUSB_TRANSFER_NO_DEVICE: + return "LIBUSB_TRANSFER_NO_DEVICE"; + case LIBUSB_TRANSFER_OVERFLOW: + return "LIBUSB_TRANSFER_OVERFLOW"; + + case 0: + return "LIBUSB_SUCCESS / LIBUSB_TRANSFER_COMPLETED"; + default: + return "**UNKNOWN**"; + } +} + +/** \ingroup libusb_misc + * Returns a pointer to const struct libusb_version with the version + * (major, minor, micro, nano and rc) of the running library. + */ +DEFAULT_VISIBILITY +const struct libusb_version * LIBUSB_CALL libusb_get_version(void) +{ + return &libusb_version_internal; +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/descriptor.c b/go-api-for-hardware-wallet/usbhid/c/libusb/descriptor.c new file mode 100644 index 00000000..4c9435ff --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/descriptor.c @@ -0,0 +1,1191 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * USB descriptor handling functions for libusb + * Copyright © 2007 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +#define DESC_HEADER_LENGTH 2 +#define DEVICE_DESC_LENGTH 18 +#define CONFIG_DESC_LENGTH 9 +#define INTERFACE_DESC_LENGTH 9 +#define ENDPOINT_DESC_LENGTH 7 +#define ENDPOINT_AUDIO_DESC_LENGTH 9 + +/** @defgroup libusb_desc USB descriptors + * This page details how to examine the various standard USB descriptors + * for detected devices + */ + +/* set host_endian if the w values are already in host endian format, + * as opposed to bus endian. */ +int usbi_parse_descriptor(const unsigned char *source, const char *descriptor, + void *dest, int host_endian) +{ + const unsigned char *sp = source; + unsigned char *dp = dest; + uint16_t w; + const char *cp; + uint32_t d; + + for (cp = descriptor; *cp; cp++) { + switch (*cp) { + case 'b': /* 8-bit byte */ + *dp++ = *sp++; + break; + case 'w': /* 16-bit word, convert from little endian to CPU */ + dp += ((uintptr_t)dp & 1); /* Align to word boundary */ + + if (host_endian) { + memcpy(dp, sp, 2); + } else { + w = (sp[1] << 8) | sp[0]; + *((uint16_t *)dp) = w; + } + sp += 2; + dp += 2; + break; + case 'd': /* 32-bit word, convert from little endian to CPU */ + dp += ((uintptr_t)dp & 1); /* Align to word boundary */ + + if (host_endian) { + memcpy(dp, sp, 4); + } else { + d = (sp[3] << 24) | (sp[2] << 16) | + (sp[1] << 8) | sp[0]; + *((uint32_t *)dp) = d; + } + sp += 4; + dp += 4; + break; + case 'u': /* 16 byte UUID */ + memcpy(dp, sp, 16); + sp += 16; + dp += 16; + break; + } + } + + return (int) (sp - source); +} + +static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint) +{ + free((void *) endpoint->extra); +} + +static int parse_endpoint(struct libusb_context *ctx, + struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer, + int size, int host_endian) +{ + struct usb_descriptor_header header; + unsigned char *extra; + unsigned char *begin; + int parsed = 0; + int len; + + if (size < DESC_HEADER_LENGTH) { + usbi_err(ctx, "short endpoint descriptor read %d/%d", + size, DESC_HEADER_LENGTH); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + header.bDescriptorType, LIBUSB_DT_ENDPOINT); + return parsed; + } + if (header.bLength > size) { + usbi_warn(ctx, "short endpoint descriptor read %d/%d", + size, header.bLength); + return parsed; + } + if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH) + usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian); + else if (header.bLength >= ENDPOINT_DESC_LENGTH) + usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian); + else { + usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength); + return LIBUSB_ERROR_IO; + } + + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + + /* Skip over the rest of the Class Specific or Vendor Specific */ + /* descriptors */ + begin = buffer; + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, "invalid extra ep desc len (%d)", + header.bLength); + return LIBUSB_ERROR_IO; + } else if (header.bLength > size) { + usbi_warn(ctx, "short extra ep desc read %d/%d", + size, header.bLength); + return parsed; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + usbi_dbg("skipping descriptor %x", header.bDescriptorType); + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + } + + /* Copy any unknown descriptors into a storage area for drivers */ + /* to later parse */ + len = (int)(buffer - begin); + if (!len) { + endpoint->extra = NULL; + endpoint->extra_length = 0; + return parsed; + } + + extra = malloc(len); + endpoint->extra = extra; + if (!extra) { + endpoint->extra_length = 0; + return LIBUSB_ERROR_NO_MEM; + } + + memcpy(extra, begin, len); + endpoint->extra_length = len; + + return parsed; +} + +static void clear_interface(struct libusb_interface *usb_interface) +{ + int i; + int j; + + if (usb_interface->altsetting) { + for (i = 0; i < usb_interface->num_altsetting; i++) { + struct libusb_interface_descriptor *ifp = + (struct libusb_interface_descriptor *) + usb_interface->altsetting + i; + free((void *) ifp->extra); + if (ifp->endpoint) { + for (j = 0; j < ifp->bNumEndpoints; j++) + clear_endpoint((struct libusb_endpoint_descriptor *) + ifp->endpoint + j); + } + free((void *) ifp->endpoint); + } + } + free((void *) usb_interface->altsetting); + usb_interface->altsetting = NULL; +} + +static int parse_interface(libusb_context *ctx, + struct libusb_interface *usb_interface, unsigned char *buffer, int size, + int host_endian) +{ + int i; + int len; + int r; + int parsed = 0; + int interface_number = -1; + struct usb_descriptor_header header; + struct libusb_interface_descriptor *ifp; + unsigned char *begin; + + usb_interface->num_altsetting = 0; + + while (size >= INTERFACE_DESC_LENGTH) { + struct libusb_interface_descriptor *altsetting = + (struct libusb_interface_descriptor *) usb_interface->altsetting; + altsetting = usbi_reallocf(altsetting, + sizeof(struct libusb_interface_descriptor) * + (usb_interface->num_altsetting + 1)); + if (!altsetting) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + usb_interface->altsetting = altsetting; + + ifp = altsetting + usb_interface->num_altsetting; + usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0); + if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + ifp->bDescriptorType, LIBUSB_DT_INTERFACE); + return parsed; + } + if (ifp->bLength < INTERFACE_DESC_LENGTH) { + usbi_err(ctx, "invalid interface bLength (%d)", + ifp->bLength); + r = LIBUSB_ERROR_IO; + goto err; + } + if (ifp->bLength > size) { + usbi_warn(ctx, "short intf descriptor read %d/%d", + size, ifp->bLength); + return parsed; + } + if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { + usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints); + r = LIBUSB_ERROR_IO; + goto err; + } + + usb_interface->num_altsetting++; + ifp->extra = NULL; + ifp->extra_length = 0; + ifp->endpoint = NULL; + + if (interface_number == -1) + interface_number = ifp->bInterfaceNumber; + + /* Skip over the interface */ + buffer += ifp->bLength; + parsed += ifp->bLength; + size -= ifp->bLength; + + begin = buffer; + + /* Skip over any interface, class or vendor descriptors */ + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, + "invalid extra intf desc len (%d)", + header.bLength); + r = LIBUSB_ERROR_IO; + goto err; + } else if (header.bLength > size) { + usbi_warn(ctx, + "short extra intf desc read %d/%d", + size, header.bLength); + return parsed; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + buffer += header.bLength; + parsed += header.bLength; + size -= header.bLength; + } + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (len) { + ifp->extra = malloc(len); + if (!ifp->extra) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + memcpy((unsigned char *) ifp->extra, begin, len); + ifp->extra_length = len; + } + + if (ifp->bNumEndpoints > 0) { + struct libusb_endpoint_descriptor *endpoint; + endpoint = calloc(ifp->bNumEndpoints, sizeof(struct libusb_endpoint_descriptor)); + ifp->endpoint = endpoint; + if (!endpoint) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + + for (i = 0; i < ifp->bNumEndpoints; i++) { + r = parse_endpoint(ctx, endpoint + i, buffer, size, + host_endian); + if (r < 0) + goto err; + if (r == 0) { + ifp->bNumEndpoints = (uint8_t)i; + break;; + } + + buffer += r; + parsed += r; + size -= r; + } + } + + /* We check to see if it's an alternate to this one */ + ifp = (struct libusb_interface_descriptor *) buffer; + if (size < LIBUSB_DT_INTERFACE_SIZE || + ifp->bDescriptorType != LIBUSB_DT_INTERFACE || + ifp->bInterfaceNumber != interface_number) + return parsed; + } + + return parsed; +err: + clear_interface(usb_interface); + return r; +} + +static void clear_configuration(struct libusb_config_descriptor *config) +{ + int i; + if (config->interface) { + for (i = 0; i < config->bNumInterfaces; i++) + clear_interface((struct libusb_interface *) + config->interface + i); + } + free((void *) config->interface); + free((void *) config->extra); +} + +static int parse_configuration(struct libusb_context *ctx, + struct libusb_config_descriptor *config, unsigned char *buffer, + int size, int host_endian) +{ + int i; + int r; + struct usb_descriptor_header header; + struct libusb_interface *usb_interface; + + if (size < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "short config descriptor read %d/%d", + size, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian); + if (config->bDescriptorType != LIBUSB_DT_CONFIG) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + config->bDescriptorType, LIBUSB_DT_CONFIG); + return LIBUSB_ERROR_IO; + } + if (config->bLength < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "invalid config bLength (%d)", config->bLength); + return LIBUSB_ERROR_IO; + } + if (config->bLength > size) { + usbi_err(ctx, "short config descriptor read %d/%d", + size, config->bLength); + return LIBUSB_ERROR_IO; + } + if (config->bNumInterfaces > USB_MAXINTERFACES) { + usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces); + return LIBUSB_ERROR_IO; + } + + usb_interface = calloc(config->bNumInterfaces, sizeof(struct libusb_interface)); + config->interface = usb_interface; + if (!usb_interface) + return LIBUSB_ERROR_NO_MEM; + + buffer += config->bLength; + size -= config->bLength; + + config->extra = NULL; + config->extra_length = 0; + + for (i = 0; i < config->bNumInterfaces; i++) { + int len; + unsigned char *begin; + + /* Skip over the rest of the Class Specific or Vendor */ + /* Specific descriptors */ + begin = buffer; + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, + "invalid extra config desc len (%d)", + header.bLength); + r = LIBUSB_ERROR_IO; + goto err; + } else if (header.bLength > size) { + usbi_warn(ctx, + "short extra config desc read %d/%d", + size, header.bLength); + config->bNumInterfaces = (uint8_t)i; + return size; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + usbi_dbg("skipping descriptor 0x%x", header.bDescriptorType); + buffer += header.bLength; + size -= header.bLength; + } + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (len) { + /* FIXME: We should realloc and append here */ + if (!config->extra_length) { + config->extra = malloc(len); + if (!config->extra) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + + memcpy((unsigned char *) config->extra, begin, len); + config->extra_length = len; + } + } + + r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian); + if (r < 0) + goto err; + if (r == 0) { + config->bNumInterfaces = (uint8_t)i; + break; + } + + buffer += r; + size -= r; + } + + return size; + +err: + clear_configuration(config); + return r; +} + +static int raw_desc_to_config(struct libusb_context *ctx, + unsigned char *buf, int size, int host_endian, + struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor *_config = malloc(sizeof(*_config)); + int r; + + if (!_config) + return LIBUSB_ERROR_NO_MEM; + + r = parse_configuration(ctx, _config, buf, size, host_endian); + if (r < 0) { + usbi_err(ctx, "parse_configuration failed with error %d", r); + free(_config); + return r; + } else if (r > 0) { + usbi_warn(ctx, "still %d bytes of descriptor data left", r); + } + + *config = _config; + return LIBUSB_SUCCESS; +} + +int usbi_device_cache_descriptor(libusb_device *dev) +{ + int r, host_endian = 0; + + r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor, + &host_endian); + if (r < 0) + return r; + + if (!host_endian) { + dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB); + dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor); + dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct); + dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice); + } + + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Get the USB device descriptor for a given device. + * + * This is a non-blocking function; the device descriptor is cached in memory. + * + * Note since libusb-1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, this + * function always succeeds. + * + * \param dev the device + * \param desc output location for the descriptor data + * \returns 0 on success or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc) +{ + usbi_dbg(""); + memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor, + sizeof (dev->device_descriptor)); + return 0; +} + +/** \ingroup libusb_desc + * Get the USB configuration descriptor for the currently active configuration. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_config_descriptor + */ +int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor _config; + unsigned char tmp[LIBUSB_DT_CONFIG_SIZE]; + unsigned char *buf = NULL; + int host_endian = 0; + int r; + + r = usbi_backend->get_active_config_descriptor(dev, tmp, + LIBUSB_DT_CONFIG_SIZE, &host_endian); + if (r < 0) + return r; + if (r < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(dev->ctx, "short config descriptor read %d/%d", + r, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(tmp, "bbw", &_config, host_endian); + buf = malloc(_config.wTotalLength); + if (!buf) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_backend->get_active_config_descriptor(dev, buf, + _config.wTotalLength, &host_endian); + if (r >= 0) + r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + + free(buf); + return r; +} + +/** \ingroup libusb_desc + * Get a USB configuration descriptor based on its index. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param config_index the index of the configuration you wish to retrieve + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor_by_value() + */ +int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor _config; + unsigned char tmp[LIBUSB_DT_CONFIG_SIZE]; + unsigned char *buf = NULL; + int host_endian = 0; + int r; + + usbi_dbg("index %d", config_index); + if (config_index >= dev->num_configurations) + return LIBUSB_ERROR_NOT_FOUND; + + r = usbi_backend->get_config_descriptor(dev, config_index, tmp, + LIBUSB_DT_CONFIG_SIZE, &host_endian); + if (r < 0) + return r; + if (r < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(dev->ctx, "short config descriptor read %d/%d", + r, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(tmp, "bbw", &_config, host_endian); + buf = malloc(_config.wTotalLength); + if (!buf) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_backend->get_config_descriptor(dev, config_index, buf, + _config.wTotalLength, &host_endian); + if (r >= 0) + r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + + free(buf); + return r; +} + +/* iterate through all configurations, returning the index of the configuration + * matching a specific bConfigurationValue in the idx output parameter, or -1 + * if the config was not found. + * returns 0 on success or a LIBUSB_ERROR code + */ +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx) +{ + uint8_t i; + + usbi_dbg("value %d", bConfigurationValue); + for (i = 0; i < dev->num_configurations; i++) { + unsigned char tmp[6]; + int host_endian; + int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp), + &host_endian); + if (r < 0) { + *idx = -1; + return r; + } + if (tmp[5] == bConfigurationValue) { + *idx = i; + return 0; + } + } + + *idx = -1; + return 0; +} + +/** \ingroup libusb_desc + * Get a USB configuration descriptor with a specific bConfigurationValue. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param bConfigurationValue the bConfigurationValue of the configuration you + * wish to retrieve + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor() + */ +int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config) +{ + int r, idx, host_endian; + unsigned char *buf = NULL; + + if (usbi_backend->get_config_descriptor_by_value) { + r = usbi_backend->get_config_descriptor_by_value(dev, + bConfigurationValue, &buf, &host_endian); + if (r < 0) + return r; + return raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + } + + r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx); + if (r < 0) + return r; + else if (idx == -1) + return LIBUSB_ERROR_NOT_FOUND; + else + return libusb_get_config_descriptor(dev, (uint8_t) idx, config); +} + +/** \ingroup libusb_desc + * Free a configuration descriptor obtained from + * libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). + * It is safe to call this function with a NULL config parameter, in which + * case the function simply returns. + * + * \param config the configuration descriptor to free + */ +void API_EXPORTED libusb_free_config_descriptor( + struct libusb_config_descriptor *config) +{ + if (!config) + return; + + clear_configuration(config); + free(config); +} + +/** \ingroup libusb_desc + * Get an endpoints superspeed endpoint companion descriptor (if any) + * + * \param ctx the context to operate on, or NULL for the default context + * \param endpoint endpoint descriptor from which to get the superspeed + * endpoint companion descriptor + * \param ep_comp output location for the superspeed endpoint companion + * descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_ss_endpoint_companion_descriptor() after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor( + struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp) +{ + struct usb_descriptor_header header; + int size = endpoint->extra_length; + const unsigned char *buffer = endpoint->extra; + + *ep_comp = NULL; + + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < 2 || header.bLength > size) { + usbi_err(ctx, "invalid descriptor length %d", + header.bLength); + return LIBUSB_ERROR_IO; + } + if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) { + buffer += header.bLength; + size -= header.bLength; + continue; + } + if (header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) { + usbi_err(ctx, "invalid ss-ep-comp-desc length %d", + header.bLength); + return LIBUSB_ERROR_IO; + } + *ep_comp = malloc(sizeof(**ep_comp)); + if (*ep_comp == NULL) + return LIBUSB_ERROR_NO_MEM; + usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0); + return LIBUSB_SUCCESS; + } + return LIBUSB_ERROR_NOT_FOUND; +} + +/** \ingroup libusb_desc + * Free a superspeed endpoint companion descriptor obtained from + * libusb_get_ss_endpoint_companion_descriptor(). + * It is safe to call this function with a NULL ep_comp parameter, in which + * case the function simply returns. + * + * \param ep_comp the superspeed endpoint companion descriptor to free + */ +void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor( + struct libusb_ss_endpoint_companion_descriptor *ep_comp) +{ + free(ep_comp); +} + +static int parse_bos(struct libusb_context *ctx, + struct libusb_bos_descriptor **bos, + unsigned char *buffer, int size, int host_endian) +{ + struct libusb_bos_descriptor bos_header, *_bos; + struct libusb_bos_dev_capability_descriptor dev_cap; + int i; + + if (size < LIBUSB_DT_BOS_SIZE) { + usbi_err(ctx, "short bos descriptor read %d/%d", + size, LIBUSB_DT_BOS_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian); + if (bos_header.bDescriptorType != LIBUSB_DT_BOS) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + bos_header.bDescriptorType, LIBUSB_DT_BOS); + return LIBUSB_ERROR_IO; + } + if (bos_header.bLength < LIBUSB_DT_BOS_SIZE) { + usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength); + return LIBUSB_ERROR_IO; + } + if (bos_header.bLength > size) { + usbi_err(ctx, "short bos descriptor read %d/%d", + size, bos_header.bLength); + return LIBUSB_ERROR_IO; + } + + _bos = calloc (1, + sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *)); + if (!_bos) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian); + buffer += bos_header.bLength; + size -= bos_header.bLength; + + /* Get the device capability descriptors */ + for (i = 0; i < bos_header.bNumDeviceCaps; i++) { + if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) { + usbi_warn(ctx, "short dev-cap descriptor read %d/%d", + size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE); + break; + } + usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian); + if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) { + usbi_warn(ctx, "unexpected descriptor %x (expected %x)", + dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY); + break; + } + if (dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) { + usbi_err(ctx, "invalid dev-cap bLength (%d)", + dev_cap.bLength); + libusb_free_bos_descriptor(_bos); + return LIBUSB_ERROR_IO; + } + if (dev_cap.bLength > size) { + usbi_warn(ctx, "short dev-cap descriptor read %d/%d", + size, dev_cap.bLength); + break; + } + + _bos->dev_capability[i] = malloc(dev_cap.bLength); + if (!_bos->dev_capability[i]) { + libusb_free_bos_descriptor(_bos); + return LIBUSB_ERROR_NO_MEM; + } + memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength); + buffer += dev_cap.bLength; + size -= dev_cap.bLength; + } + _bos->bNumDeviceCaps = (uint8_t)i; + *bos = _bos; + + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Get a Binary Object Store (BOS) descriptor + * This is a BLOCKING function, which will send requests to the device. + * + * \param dev_handle the handle of an open libusb device + * \param bos output location for the BOS descriptor. Only valid if 0 was returned. + * Must be freed with \ref libusb_free_bos_descriptor() after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor + * \returns another LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *dev_handle, + struct libusb_bos_descriptor **bos) +{ + struct libusb_bos_descriptor _bos; + uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0}; + unsigned char *bos_data = NULL; + const int host_endian = 0; + int r; + + /* Read the BOS. This generates 2 requests on the bus, + * one for the header, and one for the full BOS */ + r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_header, + LIBUSB_DT_BOS_SIZE); + if (r < 0) { + if (r != LIBUSB_ERROR_PIPE) + usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r); + return r; + } + if (r < LIBUSB_DT_BOS_SIZE) { + usbi_err(HANDLE_CTX(dev_handle), "short BOS read %d/%d", + r, LIBUSB_DT_BOS_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian); + usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities", + _bos.wTotalLength, _bos.bNumDeviceCaps); + bos_data = calloc(_bos.wTotalLength, 1); + if (bos_data == NULL) + return LIBUSB_ERROR_NO_MEM; + + r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data, + _bos.wTotalLength); + if (r >= 0) + r = parse_bos(HANDLE_CTX(dev_handle), bos, bos_data, r, host_endian); + else + usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r); + + free(bos_data); + return r; +} + +/** \ingroup libusb_desc + * Free a BOS descriptor obtained from libusb_get_bos_descriptor(). + * It is safe to call this function with a NULL bos parameter, in which + * case the function simply returns. + * + * \param bos the BOS descriptor to free + */ +void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos) +{ + int i; + + if (!bos) + return; + + for (i = 0; i < bos->bNumDeviceCaps; i++) + free(bos->dev_capability[i]); + free(bos); +} + +/** \ingroup libusb_desc + * Get an USB 2.0 Extension descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + * LIBUSB_BT_USB_2_0_EXTENSION + * \param usb_2_0_extension output location for the USB 2.0 Extension + * descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_usb_2_0_extension_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_usb_2_0_extension_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension) +{ + struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_USB_2_0_EXTENSION); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE); + return LIBUSB_ERROR_IO; + } + + _usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension)); + if (!_usb_2_0_extension) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd", + _usb_2_0_extension, host_endian); + + *usb_2_0_extension = _usb_2_0_extension; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Free a USB 2.0 Extension descriptor obtained from + * libusb_get_usb_2_0_extension_descriptor(). + * It is safe to call this function with a NULL usb_2_0_extension parameter, + * in which case the function simply returns. + * + * \param usb_2_0_extension the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension) +{ + free(usb_2_0_extension); +} + +/** \ingroup libusb_desc + * Get a SuperSpeed USB Device Capability descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * \param ss_usb_device_cap output location for the SuperSpeed USB Device + * Capability descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_ss_usb_device_capability_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap) +{ + struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE); + return LIBUSB_ERROR_IO; + } + + _ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap)); + if (!_ss_usb_device_cap) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw", + _ss_usb_device_cap, host_endian); + + *ss_usb_device_cap = _ss_usb_device_cap; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Free a SuperSpeed USB Device Capability descriptor obtained from + * libusb_get_ss_usb_device_capability_descriptor(). + * It is safe to call this function with a NULL ss_usb_device_cap + * parameter, in which case the function simply returns. + * + * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap) +{ + free(ss_usb_device_cap); +} + +/** \ingroup libusb_desc + * Get a Container ID descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + * LIBUSB_BT_CONTAINER_ID + * \param container_id output location for the Container ID descriptor. + * Only valid if 0 was returned. Must be freed with + * libusb_free_container_id_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id) +{ + struct libusb_container_id_descriptor *_container_id; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_CONTAINER_ID); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE); + return LIBUSB_ERROR_IO; + } + + _container_id = malloc(sizeof(*_container_id)); + if (!_container_id) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu", + _container_id, host_endian); + + *container_id = _container_id; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Free a Container ID descriptor obtained from + * libusb_get_container_id_descriptor(). + * It is safe to call this function with a NULL container_id parameter, + * in which case the function simply returns. + * + * \param container_id the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id) +{ + free(container_id); +} + +/** \ingroup libusb_desc + * Retrieve a string descriptor in C style ASCII. + * + * Wrapper around libusb_get_string_descriptor(). Uses the first language + * supported by the device. + * + * \param dev_handle a device handle + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for ASCII string descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle, + uint8_t desc_index, unsigned char *data, int length) +{ + unsigned char tbuf[255]; /* Some devices choke on size > 255 */ + int r, si, di; + uint16_t langid; + + /* Asking for the zero'th index is special - it returns a string + * descriptor that contains all the language IDs supported by the + * device. Typically there aren't many - often only one. Language + * IDs are 16 bit numbers, and they start at the third byte in the + * descriptor. There's also no point in trying to read descriptor 0 + * with this function. See USB 2.0 specification section 9.6.7 for + * more information. + */ + + if (desc_index == 0) + return LIBUSB_ERROR_INVALID_PARAM; + + r = libusb_get_string_descriptor(dev_handle, 0, 0, tbuf, sizeof(tbuf)); + if (r < 0) + return r; + + if (r < 4) + return LIBUSB_ERROR_IO; + + langid = tbuf[2] | (tbuf[3] << 8); + + r = libusb_get_string_descriptor(dev_handle, desc_index, langid, tbuf, + sizeof(tbuf)); + if (r < 0) + return r; + + if (tbuf[1] != LIBUSB_DT_STRING) + return LIBUSB_ERROR_IO; + + if (tbuf[0] > r) + return LIBUSB_ERROR_IO; + + for (di = 0, si = 2; si < tbuf[0]; si += 2) { + if (di >= (length - 1)) + break; + + if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */ + data[di++] = '?'; + else + data[di++] = tbuf[si]; + } + + data[di] = 0; + return di; +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.c b/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.c new file mode 100644 index 00000000..bbfd6e79 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.c @@ -0,0 +1,350 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Hotplug functions for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2012-2013 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + +#include "libusbi.h" +#include "hotplug.h" + +/** + * @defgroup libusb_hotplug Device hotplug event notification + * This page details how to use the libusb hotplug interface, where available. + * + * Be mindful that not all platforms currently implement hotplug notification and + * that you should first call on \ref libusb_has_capability() with parameter + * \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available. + * + * \page libusb_hotplug Device hotplug event notification + * + * \section hotplug_intro Introduction + * + * Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support + * for hotplug events on some platforms (you should test if your platform + * supports hotplug notification by calling \ref libusb_has_capability() with + * parameter \ref LIBUSB_CAP_HAS_HOTPLUG). + * + * This interface allows you to request notification for the arrival and departure + * of matching USB devices. + * + * To receive hotplug notification you register a callback by calling + * \ref libusb_hotplug_register_callback(). This function will optionally return + * a callback handle that can be passed to \ref libusb_hotplug_deregister_callback(). + * + * A callback function must return an int (0 or 1) indicating whether the callback is + * expecting additional events. Returning 0 will rearm the callback and 1 will cause + * the callback to be deregistered. Note that when callbacks are called from + * libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE + * flag, the callback return value is ignored, iow you cannot cause a callback + * to be deregistered by returning 1 when it is called from + * libusb_hotplug_register_callback(). + * + * Callbacks for a particular context are automatically deregistered by libusb_exit(). + * + * As of 1.0.16 there are two supported hotplug events: + * - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: A device has arrived and is ready to use + * - LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: A device has left and is no longer available + * + * A hotplug event can listen for either or both of these events. + * + * Note: If you receive notification that a device has left and you have any + * a libusb_device_handles for the device it is up to you to call libusb_close() + * on each device handle to free up any remaining resources associated with the device. + * Once a device has left any libusb_device_handle associated with the device + * are invalid and will remain so even if the device comes back. + * + * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered + * safe to call any libusb function that takes a libusb_device. It also safe to + * open a device and submit asynchronous transfers. However, most other functions + * that take a libusb_device_handle are not safe to call. Examples of such + * functions are any of the \ref libusb_syncio "synchronous API" functions or the blocking + * functions that retrieve various \ref libusb_desc "USB descriptors". These functions must + * be used outside of the context of the hotplug callback. + * + * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function + * is libusb_get_device_descriptor(). + * + * The following code provides an example of the usage of the hotplug interface: +\code +#include +#include +#include +#include + +static int count = 0; + +int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event, void *user_data) { + static libusb_device_handle *dev_handle = NULL; + struct libusb_device_descriptor desc; + int rc; + + (void)libusb_get_device_descriptor(dev, &desc); + + if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) { + rc = libusb_open(dev, &dev_handle); + if (LIBUSB_SUCCESS != rc) { + printf("Could not open USB device\n"); + } + } else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) { + if (dev_handle) { + libusb_close(dev_handle); + dev_handle = NULL; + } + } else { + printf("Unhandled event %d\n", event); + } + count++; + + return 0; +} + +int main (void) { + libusb_hotplug_callback_handle callback_handle; + int rc; + + libusb_init(NULL); + + rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005, + LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, + &callback_handle); + if (LIBUSB_SUCCESS != rc) { + printf("Error creating a hotplug callback\n"); + libusb_exit(NULL); + return EXIT_FAILURE; + } + + while (count < 2) { + libusb_handle_events_completed(NULL, NULL); + nanosleep(&(struct timespec){0, 10000000UL}, NULL); + } + + libusb_hotplug_deregister_callback(NULL, callback_handle); + libusb_exit(NULL); + + return 0; +} +\endcode + */ + +static int usbi_hotplug_match_cb (struct libusb_context *ctx, + struct libusb_device *dev, libusb_hotplug_event event, + struct libusb_hotplug_callback *hotplug_cb) +{ + /* Handle lazy deregistration of callback */ + if (hotplug_cb->needs_free) { + /* Free callback */ + return 1; + } + + if (!(hotplug_cb->events & event)) { + return 0; + } + + if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->vendor_id && + hotplug_cb->vendor_id != dev->device_descriptor.idVendor) { + return 0; + } + + if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->product_id && + hotplug_cb->product_id != dev->device_descriptor.idProduct) { + return 0; + } + + if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->dev_class && + hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) { + return 0; + } + + return hotplug_cb->cb (ctx, dev, event, hotplug_cb->user_data); +} + +void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event) +{ + struct libusb_hotplug_callback *hotplug_cb, *next; + int ret; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + ret = usbi_hotplug_match_cb (ctx, dev, event, hotplug_cb); + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + if (ret) { + list_del(&hotplug_cb->list); + free(hotplug_cb); + } + } + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + /* the backend is expected to call the callback for each active transfer */ +} + +void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event) +{ + int pending_events; + libusb_hotplug_message *message = calloc(1, sizeof(*message)); + + if (!message) { + usbi_err(ctx, "error allocating hotplug message"); + return; + } + + message->event = event; + message->device = dev; + + /* Take the event data lock and add this message to the list. + * Only signal an event if there are no prior pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + list_add_tail(&message->list, &ctx->hotplug_msgs); + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); +} + +int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx, + libusb_hotplug_event events, libusb_hotplug_flag flags, + int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data, + libusb_hotplug_callback_handle *callback_handle) +{ + libusb_hotplug_callback *new_callback; + static int handle_id = 1; + + /* check for hotplug support */ + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + /* check for sane values */ + if ((LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) || + (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) || + (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) || + !cb_fn) { + return LIBUSB_ERROR_INVALID_PARAM; + } + + USBI_GET_CONTEXT(ctx); + + new_callback = (libusb_hotplug_callback *)calloc(1, sizeof (*new_callback)); + if (!new_callback) { + return LIBUSB_ERROR_NO_MEM; + } + + new_callback->ctx = ctx; + new_callback->vendor_id = vendor_id; + new_callback->product_id = product_id; + new_callback->dev_class = dev_class; + new_callback->flags = flags; + new_callback->events = events; + new_callback->cb = cb_fn; + new_callback->user_data = user_data; + new_callback->needs_free = 0; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + /* protect the handle by the context hotplug lock. it doesn't matter if the same handle + * is used for different contexts only that the handle is unique for this context */ + new_callback->handle = handle_id++; + + list_add(&new_callback->list, &ctx->hotplug_cbs); + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + + if (flags & LIBUSB_HOTPLUG_ENUMERATE) { + int i, len; + struct libusb_device **devs; + + len = (int) libusb_get_device_list(ctx, &devs); + if (len < 0) { + libusb_hotplug_deregister_callback(ctx, + new_callback->handle); + return len; + } + + for (i = 0; i < len; i++) { + usbi_hotplug_match_cb(ctx, devs[i], + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, + new_callback); + } + + libusb_free_device_list(devs, 1); + } + + + if (callback_handle) + *callback_handle = new_callback->handle; + + return LIBUSB_SUCCESS; +} + +void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx, + libusb_hotplug_callback_handle callback_handle) +{ + struct libusb_hotplug_callback *hotplug_cb; + + /* check for hotplug support */ + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + return; + } + + USBI_GET_CONTEXT(ctx); + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, + struct libusb_hotplug_callback) { + if (callback_handle == hotplug_cb->handle) { + /* Mark this callback for deregistration */ + hotplug_cb->needs_free = 1; + } + } + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + usbi_hotplug_notification(ctx, NULL, 0); +} + +void usbi_hotplug_deregister_all(struct libusb_context *ctx) { + struct libusb_hotplug_callback *hotplug_cb, *next; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, + struct libusb_hotplug_callback) { + list_del(&hotplug_cb->list); + free(hotplug_cb); + } + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.h b/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.h new file mode 100644 index 00000000..2bec81b0 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.h @@ -0,0 +1,90 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Hotplug support for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2012-2013 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(USBI_HOTPLUG_H) +#define USBI_HOTPLUG_H + +#ifndef LIBUSBI_H +#include "libusbi.h" +#endif + +/** \ingroup hotplug + * The hotplug callback structure. The user populates this structure with + * libusb_hotplug_prepare_callback() and then calls libusb_hotplug_register_callback() + * to receive notification of hotplug events. + */ +struct libusb_hotplug_callback { + /** Context this callback is associated with */ + struct libusb_context *ctx; + + /** Vendor ID to match or LIBUSB_HOTPLUG_MATCH_ANY */ + int vendor_id; + + /** Product ID to match or LIBUSB_HOTPLUG_MATCH_ANY */ + int product_id; + + /** Device class to match or LIBUSB_HOTPLUG_MATCH_ANY */ + int dev_class; + + /** Hotplug callback flags */ + libusb_hotplug_flag flags; + + /** Event(s) that will trigger this callback */ + libusb_hotplug_event events; + + /** Callback function to invoke for matching event/device */ + libusb_hotplug_callback_fn cb; + + /** Handle for this callback (used to match on deregister) */ + libusb_hotplug_callback_handle handle; + + /** User data that will be passed to the callback function */ + void *user_data; + + /** Callback is marked for deletion */ + int needs_free; + + /** List this callback is registered in (ctx->hotplug_cbs) */ + struct list_head list; +}; + +typedef struct libusb_hotplug_callback libusb_hotplug_callback; + +struct libusb_hotplug_message { + /** The hotplug event that occurred */ + libusb_hotplug_event event; + + /** The device for which this hotplug event occurred */ + struct libusb_device *device; + + /** List this message is contained in (ctx->hotplug_msgs) */ + struct list_head list; +}; + +typedef struct libusb_hotplug_message libusb_hotplug_message; + +void usbi_hotplug_deregister_all(struct libusb_context *ctx); +void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event); +void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event); + +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/io.c b/go-api-for-hardware-wallet/usbhid/c/libusb/io.c new file mode 100644 index 00000000..eb1eabf1 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/io.c @@ -0,0 +1,2819 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * I/O functions for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef USBI_TIMERFD_AVAILABLE +#include +#endif + +#include "libusbi.h" +#include "hotplug.h" + +/** + * \page libusb_io Synchronous and asynchronous device I/O + * + * \section io_intro Introduction + * + * If you're using libusb in your application, you're probably wanting to + * perform I/O with devices - you want to perform USB data transfers. + * + * libusb offers two separate interfaces for device I/O. This page aims to + * introduce the two in order to help you decide which one is more suitable + * for your application. You can also choose to use both interfaces in your + * application by considering each transfer on a case-by-case basis. + * + * Once you have read through the following discussion, you should consult the + * detailed API documentation pages for the details: + * - \ref libusb_syncio + * - \ref libusb_asyncio + * + * \section theory Transfers at a logical level + * + * At a logical level, USB transfers typically happen in two parts. For + * example, when reading data from a endpoint: + * -# A request for data is sent to the device + * -# Some time later, the incoming data is received by the host + * + * or when writing data to an endpoint: + * + * -# The data is sent to the device + * -# Some time later, the host receives acknowledgement from the device that + * the data has been transferred. + * + * There may be an indefinite delay between the two steps. Consider a + * fictional USB input device with a button that the user can press. In order + * to determine when the button is pressed, you would likely submit a request + * to read data on a bulk or interrupt endpoint and wait for data to arrive. + * Data will arrive when the button is pressed by the user, which is + * potentially hours later. + * + * libusb offers both a synchronous and an asynchronous interface to performing + * USB transfers. The main difference is that the synchronous interface + * combines both steps indicated above into a single function call, whereas + * the asynchronous interface separates them. + * + * \section sync The synchronous interface + * + * The synchronous I/O interface allows you to perform a USB transfer with + * a single function call. When the function call returns, the transfer has + * completed and you can parse the results. + * + * If you have used the libusb-0.1 before, this I/O style will seem familar to + * you. libusb-0.1 only offered a synchronous interface. + * + * In our input device example, to read button presses you might write code + * in the following style: +\code +unsigned char data[4]; +int actual_length; +int r = libusb_bulk_transfer(dev_handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0); +if (r == 0 && actual_length == sizeof(data)) { + // results of the transaction can now be found in the data buffer + // parse them here and report button press +} else { + error(); +} +\endcode + * + * The main advantage of this model is simplicity: you did everything with + * a single simple function call. + * + * However, this interface has its limitations. Your application will sleep + * inside libusb_bulk_transfer() until the transaction has completed. If it + * takes the user 3 hours to press the button, your application will be + * sleeping for that long. Execution will be tied up inside the library - + * the entire thread will be useless for that duration. + * + * Another issue is that by tieing up the thread with that single transaction + * there is no possibility of performing I/O with multiple endpoints and/or + * multiple devices simultaneously, unless you resort to creating one thread + * per transaction. + * + * Additionally, there is no opportunity to cancel the transfer after the + * request has been submitted. + * + * For details on how to use the synchronous API, see the + * \ref libusb_syncio "synchronous I/O API documentation" pages. + * + * \section async The asynchronous interface + * + * Asynchronous I/O is the most significant new feature in libusb-1.0. + * Although it is a more complex interface, it solves all the issues detailed + * above. + * + * Instead of providing which functions that block until the I/O has complete, + * libusb's asynchronous interface presents non-blocking functions which + * begin a transfer and then return immediately. Your application passes a + * callback function pointer to this non-blocking function, which libusb will + * call with the results of the transaction when it has completed. + * + * Transfers which have been submitted through the non-blocking functions + * can be cancelled with a separate function call. + * + * The non-blocking nature of this interface allows you to be simultaneously + * performing I/O to multiple endpoints on multiple devices, without having + * to use threads. + * + * This added flexibility does come with some complications though: + * - In the interest of being a lightweight library, libusb does not create + * threads and can only operate when your application is calling into it. Your + * application must call into libusb from it's main loop when events are ready + * to be handled, or you must use some other scheme to allow libusb to + * undertake whatever work needs to be done. + * - libusb also needs to be called into at certain fixed points in time in + * order to accurately handle transfer timeouts. + * - Memory handling becomes more complex. You cannot use stack memory unless + * the function with that stack is guaranteed not to return until the transfer + * callback has finished executing. + * - You generally lose some linearity from your code flow because submitting + * the transfer request is done in a separate function from where the transfer + * results are handled. This becomes particularly obvious when you want to + * submit a second transfer based on the results of an earlier transfer. + * + * Internally, libusb's synchronous interface is expressed in terms of function + * calls to the asynchronous interface. + * + * For details on how to use the asynchronous API, see the + * \ref libusb_asyncio "asynchronous I/O API" documentation pages. + */ + + +/** + * \page libusb_packetoverflow Packets and overflows + * + * \section packets Packet abstraction + * + * The USB specifications describe how data is transmitted in packets, with + * constraints on packet size defined by endpoint descriptors. The host must + * not send data payloads larger than the endpoint's maximum packet size. + * + * libusb and the underlying OS abstract out the packet concept, allowing you + * to request transfers of any size. Internally, the request will be divided + * up into correctly-sized packets. You do not have to be concerned with + * packet sizes, but there is one exception when considering overflows. + * + * \section overflow Bulk/interrupt transfer overflows + * + * When requesting data on a bulk endpoint, libusb requires you to supply a + * buffer and the maximum number of bytes of data that libusb can put in that + * buffer. However, the size of the buffer is not communicated to the device - + * the device is just asked to send any amount of data. + * + * There is no problem if the device sends an amount of data that is less than + * or equal to the buffer size. libusb reports this condition to you through + * the \ref libusb_transfer::actual_length "libusb_transfer.actual_length" + * field. + * + * Problems may occur if the device attempts to send more data than can fit in + * the buffer. libusb reports LIBUSB_TRANSFER_OVERFLOW for this condition but + * other behaviour is largely undefined: actual_length may or may not be + * accurate, the chunk of data that can fit in the buffer (before overflow) + * may or may not have been transferred. + * + * Overflows are nasty, but can be avoided. Even though you were told to + * ignore packets above, think about the lower level details: each transfer is + * split into packets (typically small, with a maximum size of 512 bytes). + * Overflows can only happen if the final packet in an incoming data transfer + * is smaller than the actual packet that the device wants to transfer. + * Therefore, you will never see an overflow if your transfer buffer size is a + * multiple of the endpoint's packet size: the final packet will either + * fill up completely or will be only partially filled. + */ + +/** + * @defgroup libusb_asyncio Asynchronous device I/O + * + * This page details libusb's asynchronous (non-blocking) API for USB device + * I/O. This interface is very powerful but is also quite complex - you will + * need to read this page carefully to understand the necessary considerations + * and issues surrounding use of this interface. Simplistic applications + * may wish to consider the \ref libusb_syncio "synchronous I/O API" instead. + * + * The asynchronous interface is built around the idea of separating transfer + * submission and handling of transfer completion (the synchronous model + * combines both of these into one). There may be a long delay between + * submission and completion, however the asynchronous submission function + * is non-blocking so will return control to your application during that + * potentially long delay. + * + * \section asyncabstraction Transfer abstraction + * + * For the asynchronous I/O, libusb implements the concept of a generic + * transfer entity for all types of I/O (control, bulk, interrupt, + * isochronous). The generic transfer object must be treated slightly + * differently depending on which type of I/O you are performing with it. + * + * This is represented by the public libusb_transfer structure type. + * + * \section asynctrf Asynchronous transfers + * + * We can view asynchronous I/O as a 5 step process: + * -# Allocation: allocate a libusb_transfer + * -# Filling: populate the libusb_transfer instance with information + * about the transfer you wish to perform + * -# Submission: ask libusb to submit the transfer + * -# Completion handling: examine transfer results in the + * libusb_transfer structure + * -# Deallocation: clean up resources + * + * + * \subsection asyncalloc Allocation + * + * This step involves allocating memory for a USB transfer. This is the + * generic transfer object mentioned above. At this stage, the transfer + * is "blank" with no details about what type of I/O it will be used for. + * + * Allocation is done with the libusb_alloc_transfer() function. You must use + * this function rather than allocating your own transfers. + * + * \subsection asyncfill Filling + * + * This step is where you take a previously allocated transfer and fill it + * with information to determine the message type and direction, data buffer, + * callback function, etc. + * + * You can either fill the required fields yourself or you can use the + * helper functions: libusb_fill_control_transfer(), libusb_fill_bulk_transfer() + * and libusb_fill_interrupt_transfer(). + * + * \subsection asyncsubmit Submission + * + * When you have allocated a transfer and filled it, you can submit it using + * libusb_submit_transfer(). This function returns immediately but can be + * regarded as firing off the I/O request in the background. + * + * \subsection asynccomplete Completion handling + * + * After a transfer has been submitted, one of four things can happen to it: + * + * - The transfer completes (i.e. some data was transferred) + * - The transfer has a timeout and the timeout expires before all data is + * transferred + * - The transfer fails due to an error + * - The transfer is cancelled + * + * Each of these will cause the user-specified transfer callback function to + * be invoked. It is up to the callback function to determine which of the + * above actually happened and to act accordingly. + * + * The user-specified callback is passed a pointer to the libusb_transfer + * structure which was used to setup and submit the transfer. At completion + * time, libusb has populated this structure with results of the transfer: + * success or failure reason, number of bytes of data transferred, etc. See + * the libusb_transfer structure documentation for more information. + * + * Important Note: The user-specified callback is called from an event + * handling context. It is therefore important that no calls are made into + * libusb that will attempt to perform any event handling. Examples of such + * functions are any listed in the \ref libusb_syncio "synchronous API" and any of + * the blocking functions that retrieve \ref libusb_desc "USB descriptors". + * + * \subsection Deallocation + * + * When a transfer has completed (i.e. the callback function has been invoked), + * you are advised to free the transfer (unless you wish to resubmit it, see + * below). Transfers are deallocated with libusb_free_transfer(). + * + * It is undefined behaviour to free a transfer which has not completed. + * + * \section asyncresubmit Resubmission + * + * You may be wondering why allocation, filling, and submission are all + * separated above where they could reasonably be combined into a single + * operation. + * + * The reason for separation is to allow you to resubmit transfers without + * having to allocate new ones every time. This is especially useful for + * common situations dealing with interrupt endpoints - you allocate one + * transfer, fill and submit it, and when it returns with results you just + * resubmit it for the next interrupt. + * + * \section asynccancel Cancellation + * + * Another advantage of using the asynchronous interface is that you have + * the ability to cancel transfers which have not yet completed. This is + * done by calling the libusb_cancel_transfer() function. + * + * libusb_cancel_transfer() is asynchronous/non-blocking in itself. When the + * cancellation actually completes, the transfer's callback function will + * be invoked, and the callback function should check the transfer status to + * determine that it was cancelled. + * + * Freeing the transfer after it has been cancelled but before cancellation + * has completed will result in undefined behaviour. + * + * When a transfer is cancelled, some of the data may have been transferred. + * libusb will communicate this to you in the transfer callback. Do not assume + * that no data was transferred. + * + * \section bulk_overflows Overflows on device-to-host bulk/interrupt endpoints + * + * If your device does not have predictable transfer sizes (or it misbehaves), + * your application may submit a request for data on an IN endpoint which is + * smaller than the data that the device wishes to send. In some circumstances + * this will cause an overflow, which is a nasty condition to deal with. See + * the \ref libusb_packetoverflow page for discussion. + * + * \section asyncctrl Considerations for control transfers + * + * The libusb_transfer structure is generic and hence does not + * include specific fields for the control-specific setup packet structure. + * + * In order to perform a control transfer, you must place the 8-byte setup + * packet at the start of the data buffer. To simplify this, you could + * cast the buffer pointer to type struct libusb_control_setup, or you can + * use the helper function libusb_fill_control_setup(). + * + * The wLength field placed in the setup packet must be the length you would + * expect to be sent in the setup packet: the length of the payload that + * follows (or the expected maximum number of bytes to receive). However, + * the length field of the libusb_transfer object must be the length of + * the data buffer - i.e. it should be wLength plus the size of + * the setup packet (LIBUSB_CONTROL_SETUP_SIZE). + * + * If you use the helper functions, this is simplified for you: + * -# Allocate a buffer of size LIBUSB_CONTROL_SETUP_SIZE plus the size of the + * data you are sending/requesting. + * -# Call libusb_fill_control_setup() on the data buffer, using the transfer + * request size as the wLength value (i.e. do not include the extra space you + * allocated for the control setup). + * -# If this is a host-to-device transfer, place the data to be transferred + * in the data buffer, starting at offset LIBUSB_CONTROL_SETUP_SIZE. + * -# Call libusb_fill_control_transfer() to associate the data buffer with + * the transfer (and to set the remaining details such as callback and timeout). + * - Note that there is no parameter to set the length field of the transfer. + * The length is automatically inferred from the wLength field of the setup + * packet. + * -# Submit the transfer. + * + * The multi-byte control setup fields (wValue, wIndex and wLength) must + * be given in little-endian byte order (the endianness of the USB bus). + * Endianness conversion is transparently handled by + * libusb_fill_control_setup() which is documented to accept host-endian + * values. + * + * Further considerations are needed when handling transfer completion in + * your callback function: + * - As you might expect, the setup packet will still be sitting at the start + * of the data buffer. + * - If this was a device-to-host transfer, the received data will be sitting + * at offset LIBUSB_CONTROL_SETUP_SIZE into the buffer. + * - The actual_length field of the transfer structure is relative to the + * wLength of the setup packet, rather than the size of the data buffer. So, + * if your wLength was 4, your transfer's length was 12, then you + * should expect an actual_length of 4 to indicate that the data was + * transferred in entirity. + * + * To simplify parsing of setup packets and obtaining the data from the + * correct offset, you may wish to use the libusb_control_transfer_get_data() + * and libusb_control_transfer_get_setup() functions within your transfer + * callback. + * + * Even though control endpoints do not halt, a completed control transfer + * may have a LIBUSB_TRANSFER_STALL status code. This indicates the control + * request was not supported. + * + * \section asyncintr Considerations for interrupt transfers + * + * All interrupt transfers are performed using the polling interval presented + * by the bInterval value of the endpoint descriptor. + * + * \section asynciso Considerations for isochronous transfers + * + * Isochronous transfers are more complicated than transfers to + * non-isochronous endpoints. + * + * To perform I/O to an isochronous endpoint, allocate the transfer by calling + * libusb_alloc_transfer() with an appropriate number of isochronous packets. + * + * During filling, set \ref libusb_transfer::type "type" to + * \ref libusb_transfer_type::LIBUSB_TRANSFER_TYPE_ISOCHRONOUS + * "LIBUSB_TRANSFER_TYPE_ISOCHRONOUS", and set + * \ref libusb_transfer::num_iso_packets "num_iso_packets" to a value less than + * or equal to the number of packets you requested during allocation. + * libusb_alloc_transfer() does not set either of these fields for you, given + * that you might not even use the transfer on an isochronous endpoint. + * + * Next, populate the length field for the first num_iso_packets entries in + * the \ref libusb_transfer::iso_packet_desc "iso_packet_desc" array. Section + * 5.6.3 of the USB2 specifications describe how the maximum isochronous + * packet length is determined by the wMaxPacketSize field in the endpoint + * descriptor. + * Two functions can help you here: + * + * - libusb_get_max_iso_packet_size() is an easy way to determine the max + * packet size for an isochronous endpoint. Note that the maximum packet + * size is actually the maximum number of bytes that can be transmitted in + * a single microframe, therefore this function multiplies the maximum number + * of bytes per transaction by the number of transaction opportunities per + * microframe. + * - libusb_set_iso_packet_lengths() assigns the same length to all packets + * within a transfer, which is usually what you want. + * + * For outgoing transfers, you'll obviously fill the buffer and populate the + * packet descriptors in hope that all the data gets transferred. For incoming + * transfers, you must ensure the buffer has sufficient capacity for + * the situation where all packets transfer the full amount of requested data. + * + * Completion handling requires some extra consideration. The + * \ref libusb_transfer::actual_length "actual_length" field of the transfer + * is meaningless and should not be examined; instead you must refer to the + * \ref libusb_iso_packet_descriptor::actual_length "actual_length" field of + * each individual packet. + * + * The \ref libusb_transfer::status "status" field of the transfer is also a + * little misleading: + * - If the packets were submitted and the isochronous data microframes + * completed normally, status will have value + * \ref libusb_transfer_status::LIBUSB_TRANSFER_COMPLETED + * "LIBUSB_TRANSFER_COMPLETED". Note that bus errors and software-incurred + * delays are not counted as transfer errors; the transfer.status field may + * indicate COMPLETED even if some or all of the packets failed. Refer to + * the \ref libusb_iso_packet_descriptor::status "status" field of each + * individual packet to determine packet failures. + * - The status field will have value + * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR + * "LIBUSB_TRANSFER_ERROR" only when serious errors were encountered. + * - Other transfer status codes occur with normal behaviour. + * + * The data for each packet will be found at an offset into the buffer that + * can be calculated as if each prior packet completed in full. The + * libusb_get_iso_packet_buffer() and libusb_get_iso_packet_buffer_simple() + * functions may help you here. + * + * Note: Some operating systems (e.g. Linux) may impose limits on the + * length of individual isochronous packets and/or the total length of the + * isochronous transfer. Such limits can be difficult for libusb to detect, + * so the library will simply try and submit the transfer as set up by you. + * If the transfer fails to submit because it is too large, + * libusb_submit_transfer() will return + * \ref libusb_error::LIBUSB_ERROR_INVALID_PARAM "LIBUSB_ERROR_INVALID_PARAM". + * + * \section asyncmem Memory caveats + * + * In most circumstances, it is not safe to use stack memory for transfer + * buffers. This is because the function that fired off the asynchronous + * transfer may return before libusb has finished using the buffer, and when + * the function returns it's stack gets destroyed. This is true for both + * host-to-device and device-to-host transfers. + * + * The only case in which it is safe to use stack memory is where you can + * guarantee that the function owning the stack space for the buffer does not + * return until after the transfer's callback function has completed. In every + * other case, you need to use heap memory instead. + * + * \section asyncflags Fine control + * + * Through using this asynchronous interface, you may find yourself repeating + * a few simple operations many times. You can apply a bitwise OR of certain + * flags to a transfer to simplify certain things: + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_SHORT_NOT_OK + * "LIBUSB_TRANSFER_SHORT_NOT_OK" results in transfers which transferred + * less than the requested amount of data being marked with status + * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR "LIBUSB_TRANSFER_ERROR" + * (they would normally be regarded as COMPLETED) + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER + * "LIBUSB_TRANSFER_FREE_BUFFER" allows you to ask libusb to free the transfer + * buffer when freeing the transfer. + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_TRANSFER + * "LIBUSB_TRANSFER_FREE_TRANSFER" causes libusb to automatically free the + * transfer after the transfer callback returns. + * + * \section asyncevent Event handling + * + * An asynchronous model requires that libusb perform work at various + * points in time - namely processing the results of previously-submitted + * transfers and invoking the user-supplied callback function. + * + * This gives rise to the libusb_handle_events() function which your + * application must call into when libusb has work do to. This gives libusb + * the opportunity to reap pending transfers, invoke callbacks, etc. + * + * There are 2 different approaches to dealing with libusb_handle_events: + * + * -# Repeatedly call libusb_handle_events() in blocking mode from a dedicated + * thread. + * -# Integrate libusb with your application's main event loop. libusb + * exposes a set of file descriptors which allow you to do this. + * + * The first approach has the big advantage that it will also work on Windows + * were libusb' poll API for select / poll integration is not available. So + * if you want to support Windows and use the async API, you must use this + * approach, see the \ref eventthread "Using an event handling thread" section + * below for details. + * + * If you prefer a single threaded approach with a single central event loop, + * see the \ref libusb_poll "polling and timing" section for how to integrate libusb + * into your application's main event loop. + * + * \section eventthread Using an event handling thread + * + * Lets begin with stating the obvious: If you're going to use a separate + * thread for libusb event handling, your callback functions MUST be + * threadsafe. + * + * Other then that doing event handling from a separate thread, is mostly + * simple. You can use an event thread function as follows: +\code +void *event_thread_func(void *ctx) +{ + while (event_thread_run) + libusb_handle_events(ctx); + + return NULL; +} +\endcode + * + * There is one caveat though, stopping this thread requires setting the + * event_thread_run variable to 0, and after that libusb_handle_events() needs + * to return control to event_thread_func. But unless some event happens, + * libusb_handle_events() will not return. + * + * There are 2 different ways of dealing with this, depending on if your + * application uses libusb' \ref libusb_hotplug "hotplug" support or not. + * + * Applications which do not use hotplug support, should not start the event + * thread until after their first call to libusb_open(), and should stop the + * thread when closing the last open device as follows: +\code +void my_close_handle(libusb_device_handle *dev_handle) +{ + if (open_devs == 1) + event_thread_run = 0; + + libusb_close(dev_handle); // This wakes up libusb_handle_events() + + if (open_devs == 1) + pthread_join(event_thread); + + open_devs--; +} +\endcode + * + * Applications using hotplug support should start the thread at program init, + * after having successfully called libusb_hotplug_register_callback(), and + * should stop the thread at program exit as follows: +\code +void my_libusb_exit(void) +{ + event_thread_run = 0; + libusb_hotplug_deregister_callback(ctx, hotplug_cb_handle); // This wakes up libusb_handle_events() + pthread_join(event_thread); + libusb_exit(ctx); +} +\endcode + */ + +/** + * @defgroup libusb_poll Polling and timing + * + * This page documents libusb's functions for polling events and timing. + * These functions are only necessary for users of the + * \ref libusb_asyncio "asynchronous API". If you are only using the simpler + * \ref libusb_syncio "synchronous API" then you do not need to ever call these + * functions. + * + * The justification for the functionality described here has already been + * discussed in the \ref asyncevent "event handling" section of the + * asynchronous API documentation. In summary, libusb does not create internal + * threads for event processing and hence relies on your application calling + * into libusb at certain points in time so that pending events can be handled. + * + * Your main loop is probably already calling poll() or select() or a + * variant on a set of file descriptors for other event sources (e.g. keyboard + * button presses, mouse movements, network sockets, etc). You then add + * libusb's file descriptors to your poll()/select() calls, and when activity + * is detected on such descriptors you know it is time to call + * libusb_handle_events(). + * + * There is one final event handling complication. libusb supports + * asynchronous transfers which time out after a specified time period. + * + * On some platforms a timerfd is used, so the timeout handling is just another + * fd, on other platforms this requires that libusb is called into at or after + * the timeout to handle it. So, in addition to considering libusb's file + * descriptors in your main event loop, you must also consider that libusb + * sometimes needs to be called into at fixed points in time even when there + * is no file descriptor activity, see \ref polltime details. + * + * In order to know precisely when libusb needs to be called into, libusb + * offers you a set of pollable file descriptors and information about when + * the next timeout expires. + * + * If you are using the asynchronous I/O API, you must take one of the two + * following options, otherwise your I/O will not complete. + * + * \section pollsimple The simple option + * + * If your application revolves solely around libusb and does not need to + * handle other event sources, you can have a program structure as follows: +\code +// initialize libusb +// find and open device +// maybe fire off some initial async I/O + +while (user_has_not_requested_exit) + libusb_handle_events(ctx); + +// clean up and exit +\endcode + * + * With such a simple main loop, you do not have to worry about managing + * sets of file descriptors or handling timeouts. libusb_handle_events() will + * handle those details internally. + * + * \section libusb_pollmain The more advanced option + * + * \note This functionality is currently only available on Unix-like platforms. + * On Windows, libusb_get_pollfds() simply returns NULL. Applications which + * want to support Windows are advised to use an \ref eventthread + * "event handling thread" instead. + * + * In more advanced applications, you will already have a main loop which + * is monitoring other event sources: network sockets, X11 events, mouse + * movements, etc. Through exposing a set of file descriptors, libusb is + * designed to cleanly integrate into such main loops. + * + * In addition to polling file descriptors for the other event sources, you + * take a set of file descriptors from libusb and monitor those too. When you + * detect activity on libusb's file descriptors, you call + * libusb_handle_events_timeout() in non-blocking mode. + * + * What's more, libusb may also need to handle events at specific moments in + * time. No file descriptor activity is generated at these times, so your + * own application needs to be continually aware of when the next one of these + * moments occurs (through calling libusb_get_next_timeout()), and then it + * needs to call libusb_handle_events_timeout() in non-blocking mode when + * these moments occur. This means that you need to adjust your + * poll()/select() timeout accordingly. + * + * libusb provides you with a set of file descriptors to poll and expects you + * to poll all of them, treating them as a single entity. The meaning of each + * file descriptor in the set is an internal implementation detail, + * platform-dependent and may vary from release to release. Don't try and + * interpret the meaning of the file descriptors, just do as libusb indicates, + * polling all of them at once. + * + * In pseudo-code, you want something that looks like: +\code +// initialise libusb + +libusb_get_pollfds(ctx) +while (user has not requested application exit) { + libusb_get_next_timeout(ctx); + poll(on libusb file descriptors plus any other event sources of interest, + using a timeout no larger than the value libusb just suggested) + if (poll() indicated activity on libusb file descriptors) + libusb_handle_events_timeout(ctx, &zero_tv); + if (time has elapsed to or beyond the libusb timeout) + libusb_handle_events_timeout(ctx, &zero_tv); + // handle events from other sources here +} + +// clean up and exit +\endcode + * + * \subsection polltime Notes on time-based events + * + * The above complication with having to track time and call into libusb at + * specific moments is a bit of a headache. For maximum compatibility, you do + * need to write your main loop as above, but you may decide that you can + * restrict the supported platforms of your application and get away with + * a more simplistic scheme. + * + * These time-based event complications are \b not required on the following + * platforms: + * - Darwin + * - Linux, provided that the following version requirements are satisfied: + * - Linux v2.6.27 or newer, compiled with timerfd support + * - glibc v2.9 or newer + * - libusb v1.0.5 or newer + * + * Under these configurations, libusb_get_next_timeout() will \em always return + * 0, so your main loop can be simplified to: +\code +// initialise libusb + +libusb_get_pollfds(ctx) +while (user has not requested application exit) { + poll(on libusb file descriptors plus any other event sources of interest, + using any timeout that you like) + if (poll() indicated activity on libusb file descriptors) + libusb_handle_events_timeout(ctx, &zero_tv); + // handle events from other sources here +} + +// clean up and exit +\endcode + * + * Do remember that if you simplify your main loop to the above, you will + * lose compatibility with some platforms (including legacy Linux platforms, + * and any future platforms supported by libusb which may have time-based + * event requirements). The resultant problems will likely appear as + * strange bugs in your application. + * + * You can use the libusb_pollfds_handle_timeouts() function to do a runtime + * check to see if it is safe to ignore the time-based event complications. + * If your application has taken the shortcut of ignoring libusb's next timeout + * in your main loop, then you are advised to check the return value of + * libusb_pollfds_handle_timeouts() during application startup, and to abort + * if the platform does suffer from these timing complications. + * + * \subsection fdsetchange Changes in the file descriptor set + * + * The set of file descriptors that libusb uses as event sources may change + * during the life of your application. Rather than having to repeatedly + * call libusb_get_pollfds(), you can set up notification functions for when + * the file descriptor set changes using libusb_set_pollfd_notifiers(). + * + * \subsection mtissues Multi-threaded considerations + * + * Unfortunately, the situation is complicated further when multiple threads + * come into play. If two threads are monitoring the same file descriptors, + * the fact that only one thread will be woken up when an event occurs causes + * some headaches. + * + * The events lock, event waiters lock, and libusb_handle_events_locked() + * entities are added to solve these problems. You do not need to be concerned + * with these entities otherwise. + * + * See the extra documentation: \ref libusb_mtasync + */ + +/** \page libusb_mtasync Multi-threaded applications and asynchronous I/O + * + * libusb is a thread-safe library, but extra considerations must be applied + * to applications which interact with libusb from multiple threads. + * + * The underlying issue that must be addressed is that all libusb I/O + * revolves around monitoring file descriptors through the poll()/select() + * system calls. This is directly exposed at the + * \ref libusb_asyncio "asynchronous interface" but it is important to note that the + * \ref libusb_syncio "synchronous interface" is implemented on top of the + * asynchonrous interface, therefore the same considerations apply. + * + * The issue is that if two or more threads are concurrently calling poll() + * or select() on libusb's file descriptors then only one of those threads + * will be woken up when an event arrives. The others will be completely + * oblivious that anything has happened. + * + * Consider the following pseudo-code, which submits an asynchronous transfer + * then waits for its completion. This style is one way you could implement a + * synchronous interface on top of the asynchronous interface (and libusb + * does something similar, albeit more advanced due to the complications + * explained on this page). + * +\code +void cb(struct libusb_transfer *transfer) +{ + int *completed = transfer->user_data; + *completed = 1; +} + +void myfunc() { + struct libusb_transfer *transfer; + unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE] __attribute__ ((aligned (2))); + int completed = 0; + + transfer = libusb_alloc_transfer(0); + libusb_fill_control_setup(buffer, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, 0x04, 0x01, 0, 0); + libusb_fill_control_transfer(transfer, dev, buffer, cb, &completed, 1000); + libusb_submit_transfer(transfer); + + while (!completed) { + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_timeout(ctx, &zero_tv); + } + printf("completed!"); + // other code here +} +\endcode + * + * Here we are serializing completion of an asynchronous event + * against a condition - the condition being completion of a specific transfer. + * The poll() loop has a long timeout to minimize CPU usage during situations + * when nothing is happening (it could reasonably be unlimited). + * + * If this is the only thread that is polling libusb's file descriptors, there + * is no problem: there is no danger that another thread will swallow up the + * event that we are interested in. On the other hand, if there is another + * thread polling the same descriptors, there is a chance that it will receive + * the event that we were interested in. In this situation, myfunc() + * will only realise that the transfer has completed on the next iteration of + * the loop, up to 120 seconds later. Clearly a two-minute delay is + * undesirable, and don't even think about using short timeouts to circumvent + * this issue! + * + * The solution here is to ensure that no two threads are ever polling the + * file descriptors at the same time. A naive implementation of this would + * impact the capabilities of the library, so libusb offers the scheme + * documented below to ensure no loss of functionality. + * + * Before we go any further, it is worth mentioning that all libusb-wrapped + * event handling procedures fully adhere to the scheme documented below. + * This includes libusb_handle_events() and its variants, and all the + * synchronous I/O functions - libusb hides this headache from you. + * + * \section Using libusb_handle_events() from multiple threads + * + * Even when only using libusb_handle_events() and synchronous I/O functions, + * you can still have a race condition. You might be tempted to solve the + * above with libusb_handle_events() like so: + * +\code + libusb_submit_transfer(transfer); + + while (!completed) { + libusb_handle_events(ctx); + } + printf("completed!"); +\endcode + * + * This however has a race between the checking of completed and + * libusb_handle_events() acquiring the events lock, so another thread + * could have completed the transfer, resulting in this thread hanging + * until either a timeout or another event occurs. See also commit + * 6696512aade99bb15d6792af90ae329af270eba6 which fixes this in the + * synchronous API implementation of libusb. + * + * Fixing this race requires checking the variable completed only after + * taking the event lock, which defeats the concept of just calling + * libusb_handle_events() without worrying about locking. This is why + * libusb-1.0.9 introduces the new libusb_handle_events_timeout_completed() + * and libusb_handle_events_completed() functions, which handles doing the + * completion check for you after they have acquired the lock: + * +\code + libusb_submit_transfer(transfer); + + while (!completed) { + libusb_handle_events_completed(ctx, &completed); + } + printf("completed!"); +\endcode + * + * This nicely fixes the race in our example. Note that if all you want to + * do is submit a single transfer and wait for its completion, then using + * one of the synchronous I/O functions is much easier. + * + * \section eventlock The events lock + * + * The problem is when we consider the fact that libusb exposes file + * descriptors to allow for you to integrate asynchronous USB I/O into + * existing main loops, effectively allowing you to do some work behind + * libusb's back. If you do take libusb's file descriptors and pass them to + * poll()/select() yourself, you need to be aware of the associated issues. + * + * The first concept to be introduced is the events lock. The events lock + * is used to serialize threads that want to handle events, such that only + * one thread is handling events at any one time. + * + * You must take the events lock before polling libusb file descriptors, + * using libusb_lock_events(). You must release the lock as soon as you have + * aborted your poll()/select() loop, using libusb_unlock_events(). + * + * \section threadwait Letting other threads do the work for you + * + * Although the events lock is a critical part of the solution, it is not + * enough on it's own. You might wonder if the following is sufficient... +\code + libusb_lock_events(ctx); + while (!completed) { + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_timeout(ctx, &zero_tv); + } + libusb_unlock_events(ctx); +\endcode + * ...and the answer is that it is not. This is because the transfer in the + * code shown above may take a long time (say 30 seconds) to complete, and + * the lock is not released until the transfer is completed. + * + * Another thread with similar code that wants to do event handling may be + * working with a transfer that completes after a few milliseconds. Despite + * having such a quick completion time, the other thread cannot check that + * status of its transfer until the code above has finished (30 seconds later) + * due to contention on the lock. + * + * To solve this, libusb offers you a mechanism to determine when another + * thread is handling events. It also offers a mechanism to block your thread + * until the event handling thread has completed an event (and this mechanism + * does not involve polling of file descriptors). + * + * After determining that another thread is currently handling events, you + * obtain the event waiters lock using libusb_lock_event_waiters(). + * You then re-check that some other thread is still handling events, and if + * so, you call libusb_wait_for_event(). + * + * libusb_wait_for_event() puts your application to sleep until an event + * occurs, or until a thread releases the events lock. When either of these + * things happen, your thread is woken up, and should re-check the condition + * it was waiting on. It should also re-check that another thread is handling + * events, and if not, it should start handling events itself. + * + * This looks like the following, as pseudo-code: +\code +retry: +if (libusb_try_lock_events(ctx) == 0) { + // we obtained the event lock: do our own event handling + while (!completed) { + if (!libusb_event_handling_ok(ctx)) { + libusb_unlock_events(ctx); + goto retry; + } + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_locked(ctx, 0); + } + libusb_unlock_events(ctx); +} else { + // another thread is doing event handling. wait for it to signal us that + // an event has completed + libusb_lock_event_waiters(ctx); + + while (!completed) { + // now that we have the event waiters lock, double check that another + // thread is still handling events for us. (it may have ceased handling + // events in the time it took us to reach this point) + if (!libusb_event_handler_active(ctx)) { + // whoever was handling events is no longer doing so, try again + libusb_unlock_event_waiters(ctx); + goto retry; + } + + libusb_wait_for_event(ctx, NULL); + } + libusb_unlock_event_waiters(ctx); +} +printf("completed!\n"); +\endcode + * + * A naive look at the above code may suggest that this can only support + * one event waiter (hence a total of 2 competing threads, the other doing + * event handling), because the event waiter seems to have taken the event + * waiters lock while waiting for an event. However, the system does support + * multiple event waiters, because libusb_wait_for_event() actually drops + * the lock while waiting, and reaquires it before continuing. + * + * We have now implemented code which can dynamically handle situations where + * nobody is handling events (so we should do it ourselves), and it can also + * handle situations where another thread is doing event handling (so we can + * piggyback onto them). It is also equipped to handle a combination of + * the two, for example, another thread is doing event handling, but for + * whatever reason it stops doing so before our condition is met, so we take + * over the event handling. + * + * Four functions were introduced in the above pseudo-code. Their importance + * should be apparent from the code shown above. + * -# libusb_try_lock_events() is a non-blocking function which attempts + * to acquire the events lock but returns a failure code if it is contended. + * -# libusb_event_handling_ok() checks that libusb is still happy for your + * thread to be performing event handling. Sometimes, libusb needs to + * interrupt the event handler, and this is how you can check if you have + * been interrupted. If this function returns 0, the correct behaviour is + * for you to give up the event handling lock, and then to repeat the cycle. + * The following libusb_try_lock_events() will fail, so you will become an + * events waiter. For more information on this, read \ref fullstory below. + * -# libusb_handle_events_locked() is a variant of + * libusb_handle_events_timeout() that you can call while holding the + * events lock. libusb_handle_events_timeout() itself implements similar + * logic to the above, so be sure not to call it when you are + * "working behind libusb's back", as is the case here. + * -# libusb_event_handler_active() determines if someone is currently + * holding the events lock + * + * You might be wondering why there is no function to wake up all threads + * blocked on libusb_wait_for_event(). This is because libusb can do this + * internally: it will wake up all such threads when someone calls + * libusb_unlock_events() or when a transfer completes (at the point after its + * callback has returned). + * + * \subsection fullstory The full story + * + * The above explanation should be enough to get you going, but if you're + * really thinking through the issues then you may be left with some more + * questions regarding libusb's internals. If you're curious, read on, and if + * not, skip to the next section to avoid confusing yourself! + * + * The immediate question that may spring to mind is: what if one thread + * modifies the set of file descriptors that need to be polled while another + * thread is doing event handling? + * + * There are 2 situations in which this may happen. + * -# libusb_open() will add another file descriptor to the poll set, + * therefore it is desirable to interrupt the event handler so that it + * restarts, picking up the new descriptor. + * -# libusb_close() will remove a file descriptor from the poll set. There + * are all kinds of race conditions that could arise here, so it is + * important that nobody is doing event handling at this time. + * + * libusb handles these issues internally, so application developers do not + * have to stop their event handlers while opening/closing devices. Here's how + * it works, focusing on the libusb_close() situation first: + * + * -# During initialization, libusb opens an internal pipe, and it adds the read + * end of this pipe to the set of file descriptors to be polled. + * -# During libusb_close(), libusb writes some dummy data on this event pipe. + * This immediately interrupts the event handler. libusb also records + * internally that it is trying to interrupt event handlers for this + * high-priority event. + * -# At this point, some of the functions described above start behaving + * differently: + * - libusb_event_handling_ok() starts returning 1, indicating that it is NOT + * OK for event handling to continue. + * - libusb_try_lock_events() starts returning 1, indicating that another + * thread holds the event handling lock, even if the lock is uncontended. + * - libusb_event_handler_active() starts returning 1, indicating that + * another thread is doing event handling, even if that is not true. + * -# The above changes in behaviour result in the event handler stopping and + * giving up the events lock very quickly, giving the high-priority + * libusb_close() operation a "free ride" to acquire the events lock. All + * threads that are competing to do event handling become event waiters. + * -# With the events lock held inside libusb_close(), libusb can safely remove + * a file descriptor from the poll set, in the safety of knowledge that + * nobody is polling those descriptors or trying to access the poll set. + * -# After obtaining the events lock, the close operation completes very + * quickly (usually a matter of milliseconds) and then immediately releases + * the events lock. + * -# At the same time, the behaviour of libusb_event_handling_ok() and friends + * reverts to the original, documented behaviour. + * -# The release of the events lock causes the threads that are waiting for + * events to be woken up and to start competing to become event handlers + * again. One of them will succeed; it will then re-obtain the list of poll + * descriptors, and USB I/O will then continue as normal. + * + * libusb_open() is similar, and is actually a more simplistic case. Upon a + * call to libusb_open(): + * + * -# The device is opened and a file descriptor is added to the poll set. + * -# libusb sends some dummy data on the event pipe, and records that it + * is trying to modify the poll descriptor set. + * -# The event handler is interrupted, and the same behaviour change as for + * libusb_close() takes effect, causing all event handling threads to become + * event waiters. + * -# The libusb_open() implementation takes its free ride to the events lock. + * -# Happy that it has successfully paused the events handler, libusb_open() + * releases the events lock. + * -# The event waiter threads are all woken up and compete to become event + * handlers again. The one that succeeds will obtain the list of poll + * descriptors again, which will include the addition of the new device. + * + * \subsection concl Closing remarks + * + * The above may seem a little complicated, but hopefully I have made it clear + * why such complications are necessary. Also, do not forget that this only + * applies to applications that take libusb's file descriptors and integrate + * them into their own polling loops. + * + * You may decide that it is OK for your multi-threaded application to ignore + * some of the rules and locks detailed above, because you don't think that + * two threads can ever be polling the descriptors at the same time. If that + * is the case, then that's good news for you because you don't have to worry. + * But be careful here; remember that the synchronous I/O functions do event + * handling internally. If you have one thread doing event handling in a loop + * (without implementing the rules and locking semantics documented above) + * and another trying to send a synchronous USB transfer, you will end up with + * two threads monitoring the same descriptors, and the above-described + * undesirable behaviour occurring. The solution is for your polling thread to + * play by the rules; the synchronous I/O functions do so, and this will result + * in them getting along in perfect harmony. + * + * If you do have a dedicated thread doing event handling, it is perfectly + * legal for it to take the event handling lock for long periods of time. Any + * synchronous I/O functions you call from other threads will transparently + * fall back to the "event waiters" mechanism detailed above. The only + * consideration that your event handling thread must apply is the one related + * to libusb_event_handling_ok(): you must call this before every poll(), and + * give up the events lock if instructed. + */ + +int usbi_io_init(struct libusb_context *ctx) +{ + int r; + + usbi_mutex_init(&ctx->flying_transfers_lock); + usbi_mutex_init(&ctx->events_lock); + usbi_mutex_init(&ctx->event_waiters_lock); + usbi_cond_init(&ctx->event_waiters_cond); + usbi_mutex_init(&ctx->event_data_lock); + usbi_tls_key_create(&ctx->event_handling_key); + list_init(&ctx->flying_transfers); + list_init(&ctx->ipollfds); + list_init(&ctx->hotplug_msgs); + list_init(&ctx->completed_transfers); + + /* FIXME should use an eventfd on kernels that support it */ + r = usbi_pipe(ctx->event_pipe); + if (r < 0) { + r = LIBUSB_ERROR_OTHER; + goto err; + } + + r = usbi_add_pollfd(ctx, ctx->event_pipe[0], POLLIN); + if (r < 0) + goto err_close_pipe; + +#ifdef USBI_TIMERFD_AVAILABLE + ctx->timerfd = timerfd_create(usbi_backend->get_timerfd_clockid(), + TFD_NONBLOCK); + if (ctx->timerfd >= 0) { + usbi_dbg("using timerfd for timeouts"); + r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN); + if (r < 0) + goto err_close_timerfd; + } else { + usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno); + ctx->timerfd = -1; + } +#endif + + return 0; + +#ifdef USBI_TIMERFD_AVAILABLE +err_close_timerfd: + close(ctx->timerfd); + usbi_remove_pollfd(ctx, ctx->event_pipe[0]); +#endif +err_close_pipe: + usbi_close(ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[1]); +err: + usbi_mutex_destroy(&ctx->flying_transfers_lock); + usbi_mutex_destroy(&ctx->events_lock); + usbi_mutex_destroy(&ctx->event_waiters_lock); + usbi_cond_destroy(&ctx->event_waiters_cond); + usbi_mutex_destroy(&ctx->event_data_lock); + usbi_tls_key_delete(ctx->event_handling_key); + return r; +} + +void usbi_io_exit(struct libusb_context *ctx) +{ + usbi_remove_pollfd(ctx, ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[1]); +#ifdef USBI_TIMERFD_AVAILABLE + if (usbi_using_timerfd(ctx)) { + usbi_remove_pollfd(ctx, ctx->timerfd); + close(ctx->timerfd); + } +#endif + usbi_mutex_destroy(&ctx->flying_transfers_lock); + usbi_mutex_destroy(&ctx->events_lock); + usbi_mutex_destroy(&ctx->event_waiters_lock); + usbi_cond_destroy(&ctx->event_waiters_cond); + usbi_mutex_destroy(&ctx->event_data_lock); + usbi_tls_key_delete(ctx->event_handling_key); + if (ctx->pollfds) + free(ctx->pollfds); +} + +static int calculate_timeout(struct usbi_transfer *transfer) +{ + int r; + struct timespec current_time; + unsigned int timeout = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout; + + if (!timeout) + return 0; + + r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, ¤t_time); + if (r < 0) { + usbi_err(ITRANSFER_CTX(transfer), + "failed to read monotonic clock, errno=%d", errno); + return r; + } + + current_time.tv_sec += timeout / 1000; + current_time.tv_nsec += (timeout % 1000) * 1000000; + + while (current_time.tv_nsec >= 1000000000) { + current_time.tv_nsec -= 1000000000; + current_time.tv_sec++; + } + + TIMESPEC_TO_TIMEVAL(&transfer->timeout, ¤t_time); + return 0; +} + +/** \ingroup libusb_asyncio + * Allocate a libusb transfer with a specified number of isochronous packet + * descriptors. The returned transfer is pre-initialized for you. When the new + * transfer is no longer needed, it should be freed with + * libusb_free_transfer(). + * + * Transfers intended for non-isochronous endpoints (e.g. control, bulk, + * interrupt) should specify an iso_packets count of zero. + * + * For transfers intended for isochronous endpoints, specify an appropriate + * number of packet descriptors to be allocated as part of the transfer. + * The returned transfer is not specially initialized for isochronous I/O; + * you are still required to set the + * \ref libusb_transfer::num_iso_packets "num_iso_packets" and + * \ref libusb_transfer::type "type" fields accordingly. + * + * It is safe to allocate a transfer with some isochronous packets and then + * use it on a non-isochronous endpoint. If you do this, ensure that at time + * of submission, num_iso_packets is 0 and that type is set appropriately. + * + * \param iso_packets number of isochronous packet descriptors to allocate + * \returns a newly allocated transfer, or NULL on error + */ +DEFAULT_VISIBILITY +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer( + int iso_packets) +{ + struct libusb_transfer *transfer; + size_t os_alloc_size = usbi_backend->transfer_priv_size; + size_t alloc_size = sizeof(struct usbi_transfer) + + sizeof(struct libusb_transfer) + + (sizeof(struct libusb_iso_packet_descriptor) * iso_packets) + + os_alloc_size; + struct usbi_transfer *itransfer = calloc(1, alloc_size); + if (!itransfer) + return NULL; + + itransfer->num_iso_packets = iso_packets; + usbi_mutex_init(&itransfer->lock); + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + usbi_dbg("transfer %p", transfer); + return transfer; +} + +/** \ingroup libusb_asyncio + * Free a transfer structure. This should be called for all transfers + * allocated with libusb_alloc_transfer(). + * + * If the \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER + * "LIBUSB_TRANSFER_FREE_BUFFER" flag is set and the transfer buffer is + * non-NULL, this function will also free the transfer buffer using the + * standard system memory allocator (e.g. free()). + * + * It is legal to call this function with a NULL transfer. In this case, + * the function will simply return safely. + * + * It is not legal to free an active transfer (one which has been submitted + * and has not yet completed). + * + * \param transfer the transfer to free + */ +void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer; + if (!transfer) + return; + + usbi_dbg("transfer %p", transfer); + if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER && transfer->buffer) + free(transfer->buffer); + + itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + usbi_mutex_destroy(&itransfer->lock); + free(itransfer); +} + +#ifdef USBI_TIMERFD_AVAILABLE +static int disarm_timerfd(struct libusb_context *ctx) +{ + const struct itimerspec disarm_timer = { { 0, 0 }, { 0, 0 } }; + int r; + + usbi_dbg(""); + r = timerfd_settime(ctx->timerfd, 0, &disarm_timer, NULL); + if (r < 0) + return LIBUSB_ERROR_OTHER; + else + return 0; +} + +/* iterates through the flying transfers, and rearms the timerfd based on the + * next upcoming timeout. + * must be called with flying_list locked. + * returns 0 on success or a LIBUSB_ERROR code on failure. + */ +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx) +{ + struct usbi_transfer *transfer; + + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + struct timeval *cur_tv = &transfer->timeout; + + /* if we've reached transfers of infinite timeout, then we have no + * arming to do */ + if (!timerisset(cur_tv)) + goto disarm; + + /* act on first transfer that has not already been handled */ + if (!(transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) { + int r; + const struct itimerspec it = { {0, 0}, + { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } }; + usbi_dbg("next timeout originally %dms", USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout); + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL); + if (r < 0) + return LIBUSB_ERROR_OTHER; + return 0; + } + } + +disarm: + return disarm_timerfd(ctx); +} +#else +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx) +{ + UNUSED(ctx); + return 0; +} +#endif + +/* add a transfer to the (timeout-sorted) active transfers list. + * This function will return non 0 if fails to update the timer, + * in which case the transfer is *not* on the flying_transfers list. */ +static int add_to_flying_list(struct usbi_transfer *transfer) +{ + struct usbi_transfer *cur; + struct timeval *timeout = &transfer->timeout; + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int r; + int first = 1; + + r = calculate_timeout(transfer); + if (r) + return r; + + /* if we have no other flying transfers, start the list with this one */ + if (list_empty(&ctx->flying_transfers)) { + list_add(&transfer->list, &ctx->flying_transfers); + goto out; + } + + /* if we have infinite timeout, append to end of list */ + if (!timerisset(timeout)) { + list_add_tail(&transfer->list, &ctx->flying_transfers); + /* first is irrelevant in this case */ + goto out; + } + + /* otherwise, find appropriate place in list */ + list_for_each_entry(cur, &ctx->flying_transfers, list, struct usbi_transfer) { + /* find first timeout that occurs after the transfer in question */ + struct timeval *cur_tv = &cur->timeout; + + if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) || + (cur_tv->tv_sec == timeout->tv_sec && + cur_tv->tv_usec > timeout->tv_usec)) { + list_add_tail(&transfer->list, &cur->list); + goto out; + } + first = 0; + } + /* first is 0 at this stage (list not empty) */ + + /* otherwise we need to be inserted at the end */ + list_add_tail(&transfer->list, &ctx->flying_transfers); +out: +#ifdef USBI_TIMERFD_AVAILABLE + if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) { + /* if this transfer has the lowest timeout of all active transfers, + * rearm the timerfd with this transfer's timeout */ + const struct itimerspec it = { {0, 0}, + { timeout->tv_sec, timeout->tv_usec * 1000 } }; + usbi_dbg("arm timerfd for timeout in %dms (first in line)", + USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout); + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL); + if (r < 0) { + usbi_warn(ctx, "failed to arm first timerfd (errno %d)", errno); + r = LIBUSB_ERROR_OTHER; + } + } +#else + UNUSED(first); +#endif + + if (r) + list_del(&transfer->list); + + return r; +} + +/* remove a transfer from the active transfers list. + * This function will *always* remove the transfer from the + * flying_transfers list. It will return a LIBUSB_ERROR code + * if it fails to update the timer for the next timeout. */ +static int remove_from_flying_list(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int rearm_timerfd; + int r = 0; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + rearm_timerfd = (timerisset(&transfer->timeout) && + list_first_entry(&ctx->flying_transfers, struct usbi_transfer, list) == transfer); + list_del(&transfer->list); + if (usbi_using_timerfd(ctx) && rearm_timerfd) + r = arm_timerfd_for_next_timeout(ctx); + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + return r; +} + +/** \ingroup libusb_asyncio + * Submit a transfer. This function will fire off the USB transfer and then + * return immediately. + * + * \param transfer the transfer to submit + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted. + * \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported + * by the operating system. + * \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than + * the operating system and/or hardware can support + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + struct libusb_context *ctx = TRANSFER_CTX(transfer); + int r; + + usbi_dbg("transfer %p", transfer); + + /* + * Important note on locking, this function takes / releases locks + * in the following order: + * take flying_transfers_lock + * take itransfer->lock + * clear transfer + * add to flying_transfers list + * release flying_transfers_lock + * submit transfer + * release itransfer->lock + * if submit failed: + * take flying_transfers_lock + * remove from flying_transfers list + * release flying_transfers_lock + * + * Note that it takes locks in the order a-b and then releases them + * in the same order a-b. This is somewhat unusual but not wrong, + * release order is not important as long as *all* locks are released + * before re-acquiring any locks. + * + * This means that the ordering of first releasing itransfer->lock + * and then re-acquiring the flying_transfers_list on error is + * important and must not be changed! + * + * This is done this way because when we take both locks we must always + * take flying_transfers_lock first to avoid ab-ba style deadlocks with + * the timeout handling and usbi_handle_disconnect paths. + * + * And we cannot release itransfer->lock before the submission is + * complete otherwise timeout handling for transfers with short + * timeouts may run before submission. + */ + usbi_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&itransfer->lock); + if (itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT) { + usbi_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&itransfer->lock); + return LIBUSB_ERROR_BUSY; + } + itransfer->transferred = 0; + itransfer->state_flags = 0; + itransfer->timeout_flags = 0; + r = add_to_flying_list(itransfer); + if (r) { + usbi_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&itransfer->lock); + return r; + } + /* + * We must release the flying transfers lock here, because with + * some backends the submit_transfer method is synchroneous. + */ + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + r = usbi_backend->submit_transfer(itransfer); + if (r == LIBUSB_SUCCESS) { + itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT; + /* keep a reference to this device */ + libusb_ref_device(transfer->dev_handle->dev); + } + usbi_mutex_unlock(&itransfer->lock); + + if (r != LIBUSB_SUCCESS) + remove_from_flying_list(itransfer); + + return r; +} + +/** \ingroup libusb_asyncio + * Asynchronously cancel a previously submitted transfer. + * This function returns immediately, but this does not indicate cancellation + * is complete. Your callback function will be invoked at some later time + * with a transfer status of + * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED + * "LIBUSB_TRANSFER_CANCELLED." + * + * \param transfer the transfer to cancel + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress, + * already complete, or already cancelled. + * \returns a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + int r; + + usbi_dbg("transfer %p", transfer ); + usbi_mutex_lock(&itransfer->lock); + if (!(itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT) + || (itransfer->state_flags & USBI_TRANSFER_CANCELLING)) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + r = usbi_backend->cancel_transfer(itransfer); + if (r < 0) { + if (r != LIBUSB_ERROR_NOT_FOUND && + r != LIBUSB_ERROR_NO_DEVICE) + usbi_err(TRANSFER_CTX(transfer), + "cancel transfer failed error %d", r); + else + usbi_dbg("cancel transfer failed error %d", r); + + if (r == LIBUSB_ERROR_NO_DEVICE) + itransfer->state_flags |= USBI_TRANSFER_DEVICE_DISAPPEARED; + } + + itransfer->state_flags |= USBI_TRANSFER_CANCELLING; + +out: + usbi_mutex_unlock(&itransfer->lock); + return r; +} + +/** \ingroup libusb_asyncio + * Set a transfers bulk stream id. Note users are advised to use + * libusb_fill_bulk_stream_transfer() instead of calling this function + * directly. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to set the stream id for + * \param stream_id the stream id to set + * \see libusb_alloc_streams() + */ +void API_EXPORTED libusb_transfer_set_stream_id( + struct libusb_transfer *transfer, uint32_t stream_id) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + + itransfer->stream_id = stream_id; +} + +/** \ingroup libusb_asyncio + * Get a transfers bulk stream id. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to get the stream id for + * \returns the stream id for the transfer + */ +uint32_t API_EXPORTED libusb_transfer_get_stream_id( + struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + + return itransfer->stream_id; +} + +/* Handle completion of a transfer (completion might be an error condition). + * This will invoke the user-supplied callback function, which may end up + * freeing the transfer. Therefore you cannot use the transfer structure + * after calling this function, and you should free all backend-specific + * data before calling it. + * Do not call this function with the usbi_transfer lock held. User-specified + * callback functions may attempt to directly resubmit the transfer, which + * will attempt to take the lock. */ +int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, + enum libusb_transfer_status status) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_device_handle *dev_handle = transfer->dev_handle; + uint8_t flags; + int r; + + r = remove_from_flying_list(itransfer); + if (r < 0) + usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno); + + usbi_mutex_lock(&itransfer->lock); + itransfer->state_flags &= ~USBI_TRANSFER_IN_FLIGHT; + usbi_mutex_unlock(&itransfer->lock); + + if (status == LIBUSB_TRANSFER_COMPLETED + && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { + int rqlen = transfer->length; + if (transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL) + rqlen -= LIBUSB_CONTROL_SETUP_SIZE; + if (rqlen != itransfer->transferred) { + usbi_dbg("interpreting short transfer as error"); + status = LIBUSB_TRANSFER_ERROR; + } + } + + flags = transfer->flags; + transfer->status = status; + transfer->actual_length = itransfer->transferred; + usbi_dbg("transfer %p has callback %p", transfer, transfer->callback); + if (transfer->callback) + transfer->callback(transfer); + /* transfer might have been freed by the above call, do not use from + * this point. */ + if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) + libusb_free_transfer(transfer); + libusb_unref_device(dev_handle->dev); + return r; +} + +/* Similar to usbi_handle_transfer_completion() but exclusively for transfers + * that were asynchronously cancelled. The same concerns w.r.t. freeing of + * transfers exist here. + * Do not call this function with the usbi_transfer lock held. User-specified + * callback functions may attempt to directly resubmit the transfer, which + * will attempt to take the lock. */ +int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + uint8_t timed_out; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + timed_out = transfer->timeout_flags & USBI_TRANSFER_TIMED_OUT; + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + /* if the URB was cancelled due to timeout, report timeout to the user */ + if (timed_out) { + usbi_dbg("detected timeout cancellation"); + return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT); + } + + /* otherwise its a normal async cancel */ + return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED); +} + +/* Add a completed transfer to the completed_transfers list of the + * context and signal the event. The backend's handle_transfer_completion() + * function will be called the next time an event handler runs. */ +void usbi_signal_transfer_completion(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int pending_events; + + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + list_add_tail(&transfer->completed_list, &ctx->completed_transfers); + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); +} + +/** \ingroup libusb_poll + * Attempt to acquire the event handling lock. This lock is used to ensure that + * only one thread is monitoring libusb event sources at any one time. + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * While holding this lock, you are trusted to actually be handling events. + * If you are no longer handling events, you must call libusb_unlock_events() + * as soon as possible. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 if the lock was obtained successfully + * \returns 1 if the lock was not obtained (i.e. another thread holds the lock) + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_try_lock_events(libusb_context *ctx) +{ + int r; + unsigned int ru; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * start event handling */ + usbi_mutex_lock(&ctx->event_data_lock); + ru = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (ru) { + usbi_dbg("someone else is closing a device"); + return 1; + } + + r = usbi_mutex_trylock(&ctx->events_lock); + if (r) + return 1; + + ctx->event_handler_active = 1; + return 0; +} + +/** \ingroup libusb_poll + * Acquire the event handling lock, blocking until successful acquisition if + * it is contended. This lock is used to ensure that only one thread is + * monitoring libusb event sources at any one time. + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * While holding this lock, you are trusted to actually be handling events. + * If you are no longer handling events, you must call libusb_unlock_events() + * as soon as possible. + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_lock_events(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->events_lock); + ctx->event_handler_active = 1; +} + +/** \ingroup libusb_poll + * Release the lock previously acquired with libusb_try_lock_events() or + * libusb_lock_events(). Releasing this lock will wake up any threads blocked + * on libusb_wait_for_event(). + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_unlock_events(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + ctx->event_handler_active = 0; + usbi_mutex_unlock(&ctx->events_lock); + + /* FIXME: perhaps we should be a bit more efficient by not broadcasting + * the availability of the events lock when we are modifying pollfds + * (check ctx->device_close)? */ + usbi_mutex_lock(&ctx->event_waiters_lock); + usbi_cond_broadcast(&ctx->event_waiters_cond); + usbi_mutex_unlock(&ctx->event_waiters_lock); +} + +/** \ingroup libusb_poll + * Determine if it is still OK for this thread to be doing event handling. + * + * Sometimes, libusb needs to temporarily pause all event handlers, and this + * is the function you should use before polling file descriptors to see if + * this is the case. + * + * If this function instructs your thread to give up the events lock, you + * should just continue the usual logic that is documented in \ref libusb_mtasync. + * On the next iteration, your thread will fail to obtain the events lock, + * and will hence become an event waiter. + * + * This function should be called while the events lock is held: you don't + * need to worry about the results of this function if your thread is not + * the current event handler. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 1 if event handling can start or continue + * \returns 0 if this thread must give up the events lock + * \ref fullstory "Multi-threaded I/O: the full story" + */ +int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx) +{ + unsigned int r; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * continue event handling */ + usbi_mutex_lock(&ctx->event_data_lock); + r = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (r) { + usbi_dbg("someone else is closing a device"); + return 0; + } + + return 1; +} + + +/** \ingroup libusb_poll + * Determine if an active thread is handling events (i.e. if anyone is holding + * the event handling lock). + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 1 if a thread is handling events + * \returns 0 if there are no threads currently handling events + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_event_handler_active(libusb_context *ctx) +{ + unsigned int r; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * start event handling -- indicate that event handling is happening */ + usbi_mutex_lock(&ctx->event_data_lock); + r = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (r) { + usbi_dbg("someone else is closing a device"); + return 1; + } + + return ctx->event_handler_active; +} + +/** \ingroup libusb_poll + * Interrupt any active thread that is handling events. This is mainly useful + * for interrupting a dedicated event handling thread when an application + * wishes to call libusb_exit(). + * + * Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105 + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx) +{ + int pending_events; + USBI_GET_CONTEXT(ctx); + + usbi_dbg(""); + usbi_mutex_lock(&ctx->event_data_lock); + + pending_events = usbi_pending_events(ctx); + ctx->event_flags |= USBI_EVENT_USER_INTERRUPT; + if (!pending_events) + usbi_signal_event(ctx); + + usbi_mutex_unlock(&ctx->event_data_lock); +} + +/** \ingroup libusb_poll + * Acquire the event waiters lock. This lock is designed to be obtained under + * the situation where you want to be aware when events are completed, but + * some other thread is event handling so calling libusb_handle_events() is not + * allowed. + * + * You then obtain this lock, re-check that another thread is still handling + * events, then call libusb_wait_for_event(). + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly, + * and may potentially be handling events from 2 threads simultaenously. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->event_waiters_lock); +} + +/** \ingroup libusb_poll + * Release the event waiters lock. + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_unlock(&ctx->event_waiters_lock); +} + +/** \ingroup libusb_poll + * Wait for another thread to signal completion of an event. Must be called + * with the event waiters lock held, see libusb_lock_event_waiters(). + * + * This function will block until any of the following conditions are met: + * -# The timeout expires + * -# A transfer completes + * -# A thread releases the event handling lock through libusb_unlock_events() + * + * Condition 1 is obvious. Condition 2 unblocks your thread after + * the callback for the transfer has completed. Condition 3 is important + * because it means that the thread that was previously handling events is no + * longer doing so, so if any events are to complete, another thread needs to + * step up and start event handling. + * + * This function releases the event waiters lock before putting your thread + * to sleep, and reacquires the lock as it is being woken up. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv maximum timeout for this blocking function. A NULL value + * indicates unlimited timeout. + * \returns 0 after a transfer completes or another thread stops event handling + * \returns 1 if the timeout expired + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) +{ + int r; + + USBI_GET_CONTEXT(ctx); + if (tv == NULL) { + usbi_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock); + return 0; + } + + r = usbi_cond_timedwait(&ctx->event_waiters_cond, + &ctx->event_waiters_lock, tv); + + if (r < 0) + return r; + else + return (r == ETIMEDOUT); +} + +static void handle_timeout(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int r; + + itransfer->timeout_flags |= USBI_TRANSFER_TIMEOUT_HANDLED; + r = libusb_cancel_transfer(transfer); + if (r == LIBUSB_SUCCESS) + itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT; + else + usbi_warn(TRANSFER_CTX(transfer), + "async cancel failed %d errno=%d", r, errno); +} + +static int handle_timeouts_locked(struct libusb_context *ctx) +{ + int r; + struct timespec systime_ts; + struct timeval systime; + struct usbi_transfer *transfer; + + if (list_empty(&ctx->flying_transfers)) + return 0; + + /* get current time */ + r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &systime_ts); + if (r < 0) + return r; + + TIMESPEC_TO_TIMEVAL(&systime, &systime_ts); + + /* iterate through flying transfers list, finding all transfers that + * have expired timeouts */ + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + struct timeval *cur_tv = &transfer->timeout; + + /* if we've reached transfers of infinite timeout, we're all done */ + if (!timerisset(cur_tv)) + return 0; + + /* ignore timeouts we've already handled */ + if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) + continue; + + /* if transfer has non-expired timeout, nothing more to do */ + if ((cur_tv->tv_sec > systime.tv_sec) || + (cur_tv->tv_sec == systime.tv_sec && + cur_tv->tv_usec > systime.tv_usec)) + return 0; + + /* otherwise, we've got an expired timeout to handle */ + handle_timeout(transfer); + } + return 0; +} + +static int handle_timeouts(struct libusb_context *ctx) +{ + int r; + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->flying_transfers_lock); + r = handle_timeouts_locked(ctx); + usbi_mutex_unlock(&ctx->flying_transfers_lock); + return r; +} + +#ifdef USBI_TIMERFD_AVAILABLE +static int handle_timerfd_trigger(struct libusb_context *ctx) +{ + int r; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + + /* process the timeout that just happened */ + r = handle_timeouts_locked(ctx); + if (r < 0) + goto out; + + /* arm for next timeout*/ + r = arm_timerfd_for_next_timeout(ctx); + +out: + usbi_mutex_unlock(&ctx->flying_transfers_lock); + return r; +} +#endif + +/* do the actual event handling. assumes that no other thread is concurrently + * doing the same thing. */ +static int handle_events(struct libusb_context *ctx, struct timeval *tv) +{ + int r; + struct usbi_pollfd *ipollfd; + POLL_NFDS_TYPE nfds = 0; + POLL_NFDS_TYPE internal_nfds; + struct pollfd *fds = NULL; + int i = -1; + int timeout_ms; + int special_event; + + /* prevent attempts to recursively handle events (e.g. calling into + * libusb_handle_events() from within a hotplug or transfer callback) */ + if (usbi_handling_events(ctx)) + return LIBUSB_ERROR_BUSY; + usbi_start_event_handling(ctx); + + /* there are certain fds that libusb uses internally, currently: + * + * 1) event pipe + * 2) timerfd + * + * the backend will never need to attempt to handle events on these fds, so + * we determine how many fds are in use internally for this context and when + * handle_events() is called in the backend, the pollfd list and count will + * be adjusted to skip over these internal fds */ + if (usbi_using_timerfd(ctx)) + internal_nfds = 2; + else + internal_nfds = 1; + + /* only reallocate the poll fds when the list of poll fds has been modified + * since the last poll, otherwise reuse them to save the additional overhead */ + usbi_mutex_lock(&ctx->event_data_lock); + if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) { + usbi_dbg("poll fds modified, reallocating"); + + if (ctx->pollfds) { + free(ctx->pollfds); + ctx->pollfds = NULL; + } + + /* sanity check - it is invalid for a context to have fewer than the + * required internal fds (memory corruption?) */ + assert(ctx->pollfds_cnt >= internal_nfds); + + ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds)); + if (!ctx->pollfds) { + usbi_mutex_unlock(&ctx->event_data_lock); + r = LIBUSB_ERROR_NO_MEM; + goto done; + } + + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) { + struct libusb_pollfd *pollfd = &ipollfd->pollfd; + i++; + ctx->pollfds[i].fd = pollfd->fd; + ctx->pollfds[i].events = pollfd->events; + } + + /* reset the flag now that we have the updated list */ + ctx->event_flags &= ~USBI_EVENT_POLLFDS_MODIFIED; + + /* if no further pending events, clear the event pipe so that we do + * not immediately return from poll */ + if (!usbi_pending_events(ctx)) + usbi_clear_event(ctx); + } + fds = ctx->pollfds; + nfds = ctx->pollfds_cnt; + usbi_mutex_unlock(&ctx->event_data_lock); + + timeout_ms = (int)(tv->tv_sec * 1000) + (tv->tv_usec / 1000); + + /* round up to next millisecond */ + if (tv->tv_usec % 1000) + timeout_ms++; + +redo_poll: + usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms); + r = usbi_poll(fds, nfds, timeout_ms); + usbi_dbg("poll() returned %d", r); + if (r == 0) { + r = handle_timeouts(ctx); + goto done; + } + else if (r == -1 && errno == EINTR) { + r = LIBUSB_ERROR_INTERRUPTED; + goto done; + } + else if (r < 0) { + usbi_err(ctx, "poll failed %d err=%d", r, errno); + r = LIBUSB_ERROR_IO; + goto done; + } + + special_event = 0; + + /* fds[0] is always the event pipe */ + if (fds[0].revents) { + libusb_hotplug_message *message = NULL; + struct usbi_transfer *itransfer; + int ret = 0; + + usbi_dbg("caught a fish on the event pipe"); + + /* take the the event data lock while processing events */ + usbi_mutex_lock(&ctx->event_data_lock); + + /* check if someone added a new poll fd */ + if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) + usbi_dbg("someone updated the poll fds"); + + if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) { + usbi_dbg("someone purposely interrupted"); + ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT; + } + + /* check if someone is closing a device */ + if (ctx->device_close) + usbi_dbg("someone is closing a device"); + + /* check for any pending hotplug messages */ + if (!list_empty(&ctx->hotplug_msgs)) { + usbi_dbg("hotplug message received"); + special_event = 1; + message = list_first_entry(&ctx->hotplug_msgs, libusb_hotplug_message, list); + list_del(&message->list); + } + + /* complete any pending transfers */ + while (ret == 0 && !list_empty(&ctx->completed_transfers)) { + itransfer = list_first_entry(&ctx->completed_transfers, struct usbi_transfer, completed_list); + list_del(&itransfer->completed_list); + usbi_mutex_unlock(&ctx->event_data_lock); + ret = usbi_backend->handle_transfer_completion(itransfer); + if (ret) + usbi_err(ctx, "backend handle_transfer_completion failed with error %d", ret); + usbi_mutex_lock(&ctx->event_data_lock); + } + + /* if no further pending events, clear the event pipe */ + if (!usbi_pending_events(ctx)) + usbi_clear_event(ctx); + + usbi_mutex_unlock(&ctx->event_data_lock); + + /* process the hotplug message, if any */ + if (message) { + usbi_hotplug_match(ctx, message->device, message->event); + + /* the device left, dereference the device */ + if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == message->event) + libusb_unref_device(message->device); + + free(message); + } + + if (ret) { + /* return error code */ + r = ret; + goto done; + } + + if (0 == --r) + goto handled; + } + +#ifdef USBI_TIMERFD_AVAILABLE + /* on timerfd configurations, fds[1] is the timerfd */ + if (usbi_using_timerfd(ctx) && fds[1].revents) { + /* timerfd indicates that a timeout has expired */ + int ret; + usbi_dbg("timerfd triggered"); + special_event = 1; + + ret = handle_timerfd_trigger(ctx); + if (ret < 0) { + /* return error code */ + r = ret; + goto done; + } + + if (0 == --r) + goto handled; + } +#endif + + r = usbi_backend->handle_events(ctx, fds + internal_nfds, nfds - internal_nfds, r); + if (r) + usbi_err(ctx, "backend handle_events failed with error %d", r); + +handled: + if (r == 0 && special_event) { + timeout_ms = 0; + goto redo_poll; + } + +done: + usbi_end_event_handling(ctx); + return r; +} + +/* returns the smallest of: + * 1. timeout of next URB + * 2. user-supplied timeout + * returns 1 if there is an already-expired timeout, otherwise returns 0 + * and populates out + */ +static int get_next_timeout(libusb_context *ctx, struct timeval *tv, + struct timeval *out) +{ + struct timeval timeout; + int r = libusb_get_next_timeout(ctx, &timeout); + if (r) { + /* timeout already expired? */ + if (!timerisset(&timeout)) + return 1; + + /* choose the smallest of next URB timeout or user specified timeout */ + if (timercmp(&timeout, tv, <)) + *out = timeout; + else + *out = *tv; + } else { + *out = *tv; + } + return 0; +} + +/** \ingroup libusb_poll + * Handle any pending events. + * + * libusb determines "pending events" by checking if any timeouts have expired + * and by checking the set of file descriptors for activity. + * + * If a zero timeval is passed, this function will handle any already-pending + * events and then immediately return in non-blocking style. + * + * If a non-zero timeval is passed and no events are currently pending, this + * function will block waiting for events to handle up until the specified + * timeout. If an event arrives or a signal is raised, this function will + * return early. + * + * If the parameter completed is not NULL then after obtaining the event + * handling lock this function will return immediately if the integer + * pointed to is not 0. This allows for race free waiting for the completion + * of a specific transfer. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or an all zero + * timeval struct for non-blocking mode + * \param completed pointer to completion integer to check, or NULL + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed) +{ + int r; + struct timeval poll_timeout; + + USBI_GET_CONTEXT(ctx); + r = get_next_timeout(ctx, tv, &poll_timeout); + if (r) { + /* timeout already expired */ + return handle_timeouts(ctx); + } + +retry: + if (libusb_try_lock_events(ctx) == 0) { + if (completed == NULL || !*completed) { + /* we obtained the event lock: do our own event handling */ + usbi_dbg("doing our own event handling"); + r = handle_events(ctx, &poll_timeout); + } + libusb_unlock_events(ctx); + return r; + } + + /* another thread is doing event handling. wait for thread events that + * notify event completion. */ + libusb_lock_event_waiters(ctx); + + if (completed && *completed) + goto already_done; + + if (!libusb_event_handler_active(ctx)) { + /* we hit a race: whoever was event handling earlier finished in the + * time it took us to reach this point. try the cycle again. */ + libusb_unlock_event_waiters(ctx); + usbi_dbg("event handler was active but went away, retrying"); + goto retry; + } + + usbi_dbg("another thread is doing event handling"); + r = libusb_wait_for_event(ctx, &poll_timeout); + +already_done: + libusb_unlock_event_waiters(ctx); + + if (r < 0) + return r; + else if (r == 1) + return handle_timeouts(ctx); + else + return 0; +} + +/** \ingroup libusb_poll + * Handle any pending events + * + * Like libusb_handle_events_timeout_completed(), but without the completed + * parameter, calling this function is equivalent to calling + * libusb_handle_events_timeout_completed() with a NULL completed parameter. + * + * This function is kept primarily for backwards compatibility. + * All new code should call libusb_handle_events_completed() or + * libusb_handle_events_timeout_completed() to avoid race conditions. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or an all zero + * timeval struct for non-blocking mode + * \returns 0 on success, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv) +{ + return libusb_handle_events_timeout_completed(ctx, tv, NULL); +} + +/** \ingroup libusb_poll + * Handle any pending events in blocking mode. There is currently a timeout + * hardcoded at 60 seconds but we plan to make it unlimited in future. For + * finer control over whether this function is blocking or non-blocking, or + * for control over the timeout, use libusb_handle_events_timeout_completed() + * instead. + * + * This function is kept primarily for backwards compatibility. + * All new code should call libusb_handle_events_completed() or + * libusb_handle_events_timeout_completed() to avoid race conditions. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 on success, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_handle_events(libusb_context *ctx) +{ + struct timeval tv; + tv.tv_sec = 60; + tv.tv_usec = 0; + return libusb_handle_events_timeout_completed(ctx, &tv, NULL); +} + +/** \ingroup libusb_poll + * Handle any pending events in blocking mode. + * + * Like libusb_handle_events(), with the addition of a completed parameter + * to allow for race free waiting for the completion of a specific transfer. + * + * See libusb_handle_events_timeout_completed() for details on the completed + * parameter. + * + * \param ctx the context to operate on, or NULL for the default context + * \param completed pointer to completion integer to check, or NULL + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx, + int *completed) +{ + struct timeval tv; + tv.tv_sec = 60; + tv.tv_usec = 0; + return libusb_handle_events_timeout_completed(ctx, &tv, completed); +} + +/** \ingroup libusb_poll + * Handle any pending events by polling file descriptors, without checking if + * any other threads are already doing so. Must be called with the event lock + * held, see libusb_lock_events(). + * + * This function is designed to be called under the situation where you have + * taken the event lock and are calling poll()/select() directly on libusb's + * file descriptors (as opposed to using libusb_handle_events() or similar). + * You detect events on libusb's descriptors, so you then call this function + * with a zero timeout value (while still holding the event lock). + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or zero for + * non-blocking mode + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv) +{ + int r; + struct timeval poll_timeout; + + USBI_GET_CONTEXT(ctx); + r = get_next_timeout(ctx, tv, &poll_timeout); + if (r) { + /* timeout already expired */ + return handle_timeouts(ctx); + } + + return handle_events(ctx, &poll_timeout); +} + +/** \ingroup libusb_poll + * Determines whether your application must apply special timing considerations + * when monitoring libusb's file descriptors. + * + * This function is only useful for applications which retrieve and poll + * libusb's file descriptors in their own main loop (\ref libusb_pollmain). + * + * Ordinarily, libusb's event handler needs to be called into at specific + * moments in time (in addition to times when there is activity on the file + * descriptor set). The usual approach is to use libusb_get_next_timeout() + * to learn about when the next timeout occurs, and to adjust your + * poll()/select() timeout accordingly so that you can make a call into the + * library at that time. + * + * Some platforms supported by libusb do not come with this baggage - any + * events relevant to timing will be represented by activity on the file + * descriptor set, and libusb_get_next_timeout() will always return 0. + * This function allows you to detect whether you are running on such a + * platform. + * + * Since v1.0.5. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 if you must call into libusb at times determined by + * libusb_get_next_timeout(), or 1 if all timeout events are handled internally + * or through regular activity on the file descriptors. + * \ref libusb_pollmain "Polling libusb file descriptors for event handling" + */ +int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx) +{ +#if defined(USBI_TIMERFD_AVAILABLE) + USBI_GET_CONTEXT(ctx); + return usbi_using_timerfd(ctx); +#else + UNUSED(ctx); + return 0; +#endif +} + +/** \ingroup libusb_poll + * Determine the next internal timeout that libusb needs to handle. You only + * need to use this function if you are calling poll() or select() or similar + * on libusb's file descriptors yourself - you do not need to use it if you + * are calling libusb_handle_events() or a variant directly. + * + * You should call this function in your main loop in order to determine how + * long to wait for select() or poll() to return results. libusb needs to be + * called into at this timeout, so you should use it as an upper bound on + * your select() or poll() call. + * + * When the timeout has expired, call into libusb_handle_events_timeout() + * (perhaps in non-blocking mode) so that libusb can handle the timeout. + * + * This function may return 1 (success) and an all-zero timeval. If this is + * the case, it indicates that libusb has a timeout that has already expired + * so you should call libusb_handle_events_timeout() or similar immediately. + * A return code of 0 indicates that there are no pending timeouts. + * + * On some platforms, this function will always returns 0 (no pending + * timeouts). See \ref polltime. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv output location for a relative time against the current + * clock in which libusb must be called into in order to process timeout events + * \returns 0 if there are no pending timeouts, 1 if a timeout was returned, + * or LIBUSB_ERROR_OTHER on failure + */ +int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv) +{ + struct usbi_transfer *transfer; + struct timespec cur_ts; + struct timeval cur_tv; + struct timeval next_timeout = { 0, 0 }; + int r; + + USBI_GET_CONTEXT(ctx); + if (usbi_using_timerfd(ctx)) + return 0; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + if (list_empty(&ctx->flying_transfers)) { + usbi_mutex_unlock(&ctx->flying_transfers_lock); + usbi_dbg("no URBs, no timeout!"); + return 0; + } + + /* find next transfer which hasn't already been processed as timed out */ + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) + continue; + + /* if we've reached transfers of infinte timeout, we're done looking */ + if (!timerisset(&transfer->timeout)) + break; + + next_timeout = transfer->timeout; + break; + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + if (!timerisset(&next_timeout)) { + usbi_dbg("no URB with timeout or all handled by OS; no timeout!"); + return 0; + } + + r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts); + if (r < 0) { + usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno); + return 0; + } + TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts); + + if (!timercmp(&cur_tv, &next_timeout, <)) { + usbi_dbg("first timeout already expired"); + timerclear(tv); + } else { + timersub(&next_timeout, &cur_tv, tv); + usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec); + } + + return 1; +} + +/** \ingroup libusb_poll + * Register notification functions for file descriptor additions/removals. + * These functions will be invoked for every new or removed file descriptor + * that libusb uses as an event source. + * + * To remove notifiers, pass NULL values for the function pointers. + * + * Note that file descriptors may have been added even before you register + * these notifiers (e.g. at libusb_init() time). + * + * Additionally, note that the removal notifier may be called during + * libusb_exit() (e.g. when it is closing file descriptors that were opened + * and added to the poll set at libusb_init() time). If you don't want this, + * remove the notifiers immediately before calling libusb_exit(). + * + * \param ctx the context to operate on, or NULL for the default context + * \param added_cb pointer to function for addition notifications + * \param removed_cb pointer to function for removal notifications + * \param user_data User data to be passed back to callbacks (useful for + * passing context information) + */ +void API_EXPORTED libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data) +{ + USBI_GET_CONTEXT(ctx); + ctx->fd_added_cb = added_cb; + ctx->fd_removed_cb = removed_cb; + ctx->fd_cb_user_data = user_data; +} + +/* + * Interrupt the iteration of the event handling thread, so that it picks + * up the fd change. Callers of this function must hold the event_data_lock. + */ +static void usbi_fd_notification(struct libusb_context *ctx) +{ + int pending_events; + + /* Record that there is a new poll fd. + * Only signal an event if there are no prior pending events. */ + pending_events = usbi_pending_events(ctx); + ctx->event_flags |= USBI_EVENT_POLLFDS_MODIFIED; + if (!pending_events) + usbi_signal_event(ctx); +} + +/* Add a file descriptor to the list of file descriptors to be monitored. + * events should be specified as a bitmask of events passed to poll(), e.g. + * POLLIN and/or POLLOUT. */ +int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events) +{ + struct usbi_pollfd *ipollfd = malloc(sizeof(*ipollfd)); + if (!ipollfd) + return LIBUSB_ERROR_NO_MEM; + + usbi_dbg("add fd %d events %d", fd, events); + ipollfd->pollfd.fd = fd; + ipollfd->pollfd.events = events; + usbi_mutex_lock(&ctx->event_data_lock); + list_add_tail(&ipollfd->list, &ctx->ipollfds); + ctx->pollfds_cnt++; + usbi_fd_notification(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + if (ctx->fd_added_cb) + ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data); + return 0; +} + +/* Remove a file descriptor from the list of file descriptors to be polled. */ +void usbi_remove_pollfd(struct libusb_context *ctx, int fd) +{ + struct usbi_pollfd *ipollfd; + int found = 0; + + usbi_dbg("remove fd %d", fd); + usbi_mutex_lock(&ctx->event_data_lock); + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) + if (ipollfd->pollfd.fd == fd) { + found = 1; + break; + } + + if (!found) { + usbi_dbg("couldn't find fd %d to remove", fd); + usbi_mutex_unlock(&ctx->event_data_lock); + return; + } + + list_del(&ipollfd->list); + ctx->pollfds_cnt--; + usbi_fd_notification(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + free(ipollfd); + if (ctx->fd_removed_cb) + ctx->fd_removed_cb(fd, ctx->fd_cb_user_data); +} + +/** \ingroup libusb_poll + * Retrieve a list of file descriptors that should be polled by your main loop + * as libusb event sources. + * + * The returned list is NULL-terminated and should be freed with libusb_free_pollfds() + * when done. The actual list contents must not be touched. + * + * As file descriptors are a Unix-specific concept, this function is not + * available on Windows and will always return NULL. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns a NULL-terminated list of libusb_pollfd structures + * \returns NULL on error + * \returns NULL on platforms where the functionality is not available + */ +DEFAULT_VISIBILITY +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx) +{ +#ifndef OS_WINDOWS + struct libusb_pollfd **ret = NULL; + struct usbi_pollfd *ipollfd; + size_t i = 0; + USBI_GET_CONTEXT(ctx); + + usbi_mutex_lock(&ctx->event_data_lock); + + ret = calloc(ctx->pollfds_cnt + 1, sizeof(struct libusb_pollfd *)); + if (!ret) + goto out; + + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) + ret[i++] = (struct libusb_pollfd *) ipollfd; + ret[ctx->pollfds_cnt] = NULL; + +out: + usbi_mutex_unlock(&ctx->event_data_lock); + return (const struct libusb_pollfd **) ret; +#else + usbi_err(ctx, "external polling of libusb's internal descriptors "\ + "is not yet supported on Windows platforms"); + return NULL; +#endif +} + +/** \ingroup libusb_poll + * Free a list of libusb_pollfd structures. This should be called for all + * pollfd lists allocated with libusb_get_pollfds(). + * + * Since version 1.0.20, \ref LIBUSB_API_VERSION >= 0x01000104 + * + * It is legal to call this function with a NULL pollfd list. In this case, + * the function will simply return safely. + * + * \param pollfds the list of libusb_pollfd structures to free + */ +void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds) +{ + if (!pollfds) + return; + + free((void *)pollfds); +} + +/* Backends may call this from handle_events to report disconnection of a + * device. This function ensures transfers get cancelled appropriately. + * Callers of this function must hold the events_lock. + */ +void usbi_handle_disconnect(struct libusb_device_handle *dev_handle) +{ + struct usbi_transfer *cur; + struct usbi_transfer *to_cancel; + + usbi_dbg("device %d.%d", + dev_handle->dev->bus_number, dev_handle->dev->device_address); + + /* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE + * status code. + * + * when we find a transfer for this device on the list, there are two + * possible scenarios: + * 1. the transfer is currently in-flight, in which case we terminate the + * transfer here + * 2. the transfer has been added to the flying transfer list by + * libusb_submit_transfer, has failed to submit and + * libusb_submit_transfer is waiting for us to release the + * flying_transfers_lock to remove it, so we ignore it + */ + + while (1) { + to_cancel = NULL; + usbi_mutex_lock(&HANDLE_CTX(dev_handle)->flying_transfers_lock); + list_for_each_entry(cur, &HANDLE_CTX(dev_handle)->flying_transfers, list, struct usbi_transfer) + if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == dev_handle) { + usbi_mutex_lock(&cur->lock); + if (cur->state_flags & USBI_TRANSFER_IN_FLIGHT) + to_cancel = cur; + usbi_mutex_unlock(&cur->lock); + + if (to_cancel) + break; + } + usbi_mutex_unlock(&HANDLE_CTX(dev_handle)->flying_transfers_lock); + + if (!to_cancel) + break; + + usbi_dbg("cancelling transfer %p from disconnect", + USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel)); + + usbi_mutex_lock(&to_cancel->lock); + usbi_backend->clear_transfer_priv(to_cancel); + usbi_mutex_unlock(&to_cancel->lock); + usbi_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE); + } + +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/libusb.h b/go-api-for-hardware-wallet/usbhid/c/libusb/libusb.h new file mode 100644 index 00000000..c562690f --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/libusb.h @@ -0,0 +1,2008 @@ +/* + * Public libusb header file + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2007-2008 Daniel Drake + * Copyright © 2012 Pete Batard + * Copyright © 2012 Nathan Hjelm + * For more information, please visit: http://libusb.info + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_H +#define LIBUSB_H + +#ifdef _MSC_VER +/* on MS environments, the inline keyword is available in C++ only */ +#if !defined(__cplusplus) +#define inline __inline +#endif +/* ssize_t is also not available (copy/paste from MinGW) */ +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 + typedef __int64 ssize_t; +#else + typedef int ssize_t; +#endif /* _WIN64 */ +#endif /* _SSIZE_T_DEFINED */ +#endif /* _MSC_VER */ + +/* stdint.h is not available on older MSVC */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H)) +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +#if !defined(_WIN32_WCE) +#include +#endif + +#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__) +#include +#endif + +#include +#include + +/* 'interface' might be defined as a macro on Windows, so we need to + * undefine it so as not to break the current libusb API, because + * libusb_config_descriptor has an 'interface' member + * As this can be problematic if you include windows.h after libusb.h + * in your sources, we force windows.h to be included first. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#include +#if defined(interface) +#undef interface +#endif +#if !defined(__CYGWIN__) +#include +#endif +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define LIBUSB_DEPRECATED_FOR(f) \ + __attribute__((deprecated("Use " #f " instead"))) +#else +#define LIBUSB_DEPRECATED_FOR(f) +#endif /* __GNUC__ */ + +/** \def LIBUSB_CALL + * \ingroup libusb_misc + * libusb's Windows calling convention. + * + * Under Windows, the selection of available compilers and configurations + * means that, unlike other platforms, there is not one true calling + * convention (calling convention: the manner in which parameters are + * passed to functions in the generated assembly code). + * + * Matching the Windows API itself, libusb uses the WINAPI convention (which + * translates to the stdcall convention) and guarantees that the + * library is compiled in this way. The public header file also includes + * appropriate annotations so that your own software will use the right + * convention, even if another convention is being used by default within + * your codebase. + * + * The one consideration that you must apply in your software is to mark + * all functions which you use as libusb callbacks with this LIBUSB_CALL + * annotation, so that they too get compiled for the correct calling + * convention. + * + * On non-Windows operating systems, this macro is defined as nothing. This + * means that you can apply it to your code without worrying about + * cross-platform compatibility. + */ +/* LIBUSB_CALL must be defined on both definition and declaration of libusb + * functions. You'd think that declaration would be enough, but cygwin will + * complain about conflicting types unless both are marked this way. + * The placement of this macro is important too; it must appear after the + * return type, before the function name. See internal documentation for + * API_EXPORTED. + */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#define LIBUSB_CALL WINAPI +#else +#define LIBUSB_CALL +#endif + +/** \def LIBUSB_API_VERSION + * \ingroup libusb_misc + * libusb's API version. + * + * Since version 1.0.13, to help with feature detection, libusb defines + * a LIBUSB_API_VERSION macro that gets increased every time there is a + * significant change to the API, such as the introduction of a new call, + * the definition of a new macro/enum member, or any other element that + * libusb applications may want to detect at compilation time. + * + * The macro is typically used in an application as follows: + * \code + * #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01001234) + * // Use one of the newer features from the libusb API + * #endif + * \endcode + * + * Internally, LIBUSB_API_VERSION is defined as follows: + * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) + */ +#define LIBUSB_API_VERSION 0x01000105 + +/* The following is kept for compatibility, but will be deprecated in the future */ +#define LIBUSBX_API_VERSION LIBUSB_API_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup libusb_misc + * Convert a 16-bit value from host-endian to little-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the host-endian value to convert + * \returns the value in little-endian byte order + */ +static inline uint16_t libusb_cpu_to_le16(const uint16_t x) +{ + union { + uint8_t b8[2]; + uint16_t b16; + } _tmp; + _tmp.b8[1] = (uint8_t) (x >> 8); + _tmp.b8[0] = (uint8_t) (x & 0xff); + return _tmp.b16; +} + +/** \def libusb_le16_to_cpu + * \ingroup libusb_misc + * Convert a 16-bit value from little-endian to host-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the little-endian value to convert + * \returns the value in host-endian byte order + */ +#define libusb_le16_to_cpu libusb_cpu_to_le16 + +/* standard USB stuff */ + +/** \ingroup libusb_desc + * Device and/or Interface Class codes */ +enum libusb_class_code { + /** In the context of a \ref libusb_device_descriptor "device descriptor", + * this bDeviceClass value indicates that each interface specifies its + * own class information and all interfaces operate independently. + */ + LIBUSB_CLASS_PER_INTERFACE = 0, + + /** Audio class */ + LIBUSB_CLASS_AUDIO = 1, + + /** Communications class */ + LIBUSB_CLASS_COMM = 2, + + /** Human Interface Device class */ + LIBUSB_CLASS_HID = 3, + + /** Physical */ + LIBUSB_CLASS_PHYSICAL = 5, + + /** Printer class */ + LIBUSB_CLASS_PRINTER = 7, + + /** Image class */ + LIBUSB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */ + LIBUSB_CLASS_IMAGE = 6, + + /** Mass storage class */ + LIBUSB_CLASS_MASS_STORAGE = 8, + + /** Hub class */ + LIBUSB_CLASS_HUB = 9, + + /** Data class */ + LIBUSB_CLASS_DATA = 10, + + /** Smart Card */ + LIBUSB_CLASS_SMART_CARD = 0x0b, + + /** Content Security */ + LIBUSB_CLASS_CONTENT_SECURITY = 0x0d, + + /** Video */ + LIBUSB_CLASS_VIDEO = 0x0e, + + /** Personal Healthcare */ + LIBUSB_CLASS_PERSONAL_HEALTHCARE = 0x0f, + + /** Diagnostic Device */ + LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + + /** Wireless class */ + LIBUSB_CLASS_WIRELESS = 0xe0, + + /** Application class */ + LIBUSB_CLASS_APPLICATION = 0xfe, + + /** Class is vendor-specific */ + LIBUSB_CLASS_VENDOR_SPEC = 0xff +}; + +/** \ingroup libusb_desc + * Descriptor types as defined by the USB specification. */ +enum libusb_descriptor_type { + /** Device descriptor. See libusb_device_descriptor. */ + LIBUSB_DT_DEVICE = 0x01, + + /** Configuration descriptor. See libusb_config_descriptor. */ + LIBUSB_DT_CONFIG = 0x02, + + /** String descriptor */ + LIBUSB_DT_STRING = 0x03, + + /** Interface descriptor. See libusb_interface_descriptor. */ + LIBUSB_DT_INTERFACE = 0x04, + + /** Endpoint descriptor. See libusb_endpoint_descriptor. */ + LIBUSB_DT_ENDPOINT = 0x05, + + /** BOS descriptor */ + LIBUSB_DT_BOS = 0x0f, + + /** Device Capability descriptor */ + LIBUSB_DT_DEVICE_CAPABILITY = 0x10, + + /** HID descriptor */ + LIBUSB_DT_HID = 0x21, + + /** HID report descriptor */ + LIBUSB_DT_REPORT = 0x22, + + /** Physical descriptor */ + LIBUSB_DT_PHYSICAL = 0x23, + + /** Hub descriptor */ + LIBUSB_DT_HUB = 0x29, + + /** SuperSpeed Hub descriptor */ + LIBUSB_DT_SUPERSPEED_HUB = 0x2a, + + /** SuperSpeed Endpoint Companion descriptor */ + LIBUSB_DT_SS_ENDPOINT_COMPANION = 0x30 +}; + +/* Descriptor sizes per descriptor type */ +#define LIBUSB_DT_DEVICE_SIZE 18 +#define LIBUSB_DT_CONFIG_SIZE 9 +#define LIBUSB_DT_INTERFACE_SIZE 9 +#define LIBUSB_DT_ENDPOINT_SIZE 7 +#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define LIBUSB_DT_HUB_NONVAR_SIZE 7 +#define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE 6 +#define LIBUSB_DT_BOS_SIZE 5 +#define LIBUSB_DT_DEVICE_CAPABILITY_SIZE 3 + +/* BOS descriptor sizes */ +#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7 +#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10 +#define LIBUSB_BT_CONTAINER_ID_SIZE 20 + +/* We unwrap the BOS => define its max size */ +#define LIBUSB_DT_BOS_MAX_SIZE ((LIBUSB_DT_BOS_SIZE) +\ + (LIBUSB_BT_USB_2_0_EXTENSION_SIZE) +\ + (LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) +\ + (LIBUSB_BT_CONTAINER_ID_SIZE)) + +#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define LIBUSB_ENDPOINT_DIR_MASK 0x80 + +/** \ingroup libusb_desc + * Endpoint direction. Values for bit 7 of the + * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. + */ +enum libusb_endpoint_direction { + /** In: device-to-host */ + LIBUSB_ENDPOINT_IN = 0x80, + + /** Out: host-to-device */ + LIBUSB_ENDPOINT_OUT = 0x00 +}; + +#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ + +/** \ingroup libusb_desc + * Endpoint transfer type. Values for bits 0:1 of the + * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. + */ +enum libusb_transfer_type { + /** Control endpoint */ + LIBUSB_TRANSFER_TYPE_CONTROL = 0, + + /** Isochronous endpoint */ + LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1, + + /** Bulk endpoint */ + LIBUSB_TRANSFER_TYPE_BULK = 2, + + /** Interrupt endpoint */ + LIBUSB_TRANSFER_TYPE_INTERRUPT = 3, + + /** Stream endpoint */ + LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4, +}; + +/** \ingroup libusb_misc + * Standard requests, as defined in table 9-5 of the USB 3.0 specifications */ +enum libusb_standard_request { + /** Request status of the specific recipient */ + LIBUSB_REQUEST_GET_STATUS = 0x00, + + /** Clear or disable a specific feature */ + LIBUSB_REQUEST_CLEAR_FEATURE = 0x01, + + /* 0x02 is reserved */ + + /** Set or enable a specific feature */ + LIBUSB_REQUEST_SET_FEATURE = 0x03, + + /* 0x04 is reserved */ + + /** Set device address for all future accesses */ + LIBUSB_REQUEST_SET_ADDRESS = 0x05, + + /** Get the specified descriptor */ + LIBUSB_REQUEST_GET_DESCRIPTOR = 0x06, + + /** Used to update existing descriptors or add new descriptors */ + LIBUSB_REQUEST_SET_DESCRIPTOR = 0x07, + + /** Get the current device configuration value */ + LIBUSB_REQUEST_GET_CONFIGURATION = 0x08, + + /** Set device configuration */ + LIBUSB_REQUEST_SET_CONFIGURATION = 0x09, + + /** Return the selected alternate setting for the specified interface */ + LIBUSB_REQUEST_GET_INTERFACE = 0x0A, + + /** Select an alternate interface for the specified interface */ + LIBUSB_REQUEST_SET_INTERFACE = 0x0B, + + /** Set then report an endpoint's synchronization frame */ + LIBUSB_REQUEST_SYNCH_FRAME = 0x0C, + + /** Sets both the U1 and U2 Exit Latency */ + LIBUSB_REQUEST_SET_SEL = 0x30, + + /** Delay from the time a host transmits a packet to the time it is + * received by the device. */ + LIBUSB_SET_ISOCH_DELAY = 0x31, +}; + +/** \ingroup libusb_misc + * Request type bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. */ +enum libusb_request_type { + /** Standard */ + LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), + + /** Class */ + LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5), + + /** Vendor */ + LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), + + /** Reserved */ + LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5) +}; + +/** \ingroup libusb_misc + * Recipient bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. Values 4 through 31 are reserved. */ +enum libusb_request_recipient { + /** Device */ + LIBUSB_RECIPIENT_DEVICE = 0x00, + + /** Interface */ + LIBUSB_RECIPIENT_INTERFACE = 0x01, + + /** Endpoint */ + LIBUSB_RECIPIENT_ENDPOINT = 0x02, + + /** Other */ + LIBUSB_RECIPIENT_OTHER = 0x03, +}; + +#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C + +/** \ingroup libusb_desc + * Synchronization type for isochronous endpoints. Values for bits 2:3 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_sync_type { + /** No synchronization */ + LIBUSB_ISO_SYNC_TYPE_NONE = 0, + + /** Asynchronous */ + LIBUSB_ISO_SYNC_TYPE_ASYNC = 1, + + /** Adaptive */ + LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 2, + + /** Synchronous */ + LIBUSB_ISO_SYNC_TYPE_SYNC = 3 +}; + +#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 + +/** \ingroup libusb_desc + * Usage type for isochronous endpoints. Values for bits 4:5 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_usage_type { + /** Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_DATA = 0, + + /** Feedback endpoint */ + LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 1, + + /** Implicit feedback Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB device descriptor. This + * descriptor is documented in section 9.6.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_device_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this + * context. */ + uint8_t bDescriptorType; + + /** USB specification release number in binary-coded decimal. A value of + * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */ + uint16_t bcdUSB; + + /** USB-IF class code for the device. See \ref libusb_class_code. */ + uint8_t bDeviceClass; + + /** USB-IF subclass code for the device, qualified by the bDeviceClass + * value */ + uint8_t bDeviceSubClass; + + /** USB-IF protocol code for the device, qualified by the bDeviceClass and + * bDeviceSubClass values */ + uint8_t bDeviceProtocol; + + /** Maximum packet size for endpoint 0 */ + uint8_t bMaxPacketSize0; + + /** USB-IF vendor ID */ + uint16_t idVendor; + + /** USB-IF product ID */ + uint16_t idProduct; + + /** Device release number in binary-coded decimal */ + uint16_t bcdDevice; + + /** Index of string descriptor describing manufacturer */ + uint8_t iManufacturer; + + /** Index of string descriptor describing product */ + uint8_t iProduct; + + /** Index of string descriptor containing device serial number */ + uint8_t iSerialNumber; + + /** Number of possible configurations */ + uint8_t bNumConfigurations; +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB endpoint descriptor. This + * descriptor is documented in section 9.6.6 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_endpoint_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in + * this context. */ + uint8_t bDescriptorType; + + /** The address of the endpoint described by this descriptor. Bits 0:3 are + * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction, + * see \ref libusb_endpoint_direction. + */ + uint8_t bEndpointAddress; + + /** Attributes which apply to the endpoint when it is configured using + * the bConfigurationValue. Bits 0:1 determine the transfer type and + * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for + * isochronous endpoints and correspond to \ref libusb_iso_sync_type. + * Bits 4:5 are also only used for isochronous endpoints and correspond to + * \ref libusb_iso_usage_type. Bits 6:7 are reserved. + */ + uint8_t bmAttributes; + + /** Maximum packet size this endpoint is capable of sending/receiving. */ + uint16_t wMaxPacketSize; + + /** Interval for polling endpoint for data transfers. */ + uint8_t bInterval; + + /** For audio devices only: the rate at which synchronization feedback + * is provided. */ + uint8_t bRefresh; + + /** For audio devices only: the address if the synch endpoint */ + uint8_t bSynchAddress; + + /** Extra descriptors. If libusb encounters unknown endpoint descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB interface descriptor. This + * descriptor is documented in section 9.6.5 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_interface_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE + * in this context. */ + uint8_t bDescriptorType; + + /** Number of this interface */ + uint8_t bInterfaceNumber; + + /** Value used to select this alternate setting for this interface */ + uint8_t bAlternateSetting; + + /** Number of endpoints used by this interface (excluding the control + * endpoint). */ + uint8_t bNumEndpoints; + + /** USB-IF class code for this interface. See \ref libusb_class_code. */ + uint8_t bInterfaceClass; + + /** USB-IF subclass code for this interface, qualified by the + * bInterfaceClass value */ + uint8_t bInterfaceSubClass; + + /** USB-IF protocol code for this interface, qualified by the + * bInterfaceClass and bInterfaceSubClass values */ + uint8_t bInterfaceProtocol; + + /** Index of string descriptor describing this interface */ + uint8_t iInterface; + + /** Array of endpoint descriptors. This length of this array is determined + * by the bNumEndpoints field. */ + const struct libusb_endpoint_descriptor *endpoint; + + /** Extra descriptors. If libusb encounters unknown interface descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup libusb_desc + * A collection of alternate settings for a particular USB interface. + */ +struct libusb_interface { + /** Array of interface descriptors. The length of this array is determined + * by the num_altsetting field. */ + const struct libusb_interface_descriptor *altsetting; + + /** The number of alternate settings that belong to this interface */ + int num_altsetting; +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB configuration descriptor. This + * descriptor is documented in section 9.6.3 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_config_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG + * in this context. */ + uint8_t bDescriptorType; + + /** Total length of data returned for this configuration */ + uint16_t wTotalLength; + + /** Number of interfaces supported by this configuration */ + uint8_t bNumInterfaces; + + /** Identifier value for this configuration */ + uint8_t bConfigurationValue; + + /** Index of string descriptor describing this configuration */ + uint8_t iConfiguration; + + /** Configuration characteristics */ + uint8_t bmAttributes; + + /** Maximum power consumption of the USB device from this bus in this + * configuration when the device is fully operation. Expressed in units + * of 2 mA when the device is operating in high-speed mode and in units + * of 8 mA when the device is operating in super-speed mode. */ + uint8_t MaxPower; + + /** Array of interfaces supported by this configuration. The length of + * this array is determined by the bNumInterfaces field. */ + const struct libusb_interface *interface; + + /** Extra descriptors. If libusb encounters unknown configuration + * descriptors, it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup libusb_desc + * A structure representing the superspeed endpoint companion + * descriptor. This descriptor is documented in section 9.6.7 of + * the USB 3.0 specification. All multiple-byte fields are represented in + * host-endian format. + */ +struct libusb_ss_endpoint_companion_descriptor { + + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_SS_ENDPOINT_COMPANION in + * this context. */ + uint8_t bDescriptorType; + + + /** The maximum number of packets the endpoint can send or + * receive as part of a burst. */ + uint8_t bMaxBurst; + + /** In bulk EP: bits 4:0 represents the maximum number of + * streams the EP supports. In isochronous EP: bits 1:0 + * represents the Mult - a zero based value that determines + * the maximum number of packets within a service interval */ + uint8_t bmAttributes; + + /** The total number of bytes this EP will transfer every + * service interval. valid only for periodic EPs. */ + uint16_t wBytesPerInterval; +}; + +/** \ingroup libusb_desc + * A generic representation of a BOS Device Capability descriptor. It is + * advised to check bDevCapabilityType and call the matching + * libusb_get_*_descriptor function to get a structure fully matching the type. + */ +struct libusb_bos_dev_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + /** Device Capability type */ + uint8_t bDevCapabilityType; + /** Device Capability data (bLength - 3 bytes) */ + uint8_t dev_capability_data +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup libusb_desc + * A structure representing the Binary Device Object Store (BOS) descriptor. + * This descriptor is documented in section 9.6.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_bos_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_BOS LIBUSB_DT_BOS + * in this context. */ + uint8_t bDescriptorType; + + /** Length of this descriptor and all of its sub descriptors */ + uint16_t wTotalLength; + + /** The number of separate device capability descriptors in + * the BOS */ + uint8_t bNumDeviceCaps; + + /** bNumDeviceCap Device Capability Descriptors */ + struct libusb_bos_dev_capability_descriptor *dev_capability +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup libusb_desc + * A structure representing the USB 2.0 Extension descriptor + * This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_usb_2_0_extension_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + * LIBUSB_BT_USB_2_0_EXTENSION in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_usb_2_0_extension_attributes. */ + uint32_t bmAttributes; +}; + +/** \ingroup libusb_desc + * A structure representing the SuperSpeed USB Device Capability descriptor + * This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_ss_usb_device_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_ss_usb_device_capability_attributes. */ + uint8_t bmAttributes; + + /** Bitmap encoding of the speed supported by this device when + * operating in SuperSpeed mode. See \ref libusb_supported_speed. */ + uint16_t wSpeedSupported; + + /** The lowest speed at which all the functionality supported + * by the device is available to the user. For example if the + * device supports all its functionality when connected at + * full speed and above then it sets this value to 1. */ + uint8_t bFunctionalitySupport; + + /** U1 Device Exit Latency. */ + uint8_t bU1DevExitLat; + + /** U2 Device Exit Latency. */ + uint16_t bU2DevExitLat; +}; + +/** \ingroup libusb_desc + * A structure representing the Container ID descriptor. + * This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification. + * All multiple-byte fields, except UUIDs, are represented in host-endian format. + */ +struct libusb_container_id_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + * LIBUSB_BT_CONTAINER_ID in this context. */ + uint8_t bDevCapabilityType; + + /** Reserved field */ + uint8_t bReserved; + + /** 128 bit UUID */ + uint8_t ContainerID[16]; +}; + +/** \ingroup libusb_asyncio + * Setup packet for control transfers. */ +struct libusb_control_setup { + /** Request type. Bits 0:4 determine recipient, see + * \ref libusb_request_recipient. Bits 5:6 determine type, see + * \ref libusb_request_type. Bit 7 determines data transfer direction, see + * \ref libusb_endpoint_direction. + */ + uint8_t bmRequestType; + + /** Request. If the type bits of bmRequestType are equal to + * \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD + * "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to + * \ref libusb_standard_request. For other cases, use of this field is + * application-specific. */ + uint8_t bRequest; + + /** Value. Varies according to request */ + uint16_t wValue; + + /** Index. Varies according to request, typically used to pass an index + * or offset */ + uint16_t wIndex; + + /** Number of bytes to transfer */ + uint16_t wLength; +}; + +#define LIBUSB_CONTROL_SETUP_SIZE (sizeof(struct libusb_control_setup)) + +/* libusb */ + +struct libusb_context; +struct libusb_device; +struct libusb_device_handle; + +/** \ingroup libusb_lib + * Structure providing the version of the libusb runtime + */ +struct libusb_version { + /** Library major version. */ + const uint16_t major; + + /** Library minor version. */ + const uint16_t minor; + + /** Library micro version. */ + const uint16_t micro; + + /** Library nano version. */ + const uint16_t nano; + + /** Library release candidate suffix string, e.g. "-rc4". */ + const char *rc; + + /** For ABI compatibility only. */ + const char* describe; +}; + +/** \ingroup libusb_lib + * Structure representing a libusb session. The concept of individual libusb + * sessions allows for your program to use two libraries (or dynamically + * load two modules) which both independently use libusb. This will prevent + * interference between the individual libusb users - for example + * libusb_set_debug() will not affect the other user of the library, and + * libusb_exit() will not destroy resources that the other user is still + * using. + * + * Sessions are created by libusb_init() and destroyed through libusb_exit(). + * If your application is guaranteed to only ever include a single libusb + * user (i.e. you), you do not have to worry about contexts: pass NULL in + * every function call where a context is required. The default context + * will be used. + * + * For more information, see \ref libusb_contexts. + */ +typedef struct libusb_context libusb_context; + +/** \ingroup libusb_dev + * Structure representing a USB device detected on the system. This is an + * opaque type for which you are only ever provided with a pointer, usually + * originating from libusb_get_device_list(). + * + * Certain operations can be performed on a device, but in order to do any + * I/O you will have to first obtain a device handle using libusb_open(). + * + * Devices are reference counted with libusb_ref_device() and + * libusb_unref_device(), and are freed when the reference count reaches 0. + * New devices presented by libusb_get_device_list() have a reference count of + * 1, and libusb_free_device_list() can optionally decrease the reference count + * on all devices in the list. libusb_open() adds another reference which is + * later destroyed by libusb_close(). + */ +typedef struct libusb_device libusb_device; + + +/** \ingroup libusb_dev + * Structure representing a handle on a USB device. This is an opaque type for + * which you are only ever provided with a pointer, usually originating from + * libusb_open(). + * + * A device handle is used to perform I/O and other operations. When finished + * with a device handle, you should call libusb_close(). + */ +typedef struct libusb_device_handle libusb_device_handle; + +/** \ingroup libusb_dev + * Speed codes. Indicates the speed at which the device is operating. + */ +enum libusb_speed { + /** The OS doesn't report or know the device speed. */ + LIBUSB_SPEED_UNKNOWN = 0, + + /** The device is operating at low speed (1.5MBit/s). */ + LIBUSB_SPEED_LOW = 1, + + /** The device is operating at full speed (12MBit/s). */ + LIBUSB_SPEED_FULL = 2, + + /** The device is operating at high speed (480MBit/s). */ + LIBUSB_SPEED_HIGH = 3, + + /** The device is operating at super speed (5000MBit/s). */ + LIBUSB_SPEED_SUPER = 4, +}; + +/** \ingroup libusb_dev + * Supported speeds (wSpeedSupported) bitfield. Indicates what + * speeds the device supports. + */ +enum libusb_supported_speed { + /** Low speed operation supported (1.5MBit/s). */ + LIBUSB_LOW_SPEED_OPERATION = 1, + + /** Full speed operation supported (12MBit/s). */ + LIBUSB_FULL_SPEED_OPERATION = 2, + + /** High speed operation supported (480MBit/s). */ + LIBUSB_HIGH_SPEED_OPERATION = 4, + + /** Superspeed operation supported (5000MBit/s). */ + LIBUSB_SUPER_SPEED_OPERATION = 8, +}; + +/** \ingroup libusb_dev + * Masks for the bits of the + * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field + * of the USB 2.0 Extension descriptor. + */ +enum libusb_usb_2_0_extension_attributes { + /** Supports Link Power Management (LPM) */ + LIBUSB_BM_LPM_SUPPORT = 2, +}; + +/** \ingroup libusb_dev + * Masks for the bits of the + * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field + * field of the SuperSpeed USB Device Capability descriptor. + */ +enum libusb_ss_usb_device_capability_attributes { + /** Supports Latency Tolerance Messages (LTM) */ + LIBUSB_BM_LTM_SUPPORT = 2, +}; + +/** \ingroup libusb_dev + * USB capability types + */ +enum libusb_bos_type { + /** Wireless USB device capability */ + LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1, + + /** USB 2.0 extensions */ + LIBUSB_BT_USB_2_0_EXTENSION = 2, + + /** SuperSpeed USB device capability */ + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3, + + /** Container ID type */ + LIBUSB_BT_CONTAINER_ID = 4, +}; + +/** \ingroup libusb_misc + * Error codes. Most libusb functions return 0 on success or one of these + * codes on failure. + * You can call libusb_error_name() to retrieve a string representation of an + * error code or libusb_strerror() to get an end-user suitable description of + * an error code. + */ +enum libusb_error { + /** Success (no error) */ + LIBUSB_SUCCESS = 0, + + /** Input/output error */ + LIBUSB_ERROR_IO = -1, + + /** Invalid parameter */ + LIBUSB_ERROR_INVALID_PARAM = -2, + + /** Access denied (insufficient permissions) */ + LIBUSB_ERROR_ACCESS = -3, + + /** No such device (it may have been disconnected) */ + LIBUSB_ERROR_NO_DEVICE = -4, + + /** Entity not found */ + LIBUSB_ERROR_NOT_FOUND = -5, + + /** Resource busy */ + LIBUSB_ERROR_BUSY = -6, + + /** Operation timed out */ + LIBUSB_ERROR_TIMEOUT = -7, + + /** Overflow */ + LIBUSB_ERROR_OVERFLOW = -8, + + /** Pipe error */ + LIBUSB_ERROR_PIPE = -9, + + /** System call interrupted (perhaps due to signal) */ + LIBUSB_ERROR_INTERRUPTED = -10, + + /** Insufficient memory */ + LIBUSB_ERROR_NO_MEM = -11, + + /** Operation not supported or unimplemented on this platform */ + LIBUSB_ERROR_NOT_SUPPORTED = -12, + + /* NB: Remember to update LIBUSB_ERROR_COUNT below as well as the + message strings in strerror.c when adding new error codes here. */ + + /** Other error */ + LIBUSB_ERROR_OTHER = -99, +}; + +/* Total number of error codes in enum libusb_error */ +#define LIBUSB_ERROR_COUNT 14 + +/** \ingroup libusb_asyncio + * Transfer status codes */ +enum libusb_transfer_status { + /** Transfer completed without error. Note that this does not indicate + * that the entire amount of requested data was transferred. */ + LIBUSB_TRANSFER_COMPLETED, + + /** Transfer failed */ + LIBUSB_TRANSFER_ERROR, + + /** Transfer timed out */ + LIBUSB_TRANSFER_TIMED_OUT, + + /** Transfer was cancelled */ + LIBUSB_TRANSFER_CANCELLED, + + /** For bulk/interrupt endpoints: halt condition detected (endpoint + * stalled). For control endpoints: control request not supported. */ + LIBUSB_TRANSFER_STALL, + + /** Device was disconnected */ + LIBUSB_TRANSFER_NO_DEVICE, + + /** Device sent more data than requested */ + LIBUSB_TRANSFER_OVERFLOW, + + /* NB! Remember to update libusb_error_name() + when adding new status codes here. */ +}; + +/** \ingroup libusb_asyncio + * libusb_transfer.flags values */ +enum libusb_transfer_flags { + /** Report short frames as errors */ + LIBUSB_TRANSFER_SHORT_NOT_OK = 1<<0, + + /** Automatically free() transfer buffer during libusb_free_transfer(). + * Note that buffers allocated with libusb_dev_mem_alloc() should not + * be attempted freed in this way, since free() is not an appropriate + * way to release such memory. */ + LIBUSB_TRANSFER_FREE_BUFFER = 1<<1, + + /** Automatically call libusb_free_transfer() after callback returns. + * If this flag is set, it is illegal to call libusb_free_transfer() + * from your transfer callback, as this will result in a double-free + * when this flag is acted upon. */ + LIBUSB_TRANSFER_FREE_TRANSFER = 1<<2, + + /** Terminate transfers that are a multiple of the endpoint's + * wMaxPacketSize with an extra zero length packet. This is useful + * when a device protocol mandates that each logical request is + * terminated by an incomplete packet (i.e. the logical requests are + * not separated by other means). + * + * This flag only affects host-to-device transfers to bulk and interrupt + * endpoints. In other situations, it is ignored. + * + * This flag only affects transfers with a length that is a multiple of + * the endpoint's wMaxPacketSize. On transfers of other lengths, this + * flag has no effect. Therefore, if you are working with a device that + * needs a ZLP whenever the end of the logical request falls on a packet + * boundary, then it is sensible to set this flag on every + * transfer (you do not have to worry about only setting it on transfers + * that end on the boundary). + * + * This flag is currently only supported on Linux. + * On other systems, libusb_submit_transfer() will return + * LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set. + * + * Available since libusb-1.0.9. + */ + LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3, +}; + +/** \ingroup libusb_asyncio + * Isochronous packet descriptor. */ +struct libusb_iso_packet_descriptor { + /** Length of data to request in this packet */ + unsigned int length; + + /** Amount of data that was actually transferred */ + unsigned int actual_length; + + /** Status code for this packet */ + enum libusb_transfer_status status; +}; + +struct libusb_transfer; + +/** \ingroup libusb_asyncio + * Asynchronous transfer callback function type. When submitting asynchronous + * transfers, you pass a pointer to a callback function of this type via the + * \ref libusb_transfer::callback "callback" member of the libusb_transfer + * structure. libusb will call this function later, when the transfer has + * completed or failed. See \ref libusb_asyncio for more information. + * \param transfer The libusb_transfer struct the callback function is being + * notified about. + */ +typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer); + +/** \ingroup libusb_asyncio + * The generic USB transfer structure. The user populates this structure and + * then submits it in order to request a transfer. After the transfer has + * completed, the library populates the transfer with the results and passes + * it back to the user. + */ +struct libusb_transfer { + /** Handle of the device that this transfer will be submitted to */ + libusb_device_handle *dev_handle; + + /** A bitwise OR combination of \ref libusb_transfer_flags. */ + uint8_t flags; + + /** Address of the endpoint where this transfer will be sent. */ + unsigned char endpoint; + + /** Type of the endpoint from \ref libusb_transfer_type */ + unsigned char type; + + /** Timeout for this transfer in milliseconds. A value of 0 indicates no + * timeout. */ + unsigned int timeout; + + /** The status of the transfer. Read-only, and only for use within + * transfer callback function. + * + * If this is an isochronous transfer, this field may read COMPLETED even + * if there were errors in the frames. Use the + * \ref libusb_iso_packet_descriptor::status "status" field in each packet + * to determine if errors occurred. */ + enum libusb_transfer_status status; + + /** Length of the data buffer */ + int length; + + /** Actual length of data that was transferred. Read-only, and only for + * use within transfer callback function. Not valid for isochronous + * endpoint transfers. */ + int actual_length; + + /** Callback function. This will be invoked when the transfer completes, + * fails, or is cancelled. */ + libusb_transfer_cb_fn callback; + + /** User context data to pass to the callback function. */ + void *user_data; + + /** Data buffer */ + unsigned char *buffer; + + /** Number of isochronous packets. Only used for I/O with isochronous + * endpoints. */ + int num_iso_packets; + + /** Isochronous packet descriptors, for isochronous transfers only. */ + struct libusb_iso_packet_descriptor iso_packet_desc +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup libusb_misc + * Capabilities supported by an instance of libusb on the current running + * platform. Test if the loaded library supports a given capability by calling + * \ref libusb_has_capability(). + */ +enum libusb_capability { + /** The libusb_has_capability() API is available. */ + LIBUSB_CAP_HAS_CAPABILITY = 0x0000, + /** Hotplug support is available on this platform. */ + LIBUSB_CAP_HAS_HOTPLUG = 0x0001, + /** The library can access HID devices without requiring user intervention. + * Note that before being able to actually access an HID device, you may + * still have to call additional libusb functions such as + * \ref libusb_detach_kernel_driver(). */ + LIBUSB_CAP_HAS_HID_ACCESS = 0x0100, + /** The library supports detaching of the default USB driver, using + * \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */ + LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101 +}; + +/** \ingroup libusb_lib + * Log message levels. + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stdout, warning + * and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stdout, + * warnings and errors to stderr + */ +enum libusb_log_level { + LIBUSB_LOG_LEVEL_NONE = 0, + LIBUSB_LOG_LEVEL_ERROR, + LIBUSB_LOG_LEVEL_WARNING, + LIBUSB_LOG_LEVEL_INFO, + LIBUSB_LOG_LEVEL_DEBUG, +}; + +int LIBUSB_CALL libusb_init(libusb_context **ctx); +void LIBUSB_CALL libusb_exit(libusb_context *ctx); +void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +const struct libusb_version * LIBUSB_CALL libusb_get_version(void); +int LIBUSB_CALL libusb_has_capability(uint32_t capability); +const char * LIBUSB_CALL libusb_error_name(int errcode); +int LIBUSB_CALL libusb_setlocale(const char *locale); +const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode); + +ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, + libusb_device ***list); +void LIBUSB_CALL libusb_free_device_list(libusb_device **list, + int unref_devices); +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev); +void LIBUSB_CALL libusb_unref_device(libusb_device *dev); + +int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev, + int *config); +int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc); +int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config); +void LIBUSB_CALL libusb_free_config_descriptor( + struct libusb_config_descriptor *config); +int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor( + struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp); +void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor( + struct libusb_ss_endpoint_companion_descriptor *ep_comp); +int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *dev_handle, + struct libusb_bos_descriptor **bos); +void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos); +int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension); +void LIBUSB_CALL libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension); +int LIBUSB_CALL libusb_get_ss_usb_device_capability_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap); +void LIBUSB_CALL libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap); +int LIBUSB_CALL libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id); +void LIBUSB_CALL libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id); +uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_port_number(libusb_device *dev); +int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t* port_numbers, int port_numbers_len); +LIBUSB_DEPRECATED_FOR(libusb_get_port_numbers) +int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t* path, uint8_t path_length); +libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); +int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev); +int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint); + +int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **dev_handle); +void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle); +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle); + +int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev_handle, + int configuration); +int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev_handle, + int interface_number); + +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); + +int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev_handle, + int interface_number, int alternate_setting); +int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev_handle, + unsigned char endpoint); +int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev_handle); + +int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev_handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints); +int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev_handle, + unsigned char *endpoints, int num_endpoints); + +unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle, + size_t length); +int LIBUSB_CALL libusb_dev_mem_free(libusb_device_handle *dev_handle, + unsigned char *buffer, size_t length); + +int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_set_auto_detach_kernel_driver( + libusb_device_handle *dev_handle, int enable); + +/* async I/O */ + +/** \ingroup libusb_asyncio + * Get the data section of a control transfer. This convenience function is here + * to remind you that the data does not start until 8 bytes into the actual + * buffer, as the setup packet comes first. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns pointer to the first byte of the data section + */ +static inline unsigned char *libusb_control_transfer_get_data( + struct libusb_transfer *transfer) +{ + return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; +} + +/** \ingroup libusb_asyncio + * Get the control setup packet of a control transfer. This convenience + * function is here to remind you that the control setup occupies the first + * 8 bytes of the transfer data buffer. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns a casted pointer to the start of the transfer data buffer + */ +static inline struct libusb_control_setup *libusb_control_transfer_get_setup( + struct libusb_transfer *transfer) +{ + return (struct libusb_control_setup *)(void *) transfer->buffer; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the setup packet (first 8 bytes of the data + * buffer) for a control transfer. The wIndex, wValue and wLength values should + * be given in host-endian byte order. + * + * \param buffer buffer to output the setup packet into + * This pointer must be aligned to at least 2 bytes boundary. + * \param bmRequestType see the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field of + * \ref libusb_control_setup + * \param bRequest see the + * \ref libusb_control_setup::bRequest "bRequest" field of + * \ref libusb_control_setup + * \param wValue see the + * \ref libusb_control_setup::wValue "wValue" field of + * \ref libusb_control_setup + * \param wIndex see the + * \ref libusb_control_setup::wIndex "wIndex" field of + * \ref libusb_control_setup + * \param wLength see the + * \ref libusb_control_setup::wLength "wLength" field of + * \ref libusb_control_setup + */ +static inline void libusb_fill_control_setup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + setup->bmRequestType = bmRequestType; + setup->bRequest = bRequest; + setup->wValue = libusb_cpu_to_le16(wValue); + setup->wIndex = libusb_cpu_to_le16(wIndex); + setup->wLength = libusb_cpu_to_le16(wLength); +} + +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets); +int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer); +int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_transfer_set_stream_id( + struct libusb_transfer *transfer, uint32_t stream_id); +uint32_t LIBUSB_CALL libusb_transfer_get_stream_id( + struct libusb_transfer *transfer); + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a control transfer. + * + * If you pass a transfer buffer to this function, the first 8 bytes will + * be interpreted as a control setup packet, and the wLength field will be + * used to automatically populate the \ref libusb_transfer::length "length" + * field of the transfer. Therefore the recommended approach is: + * -# Allocate a suitably sized data buffer (including space for control setup) + * -# Call libusb_fill_control_setup() + * -# If this is a host-to-device transfer with a data stage, put the data + * in place after the setup packet + * -# Call this function + * -# Call libusb_submit_transfer() + * + * It is also legal to pass a NULL buffer to this function, in which case this + * function will not attempt to populate the length field. Remember that you + * must then populate the buffer and length fields later. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param buffer data buffer. If provided, this function will interpret the + * first 8 bytes as a setup packet and infer the transfer length from that. + * This pointer must be aligned to at least 2 bytes boundary. + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_control_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + transfer->dev_handle = dev_handle; + transfer->endpoint = 0; + transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; + transfer->timeout = timeout; + transfer->buffer = buffer; + if (setup) + transfer->length = (int) (LIBUSB_CONTROL_SETUP_SIZE + + libusb_le16_to_cpu(setup->wLength)); + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_BULK; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer using bulk streams. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param stream_id bulk stream id for this transfer + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_stream_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, uint32_t stream_id, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, + length, callback, user_data, timeout); + transfer->type = LIBUSB_TRANSFER_TYPE_BULK_STREAM; + libusb_transfer_set_stream_id(transfer, stream_id); +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an interrupt transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_interrupt_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an isochronous transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param num_iso_packets the number of isochronous packets + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, int num_iso_packets, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->num_iso_packets = num_iso_packets; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Convenience function to set the length of all packets in an isochronous + * transfer, based on the num_iso_packets field in the transfer structure. + * + * \param transfer a transfer + * \param length the length to set in each isochronous packet descriptor + * \see libusb_get_max_packet_size() + */ +static inline void libusb_set_iso_packet_lengths( + struct libusb_transfer *transfer, unsigned int length) +{ + int i; + for (i = 0; i < transfer->num_iso_packets; i++) + transfer->iso_packet_desc[i].length = length; +} + +/** \ingroup libusb_asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer. + * + * This is a thorough function which loops through all preceding packets, + * accumulating their lengths to find the position of the specified packet. + * Typically you will assign equal lengths to each packet in the transfer, + * and hence the above method is sub-optimal. You may wish to use + * libusb_get_iso_packet_buffer_simple() instead. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer_simple() + */ +static inline unsigned char *libusb_get_iso_packet_buffer( + struct libusb_transfer *transfer, unsigned int packet) +{ + int i; + size_t offset = 0; + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + for (i = 0; i < _packet; i++) + offset += transfer->iso_packet_desc[i].length; + + return transfer->buffer + offset; +} + +/** \ingroup libusb_asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer, for transfers where each + * packet is of identical size. + * + * This function relies on the assumption that every packet within the transfer + * is of identical size to the first packet. Calculating the location of + * the packet buffer is then just a simple calculation: + * buffer + (packet_size * packet) + * + * Do not use this function on transfers other than those that have identical + * packet lengths for each packet. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer() + */ +static inline unsigned char *libusb_get_iso_packet_buffer_simple( + struct libusb_transfer *transfer, unsigned int packet) +{ + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + return transfer->buffer + ((int) transfer->iso_packet_desc[0].length * _packet); +} + +/* sync I/O */ + +int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout); + +int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +/** \ingroup libusb_desc + * Retrieve a descriptor from the default control pipe. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. + * + * \param dev_handle a device handle + * \param desc_type the descriptor type, see \ref libusb_descriptor_type + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +static inline int libusb_get_descriptor(libusb_device_handle *dev_handle, + uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length) +{ + return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t) ((desc_type << 8) | desc_index), + 0, data, (uint16_t) length, 1000); +} + +/** \ingroup libusb_desc + * Retrieve a descriptor from a device. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. The string returned is Unicode, as + * detailed in the USB specifications. + * + * \param dev_handle a device handle + * \param desc_index the index of the descriptor to retrieve + * \param langid the language ID for the string descriptor + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + * \see libusb_get_string_descriptor_ascii() + */ +static inline int libusb_get_string_descriptor(libusb_device_handle *dev_handle, + uint8_t desc_index, uint16_t langid, unsigned char *data, int length) +{ + return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index), + langid, data, (uint16_t) length, 1000); +} + +int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle, + uint8_t desc_index, unsigned char *data, int length); + +/* polling and timeouts */ + +int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); +void LIBUSB_CALL libusb_interrupt_event_handler(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); +int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); + +int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed); +int LIBUSB_CALL libusb_handle_events(libusb_context *ctx); +int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed); +int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx); +int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv); + +/** \ingroup libusb_poll + * File descriptor for polling + */ +struct libusb_pollfd { + /** Numeric file descriptor */ + int fd; + + /** Event flags to poll for from . POLLIN indicates that you + * should monitor this file descriptor for becoming ready to read from, + * and POLLOUT indicates that you should monitor this file descriptor for + * nonblocking write readiness. */ + short events; +}; + +/** \ingroup libusb_poll + * Callback function, invoked when a new file descriptor should be added + * to the set of file descriptors monitored for events. + * \param fd the new file descriptor + * \param events events to monitor for, see \ref libusb_pollfd for a + * description + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events, + void *user_data); + +/** \ingroup libusb_poll + * Callback function, invoked when a file descriptor should be removed from + * the set of file descriptors being monitored for events. After returning + * from this callback, do not use that file descriptor again. + * \param fd the file descriptor to stop monitoring + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data); + +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx); +void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds); +void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data); + +/** \ingroup libusb_hotplug + * Callback handle. + * + * Callbacks handles are generated by libusb_hotplug_register_callback() + * and can be used to deregister callbacks. Callback handles are unique + * per libusb_context and it is safe to call libusb_hotplug_deregister_callback() + * on an already deregisted callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * For more information, see \ref libusb_hotplug. + */ +typedef int libusb_hotplug_callback_handle; + +/** \ingroup libusb_hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Flags for hotplug events */ +typedef enum { + /** Default value when not using any flags. */ + LIBUSB_HOTPLUG_NO_FLAGS = 0, + + /** Arm the callback and fire it for all matching currently attached devices. */ + LIBUSB_HOTPLUG_ENUMERATE = 1<<0, +} libusb_hotplug_flag; + +/** \ingroup libusb_hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Hotplug events */ +typedef enum { + /** A device has been plugged in and is ready to use */ + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01, + + /** A device has left and is no longer available. + * It is the user's responsibility to call libusb_close on any handle associated with a disconnected device. + * It is safe to call libusb_get_device_descriptor on a device that has left */ + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02, +} libusb_hotplug_event; + +/** \ingroup libusb_hotplug + * Wildcard matching for hotplug events */ +#define LIBUSB_HOTPLUG_MATCH_ANY -1 + +/** \ingroup libusb_hotplug + * Hotplug callback function type. When requesting hotplug event notifications, + * you pass a pointer to a callback function of this type. + * + * This callback may be called by an internal event thread and as such it is + * recommended the callback do minimal processing before returning. + * + * libusb will call this function later, when a matching event had happened on + * a matching device. See \ref libusb_hotplug for more information. + * + * It is safe to call either libusb_hotplug_register_callback() or + * libusb_hotplug_deregister_callback() from within a callback function. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param ctx context of this notification + * \param device libusb_device this event occurred on + * \param event event that occurred + * \param user_data user data provided when this callback was registered + * \returns bool whether this callback is finished processing events. + * returning 1 will cause this callback to be deregistered + */ +typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx, + libusb_device *device, + libusb_hotplug_event event, + void *user_data); + +/** \ingroup libusb_hotplug + * Register a hotplug callback function + * + * Register a callback with the libusb_context. The callback will fire + * when a matching event occurs on a matching device. The callback is + * armed until either it is deregistered with libusb_hotplug_deregister_callback() + * or the supplied callback returns 1 to indicate it is finished processing events. + * + * If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be + * called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices + * already plugged into the machine. Note that libusb modifies its internal + * device list from a separate thread, while calling hotplug callbacks from + * libusb_handle_events(), so it is possible for a device to already be present + * on, or removed from, its internal device list, while the hotplug callbacks + * still need to be dispatched. This means that when using \ref + * LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival + * of the same device, once from libusb_hotplug_register_callback() and once + * from libusb_handle_events(); and/or your callback may be called for the + * removal of a device for which an arrived call was never made. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context to register this callback with + * \param[in] events bitwise or of events that will trigger this callback. See \ref + * libusb_hotplug_event + * \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag + * \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] cb_fn the function to be invoked on a matching event/device + * \param[in] user_data user data to pass to the callback function + * \param[out] callback_handle pointer to store the handle of the allocated callback (can be NULL) + * \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure + */ +int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, + libusb_hotplug_event events, + libusb_hotplug_flag flags, + int vendor_id, int product_id, + int dev_class, + libusb_hotplug_callback_fn cb_fn, + void *user_data, + libusb_hotplug_callback_handle *callback_handle); + +/** \ingroup libusb_hotplug + * Deregisters a hotplug callback. + * + * Deregister a callback from a libusb_context. This function is safe to call from within + * a hotplug callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context this callback is registered with + * \param[in] callback_handle the handle of the callback to deregister + */ +void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx, + libusb_hotplug_callback_handle callback_handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/libusbi.h b/go-api-for-hardware-wallet/usbhid/c/libusb/libusbi.h new file mode 100644 index 00000000..752e3988 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/libusbi.h @@ -0,0 +1,1149 @@ +/* + * Internal header for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSBI_H +#define LIBUSBI_H + +#include + +#include + +#include +#include +#include +#include +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_MISSING_H +#include +#endif + +#include "libusb.h" +#include "version.h" + +/* Inside the libusb code, mark all public functions as follows: + * return_type API_EXPORTED function_name(params) { ... } + * But if the function returns a pointer, mark it as follows: + * DEFAULT_VISIBILITY return_type * LIBUSB_CALL function_name(params) { ... } + * In the libusb public header, mark all declarations as: + * return_type LIBUSB_CALL function_name(params); + */ +#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICE_DESC_LENGTH 18 + +#define USB_MAXENDPOINTS 32 +#define USB_MAXINTERFACES 32 +#define USB_MAXCONFIG 8 + +/* Backend specific capabilities */ +#define USBI_CAP_HAS_HID_ACCESS 0x00010000 +#define USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER 0x00020000 + +/* Maximum number of bytes in a log line */ +#define USBI_MAX_LOG_LEN 1024 +/* Terminator for log lines */ +#define USBI_LOG_LINE_END "\n" + +/* The following is used to silence warnings for unused variables */ +#define UNUSED(var) do { (void)(var); } while(0) + +#if !defined(ARRAYSIZE) +#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0])) +#endif + +struct list_head { + struct list_head *prev, *next; +}; + +/* Get an entry from the list + * ptr - the address of this list_head element in "type" + * type - the data type that contains "member" + * member - the list_head element in "type" + */ +#define list_entry(ptr, type, member) \ + ((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member))) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/* Get each entry from a list + * pos - A structure pointer has a "member" element + * head - list head + * member - the list_head element in "pos" + * type - the type of the first parameter + */ +#define list_for_each_entry(pos, head, member, type) \ + for (pos = list_entry((head)->next, type, member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, type, member)) + +#define list_for_each_entry_safe(pos, n, head, member, type) \ + for (pos = list_entry((head)->next, type, member), \ + n = list_entry(pos->member.next, type, member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, type, member)) + +#define list_empty(entry) ((entry)->next == (entry)) + +static inline void list_init(struct list_head *entry) +{ + entry->prev = entry->next = entry; +} + +static inline void list_add(struct list_head *entry, struct list_head *head) +{ + entry->next = head->next; + entry->prev = head; + + head->next->prev = entry; + head->next = entry; +} + +static inline void list_add_tail(struct list_head *entry, + struct list_head *head) +{ + entry->next = head; + entry->prev = head->prev; + + head->prev->next = entry; + head->prev = entry; +} + +static inline void list_del(struct list_head *entry) +{ + entry->next->prev = entry->prev; + entry->prev->next = entry->next; + entry->next = entry->prev = NULL; +} + +static inline void *usbi_reallocf(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + if (!ret) + free(ptr); + return ret; +} + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *mptr = (ptr); \ + (type *)( (char *)mptr - offsetof(type,member) );}) + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0) + +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#define TIMEVAL_TV_SEC_TYPE long +#else +#define TIMEVAL_TV_SEC_TYPE time_t +#endif + +/* Some platforms don't have this define */ +#ifndef TIMESPEC_TO_TIMEVAL +#define TIMESPEC_TO_TIMEVAL(tv, ts) \ + do { \ + (tv)->tv_sec = (TIMEVAL_TV_SEC_TYPE) (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ + } while (0) +#endif + +void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, ...); + +void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, va_list args); + +#if !defined(_MSC_VER) || _MSC_VER >= 1400 + +#ifdef ENABLE_LOGGING +#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __FUNCTION__, __VA_ARGS__) +#define usbi_dbg(...) _usbi_log(NULL, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__) +#else +#define _usbi_log(ctx, level, ...) do { (void)(ctx); } while(0) +#define usbi_dbg(...) do {} while(0) +#endif + +#define usbi_info(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_INFO, __VA_ARGS__) +#define usbi_warn(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__) +#define usbi_err(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__) + +#else /* !defined(_MSC_VER) || _MSC_VER >= 1400 */ + +#ifdef ENABLE_LOGGING +#define LOG_BODY(ctxt, level) \ +{ \ + va_list args; \ + va_start(args, format); \ + usbi_log_v(ctxt, level, "", format, args); \ + va_end(args); \ +} +#else +#define LOG_BODY(ctxt, level) \ +{ \ + (void)(ctxt); \ +} +#endif + +static inline void usbi_info(struct libusb_context *ctx, const char *format, ...) + LOG_BODY(ctx, LIBUSB_LOG_LEVEL_INFO) +static inline void usbi_warn(struct libusb_context *ctx, const char *format, ...) + LOG_BODY(ctx, LIBUSB_LOG_LEVEL_WARNING) +static inline void usbi_err(struct libusb_context *ctx, const char *format, ...) + LOG_BODY(ctx, LIBUSB_LOG_LEVEL_ERROR) + +static inline void usbi_dbg(const char *format, ...) + LOG_BODY(NULL, LIBUSB_LOG_LEVEL_DEBUG) + +#endif /* !defined(_MSC_VER) || _MSC_VER >= 1400 */ + +#define USBI_GET_CONTEXT(ctx) \ + do { \ + if (!(ctx)) \ + (ctx) = usbi_default_context; \ + } while(0) + +#define DEVICE_CTX(dev) ((dev)->ctx) +#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev)) +#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle)) +#define ITRANSFER_CTX(transfer) \ + (TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer))) + +#define IS_EPIN(ep) (0 != ((ep) & LIBUSB_ENDPOINT_IN)) +#define IS_EPOUT(ep) (!IS_EPIN(ep)) +#define IS_XFERIN(xfer) (0 != ((xfer)->endpoint & LIBUSB_ENDPOINT_IN)) +#define IS_XFEROUT(xfer) (!IS_XFERIN(xfer)) + +/* Internal abstraction for thread synchronization */ +#if defined(THREADS_POSIX) +#include "os/threads_posix.h" +#elif defined(OS_WINDOWS) || defined(OS_WINCE) +#include "os/threads_windows.h" +#endif + +extern struct libusb_context *usbi_default_context; + +/* Forward declaration for use in context (fully defined inside poll abstraction) */ +struct pollfd; + +struct libusb_context { + int debug; + int debug_fixed; + + /* internal event pipe, used for signalling occurrence of an internal event. */ + int event_pipe[2]; + + struct list_head usb_devs; + usbi_mutex_t usb_devs_lock; + + /* A list of open handles. Backends are free to traverse this if required. + */ + struct list_head open_devs; + usbi_mutex_t open_devs_lock; + + /* A list of registered hotplug callbacks */ + struct list_head hotplug_cbs; + usbi_mutex_t hotplug_cbs_lock; + + /* this is a list of in-flight transfer handles, sorted by timeout + * expiration. URBs to timeout the soonest are placed at the beginning of + * the list, URBs that will time out later are placed after, and urbs with + * infinite timeout are always placed at the very end. */ + struct list_head flying_transfers; + /* Note paths taking both this and usbi_transfer->lock must always + * take this lock first */ + usbi_mutex_t flying_transfers_lock; + + /* user callbacks for pollfd changes */ + libusb_pollfd_added_cb fd_added_cb; + libusb_pollfd_removed_cb fd_removed_cb; + void *fd_cb_user_data; + + /* ensures that only one thread is handling events at any one time */ + usbi_mutex_t events_lock; + + /* used to see if there is an active thread doing event handling */ + int event_handler_active; + + /* A thread-local storage key to track which thread is performing event + * handling */ + usbi_tls_key_t event_handling_key; + + /* used to wait for event completion in threads other than the one that is + * event handling */ + usbi_mutex_t event_waiters_lock; + usbi_cond_t event_waiters_cond; + + /* A lock to protect internal context event data. */ + usbi_mutex_t event_data_lock; + + /* A bitmask of flags that are set to indicate specific events that need to + * be handled. Protected by event_data_lock. */ + unsigned int event_flags; + + /* A counter that is set when we want to interrupt and prevent event handling, + * in order to safely close a device. Protected by event_data_lock. */ + unsigned int device_close; + + /* list and count of poll fds and an array of poll fd structures that is + * (re)allocated as necessary prior to polling. Protected by event_data_lock. */ + struct list_head ipollfds; + struct pollfd *pollfds; + POLL_NFDS_TYPE pollfds_cnt; + + /* A list of pending hotplug messages. Protected by event_data_lock. */ + struct list_head hotplug_msgs; + + /* A list of pending completed transfers. Protected by event_data_lock. */ + struct list_head completed_transfers; + +#ifdef USBI_TIMERFD_AVAILABLE + /* used for timeout handling, if supported by OS. + * this timerfd is maintained to trigger on the next pending timeout */ + int timerfd; +#endif + + struct list_head list; +}; + +enum usbi_event_flags { + /* The list of pollfds has been modified */ + USBI_EVENT_POLLFDS_MODIFIED = 1 << 0, + + /* The user has interrupted the event handler */ + USBI_EVENT_USER_INTERRUPT = 1 << 1, +}; + +/* Macros for managing event handling state */ +#define usbi_handling_events(ctx) \ + (usbi_tls_key_get((ctx)->event_handling_key) != NULL) + +#define usbi_start_event_handling(ctx) \ + usbi_tls_key_set((ctx)->event_handling_key, ctx) + +#define usbi_end_event_handling(ctx) \ + usbi_tls_key_set((ctx)->event_handling_key, NULL) + +/* Update the following macro if new event sources are added */ +#define usbi_pending_events(ctx) \ + ((ctx)->event_flags || (ctx)->device_close \ + || !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers)) + +#ifdef USBI_TIMERFD_AVAILABLE +#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0) +#else +#define usbi_using_timerfd(ctx) (0) +#endif + +struct libusb_device { + /* lock protects refcnt, everything else is finalized at initialization + * time */ + usbi_mutex_t lock; + int refcnt; + + struct libusb_context *ctx; + + uint8_t bus_number; + uint8_t port_number; + struct libusb_device* parent_dev; + uint8_t device_address; + uint8_t num_configurations; + enum libusb_speed speed; + + struct list_head list; + unsigned long session_data; + + struct libusb_device_descriptor device_descriptor; + int attached; + + unsigned char os_priv +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif +#if defined(OS_SUNOS) + __attribute__ ((aligned (8))); +#else + ; +#endif +}; + +struct libusb_device_handle { + /* lock protects claimed_interfaces */ + usbi_mutex_t lock; + unsigned long claimed_interfaces; + + struct list_head list; + struct libusb_device *dev; + int auto_detach_kernel_driver; + unsigned char os_priv +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif +#if defined(OS_SUNOS) + __attribute__ ((aligned (8))); +#else + ; +#endif +}; + +enum { + USBI_CLOCK_MONOTONIC, + USBI_CLOCK_REALTIME +}; + +/* in-memory transfer layout: + * + * 1. struct usbi_transfer + * 2. struct libusb_transfer (which includes iso packets) [variable size] + * 3. os private data [variable size] + * + * from a libusb_transfer, you can get the usbi_transfer by rewinding the + * appropriate number of bytes. + * the usbi_transfer includes the number of allocated packets, so you can + * determine the size of the transfer and hence the start and length of the + * OS-private data. + */ + +struct usbi_transfer { + int num_iso_packets; + struct list_head list; + struct list_head completed_list; + struct timeval timeout; + int transferred; + uint32_t stream_id; + uint8_t state_flags; /* Protected by usbi_transfer->lock */ + uint8_t timeout_flags; /* Protected by the flying_stransfers_lock */ + + /* this lock is held during libusb_submit_transfer() and + * libusb_cancel_transfer() (allowing the OS backend to prevent duplicate + * cancellation, submission-during-cancellation, etc). the OS backend + * should also take this lock in the handle_events path, to prevent the user + * cancelling the transfer from another thread while you are processing + * its completion (presumably there would be races within your OS backend + * if this were possible). + * Note paths taking both this and the flying_transfers_lock must + * always take the flying_transfers_lock first */ + usbi_mutex_t lock; +}; + +enum usbi_transfer_state_flags { + /* Transfer successfully submitted by backend */ + USBI_TRANSFER_IN_FLIGHT = 1 << 0, + + /* Cancellation was requested via libusb_cancel_transfer() */ + USBI_TRANSFER_CANCELLING = 1 << 1, + + /* Operation on the transfer failed because the device disappeared */ + USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 2, +}; + +enum usbi_transfer_timeout_flags { + /* Set by backend submit_transfer() if the OS handles timeout */ + USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1 << 0, + + /* The transfer timeout has been handled */ + USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 1, + + /* The transfer timeout was successfully processed */ + USBI_TRANSFER_TIMED_OUT = 1 << 2, +}; + +#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \ + ((struct libusb_transfer *)(((unsigned char *)(transfer)) \ + + sizeof(struct usbi_transfer))) +#define LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer) \ + ((struct usbi_transfer *)(((unsigned char *)(transfer)) \ + - sizeof(struct usbi_transfer))) + +static inline void *usbi_transfer_get_os_priv(struct usbi_transfer *transfer) +{ + return ((unsigned char *)transfer) + sizeof(struct usbi_transfer) + + sizeof(struct libusb_transfer) + + (transfer->num_iso_packets + * sizeof(struct libusb_iso_packet_descriptor)); +} + +/* bus structures */ + +/* All standard descriptors have these 2 fields in common */ +struct usb_descriptor_header { + uint8_t bLength; + uint8_t bDescriptorType; +}; + +/* shared data and functions */ + +int usbi_io_init(struct libusb_context *ctx); +void usbi_io_exit(struct libusb_context *ctx); + +struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, + unsigned long session_id); +struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, + unsigned long session_id); +int usbi_sanitize_device(struct libusb_device *dev); +void usbi_handle_disconnect(struct libusb_device_handle *dev_handle); + +int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, + enum libusb_transfer_status status); +int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer); +void usbi_signal_transfer_completion(struct usbi_transfer *transfer); + +int usbi_parse_descriptor(const unsigned char *source, const char *descriptor, + void *dest, int host_endian); +int usbi_device_cache_descriptor(libusb_device *dev); +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx); + +void usbi_connect_device (struct libusb_device *dev); +void usbi_disconnect_device (struct libusb_device *dev); + +int usbi_signal_event(struct libusb_context *ctx); +int usbi_clear_event(struct libusb_context *ctx); + +/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */ +#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) ||\ + defined(OS_HAIKU) || defined(OS_SUNOS) +#include +#include "os/poll_posix.h" +#elif defined(OS_WINDOWS) || defined(OS_WINCE) +#include "os/poll_windows.h" +#endif + +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define snprintf usbi_snprintf +#define vsnprintf usbi_vsnprintf +int usbi_snprintf(char *dst, size_t size, const char *format, ...); +int usbi_vsnprintf(char *dst, size_t size, const char *format, va_list ap); +#define LIBUSB_PRINTF_WIN32 +#endif + +struct usbi_pollfd { + /* must come first */ + struct libusb_pollfd pollfd; + + struct list_head list; +}; + +int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events); +void usbi_remove_pollfd(struct libusb_context *ctx, int fd); + +/* device discovery */ + +/* we traverse usbfs without knowing how many devices we are going to find. + * so we create this discovered_devs model which is similar to a linked-list + * which grows when required. it can be freed once discovery has completed, + * eliminating the need for a list node in the libusb_device structure + * itself. */ +struct discovered_devs { + size_t len; + size_t capacity; + struct libusb_device *devices +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +struct discovered_devs *discovered_devs_append( + struct discovered_devs *discdevs, struct libusb_device *dev); + +/* OS abstraction */ + +/* This is the interface that OS backends need to implement. + * All fields are mandatory, except ones explicitly noted as optional. */ +struct usbi_os_backend { + /* A human-readable name for your backend, e.g. "Linux usbfs" */ + const char *name; + + /* Binary mask for backend specific capabilities */ + uint32_t caps; + + /* Perform initialization of your backend. You might use this function + * to determine specific capabilities of the system, allocate required + * data structures for later, etc. + * + * This function is called when a libusb user initializes the library + * prior to use. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*init)(struct libusb_context *ctx); + + /* Deinitialization. Optional. This function should destroy anything + * that was set up by init. + * + * This function is called when the user deinitializes the library. + */ + void (*exit)(void); + + /* Enumerate all the USB devices on the system, returning them in a list + * of discovered devices. + * + * Your implementation should enumerate all devices on the system, + * regardless of whether they have been seen before or not. + * + * When you have found a device, compute a session ID for it. The session + * ID should uniquely represent that particular device for that particular + * connection session since boot (i.e. if you disconnect and reconnect a + * device immediately after, it should be assigned a different session ID). + * If your OS cannot provide a unique session ID as described above, + * presenting a session ID of (bus_number << 8 | device_address) should + * be sufficient. Bus numbers and device addresses wrap and get reused, + * but that is an unlikely case. + * + * After computing a session ID for a device, call + * usbi_get_device_by_session_id(). This function checks if libusb already + * knows about the device, and if so, it provides you with a reference + * to a libusb_device structure for it. + * + * If usbi_get_device_by_session_id() returns NULL, it is time to allocate + * a new device structure for the device. Call usbi_alloc_device() to + * obtain a new libusb_device structure with reference count 1. Populate + * the bus_number and device_address attributes of the new device, and + * perform any other internal backend initialization you need to do. At + * this point, you should be ready to provide device descriptors and so + * on through the get_*_descriptor functions. Finally, call + * usbi_sanitize_device() to perform some final sanity checks on the + * device. Assuming all of the above succeeded, we can now continue. + * If any of the above failed, remember to unreference the device that + * was returned by usbi_alloc_device(). + * + * At this stage we have a populated libusb_device structure (either one + * that was found earlier, or one that we have just allocated and + * populated). This can now be added to the discovered devices list + * using discovered_devs_append(). Note that discovered_devs_append() + * may reallocate the list, returning a new location for it, and also + * note that reallocation can fail. Your backend should handle these + * error conditions appropriately. + * + * This function should not generate any bus I/O and should not block. + * If I/O is required (e.g. reading the active configuration value), it is + * OK to ignore these suggestions :) + * + * This function is executed when the user wishes to retrieve a list + * of USB devices connected to the system. + * + * If the backend has hotplug support, this function is not used! + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*get_device_list)(struct libusb_context *ctx, + struct discovered_devs **discdevs); + + /* Apps which were written before hotplug support, may listen for + * hotplug events on their own and call libusb_get_device_list on + * device addition. In this case libusb_get_device_list will likely + * return a list without the new device in there, as the hotplug + * event thread will still be busy enumerating the device, which may + * take a while, or may not even have seen the event yet. + * + * To avoid this libusb_get_device_list will call this optional + * function for backends with hotplug support before copying + * ctx->usb_devs to the user. In this function the backend should + * ensure any pending hotplug events are fully processed before + * returning. + * + * Optional, should be implemented by backends with hotplug support. + */ + void (*hotplug_poll)(void); + + /* Open a device for I/O and other USB operations. The device handle + * is preallocated for you, you can retrieve the device in question + * through handle->dev. + * + * Your backend should allocate any internal resources required for I/O + * and other operations so that those operations can happen (hopefully) + * without hiccup. This is also a good place to inform libusb that it + * should monitor certain file descriptors related to this device - + * see the usbi_add_pollfd() function. + * + * This function should not generate any bus I/O and should not block. + * + * This function is called when the user attempts to obtain a device + * handle for a device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_ACCESS if the user has insufficient permissions + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since + * discovery + * - another LIBUSB_ERROR code on other failure + * + * Do not worry about freeing the handle on failed open, the upper layers + * do this for you. + */ + int (*open)(struct libusb_device_handle *dev_handle); + + /* Close a device such that the handle cannot be used again. Your backend + * should destroy any resources that were allocated in the open path. + * This may also be a good place to call usbi_remove_pollfd() to inform + * libusb of any file descriptors associated with this device that should + * no longer be monitored. + * + * This function is called when the user closes a device handle. + */ + void (*close)(struct libusb_device_handle *dev_handle); + + /* Retrieve the device descriptor from a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. Alternatively, you may be able + * to retrieve it from a kernel interface (some Linux setups can do this) + * still without generating bus I/O. + * + * This function is expected to write DEVICE_DESC_LENGTH (18) bytes into + * buffer, which is guaranteed to be big enough. + * + * This function is called when sanity-checking a device before adding + * it to the list of discovered devices, and also when the user requests + * to read the device descriptor. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return 0 on success or a LIBUSB_ERROR code on failure. + */ + int (*get_device_descriptor)(struct libusb_device *device, + unsigned char *buffer, int *host_endian); + + /* Get the ACTIVE configuration descriptor for a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. You may also have to keep track + * of which configuration is active when the user changes it. + * + * This function is expected to write len bytes of data into buffer, which + * is guaranteed to be big enough. If you can only do a partial write, + * return an error code. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state + * - another LIBUSB_ERROR code on other failure + */ + int (*get_active_config_descriptor)(struct libusb_device *device, + unsigned char *buffer, size_t len, int *host_endian); + + /* Get a specific configuration descriptor for a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. + * + * The requested descriptor is expressed as a zero-based index (i.e. 0 + * indicates that we are requesting the first descriptor). The index does + * not (necessarily) equal the bConfigurationValue of the configuration + * being requested. + * + * This function is expected to write len bytes of data into buffer, which + * is guaranteed to be big enough. If you can only do a partial write, + * return an error code. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return the length read on success or a LIBUSB_ERROR code on failure. + */ + int (*get_config_descriptor)(struct libusb_device *device, + uint8_t config_index, unsigned char *buffer, size_t len, + int *host_endian); + + /* Like get_config_descriptor but then by bConfigurationValue instead + * of by index. + * + * Optional, if not present the core will call get_config_descriptor + * for all configs until it finds the desired bConfigurationValue. + * + * Returns a pointer to the raw-descriptor in *buffer, this memory + * is valid as long as device is valid. + * + * Returns the length of the returned raw-descriptor on success, + * or a LIBUSB_ERROR code on failure. + */ + int (*get_config_descriptor_by_value)(struct libusb_device *device, + uint8_t bConfigurationValue, unsigned char **buffer, + int *host_endian); + + /* Get the bConfigurationValue for the active configuration for a device. + * Optional. This should only be implemented if you can retrieve it from + * cache (don't generate I/O). + * + * If you cannot retrieve this from cache, either do not implement this + * function, or return LIBUSB_ERROR_NOT_SUPPORTED. This will cause + * libusb to retrieve the information through a standard control transfer. + * + * This function must be non-blocking. + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - LIBUSB_ERROR_NOT_SUPPORTED if the value cannot be retrieved without + * blocking + * - another LIBUSB_ERROR code on other failure. + */ + int (*get_configuration)(struct libusb_device_handle *dev_handle, int *config); + + /* Set the active configuration for a device. + * + * A configuration value of -1 should put the device in unconfigured state. + * + * This function can block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * - LIBUSB_ERROR_BUSY if interfaces are currently claimed (and hence + * configuration cannot be changed) + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure. + */ + int (*set_configuration)(struct libusb_device_handle *dev_handle, int config); + + /* Claim an interface. When claimed, the application can then perform + * I/O to an interface's endpoints. + * + * This function should not generate any bus I/O and should not block. + * Interface claiming is a logical operation that simply ensures that + * no other drivers/applications are using the interface, and after + * claiming, no other drivers/applications can use the interface because + * we now "own" it. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the interface does not exist + * - LIBUSB_ERROR_BUSY if the interface is in use by another driver/app + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*claim_interface)(struct libusb_device_handle *dev_handle, int interface_number); + + /* Release a previously claimed interface. + * + * This function should also generate a SET_INTERFACE control request, + * resetting the alternate setting of that interface to 0. It's OK for + * this function to block as a result. + * + * You will only ever be asked to release an interface which was + * successfully claimed earlier. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*release_interface)(struct libusb_device_handle *dev_handle, int interface_number); + + /* Set the alternate setting for an interface. + * + * You will only ever be asked to set the alternate setting for an + * interface which was successfully claimed earlier. + * + * It's OK for this function to block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the alternate setting does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle, + int interface_number, int altsetting); + + /* Clear a halt/stall condition on an endpoint. + * + * It's OK for this function to block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*clear_halt)(struct libusb_device_handle *dev_handle, + unsigned char endpoint); + + /* Perform a USB port reset to reinitialize a device. + * + * If possible, the device handle should still be usable after the reset + * completes, assuming that the device descriptors did not change during + * reset and all previous interface state can be restored. + * + * If something changes, or you cannot easily locate/verify the resetted + * device, return LIBUSB_ERROR_NOT_FOUND. This prompts the application + * to close the old handle and re-enumerate the device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the device + * has been disconnected since it was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*reset_device)(struct libusb_device_handle *dev_handle); + + /* Alloc num_streams usb3 bulk streams on the passed in endpoints */ + int (*alloc_streams)(struct libusb_device_handle *dev_handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints); + + /* Free usb3 bulk streams allocated with alloc_streams */ + int (*free_streams)(struct libusb_device_handle *dev_handle, + unsigned char *endpoints, int num_endpoints); + + /* Allocate persistent DMA memory for the given device, suitable for + * zerocopy. May return NULL on failure. Optional to implement. + */ + unsigned char *(*dev_mem_alloc)(struct libusb_device_handle *handle, + size_t len); + + /* Free memory allocated by dev_mem_alloc. */ + int (*dev_mem_free)(struct libusb_device_handle *handle, + unsigned char *buffer, size_t len); + + /* Determine if a kernel driver is active on an interface. Optional. + * + * The presence of a kernel driver on an interface indicates that any + * calls to claim_interface would fail with the LIBUSB_ERROR_BUSY code. + * + * Return: + * - 0 if no driver is active + * - 1 if a driver is active + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*kernel_driver_active)(struct libusb_device_handle *dev_handle, + int interface_number); + + /* Detach a kernel driver from an interface. Optional. + * + * After detaching a kernel driver, the interface should be available + * for claim. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*detach_kernel_driver)(struct libusb_device_handle *dev_handle, + int interface_number); + + /* Attach a kernel driver to an interface. Optional. + * + * Reattach a kernel driver to the device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - LIBUSB_ERROR_BUSY if a program or driver has claimed the interface, + * preventing reattachment + * - another LIBUSB_ERROR code on other failure + */ + int (*attach_kernel_driver)(struct libusb_device_handle *dev_handle, + int interface_number); + + /* Destroy a device. Optional. + * + * This function is called when the last reference to a device is + * destroyed. It should free any resources allocated in the get_device_list + * path. + */ + void (*destroy_device)(struct libusb_device *dev); + + /* Submit a transfer. Your implementation should take the transfer, + * morph it into whatever form your platform requires, and submit it + * asynchronously. + * + * This function must not block. + * + * This function gets called with the flying_transfers_lock locked! + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * - another LIBUSB_ERROR code on other failure + */ + int (*submit_transfer)(struct usbi_transfer *itransfer); + + /* Cancel a previously submitted transfer. + * + * This function must not block. The transfer cancellation must complete + * later, resulting in a call to usbi_handle_transfer_cancellation() + * from the context of handle_events. + */ + int (*cancel_transfer)(struct usbi_transfer *itransfer); + + /* Clear a transfer as if it has completed or cancelled, but do not + * report any completion/cancellation to the library. You should free + * all private data from the transfer as if you were just about to report + * completion or cancellation. + * + * This function might seem a bit out of place. It is used when libusb + * detects a disconnected device - it calls this function for all pending + * transfers before reporting completion (with the disconnect code) to + * the user. Maybe we can improve upon this internal interface in future. + */ + void (*clear_transfer_priv)(struct usbi_transfer *itransfer); + + /* Handle any pending events on file descriptors. Optional. + * + * Provide this function when file descriptors directly indicate device + * or transfer activity. If your backend does not have such file descriptors, + * implement the handle_transfer_completion function below. + * + * This involves monitoring any active transfers and processing their + * completion or cancellation. + * + * The function is passed an array of pollfd structures (size nfds) + * as a result of the poll() system call. The num_ready parameter + * indicates the number of file descriptors that have reported events + * (i.e. the poll() return value). This should be enough information + * for you to determine which actions need to be taken on the currently + * active transfers. + * + * For any cancelled transfers, call usbi_handle_transfer_cancellation(). + * For completed transfers, call usbi_handle_transfer_completion(). + * For control/bulk/interrupt transfers, populate the "transferred" + * element of the appropriate usbi_transfer structure before calling the + * above functions. For isochronous transfers, populate the status and + * transferred fields of the iso packet descriptors of the transfer. + * + * This function should also be able to detect disconnection of the + * device, reporting that situation with usbi_handle_disconnect(). + * + * When processing an event related to a transfer, you probably want to + * take usbi_transfer.lock to prevent races. See the documentation for + * the usbi_transfer structure. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*handle_events)(struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready); + + /* Handle transfer completion. Optional. + * + * Provide this function when there are no file descriptors available + * that directly indicate device or transfer activity. If your backend does + * have such file descriptors, implement the handle_events function above. + * + * Your backend must tell the library when a transfer has completed by + * calling usbi_signal_transfer_completion(). You should store any private + * information about the transfer and its completion status in the transfer's + * private backend data. + * + * During event handling, this function will be called on each transfer for + * which usbi_signal_transfer_completion() was called. + * + * For any cancelled transfers, call usbi_handle_transfer_cancellation(). + * For completed transfers, call usbi_handle_transfer_completion(). + * For control/bulk/interrupt transfers, populate the "transferred" + * element of the appropriate usbi_transfer structure before calling the + * above functions. For isochronous transfers, populate the status and + * transferred fields of the iso packet descriptors of the transfer. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*handle_transfer_completion)(struct usbi_transfer *itransfer); + + /* Get time from specified clock. At least two clocks must be implemented + by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC. + + Description of clocks: + USBI_CLOCK_REALTIME : clock returns time since system epoch. + USBI_CLOCK_MONOTONIC: clock returns time since unspecified start + time (usually boot). + */ + int (*clock_gettime)(int clkid, struct timespec *tp); + +#ifdef USBI_TIMERFD_AVAILABLE + /* clock ID of the clock that should be used for timerfd */ + clockid_t (*get_timerfd_clockid)(void); +#endif + + /* Number of bytes to reserve for per-device private backend data. + * This private data area is accessible through the "os_priv" field of + * struct libusb_device. */ + size_t device_priv_size; + + /* Number of bytes to reserve for per-handle private backend data. + * This private data area is accessible through the "os_priv" field of + * struct libusb_device. */ + size_t device_handle_priv_size; + + /* Number of bytes to reserve for per-transfer private backend data. + * This private data area is accessible by calling + * usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance. + */ + size_t transfer_priv_size; +}; + +extern const struct usbi_os_backend * const usbi_backend; + +extern const struct usbi_os_backend linux_usbfs_backend; +extern const struct usbi_os_backend darwin_backend; +extern const struct usbi_os_backend openbsd_backend; +extern const struct usbi_os_backend netbsd_backend; +extern const struct usbi_os_backend windows_backend; +extern const struct usbi_os_backend usbdk_backend; +extern const struct usbi_os_backend wince_backend; +extern const struct usbi_os_backend haiku_usb_raw_backend; +extern const struct usbi_os_backend sunos_backend; + +extern struct list_head active_contexts_list; +extern usbi_mutex_static_t active_contexts_lock; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.c new file mode 100644 index 00000000..b0219d1b --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.c @@ -0,0 +1,2094 @@ +/* -*- Mode: C; indent-tabs-mode:nil -*- */ +/* + * darwin backend for libusb 1.0 + * Copyright © 2008-2016 Nathan Hjelm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + #include +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 +/* Apple deprecated the darwin atomics in 10.12 in favor of C11 atomics */ +#include +#define libusb_darwin_atomic_fetch_add(x, y) atomic_fetch_add(x, y) + +_Atomic int32_t initCount = ATOMIC_VAR_INIT(0); +#else +/* use darwin atomics if the target is older than 10.12 */ +#include + +/* OSAtomicAdd32Barrier returns the new value */ +#define libusb_darwin_atomic_fetch_add(x, y) (OSAtomicAdd32Barrier(y, x) - y) + +static volatile int32_t initCount = 0; +#endif + +#include "darwin_usb.h" + +/* async event thread */ +static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER; + +static pthread_once_t darwin_init_once = PTHREAD_ONCE_INIT; + +static clock_serv_t clock_realtime; +static clock_serv_t clock_monotonic; + +static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */ +static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */ + +static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER; +static struct list_head darwin_cached_devices = {&darwin_cached_devices, &darwin_cached_devices}; +static char *darwin_device_class = kIOUSBDeviceClassName; + +#define DARWIN_CACHED_DEVICE(a) ((struct darwin_cached_device *) (((struct darwin_device_priv *)((a)->os_priv))->dev)) + +/* async event thread */ +static pthread_t libusb_darwin_at; + +static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian); +static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface); +static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface); +static int darwin_reset_device(struct libusb_device_handle *dev_handle); +static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0); + +static int darwin_scan_devices(struct libusb_context *ctx); +static int process_new_device (struct libusb_context *ctx, io_service_t service); + +#if defined(ENABLE_LOGGING) +static const char *darwin_error_str (int result) { + static char string_buffer[50]; + switch (result) { + case kIOReturnSuccess: + return "no error"; + case kIOReturnNotOpen: + return "device not opened for exclusive access"; + case kIOReturnNoDevice: + return "no connection to an IOService"; + case kIOUSBNoAsyncPortErr: + return "no async port has been opened for interface"; + case kIOReturnExclusiveAccess: + return "another process has device opened for exclusive access"; + case kIOUSBPipeStalled: + return "pipe is stalled"; + case kIOReturnError: + return "could not establish a connection to the Darwin kernel"; + case kIOUSBTransactionTimeout: + return "transaction timed out"; + case kIOReturnBadArgument: + return "invalid argument"; + case kIOReturnAborted: + return "transaction aborted"; + case kIOReturnNotResponding: + return "device not responding"; + case kIOReturnOverrun: + return "data overrun"; + case kIOReturnCannotWire: + return "physical memory can not be wired down"; + case kIOReturnNoResources: + return "out of resources"; + case kIOUSBHighSpeedSplitError: + return "high speed split error"; + default: + snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result); + return string_buffer; + } +} +#endif + +static int darwin_to_libusb (int result) { + switch (result) { + case kIOReturnUnderrun: + case kIOReturnSuccess: + return LIBUSB_SUCCESS; + case kIOReturnNotOpen: + case kIOReturnNoDevice: + return LIBUSB_ERROR_NO_DEVICE; + case kIOReturnExclusiveAccess: + return LIBUSB_ERROR_ACCESS; + case kIOUSBPipeStalled: + return LIBUSB_ERROR_PIPE; + case kIOReturnBadArgument: + return LIBUSB_ERROR_INVALID_PARAM; + case kIOUSBTransactionTimeout: + return LIBUSB_ERROR_TIMEOUT; + case kIOReturnNotResponding: + case kIOReturnAborted: + case kIOReturnError: + case kIOUSBNoAsyncPortErr: + default: + return LIBUSB_ERROR_OTHER; + } +} + +/* this function must be called with the darwin_cached_devices_lock held */ +static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) { + cached_dev->refcount--; + /* free the device and remove it from the cache */ + if (0 == cached_dev->refcount) { + list_del(&cached_dev->list); + + (*(cached_dev->device))->Release(cached_dev->device); + free (cached_dev); + } +} + +static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) { + cached_dev->refcount++; +} + +static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, uint8_t *pipep, uint8_t *ifcp, struct darwin_interface **interface_out) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + + /* current interface */ + struct darwin_interface *cInterface; + + int8_t i, iface; + + usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep); + + for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) { + cInterface = &priv->interfaces[iface]; + + if (dev_handle->claimed_interfaces & (1 << iface)) { + for (i = 0 ; i < cInterface->num_endpoints ; i++) { + if (cInterface->endpoint_addrs[i] == ep) { + *pipep = i + 1; + + if (ifcp) + *ifcp = iface; + + if (interface_out) + *interface_out = cInterface; + + usbi_dbg ("pipe %d on interface %d matches", *pipep, iface); + return 0; + } + } + } + } + + /* No pipe found with the correct endpoint address */ + usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep); + + return LIBUSB_ERROR_NOT_FOUND; +} + +static int usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) { + CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class); + + if (!matchingDict) + return kIOReturnError; + + if (location) { + CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (propertyMatchDict) { + /* there are no unsigned CFNumber types so treat the value as signed. the os seems to do this + internally (CFNumberType of locationID is 3) */ + CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location); + + CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF); + /* release our reference to the CFNumber (CFDictionarySetValue retains it) */ + CFRelease (locationCF); + + CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict); + /* release out reference to the CFMutableDictionaryRef (CFDictionarySetValue retains it) */ + CFRelease (propertyMatchDict); + } + /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */ + } + + return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator); +} + +/* Returns 1 on success, 0 on failure. */ +static int get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) { + CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0); + int ret = 0; + + if (cfNumber) { + if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) { + ret = CFNumberGetValue(cfNumber, type, p); + } + + CFRelease (cfNumber); + } + + return ret; +} + +static int get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) { + CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0); + int ret = 0; + + if (cfData) { + if (CFGetTypeID (cfData) == CFDataGetTypeID ()) { + CFIndex length = CFDataGetLength (cfData); + if (length < size) { + size = length; + } + + CFDataGetBytes (cfData, CFRangeMake(0, size), p); + ret = 1; + } + + CFRelease (cfData); + } + + return ret; +} + +static usb_device_t **darwin_device_from_service (io_service_t service) +{ + io_cf_plugin_ref_t *plugInInterface = NULL; + usb_device_t **device; + kern_return_t result; + SInt32 score; + + result = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, &plugInInterface, + &score); + + if (kIOReturnSuccess != result || !plugInInterface) { + usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (result)); + return NULL; + } + + (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID), + (LPVOID)&device); + /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */ + (*plugInInterface)->Release (plugInInterface); + + return device; +} + +static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) { + struct libusb_context *ctx; + io_service_t service; + + usbi_mutex_lock(&active_contexts_lock); + + while ((service = IOIteratorNext(add_devices))) { + /* add this device to each active context's device list */ + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + process_new_device (ctx, service);; + } + + IOObjectRelease(service); + } + + usbi_mutex_unlock(&active_contexts_lock); +} + +static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { + struct libusb_device *dev = NULL; + struct libusb_context *ctx; + struct darwin_cached_device *old_device; + + io_service_t device; + UInt64 session; + int ret; + + usbi_mutex_lock(&active_contexts_lock); + + while ((device = IOIteratorNext (rem_devices)) != 0) { + /* get the location from the i/o registry */ + ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session); + IOObjectRelease (device); + if (!ret) + continue; + + /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function + otherwise no cached device will ever get freed */ + usbi_mutex_lock(&darwin_cached_devices_lock); + list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) { + if (old_device->session == session) { + darwin_deref_cached_device (old_device); + break; + } + } + usbi_mutex_unlock(&darwin_cached_devices_lock); + + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + usbi_dbg ("notifying context %p of device disconnect", ctx); + + dev = usbi_get_device_by_session_id(ctx, (unsigned long) session); + if (dev) { + /* signal the core that this device has been disconnected. the core will tear down this device + when the reference count reaches 0 */ + usbi_disconnect_device(dev); + libusb_unref_device(dev); + } + } + } + + usbi_mutex_unlock(&active_contexts_lock); +} + +static void darwin_hotplug_poll (void) +{ + /* not sure if 5 seconds will be too long/short but it should work ok */ + mach_timespec_t timeout = {.tv_sec = 5, .tv_nsec = 0}; + + /* since a kernel thread may nodify the IOInterators used for + * hotplug notidication we can't just clear the iterators. + * instead just wait until all IOService providers are quiet */ + (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout); +} + +static void darwin_clear_iterator (io_iterator_t iter) { + io_service_t device; + + while ((device = IOIteratorNext (iter)) != 0) + IOObjectRelease (device); +} + +static void *darwin_event_thread_main (void *arg0) { + IOReturn kresult; + struct libusb_context *ctx = (struct libusb_context *)arg0; + CFRunLoopRef runloop; + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 + /* Set this thread's name, so it can be seen in the debugger + and crash reports. */ + pthread_setname_np ("org.libusb.device-hotplug"); +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + /* Tell the Objective-C garbage collector about this thread. + This is required because, unlike NSThreads, pthreads are + not automatically registered. Although we don't use + Objective-C, we use CoreFoundation, which does. + Garbage collection support was entirely removed in 10.12, + so don't bother there. */ + objc_registerThreadWithCollector(); +#endif + + /* hotplug (device arrival/removal) sources */ + CFRunLoopSourceContext libusb_shutdown_cfsourcectx; + CFRunLoopSourceRef libusb_notification_cfsource; + io_notification_port_t libusb_notification_port; + io_iterator_t libusb_rem_device_iterator; + io_iterator_t libusb_add_device_iterator; + + usbi_dbg ("creating hotplug event source"); + + runloop = CFRunLoopGetCurrent (); + CFRetain (runloop); + + /* add the shutdown cfsource to the run loop */ + memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx)); + libusb_shutdown_cfsourcectx.info = runloop; + libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop; + libusb_darwin_acfls = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx); + CFRunLoopAddSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode); + + /* add the notification port to the run loop */ + libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault); + libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port); + CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode); + + /* create notifications for removed devices */ + kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification, + IOServiceMatching(darwin_device_class), + darwin_devices_detached, + ctx, &libusb_rem_device_iterator); + + if (kresult != kIOReturnSuccess) { + usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult)); + + pthread_exit (NULL); + } + + /* create notifications for attached devices */ + kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification, + IOServiceMatching(darwin_device_class), + darwin_devices_attached, + ctx, &libusb_add_device_iterator); + + if (kresult != kIOReturnSuccess) { + usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult)); + + pthread_exit (NULL); + } + + /* arm notifiers */ + darwin_clear_iterator (libusb_rem_device_iterator); + darwin_clear_iterator (libusb_add_device_iterator); + + usbi_dbg ("darwin event thread ready to receive events"); + + /* signal the main thread that the hotplug runloop has been created. */ + pthread_mutex_lock (&libusb_darwin_at_mutex); + libusb_darwin_acfl = runloop; + pthread_cond_signal (&libusb_darwin_at_cond); + pthread_mutex_unlock (&libusb_darwin_at_mutex); + + /* run the runloop */ + CFRunLoopRun(); + + usbi_dbg ("darwin event thread exiting"); + + /* remove the notification cfsource */ + CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode); + + /* remove the shutdown cfsource */ + CFRunLoopRemoveSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode); + + /* delete notification port */ + IONotificationPortDestroy (libusb_notification_port); + + /* delete iterators */ + IOObjectRelease (libusb_rem_device_iterator); + IOObjectRelease (libusb_add_device_iterator); + + CFRelease (libusb_darwin_acfls); + CFRelease (runloop); + + libusb_darwin_acfls = NULL; + libusb_darwin_acfl = NULL; + + pthread_exit (NULL); +} + +/* cleanup function to destroy cached devices */ +static void __attribute__((destructor)) _darwin_finalize(void) { + struct darwin_cached_device *dev, *next; + + usbi_mutex_lock(&darwin_cached_devices_lock); + list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) { + darwin_deref_cached_device(dev); + } + usbi_mutex_unlock(&darwin_cached_devices_lock); +} + +static void darwin_check_version (void) { + /* adjust for changes in the USB stack in xnu 15 */ + int sysctl_args[] = {CTL_KERN, KERN_OSRELEASE}; + long version; + char version_string[256] = {'\0',}; + size_t length = 256; + + sysctl(sysctl_args, 2, version_string, &length, NULL, 0); + + errno = 0; + version = strtol (version_string, NULL, 10); + if (0 == errno && version >= 15) { + darwin_device_class = "IOUSBHostDevice"; + } +} + +static int darwin_init(struct libusb_context *ctx) { + host_name_port_t host_self; + int rc; + + rc = pthread_once (&darwin_init_once, darwin_check_version); + if (rc) { + return LIBUSB_ERROR_OTHER; + } + + rc = darwin_scan_devices (ctx); + if (LIBUSB_SUCCESS != rc) { + return rc; + } + + if (libusb_darwin_atomic_fetch_add (&initCount, 1) == 0) { + /* create the clocks that will be used */ + + host_self = mach_host_self(); + host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime); + host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic); + mach_port_deallocate(mach_task_self(), host_self); + + pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx); + + pthread_mutex_lock (&libusb_darwin_at_mutex); + while (!libusb_darwin_acfl) + pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex); + pthread_mutex_unlock (&libusb_darwin_at_mutex); + } + + return rc; +} + +static void darwin_exit (void) { + if (libusb_darwin_atomic_fetch_add (&initCount, -1) == 1) { + mach_port_deallocate(mach_task_self(), clock_realtime); + mach_port_deallocate(mach_task_self(), clock_monotonic); + + /* stop the event runloop and wait for the thread to terminate. */ + CFRunLoopSourceSignal(libusb_darwin_acfls); + CFRunLoopWakeUp (libusb_darwin_acfl); + pthread_join (libusb_darwin_at, NULL); + } +} + +static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + + /* return cached copy */ + memmove (buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH); + + *host_endian = 0; + + return 0; +} + +static int get_configuration_index (struct libusb_device *dev, int config_value) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + UInt8 i, numConfig; + IOUSBConfigurationDescriptorPtr desc; + IOReturn kresult; + + /* is there a simpler way to determine the index? */ + kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + for (i = 0 ; i < numConfig ; i++) { + (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc); + + if (desc->bConfigurationValue == config_value) + return i; + } + + /* configuration not found */ + return LIBUSB_ERROR_NOT_FOUND; +} + +static int darwin_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + int config_index; + + if (0 == priv->active_config) + return LIBUSB_ERROR_NOT_FOUND; + + config_index = get_configuration_index (dev, priv->active_config); + if (config_index < 0) + return config_index; + + return darwin_get_config_descriptor (dev, config_index, buffer, len, host_endian); +} + +static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + IOUSBConfigurationDescriptorPtr desc; + IOReturn kresult; + int ret; + + if (!priv || !priv->device) + return LIBUSB_ERROR_OTHER; + + kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc); + if (kresult == kIOReturnSuccess) { + /* copy descriptor */ + if (libusb_le16_to_cpu(desc->wTotalLength) < len) + len = libusb_le16_to_cpu(desc->wTotalLength); + + memmove (buffer, desc, len); + + /* GetConfigurationDescriptorPtr returns the descriptor in USB bus order */ + *host_endian = 0; + } + + ret = darwin_to_libusb (kresult); + if (ret != LIBUSB_SUCCESS) + return ret; + + return (int) len; +} + +/* check whether the os has configured the device */ +static int darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) { + usb_device_t **darwin_device = dev->device; + + IOUSBConfigurationDescriptorPtr configDesc; + IOUSBFindInterfaceRequest request; + kern_return_t kresult; + io_iterator_t interface_iterator; + io_service_t firstInterface; + + if (dev->dev_descriptor.bNumConfigurations < 1) { + usbi_err (ctx, "device has no configurations"); + return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */ + } + + /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is + not usable anyway */ + if (0x05ac == dev->dev_descriptor.idVendor && 0x8005 == dev->dev_descriptor.idProduct) { + usbi_dbg ("ignoring configuration on root hub simulation"); + dev->active_config = 0; + return 0; + } + + /* find the first configuration */ + kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc); + dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1; + + /* check if the device is already configured. there is probably a better way than iterating over the + to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices + might lock up on the device request) */ + + /* Setup the Interface Request */ + request.bInterfaceClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + + kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator); + if (kresult) + return darwin_to_libusb (kresult); + + /* iterate once */ + firstInterface = IOIteratorNext(interface_iterator); + + /* done with the interface iterator */ + IOObjectRelease(interface_iterator); + + if (firstInterface) { + IOObjectRelease (firstInterface); + + /* device is configured */ + if (dev->dev_descriptor.bNumConfigurations == 1) + /* to avoid problems with some devices get the configurations value from the configuration descriptor */ + dev->active_config = dev->first_config; + else + /* devices with more than one configuration should work with GetConfiguration */ + (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config); + } else + /* not configured */ + dev->active_config = 0; + + usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config); + + return 0; +} + +static int darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) { + IOUSBDevRequestTO req; + + memset (buffer, 0, buffer_size); + + /* Set up request for descriptor/ */ + req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); + req.bRequest = kUSBRqGetDescriptor; + req.wValue = desc << 8; + req.wIndex = desc_index; + req.wLength = buffer_size; + req.pData = buffer; + req.noDataTimeout = 20; + req.completionTimeout = 100; + + return (*device)->DeviceRequestTO (device, &req); +} + +static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) { + usb_device_t **device = dev->device; + int retries = 1, delay = 30000; + int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1; + int is_open = 0; + int ret = 0, ret2; + UInt8 bDeviceClass; + UInt16 idProduct, idVendor; + + dev->can_enumerate = 0; + + (*device)->GetDeviceClass (device, &bDeviceClass); + (*device)->GetDeviceProduct (device, &idProduct); + (*device)->GetDeviceVendor (device, &idVendor); + + /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some + * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still, + * to follow the spec as closely as possible, try opening the device */ + is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess); + + do { + /**** retrieve device descriptor ****/ + ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor)); + + if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType) + /* received an overrun error but we still received a device descriptor */ + ret = kIOReturnSuccess; + + if (kIOUSBVendorIDAppleComputer == idVendor) { + /* NTH: don't bother retrying or unsuspending Apple devices */ + break; + } + + if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations || + 0 == dev->dev_descriptor.bcdUSB)) { + /* work around for incorrectly configured devices */ + if (try_reconfigure && is_open) { + usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again..."); + + /* set the first configuration */ + (*device)->SetConfiguration(device, 1); + + /* don't try to reconfigure again */ + try_reconfigure = 0; + } + + ret = kIOUSBPipeStalled; + } + + if (kIOReturnSuccess != ret && is_open && try_unsuspend) { + /* device may be suspended. unsuspend it and try again */ +#if DeviceVersion >= 320 + UInt32 info = 0; + + /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */ + (void)(*device)->GetUSBDeviceInformation (device, &info); + + /* note that the device was suspended */ + if (info & (1 << kUSBInformationDeviceIsSuspendedBit) || 0 == info) + try_unsuspend = 1; +#endif + + if (try_unsuspend) { + /* try to unsuspend the device */ + ret2 = (*device)->USBDeviceSuspend (device, 0); + if (kIOReturnSuccess != ret2) { + /* prevent log spew from poorly behaving devices. this indicates the + os actually had trouble communicating with the device */ + usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2)); + } else + unsuspended = 1; + + try_unsuspend = 0; + } + } + + if (kIOReturnSuccess != ret) { + usbi_dbg("kernel responded with code: 0x%08x. sleeping for %d ms before trying again", ret, delay/1000); + /* sleep for a little while before trying again */ + nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL); + } + } while (kIOReturnSuccess != ret && retries--); + + if (unsuspended) + /* resuspend the device */ + (void)(*device)->USBDeviceSuspend (device, 1); + + if (is_open) + (void) (*device)->USBDeviceClose (device); + + if (ret != kIOReturnSuccess) { + /* a debug message was already printed out for this error */ + if (LIBUSB_CLASS_HUB == bDeviceClass) + usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device", + idVendor, idProduct, darwin_error_str (ret), ret); + else + usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device", + idVendor, idProduct, darwin_error_str (ret), ret); + return darwin_to_libusb (ret); + } + + /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */ + if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) { + /* not a valid device */ + usbi_warn (ctx, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device", + idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct)); + return LIBUSB_ERROR_NO_DEVICE; + } + + usbi_dbg ("cached device descriptor:"); + usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType); + usbi_dbg (" bcdUSB: 0x%04x", dev->dev_descriptor.bcdUSB); + usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass); + usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass); + usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol); + usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0); + usbi_dbg (" idVendor: 0x%04x", dev->dev_descriptor.idVendor); + usbi_dbg (" idProduct: 0x%04x", dev->dev_descriptor.idProduct); + usbi_dbg (" bcdDevice: 0x%04x", dev->dev_descriptor.bcdDevice); + usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer); + usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct); + usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber); + usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations); + + dev->can_enumerate = 1; + + return LIBUSB_SUCCESS; +} + +static int get_device_port (io_service_t service, UInt8 *port) { + kern_return_t result; + io_service_t parent; + int ret = 0; + + if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) { + return 1; + } + + result = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent); + if (kIOReturnSuccess == result) { + ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port); + IOObjectRelease (parent); + } + + return ret; +} + +static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, + struct darwin_cached_device **cached_out) { + struct darwin_cached_device *new_device; + UInt64 sessionID = 0, parent_sessionID = 0; + int ret = LIBUSB_SUCCESS; + usb_device_t **device; + io_service_t parent; + kern_return_t result; + UInt8 port = 0; + + /* get some info from the io registry */ + (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID); + if (!get_device_port (service, &port)) { + usbi_dbg("could not get connected port number"); + } + + usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID); + + result = IORegistryEntryGetParentEntry (service, kIOUSBPlane, &parent); + + if (kIOReturnSuccess == result) { + (void) get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, &parent_sessionID); + IOObjectRelease(parent); + } + + usbi_mutex_lock(&darwin_cached_devices_lock); + do { + *cached_out = NULL; + + list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) { + usbi_dbg("matching sessionID 0x%" PRIx64 " against cached device with sessionID 0x%" PRIx64, sessionID, new_device->session); + if (new_device->session == sessionID) { + usbi_dbg("using cached device for device"); + *cached_out = new_device; + break; + } + } + + if (*cached_out) + break; + + usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID); + + device = darwin_device_from_service (service); + if (!device) { + ret = LIBUSB_ERROR_NO_DEVICE; + break; + } + + new_device = calloc (1, sizeof (*new_device)); + if (!new_device) { + ret = LIBUSB_ERROR_NO_MEM; + break; + } + + /* add this device to the cached device list */ + list_add(&new_device->list, &darwin_cached_devices); + + (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address); + + /* keep a reference to this device */ + darwin_ref_cached_device(new_device); + + new_device->device = device; + new_device->session = sessionID; + (*device)->GetLocationID (device, &new_device->location); + new_device->port = port; + new_device->parent_session = parent_sessionID; + + /* cache the device descriptor */ + ret = darwin_cache_device_descriptor(ctx, new_device); + if (ret) + break; + + if (new_device->can_enumerate) { + snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address, + new_device->dev_descriptor.idVendor, new_device->dev_descriptor.idProduct, + new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass); + } + } while (0); + + usbi_mutex_unlock(&darwin_cached_devices_lock); + + /* keep track of devices regardless of if we successfully enumerate them to + prevent them from being enumerated multiple times */ + + *cached_out = new_device; + + return ret; +} + +static int process_new_device (struct libusb_context *ctx, io_service_t service) { + struct darwin_device_priv *priv; + struct libusb_device *dev = NULL; + struct darwin_cached_device *cached_device; + UInt8 devSpeed; + int ret = 0; + + do { + ret = darwin_get_cached_device (ctx, service, &cached_device); + + if (ret < 0 || !cached_device->can_enumerate) { + return ret; + } + + /* check current active configuration (and cache the first configuration value-- + which may be used by claim_interface) */ + ret = darwin_check_configuration (ctx, cached_device); + if (ret) + break; + + usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64, + ctx, cached_device->session); + + dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session); + if (!dev) { + return LIBUSB_ERROR_NO_MEM; + } + + priv = (struct darwin_device_priv *)dev->os_priv; + + priv->dev = cached_device; + darwin_ref_cached_device (priv->dev); + + if (cached_device->parent_session > 0) { + dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session); + } else { + dev->parent_dev = NULL; + } + dev->port_number = cached_device->port; + dev->bus_number = cached_device->location >> 24; + dev->device_address = cached_device->address; + + (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed); + + switch (devSpeed) { + case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break; + case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break; + case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break; +#if DeviceVersion >= 500 + case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break; +#endif + default: + usbi_warn (ctx, "Got unknown device speed %d", devSpeed); + } + + ret = usbi_sanitize_device (dev); + if (ret < 0) + break; + + usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address, + dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path); + } while (0); + + if (0 == ret) { + usbi_connect_device (dev); + } else { + libusb_unref_device (dev); + } + + return ret; +} + +static int darwin_scan_devices(struct libusb_context *ctx) { + io_iterator_t deviceIterator; + io_service_t service; + kern_return_t kresult; + + kresult = usb_setup_device_iterator (&deviceIterator, 0); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + while ((service = IOIteratorNext (deviceIterator))) { + (void) process_new_device (ctx, service); + + IOObjectRelease(service); + } + + IOObjectRelease(deviceIterator); + + return 0; +} + +static int darwin_open (struct libusb_device_handle *dev_handle) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOReturn kresult; + + if (0 == dpriv->open_count) { + /* try to open the device */ + kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device); + if (kresult != kIOReturnSuccess) { + usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult)); + + if (kIOReturnExclusiveAccess != kresult) { + return darwin_to_libusb (kresult); + } + + /* it is possible to perform some actions on a device that is not open so do not return an error */ + priv->is_open = 0; + } else { + priv->is_open = 1; + } + + /* create async event source */ + kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource); + if (kresult != kIOReturnSuccess) { + usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult)); + + if (priv->is_open) { + (*(dpriv->device))->USBDeviceClose (dpriv->device); + } + + priv->is_open = 0; + + return darwin_to_libusb (kresult); + } + + CFRetain (libusb_darwin_acfl); + + /* add the cfSource to the aync run loop */ + CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes); + } + + /* device opened successfully */ + dpriv->open_count++; + + usbi_dbg ("device open for access"); + + return 0; +} + +static void darwin_close (struct libusb_device_handle *dev_handle) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOReturn kresult; + int i; + + if (dpriv->open_count == 0) { + /* something is probably very wrong if this is the case */ + usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!"); + return; + } + + dpriv->open_count--; + + /* make sure all interfaces are released */ + for (i = 0 ; i < USB_MAXINTERFACES ; i++) + if (dev_handle->claimed_interfaces & (1 << i)) + libusb_release_interface (dev_handle, i); + + if (0 == dpriv->open_count) { + /* delete the device's async event source */ + if (priv->cfSource) { + CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode); + CFRelease (priv->cfSource); + priv->cfSource = NULL; + CFRelease (libusb_darwin_acfl); + } + + if (priv->is_open) { + /* close the device */ + kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device); + if (kresult) { + /* Log the fact that we had a problem closing the file, however failing a + * close isn't really an error, so return success anyway */ + usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult)); + } + } + } +} + +static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + + *config = (int) dpriv->active_config; + + return 0; +} + +static int darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOReturn kresult; + int i; + + /* Setting configuration will invalidate the interface, so we need + to reclaim it. First, dispose of existing interfaces, if any. */ + for (i = 0 ; i < USB_MAXINTERFACES ; i++) + if (dev_handle->claimed_interfaces & (1 << i)) + darwin_release_interface (dev_handle, i); + + kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, config); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + /* Reclaim any interfaces. */ + for (i = 0 ; i < USB_MAXINTERFACES ; i++) + if (dev_handle->claimed_interfaces & (1 << i)) + darwin_claim_interface (dev_handle, i); + + dpriv->active_config = config; + + return 0; +} + +static int darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) { + IOUSBFindInterfaceRequest request; + kern_return_t kresult; + io_iterator_t interface_iterator; + UInt8 bInterfaceNumber; + int ret; + + *usbInterfacep = IO_OBJECT_NULL; + + /* Setup the Interface Request */ + request.bInterfaceClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + + kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator); + if (kresult) + return kresult; + + while ((*usbInterfacep = IOIteratorNext(interface_iterator))) { + /* find the interface number */ + ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type, + &bInterfaceNumber); + + if (ret && bInterfaceNumber == ifc) { + break; + } + + (void) IOObjectRelease (*usbInterfacep); + } + + /* done with the interface iterator */ + IOObjectRelease(interface_iterator); + + return 0; +} + +static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + kern_return_t kresult; + + u_int8_t numep, direction, number; + u_int8_t dont_care1, dont_care3; + u_int16_t dont_care2; + int rc; + + usbi_dbg ("building table of endpoints."); + + /* retrieve the total number of endpoints on this interface */ + kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + /* iterate through pipe references */ + for (int i = 1 ; i <= numep ; i++) { + kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1, + &dont_care2, &dont_care3); + + if (kresult != kIOReturnSuccess) { + /* probably a buggy device. try to get the endpoint address from the descriptors */ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *endpoint_desc; + UInt8 alt_setting; + + kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface"); + return darwin_to_libusb (kresult); + } + + rc = libusb_get_active_config_descriptor (dev_handle->dev, &config); + if (LIBUSB_SUCCESS != rc) { + return rc; + } + + endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1; + + cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress; + } else { + cInterface->endpoint_addrs[i - 1] = (((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK)); + } + + usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift, + cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK); + } + + cInterface->num_endpoints = numep; + + return 0; +} + +static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + io_service_t usbInterface = IO_OBJECT_NULL; + IOReturn kresult; + IOCFPlugInInterface **plugInInterface = NULL; + SInt32 score; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + kresult = darwin_get_interface (dpriv->device, iface, &usbInterface); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + /* make sure we have an interface */ + if (!usbInterface && dpriv->first_config != 0) { + usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config); + + /* set the configuration */ + kresult = darwin_set_configuration (dev_handle, dpriv->first_config); + if (kresult != LIBUSB_SUCCESS) { + usbi_err (HANDLE_CTX (dev_handle), "could not set configuration"); + return kresult; + } + + kresult = darwin_get_interface (dpriv->device, iface, &usbInterface); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + } + + if (!usbInterface) { + usbi_err (HANDLE_CTX (dev_handle), "interface not found"); + return LIBUSB_ERROR_NOT_FOUND; + } + + /* get an interface to the device's interface */ + kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID, + kIOCFPlugInInterfaceID, &plugInInterface, &score); + + /* ignore release error */ + (void)IOObjectRelease (usbInterface); + + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + if (!plugInInterface) { + usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found"); + return LIBUSB_ERROR_NOT_FOUND; + } + + /* Do the actual claim */ + kresult = (*plugInInterface)->QueryInterface(plugInInterface, + CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), + (LPVOID)&cInterface->interface); + /* We no longer need the intermediate plug-in */ + /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */ + (*plugInInterface)->Release (plugInInterface); + if (kresult || !cInterface->interface) { + usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + /* claim the interface */ + kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + /* update list of endpoints */ + kresult = get_endpoints (dev_handle, iface); + if (kresult) { + /* this should not happen */ + darwin_release_interface (dev_handle, iface); + usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table"); + return kresult; + } + + cInterface->cfSource = NULL; + + /* create async event source */ + kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource); + if (kresult != kIOReturnSuccess) { + usbi_err (HANDLE_CTX (dev_handle), "could not create async event source"); + + /* can't continue without an async event source */ + (void)darwin_release_interface (dev_handle, iface); + + return darwin_to_libusb (kresult); + } + + /* add the cfSource to the async thread's run loop */ + CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode); + + usbi_dbg ("interface opened"); + + return 0; +} + +static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + IOReturn kresult; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + /* Check to see if an interface is open */ + if (!cInterface->interface) + return LIBUSB_SUCCESS; + + /* clean up endpoint data */ + cInterface->num_endpoints = 0; + + /* delete the interface's async event source */ + if (cInterface->cfSource) { + CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode); + CFRelease (cInterface->cfSource); + } + + kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface); + if (kresult) + usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult)); + + kresult = (*(cInterface->interface))->Release(cInterface->interface); + if (kresult != kIOReturnSuccess) + usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult)); + + cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL; + + return darwin_to_libusb (kresult); +} + +static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + IOReturn kresult; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + if (!cInterface->interface) + return LIBUSB_ERROR_NO_DEVICE; + + kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting); + if (kresult != kIOReturnSuccess) + darwin_reset_device (dev_handle); + + /* update list of endpoints */ + kresult = get_endpoints (dev_handle, iface); + if (kresult) { + /* this should not happen */ + darwin_release_interface (dev_handle, iface); + usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table"); + return kresult; + } + + return darwin_to_libusb (kresult); +} + +static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) { + /* current interface */ + struct darwin_interface *cInterface; + IOReturn kresult; + uint8_t pipeRef; + + /* determine the interface/endpoint to use */ + if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + /* newer versions of darwin support clearing additional bits on the device's endpoint */ + kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef); + if (kresult) + usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult)); + + return darwin_to_libusb (kresult); +} + +static int darwin_reset_device(struct libusb_device_handle *dev_handle) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOUSBDeviceDescriptor descriptor; + IOUSBConfigurationDescriptorPtr cached_configuration; + IOUSBConfigurationDescriptor configuration; + bool reenumerate = false; + IOReturn kresult; + int i; + + kresult = (*(dpriv->device))->ResetDevice (dpriv->device); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "ResetDevice: %s", darwin_error_str (kresult)); + return darwin_to_libusb (kresult); + } + + do { + usbi_dbg ("darwin/reset_device: checking if device descriptor changed"); + + /* ignore return code. if we can't get a descriptor it might be worthwhile re-enumerating anway */ + (void) darwin_request_descriptor (dpriv->device, kUSBDeviceDesc, 0, &descriptor, sizeof (descriptor)); + + /* check if the device descriptor has changed */ + if (0 != memcmp (&dpriv->dev_descriptor, &descriptor, sizeof (descriptor))) { + reenumerate = true; + break; + } + + /* check if any configuration descriptor has changed */ + for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) { + usbi_dbg ("darwin/reset_device: checking if configuration descriptor %d changed", i); + + (void) darwin_request_descriptor (dpriv->device, kUSBConfDesc, i, &configuration, sizeof (configuration)); + (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration); + + if (!cached_configuration || 0 != memcmp (cached_configuration, &configuration, sizeof (configuration))) { + reenumerate = true; + break; + } + } + } while (0); + + if (reenumerate) { + usbi_dbg ("darwin/reset_device: device requires reenumeration"); + (void) (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg ("darwin/reset_device: device reset complete"); + + return LIBUSB_SUCCESS; +} + +static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + io_service_t usbInterface; + CFTypeRef driver; + IOReturn kresult; + + kresult = darwin_get_interface (dpriv->device, interface, &usbInterface); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult)); + + return darwin_to_libusb (kresult); + } + + driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0); + IOObjectRelease (usbInterface); + + if (driver) { + CFRelease (driver); + + return 1; + } + + /* no driver */ + return 0; +} + +/* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */ +static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) { + UNUSED(dev_handle); + UNUSED(interface); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) { + UNUSED(dev_handle); + UNUSED(interface); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static void darwin_destroy_device(struct libusb_device *dev) { + struct darwin_device_priv *dpriv = (struct darwin_device_priv *) dev->os_priv; + + if (dpriv->dev) { + /* need to hold the lock in case this is the last reference to the device */ + usbi_mutex_lock(&darwin_cached_devices_lock); + darwin_deref_cached_device (dpriv->dev); + dpriv->dev = NULL; + usbi_mutex_unlock(&darwin_cached_devices_lock); + } +} + +static int submit_bulk_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + IOReturn ret; + uint8_t transferType; + /* None of the values below are used in libusbx for bulk transfers */ + uint8_t direction, number, interval, pipeRef; + uint16_t maxPacketSize; + + struct darwin_interface *cInterface; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number, + &transferType, &maxPacketSize, &interval); + + if (ret) { + usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(ret), ret); + return darwin_to_libusb (ret); + } + + if (0 != (transfer->length % maxPacketSize)) { + /* do not need a zero packet */ + transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET; + } + + /* submit the request */ + /* timeouts are unavailable on interrupt endpoints */ + if (transferType == kUSBInterrupt) { + if (IS_XFERIN(transfer)) + ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, darwin_async_io_callback, itransfer); + else + ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, darwin_async_io_callback, itransfer); + } else { + itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; + + if (IS_XFERIN(transfer)) + ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, transfer->timeout, transfer->timeout, + darwin_async_io_callback, (void *)itransfer); + else + ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, transfer->timeout, transfer->timeout, + darwin_async_io_callback, (void *)itransfer); + } + + if (ret) + usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(ret), ret); + + return darwin_to_libusb (ret); +} + +#if InterfaceVersion >= 550 +static int submit_stream_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_interface *cInterface; + uint8_t pipeRef; + IOReturn ret; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; + + if (IS_XFERIN(transfer)) + ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id, + transfer->buffer, transfer->length, transfer->timeout, + transfer->timeout, darwin_async_io_callback, (void *)itransfer); + else + ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id, + transfer->buffer, transfer->length, transfer->timeout, + transfer->timeout, darwin_async_io_callback, (void *)itransfer); + + if (ret) + usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(ret), ret); + + return darwin_to_libusb (ret); +} +#endif + +static int submit_iso_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + IOReturn kresult; + uint8_t direction, number, interval, pipeRef, transferType; + uint16_t maxPacketSize; + UInt64 frame; + AbsoluteTime atTime; + int i; + + struct darwin_interface *cInterface; + + /* construct an array of IOUSBIsocFrames, reuse the old one if possible */ + if (tpriv->isoc_framelist && tpriv->num_iso_packets != transfer->num_iso_packets) { + free(tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + } + + if (!tpriv->isoc_framelist) { + tpriv->num_iso_packets = transfer->num_iso_packets; + tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame)); + if (!tpriv->isoc_framelist) + return LIBUSB_ERROR_NO_MEM; + } + + /* copy the frame list from the libusb descriptor (the structures differ only is member order) */ + for (i = 0 ; i < transfer->num_iso_packets ; i++) + tpriv->isoc_framelist[i].frReqCount = transfer->iso_packet_desc[i].length; + + /* determine the interface/endpoint to use */ + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + /* determine the properties of this endpoint and the speed of the device */ + (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number, + &transferType, &maxPacketSize, &interval); + + /* Last but not least we need the bus frame number */ + kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime); + if (kresult) { + usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult); + free(tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + + return darwin_to_libusb (kresult); + } + + (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number, + &transferType, &maxPacketSize, &interval); + + /* schedule for a frame a little in the future */ + frame += 4; + + if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint]) + frame = cInterface->frames[transfer->endpoint]; + + /* submit the request */ + if (IS_XFERIN(transfer)) + kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame, + transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback, + itransfer); + else + kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame, + transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback, + itransfer); + + if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed) + /* Full speed */ + cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets * (1 << (interval - 1)); + else + /* High/super speed */ + cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets * (1 << (interval - 1)) / 8; + + if (kresult != kIOReturnSuccess) { + usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(kresult)); + free (tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + } + + return darwin_to_libusb (kresult); +} + +static int submit_control_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer; + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + IOReturn kresult; + + memset(&tpriv->req, 0, sizeof(tpriv->req)); + + /* IOUSBDeviceInterface expects the request in cpu endianness */ + tpriv->req.bmRequestType = setup->bmRequestType; + tpriv->req.bRequest = setup->bRequest; + /* these values should be in bus order from libusb_fill_control_setup */ + tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue); + tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex); + tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength); + /* data is stored after the libusb control block */ + tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + tpriv->req.completionTimeout = transfer->timeout; + tpriv->req.noDataTimeout = transfer->timeout; + + itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; + + /* all transfers in libusb-1.0 are async */ + + if (transfer->endpoint) { + struct darwin_interface *cInterface; + uint8_t pipeRef; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer); + } else + /* control request on endpoint 0 */ + kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer); + + if (kresult != kIOReturnSuccess) + usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult)); + + return darwin_to_libusb (kresult); +} + +static int darwin_submit_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return submit_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return submit_iso_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: +#if InterfaceVersion >= 550 + return submit_stream_transfer(itransfer); +#else + usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers"); + return LIBUSB_ERROR_NOT_SUPPORTED; +#endif + default: + usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int cancel_control_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev); + IOReturn kresult; + + usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe"); + + if (!dpriv->device) + return LIBUSB_ERROR_NO_DEVICE; + + kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device); + + return darwin_to_libusb (kresult); +} + +static int darwin_abort_transfers (struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev); + struct darwin_interface *cInterface; + uint8_t pipeRef, iface; + IOReturn kresult; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + if (!dpriv->device) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef); + + /* abort transactions */ +#if InterfaceVersion >= 550 + if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type) + (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id); + else +#endif + (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef); + + usbi_dbg ("calling clear pipe stall to clear the data toggle bit"); + + /* newer versions of darwin support clearing additional bits on the device's endpoint */ + kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef); + + return darwin_to_libusb (kresult); +} + +static int darwin_cancel_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return cancel_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return darwin_abort_transfers (itransfer); + default: + usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static void darwin_clear_transfer_priv (struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS && tpriv->isoc_framelist) { + free (tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + } +} + +static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) { + struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon; + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + usbi_dbg ("an async io operation has completed"); + + /* if requested write a zero packet */ + if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + struct darwin_interface *cInterface; + uint8_t pipeRef; + + (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface); + + (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0); + } + + tpriv->result = result; + tpriv->size = (UInt32) (uintptr_t) arg0; + + /* signal the core that this transfer is complete */ + usbi_signal_transfer_completion(itransfer); +} + +static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) { + if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT) + result = kIOUSBTransactionTimeout; + + switch (result) { + case kIOReturnUnderrun: + case kIOReturnSuccess: + return LIBUSB_TRANSFER_COMPLETED; + case kIOReturnAborted: + return LIBUSB_TRANSFER_CANCELLED; + case kIOUSBPipeStalled: + usbi_dbg ("transfer error: pipe is stalled"); + return LIBUSB_TRANSFER_STALL; + case kIOReturnOverrun: + usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun"); + return LIBUSB_TRANSFER_OVERFLOW; + case kIOUSBTransactionTimeout: + usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out"); + itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT; + return LIBUSB_TRANSFER_TIMED_OUT; + default: + usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result); + return LIBUSB_TRANSFER_ERROR; + } +} + +static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type; + int isBulk = LIBUSB_TRANSFER_TYPE_BULK == transfer->type; + int isControl = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type; + int isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type; + int i; + + if (!isIsoc && !isBulk && !isControl && !isInterrupt) { + usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } + + usbi_dbg ("handling %s completion with kernel status %d", + isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result); + + if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) { + if (isIsoc && tpriv->isoc_framelist) { + /* copy isochronous results back */ + + for (i = 0; i < transfer->num_iso_packets ; i++) { + struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i]; + lib_desc->status = darwin_to_libusb (tpriv->isoc_framelist[i].frStatus); + lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount; + } + } else if (!isIsoc) + itransfer->transferred += tpriv->size; + } + + /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */ + return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result)); +} + +static int darwin_clock_gettime(int clk_id, struct timespec *tp) { + mach_timespec_t sys_time; + clock_serv_t clock_ref; + + switch (clk_id) { + case USBI_CLOCK_REALTIME: + /* CLOCK_REALTIME represents time since the epoch */ + clock_ref = clock_realtime; + break; + case USBI_CLOCK_MONOTONIC: + /* use system boot time as reference for the monotonic clock */ + clock_ref = clock_monotonic; + break; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } + + clock_get_time (clock_ref, &sys_time); + + tp->tv_sec = sys_time.tv_sec; + tp->tv_nsec = sys_time.tv_nsec; + + return 0; +} + +#if InterfaceVersion >= 550 +static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints, + int num_endpoints) { + struct darwin_interface *cInterface; + UInt32 supportsStreams; + uint8_t pipeRef; + int rc, i; + + /* find the mimimum number of supported streams on the endpoint list */ + for (i = 0 ; i < num_endpoints ; ++i) { + if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) { + return rc; + } + + (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams); + if (num_streams > supportsStreams) + num_streams = supportsStreams; + } + + /* it is an error if any endpoint in endpoints does not support streams */ + if (0 == num_streams) + return LIBUSB_ERROR_INVALID_PARAM; + + /* create the streams */ + for (i = 0 ; i < num_endpoints ; ++i) { + (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface); + + rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams); + if (kIOReturnSuccess != rc) + return darwin_to_libusb(rc); + } + + return num_streams; +} + +static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) { + struct darwin_interface *cInterface; + UInt32 supportsStreams; + uint8_t pipeRef; + int rc; + + for (int i = 0 ; i < num_endpoints ; ++i) { + if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) + return rc; + + (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams); + if (0 == supportsStreams) + return LIBUSB_ERROR_INVALID_PARAM; + + rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0); + if (kIOReturnSuccess != rc) + return darwin_to_libusb(rc); + } + + return LIBUSB_SUCCESS; +} +#endif + +const struct usbi_os_backend darwin_backend = { + .name = "Darwin", + .caps = 0, + .init = darwin_init, + .exit = darwin_exit, + .get_device_list = NULL, /* not needed */ + .get_device_descriptor = darwin_get_device_descriptor, + .get_active_config_descriptor = darwin_get_active_config_descriptor, + .get_config_descriptor = darwin_get_config_descriptor, + .hotplug_poll = darwin_hotplug_poll, + + .open = darwin_open, + .close = darwin_close, + .get_configuration = darwin_get_configuration, + .set_configuration = darwin_set_configuration, + .claim_interface = darwin_claim_interface, + .release_interface = darwin_release_interface, + + .set_interface_altsetting = darwin_set_interface_altsetting, + .clear_halt = darwin_clear_halt, + .reset_device = darwin_reset_device, + +#if InterfaceVersion >= 550 + .alloc_streams = darwin_alloc_streams, + .free_streams = darwin_free_streams, +#endif + + .kernel_driver_active = darwin_kernel_driver_active, + .detach_kernel_driver = darwin_detach_kernel_driver, + .attach_kernel_driver = darwin_attach_kernel_driver, + + .destroy_device = darwin_destroy_device, + + .submit_transfer = darwin_submit_transfer, + .cancel_transfer = darwin_cancel_transfer, + .clear_transfer_priv = darwin_clear_transfer_priv, + + .handle_transfer_completion = darwin_handle_transfer_completion, + + .clock_gettime = darwin_clock_gettime, + + .device_priv_size = sizeof(struct darwin_device_priv), + .device_handle_priv_size = sizeof(struct darwin_device_handle_priv), + .transfer_priv_size = sizeof(struct darwin_transfer_priv), +}; diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.h new file mode 100644 index 00000000..11804342 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.h @@ -0,0 +1,164 @@ +/* + * darwin backend for libusb 1.0 + * Copyright © 2008-2015 Nathan Hjelm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(LIBUSB_DARWIN_H) +#define LIBUSB_DARWIN_H + +#include "libusbi.h" + +#include +#include +#include +#include + +/* IOUSBInterfaceInferface */ +#if defined (kIOUSBInterfaceInterfaceID700) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + +#define usb_interface_t IOUSBInterfaceInterface700 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID700 +#define InterfaceVersion 700 + +#elif defined (kIOUSBInterfaceInterfaceID550) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + +#define usb_interface_t IOUSBInterfaceInterface550 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550 +#define InterfaceVersion 550 + +#elif defined (kIOUSBInterfaceInterfaceID500) + +#define usb_interface_t IOUSBInterfaceInterface500 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID500 +#define InterfaceVersion 500 + +#elif defined (kIOUSBInterfaceInterfaceID300) + +#define usb_interface_t IOUSBInterfaceInterface300 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300 +#define InterfaceVersion 300 + +#elif defined (kIOUSBInterfaceInterfaceID245) + +#define usb_interface_t IOUSBInterfaceInterface245 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID245 +#define InterfaceVersion 245 + +#elif defined (kIOUSBInterfaceInterfaceID220) + +#define usb_interface_t IOUSBInterfaceInterface220 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220 +#define InterfaceVersion 220 + +#else + +#error "IOUSBFamily is too old. Please upgrade your OS" + +#endif + +/* IOUSBDeviceInterface */ +#if defined (kIOUSBDeviceInterfaceID500) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 + +#define usb_device_t IOUSBDeviceInterface500 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID500 +#define DeviceVersion 500 + +#elif defined (kIOUSBDeviceInterfaceID320) + +#define usb_device_t IOUSBDeviceInterface320 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID320 +#define DeviceVersion 320 + +#elif defined (kIOUSBDeviceInterfaceID300) + +#define usb_device_t IOUSBDeviceInterface300 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID300 +#define DeviceVersion 300 + +#elif defined (kIOUSBDeviceInterfaceID245) + +#define usb_device_t IOUSBDeviceInterface245 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID245 +#define DeviceVersion 245 + +#elif defined (kIOUSBDeviceInterfaceID220) +#define usb_device_t IOUSBDeviceInterface197 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID197 +#define DeviceVersion 197 + +#else + +#error "IOUSBFamily is too old. Please upgrade your OS" + +#endif + +#if !defined(IO_OBJECT_NULL) +#define IO_OBJECT_NULL ((io_object_t) 0) +#endif + +typedef IOCFPlugInInterface *io_cf_plugin_ref_t; +typedef IONotificationPortRef io_notification_port_t; + +/* private structures */ +struct darwin_cached_device { + struct list_head list; + IOUSBDeviceDescriptor dev_descriptor; + UInt32 location; + UInt64 parent_session; + UInt64 session; + UInt16 address; + char sys_path[21]; + usb_device_t **device; + int open_count; + UInt8 first_config, active_config, port; + int can_enumerate; + int refcount; +}; + +struct darwin_device_priv { + struct darwin_cached_device *dev; +}; + +struct darwin_device_handle_priv { + int is_open; + CFRunLoopSourceRef cfSource; + + struct darwin_interface { + usb_interface_t **interface; + uint8_t num_endpoints; + CFRunLoopSourceRef cfSource; + uint64_t frames[256]; + uint8_t endpoint_addrs[USB_MAXENDPOINTS]; + } interfaces[USB_MAXINTERFACES]; +}; + +struct darwin_transfer_priv { + /* Isoc */ + IOUSBIsocFrame *isoc_framelist; + int num_iso_packets; + + /* Control */ + IOUSBDevRequestTO req; + + /* Bulk */ + + /* Completion status */ + IOReturn result; + UInt32 size; +}; + +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_pollfs.cpp b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_pollfs.cpp new file mode 100644 index 00000000..e0c77132 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_pollfs.cpp @@ -0,0 +1,367 @@ +/* + * Copyright 2007-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Lotz + */ + +#include "haiku_usb.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class WatchedEntry { +public: + WatchedEntry(BMessenger *, entry_ref *); + ~WatchedEntry(); + bool EntryCreated(entry_ref *ref); + bool EntryRemoved(ino_t node); + bool InitCheck(); + +private: + BMessenger* fMessenger; + node_ref fNode; + bool fIsDirectory; + USBDevice* fDevice; + WatchedEntry* fEntries; + WatchedEntry* fLink; + bool fInitCheck; +}; + + +class RosterLooper : public BLooper { +public: + RosterLooper(USBRoster *); + void Stop(); + virtual void MessageReceived(BMessage *); + bool InitCheck(); + +private: + USBRoster* fRoster; + WatchedEntry* fRoot; + BMessenger* fMessenger; + bool fInitCheck; +}; + + +WatchedEntry::WatchedEntry(BMessenger *messenger, entry_ref *ref) + : fMessenger(messenger), + fIsDirectory(false), + fDevice(NULL), + fEntries(NULL), + fLink(NULL), + fInitCheck(false) +{ + BEntry entry(ref); + entry.GetNodeRef(&fNode); + + BDirectory directory; + if (entry.IsDirectory() && directory.SetTo(ref) >= B_OK) { + fIsDirectory = true; + + while (directory.GetNextEntry(&entry) >= B_OK) { + if (entry.GetRef(ref) < B_OK) + continue; + + WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref); + if (child == NULL) + continue; + if (child->InitCheck() == false) { + delete child; + continue; + } + + child->fLink = fEntries; + fEntries = child; + } + + watch_node(&fNode, B_WATCH_DIRECTORY, *fMessenger); + } + else { + if (strncmp(ref->name, "raw", 3) == 0) + return; + + BPath path, parent_path; + entry.GetPath(&path); + fDevice = new(std::nothrow) USBDevice(path.Path()); + if (fDevice != NULL && fDevice->InitCheck() == true) { + // Add this new device to each active context's device list + struct libusb_context *ctx; + unsigned long session_id = (unsigned long)&fDevice; + + usbi_mutex_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + struct libusb_device *dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev) { + usbi_dbg("using previously allocated device with location %lu", session_id); + libusb_unref_device(dev); + continue; + } + usbi_dbg("allocating new device with location %lu", session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) { + usbi_dbg("device allocation failed"); + continue; + } + *((USBDevice **)dev->os_priv) = fDevice; + + // Calculate pseudo-device-address + int addr, tmp; + if (strcmp(path.Leaf(), "hub") == 0) + tmp = 100; //Random Number + else + sscanf(path.Leaf(), "%d", &tmp); + addr = tmp + 1; + path.GetParent(&parent_path); + while (strcmp(parent_path.Leaf(), "usb") != 0) { + sscanf(parent_path.Leaf(), "%d", &tmp); + addr += tmp + 1; + parent_path.GetParent(&parent_path); + } + sscanf(path.Path(), "/dev/bus/usb/%d", &dev->bus_number); + dev->device_address = addr - (dev->bus_number + 1); + + if (usbi_sanitize_device(dev) < 0) { + usbi_dbg("device sanitization failed"); + libusb_unref_device(dev); + continue; + } + usbi_connect_device(dev); + } + usbi_mutex_unlock(&active_contexts_lock); + } + else if (fDevice) { + delete fDevice; + fDevice = NULL; + return; + } + } + fInitCheck = true; +} + + +WatchedEntry::~WatchedEntry() +{ + if (fIsDirectory) { + watch_node(&fNode, B_STOP_WATCHING, *fMessenger); + + WatchedEntry *child = fEntries; + while (child) { + WatchedEntry *next = child->fLink; + delete child; + child = next; + } + } + + if (fDevice) { + // Remove this device from each active context's device list + struct libusb_context *ctx; + struct libusb_device *dev; + unsigned long session_id = (unsigned long)&fDevice; + + usbi_mutex_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev != NULL) { + usbi_disconnect_device(dev); + libusb_unref_device(dev); + } else { + usbi_dbg("device with location %lu not found", session_id); + } + } + usbi_mutex_static_unlock(&active_contexts_lock); + delete fDevice; + } +} + + +bool +WatchedEntry::EntryCreated(entry_ref *ref) +{ + if (!fIsDirectory) + return false; + + if (ref->directory != fNode.node) { + WatchedEntry *child = fEntries; + while (child) { + if (child->EntryCreated(ref)) + return true; + child = child->fLink; + } + return false; + } + + WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref); + if (child == NULL) + return false; + child->fLink = fEntries; + fEntries = child; + return true; +} + + +bool +WatchedEntry::EntryRemoved(ino_t node) +{ + if (!fIsDirectory) + return false; + + WatchedEntry *child = fEntries; + WatchedEntry *lastChild = NULL; + while (child) { + if (child->fNode.node == node) { + if (lastChild) + lastChild->fLink = child->fLink; + else + fEntries = child->fLink; + delete child; + return true; + } + + if (child->EntryRemoved(node)) + return true; + + lastChild = child; + child = child->fLink; + } + return false; +} + + +bool +WatchedEntry::InitCheck() +{ + return fInitCheck; +} + + +RosterLooper::RosterLooper(USBRoster *roster) + : BLooper("LibusbRoster Looper"), + fRoster(roster), + fRoot(NULL), + fMessenger(NULL), + fInitCheck(false) +{ + BEntry entry("/dev/bus/usb"); + if (!entry.Exists()) { + usbi_err(NULL, "usb_raw not published"); + return; + } + + Run(); + fMessenger = new(std::nothrow) BMessenger(this); + if (fMessenger == NULL) { + usbi_err(NULL, "error creating BMessenger object"); + return; + } + + if (Lock()) { + entry_ref ref; + entry.GetRef(&ref); + fRoot = new(std::nothrow) WatchedEntry(fMessenger, &ref); + Unlock(); + if (fRoot == NULL) + return; + if (fRoot->InitCheck() == false) { + delete fRoot; + fRoot = NULL; + return; + } + } + fInitCheck = true; +} + + +void +RosterLooper::Stop() +{ + Lock(); + delete fRoot; + delete fMessenger; + Quit(); +} + + +void +RosterLooper::MessageReceived(BMessage *message) +{ + int32 opcode; + if (message->FindInt32("opcode", &opcode) < B_OK) + return; + + switch (opcode) { + case B_ENTRY_CREATED: + { + dev_t device; + ino_t directory; + const char *name; + if (message->FindInt32("device", &device) < B_OK || + message->FindInt64("directory", &directory) < B_OK || + message->FindString("name", &name) < B_OK) + break; + + entry_ref ref(device, directory, name); + fRoot->EntryCreated(&ref); + break; + } + case B_ENTRY_REMOVED: + { + ino_t node; + if (message->FindInt64("node", &node) < B_OK) + break; + fRoot->EntryRemoved(node); + break; + } + } +} + + +bool +RosterLooper::InitCheck() +{ + return fInitCheck; +} + + +USBRoster::USBRoster() + : fLooper(NULL) +{ +} + + +USBRoster::~USBRoster() +{ + Stop(); +} + + +int +USBRoster::Start() +{ + if (fLooper == NULL) { + fLooper = new(std::nothrow) RosterLooper(this); + if (fLooper == NULL || ((RosterLooper *)fLooper)->InitCheck() == false) { + if (fLooper) + fLooper = NULL; + return LIBUSB_ERROR_OTHER; + } + } + return LIBUSB_SUCCESS; +} + + +void +USBRoster::Stop() +{ + if (fLooper) { + ((RosterLooper *)fLooper)->Stop(); + fLooper = NULL; + } +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb.h new file mode 100644 index 00000000..d51ae9ea --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb.h @@ -0,0 +1,112 @@ +/* + * Haiku Backend for libusb + * Copyright © 2014 Akshay Jaggi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "libusbi.h" +#include "haiku_usb_raw.h" + +using namespace std; + +class USBDevice; +class USBDeviceHandle; +class USBTransfer; + +class USBDevice { +public: + USBDevice(const char *); + virtual ~USBDevice(); + const char* Location() const; + uint8 CountConfigurations() const; + const usb_device_descriptor* Descriptor() const; + const usb_configuration_descriptor* ConfigurationDescriptor(uint32) const; + const usb_configuration_descriptor* ActiveConfiguration() const; + uint8 EndpointToIndex(uint8) const; + uint8 EndpointToInterface(uint8) const; + int ClaimInterface(int); + int ReleaseInterface(int); + int CheckInterfacesFree(int); + int SetActiveConfiguration(int); + int ActiveConfigurationIndex() const; + bool InitCheck(); +private: + int Initialise(); + unsigned int fClaimedInterfaces; // Max Interfaces can be 32. Using a bitmask + usb_device_descriptor fDeviceDescriptor; + unsigned char** fConfigurationDescriptors; + int fActiveConfiguration; + char* fPath; + map fConfigToIndex; + map* fEndpointToIndex; + map* fEndpointToInterface; + bool fInitCheck; +}; + +class USBDeviceHandle { +public: + USBDeviceHandle(USBDevice *dev); + virtual ~USBDeviceHandle(); + int ClaimInterface(int); + int ReleaseInterface(int); + int SetConfiguration(int); + int SetAltSetting(int, int); + status_t SubmitTransfer(struct usbi_transfer *); + status_t CancelTransfer(USBTransfer *); + bool InitCheck(); +private: + int fRawFD; + static status_t TransfersThread(void *); + void TransfersWorker(); + USBDevice* fUSBDevice; + unsigned int fClaimedInterfaces; + BList fTransfers; + BLocker fTransfersLock; + sem_id fTransfersSem; + thread_id fTransfersThread; + bool fInitCheck; +}; + +class USBTransfer { +public: + USBTransfer(struct usbi_transfer *, USBDevice *); + virtual ~USBTransfer(); + void Do(int); + struct usbi_transfer* UsbiTransfer(); + void SetCancelled(); + bool IsCancelled(); +private: + struct usbi_transfer* fUsbiTransfer; + struct libusb_transfer* fLibusbTransfer; + USBDevice* fUSBDevice; + BLocker fStatusLock; + bool fCancelled; +}; + +class USBRoster { +public: + USBRoster(); + virtual ~USBRoster(); + int Start(); + void Stop(); +private: + void* fLooper; +}; diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_backend.cpp b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_backend.cpp new file mode 100644 index 00000000..d3de8cc0 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_backend.cpp @@ -0,0 +1,517 @@ +/* + * Haiku Backend for libusb + * Copyright © 2014 Akshay Jaggi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include +#include +#include +#include + +#include "haiku_usb.h" + +int _errno_to_libusb(int status) +{ + return status; +} + +USBTransfer::USBTransfer(struct usbi_transfer *itransfer, USBDevice *device) +{ + fUsbiTransfer = itransfer; + fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + fUSBDevice = device; + fCancelled = false; +} + +USBTransfer::~USBTransfer() +{ +} + +struct usbi_transfer * +USBTransfer::UsbiTransfer() +{ + return fUsbiTransfer; +} + +void +USBTransfer::SetCancelled() +{ + fCancelled = true; +} + +bool +USBTransfer::IsCancelled() +{ + return fCancelled; +} + +void +USBTransfer::Do(int fRawFD) +{ + switch (fLibusbTransfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + { + struct libusb_control_setup *setup = (struct libusb_control_setup *)fLibusbTransfer->buffer; + usb_raw_command command; + command.control.request_type = setup->bmRequestType; + command.control.request = setup->bRequest; + command.control.value = setup->wValue; + command.control.index = setup->wIndex; + command.control.length = setup->wLength; + command.control.data = fLibusbTransfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + if (fCancelled) + break; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) || + command.control.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed control transfer"); + break; + } + fUsbiTransfer->transferred = command.control.length; + } + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + { + usb_raw_command command; + command.transfer.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint); + command.transfer.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint); + command.transfer.data = fLibusbTransfer->buffer; + command.transfer.length = fLibusbTransfer->length; + if (fCancelled) + break; + if (fLibusbTransfer->type == LIBUSB_TRANSFER_TYPE_BULK) { + if (ioctl(fRawFD, B_USB_RAW_COMMAND_BULK_TRANSFER, &command, sizeof(command)) || + command.transfer.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed bulk transfer"); + break; + } + } + else { + if (ioctl(fRawFD, B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, &command, sizeof(command)) || + command.transfer.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed interrupt transfer"); + break; + } + } + fUsbiTransfer->transferred = command.transfer.length; + } + break; + // IsochronousTransfers not tested + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + { + usb_raw_command command; + command.isochronous.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint); + command.isochronous.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint); + command.isochronous.data = fLibusbTransfer->buffer; + command.isochronous.length = fLibusbTransfer->length; + command.isochronous.packet_count = fLibusbTransfer->num_iso_packets; + int i; + usb_iso_packet_descriptor *packetDescriptors = new usb_iso_packet_descriptor[fLibusbTransfer->num_iso_packets]; + for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) { + if ((int16)(fLibusbTransfer->iso_packet_desc[i]).length != (fLibusbTransfer->iso_packet_desc[i]).length) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer"); + break; + } + packetDescriptors[i].request_length = (int16)(fLibusbTransfer->iso_packet_desc[i]).length; + } + if (i < fLibusbTransfer->num_iso_packets) + break; // TODO Handle this error + command.isochronous.packet_descriptors = packetDescriptors; + if (fCancelled) + break; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER, &command, sizeof(command)) || + command.isochronous.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer"); + break; + } + for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) { + (fLibusbTransfer->iso_packet_desc[i]).actual_length = packetDescriptors[i].actual_length; + switch (packetDescriptors[i].status) { + case B_OK: + (fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_COMPLETED; + break; + default: + (fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_ERROR; + break; + } + } + delete[] packetDescriptors; + // Do we put the length of transfer here, for isochronous transfers? + fUsbiTransfer->transferred = command.transfer.length; + } + break; + default: + usbi_err(TRANSFER_CTX(fLibusbTransfer), "Unknown type of transfer"); + } +} + +bool +USBDeviceHandle::InitCheck() +{ + return fInitCheck; +} + +status_t +USBDeviceHandle::TransfersThread(void *self) +{ + USBDeviceHandle *handle = (USBDeviceHandle *)self; + handle->TransfersWorker(); + return B_OK; +} + +void +USBDeviceHandle::TransfersWorker() +{ + while (true) { + status_t status = acquire_sem(fTransfersSem); + if (status == B_BAD_SEM_ID) + break; + if (status == B_INTERRUPTED) + continue; + fTransfersLock.Lock(); + USBTransfer *fPendingTransfer = (USBTransfer *) fTransfers.RemoveItem((int32)0); + fTransfersLock.Unlock(); + fPendingTransfer->Do(fRawFD); + usbi_signal_transfer_completion(fPendingTransfer->UsbiTransfer()); + } +} + +status_t +USBDeviceHandle::SubmitTransfer(struct usbi_transfer *itransfer) +{ + USBTransfer *transfer = new USBTransfer(itransfer, fUSBDevice); + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = transfer; + BAutolock locker(fTransfersLock); + fTransfers.AddItem(transfer); + release_sem(fTransfersSem); + return LIBUSB_SUCCESS; +} + +status_t +USBDeviceHandle::CancelTransfer(USBTransfer *transfer) +{ + transfer->SetCancelled(); + fTransfersLock.Lock(); + bool removed = fTransfers.RemoveItem(transfer); + fTransfersLock.Unlock(); + if(removed) + usbi_signal_transfer_completion(transfer->UsbiTransfer()); + return LIBUSB_SUCCESS; +} + +USBDeviceHandle::USBDeviceHandle(USBDevice *dev) + : + fTransfersThread(-1), + fUSBDevice(dev), + fClaimedInterfaces(0), + fInitCheck(false) +{ + fRawFD = open(dev->Location(), O_RDWR | O_CLOEXEC); + if (fRawFD < 0) { + usbi_err(NULL,"failed to open device"); + return; + } + fTransfersSem = create_sem(0, "Transfers Queue Sem"); + fTransfersThread = spawn_thread(TransfersThread, "Transfer Worker", B_NORMAL_PRIORITY, this); + resume_thread(fTransfersThread); + fInitCheck = true; +} + +USBDeviceHandle::~USBDeviceHandle() +{ + if (fRawFD > 0) + close(fRawFD); + for(int i = 0; i < 32; i++) { + if (fClaimedInterfaces & (1 << i)) + ReleaseInterface(i); + } + delete_sem(fTransfersSem); + if (fTransfersThread > 0) + wait_for_thread(fTransfersThread, NULL); +} + +int +USBDeviceHandle::ClaimInterface(int inumber) +{ + int status = fUSBDevice->ClaimInterface(inumber); + if (status == LIBUSB_SUCCESS) + fClaimedInterfaces |= (1 << inumber); + return status; +} + +int +USBDeviceHandle::ReleaseInterface(int inumber) +{ + fUSBDevice->ReleaseInterface(inumber); + fClaimedInterfaces &= ~(1 << inumber); + return LIBUSB_SUCCESS; +} + +int +USBDeviceHandle::SetConfiguration(int config) +{ + int config_index = fUSBDevice->CheckInterfacesFree(config); + if(config_index == LIBUSB_ERROR_BUSY || config_index == LIBUSB_ERROR_NOT_FOUND) + return config_index; + usb_raw_command command; + command.config.config_index = config_index; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_CONFIGURATION, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + return _errno_to_libusb(command.config.status); + } + fUSBDevice->SetActiveConfiguration(config_index); + return LIBUSB_SUCCESS; +} + +int +USBDeviceHandle::SetAltSetting(int inumber, int alt) +{ + usb_raw_command command; + command.alternate.config_index = fUSBDevice->ActiveConfigurationIndex(); + command.alternate.interface_index = inumber; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, &command, sizeof(command)) || + command.alternate.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "Error retrieving active alternate interface"); + return _errno_to_libusb(command.alternate.status); + } + if (command.alternate.alternate_info == alt) { + usbi_dbg("Setting alternate interface successful"); + return LIBUSB_SUCCESS; + } + command.alternate.alternate_info = alt; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command, sizeof(command)) || + command.alternate.status != B_USB_RAW_STATUS_SUCCESS) { //IF IOCTL FAILS DEVICE DISONNECTED PROBABLY + usbi_err(NULL, "Error setting alternate interface"); + return _errno_to_libusb(command.alternate.status); + } + usbi_dbg("Setting alternate interface successful"); + return LIBUSB_SUCCESS; +} + + +USBDevice::USBDevice(const char *path) + : + fPath(NULL), + fActiveConfiguration(0), //0? + fConfigurationDescriptors(NULL), + fClaimedInterfaces(0), + fEndpointToIndex(NULL), + fEndpointToInterface(NULL), + fInitCheck(false) +{ + fPath=strdup(path); + Initialise(); +} + +USBDevice::~USBDevice() +{ + free(fPath); + if (fConfigurationDescriptors) { + for(int i = 0; i < fDeviceDescriptor.num_configurations; i++) { + if (fConfigurationDescriptors[i]) + delete fConfigurationDescriptors[i]; + } + delete[] fConfigurationDescriptors; + } + if (fEndpointToIndex) + delete[] fEndpointToIndex; + if (fEndpointToInterface) + delete[] fEndpointToInterface; +} + +bool +USBDevice::InitCheck() +{ + return fInitCheck; +} + +const char * +USBDevice::Location() const +{ + return fPath; +} + +uint8 +USBDevice::CountConfigurations() const +{ + return fDeviceDescriptor.num_configurations; +} + +const usb_device_descriptor * +USBDevice::Descriptor() const +{ + return &fDeviceDescriptor; +} + +const usb_configuration_descriptor * +USBDevice::ConfigurationDescriptor(uint32 index) const +{ + if (index > CountConfigurations()) + return NULL; + return (usb_configuration_descriptor *) fConfigurationDescriptors[index]; +} + +const usb_configuration_descriptor * +USBDevice::ActiveConfiguration() const +{ + return (usb_configuration_descriptor *) fConfigurationDescriptors[fActiveConfiguration]; +} + +int +USBDevice::ActiveConfigurationIndex() const +{ + return fActiveConfiguration; +} + +int USBDevice::ClaimInterface(int interface) +{ + if (interface > ActiveConfiguration()->number_interfaces) + return LIBUSB_ERROR_NOT_FOUND; + if (fClaimedInterfaces & (1 << interface)) + return LIBUSB_ERROR_BUSY; + fClaimedInterfaces |= (1 << interface); + return LIBUSB_SUCCESS; +} + +int USBDevice::ReleaseInterface(int interface) +{ + fClaimedInterfaces &= ~(1 << interface); + return LIBUSB_SUCCESS; +} + +int +USBDevice::CheckInterfacesFree(int config) +{ + if (fConfigToIndex.count(config) == 0) + return LIBUSB_ERROR_NOT_FOUND; + if (fClaimedInterfaces == 0) + return fConfigToIndex[(uint8)config]; + return LIBUSB_ERROR_BUSY; +} + +int +USBDevice::SetActiveConfiguration(int config_index) +{ + fActiveConfiguration = config_index; + return LIBUSB_SUCCESS; +} + +uint8 +USBDevice::EndpointToIndex(uint8 address) const +{ + return fEndpointToIndex[fActiveConfiguration][address]; +} + +uint8 +USBDevice::EndpointToInterface(uint8 address) const +{ + return fEndpointToInterface[fActiveConfiguration][address]; +} + +int +USBDevice::Initialise() //Do we need more error checking, etc? How to report? +{ + int fRawFD = open(fPath, O_RDWR | O_CLOEXEC); + if (fRawFD < 0) + return B_ERROR; + usb_raw_command command; + command.device.descriptor = &fDeviceDescriptor; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR, &command, sizeof(command)) || + command.device.status != B_USB_RAW_STATUS_SUCCESS) { + close(fRawFD); + return B_ERROR; + } + + fConfigurationDescriptors = new(std::nothrow) unsigned char *[fDeviceDescriptor.num_configurations]; + fEndpointToIndex = new(std::nothrow) map [fDeviceDescriptor.num_configurations]; + fEndpointToInterface = new(std::nothrow) map [fDeviceDescriptor.num_configurations]; + for (int i = 0; i < fDeviceDescriptor.num_configurations; i++) { + usb_configuration_descriptor tmp_config; + command.config.descriptor = &tmp_config; + command.config.config_index = i; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving configuration descriptor"); + close(fRawFD); + return B_ERROR; + } + fConfigToIndex[tmp_config.configuration_value] = i; + fConfigurationDescriptors[i] = new(std::nothrow) unsigned char[tmp_config.total_length]; + command.control.request_type = 128; + command.control.request = 6; + command.control.value = (2 << 8) | i; + command.control.index = 0; + command.control.length = tmp_config.total_length; + command.control.data = fConfigurationDescriptors[i]; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) || + command.control.status!=B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving full configuration descriptor"); + close(fRawFD); + return B_ERROR; + } + for (int j = 0; j < tmp_config.number_interfaces; j++) { + command.alternate.config_index = i; + command.alternate.interface_index = j; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving number of alternate interfaces"); + close(fRawFD); + return B_ERROR; + } + int num_alternate = command.alternate.alternate_info; + for (int k = 0; k < num_alternate; k++) { + usb_interface_descriptor tmp_interface; + command.interface_etc.config_index = i; + command.interface_etc.interface_index = j; + command.interface_etc.alternate_index = k; + command.interface_etc.descriptor = &tmp_interface; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving interface descriptor"); + close(fRawFD); + return B_ERROR; + } + for (int l = 0; l < tmp_interface.num_endpoints; l++) { + usb_endpoint_descriptor tmp_endpoint; + command.endpoint_etc.config_index = i; + command.endpoint_etc.interface_index = j; + command.endpoint_etc.alternate_index = k; + command.endpoint_etc.endpoint_index = l; + command.endpoint_etc.descriptor = &tmp_endpoint; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving endpoint descriptor"); + close(fRawFD); + return B_ERROR; + } + fEndpointToIndex[i][tmp_endpoint.endpoint_address] = l; + fEndpointToInterface[i][tmp_endpoint.endpoint_address] = j; + } + } + } + } + close(fRawFD); + fInitCheck = true; + return B_OK; +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.cpp b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.cpp new file mode 100644 index 00000000..77adbd1e --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.cpp @@ -0,0 +1,250 @@ +/* + * Haiku Backend for libusb + * Copyright © 2014 Akshay Jaggi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include +#include +#include +#include + +#include "haiku_usb.h" + +USBRoster gUsbRoster; +int32 gInitCount = 0; + +static int +haiku_init(struct libusb_context *ctx) +{ + if (atomic_add(&gInitCount, 1) == 0) + return gUsbRoster.Start(); + return LIBUSB_SUCCESS; +} + +static void +haiku_exit(void) +{ + if (atomic_add(&gInitCount, -1) == 1) + gUsbRoster.Stop(); +} + +static int +haiku_open(struct libusb_device_handle *dev_handle) +{ + USBDevice *dev = *((USBDevice **)dev_handle->dev->os_priv); + USBDeviceHandle *handle = new(std::nothrow) USBDeviceHandle(dev); + if (handle == NULL) + return LIBUSB_ERROR_NO_MEM; + if (handle->InitCheck() == false) { + delete handle; + return LIBUSB_ERROR_NO_DEVICE; + } + *((USBDeviceHandle **)dev_handle->os_priv) = handle; + return LIBUSB_SUCCESS; +} + +static void +haiku_close(struct libusb_device_handle *dev_handle) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + if (handle == NULL) + return; + delete handle; + *((USBDeviceHandle **)dev_handle->os_priv) = NULL; +} + +static int +haiku_get_device_descriptor(struct libusb_device *device, unsigned char *buffer, int *host_endian) +{ + USBDevice *dev = *((USBDevice **)device->os_priv); + memcpy(buffer, dev->Descriptor(), DEVICE_DESC_LENGTH); + *host_endian = 0; + return LIBUSB_SUCCESS; +} + +static int +haiku_get_active_config_descriptor(struct libusb_device *device, unsigned char *buffer, size_t len, int *host_endian) +{ + USBDevice *dev = *((USBDevice **)device->os_priv); + const usb_configuration_descriptor *act_config = dev->ActiveConfiguration(); + if (len > act_config->total_length) + return LIBUSB_ERROR_OVERFLOW; + memcpy(buffer, act_config, len); + *host_endian = 0; + return LIBUSB_SUCCESS; +} + +static int +haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + USBDevice *dev = *((USBDevice **)device->os_priv); + const usb_configuration_descriptor *config = dev->ConfigurationDescriptor(config_index); + if (config == NULL) { + usbi_err(DEVICE_CTX(device), "failed getting configuration descriptor"); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (len > config->total_length) + len = config->total_length; + memcpy(buffer, config, len); + *host_endian = 0; + return len; +} + +static int +haiku_set_configuration(struct libusb_device_handle *dev_handle, int config) +{ + USBDeviceHandle *handle= *((USBDeviceHandle **)dev_handle->os_priv); + return handle->SetConfiguration(config); +} + +static int +haiku_claim_interface(struct libusb_device_handle *dev_handle, int interface_number) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + return handle->ClaimInterface(interface_number); +} + +static int +haiku_set_altsetting(struct libusb_device_handle *dev_handle, int interface_number, int altsetting) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + return handle->SetAltSetting(interface_number, altsetting); +} + +static int +haiku_release_interface(struct libusb_device_handle *dev_handle, int interface_number) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + haiku_set_altsetting(dev_handle,interface_number, 0); + return handle->ReleaseInterface(interface_number); +} + +static int +haiku_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv); + return fDeviceHandle->SubmitTransfer(itransfer); +} + +static int +haiku_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv); + return fDeviceHandle->CancelTransfer(*((USBTransfer **)usbi_transfer_get_os_priv(itransfer))); +} + +static void +haiku_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)); + delete transfer; + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL; +} + +static int +haiku_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)); + + usbi_mutex_lock(&itransfer->lock); + if (transfer->IsCancelled()) { + delete transfer; + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL; + usbi_mutex_unlock(&itransfer->lock); + if (itransfer->transferred < 0) + itransfer->transferred = 0; + return usbi_handle_transfer_cancellation(itransfer); + } + libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED; + if (itransfer->transferred < 0) { + usbi_err(ITRANSFER_CTX(itransfer), "error in transfer"); + status = LIBUSB_TRANSFER_ERROR; + itransfer->transferred = 0; + } + delete transfer; + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); +} + +static int +haiku_clock_gettime(int clkid, struct timespec *tp) +{ + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + return LIBUSB_ERROR_INVALID_PARAM; +} + +const struct usbi_os_backend haiku_usb_raw_backend = { + /*.name =*/ "Haiku usbfs", + /*.caps =*/ 0, + /*.init =*/ haiku_init, + /*.exit =*/ haiku_exit, + /*.get_device_list =*/ NULL, + /*.hotplug_poll =*/ NULL, + /*.open =*/ haiku_open, + /*.close =*/ haiku_close, + /*.get_device_descriptor =*/ haiku_get_device_descriptor, + /*.get_active_config_descriptor =*/ haiku_get_active_config_descriptor, + /*.get_config_descriptor =*/ haiku_get_config_descriptor, + /*.get_config_descriptor_by_value =*/ NULL, + + + /*.get_configuration =*/ NULL, + /*.set_configuration =*/ haiku_set_configuration, + /*.claim_interface =*/ haiku_claim_interface, + /*.release_interface =*/ haiku_release_interface, + + /*.set_interface_altsetting =*/ haiku_set_altsetting, + /*.clear_halt =*/ NULL, + /*.reset_device =*/ NULL, + + /*.alloc_streams =*/ NULL, + /*.free_streams =*/ NULL, + + /*.dev_mem_alloc =*/ NULL, + /*.dev_mem_free =*/ NULL, + + /*.kernel_driver_active =*/ NULL, + /*.detach_kernel_driver =*/ NULL, + /*.attach_kernel_driver =*/ NULL, + + /*.destroy_device =*/ NULL, + + /*.submit_transfer =*/ haiku_submit_transfer, + /*.cancel_transfer =*/ haiku_cancel_transfer, + /*.clear_transfer_priv =*/ haiku_clear_transfer_priv, + + /*.handle_events =*/ NULL, + /*.handle_transfer_completion =*/ haiku_handle_transfer_completion, + + /*.clock_gettime =*/ haiku_clock_gettime, + +#ifdef USBI_TIMERFD_AVAILABLE + /*.get_timerfd_clockid =*/ NULL, +#endif + + /*.device_priv_size =*/ sizeof(USBDevice *), + /*.device_handle_priv_size =*/ sizeof(USBDeviceHandle *), + /*.transfer_priv_size =*/ sizeof(USBTransfer *), +}; diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.h new file mode 100644 index 00000000..5baf53d7 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.h @@ -0,0 +1,180 @@ +/* + * Copyright 2006-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#ifndef _USB_RAW_H_ +#define _USB_RAW_H_ + +#include + +#define B_USB_RAW_PROTOCOL_VERSION 0x0015 +#define B_USB_RAW_ACTIVE_ALTERNATE 0xffffffff + +typedef enum { + B_USB_RAW_COMMAND_GET_VERSION = 0x1000, + + B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR = 0x2000, + B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, + B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, + B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, + B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, + B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC, + + B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000, + B_USB_RAW_COMMAND_SET_FEATURE, + B_USB_RAW_COMMAND_CLEAR_FEATURE, + B_USB_RAW_COMMAND_GET_STATUS, + B_USB_RAW_COMMAND_GET_DESCRIPTOR, + B_USB_RAW_COMMAND_SET_ALT_INTERFACE, + + B_USB_RAW_COMMAND_CONTROL_TRANSFER = 0x4000, + B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, + B_USB_RAW_COMMAND_BULK_TRANSFER, + B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER +} usb_raw_command_id; + + +typedef enum { + B_USB_RAW_STATUS_SUCCESS = 0, + + B_USB_RAW_STATUS_FAILED, + B_USB_RAW_STATUS_ABORTED, + B_USB_RAW_STATUS_STALLED, + B_USB_RAW_STATUS_CRC_ERROR, + B_USB_RAW_STATUS_TIMEOUT, + + B_USB_RAW_STATUS_INVALID_CONFIGURATION, + B_USB_RAW_STATUS_INVALID_INTERFACE, + B_USB_RAW_STATUS_INVALID_ENDPOINT, + B_USB_RAW_STATUS_INVALID_STRING, + + B_USB_RAW_STATUS_NO_MEMORY +} usb_raw_command_status; + + +typedef union { + struct { + status_t status; + } version; + + struct { + status_t status; + usb_device_descriptor *descriptor; + } device; + + struct { + status_t status; + usb_configuration_descriptor *descriptor; + uint32 config_index; + } config; + + struct { + status_t status; + uint32 alternate_info; + uint32 config_index; + uint32 interface_index; + } alternate; + + struct { + status_t status; + usb_interface_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + } interface; + + struct { + status_t status; + usb_interface_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 alternate_index; + } interface_etc; + + struct { + status_t status; + usb_endpoint_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 endpoint_index; + } endpoint; + + struct { + status_t status; + usb_endpoint_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 alternate_index; + uint32 endpoint_index; + } endpoint_etc; + + struct { + status_t status; + usb_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 generic_index; + size_t length; + } generic; + + struct { + status_t status; + usb_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 alternate_index; + uint32 generic_index; + size_t length; + } generic_etc; + + struct { + status_t status; + usb_string_descriptor *descriptor; + uint32 string_index; + size_t length; + } string; + + struct { + status_t status; + uint8 type; + uint8 index; + uint16 language_id; + void *data; + size_t length; + } descriptor; + + struct { + status_t status; + uint8 request_type; + uint8 request; + uint16 value; + uint16 index; + uint16 length; + void *data; + } control; + + struct { + status_t status; + uint32 interface; + uint32 endpoint; + void *data; + size_t length; + } transfer; + + struct { + status_t status; + uint32 interface; + uint32 endpoint; + void *data; + size_t length; + usb_iso_packet_descriptor *packet_descriptors; + uint32 packet_count; + } isochronous; +} usb_raw_command; + +#endif // _USB_RAW_H_ diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_netlink.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_netlink.c new file mode 100644 index 00000000..60cf3ad1 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_netlink.c @@ -0,0 +1,400 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright (C) 2007-2009 Daniel Drake + * Copyright (c) 2001 Johannes Erdfelt + * Copyright (c) 2013 Nathan Hjelm + * Copyright (c) 2016 Chris Dickens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#include +#include + +#include "libusbi.h" +#include "linux_usbfs.h" + +#define NL_GROUP_KERNEL 1 + +static int linux_netlink_socket = -1; +static int netlink_control_pipe[2] = { -1, -1 }; +static pthread_t libusb_linux_event_thread; + +static void *linux_netlink_event_thread_main(void *arg); + +static int set_fd_cloexec_nb(int fd) +{ + int flags; + +#if defined(FD_CLOEXEC) + flags = fcntl(fd, F_GETFD); + if (flags == -1) { + usbi_err(NULL, "failed to get netlink fd flags (%d)", errno); + return -1; + } + + if (!(flags & FD_CLOEXEC)) { + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + usbi_err(NULL, "failed to set netlink fd flags (%d)", errno); + return -1; + } + } +#endif + + flags = fcntl(fd, F_GETFL); + if (flags == -1) { + usbi_err(NULL, "failed to get netlink fd status flags (%d)", errno); + return -1; + } + + if (!(flags & O_NONBLOCK)) { + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { + usbi_err(NULL, "failed to set netlink fd status flags (%d)", errno); + return -1; + } + } + + return 0; +} + +int linux_netlink_start_event_monitor(void) +{ + struct sockaddr_nl sa_nl = { .nl_family = AF_NETLINK, .nl_groups = NL_GROUP_KERNEL }; + int socktype = SOCK_RAW; + int opt = 1; + int ret; + +#if defined(SOCK_CLOEXEC) + socktype |= SOCK_CLOEXEC; +#endif +#if defined(SOCK_NONBLOCK) + socktype |= SOCK_NONBLOCK; +#endif + + linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT); + if (linux_netlink_socket == -1 && errno == EINVAL) { + usbi_dbg("failed to create netlink socket of type %d, attempting SOCK_RAW", socktype); + linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); + } + + if (linux_netlink_socket == -1) { + usbi_err(NULL, "failed to create netlink socket (%d)", errno); + goto err; + } + + ret = set_fd_cloexec_nb(linux_netlink_socket); + if (ret == -1) + goto err_close_socket; + + ret = bind(linux_netlink_socket, (struct sockaddr *)&sa_nl, sizeof(sa_nl)); + if (ret == -1) { + usbi_err(NULL, "failed to bind netlink socket (%d)", errno); + goto err_close_socket; + } + + ret = setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt)); + if (ret == -1) { + usbi_err(NULL, "failed to set netlink socket SO_PASSCRED option (%d)", errno); + goto err_close_socket; + } + + ret = usbi_pipe(netlink_control_pipe); + if (ret) { + usbi_err(NULL, "failed to create netlink control pipe"); + goto err_close_socket; + } + + ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL); + if (ret != 0) { + usbi_err(NULL, "failed to create netlink event thread (%d)", ret); + goto err_close_pipe; + } + + return LIBUSB_SUCCESS; + +err_close_pipe: + close(netlink_control_pipe[0]); + close(netlink_control_pipe[1]); + netlink_control_pipe[0] = -1; + netlink_control_pipe[1] = -1; +err_close_socket: + close(linux_netlink_socket); + linux_netlink_socket = -1; +err: + return LIBUSB_ERROR_OTHER; +} + +int linux_netlink_stop_event_monitor(void) +{ + char dummy = 1; + ssize_t r; + + assert(linux_netlink_socket != -1); + + /* Write some dummy data to the control pipe and + * wait for the thread to exit */ + r = usbi_write(netlink_control_pipe[1], &dummy, sizeof(dummy)); + if (r <= 0) + usbi_warn(NULL, "netlink control pipe signal failed"); + + pthread_join(libusb_linux_event_thread, NULL); + + close(linux_netlink_socket); + linux_netlink_socket = -1; + + /* close and reset control pipe */ + close(netlink_control_pipe[0]); + close(netlink_control_pipe[1]); + netlink_control_pipe[0] = -1; + netlink_control_pipe[1] = -1; + + return LIBUSB_SUCCESS; +} + +static const char *netlink_message_parse(const char *buffer, size_t len, const char *key) +{ + const char *end = buffer + len; + size_t keylen = strlen(key); + + while (buffer < end && *buffer) { + if (strncmp(buffer, key, keylen) == 0 && buffer[keylen] == '=') + return buffer + keylen + 1; + buffer += strlen(buffer) + 1; + } + + return NULL; +} + +/* parse parts of netlink message common to both libudev and the kernel */ +static int linux_netlink_parse(const char *buffer, size_t len, int *detached, + const char **sys_name, uint8_t *busnum, uint8_t *devaddr) +{ + const char *tmp, *slash; + + errno = 0; + + *sys_name = NULL; + *detached = 0; + *busnum = 0; + *devaddr = 0; + + tmp = netlink_message_parse(buffer, len, "ACTION"); + if (!tmp) { + return -1; + } else if (strcmp(tmp, "remove") == 0) { + *detached = 1; + } else if (strcmp(tmp, "add") != 0) { + usbi_dbg("unknown device action %s", tmp); + return -1; + } + + /* check that this is a usb message */ + tmp = netlink_message_parse(buffer, len, "SUBSYSTEM"); + if (!tmp || strcmp(tmp, "usb") != 0) { + /* not usb. ignore */ + return -1; + } + + /* check that this is an actual usb device */ + tmp = netlink_message_parse(buffer, len, "DEVTYPE"); + if (!tmp || strcmp(tmp, "usb_device") != 0) { + /* not usb. ignore */ + return -1; + } + + tmp = netlink_message_parse(buffer, len, "BUSNUM"); + if (tmp) { + *busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + tmp = netlink_message_parse(buffer, len, "DEVNUM"); + if (NULL == tmp) + return -1; + + *devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + } else { + /* no bus number. try "DEVICE" */ + tmp = netlink_message_parse(buffer, len, "DEVICE"); + if (!tmp) { + /* not usb. ignore */ + return -1; + } + + /* Parse a device path such as /dev/bus/usb/003/004 */ + slash = strrchr(tmp, '/'); + if (!slash) + return -1; + + *busnum = (uint8_t)(strtoul(slash - 3, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + *devaddr = (uint8_t)(strtoul(slash + 1, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + return 0; + } + + tmp = netlink_message_parse(buffer, len, "DEVPATH"); + if (!tmp) + return -1; + + slash = strrchr(tmp, '/'); + if (slash) + *sys_name = slash + 1; + + /* found a usb device */ + return 0; +} + +static int linux_netlink_read_message(void) +{ + char cred_buffer[CMSG_SPACE(sizeof(struct ucred))]; + char msg_buffer[2048]; + const char *sys_name = NULL; + uint8_t busnum, devaddr; + int detached, r; + ssize_t len; + struct cmsghdr *cmsg; + struct ucred *cred; + struct sockaddr_nl sa_nl; + struct iovec iov = { .iov_base = msg_buffer, .iov_len = sizeof(msg_buffer) }; + struct msghdr msg = { + .msg_iov = &iov, .msg_iovlen = 1, + .msg_control = cred_buffer, .msg_controllen = sizeof(cred_buffer), + .msg_name = &sa_nl, .msg_namelen = sizeof(sa_nl) + }; + + /* read netlink message */ + len = recvmsg(linux_netlink_socket, &msg, 0); + if (len == -1) { + if (errno != EAGAIN && errno != EINTR) + usbi_err(NULL, "error receiving message from netlink (%d)", errno); + return -1; + } + + if (len < 32 || (msg.msg_flags & MSG_TRUNC)) { + usbi_err(NULL, "invalid netlink message length"); + return -1; + } + + if (sa_nl.nl_groups != NL_GROUP_KERNEL || sa_nl.nl_pid != 0) { + usbi_dbg("ignoring netlink message from unknown group/PID (%u/%u)", + (unsigned int)sa_nl.nl_groups, (unsigned int)sa_nl.nl_pid); + return -1; + } + + cmsg = CMSG_FIRSTHDR(&msg); + if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) { + usbi_dbg("ignoring netlink message with no sender credentials"); + return -1; + } + + cred = (struct ucred *)CMSG_DATA(cmsg); + if (cred->uid != 0) { + usbi_dbg("ignoring netlink message with non-zero sender UID %u", (unsigned int)cred->uid); + return -1; + } + + r = linux_netlink_parse(msg_buffer, (size_t)len, &detached, &sys_name, &busnum, &devaddr); + if (r) + return r; + + usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s", + busnum, devaddr, sys_name, detached ? "yes" : "no"); + + /* signal device is available (or not) to all contexts */ + if (detached) + linux_device_disconnected(busnum, devaddr); + else + linux_hotplug_enumerate(busnum, devaddr, sys_name); + + return 0; +} + +static void *linux_netlink_event_thread_main(void *arg) +{ + char dummy; + ssize_t r; + struct pollfd fds[] = { + { .fd = netlink_control_pipe[0], + .events = POLLIN }, + { .fd = linux_netlink_socket, + .events = POLLIN }, + }; + + UNUSED(arg); + + usbi_dbg("netlink event thread entering"); + + while (poll(fds, 2, -1) >= 0) { + if (fds[0].revents & POLLIN) { + /* activity on control pipe, read the byte and exit */ + r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy)); + if (r <= 0) + usbi_warn(NULL, "netlink control pipe read failed"); + break; + } + if (fds[1].revents & POLLIN) { + usbi_mutex_static_lock(&linux_hotplug_lock); + linux_netlink_read_message(); + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + } + + usbi_dbg("netlink event thread exiting"); + + return NULL; +} + +void linux_netlink_hotplug_poll(void) +{ + int r; + + usbi_mutex_static_lock(&linux_hotplug_lock); + do { + r = linux_netlink_read_message(); + } while (r == 0); + usbi_mutex_static_unlock(&linux_hotplug_lock); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_udev.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_udev.c new file mode 100644 index 00000000..61d953d8 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_udev.c @@ -0,0 +1,311 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright (C) 2007-2009 Daniel Drake + * Copyright (c) 2001 Johannes Erdfelt + * Copyright (c) 2012-2013 Nathan Hjelm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "linux_usbfs.h" + +/* udev context */ +static struct udev *udev_ctx = NULL; +static int udev_monitor_fd = -1; +static int udev_control_pipe[2] = {-1, -1}; +static struct udev_monitor *udev_monitor = NULL; +static pthread_t linux_event_thread; + +static void udev_hotplug_event(struct udev_device* udev_dev); +static void *linux_udev_event_thread_main(void *arg); + +int linux_udev_start_event_monitor(void) +{ + int r; + + assert(udev_ctx == NULL); + udev_ctx = udev_new(); + if (!udev_ctx) { + usbi_err(NULL, "could not create udev context"); + goto err; + } + + udev_monitor = udev_monitor_new_from_netlink(udev_ctx, "udev"); + if (!udev_monitor) { + usbi_err(NULL, "could not initialize udev monitor"); + goto err_free_ctx; + } + + r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device"); + if (r) { + usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem"); + goto err_free_monitor; + } + + if (udev_monitor_enable_receiving(udev_monitor)) { + usbi_err(NULL, "failed to enable the udev monitor"); + goto err_free_monitor; + } + + udev_monitor_fd = udev_monitor_get_fd(udev_monitor); + + /* Some older versions of udev are not non-blocking by default, + * so make sure this is set */ + r = fcntl(udev_monitor_fd, F_GETFL); + if (r == -1) { + usbi_err(NULL, "getting udev monitor fd flags (%d)", errno); + goto err_free_monitor; + } + r = fcntl(udev_monitor_fd, F_SETFL, r | O_NONBLOCK); + if (r) { + usbi_err(NULL, "setting udev monitor fd flags (%d)", errno); + goto err_free_monitor; + } + + r = usbi_pipe(udev_control_pipe); + if (r) { + usbi_err(NULL, "could not create udev control pipe"); + goto err_free_monitor; + } + + r = pthread_create(&linux_event_thread, NULL, linux_udev_event_thread_main, NULL); + if (r) { + usbi_err(NULL, "creating hotplug event thread (%d)", r); + goto err_close_pipe; + } + + return LIBUSB_SUCCESS; + +err_close_pipe: + close(udev_control_pipe[0]); + close(udev_control_pipe[1]); +err_free_monitor: + udev_monitor_unref(udev_monitor); + udev_monitor = NULL; + udev_monitor_fd = -1; +err_free_ctx: + udev_unref(udev_ctx); +err: + udev_ctx = NULL; + return LIBUSB_ERROR_OTHER; +} + +int linux_udev_stop_event_monitor(void) +{ + char dummy = 1; + int r; + + assert(udev_ctx != NULL); + assert(udev_monitor != NULL); + assert(udev_monitor_fd != -1); + + /* Write some dummy data to the control pipe and + * wait for the thread to exit */ + r = usbi_write(udev_control_pipe[1], &dummy, sizeof(dummy)); + if (r <= 0) { + usbi_warn(NULL, "udev control pipe signal failed"); + } + pthread_join(linux_event_thread, NULL); + + /* Release the udev monitor */ + udev_monitor_unref(udev_monitor); + udev_monitor = NULL; + udev_monitor_fd = -1; + + /* Clean up the udev context */ + udev_unref(udev_ctx); + udev_ctx = NULL; + + /* close and reset control pipe */ + close(udev_control_pipe[0]); + close(udev_control_pipe[1]); + udev_control_pipe[0] = -1; + udev_control_pipe[1] = -1; + + return LIBUSB_SUCCESS; +} + +static void *linux_udev_event_thread_main(void *arg) +{ + char dummy; + int r; + struct udev_device* udev_dev; + struct pollfd fds[] = { + {.fd = udev_control_pipe[0], + .events = POLLIN}, + {.fd = udev_monitor_fd, + .events = POLLIN}, + }; + + usbi_dbg("udev event thread entering."); + + while ((r = poll(fds, 2, -1)) >= 0 || errno == EINTR) { + if (r < 0) { + /* temporary failure */ + continue; + } + if (fds[0].revents & POLLIN) { + /* activity on control pipe, read the byte and exit */ + r = usbi_read(udev_control_pipe[0], &dummy, sizeof(dummy)); + if (r <= 0) { + usbi_warn(NULL, "udev control pipe read failed"); + } + break; + } + if (fds[1].revents & POLLIN) { + usbi_mutex_static_lock(&linux_hotplug_lock); + udev_dev = udev_monitor_receive_device(udev_monitor); + if (udev_dev) + udev_hotplug_event(udev_dev); + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + } + + usbi_dbg("udev event thread exiting"); + + return NULL; +} + +static int udev_device_info(struct libusb_context *ctx, int detached, + struct udev_device *udev_dev, uint8_t *busnum, + uint8_t *devaddr, const char **sys_name) { + const char *dev_node; + + dev_node = udev_device_get_devnode(udev_dev); + if (!dev_node) { + return LIBUSB_ERROR_OTHER; + } + + *sys_name = udev_device_get_sysname(udev_dev); + if (!*sys_name) { + return LIBUSB_ERROR_OTHER; + } + + return linux_get_device_address(ctx, detached, busnum, devaddr, + dev_node, *sys_name); +} + +static void udev_hotplug_event(struct udev_device* udev_dev) +{ + const char* udev_action; + const char* sys_name = NULL; + uint8_t busnum = 0, devaddr = 0; + int detached; + int r; + + do { + udev_action = udev_device_get_action(udev_dev); + if (!udev_action) { + break; + } + + detached = !strncmp(udev_action, "remove", 6); + + r = udev_device_info(NULL, detached, udev_dev, &busnum, &devaddr, &sys_name); + if (LIBUSB_SUCCESS != r) { + break; + } + + usbi_dbg("udev hotplug event. action: %s.", udev_action); + + if (strncmp(udev_action, "add", 3) == 0) { + linux_hotplug_enumerate(busnum, devaddr, sys_name); + } else if (detached) { + linux_device_disconnected(busnum, devaddr); + } else { + usbi_err(NULL, "ignoring udev action %s", udev_action); + } + } while (0); + + udev_device_unref(udev_dev); +} + +int linux_udev_scan_devices(struct libusb_context *ctx) +{ + struct udev_enumerate *enumerator; + struct udev_list_entry *devices, *entry; + struct udev_device *udev_dev; + const char *sys_name; + int r; + + assert(udev_ctx != NULL); + + enumerator = udev_enumerate_new(udev_ctx); + if (NULL == enumerator) { + usbi_err(ctx, "error creating udev enumerator"); + return LIBUSB_ERROR_OTHER; + } + + udev_enumerate_add_match_subsystem(enumerator, "usb"); + udev_enumerate_add_match_property(enumerator, "DEVTYPE", "usb_device"); + udev_enumerate_scan_devices(enumerator); + devices = udev_enumerate_get_list_entry(enumerator); + + udev_list_entry_foreach(entry, devices) { + const char *path = udev_list_entry_get_name(entry); + uint8_t busnum = 0, devaddr = 0; + + udev_dev = udev_device_new_from_syspath(udev_ctx, path); + + r = udev_device_info(ctx, 0, udev_dev, &busnum, &devaddr, &sys_name); + if (r) { + udev_device_unref(udev_dev); + continue; + } + + linux_enumerate_device(ctx, busnum, devaddr, sys_name); + udev_device_unref(udev_dev); + } + + udev_enumerate_unref(enumerator); + + return LIBUSB_SUCCESS; +} + +void linux_udev_hotplug_poll(void) +{ + struct udev_device* udev_dev; + + usbi_mutex_static_lock(&linux_hotplug_lock); + do { + udev_dev = udev_monitor_receive_device(udev_monitor); + if (udev_dev) { + usbi_dbg("Handling hotplug event from hotplug_poll"); + udev_hotplug_event(udev_dev); + } + } while (udev_dev); + usbi_mutex_static_unlock(&linux_hotplug_lock); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.c new file mode 100644 index 00000000..6b89ba28 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.c @@ -0,0 +1,2738 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2013 Nathan Hjelm + * Copyright © 2012-2013 Hans de Goede + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "linux_usbfs.h" + +/* sysfs vs usbfs: + * opening a usbfs node causes the device to be resumed, so we attempt to + * avoid this during enumeration. + * + * sysfs allows us to read the kernel's in-memory copies of device descriptors + * and so forth, avoiding the need to open the device: + * - The binary "descriptors" file contains all config descriptors since + * 2.6.26, commit 217a9081d8e69026186067711131b77f0ce219ed + * - The binary "descriptors" file was added in 2.6.23, commit + * 69d42a78f935d19384d1f6e4f94b65bb162b36df, but it only contains the + * active config descriptors + * - The "busnum" file was added in 2.6.22, commit + * 83f7d958eab2fbc6b159ee92bf1493924e1d0f72 + * - The "devnum" file has been present since pre-2.6.18 + * - the "bConfigurationValue" file has been present since pre-2.6.18 + * + * If we have bConfigurationValue, busnum, and devnum, then we can determine + * the active configuration without having to open the usbfs node in RDWR mode. + * The busnum file is important as that is the only way we can relate sysfs + * devices to usbfs nodes. + * + * If we also have all descriptors, we can obtain the device descriptor and + * configuration without touching usbfs at all. + */ + +/* endianness for multi-byte fields: + * + * Descriptors exposed by usbfs have the multi-byte fields in the device + * descriptor as host endian. Multi-byte fields in the other descriptors are + * bus-endian. The kernel documentation says otherwise, but it is wrong. + * + * In sysfs all descriptors are bus-endian. + */ + +static const char *usbfs_path = NULL; + +/* use usbdev*.* device names in /dev instead of the usbfs bus directories */ +static int usbdev_names = 0; + +/* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically + * allows us to mark URBs as being part of a specific logical transfer when + * we submit them to the kernel. then, on any error except a cancellation, all + * URBs within that transfer will be cancelled and no more URBs will be + * accepted for the transfer, meaning that no more data can creep in. + * + * The BULK_CONTINUATION flag must be set on all URBs within a bulk transfer + * (in either direction) except the first. + * For IN transfers, we must also set SHORT_NOT_OK on all URBs except the + * last; it means that the kernel should treat a short reply as an error. + * For OUT transfers, SHORT_NOT_OK must not be set. it isn't needed (OUT + * transfers can't be short unless there's already some sort of error), and + * setting this flag is disallowed (a kernel with USB debugging enabled will + * reject such URBs). + */ +static int supports_flag_bulk_continuation = -1; + +/* Linux 2.6.31 fixes support for the zero length packet URB flag. This + * allows us to mark URBs that should be followed by a zero length data + * packet, which can be required by device- or class-specific protocols. + */ +static int supports_flag_zero_packet = -1; + +/* clock ID for monotonic clock, as not all clock sources are available on all + * systems. appropriate choice made at initialization time. */ +static clockid_t monotonic_clkid = -1; + +/* Linux 2.6.22 (commit 83f7d958eab2fbc6b159ee92bf1493924e1d0f72) adds a busnum + * to sysfs, so we can relate devices. This also implies that we can read + * the active configuration through bConfigurationValue */ +static int sysfs_can_relate_devices = -1; + +/* Linux 2.6.26 (commit 217a9081d8e69026186067711131b77f0ce219ed) adds all + * config descriptors (rather then just the active config) to the sysfs + * descriptors file, so from then on we can use them. */ +static int sysfs_has_descriptors = -1; + +/* how many times have we initted (and not exited) ? */ +static int init_count = 0; + +/* Serialize hotplug start/stop */ +static usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER; +/* Serialize scan-devices, event-thread, and poll */ +usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER; + +static int linux_start_event_monitor(void); +static int linux_stop_event_monitor(void); +static int linux_scan_devices(struct libusb_context *ctx); +static int sysfs_scan_device(struct libusb_context *ctx, const char *devname); +static int detach_kernel_driver_and_claim(struct libusb_device_handle *, int); + +#if !defined(USE_UDEV) +static int linux_default_scan_devices (struct libusb_context *ctx); +#endif + +struct linux_device_priv { + char *sysfs_dir; + unsigned char *descriptors; + int descriptors_len; + int active_config; /* cache val for !sysfs_can_relate_devices */ +}; + +struct linux_device_handle_priv { + int fd; + int fd_removed; + uint32_t caps; +}; + +enum reap_action { + NORMAL = 0, + /* submission failed after the first URB, so await cancellation/completion + * of all the others */ + SUBMIT_FAILED, + + /* cancelled by user or timeout */ + CANCELLED, + + /* completed multi-URB transfer in non-final URB */ + COMPLETED_EARLY, + + /* one or more urbs encountered a low-level error */ + ERROR, +}; + +struct linux_transfer_priv { + union { + struct usbfs_urb *urbs; + struct usbfs_urb **iso_urbs; + }; + + enum reap_action reap_action; + int num_urbs; + int num_retired; + enum libusb_transfer_status reap_status; + + /* next iso packet in user-supplied transfer to be populated */ + int iso_packet_offset; +}; + +static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + char path[PATH_MAX]; + int fd; + int delay = 10000; + + if (usbdev_names) + snprintf(path, PATH_MAX, "%s/usbdev%d.%d", + usbfs_path, dev->bus_number, dev->device_address); + else + snprintf(path, PATH_MAX, "%s/%03d/%03d", + usbfs_path, dev->bus_number, dev->device_address); + + fd = open(path, mode); + if (fd != -1) + return fd; /* Success */ + + if (errno == ENOENT) { + if (!silent) + usbi_err(ctx, "File doesn't exist, wait %d ms and try again", delay/1000); + + /* Wait 10ms for USB device path creation.*/ + nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL); + + fd = open(path, mode); + if (fd != -1) + return fd; /* Success */ + } + + if (!silent) { + usbi_err(ctx, "libusb couldn't open USB device %s: %s", + path, strerror(errno)); + if (errno == EACCES && mode == O_RDWR) + usbi_err(ctx, "libusb requires write access to USB " + "device nodes."); + } + + if (errno == EACCES) + return LIBUSB_ERROR_ACCESS; + if (errno == ENOENT) + return LIBUSB_ERROR_NO_DEVICE; + return LIBUSB_ERROR_IO; +} + +static struct linux_device_priv *_device_priv(struct libusb_device *dev) +{ + return (struct linux_device_priv *) dev->os_priv; +} + +static struct linux_device_handle_priv *_device_handle_priv( + struct libusb_device_handle *handle) +{ + return (struct linux_device_handle_priv *) handle->os_priv; +} + +/* check dirent for a /dev/usbdev%d.%d name + * optionally return bus/device on success */ +static int _is_usbdev_entry(struct dirent *entry, int *bus_p, int *dev_p) +{ + int busnum, devnum; + + if (sscanf(entry->d_name, "usbdev%d.%d", &busnum, &devnum) != 2) + return 0; + + usbi_dbg("found: %s", entry->d_name); + if (bus_p != NULL) + *bus_p = busnum; + if (dev_p != NULL) + *dev_p = devnum; + return 1; +} + +static int check_usb_vfs(const char *dirname) +{ + DIR *dir; + struct dirent *entry; + int found = 0; + + dir = opendir(dirname); + if (!dir) + return 0; + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_name[0] == '.') + continue; + + /* We assume if we find any files that it must be the right place */ + found = 1; + break; + } + + closedir(dir); + return found; +} + +static const char *find_usbfs_path(void) +{ + const char *path = "/dev/bus/usb"; + const char *ret = NULL; + + if (check_usb_vfs(path)) { + ret = path; + } else { + path = "/proc/bus/usb"; + if (check_usb_vfs(path)) + ret = path; + } + + /* look for /dev/usbdev*.* if the normal places fail */ + if (ret == NULL) { + struct dirent *entry; + DIR *dir; + + path = "/dev"; + dir = opendir(path); + if (dir != NULL) { + while ((entry = readdir(dir)) != NULL) { + if (_is_usbdev_entry(entry, NULL, NULL)) { + /* found one; that's enough */ + ret = path; + usbdev_names = 1; + break; + } + } + closedir(dir); + } + } + +/* On udev based systems without any usb-devices /dev/bus/usb will not + * exist. So if we've not found anything and we're using udev for hotplug + * simply assume /dev/bus/usb rather then making libusb_init fail. */ +#if defined(USE_UDEV) + if (ret == NULL) + ret = "/dev/bus/usb"; +#endif + + if (ret != NULL) + usbi_dbg("found usbfs at %s", ret); + + return ret; +} + +/* the monotonic clock is not usable on all systems (e.g. embedded ones often + * seem to lack it). fall back to REALTIME if we have to. */ +static clockid_t find_monotonic_clock(void) +{ +#ifdef CLOCK_MONOTONIC + struct timespec ts; + int r; + + /* Linux 2.6.28 adds CLOCK_MONOTONIC_RAW but we don't use it + * because it's not available through timerfd */ + r = clock_gettime(CLOCK_MONOTONIC, &ts); + if (r == 0) + return CLOCK_MONOTONIC; + usbi_dbg("monotonic clock doesn't work, errno %d", errno); +#endif + + return CLOCK_REALTIME; +} + +static int kernel_version_ge(int major, int minor, int sublevel) +{ + struct utsname uts; + int atoms, kmajor, kminor, ksublevel; + + if (uname(&uts) < 0) + return -1; + atoms = sscanf(uts.release, "%d.%d.%d", &kmajor, &kminor, &ksublevel); + if (atoms < 1) + return -1; + + if (kmajor > major) + return 1; + if (kmajor < major) + return 0; + + /* kmajor == major */ + if (atoms < 2) + return 0 == minor && 0 == sublevel; + if (kminor > minor) + return 1; + if (kminor < minor) + return 0; + + /* kminor == minor */ + if (atoms < 3) + return 0 == sublevel; + + return ksublevel >= sublevel; +} + +static int op_init(struct libusb_context *ctx) +{ + struct stat statbuf; + int r; + + usbfs_path = find_usbfs_path(); + if (!usbfs_path) { + usbi_err(ctx, "could not find usbfs"); + return LIBUSB_ERROR_OTHER; + } + + if (monotonic_clkid == -1) + monotonic_clkid = find_monotonic_clock(); + + if (supports_flag_bulk_continuation == -1) { + /* bulk continuation URB flag available from Linux 2.6.32 */ + supports_flag_bulk_continuation = kernel_version_ge(2,6,32); + if (supports_flag_bulk_continuation == -1) { + usbi_err(ctx, "error checking for bulk continuation support"); + return LIBUSB_ERROR_OTHER; + } + } + + if (supports_flag_bulk_continuation) + usbi_dbg("bulk continuation flag supported"); + + if (-1 == supports_flag_zero_packet) { + /* zero length packet URB flag fixed since Linux 2.6.31 */ + supports_flag_zero_packet = kernel_version_ge(2,6,31); + if (-1 == supports_flag_zero_packet) { + usbi_err(ctx, "error checking for zero length packet support"); + return LIBUSB_ERROR_OTHER; + } + } + + if (supports_flag_zero_packet) + usbi_dbg("zero length packet flag supported"); + + if (-1 == sysfs_has_descriptors) { + /* sysfs descriptors has all descriptors since Linux 2.6.26 */ + sysfs_has_descriptors = kernel_version_ge(2,6,26); + if (-1 == sysfs_has_descriptors) { + usbi_err(ctx, "error checking for sysfs descriptors"); + return LIBUSB_ERROR_OTHER; + } + } + + if (-1 == sysfs_can_relate_devices) { + /* sysfs has busnum since Linux 2.6.22 */ + sysfs_can_relate_devices = kernel_version_ge(2,6,22); + if (-1 == sysfs_can_relate_devices) { + usbi_err(ctx, "error checking for sysfs busnum"); + return LIBUSB_ERROR_OTHER; + } + } + + if (sysfs_can_relate_devices || sysfs_has_descriptors) { + r = stat(SYSFS_DEVICE_PATH, &statbuf); + if (r != 0 || !S_ISDIR(statbuf.st_mode)) { + usbi_warn(ctx, "sysfs not mounted"); + sysfs_can_relate_devices = 0; + sysfs_has_descriptors = 0; + } + } + + if (sysfs_can_relate_devices) + usbi_dbg("sysfs can relate devices"); + + if (sysfs_has_descriptors) + usbi_dbg("sysfs has complete descriptors"); + + usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + r = LIBUSB_SUCCESS; + if (init_count == 0) { + /* start up hotplug event handler */ + r = linux_start_event_monitor(); + } + if (r == LIBUSB_SUCCESS) { + r = linux_scan_devices(ctx); + if (r == LIBUSB_SUCCESS) + init_count++; + else if (init_count == 0) + linux_stop_event_monitor(); + } else + usbi_err(ctx, "error starting hotplug event monitor"); + usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); + + return r; +} + +static void op_exit(void) +{ + usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + assert(init_count != 0); + if (!--init_count) { + /* tear down event handler */ + (void)linux_stop_event_monitor(); + } + usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); +} + +static int linux_start_event_monitor(void) +{ +#if defined(USE_UDEV) + return linux_udev_start_event_monitor(); +#else + return linux_netlink_start_event_monitor(); +#endif +} + +static int linux_stop_event_monitor(void) +{ +#if defined(USE_UDEV) + return linux_udev_stop_event_monitor(); +#else + return linux_netlink_stop_event_monitor(); +#endif +} + +static int linux_scan_devices(struct libusb_context *ctx) +{ + int ret; + + usbi_mutex_static_lock(&linux_hotplug_lock); + +#if defined(USE_UDEV) + ret = linux_udev_scan_devices(ctx); +#else + ret = linux_default_scan_devices(ctx); +#endif + + usbi_mutex_static_unlock(&linux_hotplug_lock); + + return ret; +} + +static void op_hotplug_poll(void) +{ +#if defined(USE_UDEV) + linux_udev_hotplug_poll(); +#else + linux_netlink_hotplug_poll(); +#endif +} + +static int _open_sysfs_attr(struct libusb_device *dev, const char *attr) +{ + struct linux_device_priv *priv = _device_priv(dev); + char filename[PATH_MAX]; + int fd; + + snprintf(filename, PATH_MAX, "%s/%s/%s", + SYSFS_DEVICE_PATH, priv->sysfs_dir, attr); + fd = open(filename, O_RDONLY); + if (fd < 0) { + usbi_err(DEVICE_CTX(dev), + "open %s failed ret=%d errno=%d", filename, fd, errno); + return LIBUSB_ERROR_IO; + } + + return fd; +} + +/* Note only suitable for attributes which always read >= 0, < 0 is error */ +static int __read_sysfs_attr(struct libusb_context *ctx, + const char *devname, const char *attr) +{ + char filename[PATH_MAX]; + FILE *f; + int r, value; + + snprintf(filename, PATH_MAX, "%s/%s/%s", SYSFS_DEVICE_PATH, + devname, attr); + f = fopen(filename, "r"); + if (f == NULL) { + if (errno == ENOENT) { + /* File doesn't exist. Assume the device has been + disconnected (see trac ticket #70). */ + return LIBUSB_ERROR_NO_DEVICE; + } + usbi_err(ctx, "open %s failed errno=%d", filename, errno); + return LIBUSB_ERROR_IO; + } + + r = fscanf(f, "%d", &value); + fclose(f); + if (r != 1) { + usbi_err(ctx, "fscanf %s returned %d, errno=%d", attr, r, errno); + return LIBUSB_ERROR_NO_DEVICE; /* For unplug race (trac #70) */ + } + if (value < 0) { + usbi_err(ctx, "%s contains a negative value", filename); + return LIBUSB_ERROR_IO; + } + + return value; +} + +static int op_get_device_descriptor(struct libusb_device *dev, + unsigned char *buffer, int *host_endian) +{ + struct linux_device_priv *priv = _device_priv(dev); + + *host_endian = sysfs_has_descriptors ? 0 : 1; + memcpy(buffer, priv->descriptors, DEVICE_DESC_LENGTH); + + return 0; +} + +/* read the bConfigurationValue for a device */ +static int sysfs_get_active_config(struct libusb_device *dev, int *config) +{ + char *endptr; + char tmp[5] = {0, 0, 0, 0, 0}; + long num; + int fd; + ssize_t r; + + fd = _open_sysfs_attr(dev, "bConfigurationValue"); + if (fd < 0) + return fd; + + r = read(fd, tmp, sizeof(tmp)); + close(fd); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "read bConfigurationValue failed ret=%d errno=%d", r, errno); + return LIBUSB_ERROR_IO; + } else if (r == 0) { + usbi_dbg("device unconfigured"); + *config = -1; + return 0; + } + + if (tmp[sizeof(tmp) - 1] != 0) { + usbi_err(DEVICE_CTX(dev), "not null-terminated?"); + return LIBUSB_ERROR_IO; + } else if (tmp[0] == 0) { + usbi_err(DEVICE_CTX(dev), "no configuration value?"); + return LIBUSB_ERROR_IO; + } + + num = strtol(tmp, &endptr, 10); + if (endptr == tmp) { + usbi_err(DEVICE_CTX(dev), "error converting '%s' to integer", tmp); + return LIBUSB_ERROR_IO; + } + + *config = (int) num; + return 0; +} + +int linux_get_device_address (struct libusb_context *ctx, int detached, + uint8_t *busnum, uint8_t *devaddr,const char *dev_node, + const char *sys_name) +{ + int sysfs_attr; + + usbi_dbg("getting address for device: %s detached: %d", sys_name, detached); + /* can't use sysfs to read the bus and device number if the + * device has been detached */ + if (!sysfs_can_relate_devices || detached || NULL == sys_name) { + if (NULL == dev_node) { + return LIBUSB_ERROR_OTHER; + } + + /* will this work with all supported kernel versions? */ + if (!strncmp(dev_node, "/dev/bus/usb", 12)) { + sscanf (dev_node, "/dev/bus/usb/%hhu/%hhu", busnum, devaddr); + } else if (!strncmp(dev_node, "/proc/bus/usb", 13)) { + sscanf (dev_node, "/proc/bus/usb/%hhu/%hhu", busnum, devaddr); + } + + return LIBUSB_SUCCESS; + } + + usbi_dbg("scan %s", sys_name); + + sysfs_attr = __read_sysfs_attr(ctx, sys_name, "busnum"); + if (0 > sysfs_attr) + return sysfs_attr; + if (sysfs_attr > 255) + return LIBUSB_ERROR_INVALID_PARAM; + *busnum = (uint8_t) sysfs_attr; + + sysfs_attr = __read_sysfs_attr(ctx, sys_name, "devnum"); + if (0 > sysfs_attr) + return sysfs_attr; + if (sysfs_attr > 255) + return LIBUSB_ERROR_INVALID_PARAM; + + *devaddr = (uint8_t) sysfs_attr; + + usbi_dbg("bus=%d dev=%d", *busnum, *devaddr); + + return LIBUSB_SUCCESS; +} + +/* Return offset of the next descriptor with the given type */ +static int seek_to_next_descriptor(struct libusb_context *ctx, + uint8_t descriptor_type, unsigned char *buffer, int size) +{ + struct usb_descriptor_header header; + int i; + + for (i = 0; size >= 0; i += header.bLength, size -= header.bLength) { + if (size == 0) + return LIBUSB_ERROR_NOT_FOUND; + + if (size < 2) { + usbi_err(ctx, "short descriptor read %d/2", size); + return LIBUSB_ERROR_IO; + } + usbi_parse_descriptor(buffer + i, "bb", &header, 0); + + if (i && header.bDescriptorType == descriptor_type) + return i; + } + usbi_err(ctx, "bLength overflow by %d bytes", -size); + return LIBUSB_ERROR_IO; +} + +/* Return offset to next config */ +static int seek_to_next_config(struct libusb_context *ctx, + unsigned char *buffer, int size) +{ + struct libusb_config_descriptor config; + + if (size == 0) + return LIBUSB_ERROR_NOT_FOUND; + + if (size < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "short descriptor read %d/%d", + size, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwbbbbb", &config, 0); + if (config.bDescriptorType != LIBUSB_DT_CONFIG) { + usbi_err(ctx, "descriptor is not a config desc (type 0x%02x)", + config.bDescriptorType); + return LIBUSB_ERROR_IO; + } + + /* + * In usbfs the config descriptors are config.wTotalLength bytes apart, + * with any short reads from the device appearing as holes in the file. + * + * In sysfs wTotalLength is ignored, instead the kernel returns a + * config descriptor with verified bLength fields, with descriptors + * with an invalid bLength removed. + */ + if (sysfs_has_descriptors) { + int next = seek_to_next_descriptor(ctx, LIBUSB_DT_CONFIG, + buffer, size); + if (next == LIBUSB_ERROR_NOT_FOUND) + next = size; + if (next < 0) + return next; + + if (next != config.wTotalLength) + usbi_warn(ctx, "config length mismatch wTotalLength " + "%d real %d", config.wTotalLength, next); + return next; + } else { + if (config.wTotalLength < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "invalid wTotalLength %d", + config.wTotalLength); + return LIBUSB_ERROR_IO; + } else if (config.wTotalLength > size) { + usbi_warn(ctx, "short descriptor read %d/%d", + size, config.wTotalLength); + return size; + } else + return config.wTotalLength; + } +} + +static int op_get_config_descriptor_by_value(struct libusb_device *dev, + uint8_t value, unsigned char **buffer, int *host_endian) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct linux_device_priv *priv = _device_priv(dev); + unsigned char *descriptors = priv->descriptors; + int size = priv->descriptors_len; + struct libusb_config_descriptor *config; + + *buffer = NULL; + /* Unlike the device desc. config descs. are always in raw format */ + *host_endian = 0; + + /* Skip device header */ + descriptors += DEVICE_DESC_LENGTH; + size -= DEVICE_DESC_LENGTH; + + /* Seek till the config is found, or till "EOF" */ + while (1) { + int next = seek_to_next_config(ctx, descriptors, size); + if (next < 0) + return next; + config = (struct libusb_config_descriptor *)descriptors; + if (config->bConfigurationValue == value) { + *buffer = descriptors; + return next; + } + size -= next; + descriptors += next; + } +} + +static int op_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buffer, size_t len, int *host_endian) +{ + int r, config; + unsigned char *config_desc; + + if (sysfs_can_relate_devices) { + r = sysfs_get_active_config(dev, &config); + if (r < 0) + return r; + } else { + /* Use cached bConfigurationValue */ + struct linux_device_priv *priv = _device_priv(dev); + config = priv->active_config; + } + if (config == -1) + return LIBUSB_ERROR_NOT_FOUND; + + r = op_get_config_descriptor_by_value(dev, config, &config_desc, + host_endian); + if (r < 0) + return r; + + len = MIN(len, r); + memcpy(buffer, config_desc, len); + return len; +} + +static int op_get_config_descriptor(struct libusb_device *dev, + uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + struct linux_device_priv *priv = _device_priv(dev); + unsigned char *descriptors = priv->descriptors; + int i, r, size = priv->descriptors_len; + + /* Unlike the device desc. config descs. are always in raw format */ + *host_endian = 0; + + /* Skip device header */ + descriptors += DEVICE_DESC_LENGTH; + size -= DEVICE_DESC_LENGTH; + + /* Seek till the config is found, or till "EOF" */ + for (i = 0; ; i++) { + r = seek_to_next_config(DEVICE_CTX(dev), descriptors, size); + if (r < 0) + return r; + if (i == config_index) + break; + size -= r; + descriptors += r; + } + + len = MIN(len, r); + memcpy(buffer, descriptors, len); + return len; +} + +/* send a control message to retrieve active configuration */ +static int usbfs_get_active_config(struct libusb_device *dev, int fd) +{ + struct linux_device_priv *priv = _device_priv(dev); + unsigned char active_config = 0; + int r; + + struct usbfs_ctrltransfer ctrl = { + .bmRequestType = LIBUSB_ENDPOINT_IN, + .bRequest = LIBUSB_REQUEST_GET_CONFIGURATION, + .wValue = 0, + .wIndex = 0, + .wLength = 1, + .timeout = 1000, + .data = &active_config + }; + + r = ioctl(fd, IOCTL_USBFS_CONTROL, &ctrl); + if (r < 0) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + /* we hit this error path frequently with buggy devices :( */ + usbi_warn(DEVICE_CTX(dev), + "get_configuration failed ret=%d errno=%d", r, errno); + priv->active_config = -1; + } else { + if (active_config > 0) { + priv->active_config = active_config; + } else { + /* some buggy devices have a configuration 0, but we're + * reaching into the corner of a corner case here, so let's + * not support buggy devices in these circumstances. + * stick to the specs: a configuration value of 0 means + * unconfigured. */ + usbi_warn(DEVICE_CTX(dev), + "active cfg 0? assuming unconfigured device"); + priv->active_config = -1; + } + } + + return LIBUSB_SUCCESS; +} + +static int initialize_device(struct libusb_device *dev, uint8_t busnum, + uint8_t devaddr, const char *sysfs_dir) +{ + struct linux_device_priv *priv = _device_priv(dev); + struct libusb_context *ctx = DEVICE_CTX(dev); + int descriptors_size = 512; /* Begin with a 1024 byte alloc */ + int fd, speed; + ssize_t r; + + dev->bus_number = busnum; + dev->device_address = devaddr; + + if (sysfs_dir) { + priv->sysfs_dir = strdup(sysfs_dir); + if (!priv->sysfs_dir) + return LIBUSB_ERROR_NO_MEM; + + /* Note speed can contain 1.5, in this case __read_sysfs_attr + will stop parsing at the '.' and return 1 */ + speed = __read_sysfs_attr(DEVICE_CTX(dev), sysfs_dir, "speed"); + if (speed >= 0) { + switch (speed) { + case 1: dev->speed = LIBUSB_SPEED_LOW; break; + case 12: dev->speed = LIBUSB_SPEED_FULL; break; + case 480: dev->speed = LIBUSB_SPEED_HIGH; break; + case 5000: dev->speed = LIBUSB_SPEED_SUPER; break; + default: + usbi_warn(DEVICE_CTX(dev), "Unknown device speed: %d Mbps", speed); + } + } + } + + /* cache descriptors in memory */ + if (sysfs_has_descriptors) + fd = _open_sysfs_attr(dev, "descriptors"); + else + fd = _get_usbfs_fd(dev, O_RDONLY, 0); + if (fd < 0) + return fd; + + do { + descriptors_size *= 2; + priv->descriptors = usbi_reallocf(priv->descriptors, + descriptors_size); + if (!priv->descriptors) { + close(fd); + return LIBUSB_ERROR_NO_MEM; + } + /* usbfs has holes in the file */ + if (!sysfs_has_descriptors) { + memset(priv->descriptors + priv->descriptors_len, + 0, descriptors_size - priv->descriptors_len); + } + r = read(fd, priv->descriptors + priv->descriptors_len, + descriptors_size - priv->descriptors_len); + if (r < 0) { + usbi_err(ctx, "read descriptor failed ret=%d errno=%d", + fd, errno); + close(fd); + return LIBUSB_ERROR_IO; + } + priv->descriptors_len += r; + } while (priv->descriptors_len == descriptors_size); + + close(fd); + + if (priv->descriptors_len < DEVICE_DESC_LENGTH) { + usbi_err(ctx, "short descriptor read (%d)", + priv->descriptors_len); + return LIBUSB_ERROR_IO; + } + + if (sysfs_can_relate_devices) + return LIBUSB_SUCCESS; + + /* cache active config */ + fd = _get_usbfs_fd(dev, O_RDWR, 1); + if (fd < 0) { + /* cannot send a control message to determine the active + * config. just assume the first one is active. */ + usbi_warn(ctx, "Missing rw usbfs access; cannot determine " + "active configuration descriptor"); + if (priv->descriptors_len >= + (DEVICE_DESC_LENGTH + LIBUSB_DT_CONFIG_SIZE)) { + struct libusb_config_descriptor config; + usbi_parse_descriptor( + priv->descriptors + DEVICE_DESC_LENGTH, + "bbwbbbbb", &config, 0); + priv->active_config = config.bConfigurationValue; + } else + priv->active_config = -1; /* No config dt */ + + return LIBUSB_SUCCESS; + } + + r = usbfs_get_active_config(dev, fd); + close(fd); + + return r; +} + +static int linux_get_parent_info(struct libusb_device *dev, const char *sysfs_dir) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct libusb_device *it; + char *parent_sysfs_dir, *tmp; + int ret, add_parent = 1; + + /* XXX -- can we figure out the topology when using usbfs? */ + if (NULL == sysfs_dir || 0 == strncmp(sysfs_dir, "usb", 3)) { + /* either using usbfs or finding the parent of a root hub */ + return LIBUSB_SUCCESS; + } + + parent_sysfs_dir = strdup(sysfs_dir); + if (NULL == parent_sysfs_dir) { + return LIBUSB_ERROR_NO_MEM; + } + if (NULL != (tmp = strrchr(parent_sysfs_dir, '.')) || + NULL != (tmp = strrchr(parent_sysfs_dir, '-'))) { + dev->port_number = atoi(tmp + 1); + *tmp = '\0'; + } else { + usbi_warn(ctx, "Can not parse sysfs_dir: %s, no parent info", + parent_sysfs_dir); + free (parent_sysfs_dir); + return LIBUSB_SUCCESS; + } + + /* is the parent a root hub? */ + if (NULL == strchr(parent_sysfs_dir, '-')) { + tmp = parent_sysfs_dir; + ret = asprintf (&parent_sysfs_dir, "usb%s", tmp); + free (tmp); + if (0 > ret) { + return LIBUSB_ERROR_NO_MEM; + } + } + +retry: + /* find the parent in the context */ + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(it, &ctx->usb_devs, list, struct libusb_device) { + struct linux_device_priv *priv = _device_priv(it); + if (priv->sysfs_dir) { + if (0 == strcmp (priv->sysfs_dir, parent_sysfs_dir)) { + dev->parent_dev = libusb_ref_device(it); + break; + } + } + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + if (!dev->parent_dev && add_parent) { + usbi_dbg("parent_dev %s not enumerated yet, enumerating now", + parent_sysfs_dir); + sysfs_scan_device(ctx, parent_sysfs_dir); + add_parent = 0; + goto retry; + } + + usbi_dbg("Dev %p (%s) has parent %p (%s) port %d", dev, sysfs_dir, + dev->parent_dev, parent_sysfs_dir, dev->port_number); + + free (parent_sysfs_dir); + + return LIBUSB_SUCCESS; +} + +int linux_enumerate_device(struct libusb_context *ctx, + uint8_t busnum, uint8_t devaddr, const char *sysfs_dir) +{ + unsigned long session_id; + struct libusb_device *dev; + int r = 0; + + /* FIXME: session ID is not guaranteed unique as addresses can wrap and + * will be reused. instead we should add a simple sysfs attribute with + * a session ID. */ + session_id = busnum << 8 | devaddr; + usbi_dbg("busnum %d devaddr %d session_id %ld", busnum, devaddr, + session_id); + + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev) { + /* device already exists in the context */ + usbi_dbg("session_id %ld already exists", session_id); + libusb_unref_device(dev); + return LIBUSB_SUCCESS; + } + + usbi_dbg("allocating new device for %d/%d (session %ld)", + busnum, devaddr, session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) + return LIBUSB_ERROR_NO_MEM; + + r = initialize_device(dev, busnum, devaddr, sysfs_dir); + if (r < 0) + goto out; + r = usbi_sanitize_device(dev); + if (r < 0) + goto out; + + r = linux_get_parent_info(dev, sysfs_dir); + if (r < 0) + goto out; +out: + if (r < 0) + libusb_unref_device(dev); + else + usbi_connect_device(dev); + + return r; +} + +void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name) +{ + struct libusb_context *ctx; + + usbi_mutex_static_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + linux_enumerate_device(ctx, busnum, devaddr, sys_name); + } + usbi_mutex_static_unlock(&active_contexts_lock); +} + +void linux_device_disconnected(uint8_t busnum, uint8_t devaddr) +{ + struct libusb_context *ctx; + struct libusb_device *dev; + unsigned long session_id = busnum << 8 | devaddr; + + usbi_mutex_static_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + dev = usbi_get_device_by_session_id (ctx, session_id); + if (NULL != dev) { + usbi_disconnect_device (dev); + libusb_unref_device(dev); + } else { + usbi_dbg("device not found for session %x", session_id); + } + } + usbi_mutex_static_unlock(&active_contexts_lock); +} + +#if !defined(USE_UDEV) +/* open a bus directory and adds all discovered devices to the context */ +static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum) +{ + DIR *dir; + char dirpath[PATH_MAX]; + struct dirent *entry; + int r = LIBUSB_ERROR_IO; + + snprintf(dirpath, PATH_MAX, "%s/%03d", usbfs_path, busnum); + usbi_dbg("%s", dirpath); + dir = opendir(dirpath); + if (!dir) { + usbi_err(ctx, "opendir '%s' failed, errno=%d", dirpath, errno); + /* FIXME: should handle valid race conditions like hub unplugged + * during directory iteration - this is not an error */ + return r; + } + + while ((entry = readdir(dir))) { + int devaddr; + + if (entry->d_name[0] == '.') + continue; + + devaddr = atoi(entry->d_name); + if (devaddr == 0) { + usbi_dbg("unknown dir entry %s", entry->d_name); + continue; + } + + if (linux_enumerate_device(ctx, busnum, (uint8_t) devaddr, NULL)) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + + r = 0; + } + + closedir(dir); + return r; +} + +static int usbfs_get_device_list(struct libusb_context *ctx) +{ + struct dirent *entry; + DIR *buses = opendir(usbfs_path); + int r = 0; + + if (!buses) { + usbi_err(ctx, "opendir buses failed errno=%d", errno); + return LIBUSB_ERROR_IO; + } + + while ((entry = readdir(buses))) { + int busnum; + + if (entry->d_name[0] == '.') + continue; + + if (usbdev_names) { + int devaddr; + if (!_is_usbdev_entry(entry, &busnum, &devaddr)) + continue; + + r = linux_enumerate_device(ctx, busnum, (uint8_t) devaddr, NULL); + if (r < 0) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + } else { + busnum = atoi(entry->d_name); + if (busnum == 0) { + usbi_dbg("unknown dir entry %s", entry->d_name); + continue; + } + + r = usbfs_scan_busdir(ctx, busnum); + if (r < 0) + break; + } + } + + closedir(buses); + return r; + +} +#endif + +static int sysfs_scan_device(struct libusb_context *ctx, const char *devname) +{ + uint8_t busnum, devaddr; + int ret; + + ret = linux_get_device_address (ctx, 0, &busnum, &devaddr, NULL, devname); + if (LIBUSB_SUCCESS != ret) { + return ret; + } + + return linux_enumerate_device(ctx, busnum & 0xff, devaddr & 0xff, + devname); +} + +#if !defined(USE_UDEV) +static int sysfs_get_device_list(struct libusb_context *ctx) +{ + DIR *devices = opendir(SYSFS_DEVICE_PATH); + struct dirent *entry; + int r = LIBUSB_ERROR_IO; + + if (!devices) { + usbi_err(ctx, "opendir devices failed errno=%d", errno); + return r; + } + + while ((entry = readdir(devices))) { + if ((!isdigit(entry->d_name[0]) && strncmp(entry->d_name, "usb", 3)) + || strchr(entry->d_name, ':')) + continue; + + if (sysfs_scan_device(ctx, entry->d_name)) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + + r = 0; + } + + closedir(devices); + return r; +} + +static int linux_default_scan_devices (struct libusb_context *ctx) +{ + /* we can retrieve device list and descriptors from sysfs or usbfs. + * sysfs is preferable, because if we use usbfs we end up resuming + * any autosuspended USB devices. however, sysfs is not available + * everywhere, so we need a usbfs fallback too. + * + * as described in the "sysfs vs usbfs" comment at the top of this + * file, sometimes we have sysfs but not enough information to + * relate sysfs devices to usbfs nodes. op_init() determines the + * adequacy of sysfs and sets sysfs_can_relate_devices. + */ + if (sysfs_can_relate_devices != 0) + return sysfs_get_device_list(ctx); + else + return usbfs_get_device_list(ctx); +} +#endif + +static int op_open(struct libusb_device_handle *handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + int r; + + hpriv->fd = _get_usbfs_fd(handle->dev, O_RDWR, 0); + if (hpriv->fd < 0) { + if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) { + /* device will still be marked as attached if hotplug monitor thread + * hasn't processed remove event yet */ + usbi_mutex_static_lock(&linux_hotplug_lock); + if (handle->dev->attached) { + usbi_dbg("open failed with no device, but device still attached"); + linux_device_disconnected(handle->dev->bus_number, + handle->dev->device_address); + } + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + return hpriv->fd; + } + + r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps); + if (r < 0) { + if (errno == ENOTTY) + usbi_dbg("getcap not available"); + else + usbi_err(HANDLE_CTX(handle), "getcap failed (%d)", errno); + hpriv->caps = 0; + if (supports_flag_zero_packet) + hpriv->caps |= USBFS_CAP_ZERO_PACKET; + if (supports_flag_bulk_continuation) + hpriv->caps |= USBFS_CAP_BULK_CONTINUATION; + } + + r = usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT); + if (r < 0) + close(hpriv->fd); + + return r; +} + +static void op_close(struct libusb_device_handle *dev_handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(dev_handle); + /* fd may have already been removed by POLLERR condition in op_handle_events() */ + if (!hpriv->fd_removed) + usbi_remove_pollfd(HANDLE_CTX(dev_handle), hpriv->fd); + close(hpriv->fd); +} + +static int op_get_configuration(struct libusb_device_handle *handle, + int *config) +{ + int r; + + if (sysfs_can_relate_devices) { + r = sysfs_get_active_config(handle->dev, config); + } else { + r = usbfs_get_active_config(handle->dev, + _device_handle_priv(handle)->fd); + if (r == LIBUSB_SUCCESS) + *config = _device_priv(handle->dev)->active_config; + } + if (r < 0) + return r; + + if (*config == -1) { + usbi_err(HANDLE_CTX(handle), "device unconfigured"); + *config = 0; + } + + return 0; +} + +static int op_set_configuration(struct libusb_device_handle *handle, int config) +{ + struct linux_device_priv *priv = _device_priv(handle->dev); + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_SETCONFIG, &config); + if (r) { + if (errno == EINVAL) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), "failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + /* update our cached active config descriptor */ + priv->active_config = config; + + return LIBUSB_SUCCESS; +} + +static int claim_interface(struct libusb_device_handle *handle, int iface) +{ + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_CLAIMINTF, &iface); + if (r) { + if (errno == ENOENT) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "claim interface failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return 0; +} + +static int release_interface(struct libusb_device_handle *handle, int iface) +{ + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_RELEASEINTF, &iface); + if (r) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "release interface failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return 0; +} + +static int op_set_interface(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_setinterface setintf; + int r; + + setintf.interface = iface; + setintf.altsetting = altsetting; + r = ioctl(fd, IOCTL_USBFS_SETINTF, &setintf); + if (r) { + if (errno == EINVAL) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "setintf failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_clear_halt(struct libusb_device_handle *handle, + unsigned char endpoint) +{ + int fd = _device_handle_priv(handle)->fd; + unsigned int _endpoint = endpoint; + int r = ioctl(fd, IOCTL_USBFS_CLEAR_HALT, &_endpoint); + if (r) { + if (errno == ENOENT) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "clear_halt failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_reset_device(struct libusb_device_handle *handle) +{ + int fd = _device_handle_priv(handle)->fd; + int i, r, ret = 0; + + /* Doing a device reset will cause the usbfs driver to get unbound + from any interfaces it is bound to. By voluntarily unbinding + the usbfs driver ourself, we stop the kernel from rebinding + the interface after reset (which would end up with the interface + getting bound to the in kernel driver if any). */ + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (handle->claimed_interfaces & (1L << i)) { + release_interface(handle, i); + } + } + + usbi_mutex_lock(&handle->lock); + r = ioctl(fd, IOCTL_USBFS_RESET, NULL); + if (r) { + if (errno == ENODEV) { + ret = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + usbi_err(HANDLE_CTX(handle), + "reset failed error %d errno %d", r, errno); + ret = LIBUSB_ERROR_OTHER; + goto out; + } + + /* And re-claim any interfaces which were claimed before the reset */ + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (handle->claimed_interfaces & (1L << i)) { + /* + * A driver may have completed modprobing during + * IOCTL_USBFS_RESET, and bound itself as soon as + * IOCTL_USBFS_RESET released the device lock + */ + r = detach_kernel_driver_and_claim(handle, i); + if (r) { + usbi_warn(HANDLE_CTX(handle), + "failed to re-claim interface %d after reset: %s", + i, libusb_error_name(r)); + handle->claimed_interfaces &= ~(1L << i); + ret = LIBUSB_ERROR_NOT_FOUND; + } + } + } +out: + usbi_mutex_unlock(&handle->lock); + return ret; +} + +static int do_streams_ioctl(struct libusb_device_handle *handle, long req, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + int r, fd = _device_handle_priv(handle)->fd; + struct usbfs_streams *streams; + + if (num_endpoints > 30) /* Max 15 in + 15 out eps */ + return LIBUSB_ERROR_INVALID_PARAM; + + streams = malloc(sizeof(struct usbfs_streams) + num_endpoints); + if (!streams) + return LIBUSB_ERROR_NO_MEM; + + streams->num_streams = num_streams; + streams->num_eps = num_endpoints; + memcpy(streams->eps, endpoints, num_endpoints); + + r = ioctl(fd, req, streams); + + free(streams); + + if (r < 0) { + if (errno == ENOTTY) + return LIBUSB_ERROR_NOT_SUPPORTED; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "streams-ioctl failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return r; +} + +static int op_alloc_streams(struct libusb_device_handle *handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_ALLOC_STREAMS, + num_streams, endpoints, num_endpoints); +} + +static int op_free_streams(struct libusb_device_handle *handle, + unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_FREE_STREAMS, 0, + endpoints, num_endpoints); +} + +static unsigned char *op_dev_mem_alloc(struct libusb_device_handle *handle, + size_t len) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + unsigned char *buffer = (unsigned char *)mmap(NULL, len, + PROT_READ | PROT_WRITE, MAP_SHARED, hpriv->fd, 0); + if (buffer == MAP_FAILED) { + usbi_err(HANDLE_CTX(handle), "alloc dev mem failed errno %d", + errno); + return NULL; + } + return buffer; +} + +static int op_dev_mem_free(struct libusb_device_handle *handle, + unsigned char *buffer, size_t len) +{ + if (munmap(buffer, len) != 0) { + usbi_err(HANDLE_CTX(handle), "free dev mem failed errno %d", + errno); + return LIBUSB_ERROR_OTHER; + } else { + return LIBUSB_SUCCESS; + } +} + +static int op_kernel_driver_active(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_getdriver getdrv; + int r; + + getdrv.interface = interface; + r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv); + if (r) { + if (errno == ENODATA) + return 0; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "get driver failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return (strcmp(getdrv.driver, "usbfs") == 0) ? 0 : 1; +} + +static int op_detach_kernel_driver(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_ioctl command; + struct usbfs_getdriver getdrv; + int r; + + command.ifno = interface; + command.ioctl_code = IOCTL_USBFS_DISCONNECT; + command.data = NULL; + + getdrv.interface = interface; + r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv); + if (r == 0 && strcmp(getdrv.driver, "usbfs") == 0) + return LIBUSB_ERROR_NOT_FOUND; + + r = ioctl(fd, IOCTL_USBFS_IOCTL, &command); + if (r) { + if (errno == ENODATA) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "detach failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_attach_kernel_driver(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_ioctl command; + int r; + + command.ifno = interface; + command.ioctl_code = IOCTL_USBFS_CONNECT; + command.data = NULL; + + r = ioctl(fd, IOCTL_USBFS_IOCTL, &command); + if (r < 0) { + if (errno == ENODATA) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + + usbi_err(HANDLE_CTX(handle), + "attach failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } else if (r == 0) { + return LIBUSB_ERROR_NOT_FOUND; + } + + return 0; +} + +static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle, + int interface) +{ + struct usbfs_disconnect_claim dc; + int r, fd = _device_handle_priv(handle)->fd; + + dc.interface = interface; + strcpy(dc.driver, "usbfs"); + dc.flags = USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER; + r = ioctl(fd, IOCTL_USBFS_DISCONNECT_CLAIM, &dc); + if (r == 0 || (r != 0 && errno != ENOTTY)) { + if (r == 0) + return 0; + + switch (errno) { + case EBUSY: + return LIBUSB_ERROR_BUSY; + case EINVAL: + return LIBUSB_ERROR_INVALID_PARAM; + case ENODEV: + return LIBUSB_ERROR_NO_DEVICE; + } + usbi_err(HANDLE_CTX(handle), + "disconnect-and-claim failed errno %d", errno); + return LIBUSB_ERROR_OTHER; + } + + /* Fallback code for kernels which don't support the + disconnect-and-claim ioctl */ + r = op_detach_kernel_driver(handle, interface); + if (r != 0 && r != LIBUSB_ERROR_NOT_FOUND) + return r; + + return claim_interface(handle, interface); +} + +static int op_claim_interface(struct libusb_device_handle *handle, int iface) +{ + if (handle->auto_detach_kernel_driver) + return detach_kernel_driver_and_claim(handle, iface); + else + return claim_interface(handle, iface); +} + +static int op_release_interface(struct libusb_device_handle *handle, int iface) +{ + int r; + + r = release_interface(handle, iface); + if (r) + return r; + + if (handle->auto_detach_kernel_driver) + op_attach_kernel_driver(handle, iface); + + return 0; +} + +static void op_destroy_device(struct libusb_device *dev) +{ + struct linux_device_priv *priv = _device_priv(dev); + if (priv->descriptors) + free(priv->descriptors); + if (priv->sysfs_dir) + free(priv->sysfs_dir); +} + +/* URBs are discarded in reverse order of submission to avoid races. */ +static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plus_one) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = + usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + int i, ret = 0; + struct usbfs_urb *urb; + + for (i = last_plus_one - 1; i >= first; i--) { + if (LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type) + urb = tpriv->iso_urbs[i]; + else + urb = &tpriv->urbs[i]; + + if (0 == ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, urb)) + continue; + + if (EINVAL == errno) { + usbi_dbg("URB not found --> assuming ready to be reaped"); + if (i == (last_plus_one - 1)) + ret = LIBUSB_ERROR_NOT_FOUND; + } else if (ENODEV == errno) { + usbi_dbg("Device not found for URB --> assuming ready to be reaped"); + ret = LIBUSB_ERROR_NO_DEVICE; + } else { + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised discard errno %d", errno); + ret = LIBUSB_ERROR_OTHER; + } + } + return ret; +} + +static void free_iso_urbs(struct linux_transfer_priv *tpriv) +{ + int i; + for (i = 0; i < tpriv->num_urbs; i++) { + struct usbfs_urb *urb = tpriv->iso_urbs[i]; + if (!urb) + break; + free(urb); + } + + free(tpriv->iso_urbs); + tpriv->iso_urbs = NULL; +} + +static int submit_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb *urbs; + int is_out = (transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_OUT; + int bulk_buffer_len, use_bulk_continuation; + int r; + int i; + + if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) && + !(dpriv->caps & USBFS_CAP_ZERO_PACKET)) + return LIBUSB_ERROR_NOT_SUPPORTED; + + /* + * Older versions of usbfs place a 16kb limit on bulk URBs. We work + * around this by splitting large transfers into 16k blocks, and then + * submit all urbs at once. it would be simpler to submit one urb at + * a time, but there is a big performance gain doing it this way. + * + * Newer versions lift the 16k limit (USBFS_CAP_NO_PACKET_SIZE_LIM), + * using arbritary large transfers can still be a bad idea though, as + * the kernel needs to allocate physical contiguous memory for this, + * which may fail for large buffers. + * + * The kernel solves this problem by splitting the transfer into + * blocks itself when the host-controller is scatter-gather capable + * (USBFS_CAP_BULK_SCATTER_GATHER), which most controllers are. + * + * Last, there is the issue of short-transfers when splitting, for + * short split-transfers to work reliable USBFS_CAP_BULK_CONTINUATION + * is needed, but this is not always available. + */ + if (dpriv->caps & USBFS_CAP_BULK_SCATTER_GATHER) { + /* Good! Just submit everything in one go */ + bulk_buffer_len = transfer->length ? transfer->length : 1; + use_bulk_continuation = 0; + } else if (dpriv->caps & USBFS_CAP_BULK_CONTINUATION) { + /* Split the transfers and use bulk-continuation to + avoid issues with short-transfers */ + bulk_buffer_len = MAX_BULK_BUFFER_LENGTH; + use_bulk_continuation = 1; + } else if (dpriv->caps & USBFS_CAP_NO_PACKET_SIZE_LIM) { + /* Don't split, assume the kernel can alloc the buffer + (otherwise the submit will fail with -ENOMEM) */ + bulk_buffer_len = transfer->length ? transfer->length : 1; + use_bulk_continuation = 0; + } else { + /* Bad, splitting without bulk-continuation, short transfers + which end before the last urb will not work reliable! */ + /* Note we don't warn here as this is "normal" on kernels < + 2.6.32 and not a problem for most applications */ + bulk_buffer_len = MAX_BULK_BUFFER_LENGTH; + use_bulk_continuation = 0; + } + + int num_urbs = transfer->length / bulk_buffer_len; + int last_urb_partial = 0; + + if (transfer->length == 0) { + num_urbs = 1; + } else if ((transfer->length % bulk_buffer_len) > 0) { + last_urb_partial = 1; + num_urbs++; + } + usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, + transfer->length); + urbs = calloc(num_urbs, sizeof(struct usbfs_urb)); + if (!urbs) + return LIBUSB_ERROR_NO_MEM; + tpriv->urbs = urbs; + tpriv->num_urbs = num_urbs; + tpriv->num_retired = 0; + tpriv->reap_action = NORMAL; + tpriv->reap_status = LIBUSB_TRANSFER_COMPLETED; + + for (i = 0; i < num_urbs; i++) { + struct usbfs_urb *urb = &urbs[i]; + urb->usercontext = itransfer; + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + urb->type = USBFS_URB_TYPE_BULK; + urb->stream_id = 0; + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + urb->type = USBFS_URB_TYPE_BULK; + urb->stream_id = itransfer->stream_id; + break; + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + urb->type = USBFS_URB_TYPE_INTERRUPT; + break; + } + urb->endpoint = transfer->endpoint; + urb->buffer = transfer->buffer + (i * bulk_buffer_len); + /* don't set the short not ok flag for the last URB */ + if (use_bulk_continuation && !is_out && (i < num_urbs - 1)) + urb->flags = USBFS_URB_SHORT_NOT_OK; + if (i == num_urbs - 1 && last_urb_partial) + urb->buffer_length = transfer->length % bulk_buffer_len; + else if (transfer->length == 0) + urb->buffer_length = 0; + else + urb->buffer_length = bulk_buffer_len; + + if (i > 0 && use_bulk_continuation) + urb->flags |= USBFS_URB_BULK_CONTINUATION; + + /* we have already checked that the flag is supported */ + if (is_out && i == num_urbs - 1 && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) + urb->flags |= USBFS_URB_ZERO_PACKET; + + r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb); + if (r < 0) { + if (errno == ENODEV) { + r = LIBUSB_ERROR_NO_DEVICE; + } else { + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + r = LIBUSB_ERROR_IO; + } + + /* if the first URB submission fails, we can simply free up and + * return failure immediately. */ + if (i == 0) { + usbi_dbg("first URB failed, easy peasy"); + free(urbs); + tpriv->urbs = NULL; + return r; + } + + /* if it's not the first URB that failed, the situation is a bit + * tricky. we may need to discard all previous URBs. there are + * complications: + * - discarding is asynchronous - discarded urbs will be reaped + * later. the user must not have freed the transfer when the + * discarded URBs are reaped, otherwise libusb will be using + * freed memory. + * - the earlier URBs may have completed successfully and we do + * not want to throw away any data. + * - this URB failing may be no error; EREMOTEIO means that + * this transfer simply didn't need all the URBs we submitted + * so, we report that the transfer was submitted successfully and + * in case of error we discard all previous URBs. later when + * the final reap completes we can report error to the user, + * or success if an earlier URB was completed successfully. + */ + tpriv->reap_action = EREMOTEIO == errno ? COMPLETED_EARLY : SUBMIT_FAILED; + + /* The URBs we haven't submitted yet we count as already + * retired. */ + tpriv->num_retired += num_urbs - i; + + /* If we completed short then don't try to discard. */ + if (COMPLETED_EARLY == tpriv->reap_action) + return 0; + + discard_urbs(itransfer, 0, i); + + usbi_dbg("reporting successful submission but waiting for %d " + "discards before reporting error", i); + return 0; + } + } + + return 0; +} + +static int submit_iso_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb **urbs; + size_t alloc_size; + int num_packets = transfer->num_iso_packets; + int i; + int this_urb_len = 0; + int num_urbs = 1; + int packet_offset = 0; + unsigned int packet_len; + unsigned char *urb_buffer = transfer->buffer; + + /* usbfs places arbitrary limits on iso URBs. this limit has changed + * at least three times, and it's difficult to accurately detect which + * limit this running kernel might impose. so we attempt to submit + * whatever the user has provided. if the kernel rejects the request + * due to its size, we return an error indicating such to the user. + */ + + /* calculate how many URBs we need */ + for (i = 0; i < num_packets; i++) { + unsigned int space_remaining = MAX_ISO_BUFFER_LENGTH - this_urb_len; + packet_len = transfer->iso_packet_desc[i].length; + + if (packet_len > space_remaining) { + num_urbs++; + this_urb_len = packet_len; + /* check that we can actually support this packet length */ + if (this_urb_len > MAX_ISO_BUFFER_LENGTH) + return LIBUSB_ERROR_INVALID_PARAM; + } else { + this_urb_len += packet_len; + } + } + usbi_dbg("need %d %dk URBs for transfer", num_urbs, MAX_ISO_BUFFER_LENGTH / 1024); + + urbs = calloc(num_urbs, sizeof(*urbs)); + if (!urbs) + return LIBUSB_ERROR_NO_MEM; + + tpriv->iso_urbs = urbs; + tpriv->num_urbs = num_urbs; + tpriv->num_retired = 0; + tpriv->reap_action = NORMAL; + tpriv->iso_packet_offset = 0; + + /* allocate + initialize each URB with the correct number of packets */ + for (i = 0; i < num_urbs; i++) { + struct usbfs_urb *urb; + unsigned int space_remaining_in_urb = MAX_ISO_BUFFER_LENGTH; + int urb_packet_offset = 0; + unsigned char *urb_buffer_orig = urb_buffer; + int j; + int k; + + /* swallow up all the packets we can fit into this URB */ + while (packet_offset < transfer->num_iso_packets) { + packet_len = transfer->iso_packet_desc[packet_offset].length; + if (packet_len <= space_remaining_in_urb) { + /* throw it in */ + urb_packet_offset++; + packet_offset++; + space_remaining_in_urb -= packet_len; + urb_buffer += packet_len; + } else { + /* it can't fit, save it for the next URB */ + break; + } + } + + alloc_size = sizeof(*urb) + + (urb_packet_offset * sizeof(struct usbfs_iso_packet_desc)); + urb = calloc(1, alloc_size); + if (!urb) { + free_iso_urbs(tpriv); + return LIBUSB_ERROR_NO_MEM; + } + urbs[i] = urb; + + /* populate packet lengths */ + for (j = 0, k = packet_offset - urb_packet_offset; + k < packet_offset; k++, j++) { + packet_len = transfer->iso_packet_desc[k].length; + urb->iso_frame_desc[j].length = packet_len; + } + + urb->usercontext = itransfer; + urb->type = USBFS_URB_TYPE_ISO; + /* FIXME: interface for non-ASAP data? */ + urb->flags = USBFS_URB_ISO_ASAP; + urb->endpoint = transfer->endpoint; + urb->number_of_packets = urb_packet_offset; + urb->buffer = urb_buffer_orig; + } + + /* submit URBs */ + for (i = 0; i < num_urbs; i++) { + int r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urbs[i]); + if (r < 0) { + if (errno == ENODEV) { + r = LIBUSB_ERROR_NO_DEVICE; + } else if (errno == EINVAL) { + usbi_warn(TRANSFER_CTX(transfer), + "submiturb failed, transfer too large"); + r = LIBUSB_ERROR_INVALID_PARAM; + } else { + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + r = LIBUSB_ERROR_IO; + } + + /* if the first URB submission fails, we can simply free up and + * return failure immediately. */ + if (i == 0) { + usbi_dbg("first URB failed, easy peasy"); + free_iso_urbs(tpriv); + return r; + } + + /* if it's not the first URB that failed, the situation is a bit + * tricky. we must discard all previous URBs. there are + * complications: + * - discarding is asynchronous - discarded urbs will be reaped + * later. the user must not have freed the transfer when the + * discarded URBs are reaped, otherwise libusb will be using + * freed memory. + * - the earlier URBs may have completed successfully and we do + * not want to throw away any data. + * so, in this case we discard all the previous URBs BUT we report + * that the transfer was submitted successfully. then later when + * the final discard completes we can report error to the user. + */ + tpriv->reap_action = SUBMIT_FAILED; + + /* The URBs we haven't submitted yet we count as already + * retired. */ + tpriv->num_retired = num_urbs - i; + discard_urbs(itransfer, 0, i); + + usbi_dbg("reporting successful submission but waiting for %d " + "discards before reporting error", i); + return 0; + } + } + + return 0; +} + +static int submit_control_transfer(struct usbi_transfer *itransfer) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb *urb; + int r; + + if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH) + return LIBUSB_ERROR_INVALID_PARAM; + + urb = calloc(1, sizeof(struct usbfs_urb)); + if (!urb) + return LIBUSB_ERROR_NO_MEM; + tpriv->urbs = urb; + tpriv->num_urbs = 1; + tpriv->reap_action = NORMAL; + + urb->usercontext = itransfer; + urb->type = USBFS_URB_TYPE_CONTROL; + urb->endpoint = transfer->endpoint; + urb->buffer = transfer->buffer; + urb->buffer_length = transfer->length; + + r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb); + if (r < 0) { + free(urb); + tpriv->urbs = NULL; + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + return LIBUSB_ERROR_IO; + } + return 0; +} + +static int op_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return submit_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return submit_iso_transfer(itransfer); + default: + usbi_err(TRANSFER_CTX(transfer), + "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int op_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int r; + + if (!tpriv->urbs) + return LIBUSB_ERROR_NOT_FOUND; + + r = discard_urbs(itransfer, 0, tpriv->num_urbs); + if (r != 0) + return r; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + if (tpriv->reap_action == ERROR) + break; + /* else, fall through */ + default: + tpriv->reap_action = CANCELLED; + } + + return 0; +} + +static void op_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + /* urbs can be freed also in submit_transfer so lock mutex first */ + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (tpriv->urbs) { + free(tpriv->urbs); + tpriv->urbs = NULL; + } + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + if (tpriv->iso_urbs) { + free_iso_urbs(tpriv); + tpriv->iso_urbs = NULL; + } + break; + default: + usbi_err(TRANSFER_CTX(transfer), + "unknown endpoint type %d", transfer->type); + } +} + +static int handle_bulk_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int urb_idx = urb - tpriv->urbs; + + usbi_mutex_lock(&itransfer->lock); + usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status, + urb_idx + 1, tpriv->num_urbs); + + tpriv->num_retired++; + + if (tpriv->reap_action != NORMAL) { + /* cancelled, submit_fail, or completed early */ + usbi_dbg("abnormal reap: urb status %d", urb->status); + + /* even though we're in the process of cancelling, it's possible that + * we may receive some data in these URBs that we don't want to lose. + * examples: + * 1. while the kernel is cancelling all the packets that make up an + * URB, a few of them might complete. so we get back a successful + * cancellation *and* some data. + * 2. we receive a short URB which marks the early completion condition, + * so we start cancelling the remaining URBs. however, we're too + * slow and another URB completes (or at least completes partially). + * (this can't happen since we always use BULK_CONTINUATION.) + * + * When this happens, our objectives are not to lose any "surplus" data, + * and also to stick it at the end of the previously-received data + * (closing any holes), so that libusb reports the total amount of + * transferred data and presents it in a contiguous chunk. + */ + if (urb->actual_length > 0) { + unsigned char *target = transfer->buffer + itransfer->transferred; + usbi_dbg("received %d bytes of surplus data", urb->actual_length); + if (urb->buffer != target) { + usbi_dbg("moving surplus data from offset %d to offset %d", + (unsigned char *) urb->buffer - transfer->buffer, + target - transfer->buffer); + memmove(target, urb->buffer, urb->actual_length); + } + itransfer->transferred += urb->actual_length; + } + + if (tpriv->num_retired == tpriv->num_urbs) { + usbi_dbg("abnormal reap: last URB handled, reporting"); + if (tpriv->reap_action != COMPLETED_EARLY && + tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_ERROR; + goto completed; + } + goto out_unlock; + } + + itransfer->transferred += urb->actual_length; + + /* Many of these errors can occur on *any* urb of a multi-urb + * transfer. When they do, we tear down the rest of the transfer. + */ + switch (urb->status) { + case 0: + break; + case -EREMOTEIO: /* short transfer */ + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE; + goto cancel_remaining; + case -EPIPE: + usbi_dbg("detected endpoint stall"); + if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_STALL; + goto cancel_remaining; + case -EOVERFLOW: + /* overflow can only ever occur in the last urb */ + usbi_dbg("overflow, actual_length=%d", urb->actual_length); + if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_OVERFLOW; + goto completed; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + usbi_dbg("low level error %d", urb->status); + tpriv->reap_action = ERROR; + goto cancel_remaining; + default: + usbi_warn(ITRANSFER_CTX(itransfer), + "unrecognised urb status %d", urb->status); + tpriv->reap_action = ERROR; + goto cancel_remaining; + } + + /* if we're the last urb or we got less data than requested then we're + * done */ + if (urb_idx == tpriv->num_urbs - 1) { + usbi_dbg("last URB in transfer --> complete!"); + goto completed; + } else if (urb->actual_length < urb->buffer_length) { + usbi_dbg("short transfer %d/%d --> complete!", + urb->actual_length, urb->buffer_length); + if (tpriv->reap_action == NORMAL) + tpriv->reap_action = COMPLETED_EARLY; + } else + goto out_unlock; + +cancel_remaining: + if (ERROR == tpriv->reap_action && LIBUSB_TRANSFER_COMPLETED == tpriv->reap_status) + tpriv->reap_status = LIBUSB_TRANSFER_ERROR; + + if (tpriv->num_retired == tpriv->num_urbs) /* nothing to cancel */ + goto completed; + + /* cancel remaining urbs and wait for their completion before + * reporting results */ + discard_urbs(itransfer, urb_idx + 1, tpriv->num_urbs); + +out_unlock: + usbi_mutex_unlock(&itransfer->lock); + return 0; + +completed: + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return CANCELLED == tpriv->reap_action ? + usbi_handle_transfer_cancellation(itransfer) : + usbi_handle_transfer_completion(itransfer, tpriv->reap_status); +} + +static int handle_iso_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int num_urbs = tpriv->num_urbs; + int urb_idx = 0; + int i; + enum libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED; + + usbi_mutex_lock(&itransfer->lock); + for (i = 0; i < num_urbs; i++) { + if (urb == tpriv->iso_urbs[i]) { + urb_idx = i + 1; + break; + } + } + if (urb_idx == 0) { + usbi_err(TRANSFER_CTX(transfer), "could not locate urb!"); + usbi_mutex_unlock(&itransfer->lock); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("handling completion status %d of iso urb %d/%d", urb->status, + urb_idx, num_urbs); + + /* copy isochronous results back in */ + + for (i = 0; i < urb->number_of_packets; i++) { + struct usbfs_iso_packet_desc *urb_desc = &urb->iso_frame_desc[i]; + struct libusb_iso_packet_descriptor *lib_desc = + &transfer->iso_packet_desc[tpriv->iso_packet_offset++]; + lib_desc->status = LIBUSB_TRANSFER_COMPLETED; + switch (urb_desc->status) { + case 0: + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE; + break; + case -EPIPE: + usbi_dbg("detected endpoint stall"); + lib_desc->status = LIBUSB_TRANSFER_STALL; + break; + case -EOVERFLOW: + usbi_dbg("overflow error"); + lib_desc->status = LIBUSB_TRANSFER_OVERFLOW; + break; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + case -EXDEV: + usbi_dbg("low-level USB error %d", urb_desc->status); + lib_desc->status = LIBUSB_TRANSFER_ERROR; + break; + default: + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised urb status %d", urb_desc->status); + lib_desc->status = LIBUSB_TRANSFER_ERROR; + break; + } + lib_desc->actual_length = urb_desc->actual_length; + } + + tpriv->num_retired++; + + if (tpriv->reap_action != NORMAL) { /* cancelled or submit_fail */ + usbi_dbg("CANCEL: urb status %d", urb->status); + + if (tpriv->num_retired == num_urbs) { + usbi_dbg("CANCEL: last URB handled, reporting"); + free_iso_urbs(tpriv); + if (tpriv->reap_action == CANCELLED) { + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_cancellation(itransfer); + } else { + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, + LIBUSB_TRANSFER_ERROR); + } + } + goto out; + } + + switch (urb->status) { + case 0: + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ESHUTDOWN: + usbi_dbg("device removed"); + status = LIBUSB_TRANSFER_NO_DEVICE; + break; + default: + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised urb status %d", urb->status); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + /* if we're the last urb then we're done */ + if (urb_idx == num_urbs) { + usbi_dbg("last URB in transfer --> complete!"); + free_iso_urbs(tpriv); + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); + } + +out: + usbi_mutex_unlock(&itransfer->lock); + return 0; +} + +static int handle_control_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int status; + + usbi_mutex_lock(&itransfer->lock); + usbi_dbg("handling completion status %d", urb->status); + + itransfer->transferred += urb->actual_length; + + if (tpriv->reap_action == CANCELLED) { + if (urb->status != 0 && urb->status != -ENOENT) + usbi_warn(ITRANSFER_CTX(itransfer), + "cancel: unrecognised urb status %d", urb->status); + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_cancellation(itransfer); + } + + switch (urb->status) { + case 0: + status = LIBUSB_TRANSFER_COMPLETED; + break; + case -ENOENT: /* cancelled */ + status = LIBUSB_TRANSFER_CANCELLED; + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + status = LIBUSB_TRANSFER_NO_DEVICE; + break; + case -EPIPE: + usbi_dbg("unsupported control request"); + status = LIBUSB_TRANSFER_STALL; + break; + case -EOVERFLOW: + usbi_dbg("control overflow error"); + status = LIBUSB_TRANSFER_OVERFLOW; + break; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + usbi_dbg("low-level bus error occurred"); + status = LIBUSB_TRANSFER_ERROR; + break; + default: + usbi_warn(ITRANSFER_CTX(itransfer), + "unrecognised urb status %d", urb->status); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); +} + +static int reap_for_handle(struct libusb_device_handle *handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + int r; + struct usbfs_urb *urb; + struct usbi_transfer *itransfer; + struct libusb_transfer *transfer; + + r = ioctl(hpriv->fd, IOCTL_USBFS_REAPURBNDELAY, &urb); + if (r == -1 && errno == EAGAIN) + return 1; + if (r < 0) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), "reap failed error %d errno=%d", + r, errno); + return LIBUSB_ERROR_IO; + } + + itransfer = urb->usercontext; + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status, + urb->actual_length); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return handle_iso_completion(itransfer, urb); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return handle_bulk_completion(itransfer, urb); + case LIBUSB_TRANSFER_TYPE_CONTROL: + return handle_control_completion(itransfer, urb); + default: + usbi_err(HANDLE_CTX(handle), "unrecognised endpoint type %x", + transfer->type); + return LIBUSB_ERROR_OTHER; + } +} + +static int op_handle_events(struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) +{ + int r; + unsigned int i = 0; + + usbi_mutex_lock(&ctx->open_devs_lock); + for (i = 0; i < nfds && num_ready > 0; i++) { + struct pollfd *pollfd = &fds[i]; + struct libusb_device_handle *handle; + struct linux_device_handle_priv *hpriv = NULL; + + if (!pollfd->revents) + continue; + + num_ready--; + list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) { + hpriv = _device_handle_priv(handle); + if (hpriv->fd == pollfd->fd) + break; + } + + if (!hpriv || hpriv->fd != pollfd->fd) { + usbi_err(ctx, "cannot find handle for fd %d", + pollfd->fd); + continue; + } + + if (pollfd->revents & POLLERR) { + /* remove the fd from the pollfd set so that it doesn't continuously + * trigger an event, and flag that it has been removed so op_close() + * doesn't try to remove it a second time */ + usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd); + hpriv->fd_removed = 1; + + /* device will still be marked as attached if hotplug monitor thread + * hasn't processed remove event yet */ + usbi_mutex_static_lock(&linux_hotplug_lock); + if (handle->dev->attached) + linux_device_disconnected(handle->dev->bus_number, + handle->dev->device_address); + usbi_mutex_static_unlock(&linux_hotplug_lock); + + if (hpriv->caps & USBFS_CAP_REAP_AFTER_DISCONNECT) { + do { + r = reap_for_handle(handle); + } while (r == 0); + } + + usbi_handle_disconnect(handle); + continue; + } + + do { + r = reap_for_handle(handle); + } while (r == 0); + if (r == 1 || r == LIBUSB_ERROR_NO_DEVICE) + continue; + else if (r < 0) + goto out; + } + + r = 0; +out: + usbi_mutex_unlock(&ctx->open_devs_lock); + return r; +} + +static int op_clock_gettime(int clk_id, struct timespec *tp) +{ + switch (clk_id) { + case USBI_CLOCK_MONOTONIC: + return clock_gettime(monotonic_clkid, tp); + case USBI_CLOCK_REALTIME: + return clock_gettime(CLOCK_REALTIME, tp); + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +#ifdef USBI_TIMERFD_AVAILABLE +static clockid_t op_get_timerfd_clockid(void) +{ + return monotonic_clkid; + +} +#endif + +const struct usbi_os_backend linux_usbfs_backend = { + .name = "Linux usbfs", + .caps = USBI_CAP_HAS_HID_ACCESS|USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER, + .init = op_init, + .exit = op_exit, + .get_device_list = NULL, + .hotplug_poll = op_hotplug_poll, + .get_device_descriptor = op_get_device_descriptor, + .get_active_config_descriptor = op_get_active_config_descriptor, + .get_config_descriptor = op_get_config_descriptor, + .get_config_descriptor_by_value = op_get_config_descriptor_by_value, + + .open = op_open, + .close = op_close, + .get_configuration = op_get_configuration, + .set_configuration = op_set_configuration, + .claim_interface = op_claim_interface, + .release_interface = op_release_interface, + + .set_interface_altsetting = op_set_interface, + .clear_halt = op_clear_halt, + .reset_device = op_reset_device, + + .alloc_streams = op_alloc_streams, + .free_streams = op_free_streams, + + .dev_mem_alloc = op_dev_mem_alloc, + .dev_mem_free = op_dev_mem_free, + + .kernel_driver_active = op_kernel_driver_active, + .detach_kernel_driver = op_detach_kernel_driver, + .attach_kernel_driver = op_attach_kernel_driver, + + .destroy_device = op_destroy_device, + + .submit_transfer = op_submit_transfer, + .cancel_transfer = op_cancel_transfer, + .clear_transfer_priv = op_clear_transfer_priv, + + .handle_events = op_handle_events, + + .clock_gettime = op_clock_gettime, + +#ifdef USBI_TIMERFD_AVAILABLE + .get_timerfd_clockid = op_get_timerfd_clockid, +#endif + + .device_priv_size = sizeof(struct linux_device_priv), + .device_handle_priv_size = sizeof(struct linux_device_handle_priv), + .transfer_priv_size = sizeof(struct linux_transfer_priv), +}; diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.h new file mode 100644 index 00000000..8bd3ebcb --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.h @@ -0,0 +1,193 @@ +/* + * usbfs header structures + * Copyright © 2007 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_USBFS_H +#define LIBUSB_USBFS_H + +#include + +#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices" + +struct usbfs_ctrltransfer { + /* keep in sync with usbdevice_fs.h:usbdevfs_ctrltransfer */ + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + + uint32_t timeout; /* in milliseconds */ + + /* pointer to data */ + void *data; +}; + +struct usbfs_bulktransfer { + /* keep in sync with usbdevice_fs.h:usbdevfs_bulktransfer */ + unsigned int ep; + unsigned int len; + unsigned int timeout; /* in milliseconds */ + + /* pointer to data */ + void *data; +}; + +struct usbfs_setinterface { + /* keep in sync with usbdevice_fs.h:usbdevfs_setinterface */ + unsigned int interface; + unsigned int altsetting; +}; + +#define USBFS_MAXDRIVERNAME 255 + +struct usbfs_getdriver { + unsigned int interface; + char driver[USBFS_MAXDRIVERNAME + 1]; +}; + +#define USBFS_URB_SHORT_NOT_OK 0x01 +#define USBFS_URB_ISO_ASAP 0x02 +#define USBFS_URB_BULK_CONTINUATION 0x04 +#define USBFS_URB_QUEUE_BULK 0x10 +#define USBFS_URB_ZERO_PACKET 0x40 + +enum usbfs_urb_type { + USBFS_URB_TYPE_ISO = 0, + USBFS_URB_TYPE_INTERRUPT = 1, + USBFS_URB_TYPE_CONTROL = 2, + USBFS_URB_TYPE_BULK = 3, +}; + +struct usbfs_iso_packet_desc { + unsigned int length; + unsigned int actual_length; + unsigned int status; +}; + +#define MAX_ISO_BUFFER_LENGTH 49152 * 128 +#define MAX_BULK_BUFFER_LENGTH 16384 +#define MAX_CTRL_BUFFER_LENGTH 4096 + +struct usbfs_urb { + unsigned char type; + unsigned char endpoint; + int status; + unsigned int flags; + void *buffer; + int buffer_length; + int actual_length; + int start_frame; + union { + int number_of_packets; /* Only used for isoc urbs */ + unsigned int stream_id; /* Only used with bulk streams */ + }; + int error_count; + unsigned int signr; + void *usercontext; + struct usbfs_iso_packet_desc iso_frame_desc[0]; +}; + +struct usbfs_connectinfo { + unsigned int devnum; + unsigned char slow; +}; + +struct usbfs_ioctl { + int ifno; /* interface 0..N ; negative numbers reserved */ + int ioctl_code; /* MUST encode size + direction of data so the + * macros in give correct values */ + void *data; /* param buffer (in, or out) */ +}; + +struct usbfs_hub_portinfo { + unsigned char numports; + unsigned char port[127]; /* port to device num mapping */ +}; + +#define USBFS_CAP_ZERO_PACKET 0x01 +#define USBFS_CAP_BULK_CONTINUATION 0x02 +#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04 +#define USBFS_CAP_BULK_SCATTER_GATHER 0x08 +#define USBFS_CAP_REAP_AFTER_DISCONNECT 0x10 + +#define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01 +#define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02 + +struct usbfs_disconnect_claim { + unsigned int interface; + unsigned int flags; + char driver[USBFS_MAXDRIVERNAME + 1]; +}; + +struct usbfs_streams { + unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */ + unsigned int num_eps; + unsigned char eps[0]; +}; + +#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer) +#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer) +#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int) +#define IOCTL_USBFS_SETINTF _IOR('U', 4, struct usbfs_setinterface) +#define IOCTL_USBFS_SETCONFIG _IOR('U', 5, unsigned int) +#define IOCTL_USBFS_GETDRIVER _IOW('U', 8, struct usbfs_getdriver) +#define IOCTL_USBFS_SUBMITURB _IOR('U', 10, struct usbfs_urb) +#define IOCTL_USBFS_DISCARDURB _IO('U', 11) +#define IOCTL_USBFS_REAPURB _IOW('U', 12, void *) +#define IOCTL_USBFS_REAPURBNDELAY _IOW('U', 13, void *) +#define IOCTL_USBFS_CLAIMINTF _IOR('U', 15, unsigned int) +#define IOCTL_USBFS_RELEASEINTF _IOR('U', 16, unsigned int) +#define IOCTL_USBFS_CONNECTINFO _IOW('U', 17, struct usbfs_connectinfo) +#define IOCTL_USBFS_IOCTL _IOWR('U', 18, struct usbfs_ioctl) +#define IOCTL_USBFS_HUB_PORTINFO _IOR('U', 19, struct usbfs_hub_portinfo) +#define IOCTL_USBFS_RESET _IO('U', 20) +#define IOCTL_USBFS_CLEAR_HALT _IOR('U', 21, unsigned int) +#define IOCTL_USBFS_DISCONNECT _IO('U', 22) +#define IOCTL_USBFS_CONNECT _IO('U', 23) +#define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int) +#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int) +#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32) +#define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbfs_disconnect_claim) +#define IOCTL_USBFS_ALLOC_STREAMS _IOR('U', 28, struct usbfs_streams) +#define IOCTL_USBFS_FREE_STREAMS _IOR('U', 29, struct usbfs_streams) + +extern usbi_mutex_static_t linux_hotplug_lock; + +#if defined(HAVE_LIBUDEV) +int linux_udev_start_event_monitor(void); +int linux_udev_stop_event_monitor(void); +int linux_udev_scan_devices(struct libusb_context *ctx); +void linux_udev_hotplug_poll(void); +#else +int linux_netlink_start_event_monitor(void); +int linux_netlink_stop_event_monitor(void); +void linux_netlink_hotplug_poll(void); +#endif + +void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name); +void linux_device_disconnected(uint8_t busnum, uint8_t devaddr); + +int linux_get_device_address (struct libusb_context *ctx, int detached, + uint8_t *busnum, uint8_t *devaddr, const char *dev_node, + const char *sys_name); +int linux_enumerate_device(struct libusb_context *ctx, + uint8_t busnum, uint8_t devaddr, const char *sysfs_dir); + +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/netbsd_usb.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/netbsd_usb.c new file mode 100644 index 00000000..ad1ede73 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/netbsd_usb.c @@ -0,0 +1,677 @@ +/* + * Copyright © 2011 Martin Pieuchot + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "libusbi.h" + +struct device_priv { + char devnode[16]; + int fd; + + unsigned char *cdesc; /* active config descriptor */ + usb_device_descriptor_t ddesc; /* usb device descriptor */ +}; + +struct handle_priv { + int endpoints[USB_MAX_ENDPOINTS]; +}; + +/* + * Backend functions + */ +static int netbsd_get_device_list(struct libusb_context *, + struct discovered_devs **); +static int netbsd_open(struct libusb_device_handle *); +static void netbsd_close(struct libusb_device_handle *); + +static int netbsd_get_device_descriptor(struct libusb_device *, unsigned char *, + int *); +static int netbsd_get_active_config_descriptor(struct libusb_device *, + unsigned char *, size_t, int *); +static int netbsd_get_config_descriptor(struct libusb_device *, uint8_t, + unsigned char *, size_t, int *); + +static int netbsd_get_configuration(struct libusb_device_handle *, int *); +static int netbsd_set_configuration(struct libusb_device_handle *, int); + +static int netbsd_claim_interface(struct libusb_device_handle *, int); +static int netbsd_release_interface(struct libusb_device_handle *, int); + +static int netbsd_set_interface_altsetting(struct libusb_device_handle *, int, + int); +static int netbsd_clear_halt(struct libusb_device_handle *, unsigned char); +static int netbsd_reset_device(struct libusb_device_handle *); +static void netbsd_destroy_device(struct libusb_device *); + +static int netbsd_submit_transfer(struct usbi_transfer *); +static int netbsd_cancel_transfer(struct usbi_transfer *); +static void netbsd_clear_transfer_priv(struct usbi_transfer *); +static int netbsd_handle_transfer_completion(struct usbi_transfer *); +static int netbsd_clock_gettime(int, struct timespec *); + +/* + * Private functions + */ +static int _errno_to_libusb(int); +static int _cache_active_config_descriptor(struct libusb_device *, int); +static int _sync_control_transfer(struct usbi_transfer *); +static int _sync_gen_transfer(struct usbi_transfer *); +static int _access_endpoint(struct libusb_transfer *); + +const struct usbi_os_backend netbsd_backend = { + "Synchronous NetBSD backend", + 0, + NULL, /* init() */ + NULL, /* exit() */ + netbsd_get_device_list, + NULL, /* hotplug_poll */ + netbsd_open, + netbsd_close, + + netbsd_get_device_descriptor, + netbsd_get_active_config_descriptor, + netbsd_get_config_descriptor, + NULL, /* get_config_descriptor_by_value() */ + + netbsd_get_configuration, + netbsd_set_configuration, + + netbsd_claim_interface, + netbsd_release_interface, + + netbsd_set_interface_altsetting, + netbsd_clear_halt, + netbsd_reset_device, + + NULL, /* alloc_streams */ + NULL, /* free_streams */ + + NULL, /* dev_mem_alloc() */ + NULL, /* dev_mem_free() */ + + NULL, /* kernel_driver_active() */ + NULL, /* detach_kernel_driver() */ + NULL, /* attach_kernel_driver() */ + + netbsd_destroy_device, + + netbsd_submit_transfer, + netbsd_cancel_transfer, + netbsd_clear_transfer_priv, + + NULL, /* handle_events() */ + netbsd_handle_transfer_completion, + + netbsd_clock_gettime, + sizeof(struct device_priv), + sizeof(struct handle_priv), + 0, /* transfer_priv_size */ +}; + +int +netbsd_get_device_list(struct libusb_context * ctx, + struct discovered_devs **discdevs) +{ + struct libusb_device *dev; + struct device_priv *dpriv; + struct usb_device_info di; + unsigned long session_id; + char devnode[16]; + int fd, err, i; + + usbi_dbg(""); + + /* Only ugen(4) is supported */ + for (i = 0; i < USB_MAX_DEVICES; i++) { + /* Control endpoint is always .00 */ + snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i); + + if ((fd = open(devnode, O_RDONLY)) < 0) { + if (errno != ENOENT && errno != ENXIO) + usbi_err(ctx, "could not open %s", devnode); + continue; + } + + if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0) + continue; + + session_id = (di.udi_bus << 8 | di.udi_addr); + dev = usbi_get_device_by_session_id(ctx, session_id); + + if (dev == NULL) { + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) + return (LIBUSB_ERROR_NO_MEM); + + dev->bus_number = di.udi_bus; + dev->device_address = di.udi_addr; + dev->speed = di.udi_speed; + + dpriv = (struct device_priv *)dev->os_priv; + strlcpy(dpriv->devnode, devnode, sizeof(devnode)); + dpriv->fd = -1; + + if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) { + err = errno; + goto error; + } + + dpriv->cdesc = NULL; + if (_cache_active_config_descriptor(dev, fd)) { + err = errno; + goto error; + } + + if ((err = usbi_sanitize_device(dev))) + goto error; + } + close(fd); + + if (discovered_devs_append(*discdevs, dev) == NULL) + return (LIBUSB_ERROR_NO_MEM); + + libusb_unref_device(dev); + } + + return (LIBUSB_SUCCESS); + +error: + close(fd); + libusb_unref_device(dev); + return _errno_to_libusb(err); +} + +int +netbsd_open(struct libusb_device_handle *handle) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + dpriv->fd = open(dpriv->devnode, O_RDWR); + if (dpriv->fd < 0) { + dpriv->fd = open(dpriv->devnode, O_RDONLY); + if (dpriv->fd < 0) + return _errno_to_libusb(errno); + } + + usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd); + + return (LIBUSB_SUCCESS); +} + +void +netbsd_close(struct libusb_device_handle *handle) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + usbi_dbg("close: fd %d", dpriv->fd); + + close(dpriv->fd); + dpriv->fd = -1; +} + +int +netbsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf, + int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH); + + *host_endian = 0; + + return (LIBUSB_SUCCESS); +} + +int +netbsd_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buf, size_t len, int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + usb_config_descriptor_t *ucd; + + ucd = (usb_config_descriptor_t *) dpriv->cdesc; + len = MIN(len, UGETW(ucd->wTotalLength)); + + usbi_dbg("len %d", len); + + memcpy(buf, dpriv->cdesc, len); + + *host_endian = 0; + + return len; +} + +int +netbsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx, + unsigned char *buf, size_t len, int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + struct usb_full_desc ufd; + int fd, err; + + usbi_dbg("index %d, len %d", idx, len); + + /* A config descriptor may be requested before opening the device */ + if (dpriv->fd >= 0) { + fd = dpriv->fd; + } else { + fd = open(dpriv->devnode, O_RDONLY); + if (fd < 0) + return _errno_to_libusb(errno); + } + + ufd.ufd_config_index = idx; + ufd.ufd_size = len; + ufd.ufd_data = buf; + + if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { + err = errno; + if (dpriv->fd < 0) + close(fd); + return _errno_to_libusb(err); + } + + if (dpriv->fd < 0) + close(fd); + + *host_endian = 0; + + return len; +} + +int +netbsd_get_configuration(struct libusb_device_handle *handle, int *config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + usbi_dbg(""); + + if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0) + return _errno_to_libusb(errno); + + usbi_dbg("configuration %d", *config); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_set_configuration(struct libusb_device_handle *handle, int config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + usbi_dbg("configuration %d", config); + + if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0) + return _errno_to_libusb(errno); + + return _cache_active_config_descriptor(handle->dev, dpriv->fd); +} + +int +netbsd_claim_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + hpriv->endpoints[i] = -1; + + return (LIBUSB_SUCCESS); +} + +int +netbsd_release_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + if (hpriv->endpoints[i] >= 0) + close(hpriv->endpoints[i]); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + struct usb_alt_interface intf; + + usbi_dbg("iface %d, setting %d", iface, altsetting); + + memset(&intf, 0, sizeof(intf)); + + intf.uai_interface_index = iface; + intf.uai_alt_no = altsetting; + + if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0) + return _errno_to_libusb(errno); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + struct usb_ctl_request req; + + usbi_dbg(""); + + req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; + req.ucr_request.bRequest = UR_CLEAR_FEATURE; + USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT); + USETW(req.ucr_request.wIndex, endpoint); + USETW(req.ucr_request.wLength, 0); + + if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0) + return _errno_to_libusb(errno); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_reset_device(struct libusb_device_handle *handle) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +netbsd_destroy_device(struct libusb_device *dev) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + free(dpriv->cdesc); +} + +int +netbsd_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct handle_priv *hpriv; + int err = 0; + + usbi_dbg(""); + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + err = _sync_control_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + if (IS_XFEROUT(transfer)) { + /* Isochronous write is not supported */ + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + + if (err) + return (err); + + usbi_signal_transfer_completion(itransfer); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_cancel_transfer(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +netbsd_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + /* Nothing to do */ +} + +int +netbsd_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED); +} + +int +netbsd_clock_gettime(int clkid, struct timespec *tp) +{ + usbi_dbg("clock %d", clkid); + + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +int +_errno_to_libusb(int err) +{ + switch (err) { + case EIO: + return (LIBUSB_ERROR_IO); + case EACCES: + return (LIBUSB_ERROR_ACCESS); + case ENOENT: + return (LIBUSB_ERROR_NO_DEVICE); + case ENOMEM: + return (LIBUSB_ERROR_NO_MEM); + } + + usbi_dbg("error: %s", strerror(err)); + + return (LIBUSB_ERROR_OTHER); +} + +int +_cache_active_config_descriptor(struct libusb_device *dev, int fd) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + struct usb_config_desc ucd; + struct usb_full_desc ufd; + unsigned char* buf; + int len; + + usbi_dbg("fd %d", fd); + + ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX; + + if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0) + return _errno_to_libusb(errno); + + usbi_dbg("active bLength %d", ucd.ucd_desc.bLength); + + len = UGETW(ucd.ucd_desc.wTotalLength); + buf = malloc(len); + if (buf == NULL) + return (LIBUSB_ERROR_NO_MEM); + + ufd.ufd_config_index = ucd.ucd_config_index; + ufd.ufd_size = len; + ufd.ufd_data = buf; + + usbi_dbg("index %d, len %d", ufd.ufd_config_index, len); + + if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { + free(buf); + return _errno_to_libusb(errno); + } + + if (dpriv->cdesc) + free(dpriv->cdesc); + dpriv->cdesc = buf; + + return (0); +} + +int +_sync_control_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct libusb_control_setup *setup; + struct device_priv *dpriv; + struct usb_ctl_request req; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + setup = (struct libusb_control_setup *)transfer->buffer; + + usbi_dbg("type %d request %d value %d index %d length %d timeout %d", + setup->bmRequestType, setup->bRequest, + libusb_le16_to_cpu(setup->wValue), + libusb_le16_to_cpu(setup->wIndex), + libusb_le16_to_cpu(setup->wLength), transfer->timeout); + + req.ucr_request.bmRequestType = setup->bmRequestType; + req.ucr_request.bRequest = setup->bRequest; + /* Don't use USETW, libusb already deals with the endianness */ + (*(uint16_t *)req.ucr_request.wValue) = setup->wValue; + (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex; + (*(uint16_t *)req.ucr_request.wLength) = setup->wLength; + req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + req.ucr_flags = USBD_SHORT_XFER_OK; + + if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) + return _errno_to_libusb(errno); + + itransfer->transferred = req.ucr_actlen; + + usbi_dbg("transferred %d", itransfer->transferred); + + return (0); +} + +int +_access_endpoint(struct libusb_transfer *transfer) +{ + struct handle_priv *hpriv; + struct device_priv *dpriv; + char *s, devnode[16]; + int fd, endpt; + mode_t mode; + + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + + endpt = UE_GET_ADDR(transfer->endpoint); + mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; + + usbi_dbg("endpoint %d mode %d", endpt, mode); + + if (hpriv->endpoints[endpt] < 0) { + /* Pick the right node given the control one */ + strlcpy(devnode, dpriv->devnode, sizeof(devnode)); + s = strchr(devnode, '.'); + snprintf(s, 4, ".%02d", endpt); + + /* We may need to read/write to the same endpoint later. */ + if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) + if ((fd = open(devnode, mode)) < 0) + return (-1); + + hpriv->endpoints[endpt] = fd; + } + + return (hpriv->endpoints[endpt]); +} + +int +_sync_gen_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + int fd, nr = 1; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + /* + * Bulk, Interrupt or Isochronous transfer depends on the + * endpoint and thus the node to open. + */ + if ((fd = _access_endpoint(transfer)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if (IS_XFERIN(transfer)) { + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0) + return _errno_to_libusb(errno); + + nr = read(fd, transfer->buffer, transfer->length); + } else { + nr = write(fd, transfer->buffer, transfer->length); + } + + if (nr < 0) + return _errno_to_libusb(errno); + + itransfer->transferred = nr; + + return (0); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/openbsd_usb.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/openbsd_usb.c new file mode 100644 index 00000000..c6602571 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/openbsd_usb.c @@ -0,0 +1,771 @@ +/* + * Copyright © 2011-2013 Martin Pieuchot + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "libusbi.h" + +struct device_priv { + char *devname; /* name of the ugen(4) node */ + int fd; /* device file descriptor */ + + unsigned char *cdesc; /* active config descriptor */ + usb_device_descriptor_t ddesc; /* usb device descriptor */ +}; + +struct handle_priv { + int endpoints[USB_MAX_ENDPOINTS]; +}; + +/* + * Backend functions + */ +static int obsd_get_device_list(struct libusb_context *, + struct discovered_devs **); +static int obsd_open(struct libusb_device_handle *); +static void obsd_close(struct libusb_device_handle *); + +static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *, + int *); +static int obsd_get_active_config_descriptor(struct libusb_device *, + unsigned char *, size_t, int *); +static int obsd_get_config_descriptor(struct libusb_device *, uint8_t, + unsigned char *, size_t, int *); + +static int obsd_get_configuration(struct libusb_device_handle *, int *); +static int obsd_set_configuration(struct libusb_device_handle *, int); + +static int obsd_claim_interface(struct libusb_device_handle *, int); +static int obsd_release_interface(struct libusb_device_handle *, int); + +static int obsd_set_interface_altsetting(struct libusb_device_handle *, int, + int); +static int obsd_clear_halt(struct libusb_device_handle *, unsigned char); +static int obsd_reset_device(struct libusb_device_handle *); +static void obsd_destroy_device(struct libusb_device *); + +static int obsd_submit_transfer(struct usbi_transfer *); +static int obsd_cancel_transfer(struct usbi_transfer *); +static void obsd_clear_transfer_priv(struct usbi_transfer *); +static int obsd_handle_transfer_completion(struct usbi_transfer *); +static int obsd_clock_gettime(int, struct timespec *); + +/* + * Private functions + */ +static int _errno_to_libusb(int); +static int _cache_active_config_descriptor(struct libusb_device *); +static int _sync_control_transfer(struct usbi_transfer *); +static int _sync_gen_transfer(struct usbi_transfer *); +static int _access_endpoint(struct libusb_transfer *); + +static int _bus_open(int); + + +const struct usbi_os_backend openbsd_backend = { + "Synchronous OpenBSD backend", + 0, + NULL, /* init() */ + NULL, /* exit() */ + obsd_get_device_list, + NULL, /* hotplug_poll */ + obsd_open, + obsd_close, + + obsd_get_device_descriptor, + obsd_get_active_config_descriptor, + obsd_get_config_descriptor, + NULL, /* get_config_descriptor_by_value() */ + + obsd_get_configuration, + obsd_set_configuration, + + obsd_claim_interface, + obsd_release_interface, + + obsd_set_interface_altsetting, + obsd_clear_halt, + obsd_reset_device, + + NULL, /* alloc_streams */ + NULL, /* free_streams */ + + NULL, /* dev_mem_alloc() */ + NULL, /* dev_mem_free() */ + + NULL, /* kernel_driver_active() */ + NULL, /* detach_kernel_driver() */ + NULL, /* attach_kernel_driver() */ + + obsd_destroy_device, + + obsd_submit_transfer, + obsd_cancel_transfer, + obsd_clear_transfer_priv, + + NULL, /* handle_events() */ + obsd_handle_transfer_completion, + + obsd_clock_gettime, + sizeof(struct device_priv), + sizeof(struct handle_priv), + 0, /* transfer_priv_size */ +}; + +#define DEVPATH "/dev/" +#define USBDEV DEVPATH "usb" + +int +obsd_get_device_list(struct libusb_context * ctx, + struct discovered_devs **discdevs) +{ + struct discovered_devs *ddd; + struct libusb_device *dev; + struct device_priv *dpriv; + struct usb_device_info di; + struct usb_device_ddesc dd; + unsigned long session_id; + char devices[USB_MAX_DEVICES]; + char busnode[16]; + char *udevname; + int fd, addr, i, j; + + usbi_dbg(""); + + for (i = 0; i < 8; i++) { + snprintf(busnode, sizeof(busnode), USBDEV "%d", i); + + if ((fd = open(busnode, O_RDWR)) < 0) { + if (errno != ENOENT && errno != ENXIO) + usbi_err(ctx, "could not open %s", busnode); + continue; + } + + bzero(devices, sizeof(devices)); + for (addr = 1; addr < USB_MAX_DEVICES; addr++) { + if (devices[addr]) + continue; + + di.udi_addr = addr; + if (ioctl(fd, USB_DEVICEINFO, &di) < 0) + continue; + + /* + * XXX If ugen(4) is attached to the USB device + * it will be used. + */ + udevname = NULL; + for (j = 0; j < USB_MAX_DEVNAMES; j++) + if (!strncmp("ugen", di.udi_devnames[j], 4)) { + udevname = strdup(di.udi_devnames[j]); + break; + } + + session_id = (di.udi_bus << 8 | di.udi_addr); + dev = usbi_get_device_by_session_id(ctx, session_id); + + if (dev == NULL) { + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) { + close(fd); + return (LIBUSB_ERROR_NO_MEM); + } + + dev->bus_number = di.udi_bus; + dev->device_address = di.udi_addr; + dev->speed = di.udi_speed; + + dpriv = (struct device_priv *)dev->os_priv; + dpriv->fd = -1; + dpriv->cdesc = NULL; + dpriv->devname = udevname; + + dd.udd_bus = di.udi_bus; + dd.udd_addr = di.udi_addr; + if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) { + libusb_unref_device(dev); + continue; + } + dpriv->ddesc = dd.udd_desc; + + if (_cache_active_config_descriptor(dev)) { + libusb_unref_device(dev); + continue; + } + + if (usbi_sanitize_device(dev)) { + libusb_unref_device(dev); + continue; + } + } + + ddd = discovered_devs_append(*discdevs, dev); + if (ddd == NULL) { + close(fd); + return (LIBUSB_ERROR_NO_MEM); + } + libusb_unref_device(dev); + + *discdevs = ddd; + devices[addr] = 1; + } + + close(fd); + } + + return (LIBUSB_SUCCESS); +} + +int +obsd_open(struct libusb_device_handle *handle) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + char devnode[16]; + + if (dpriv->devname) { + /* + * Only open ugen(4) attached devices read-write, all + * read-only operations are done through the bus node. + */ + snprintf(devnode, sizeof(devnode), DEVPATH "%s.00", + dpriv->devname); + dpriv->fd = open(devnode, O_RDWR); + if (dpriv->fd < 0) + return _errno_to_libusb(errno); + + usbi_dbg("open %s: fd %d", devnode, dpriv->fd); + } + + return (LIBUSB_SUCCESS); +} + +void +obsd_close(struct libusb_device_handle *handle) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + if (dpriv->devname) { + usbi_dbg("close: fd %d", dpriv->fd); + + close(dpriv->fd); + dpriv->fd = -1; + } +} + +int +obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf, + int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH); + + *host_endian = 0; + + return (LIBUSB_SUCCESS); +} + +int +obsd_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buf, size_t len, int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; + + len = MIN(len, UGETW(ucd->wTotalLength)); + + usbi_dbg("len %d", len); + + memcpy(buf, dpriv->cdesc, len); + + *host_endian = 0; + + return (len); +} + +int +obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx, + unsigned char *buf, size_t len, int *host_endian) +{ + struct usb_device_fdesc udf; + int fd, err; + + if ((fd = _bus_open(dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + udf.udf_bus = dev->bus_number; + udf.udf_addr = dev->device_address; + udf.udf_config_index = idx; + udf.udf_size = len; + udf.udf_data = buf; + + usbi_dbg("index %d, len %d", udf.udf_config_index, len); + + if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(err); + } + close(fd); + + *host_endian = 0; + + return (len); +} + +int +obsd_get_configuration(struct libusb_device_handle *handle, int *config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; + + *config = ucd->bConfigurationValue; + + usbi_dbg("bConfigurationValue %d", *config); + + return (LIBUSB_SUCCESS); +} + +int +obsd_set_configuration(struct libusb_device_handle *handle, int config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + if (dpriv->devname == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + usbi_dbg("bConfigurationValue %d", config); + + if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0) + return _errno_to_libusb(errno); + + return _cache_active_config_descriptor(handle->dev); +} + +int +obsd_claim_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + hpriv->endpoints[i] = -1; + + return (LIBUSB_SUCCESS); +} + +int +obsd_release_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + if (hpriv->endpoints[i] >= 0) + close(hpriv->endpoints[i]); + + return (LIBUSB_SUCCESS); +} + +int +obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + struct usb_alt_interface intf; + + if (dpriv->devname == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + usbi_dbg("iface %d, setting %d", iface, altsetting); + + memset(&intf, 0, sizeof(intf)); + + intf.uai_interface_index = iface; + intf.uai_alt_no = altsetting; + + if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0) + return _errno_to_libusb(errno); + + return (LIBUSB_SUCCESS); +} + +int +obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint) +{ + struct usb_ctl_request req; + int fd, err; + + if ((fd = _bus_open(handle->dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + usbi_dbg(""); + + req.ucr_addr = handle->dev->device_address; + req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; + req.ucr_request.bRequest = UR_CLEAR_FEATURE; + USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT); + USETW(req.ucr_request.wIndex, endpoint); + USETW(req.ucr_request.wLength, 0); + + if (ioctl(fd, USB_REQUEST, &req) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(err); + } + close(fd); + + return (LIBUSB_SUCCESS); +} + +int +obsd_reset_device(struct libusb_device_handle *handle) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +obsd_destroy_device(struct libusb_device *dev) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + free(dpriv->cdesc); + free(dpriv->devname); +} + +int +obsd_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct handle_priv *hpriv; + int err = 0; + + usbi_dbg(""); + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + err = _sync_control_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + if (IS_XFEROUT(transfer)) { + /* Isochronous write is not supported */ + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + + if (err) + return (err); + + usbi_signal_transfer_completion(itransfer); + + return (LIBUSB_SUCCESS); +} + +int +obsd_cancel_transfer(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +obsd_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + /* Nothing to do */ +} + +int +obsd_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED); +} + +int +obsd_clock_gettime(int clkid, struct timespec *tp) +{ + usbi_dbg("clock %d", clkid); + + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +int +_errno_to_libusb(int err) +{ + usbi_dbg("error: %s (%d)", strerror(err), err); + + switch (err) { + case EIO: + return (LIBUSB_ERROR_IO); + case EACCES: + return (LIBUSB_ERROR_ACCESS); + case ENOENT: + return (LIBUSB_ERROR_NO_DEVICE); + case ENOMEM: + return (LIBUSB_ERROR_NO_MEM); + case ETIMEDOUT: + return (LIBUSB_ERROR_TIMEOUT); + } + + return (LIBUSB_ERROR_OTHER); +} + +int +_cache_active_config_descriptor(struct libusb_device *dev) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + struct usb_device_cdesc udc; + struct usb_device_fdesc udf; + unsigned char* buf; + int fd, len, err; + + if ((fd = _bus_open(dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + usbi_dbg("fd %d, addr %d", fd, dev->device_address); + + udc.udc_bus = dev->bus_number; + udc.udc_addr = dev->device_address; + udc.udc_config_index = USB_CURRENT_CONFIG_INDEX; + if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(errno); + } + + usbi_dbg("active bLength %d", udc.udc_desc.bLength); + + len = UGETW(udc.udc_desc.wTotalLength); + buf = malloc(len); + if (buf == NULL) + return (LIBUSB_ERROR_NO_MEM); + + udf.udf_bus = dev->bus_number; + udf.udf_addr = dev->device_address; + udf.udf_config_index = udc.udc_config_index; + udf.udf_size = len; + udf.udf_data = buf; + + usbi_dbg("index %d, len %d", udf.udf_config_index, len); + + if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { + err = errno; + close(fd); + free(buf); + return _errno_to_libusb(err); + } + close(fd); + + if (dpriv->cdesc) + free(dpriv->cdesc); + dpriv->cdesc = buf; + + return (LIBUSB_SUCCESS); +} + +int +_sync_control_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct libusb_control_setup *setup; + struct device_priv *dpriv; + struct usb_ctl_request req; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + setup = (struct libusb_control_setup *)transfer->buffer; + + usbi_dbg("type %x request %x value %x index %d length %d timeout %d", + setup->bmRequestType, setup->bRequest, + libusb_le16_to_cpu(setup->wValue), + libusb_le16_to_cpu(setup->wIndex), + libusb_le16_to_cpu(setup->wLength), transfer->timeout); + + req.ucr_addr = transfer->dev_handle->dev->device_address; + req.ucr_request.bmRequestType = setup->bmRequestType; + req.ucr_request.bRequest = setup->bRequest; + /* Don't use USETW, libusb already deals with the endianness */ + (*(uint16_t *)req.ucr_request.wValue) = setup->wValue; + (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex; + (*(uint16_t *)req.ucr_request.wLength) = setup->wLength; + req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + req.ucr_flags = USBD_SHORT_XFER_OK; + + if (dpriv->devname == NULL) { + /* + * XXX If the device is not attached to ugen(4) it is + * XXX still possible to submit a control transfer but + * XXX with the default timeout only. + */ + int fd, err; + + if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(fd, USB_REQUEST, &req)) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(err); + } + close(fd); + } else { + if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) + return _errno_to_libusb(errno); + } + + itransfer->transferred = req.ucr_actlen; + + usbi_dbg("transferred %d", itransfer->transferred); + + return (0); +} + +int +_access_endpoint(struct libusb_transfer *transfer) +{ + struct handle_priv *hpriv; + struct device_priv *dpriv; + char devnode[16]; + int fd, endpt; + mode_t mode; + + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + + endpt = UE_GET_ADDR(transfer->endpoint); + mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; + + usbi_dbg("endpoint %d mode %d", endpt, mode); + + if (hpriv->endpoints[endpt] < 0) { + /* Pick the right endpoint node */ + snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d", + dpriv->devname, endpt); + + /* We may need to read/write to the same endpoint later. */ + if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) + if ((fd = open(devnode, mode)) < 0) + return (-1); + + hpriv->endpoints[endpt] = fd; + } + + return (hpriv->endpoints[endpt]); +} + +int +_sync_gen_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct device_priv *dpriv; + int fd, nr = 1; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + + if (dpriv->devname == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + /* + * Bulk, Interrupt or Isochronous transfer depends on the + * endpoint and thus the node to open. + */ + if ((fd = _access_endpoint(transfer)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if (IS_XFERIN(transfer)) { + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0) + return _errno_to_libusb(errno); + + nr = read(fd, transfer->buffer, transfer->length); + } else { + nr = write(fd, transfer->buffer, transfer->length); + } + + if (nr < 0) + return _errno_to_libusb(errno); + + itransfer->transferred = nr; + + return (0); +} + +int +_bus_open(int number) +{ + char busnode[16]; + + snprintf(busnode, sizeof(busnode), USBDEV "%d", number); + + return open(busnode, O_RDWR); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.c new file mode 100644 index 00000000..e2f55a57 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.c @@ -0,0 +1,53 @@ +/* + * poll_posix: poll compatibility wrapper for POSIX systems + * Copyright © 2013 RealVNC Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +int usbi_pipe(int pipefd[2]) +{ + int ret = pipe(pipefd); + if (ret != 0) { + return ret; + } + ret = fcntl(pipefd[1], F_GETFL); + if (ret == -1) { + usbi_dbg("Failed to get pipe fd flags: %d", errno); + goto err_close_pipe; + } + ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK); + if (ret != 0) { + usbi_dbg("Failed to set non-blocking on new pipe: %d", errno); + goto err_close_pipe; + } + + return 0; + +err_close_pipe: + usbi_close(pipefd[0]); + usbi_close(pipefd[1]); + return ret; +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.h new file mode 100644 index 00000000..5b4b2c90 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.h @@ -0,0 +1,11 @@ +#ifndef LIBUSB_POLL_POSIX_H +#define LIBUSB_POLL_POSIX_H + +#define usbi_write write +#define usbi_read read +#define usbi_close close +#define usbi_poll poll + +int usbi_pipe(int pipefd[2]); + +#endif /* LIBUSB_POLL_POSIX_H */ diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.c new file mode 100644 index 00000000..98256075 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.c @@ -0,0 +1,728 @@ +/* + * poll_windows: poll compatibility wrapper for Windows + * Copyright © 2012-2013 RealVNC Ltd. + * Copyright © 2009-2010 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of poll implementation from libusb-win32, by Stephan Meyer et al. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* + * poll() and pipe() Windows compatibility layer for libusb 1.0 + * + * The way this layer works is by using OVERLAPPED with async I/O transfers, as + * OVERLAPPED have an associated event which is flagged for I/O completion. + * + * For USB pollable async I/O, you would typically: + * - obtain a Windows HANDLE to a file or device that has been opened in + * OVERLAPPED mode + * - call usbi_create_fd with this handle to obtain a custom fd. + * Note that if you need simultaneous R/W access, you need to call create_fd + * twice, once in RW_READ and once in RW_WRITE mode to obtain 2 separate + * pollable fds + * - leave the core functions call the poll routine and flag POLLIN/POLLOUT + * + * The pipe pollable synchronous I/O works using the overlapped event associated + * with a fake pipe. The read/write functions are only meant to be used in that + * context. + */ +#include + +#include +#include +#include + +#include "libusbi.h" + +// Uncomment to debug the polling layer +//#define DEBUG_POLL_WINDOWS +#if defined(DEBUG_POLL_WINDOWS) +#define poll_dbg usbi_dbg +#else +// MSVC++ < 2005 cannot use a variadic argument and non MSVC +// compilers produce warnings if parenthesis are omitted. +#if defined(_MSC_VER) && (_MSC_VER < 1400) +#define poll_dbg +#else +#define poll_dbg(...) +#endif +#endif + +#if defined(_PREFAST_) +#pragma warning(disable:28719) +#endif + +#define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0) + +// public fd data +const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, NULL, NULL, RW_NONE}; +struct winfd poll_fd[MAX_FDS]; +// internal fd data +struct { + CRITICAL_SECTION mutex; // lock for fds + // Additional variables for XP CancelIoEx partial emulation + HANDLE original_handle; + DWORD thread_id; +} _poll_fd[MAX_FDS]; + +// globals +BOOLEAN is_polling_set = FALSE; +LONG pipe_number = 0; +static volatile LONG compat_spinlock = 0; + +#if !defined(_WIN32_WCE) +// CancelIoEx, available on Vista and later only, provides the ability to cancel +// a single transfer (OVERLAPPED) when used. As it may not be part of any of the +// platform headers, we hook into the Kernel32 system DLL directly to seek it. +static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; +#define Use_Duplicate_Handles (pCancelIoEx == NULL) + +static inline void setup_cancel_io(void) +{ + HMODULE hKernel32 = GetModuleHandleA("KERNEL32"); + if (hKernel32 != NULL) { + pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED)) + GetProcAddress(hKernel32, "CancelIoEx"); + } + usbi_dbg("Will use CancelIo%s for I/O cancellation", + Use_Duplicate_Handles?"":"Ex"); +} + +static inline BOOL cancel_io(int _index) +{ + if ((_index < 0) || (_index >= MAX_FDS)) { + return FALSE; + } + + if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE) + || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) { + return TRUE; + } + if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) { + // Cancel outstanding transfer via the specific callback + (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer); + return TRUE; + } + if (pCancelIoEx != NULL) { + return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped); + } + if (_poll_fd[_index].thread_id == GetCurrentThreadId()) { + return CancelIo(poll_fd[_index].handle); + } + usbi_warn(NULL, "Unable to cancel I/O that was started from another thread"); + return FALSE; +} +#else +#define Use_Duplicate_Handles FALSE + +static __inline void setup_cancel_io() +{ + // No setup needed on WinCE +} + +static __inline BOOL cancel_io(int _index) +{ + if ((_index < 0) || (_index >= MAX_FDS)) { + return FALSE; + } + if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE) + || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) { + return TRUE; + } + if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) { + // Cancel outstanding transfer via the specific callback + (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer); + } + return TRUE; +} +#endif + +// Init +void init_polling(void) +{ + int i; + + while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) { + SleepEx(0, TRUE); + } + if (!is_polling_set) { + setup_cancel_io(); + for (i=0; ihEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if(overlapped->hEvent == NULL) { + free (overlapped); + return NULL; + } + return overlapped; +} + +static void free_overlapped(OVERLAPPED *overlapped) +{ + if (overlapped == NULL) + return; + + if ( (overlapped->hEvent != 0) + && (overlapped->hEvent != INVALID_HANDLE_VALUE) ) { + CloseHandle(overlapped->hEvent); + } + free(overlapped); +} + +void exit_polling(void) +{ + int i; + + while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) { + SleepEx(0, TRUE); + } + if (is_polling_set) { + is_polling_set = FALSE; + + for (i=0; iInternal = STATUS_PENDING; + overlapped->InternalHigh = 0; + + for (i=0; i= 0) { + LeaveCriticalSection(&_poll_fd[i].mutex); + continue; + } + + // Use index as the unique fd number + poll_fd[i].fd = i; + // Read end of the "pipe" + filedes[0] = poll_fd[i].fd; + // We can use the same handle for both ends + filedes[1] = filedes[0]; + + poll_fd[i].handle = DUMMY_HANDLE; + poll_fd[i].overlapped = overlapped; + // There's no polling on the write end, so we just use READ for our needs + poll_fd[i].rw = RW_READ; + _poll_fd[i].original_handle = INVALID_HANDLE_VALUE; + LeaveCriticalSection(&_poll_fd[i].mutex); + return 0; + } + } + free_overlapped(overlapped); + return -1; +} + +/* + * Create both an fd and an OVERLAPPED from an open Windows handle, so that + * it can be used with our polling function + * The handle MUST support overlapped transfers (usually requires CreateFile + * with FILE_FLAG_OVERLAPPED) + * Return a pollable file descriptor struct, or INVALID_WINFD on error + * + * Note that the fd returned by this function is a per-transfer fd, rather + * than a per-session fd and cannot be used for anything else but our + * custom functions (the fd itself points to the NUL: device) + * if you plan to do R/W on the same handle, you MUST create 2 fds: one for + * read and one for write. Using a single R/W fd is unsupported and will + * produce unexpected results + */ +struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn) +{ + int i; + struct winfd wfd = INVALID_WINFD; + OVERLAPPED* overlapped = NULL; + + CHECK_INIT_POLLING; + + if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) { + return INVALID_WINFD; + } + + wfd.itransfer = itransfer; + wfd.cancel_fn = cancel_fn; + + if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) { + usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported. " + "If you want to poll for R/W simultaneously, create multiple fds from the same handle."); + return INVALID_WINFD; + } + if (access_mode == RW_READ) { + wfd.rw = RW_READ; + } else { + wfd.rw = RW_WRITE; + } + + overlapped = create_overlapped(); + if(overlapped == NULL) { + return INVALID_WINFD; + } + + for (i=0; i= 0) { + LeaveCriticalSection(&_poll_fd[i].mutex); + continue; + } + // Use index as the unique fd number + wfd.fd = i; + // Attempt to emulate some of the CancelIoEx behaviour on platforms + // that don't have it + if (Use_Duplicate_Handles) { + _poll_fd[i].thread_id = GetCurrentThreadId(); + if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), + &wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { + usbi_dbg("could not duplicate handle for CancelIo - using original one"); + wfd.handle = handle; + // Make sure we won't close the original handle on fd deletion then + _poll_fd[i].original_handle = INVALID_HANDLE_VALUE; + } else { + _poll_fd[i].original_handle = handle; + } + } else { + wfd.handle = handle; + } + wfd.overlapped = overlapped; + memcpy(&poll_fd[i], &wfd, sizeof(struct winfd)); + LeaveCriticalSection(&_poll_fd[i].mutex); + return wfd; + } + } + free_overlapped(overlapped); + return INVALID_WINFD; +} + +static void _free_index(int _index) +{ + // Cancel any async IO (Don't care about the validity of our handles for this) + cancel_io(_index); + // close the duplicate handle (if we have an actual duplicate) + if (Use_Duplicate_Handles) { + if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) { + CloseHandle(poll_fd[_index].handle); + } + _poll_fd[_index].original_handle = INVALID_HANDLE_VALUE; + _poll_fd[_index].thread_id = 0; + } + free_overlapped(poll_fd[_index].overlapped); + poll_fd[_index] = INVALID_WINFD; +} + +/* + * Release a pollable file descriptor. + * + * Note that the associated Windows handle is not closed by this call + */ +void usbi_free_fd(struct winfd *wfd) +{ + int _index; + + CHECK_INIT_POLLING; + + _index = _fd_to_index_and_lock(wfd->fd); + if (_index < 0) { + return; + } + _free_index(_index); + *wfd = INVALID_WINFD; + LeaveCriticalSection(&_poll_fd[_index].mutex); +} + +/* + * The functions below perform various conversions between fd, handle and OVERLAPPED + */ +struct winfd fd_to_winfd(int fd) +{ + int i; + struct winfd wfd; + + CHECK_INIT_POLLING; + + if (fd < 0) + return INVALID_WINFD; + + for (i=0; i= 0) { + LeaveCriticalSection(&_poll_fd[_index].mutex); + } + usbi_warn(NULL, "invalid fd"); + triggered = -1; + goto poll_exit; + } + + // IN or OUT must match our fd direction + if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) { + fds[i].revents |= POLLNVAL | POLLERR; + errno = EBADF; + usbi_warn(NULL, "attempted POLLIN on fd without READ access"); + LeaveCriticalSection(&_poll_fd[_index].mutex); + triggered = -1; + goto poll_exit; + } + + if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) { + fds[i].revents |= POLLNVAL | POLLERR; + errno = EBADF; + usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access"); + LeaveCriticalSection(&_poll_fd[_index].mutex); + triggered = -1; + goto poll_exit; + } + + // The following macro only works if overlapped I/O was reported pending + if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped)) + || (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) { + poll_dbg(" completed"); + // checks above should ensure this works: + fds[i].revents = fds[i].events; + triggered++; + } else { + handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent; + handle_to_index[nb_handles_to_wait_on] = i; + nb_handles_to_wait_on++; + } + LeaveCriticalSection(&_poll_fd[_index].mutex); + } + + // If nothing was triggered, wait on all fds that require it + if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) { + if (timeout < 0) { + poll_dbg("starting infinite wait for %u handles...", (unsigned int)nb_handles_to_wait_on); + } else { + poll_dbg("starting %d ms wait for %u handles...", timeout, (unsigned int)nb_handles_to_wait_on); + } + ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on, + FALSE, (timeout<0)?INFINITE:(DWORD)timeout); + object_index = ret-WAIT_OBJECT_0; + if ((object_index >= 0) && ((DWORD)object_index < nb_handles_to_wait_on)) { + poll_dbg(" completed after wait"); + i = handle_to_index[object_index]; + _index = _fd_to_index_and_lock(fds[i].fd); + fds[i].revents = fds[i].events; + triggered++; + if (_index >= 0) { + LeaveCriticalSection(&_poll_fd[_index].mutex); + } + } else if (ret == WAIT_TIMEOUT) { + poll_dbg(" timed out"); + triggered = 0; // 0 = timeout + } else { + errno = EIO; + triggered = -1; // error + } + } + +poll_exit: + if (handles_to_wait_on != NULL) { + free(handles_to_wait_on); + } + if (handle_to_index != NULL) { + free(handle_to_index); + } + return triggered; +} + +/* + * close a fake pipe fd + */ +int usbi_close(int fd) +{ + int _index; + int r = -1; + + CHECK_INIT_POLLING; + + _index = _fd_to_index_and_lock(fd); + + if (_index < 0) { + errno = EBADF; + } else { + free_overlapped(poll_fd[_index].overlapped); + poll_fd[_index] = INVALID_WINFD; + LeaveCriticalSection(&_poll_fd[_index].mutex); + } + return r; +} + +/* + * synchronous write for fake "pipe" signaling + */ +ssize_t usbi_write(int fd, const void *buf, size_t count) +{ + int _index; + UNUSED(buf); + + CHECK_INIT_POLLING; + + if (count != sizeof(unsigned char)) { + usbi_err(NULL, "this function should only used for signaling"); + return -1; + } + + _index = _fd_to_index_and_lock(fd); + + if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) { + errno = EBADF; + if (_index >= 0) { + LeaveCriticalSection(&_poll_fd[_index].mutex); + } + return -1; + } + + poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, (unsigned int)GetCurrentThreadId()); + SetEvent(poll_fd[_index].overlapped->hEvent); + poll_fd[_index].overlapped->Internal = STATUS_WAIT_0; + // If two threads write on the pipe at the same time, we need to + // process two separate reads => use the overlapped as a counter + poll_fd[_index].overlapped->InternalHigh++; + + LeaveCriticalSection(&_poll_fd[_index].mutex); + return sizeof(unsigned char); +} + +/* + * synchronous read for fake "pipe" signaling + */ +ssize_t usbi_read(int fd, void *buf, size_t count) +{ + int _index; + ssize_t r = -1; + UNUSED(buf); + + CHECK_INIT_POLLING; + + if (count != sizeof(unsigned char)) { + usbi_err(NULL, "this function should only used for signaling"); + return -1; + } + + _index = _fd_to_index_and_lock(fd); + + if (_index < 0) { + errno = EBADF; + return -1; + } + + if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) { + usbi_warn(NULL, "waiting for event failed: %u", (unsigned int)GetLastError()); + errno = EIO; + goto out; + } + + poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, (unsigned int)GetCurrentThreadId()); + poll_fd[_index].overlapped->InternalHigh--; + // Don't reset unless we don't have any more events to process + if (poll_fd[_index].overlapped->InternalHigh <= 0) { + ResetEvent(poll_fd[_index].overlapped->hEvent); + poll_fd[_index].overlapped->Internal = STATUS_PENDING; + } + + r = sizeof(unsigned char); + +out: + LeaveCriticalSection(&_poll_fd[_index].mutex); + return r; +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.h new file mode 100644 index 00000000..aa4c985d --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.h @@ -0,0 +1,131 @@ +/* + * Windows compat: POSIX compatibility wrapper + * Copyright © 2012-2013 RealVNC Ltd. + * Copyright © 2009-2010 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of poll implementation from libusb-win32, by Stephan Meyer et al. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#pragma once + +#if defined(_MSC_VER) +// disable /W4 MSVC warnings that are benign +#pragma warning(disable:4127) // conditional expression is constant +#endif + +// Handle synchronous completion through the overlapped structure +#if !defined(STATUS_REPARSE) // reuse the REPARSE status code +#define STATUS_REPARSE ((LONG)0x00000104L) +#endif +#define STATUS_COMPLETED_SYNCHRONOUSLY STATUS_REPARSE +#if defined(_WIN32_WCE) +// WinCE doesn't have a HasOverlappedIoCompleted() macro, so attempt to emulate it +#define HasOverlappedIoCompleted(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) != STATUS_PENDING) +#endif +#define HasOverlappedIoCompletedSync(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) == STATUS_COMPLETED_SYNCHRONOUSLY) + +#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2) + +/* Windows versions */ +enum windows_version { + WINDOWS_CE = -2, + WINDOWS_UNDEFINED = -1, + WINDOWS_UNSUPPORTED = 0, + WINDOWS_XP = 0x51, + WINDOWS_2003 = 0x52, // Also XP x64 + WINDOWS_VISTA = 0x60, + WINDOWS_7 = 0x61, + WINDOWS_8 = 0x62, + WINDOWS_8_1_OR_LATER = 0x63, + WINDOWS_MAX +}; +extern int windows_version; + +#define MAX_FDS 256 + +#define POLLIN 0x0001 /* There is data to read */ +#define POLLPRI 0x0002 /* There is urgent data to read */ +#define POLLOUT 0x0004 /* Writing now will not block */ +#define POLLERR 0x0008 /* Error condition */ +#define POLLHUP 0x0010 /* Hung up */ +#define POLLNVAL 0x0020 /* Invalid request: fd not open */ + +struct pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; + +// access modes +enum rw_type { + RW_NONE, + RW_READ, + RW_WRITE, +}; + +// fd struct that can be used for polling on Windows +typedef int cancel_transfer(struct usbi_transfer *itransfer); + +struct winfd { + int fd; // what's exposed to libusb core + HANDLE handle; // what we need to attach overlapped to the I/O op, so we can poll it + OVERLAPPED* overlapped; // what will report our I/O status + struct usbi_transfer *itransfer; // Associated transfer, or NULL if completed + cancel_transfer *cancel_fn; // Function pointer to cancel transfer API + enum rw_type rw; // I/O transfer direction: read *XOR* write (NOT BOTH) +}; +extern const struct winfd INVALID_WINFD; + +int usbi_pipe(int pipefd[2]); +int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout); +ssize_t usbi_write(int fd, const void *buf, size_t count); +ssize_t usbi_read(int fd, void *buf, size_t count); +int usbi_close(int fd); + +void init_polling(void); +void exit_polling(void); +struct winfd usbi_create_fd(HANDLE handle, int access_mode, + struct usbi_transfer *transfer, cancel_transfer *cancel_fn); +void usbi_free_fd(struct winfd* winfd); +struct winfd fd_to_winfd(int fd); +struct winfd handle_to_winfd(HANDLE handle); +struct winfd overlapped_to_winfd(OVERLAPPED* overlapped); + +/* + * Timeval operations + */ +#if defined(DDKBUILD) +#include // defines timeval functions on DDK +#endif + +#if !defined(TIMESPEC_TO_TIMEVAL) +#define TIMESPEC_TO_TIMEVAL(tv, ts) { \ + (tv)->tv_sec = (long)(ts)->tv_sec; \ + (tv)->tv_usec = (long)(ts)->tv_nsec / 1000; \ +} +#endif +#if !defined(timersub) +#define timersub(a, b, result) \ +do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ +} while (0) +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.c new file mode 100644 index 00000000..cb608976 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.c @@ -0,0 +1,1292 @@ +/* + * + * Copyright (c) 2016, Oracle and/or its affiliates. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "sunos_usb.h" + +/* + * Backend functions + */ +static int sunos_init(struct libusb_context *); +static void sunos_exit(void); +static int sunos_get_device_list(struct libusb_context *, + struct discovered_devs **); +static int sunos_open(struct libusb_device_handle *); +static void sunos_close(struct libusb_device_handle *); +static int sunos_get_device_descriptor(struct libusb_device *, + uint8_t*, int *); +static int sunos_get_active_config_descriptor(struct libusb_device *, + uint8_t*, size_t, int *); +static int sunos_get_config_descriptor(struct libusb_device *, uint8_t, + uint8_t*, size_t, int *); +static int sunos_get_configuration(struct libusb_device_handle *, int *); +static int sunos_set_configuration(struct libusb_device_handle *, int); +static int sunos_claim_interface(struct libusb_device_handle *, int); +static int sunos_release_interface(struct libusb_device_handle *, int); +static int sunos_set_interface_altsetting(struct libusb_device_handle *, + int, int); +static int sunos_clear_halt(struct libusb_device_handle *, uint8_t); +static int sunos_reset_device(struct libusb_device_handle *); +static void sunos_destroy_device(struct libusb_device *); +static int sunos_submit_transfer(struct usbi_transfer *); +static int sunos_cancel_transfer(struct usbi_transfer *); +static void sunos_clear_transfer_priv(struct usbi_transfer *); +static int sunos_handle_transfer_completion(struct usbi_transfer *); +static int sunos_clock_gettime(int, struct timespec *); + +/* + * Private functions + */ +static int _errno_to_libusb(int); +static int sunos_usb_get_status(int fd); + +static int sunos_init(struct libusb_context *ctx) +{ + return (LIBUSB_SUCCESS); +} + +static void sunos_exit(void) +{ + usbi_dbg(""); +} + +static int +sunos_fill_in_dev_info(di_node_t node, struct libusb_device *dev) +{ + int proplen; + int n, *addr, *port_prop; + char *phypath; + uint8_t *rdata; + struct libusb_device_descriptor *descr; + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + + /* Device descriptors */ + proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, + "usb-dev-descriptor", &rdata); + if (proplen <= 0) { + + return (LIBUSB_ERROR_IO); + } + + descr = (struct libusb_device_descriptor *)rdata; + bcopy(descr, &dpriv->dev_descr, LIBUSB_DT_DEVICE_SIZE); + dpriv->dev_descr.bcdUSB = libusb_cpu_to_le16(descr->bcdUSB); + dpriv->dev_descr.idVendor = libusb_cpu_to_le16(descr->idVendor); + dpriv->dev_descr.idProduct = libusb_cpu_to_le16(descr->idProduct); + dpriv->dev_descr.bcdDevice = libusb_cpu_to_le16(descr->bcdDevice); + + /* Raw configuration descriptors */ + proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, + "usb-raw-cfg-descriptors", &rdata); + if (proplen <= 0) { + usbi_dbg("can't find raw config descriptors"); + + return (LIBUSB_ERROR_IO); + } + dpriv->raw_cfgdescr = calloc(1, proplen); + if (dpriv->raw_cfgdescr == NULL) { + return (LIBUSB_ERROR_NO_MEM); + } else { + bcopy(rdata, dpriv->raw_cfgdescr, proplen); + dpriv->cfgvalue = ((struct libusb_config_descriptor *) + rdata)->bConfigurationValue; + } + + n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &port_prop); + + if ((n != 1) || (*port_prop <= 0)) { + return (LIBUSB_ERROR_IO); + } + dev->port_number = *port_prop; + + /* device physical path */ + phypath = di_devfs_path(node); + if (phypath) { + dpriv->phypath = strdup(phypath); + di_devfs_path_free(phypath); + } else { + free(dpriv->raw_cfgdescr); + + return (LIBUSB_ERROR_IO); + } + + /* address */ + n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "assigned-address", &addr); + if (n != 1 || *addr == 0) { + usbi_dbg("can't get address"); + } else { + dev->device_address = *addr; + } + + /* speed */ + if (di_prop_exists(DDI_DEV_T_ANY, node, "low-speed") == 1) { + dev->speed = LIBUSB_SPEED_LOW; + } else if (di_prop_exists(DDI_DEV_T_ANY, node, "high-speed") == 1) { + dev->speed = LIBUSB_SPEED_HIGH; + } else if (di_prop_exists(DDI_DEV_T_ANY, node, "full-speed") == 1) { + dev->speed = LIBUSB_SPEED_FULL; + } else if (di_prop_exists(DDI_DEV_T_ANY, node, "super-speed") == 1) { + dev->speed = LIBUSB_SPEED_SUPER; + } + + usbi_dbg("vid=%x pid=%x, path=%s, bus_nmber=0x%x, port_number=%d, " + "speed=%d", dpriv->dev_descr.idVendor, dpriv->dev_descr.idProduct, + dpriv->phypath, dev->bus_number, dev->port_number, dev->speed); + + return (LIBUSB_SUCCESS); +} + + +static int +sunos_add_devices(di_devlink_t link, void *arg) +{ + struct devlink_cbarg *largs = (struct devlink_cbarg *)arg; + struct node_args *nargs; + di_node_t myself, pnode; + uint64_t session_id = 0; + uint16_t bdf = 0; + struct libusb_device *dev; + sunos_dev_priv_t *devpriv; + const char *path, *newpath; + int n, i; + int *addr_prop; + uint8_t bus_number = 0; + + nargs = (struct node_args *)largs->nargs; + myself = largs->myself; + if (nargs->last_ugenpath) { + /* the same node's links */ + return (DI_WALK_CONTINUE); + } + + /* + * Construct session ID. + * session ID = ...parent hub addr|hub addr|dev addr. + */ + pnode = myself; + i = 0; + while (pnode != DI_NODE_NIL) { + if (di_prop_exists(DDI_DEV_T_ANY, pnode, "root-hub") == 1) { + /* walk to root */ + uint32_t *regbuf = NULL; + uint32_t reg; + + n = di_prop_lookup_ints(DDI_DEV_T_ANY, pnode, "reg", + (int **)®buf); + reg = regbuf[0]; + bdf = (PCI_REG_BUS_G(reg) << 8) | + (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg); + session_id |= (bdf << i * 8); + + /* same as 'unit-address' property */ + bus_number = + (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg); + + usbi_dbg("device bus address=%s:%x", + di_bus_addr(pnode), bus_number); + + break; + } + + /* usb_addr */ + n = di_prop_lookup_ints(DDI_DEV_T_ANY, pnode, + "assigned-address", &addr_prop); + if ((n != 1) || (addr_prop[0] == 0)) { + usbi_dbg("cannot get valid usb_addr"); + + return (DI_WALK_CONTINUE); + } + + session_id |= ((addr_prop[0] & 0xff) << i * 8); + if (++i > 7) + break; + + pnode = di_parent_node(pnode); + } + + path = di_devlink_path(link); + dev = usbi_get_device_by_session_id(nargs->ctx, session_id); + if (dev == NULL) { + dev = usbi_alloc_device(nargs->ctx, session_id); + if (dev == NULL) { + usbi_dbg("can't alloc device"); + + return (DI_WALK_TERMINATE); + } + devpriv = (sunos_dev_priv_t *)dev->os_priv; + if ((newpath = strrchr(path, '/')) == NULL) { + libusb_unref_device(dev); + + return (DI_WALK_TERMINATE); + } + devpriv->ugenpath = strndup(path, strlen(path) - + strlen(newpath)); + dev->bus_number = bus_number; + + if (sunos_fill_in_dev_info(myself, dev) != LIBUSB_SUCCESS) { + libusb_unref_device(dev); + + return (DI_WALK_TERMINATE); + } + if (usbi_sanitize_device(dev) < 0) { + libusb_unref_device(dev); + usbi_dbg("sanatize failed: "); + return (DI_WALK_TERMINATE); + } + } else { + usbi_dbg("Dev %s exists", path); + } + + devpriv = (sunos_dev_priv_t *)dev->os_priv; + if (nargs->last_ugenpath == NULL) { + /* first device */ + nargs->last_ugenpath = devpriv->ugenpath; + + if (discovered_devs_append(*(nargs->discdevs), dev) == NULL) { + usbi_dbg("cannot append device"); + } + + /* + * we alloc and hence ref this dev. We don't need to ref it + * hereafter. Front end or app should take care of their ref. + */ + libusb_unref_device(dev); + } + + usbi_dbg("Device %s %s id=0x%llx, devcount:%d, bdf=%x", + devpriv->ugenpath, path, (uint64_t)session_id, + (*nargs->discdevs)->len, bdf); + + return (DI_WALK_CONTINUE); +} + +static int +sunos_walk_minor_node_link(di_node_t node, void *args) +{ + di_minor_t minor = DI_MINOR_NIL; + char *minor_path; + struct devlink_cbarg arg; + struct node_args *nargs = (struct node_args *)args; + di_devlink_handle_t devlink_hdl = nargs->dlink_hdl; + + /* walk each minor to find ugen devices */ + while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) { + minor_path = di_devfs_minor_path(minor); + arg.nargs = args; + arg.myself = node; + arg.minor = minor; + (void) di_devlink_walk(devlink_hdl, + "^usb/[0-9a-f]+[.][0-9a-f]+", minor_path, + DI_PRIMARY_LINK, (void *)&arg, sunos_add_devices); + di_devfs_path_free(minor_path); + } + + /* switch to a different node */ + nargs->last_ugenpath = NULL; + + return (DI_WALK_CONTINUE); +} + +int +sunos_get_device_list(struct libusb_context * ctx, + struct discovered_devs **discdevs) +{ + di_node_t root_node; + struct node_args args; + di_devlink_handle_t devlink_hdl; + + args.ctx = ctx; + args.discdevs = discdevs; + args.last_ugenpath = NULL; + if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) { + usbi_dbg("di_int() failed: %s", strerror(errno)); + return (LIBUSB_ERROR_IO); + } + + if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) { + di_fini(root_node); + usbi_dbg("di_devlink_init() failed: %s", strerror(errno)); + + return (LIBUSB_ERROR_IO); + } + args.dlink_hdl = devlink_hdl; + + /* walk each node to find USB devices */ + if (di_walk_node(root_node, DI_WALK_SIBFIRST, &args, + sunos_walk_minor_node_link) == -1) { + usbi_dbg("di_walk_node() failed: %s", strerror(errno)); + di_fini(root_node); + + return (LIBUSB_ERROR_IO); + } + + di_fini(root_node); + di_devlink_fini(&devlink_hdl); + + usbi_dbg("%d devices", (*discdevs)->len); + + return ((*discdevs)->len); +} + +static int +sunos_usb_open_ep0(sunos_dev_handle_priv_t *hpriv, sunos_dev_priv_t *dpriv) +{ + char filename[PATH_MAX + 1]; + + if (hpriv->eps[0].datafd > 0) { + + return (LIBUSB_SUCCESS); + } + snprintf(filename, PATH_MAX, "%s/cntrl0", dpriv->ugenpath); + + usbi_dbg("opening %s", filename); + hpriv->eps[0].datafd = open(filename, O_RDWR); + if (hpriv->eps[0].datafd < 0) { + return(_errno_to_libusb(errno)); + } + + snprintf(filename, PATH_MAX, "%s/cntrl0stat", dpriv->ugenpath); + hpriv->eps[0].statfd = open(filename, O_RDONLY); + if (hpriv->eps[0].statfd < 0) { + close(hpriv->eps[0].datafd); + hpriv->eps[0].datafd = -1; + + return(_errno_to_libusb(errno)); + } + + return (LIBUSB_SUCCESS); +} + +static void +sunos_usb_close_all_eps(sunos_dev_handle_priv_t *hdev) +{ + int i; + + /* not close ep0 */ + for (i = 1; i < USB_MAXENDPOINTS; i++) { + if (hdev->eps[i].datafd != -1) { + (void) close(hdev->eps[i].datafd); + hdev->eps[i].datafd = -1; + } + if (hdev->eps[i].statfd != -1) { + (void) close(hdev->eps[i].statfd); + hdev->eps[i].statfd = -1; + } + } +} + +static void +sunos_usb_close_ep0(sunos_dev_handle_priv_t *hdev, sunos_dev_priv_t *dpriv) +{ + if (hdev->eps[0].datafd >= 0) { + close(hdev->eps[0].datafd); + close(hdev->eps[0].statfd); + hdev->eps[0].datafd = -1; + hdev->eps[0].statfd = -1; + } +} + +static uchar_t +sunos_usb_ep_index(uint8_t ep_addr) +{ + return ((ep_addr & LIBUSB_ENDPOINT_ADDRESS_MASK) + + ((ep_addr & LIBUSB_ENDPOINT_DIR_MASK) ? 16 : 0)); +} + +static int +sunos_find_interface(struct libusb_device_handle *hdev, + uint8_t endpoint, uint8_t *interface) +{ + struct libusb_config_descriptor *config; + int r; + int iface_idx; + + r = libusb_get_active_config_descriptor(hdev->dev, &config); + if (r < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + + for (iface_idx = 0; iface_idx < config->bNumInterfaces; iface_idx++) { + const struct libusb_interface *iface = + &config->interface[iface_idx]; + int altsetting_idx; + + for (altsetting_idx = 0; altsetting_idx < iface->num_altsetting; + altsetting_idx++) { + const struct libusb_interface_descriptor *altsetting = + &iface->altsetting[altsetting_idx]; + int ep_idx; + + for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; + ep_idx++) { + const struct libusb_endpoint_descriptor *ep = + &altsetting->endpoint[ep_idx]; + if (ep->bEndpointAddress == endpoint) { + *interface = iface_idx; + libusb_free_config_descriptor(config); + + return (LIBUSB_SUCCESS); + } + } + } + } + libusb_free_config_descriptor(config); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +static int +sunos_check_device_and_status_open(struct libusb_device_handle *hdl, + uint8_t ep_addr, int ep_type) +{ + char filename[PATH_MAX + 1], statfilename[PATH_MAX + 1]; + char cfg_num[16], alt_num[16]; + int fd, fdstat, mode; + uint8_t ifc = 0; + uint8_t ep_index; + sunos_dev_handle_priv_t *hpriv; + + usbi_dbg("open ep 0x%02x", ep_addr); + hpriv = (sunos_dev_handle_priv_t *)hdl->os_priv; + ep_index = sunos_usb_ep_index(ep_addr); + /* ep already opened */ + if ((hpriv->eps[ep_index].datafd > 0) && + (hpriv->eps[ep_index].statfd > 0)) { + usbi_dbg("ep 0x%02x already opened, return success", + ep_addr); + + return (0); + } + + if (sunos_find_interface(hdl, ep_addr, &ifc) < 0) { + usbi_dbg("can't find interface for endpoint 0x%02x", + ep_addr); + + return (LIBUSB_ERROR_ACCESS); + } + + /* create filename */ + if (hpriv->config_index > 0) { + (void) snprintf(cfg_num, sizeof (cfg_num), "cfg%d", + hpriv->config_index + 1); + } else { + bzero(cfg_num, sizeof (cfg_num)); + } + + if (hpriv->altsetting[ifc] > 0) { + (void) snprintf(alt_num, sizeof (alt_num), ".%d", + hpriv->altsetting[ifc]); + } else { + bzero(alt_num, sizeof (alt_num)); + } + + (void) snprintf(filename, PATH_MAX, "%s/%sif%d%s%s%d", + hpriv->dpriv->ugenpath, cfg_num, ifc, alt_num, + (ep_addr & LIBUSB_ENDPOINT_DIR_MASK) ? "in" : + "out", (ep_addr & LIBUSB_ENDPOINT_ADDRESS_MASK)); + (void) snprintf(statfilename, PATH_MAX, "%sstat", filename); + + /* + * for interrupt IN endpoints, we need to enable one xfer + * mode before opening the endpoint + */ + if ((ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) && + (ep_addr & LIBUSB_ENDPOINT_IN)) { + char control = USB_EP_INTR_ONE_XFER; + int count; + + /* open the status device node for the ep first RDWR */ + if ((fdstat = open(statfilename, O_RDWR)) == -1) { + usbi_dbg("can't open %s RDWR: %d", + statfilename, errno); + } else { + count = write(fdstat, &control, sizeof (control)); + if (count != 1) { + /* this should have worked */ + usbi_dbg("can't write to %s: %d", + statfilename, errno); + (void) close(fdstat); + + return (errno); + } + /* close status node and open xfer node first */ + close (fdstat); + } + } + + /* open the xfer node first in case alt needs to be changed */ + if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { + mode = O_RDWR; + } else if (ep_addr & LIBUSB_ENDPOINT_IN) { + mode = O_RDONLY; + } else { + mode = O_WRONLY; + } + + /* + * IMPORTANT: must open data xfer node first and then open stat node + * Otherwise, it will fail on multi-config or multi-altsetting devices + * with "Device Busy" error. See ugen_epxs_switch_cfg_alt() and + * ugen_epxs_check_alt_switch() in ugen driver source code. + */ + if ((fd = open(filename, mode)) == -1) { + usbi_dbg("can't open %s: %d(%s)", filename, errno, + strerror(errno)); + + return (errno); + } + /* open the status node */ + if ((fdstat = open(statfilename, O_RDONLY)) == -1) { + usbi_dbg("can't open %s: %d", statfilename, errno); + + (void) close(fd); + + return (errno); + } + + hpriv->eps[ep_index].datafd = fd; + hpriv->eps[ep_index].statfd = fdstat; + usbi_dbg("ep=0x%02x datafd=%d, statfd=%d", ep_addr, fd, fdstat); + + return (0); +} + +int +sunos_open(struct libusb_device_handle *handle) +{ + sunos_dev_handle_priv_t *hpriv; + sunos_dev_priv_t *dpriv; + int i; + int ret; + + hpriv = (sunos_dev_handle_priv_t *)handle->os_priv; + dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + hpriv->dpriv = dpriv; + + /* set all file descriptors to "closed" */ + for (i = 0; i < USB_MAXENDPOINTS; i++) { + hpriv->eps[i].datafd = -1; + hpriv->eps[i].statfd = -1; + } + + if ((ret = sunos_usb_open_ep0(hpriv, dpriv)) != LIBUSB_SUCCESS) { + usbi_dbg("fail: %d", ret); + return (ret); + } + + return (LIBUSB_SUCCESS); +} + +void +sunos_close(struct libusb_device_handle *handle) +{ + sunos_dev_handle_priv_t *hpriv; + sunos_dev_priv_t *dpriv; + + usbi_dbg(""); + if (!handle) { + return; + } + + hpriv = (sunos_dev_handle_priv_t *)handle->os_priv; + if (!hpriv) { + return; + } + dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + if (!dpriv) { + return; + } + + sunos_usb_close_all_eps(hpriv); + sunos_usb_close_ep0(hpriv, dpriv); +} + +int +sunos_get_device_descriptor(struct libusb_device *dev, uint8_t *buf, + int *host_endian) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + + memcpy(buf, &dpriv->dev_descr, LIBUSB_DT_DEVICE_SIZE); + *host_endian = 0; + + return (LIBUSB_SUCCESS); +} + +int +sunos_get_active_config_descriptor(struct libusb_device *dev, + uint8_t *buf, size_t len, int *host_endian) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + struct libusb_config_descriptor *cfg; + int proplen; + di_node_t node; + uint8_t *rdata; + + /* + * Keep raw configuration descriptors updated, in case config + * has ever been changed through setCfg. + */ + if ((node = di_init(dpriv->phypath, DINFOCPYALL)) == DI_NODE_NIL) { + usbi_dbg("di_int() failed: %s", strerror(errno)); + return (LIBUSB_ERROR_IO); + } + proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, + "usb-raw-cfg-descriptors", &rdata); + if (proplen <= 0) { + usbi_dbg("can't find raw config descriptors"); + + return (LIBUSB_ERROR_IO); + } + dpriv->raw_cfgdescr = realloc(dpriv->raw_cfgdescr, proplen); + if (dpriv->raw_cfgdescr == NULL) { + return (LIBUSB_ERROR_NO_MEM); + } else { + bcopy(rdata, dpriv->raw_cfgdescr, proplen); + dpriv->cfgvalue = ((struct libusb_config_descriptor *) + rdata)->bConfigurationValue; + } + di_fini(node); + + cfg = (struct libusb_config_descriptor *)dpriv->raw_cfgdescr; + len = MIN(len, libusb_le16_to_cpu(cfg->wTotalLength)); + memcpy(buf, dpriv->raw_cfgdescr, len); + *host_endian = 0; + usbi_dbg("path:%s len %d", dpriv->phypath, len); + + return (len); +} + +int +sunos_get_config_descriptor(struct libusb_device *dev, uint8_t idx, + uint8_t *buf, size_t len, int *host_endian) +{ + /* XXX */ + return(sunos_get_active_config_descriptor(dev, buf, len, host_endian)); +} + +int +sunos_get_configuration(struct libusb_device_handle *handle, int *config) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + + *config = dpriv->cfgvalue; + + usbi_dbg("bConfigurationValue %d", *config); + + return (LIBUSB_SUCCESS); +} + +int +sunos_set_configuration(struct libusb_device_handle *handle, int config) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + sunos_dev_handle_priv_t *hpriv; + + usbi_dbg("bConfigurationValue %d", config); + hpriv = (sunos_dev_handle_priv_t *)handle->os_priv; + + if (dpriv->ugenpath == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + if (config < 1 || config > dpriv->dev_descr.bNumConfigurations) + return (LIBUSB_ERROR_INVALID_PARAM); + + dpriv->cfgvalue = config; + hpriv->config_index = config - 1; + + return (LIBUSB_SUCCESS); +} + +int +sunos_claim_interface(struct libusb_device_handle *handle, int iface) +{ + usbi_dbg("iface %d", iface); + if (iface < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + + return (LIBUSB_SUCCESS); +} + +int +sunos_release_interface(struct libusb_device_handle *handle, int iface) +{ + sunos_dev_handle_priv_t *hpriv = + (sunos_dev_handle_priv_t *)handle->os_priv; + + usbi_dbg("iface %d", iface); + if (iface < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + + /* XXX: can we release it? */ + hpriv->altsetting[iface] = 0; + + return (LIBUSB_SUCCESS); +} + +int +sunos_set_interface_altsetting(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + sunos_dev_handle_priv_t *hpriv = + (sunos_dev_handle_priv_t *)handle->os_priv; + + usbi_dbg("iface %d, setting %d", iface, altsetting); + + if (iface < 0 || altsetting < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + if (dpriv->ugenpath == NULL) + return (LIBUSB_ERROR_NOT_FOUND); + + /* XXX: can we switch altsetting? */ + hpriv->altsetting[iface] = altsetting; + + return (LIBUSB_SUCCESS); +} + +static void +usb_dump_data(unsigned char *data, size_t size) +{ + int i; + + if (getenv("LIBUSB_DEBUG") == NULL) { + return; + } + + (void) fprintf(stderr, "data dump:"); + for (i = 0; i < size; i++) { + if (i % 16 == 0) { + (void) fprintf(stderr, "\n%08x ", i); + } + (void) fprintf(stderr, "%02x ", (uchar_t)data[i]); + } + (void) fprintf(stderr, "\n"); +} + +static void +sunos_async_callback(union sigval arg) +{ + struct sunos_transfer_priv *tpriv = + (struct sunos_transfer_priv *)arg.sival_ptr; + struct libusb_transfer *xfer = tpriv->transfer; + struct aiocb *aiocb = &tpriv->aiocb; + int ret; + sunos_dev_handle_priv_t *hpriv; + uint8_t ep; + + hpriv = (sunos_dev_handle_priv_t *)xfer->dev_handle->os_priv; + ep = sunos_usb_ep_index(xfer->endpoint); + + ret = aio_error(aiocb); + if (ret != 0) { + xfer->status = sunos_usb_get_status(hpriv->eps[ep].statfd); + } else { + xfer->actual_length = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)->transferred = + aio_return(aiocb); + } + + usb_dump_data(xfer->buffer, xfer->actual_length); + + usbi_dbg("ret=%d, len=%d, actual_len=%d", ret, xfer->length, + xfer->actual_length); + + /* async notification */ + usbi_signal_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)); +} + +static int +sunos_do_async_io(struct libusb_transfer *transfer) +{ + int ret = -1; + struct aiocb *aiocb; + sunos_dev_handle_priv_t *hpriv; + uint8_t ep; + struct sunos_transfer_priv *tpriv; + + usbi_dbg(""); + + tpriv = usbi_transfer_get_os_priv(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)); + hpriv = (sunos_dev_handle_priv_t *)transfer->dev_handle->os_priv; + ep = sunos_usb_ep_index(transfer->endpoint); + + tpriv->transfer = transfer; + aiocb = &tpriv->aiocb; + bzero(aiocb, sizeof (*aiocb)); + aiocb->aio_fildes = hpriv->eps[ep].datafd; + aiocb->aio_buf = transfer->buffer; + aiocb->aio_nbytes = transfer->length; + aiocb->aio_lio_opcode = + ((transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK) == + LIBUSB_ENDPOINT_IN) ? LIO_READ:LIO_WRITE; + aiocb->aio_sigevent.sigev_notify = SIGEV_THREAD; + aiocb->aio_sigevent.sigev_value.sival_ptr = tpriv; + aiocb->aio_sigevent.sigev_notify_function = sunos_async_callback; + + if (aiocb->aio_lio_opcode == LIO_READ) { + ret = aio_read(aiocb); + } else { + ret = aio_write(aiocb); + } + + return (ret); +} + +/* return the number of bytes read/written */ +static int +usb_do_io(int fd, int stat_fd, char *data, size_t size, int flag, int *status) +{ + int error; + int ret = -1; + + usbi_dbg("usb_do_io(): datafd=%d statfd=%d size=0x%x flag=%s", + fd, stat_fd, size, flag? "WRITE":"READ"); + + switch (flag) { + case READ: + errno = 0; + ret = read(fd, data, size); + usb_dump_data(data, size); + break; + case WRITE: + usb_dump_data(data, size); + errno = 0; + ret = write(fd, data, size); + break; + } + + usbi_dbg("usb_do_io(): amount=%d", ret); + + if (ret < 0) { + int save_errno = errno; + + usbi_dbg("TID=%x io %s errno=%d(%s) ret=%d", pthread_self(), + flag?"WRITE":"READ", errno, strerror(errno), ret); + + /* sunos_usb_get_status will do a read and overwrite errno */ + error = sunos_usb_get_status(stat_fd); + usbi_dbg("io status=%d errno=%d(%s)", error, + save_errno, strerror(save_errno)); + + if (status) { + *status = save_errno; + } + + return (save_errno); + + } else if (status) { + *status = 0; + } + + return (ret); +} + +static int +solaris_submit_ctrl_on_default(struct libusb_transfer *transfer) +{ + int ret = -1, setup_ret; + int status; + sunos_dev_handle_priv_t *hpriv; + struct libusb_device_handle *hdl = transfer->dev_handle; + uint16_t wLength; + uint8_t *data = transfer->buffer; + + hpriv = (sunos_dev_handle_priv_t *)hdl->os_priv; + wLength = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; + + if (hpriv->eps[0].datafd == -1) { + usbi_dbg("ep0 not opened"); + + return (LIBUSB_ERROR_NOT_FOUND); + } + + if ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) { + usbi_dbg("IN request"); + ret = usb_do_io(hpriv->eps[0].datafd, + hpriv->eps[0].statfd, (char *)data, LIBUSB_CONTROL_SETUP_SIZE, + WRITE, (int *)&status); + } else { + usbi_dbg("OUT request"); + ret = usb_do_io(hpriv->eps[0].datafd, hpriv->eps[0].statfd, + transfer->buffer, transfer->length, WRITE, + (int *)&transfer->status); + } + + setup_ret = ret; + if (ret < LIBUSB_CONTROL_SETUP_SIZE) { + usbi_dbg("error sending control msg: %d", ret); + + return (LIBUSB_ERROR_IO); + } + + ret = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; + + /* Read the remaining bytes for IN request */ + if ((wLength) && ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) == + LIBUSB_ENDPOINT_IN)) { + usbi_dbg("DATA: %d", transfer->length - setup_ret); + ret = usb_do_io(hpriv->eps[0].datafd, + hpriv->eps[0].statfd, + (char *)transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, + wLength, READ, (int *)&transfer->status); + } + + if (ret >= 0) { + transfer->actual_length = ret; + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)->transferred = ret; + } + usbi_dbg("Done: ctrl data bytes %d", ret); + + /* sync transfer handling */ + ret = usbi_handle_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer), + transfer->status); + + return (ret); +} + +int +sunos_clear_halt(struct libusb_device_handle *handle, uint8_t endpoint) +{ + int ret; + + usbi_dbg("endpoint=0x%02x", endpoint); + + ret = libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT | + LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_REQUEST_TYPE_STANDARD, + LIBUSB_REQUEST_CLEAR_FEATURE, 0, endpoint, NULL, 0, 1000); + + usbi_dbg("ret=%d", ret); + + return (ret); +} + +int +sunos_reset_device(struct libusb_device_handle *handle) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +sunos_destroy_device(struct libusb_device *dev) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + + usbi_dbg(""); + + free(dpriv->raw_cfgdescr); + free(dpriv->ugenpath); + free(dpriv->phypath); +} + +int +sunos_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct libusb_device_handle *hdl; + int err = 0; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hdl = transfer->dev_handle; + + err = sunos_check_device_and_status_open(hdl, + transfer->endpoint, transfer->type); + if (err < 0) { + + return (_errno_to_libusb(err)); + } + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + /* sync transfer */ + usbi_dbg("CTRL transfer: %d", transfer->length); + err = solaris_submit_ctrl_on_default(transfer); + break; + + case LIBUSB_TRANSFER_TYPE_BULK: + /* fallthru */ + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (transfer->type == LIBUSB_TRANSFER_TYPE_BULK) + usbi_dbg("BULK transfer: %d", transfer->length); + else + usbi_dbg("INTR transfer: %d", transfer->length); + err = sunos_do_async_io(transfer); + break; + + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + /* Isochronous/Stream is not supported */ + + /* fallthru */ + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) + usbi_dbg("ISOC transfer: %d", transfer->length); + else + usbi_dbg("BULK STREAM transfer: %d", transfer->length); + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + + return (err); +} + +int +sunos_cancel_transfer(struct usbi_transfer *itransfer) +{ + sunos_xfer_priv_t *tpriv; + sunos_dev_handle_priv_t *hpriv; + struct libusb_transfer *transfer; + struct aiocb *aiocb; + uint8_t ep; + int ret; + + tpriv = usbi_transfer_get_os_priv(itransfer); + aiocb = &tpriv->aiocb; + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hpriv = (sunos_dev_handle_priv_t *)transfer->dev_handle->os_priv; + ep = sunos_usb_ep_index(transfer->endpoint); + + ret = aio_cancel(hpriv->eps[ep].datafd, aiocb); + + usbi_dbg("aio->fd=%d fd=%d ret = %d, %s", aiocb->aio_fildes, + hpriv->eps[ep].datafd, ret, (ret == AIO_CANCELED)? + strerror(0):strerror(errno)); + + if (ret != AIO_CANCELED) { + ret = _errno_to_libusb(errno); + } else { + /* + * we don't need to call usbi_handle_transfer_cancellation(), + * because we'll handle everything in sunos_async_callback. + */ + ret = LIBUSB_SUCCESS; + } + + return (ret); +} + +void +sunos_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + /* Nothing to do */ +} + +int +sunos_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED); +} + +int +sunos_clock_gettime(int clkid, struct timespec *tp) +{ + usbi_dbg("clock %d", clkid); + + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +int +_errno_to_libusb(int err) +{ + usbi_dbg("error: %s (%d)", strerror(err), err); + + switch (err) { + case EIO: + return (LIBUSB_ERROR_IO); + case EACCES: + return (LIBUSB_ERROR_ACCESS); + case ENOENT: + return (LIBUSB_ERROR_NO_DEVICE); + case ENOMEM: + return (LIBUSB_ERROR_NO_MEM); + case ETIMEDOUT: + return (LIBUSB_ERROR_TIMEOUT); + } + + return (LIBUSB_ERROR_OTHER); +} + +/* + * sunos_usb_get_status: + * gets status of endpoint + * + * Returns: ugen's last cmd status + */ +static int +sunos_usb_get_status(int fd) +{ + int status, ret; + + usbi_dbg("sunos_usb_get_status(): fd=%d", fd); + + ret = read(fd, &status, sizeof (status)); + if (ret == sizeof (status)) { + switch (status) { + case USB_LC_STAT_NOERROR: + usbi_dbg("No Error"); + break; + case USB_LC_STAT_CRC: + usbi_dbg("CRC Timeout Detected\n"); + break; + case USB_LC_STAT_BITSTUFFING: + usbi_dbg("Bit Stuffing Violation\n"); + break; + case USB_LC_STAT_DATA_TOGGLE_MM: + usbi_dbg("Data Toggle Mismatch\n"); + break; + case USB_LC_STAT_STALL: + usbi_dbg("End Point Stalled\n"); + break; + case USB_LC_STAT_DEV_NOT_RESP: + usbi_dbg("Device is Not Responding\n"); + break; + case USB_LC_STAT_PID_CHECKFAILURE: + usbi_dbg("PID Check Failure\n"); + break; + case USB_LC_STAT_UNEXP_PID: + usbi_dbg("Unexpected PID\n"); + break; + case USB_LC_STAT_DATA_OVERRUN: + usbi_dbg("Data Exceeded Size\n"); + break; + case USB_LC_STAT_DATA_UNDERRUN: + usbi_dbg("Less data received\n"); + break; + case USB_LC_STAT_BUFFER_OVERRUN: + usbi_dbg("Buffer Size Exceeded\n"); + break; + case USB_LC_STAT_BUFFER_UNDERRUN: + usbi_dbg("Buffer Underrun\n"); + break; + case USB_LC_STAT_TIMEOUT: + usbi_dbg("Command Timed Out\n"); + break; + case USB_LC_STAT_NOT_ACCESSED: + usbi_dbg("Not Accessed by h/w\n"); + break; + case USB_LC_STAT_UNSPECIFIED_ERR: + usbi_dbg("Unspecified Error\n"); + break; + case USB_LC_STAT_NO_BANDWIDTH: + usbi_dbg("No Bandwidth\n"); + break; + case USB_LC_STAT_HW_ERR: + usbi_dbg("Host Controller h/w Error\n"); + break; + case USB_LC_STAT_SUSPENDED: + usbi_dbg("Device was Suspended\n"); + break; + case USB_LC_STAT_DISCONNECTED: + usbi_dbg("Device was Disconnected\n"); + break; + case USB_LC_STAT_INTR_BUF_FULL: + usbi_dbg("Interrupt buffer was full\n"); + break; + case USB_LC_STAT_INVALID_REQ: + usbi_dbg("Request was Invalid\n"); + break; + case USB_LC_STAT_INTERRUPTED: + usbi_dbg("Request was Interrupted\n"); + break; + case USB_LC_STAT_NO_RESOURCES: + usbi_dbg("No resources available for " + "request\n"); + break; + case USB_LC_STAT_INTR_POLLING_FAILED: + usbi_dbg("Failed to Restart Poll"); + break; + default: + usbi_dbg("Error Not Determined %d\n", + status); + break; + } + } else { + usbi_dbg("read stat error: %s",strerror(errno)); + status = -1; + } + + return (status); +} + +const struct usbi_os_backend sunos_backend = { + .name = "Solaris", + .caps = 0, + .init = sunos_init, + .exit = sunos_exit, + .get_device_list = sunos_get_device_list, + .get_device_descriptor = sunos_get_device_descriptor, + .get_active_config_descriptor = sunos_get_active_config_descriptor, + .get_config_descriptor = sunos_get_config_descriptor, + .hotplug_poll = NULL, + .open = sunos_open, + .close = sunos_close, + .get_configuration = sunos_get_configuration, + .set_configuration = sunos_set_configuration, + + .claim_interface = sunos_claim_interface, + .release_interface = sunos_release_interface, + .set_interface_altsetting = sunos_set_interface_altsetting, + .clear_halt = sunos_clear_halt, + .reset_device = sunos_reset_device, /* TODO */ + .alloc_streams = NULL, + .free_streams = NULL, + .kernel_driver_active = NULL, + .detach_kernel_driver = NULL, + .attach_kernel_driver = NULL, + .destroy_device = sunos_destroy_device, + .submit_transfer = sunos_submit_transfer, + .cancel_transfer = sunos_cancel_transfer, + .handle_events = NULL, + .clear_transfer_priv = sunos_clear_transfer_priv, + .handle_transfer_completion = sunos_handle_transfer_completion, + .clock_gettime = sunos_clock_gettime, + .device_priv_size = sizeof(sunos_dev_priv_t), + .device_handle_priv_size = sizeof(sunos_dev_handle_priv_t), + .transfer_priv_size = sizeof(sunos_xfer_priv_t), +}; diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.h new file mode 100644 index 00000000..57416603 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.h @@ -0,0 +1,74 @@ +/* + * + * Copyright (c) 2016, Oracle and/or its affiliates. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_SUNOS_H +#define LIBUSB_SUNOS_H + +#include +#include +#include "libusbi.h" + +#define READ 0 +#define WRITE 1 + +typedef struct sunos_device_priv { + uint8_t cfgvalue; /* active config value */ + uint8_t *raw_cfgdescr; /* active config descriptor */ + struct libusb_device_descriptor dev_descr; /* usb device descriptor */ + char *ugenpath; /* name of the ugen(4) node */ + char *phypath; /* physical path */ +} sunos_dev_priv_t; + +typedef struct endpoint { + int datafd; /* data file */ + int statfd; /* state file */ +} sunos_ep_priv_t; + +typedef struct sunos_device_handle_priv { + uint8_t altsetting[USB_MAXINTERFACES]; /* a interface's alt */ + uint8_t config_index; + sunos_ep_priv_t eps[USB_MAXENDPOINTS]; + sunos_dev_priv_t *dpriv; /* device private */ +} sunos_dev_handle_priv_t; + +typedef struct sunos_transfer_priv { + struct aiocb aiocb; + struct libusb_transfer *transfer; +} sunos_xfer_priv_t; + +struct node_args { + struct libusb_context *ctx; + struct discovered_devs **discdevs; + const char *last_ugenpath; + di_devlink_handle_t dlink_hdl; +}; + +struct devlink_cbarg { + struct node_args *nargs; /* di node walk arguments */ + di_node_t myself; /* the di node */ + di_minor_t minor; +}; + +/* AIO callback args */ +struct aio_callback_args{ + struct libusb_transfer *transfer; + struct aiocb aiocb; +}; + +#endif /* LIBUSB_SUNOS_H */ diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.c new file mode 100644 index 00000000..a4f270bb --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.c @@ -0,0 +1,79 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright © 2011 Vitali Lovich + * Copyright © 2011 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#if defined(__linux__) || defined(__OpenBSD__) +# if defined(__OpenBSD__) +# define _BSD_SOURCE +# endif +# include +# include +#elif defined(__APPLE__) +# include +#elif defined(__CYGWIN__) +# include +#endif + +#include "threads_posix.h" +#include "libusbi.h" + +int usbi_cond_timedwait(pthread_cond_t *cond, + pthread_mutex_t *mutex, const struct timeval *tv) +{ + struct timespec timeout; + int r; + + r = usbi_backend->clock_gettime(USBI_CLOCK_REALTIME, &timeout); + if (r < 0) + return r; + + timeout.tv_sec += tv->tv_sec; + timeout.tv_nsec += tv->tv_usec * 1000; + while (timeout.tv_nsec >= 1000000000L) { + timeout.tv_nsec -= 1000000000L; + timeout.tv_sec++; + } + + return pthread_cond_timedwait(cond, mutex, &timeout); +} + +int usbi_get_tid(void) +{ + int ret = -1; +#if defined(__ANDROID__) + ret = gettid(); +#elif defined(__linux__) + ret = syscall(SYS_gettid); +#elif defined(__OpenBSD__) + /* The following only works with OpenBSD > 5.1 as it requires + real thread support. For 5.1 and earlier, -1 is returned. */ + ret = syscall(SYS_getthrid); +#elif defined(__APPLE__) + ret = mach_thread_self(); + mach_port_deallocate(mach_task_self(), ret); +#elif defined(__CYGWIN__) + ret = GetCurrentThreadId(); +#endif +/* TODO: NetBSD thread ID support */ + return ret; +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.h new file mode 100644 index 00000000..4c1514ea --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.h @@ -0,0 +1,55 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright © 2010 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_THREADS_POSIX_H +#define LIBUSB_THREADS_POSIX_H + +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#define usbi_mutex_static_t pthread_mutex_t +#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define usbi_mutex_static_lock pthread_mutex_lock +#define usbi_mutex_static_unlock pthread_mutex_unlock + +#define usbi_mutex_t pthread_mutex_t +#define usbi_mutex_init(mutex) pthread_mutex_init((mutex), NULL) +#define usbi_mutex_lock pthread_mutex_lock +#define usbi_mutex_unlock pthread_mutex_unlock +#define usbi_mutex_trylock pthread_mutex_trylock +#define usbi_mutex_destroy pthread_mutex_destroy + +#define usbi_cond_t pthread_cond_t +#define usbi_cond_init(cond) pthread_cond_init((cond), NULL) +#define usbi_cond_wait pthread_cond_wait +#define usbi_cond_broadcast pthread_cond_broadcast +#define usbi_cond_destroy pthread_cond_destroy + +#define usbi_tls_key_t pthread_key_t +#define usbi_tls_key_create(key) pthread_key_create((key), NULL) +#define usbi_tls_key_get pthread_getspecific +#define usbi_tls_key_set pthread_setspecific +#define usbi_tls_key_delete pthread_key_delete + +int usbi_get_tid(void); + +#endif /* LIBUSB_THREADS_POSIX_H */ diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.c new file mode 100644 index 00000000..9e896c64 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.c @@ -0,0 +1,268 @@ +/* + * libusb synchronization on Microsoft Windows + * + * Copyright © 2010 Michael Plante + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#ifdef OS_WINDOWS + #include + + #include + #if defined(interface) + #undef interface + #endif +#endif + +#include "libusbi.h" + +struct usbi_cond_perthread { + struct list_head list; + DWORD tid; + HANDLE event; +}; + +int usbi_mutex_static_lock(usbi_mutex_static_t *mutex) +{ + if (!mutex) + return EINVAL; + while (InterlockedExchange(mutex, 1) == 1) + SleepEx(0, TRUE); + return 0; +} + +int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex) +{ + if (!mutex) + return EINVAL; + InterlockedExchange(mutex, 0); + return 0; +} + +int usbi_mutex_init(usbi_mutex_t *mutex) +{ + if (!mutex) + return EINVAL; + *mutex = CreateMutex(NULL, FALSE, NULL); + if (!*mutex) + return ENOMEM; + return 0; +} + +int usbi_mutex_lock(usbi_mutex_t *mutex) +{ + DWORD result; + + if (!mutex) + return EINVAL; + result = WaitForSingleObject(*mutex, INFINITE); + if (result == WAIT_OBJECT_0 || result == WAIT_ABANDONED) + return 0; // acquired (ToDo: check that abandoned is ok) + else + return EINVAL; // don't know how this would happen + // so don't know proper errno +} + +int usbi_mutex_unlock(usbi_mutex_t *mutex) +{ + if (!mutex) + return EINVAL; + if (ReleaseMutex(*mutex)) + return 0; + else + return EPERM; +} + +int usbi_mutex_trylock(usbi_mutex_t *mutex) +{ + DWORD result; + + if (!mutex) + return EINVAL; + result = WaitForSingleObject(*mutex, 0); + if (result == WAIT_OBJECT_0 || result == WAIT_ABANDONED) + return 0; // acquired (ToDo: check that abandoned is ok) + else if (result == WAIT_TIMEOUT) + return EBUSY; + else + return EINVAL; // don't know how this would happen + // so don't know proper error +} + +int usbi_mutex_destroy(usbi_mutex_t *mutex) +{ + // It is not clear if CloseHandle failure is due to failure to unlock. + // If so, this should be errno=EBUSY. + if (!mutex || !CloseHandle(*mutex)) + return EINVAL; + *mutex = NULL; + return 0; +} + +int usbi_cond_init(usbi_cond_t *cond) +{ + if (!cond) + return EINVAL; + list_init(&cond->waiters); + list_init(&cond->not_waiting); + return 0; +} + +int usbi_cond_destroy(usbi_cond_t *cond) +{ + // This assumes no one is using this anymore. The check MAY NOT BE safe. + struct usbi_cond_perthread *pos, *next_pos; + + if(!cond) + return EINVAL; + if (!list_empty(&cond->waiters)) + return EBUSY; // (!see above!) + list_for_each_entry_safe(pos, next_pos, &cond->not_waiting, list, struct usbi_cond_perthread) { + CloseHandle(pos->event); + list_del(&pos->list); + free(pos); + } + return 0; +} + +int usbi_cond_broadcast(usbi_cond_t *cond) +{ + // Assumes mutex is locked; this is not in keeping with POSIX spec, but + // libusb does this anyway, so we simplify by not adding more sync + // primitives to the CV definition! + int fail = 0; + struct usbi_cond_perthread *pos; + + if (!cond) + return EINVAL; + list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) { + if (!SetEvent(pos->event)) + fail = 1; + } + // The wait function will remove its respective item from the list. + return fail ? EINVAL : 0; +} + +__inline static int usbi_cond_intwait(usbi_cond_t *cond, + usbi_mutex_t *mutex, DWORD timeout_ms) +{ + struct usbi_cond_perthread *pos; + int r, found = 0; + DWORD r2, tid = GetCurrentThreadId(); + + if (!cond || !mutex) + return EINVAL; + list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) { + if(tid == pos->tid) { + found = 1; + break; + } + } + + if (!found) { + pos = calloc(1, sizeof(struct usbi_cond_perthread)); + if (!pos) + return ENOMEM; // This errno is not POSIX-allowed. + pos->tid = tid; + pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset. + if (!pos->event) { + free(pos); + return ENOMEM; + } + list_add(&pos->list, &cond->not_waiting); + } + + list_del(&pos->list); // remove from not_waiting list. + list_add(&pos->list, &cond->waiters); + + r = usbi_mutex_unlock(mutex); + if (r) + return r; + + r2 = WaitForSingleObject(pos->event, timeout_ms); + r = usbi_mutex_lock(mutex); + if (r) + return r; + + list_del(&pos->list); + list_add(&pos->list, &cond->not_waiting); + + if (r2 == WAIT_OBJECT_0) + return 0; + else if (r2 == WAIT_TIMEOUT) + return ETIMEDOUT; + else + return EINVAL; +} +// N.B.: usbi_cond_*wait() can also return ENOMEM, even though pthread_cond_*wait cannot! +int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex) +{ + return usbi_cond_intwait(cond, mutex, INFINITE); +} + +int usbi_cond_timedwait(usbi_cond_t *cond, + usbi_mutex_t *mutex, const struct timeval *tv) +{ + DWORD millis; + + millis = (DWORD)(tv->tv_sec * 1000) + (tv->tv_usec / 1000); + /* round up to next millisecond */ + if (tv->tv_usec % 1000) + millis++; + return usbi_cond_intwait(cond, mutex, millis); +} + +int usbi_tls_key_create(usbi_tls_key_t *key) +{ + if (!key) + return EINVAL; + *key = TlsAlloc(); + if (*key == TLS_OUT_OF_INDEXES) + return ENOMEM; + else + return 0; +} + +void *usbi_tls_key_get(usbi_tls_key_t key) +{ + return TlsGetValue(key); +} + +int usbi_tls_key_set(usbi_tls_key_t key, void *value) +{ + if (TlsSetValue(key, value)) + return 0; + else + return EINVAL; +} + +int usbi_tls_key_delete(usbi_tls_key_t key) +{ + if (TlsFree(key)) + return 0; + else + return EINVAL; +} + +int usbi_get_tid(void) +{ + return (int)GetCurrentThreadId(); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.h new file mode 100644 index 00000000..e97ee787 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.h @@ -0,0 +1,76 @@ +/* + * libusb synchronization on Microsoft Windows + * + * Copyright © 2010 Michael Plante + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_THREADS_WINDOWS_H +#define LIBUSB_THREADS_WINDOWS_H + +#define usbi_mutex_static_t volatile LONG +#define USBI_MUTEX_INITIALIZER 0 + +#define usbi_mutex_t HANDLE + +typedef struct usbi_cond { + // Every time a thread touches the CV, it winds up in one of these lists. + // It stays there until the CV is destroyed, even if the thread terminates. + struct list_head waiters; + struct list_head not_waiting; +} usbi_cond_t; + +// We *were* getting timespec from pthread.h: +#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED)) +#define HAVE_STRUCT_TIMESPEC 1 +#define _TIMESPEC_DEFINED 1 +struct timespec { + long tv_sec; + long tv_nsec; +}; +#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */ + +// We *were* getting ETIMEDOUT from pthread.h: +#ifndef ETIMEDOUT +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +#define usbi_tls_key_t DWORD + +int usbi_mutex_static_lock(usbi_mutex_static_t *mutex); +int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex); + +int usbi_mutex_init(usbi_mutex_t *mutex); +int usbi_mutex_lock(usbi_mutex_t *mutex); +int usbi_mutex_unlock(usbi_mutex_t *mutex); +int usbi_mutex_trylock(usbi_mutex_t *mutex); +int usbi_mutex_destroy(usbi_mutex_t *mutex); + +int usbi_cond_init(usbi_cond_t *cond); +int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex); +int usbi_cond_timedwait(usbi_cond_t *cond, + usbi_mutex_t *mutex, const struct timeval *tv); +int usbi_cond_broadcast(usbi_cond_t *cond); +int usbi_cond_destroy(usbi_cond_t *cond); + +int usbi_tls_key_create(usbi_tls_key_t *key); +void *usbi_tls_key_get(usbi_tls_key_t key); +int usbi_tls_key_set(usbi_tls_key_t key, void *value); +int usbi_tls_key_delete(usbi_tls_key_t key); + +int usbi_get_tid(void); + +#endif /* LIBUSB_THREADS_WINDOWS_H */ diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.c new file mode 100644 index 00000000..0d466b8c --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.c @@ -0,0 +1,899 @@ +/* + * Windows CE backend for libusb 1.0 + * Copyright © 2011-2013 RealVNC Ltd. + * Large portions taken from Windows backend, which is + * Copyright © 2009-2010 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include "libusbi.h" +#include "wince_usb.h" + +// Global variables +int windows_version = WINDOWS_CE; +static uint64_t hires_frequency, hires_ticks_to_ps; +static HANDLE driver_handle = INVALID_HANDLE_VALUE; +static int concurrent_usage = -1; + +/* + * Converts a windows error to human readable string + * uses retval as errorcode, or, if 0, use GetLastError() + */ +#if defined(ENABLE_LOGGING) +static const char *windows_error_str(DWORD error_code) +{ + static TCHAR wErr_string[ERR_BUFFER_SIZE]; + static char err_string[ERR_BUFFER_SIZE]; + + DWORD size; + int len; + + if (error_code == 0) + error_code = GetLastError(); + + len = sprintf(err_string, "[%u] ", (unsigned int)error_code); + + size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + wErr_string, ERR_BUFFER_SIZE, NULL); + if (size == 0) { + DWORD format_error = GetLastError(); + if (format_error) + snprintf(err_string, ERR_BUFFER_SIZE, + "Windows error code %u (FormatMessage error code %u)", + (unsigned int)error_code, (unsigned int)format_error); + else + snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code); + } else { + // Remove CR/LF terminators, if present + size_t pos = size - 2; + if (wErr_string[pos] == 0x0D) + wErr_string[pos] = 0; + + if (!WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, &err_string[len], ERR_BUFFER_SIZE - len, NULL, NULL)) + strcpy(err_string, "Unable to convert error string"); + } + + return err_string; +} +#endif + +static struct wince_device_priv *_device_priv(struct libusb_device *dev) +{ + return (struct wince_device_priv *)dev->os_priv; +} + +// ceusbkwrapper to libusb error code mapping +static int translate_driver_error(DWORD error) +{ + switch (error) { + case ERROR_INVALID_PARAMETER: + return LIBUSB_ERROR_INVALID_PARAM; + case ERROR_CALL_NOT_IMPLEMENTED: + case ERROR_NOT_SUPPORTED: + return LIBUSB_ERROR_NOT_SUPPORTED; + case ERROR_NOT_ENOUGH_MEMORY: + return LIBUSB_ERROR_NO_MEM; + case ERROR_INVALID_HANDLE: + return LIBUSB_ERROR_NO_DEVICE; + case ERROR_BUSY: + return LIBUSB_ERROR_BUSY; + + // Error codes that are either unexpected, or have + // no suitable LIBUSB_ERROR equivalent. + case ERROR_CANCELLED: + case ERROR_INTERNAL_ERROR: + default: + return LIBUSB_ERROR_OTHER; + } +} + +static int init_dllimports(void) +{ + DLL_GET_HANDLE(ceusbkwrapper); + DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE); + + return LIBUSB_SUCCESS; +} + +static void exit_dllimports(void) +{ + DLL_FREE_HANDLE(ceusbkwrapper); +} + +static int init_device( + struct libusb_device *dev, UKW_DEVICE drv_dev, + unsigned char bus_addr, unsigned char dev_addr) +{ + struct wince_device_priv *priv = _device_priv(dev); + int r = LIBUSB_SUCCESS; + + dev->bus_number = bus_addr; + dev->device_address = dev_addr; + priv->dev = drv_dev; + + if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc))) + r = translate_driver_error(GetLastError()); + + return r; +} + +// Internal API functions +static int wince_init(struct libusb_context *ctx) +{ + int r = LIBUSB_ERROR_OTHER; + HANDLE semaphore; + LARGE_INTEGER li_frequency; + TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + + _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphore(NULL, 1, 1, sem_name); + if (semaphore == NULL) { + usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_MEM; + } + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore's release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0)); + CloseHandle(semaphore); + return LIBUSB_ERROR_NO_MEM; + } + + // NB: concurrent usage supposes that init calls are equally balanced with + // exit calls. If init is called more than exit, we will not exit properly + if ( ++concurrent_usage == 0 ) { // First init? + // Initialize pollable file descriptors + init_polling(); + + // Load DLL imports + if (init_dllimports() != LIBUSB_SUCCESS) { + usbi_err(ctx, "could not resolve DLL functions"); + r = LIBUSB_ERROR_NOT_SUPPORTED; + goto init_exit; + } + + // try to open a handle to the driver + driver_handle = UkwOpenDriver(); + if (driver_handle == INVALID_HANDLE_VALUE) { + usbi_err(ctx, "could not connect to driver"); + r = LIBUSB_ERROR_NOT_SUPPORTED; + goto init_exit; + } + + // find out if we have access to a monotonic (hires) timer + if (QueryPerformanceFrequency(&li_frequency)) { + hires_frequency = li_frequency.QuadPart; + // The hires frequency can go as high as 4 GHz, so we'll use a conversion + // to picoseconds to compute the tv_nsecs part in clock_gettime + hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency; + usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency); + } else { + usbi_dbg("no hires timer available on this platform"); + hires_frequency = 0; + hires_ticks_to_ps = UINT64_C(0); + } + } + // At this stage, either we went through full init successfully, or didn't need to + r = LIBUSB_SUCCESS; + +init_exit: // Holds semaphore here. + if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed? + exit_dllimports(); + exit_polling(); + + if (driver_handle != INVALID_HANDLE_VALUE) { + UkwCloseDriver(driver_handle); + driver_handle = INVALID_HANDLE_VALUE; + } + } + + if (r != LIBUSB_SUCCESS) + --concurrent_usage; // Not expected to call libusb_exit if we failed. + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); + return r; +} + +static void wince_exit(void) +{ + HANDLE semaphore; + TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + + _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphore(NULL, 1, 1, sem_name); + if (semaphore == NULL) + return; + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + CloseHandle(semaphore); + return; + } + + // Only works if exits and inits are balanced exactly + if (--concurrent_usage < 0) { // Last exit + exit_dllimports(); + exit_polling(); + + if (driver_handle != INVALID_HANDLE_VALUE) { + UkwCloseDriver(driver_handle); + driver_handle = INVALID_HANDLE_VALUE; + } + } + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); +} + +static int wince_get_device_list( + struct libusb_context *ctx, + struct discovered_devs **discdevs) +{ + UKW_DEVICE devices[MAX_DEVICE_COUNT]; + struct discovered_devs *new_devices = *discdevs; + DWORD count = 0, i; + struct libusb_device *dev = NULL; + unsigned char bus_addr, dev_addr; + unsigned long session_id; + BOOL success; + DWORD release_list_offset = 0; + int r = LIBUSB_SUCCESS; + + success = UkwGetDeviceList(driver_handle, devices, MAX_DEVICE_COUNT, &count); + if (!success) { + int libusbErr = translate_driver_error(GetLastError()); + usbi_err(ctx, "could not get devices: %s", windows_error_str(0)); + return libusbErr; + } + + for (i = 0; i < count; ++i) { + release_list_offset = i; + success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id); + if (!success) { + r = translate_driver_error(GetLastError()); + usbi_err(ctx, "could not get device address for %u: %s", (unsigned int)i, windows_error_str(0)); + goto err_out; + } + + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev) { + usbi_dbg("using existing device for %u/%u (session %lu)", + bus_addr, dev_addr, session_id); + // Release just this element in the device list (as we already hold a + // reference to it). + UkwReleaseDeviceList(driver_handle, &devices[i], 1); + release_list_offset++; + } else { + usbi_dbg("allocating new device for %u/%u (session %lu)", + bus_addr, dev_addr, session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) { + r = LIBUSB_ERROR_NO_MEM; + goto err_out; + } + + r = init_device(dev, devices[i], bus_addr, dev_addr); + if (r < 0) + goto err_out; + + r = usbi_sanitize_device(dev); + if (r < 0) + goto err_out; + } + + new_devices = discovered_devs_append(new_devices, dev); + if (!discdevs) { + r = LIBUSB_ERROR_NO_MEM; + goto err_out; + } + + libusb_unref_device(dev); + } + + *discdevs = new_devices; + return r; +err_out: + *discdevs = new_devices; + libusb_unref_device(dev); + // Release the remainder of the unprocessed device list. + // The devices added to new_devices already will still be passed up to libusb, + // which can dispose of them at its leisure. + UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset); + return r; +} + +static int wince_open(struct libusb_device_handle *handle) +{ + // Nothing to do to open devices as a handle to it has + // been retrieved by wince_get_device_list + return LIBUSB_SUCCESS; +} + +static void wince_close(struct libusb_device_handle *handle) +{ + // Nothing to do as wince_open does nothing. +} + +static int wince_get_device_descriptor( + struct libusb_device *device, + unsigned char *buffer, int *host_endian) +{ + struct wince_device_priv *priv = _device_priv(device); + + *host_endian = 1; + memcpy(buffer, &priv->desc, DEVICE_DESC_LENGTH); + return LIBUSB_SUCCESS; +} + +static int wince_get_active_config_descriptor( + struct libusb_device *device, + unsigned char *buffer, size_t len, int *host_endian) +{ + struct wince_device_priv *priv = _device_priv(device); + DWORD actualSize = len; + + *host_endian = 0; + if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize)) + return translate_driver_error(GetLastError()); + + return actualSize; +} + +static int wince_get_config_descriptor( + struct libusb_device *device, + uint8_t config_index, + unsigned char *buffer, size_t len, int *host_endian) +{ + struct wince_device_priv *priv = _device_priv(device); + DWORD actualSize = len; + + *host_endian = 0; + if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize)) + return translate_driver_error(GetLastError()); + + return actualSize; +} + +static int wince_get_configuration( + struct libusb_device_handle *handle, + int *config) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + UCHAR cv = 0; + + if (!UkwGetConfig(priv->dev, &cv)) + return translate_driver_error(GetLastError()); + + (*config) = cv; + return LIBUSB_SUCCESS; +} + +static int wince_set_configuration( + struct libusb_device_handle *handle, + int config) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + // Setting configuration 0 places the device in Address state. + // This should correspond to the "unconfigured state" required by + // libusb when the specified configuration is -1. + UCHAR cv = (config < 0) ? 0 : config; + if (!UkwSetConfig(priv->dev, cv)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_claim_interface( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwClaimInterface(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_release_interface( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0)) + return translate_driver_error(GetLastError()); + + if (!UkwReleaseInterface(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_set_interface_altsetting( + struct libusb_device_handle *handle, + int interface_number, int altsetting) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_clear_halt( + struct libusb_device_handle *handle, + unsigned char endpoint) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwClearHaltHost(priv->dev, endpoint)) + return translate_driver_error(GetLastError()); + + if (!UkwClearHaltDevice(priv->dev, endpoint)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_reset_device( + struct libusb_device_handle *handle) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwResetDevice(priv->dev)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_kernel_driver_active( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + BOOL result = FALSE; + + if (!UkwKernelDriverActive(priv->dev, interface_number, &result)) + return translate_driver_error(GetLastError()); + + return result ? 1 : 0; +} + +static int wince_detach_kernel_driver( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwDetachKernelDriver(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_attach_kernel_driver( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwAttachKernelDriver(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static void wince_destroy_device(struct libusb_device *dev) +{ + struct wince_device_priv *priv = _device_priv(dev); + + UkwReleaseDeviceList(driver_handle, &priv->dev, 1); +} + +static void wince_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd); + + // No need to cancel transfer as it is either complete or abandoned + wfd.itransfer = NULL; + CloseHandle(wfd.handle); + usbi_free_fd(&transfer_priv->pollable_fd); +} + +static int wince_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); + struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + + if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); + BOOL direction_in, ret; + struct winfd wfd; + DWORD flags; + HANDLE eventHandle; + PUKW_CONTROL_HEADER setup = NULL; + const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL; + + transfer_priv->pollable_fd = INVALID_WINFD; + if (control_transfer) { + setup = (PUKW_CONTROL_HEADER) transfer->buffer; + direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN; + } else { + direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN; + } + flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER; + flags |= UKW_TF_SHORT_TRANSFER_OK; + + eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); + if (eventHandle == NULL) { + usbi_err(ctx, "Failed to create event for async transfer"); + return LIBUSB_ERROR_NO_MEM; + } + + wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer); + if (wfd.fd < 0) { + CloseHandle(eventHandle); + return LIBUSB_ERROR_NO_MEM; + } + + transfer_priv->pollable_fd = wfd; + if (control_transfer) { + // Split out control setup header and data buffer + DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER); + PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)]; + + ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped); + } else { + ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer, + transfer->length, &transfer->actual_length, wfd.overlapped); + } + + if (!ret) { + int libusbErr = translate_driver_error(GetLastError()); + usbi_err(ctx, "UkwIssue%sTransfer failed: error %u", + control_transfer ? "Control" : "Bulk", (unsigned int)GetLastError()); + wince_clear_transfer_priv(itransfer); + return libusbErr; + } + usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT); + + return LIBUSB_SUCCESS; +} + +static int wince_submit_iso_transfer(struct usbi_transfer *itransfer) +{ + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static int wince_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return wince_submit_control_or_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return wince_submit_iso_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return LIBUSB_ERROR_NOT_SUPPORTED; + default: + usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static void wince_transfer_callback( + struct usbi_transfer *itransfer, + uint32_t io_result, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); + struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int status; + + usbi_dbg("handling I/O completion with errcode %u", io_result); + + if (io_result == ERROR_NOT_SUPPORTED && + transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) { + /* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper + * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the + * endpoint isn't actually stalled. + * + * One example of this is that some devices will occasionally fail to reply to an IN + * token. The WinCE USB layer carries on with the transaction until it is completed + * (or cancelled) but then completes it with USB_ERROR_STALL. + * + * This code therefore needs to confirm that there really is a stall error, by both + * checking the pipe status and requesting the endpoint status from the device. + */ + BOOL halted = FALSE; + usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall"); + if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) { + /* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS + * control request to the device. This is done synchronously, which is a bit + * naughty, but this is a special corner case. + */ + WORD wStatus = 0; + DWORD written = 0; + UKW_CONTROL_HEADER ctrlHeader; + ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD | + LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT; + ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS; + ctrlHeader.wValue = 0; + ctrlHeader.wIndex = transfer->endpoint; + ctrlHeader.wLength = sizeof(wStatus); + if (UkwIssueControlTransfer(priv->dev, + UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT, + &ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) { + if (written == sizeof(wStatus) && + (wStatus & STATUS_HALT_FLAG) == 0) { + if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) { + usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success"); + io_result = ERROR_SUCCESS; + } else { + usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error"); + io_result = ERROR_IO_DEVICE; + } + } + } + } + } + + switch(io_result) { + case ERROR_SUCCESS: + itransfer->transferred += io_size; + status = LIBUSB_TRANSFER_COMPLETED; + break; + case ERROR_CANCELLED: + usbi_dbg("detected transfer cancel"); + status = LIBUSB_TRANSFER_CANCELLED; + break; + case ERROR_NOT_SUPPORTED: + case ERROR_GEN_FAILURE: + usbi_dbg("detected endpoint stall"); + status = LIBUSB_TRANSFER_STALL; + break; + case ERROR_SEM_TIMEOUT: + usbi_dbg("detected semaphore timeout"); + status = LIBUSB_TRANSFER_TIMED_OUT; + break; + case ERROR_OPERATION_ABORTED: + usbi_dbg("detected operation aborted"); + status = LIBUSB_TRANSFER_CANCELLED; + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result)); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + wince_clear_transfer_priv(itransfer); + if (status == LIBUSB_TRANSFER_CANCELLED) + usbi_handle_transfer_cancellation(itransfer); + else + usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); +} + +static void wince_handle_callback( + struct usbi_transfer *itransfer, + uint32_t io_result, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + wince_transfer_callback (itransfer, io_result, io_size); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + } +} + +static int wince_handle_events( + struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) +{ + struct wince_transfer_priv* transfer_priv = NULL; + POLL_NFDS_TYPE i = 0; + BOOL found = FALSE; + struct usbi_transfer *transfer; + DWORD io_size, io_result; + int r = LIBUSB_SUCCESS; + + usbi_mutex_lock(&ctx->open_devs_lock); + for (i = 0; i < nfds && num_ready > 0; i++) { + + usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents); + + if (!fds[i].revents) + continue; + + num_ready--; + + // Because a Windows OVERLAPPED is used for poll emulation, + // a pollable fd is created and stored with each transfer + usbi_mutex_lock(&ctx->flying_transfers_lock); + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + transfer_priv = usbi_transfer_get_os_priv(transfer); + if (transfer_priv->pollable_fd.fd == fds[i].fd) { + found = TRUE; + break; + } + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) { + io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal; + io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh; + usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd); + // let handle_callback free the event using the transfer wfd + // If you don't use the transfer wfd, you run a risk of trying to free a + // newly allocated wfd that took the place of the one from the transfer. + wince_handle_callback(transfer, io_result, io_size); + } else if (found) { + usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]); + r = LIBUSB_ERROR_OTHER; + break; + } else { + usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]); + r = LIBUSB_ERROR_NOT_FOUND; + break; + } + } + usbi_mutex_unlock(&ctx->open_devs_lock); + + return r; +} + +/* + * Monotonic and real time functions + */ +static int wince_clock_gettime(int clk_id, struct timespec *tp) +{ + LARGE_INTEGER hires_counter; + ULARGE_INTEGER rtime; + FILETIME filetime; + SYSTEMTIME st; + + switch(clk_id) { + case USBI_CLOCK_MONOTONIC: + if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) { + tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency); + tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps); + return LIBUSB_SUCCESS; + } + // Fall through and return real-time if monotonic read failed or was not detected @ init + case USBI_CLOCK_REALTIME: + // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx + // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00 + // Note however that our resolution is bounded by the Windows system time + // functions and is at best of the order of 1 ms (or, usually, worse) + GetSystemTime(&st); + SystemTimeToFileTime(&st, &filetime); + rtime.LowPart = filetime.dwLowDateTime; + rtime.HighPart = filetime.dwHighDateTime; + rtime.QuadPart -= EPOCH_TIME; + tp->tv_sec = (long)(rtime.QuadPart / 10000000); + tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100); + return LIBUSB_SUCCESS; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +const struct usbi_os_backend wince_backend = { + "Windows CE", + 0, + wince_init, + wince_exit, + + wince_get_device_list, + NULL, /* hotplug_poll */ + wince_open, + wince_close, + + wince_get_device_descriptor, + wince_get_active_config_descriptor, + wince_get_config_descriptor, + NULL, /* get_config_descriptor_by_value() */ + + wince_get_configuration, + wince_set_configuration, + wince_claim_interface, + wince_release_interface, + + wince_set_interface_altsetting, + wince_clear_halt, + wince_reset_device, + + NULL, /* alloc_streams */ + NULL, /* free_streams */ + + NULL, /* dev_mem_alloc() */ + NULL, /* dev_mem_free() */ + + wince_kernel_driver_active, + wince_detach_kernel_driver, + wince_attach_kernel_driver, + + wince_destroy_device, + + wince_submit_transfer, + wince_cancel_transfer, + wince_clear_transfer_priv, + + wince_handle_events, + NULL, /* handle_transfer_completion() */ + + wince_clock_gettime, + sizeof(struct wince_device_priv), + 0, + sizeof(struct wince_transfer_priv), +}; diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.h new file mode 100644 index 00000000..edcb9fcc --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.h @@ -0,0 +1,126 @@ +/* + * Windows CE backend for libusb 1.0 + * Copyright © 2011-2013 RealVNC Ltd. + * Portions taken from Windows backend, which is + * Copyright © 2009-2010 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#pragma once + +#include "windows_common.h" + +#include +#include "poll_windows.h" + +#define MAX_DEVICE_COUNT 256 + +// This is a modified dump of the types in the ceusbkwrapper.h library header +// with functions transformed into extern pointers. +// +// This backend dynamically loads ceusbkwrapper.dll and doesn't include +// ceusbkwrapper.h directly to simplify the build process. The kernel +// side wrapper driver is built using the platform image build tools, +// which makes it difficult to reference directly from the libusb build +// system. +struct UKW_DEVICE_PRIV; +typedef struct UKW_DEVICE_PRIV *UKW_DEVICE; +typedef UKW_DEVICE *PUKW_DEVICE, *LPUKW_DEVICE; + +typedef struct { + UINT8 bLength; + UINT8 bDescriptorType; + UINT16 bcdUSB; + UINT8 bDeviceClass; + UINT8 bDeviceSubClass; + UINT8 bDeviceProtocol; + UINT8 bMaxPacketSize0; + UINT16 idVendor; + UINT16 idProduct; + UINT16 bcdDevice; + UINT8 iManufacturer; + UINT8 iProduct; + UINT8 iSerialNumber; + UINT8 bNumConfigurations; +} UKW_DEVICE_DESCRIPTOR, *PUKW_DEVICE_DESCRIPTOR, *LPUKW_DEVICE_DESCRIPTOR; + +typedef struct { + UINT8 bmRequestType; + UINT8 bRequest; + UINT16 wValue; + UINT16 wIndex; + UINT16 wLength; +} UKW_CONTROL_HEADER, *PUKW_CONTROL_HEADER, *LPUKW_CONTROL_HEADER; + +// Collection of flags which can be used when issuing transfer requests +/* Indicates that the transfer direction is 'in' */ +#define UKW_TF_IN_TRANSFER 0x00000001 +/* Indicates that the transfer direction is 'out' */ +#define UKW_TF_OUT_TRANSFER 0x00000000 +/* Specifies that the transfer should complete as soon as possible, + * even if no OVERLAPPED structure has been provided. */ +#define UKW_TF_NO_WAIT 0x00000100 +/* Indicates that transfers shorter than the buffer are ok */ +#define UKW_TF_SHORT_TRANSFER_OK 0x00000200 +#define UKW_TF_SEND_TO_DEVICE 0x00010000 +#define UKW_TF_SEND_TO_INTERFACE 0x00020000 +#define UKW_TF_SEND_TO_ENDPOINT 0x00040000 +/* Don't block when waiting for memory allocations */ +#define UKW_TF_DONT_BLOCK_FOR_MEM 0x00080000 + +/* Value to use when dealing with configuration values, such as UkwGetConfigDescriptor, + * to specify the currently active configuration for the device. */ +#define UKW_ACTIVE_CONFIGURATION -1 + +DLL_DECLARE_HANDLE(ceusbkwrapper); +DLL_DECLARE_FUNC(WINAPI, HANDLE, UkwOpenDriver, ()); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD)); +DLL_DECLARE_FUNC(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD)); +DLL_DECLARE_FUNC(WINAPI, void, UkwCloseDriver, (HANDLE)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL)); + +// Used to determine if an endpoint status really is halted on a failed transfer. +#define STATUS_HALT_FLAG 0x1 + +struct wince_device_priv { + UKW_DEVICE dev; + UKW_DEVICE_DESCRIPTOR desc; +}; + +struct wince_transfer_priv { + struct winfd pollable_fd; + uint8_t interface_number; +}; + diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_common.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_common.h new file mode 100644 index 00000000..55344ca2 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_common.h @@ -0,0 +1,124 @@ +/* + * Windows backend common header for libusb 1.0 + * + * This file brings together header code common between + * the desktop Windows and Windows CE backends. + * Copyright © 2012-2013 RealVNC Ltd. + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +// Windows API default is uppercase - ugh! +#if !defined(bool) +#define bool BOOL +#endif +#if !defined(true) +#define true TRUE +#endif +#if !defined(false) +#define false FALSE +#endif + +#define EPOCH_TIME UINT64_C(116444736000000000) // 1970.01.01 00:00:000 in MS Filetime + +#if defined(__CYGWIN__ ) +#define _stricmp strcasecmp +#define _strdup strdup +// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread +#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, (LPDWORD)f) +#endif + +#define safe_free(p) do {if (p != NULL) {free((void *)p); p = NULL;}} while (0) + +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + +#define ERR_BUFFER_SIZE 256 + +/* + * API macros - leveraged from libusb-win32 1.x + */ +#ifndef _WIN32_WCE +#define DLL_STRINGIFY(s) #s +#define DLL_LOAD_LIBRARY(name) LoadLibraryA(DLL_STRINGIFY(name)) +#else +#define DLL_STRINGIFY(s) L#s +#define DLL_LOAD_LIBRARY(name) LoadLibrary(DLL_STRINGIFY(name)) +#endif + +/* + * Macros for handling DLL themselves + */ +#define DLL_DECLARE_HANDLE(name) \ + static HMODULE __dll_##name##_handle = NULL + +#define DLL_GET_HANDLE(name) \ + do { \ + __dll_##name##_handle = DLL_LOAD_LIBRARY(name); \ + if (!__dll_##name##_handle) \ + return LIBUSB_ERROR_OTHER; \ + } while (0) + +#define DLL_FREE_HANDLE(name) \ + do { \ + if (__dll_##name##_handle) { \ + FreeLibrary(__dll_##name##_handle); \ + __dll_##name##_handle = NULL; \ + } \ + } while(0) + + +/* + * Macros for handling functions within a DLL + */ +#define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \ + typedef ret (api * __dll_##name##_func_t)args; \ + static __dll_##name##_func_t prefixname = NULL + +#define DLL_DECLARE_FUNC(api, ret, name, args) \ + DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args) +#define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args) \ + DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args) + +#define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \ + do { \ + HMODULE h = __dll_##dll##_handle; \ + prefixname = (__dll_##name##_func_t)GetProcAddress(h, \ + DLL_STRINGIFY(name)); \ + if (prefixname) \ + break; \ + prefixname = (__dll_##name##_func_t)GetProcAddress(h, \ + DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \ + if (prefixname) \ + break; \ + prefixname = (__dll_##name##_func_t)GetProcAddress(h, \ + DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \ + if (prefixname) \ + break; \ + if (ret_on_failure) \ + return LIBUSB_ERROR_NOT_FOUND; \ + } while(0) + +#define DLL_LOAD_FUNC(dll, name, ret_on_failure) \ + DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure) +#define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure) \ + DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure) diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.c new file mode 100644 index 00000000..d935394a --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.c @@ -0,0 +1,591 @@ +/* + * windows backend for libusb 1.0 + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software + * Hash table functions adapted from glibc, by Ulrich Drepper et al. + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include + +#include "libusbi.h" +#include "windows_common.h" +#include "windows_nt_common.h" + +// Global variables for clock_gettime mechanism +static uint64_t hires_ticks_to_ps; +static uint64_t hires_frequency; + +#define TIMER_REQUEST_RETRY_MS 100 +#define WM_TIMER_REQUEST (WM_USER + 1) +#define WM_TIMER_EXIT (WM_USER + 2) + +// used for monotonic clock_gettime() +struct timer_request { + struct timespec *tp; + HANDLE event; +}; + +// Timer thread +static HANDLE timer_thread = NULL; +static DWORD timer_thread_id = 0; + +/* User32 dependencies */ +DLL_DECLARE_HANDLE(User32); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM)); + +static unsigned __stdcall windows_clock_gettime_threaded(void *param); + +/* +* Converts a windows error to human readable string +* uses retval as errorcode, or, if 0, use GetLastError() +*/ +#if defined(ENABLE_LOGGING) +const char *windows_error_str(DWORD error_code) +{ + static char err_string[ERR_BUFFER_SIZE]; + + DWORD size; + int len; + + if (error_code == 0) + error_code = GetLastError(); + + len = sprintf(err_string, "[%u] ", (unsigned int)error_code); + + // Translate codes returned by SetupAPI. The ones we are dealing with are either + // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes. + // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx + switch (error_code & 0xE0000000) { + case 0: + error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified + break; + case 0xE0000000: + error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF); + break; + default: + break; + } + + size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + &err_string[len], ERR_BUFFER_SIZE - len, NULL); + if (size == 0) { + DWORD format_error = GetLastError(); + if (format_error) + snprintf(err_string, ERR_BUFFER_SIZE, + "Windows error code %u (FormatMessage error code %u)", + (unsigned int)error_code, (unsigned int)format_error); + else + snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code); + } else { + // Remove CRLF from end of message, if present + size_t pos = len + size - 2; + if (err_string[pos] == '\r') + err_string[pos] = '\0'; + } + + return err_string; +} +#endif + +/* Hash table functions - modified From glibc 2.3.2: + [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 + [Knuth] The Art of Computer Programming, part 3 (6.4) */ + +#define HTAB_SIZE 1021UL // *MUST* be a prime number!! + +typedef struct htab_entry { + unsigned long used; + char *str; +} htab_entry; + +static htab_entry *htab_table = NULL; +static usbi_mutex_t htab_mutex = NULL; +static unsigned long htab_filled; + +/* Before using the hash table we must allocate memory for it. + We allocate one element more as the found prime number says. + This is done for more effective indexing as explained in the + comment for the hash function. */ +static bool htab_create(struct libusb_context *ctx) +{ + if (htab_table != NULL) { + usbi_err(ctx, "hash table already allocated"); + return true; + } + + // Create a mutex + usbi_mutex_init(&htab_mutex); + + usbi_dbg("using %lu entries hash table", HTAB_SIZE); + htab_filled = 0; + + // allocate memory and zero out. + htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry)); + if (htab_table == NULL) { + usbi_err(ctx, "could not allocate space for hash table"); + return false; + } + + return true; +} + +/* After using the hash table it has to be destroyed. */ +static void htab_destroy(void) +{ + unsigned long i; + + if (htab_table == NULL) + return; + + for (i = 0; i < HTAB_SIZE; i++) + free(htab_table[i].str); + + safe_free(htab_table); + + usbi_mutex_destroy(&htab_mutex); +} + +/* This is the search function. It uses double hashing with open addressing. + We use a trick to speed up the lookup. The table is created with one + more element available. This enables us to use the index zero special. + This index will never be used because we store the first hash index in + the field used where zero means not used. Every other value means used. + The used field can be used as a first fast comparison for equality of + the stored and the parameter value. This helps to prevent unnecessary + expensive calls of strcmp. */ +unsigned long htab_hash(const char *str) +{ + unsigned long hval, hval2; + unsigned long idx; + unsigned long r = 5381; + int c; + const char *sz = str; + + if (str == NULL) + return 0; + + // Compute main hash value (algorithm suggested by Nokia) + while ((c = *sz++) != 0) + r = ((r << 5) + r) + c; + if (r == 0) + ++r; + + // compute table hash: simply take the modulus + hval = r % HTAB_SIZE; + if (hval == 0) + ++hval; + + // Try the first index + idx = hval; + + // Mutually exclusive access (R/W lock would be better) + usbi_mutex_lock(&htab_mutex); + + if (htab_table[idx].used) { + if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0)) + goto out_unlock; // existing hash + + usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str); + + // Second hash function, as suggested in [Knuth] + hval2 = 1 + hval % (HTAB_SIZE - 2); + + do { + // Because size is prime this guarantees to step through all available indexes + if (idx <= hval2) + idx = HTAB_SIZE + idx - hval2; + else + idx -= hval2; + + // If we visited all entries leave the loop unsuccessfully + if (idx == hval) + break; + + // If entry is found use it. + if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0)) + goto out_unlock; + } while (htab_table[idx].used); + } + + // Not found => New entry + + // If the table is full return an error + if (htab_filled >= HTAB_SIZE) { + usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE); + idx = 0; + goto out_unlock; + } + + htab_table[idx].str = _strdup(str); + if (htab_table[idx].str == NULL) { + usbi_err(NULL, "could not duplicate string for hash table"); + idx = 0; + goto out_unlock; + } + + htab_table[idx].used = hval; + ++htab_filled; + +out_unlock: + usbi_mutex_unlock(&htab_mutex); + + return idx; +} + +static int windows_init_dlls(void) +{ + DLL_GET_HANDLE(User32); + DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE); + DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE); + DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE); + + return LIBUSB_SUCCESS; +} + +static void windows_exit_dlls(void) +{ + DLL_FREE_HANDLE(User32); +} + +static bool windows_init_clock(struct libusb_context *ctx) +{ + DWORD_PTR affinity, dummy; + HANDLE event = NULL; + LARGE_INTEGER li_frequency; + int i; + + if (QueryPerformanceFrequency(&li_frequency)) { + // Load DLL imports + if (windows_init_dlls() != LIBUSB_SUCCESS) { + usbi_err(ctx, "could not resolve DLL functions"); + return false; + } + + // The hires frequency can go as high as 4 GHz, so we'll use a conversion + // to picoseconds to compute the tv_nsecs part in clock_gettime + hires_frequency = li_frequency.QuadPart; + hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency; + usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency); + + // Because QueryPerformanceCounter might report different values when + // running on different cores, we create a separate thread for the timer + // calls, which we glue to the first available core always to prevent timing discrepancies. + if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) { + usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0)); + return false; + } + + // The process affinity mask is a bitmask where each set bit represents a core on + // which this process is allowed to run, so we find the first set bit + for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++); + affinity = (DWORD_PTR)(1 << i); + + usbi_dbg("timer thread will run on core #%d", i); + + event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (event == NULL) { + usbi_err(ctx, "could not create event: %s", windows_error_str(0)); + return false; + } + + timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event, + 0, (unsigned int *)&timer_thread_id); + if (timer_thread == NULL) { + usbi_err(ctx, "unable to create timer thread - aborting"); + CloseHandle(event); + return false; + } + + if (!SetThreadAffinityMask(timer_thread, affinity)) + usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise"); + + // Wait for timer thread to init before continuing. + if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) { + usbi_err(ctx, "failed to wait for timer thread to become ready - aborting"); + CloseHandle(event); + return false; + } + + CloseHandle(event); + } else { + usbi_dbg("no hires timer available on this platform"); + hires_frequency = 0; + hires_ticks_to_ps = UINT64_C(0); + } + + return true; +} + +void windows_destroy_clock(void) +{ + if (timer_thread) { + // actually the signal to quit the thread. + if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0) + || (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) { + usbi_dbg("could not wait for timer thread to quit"); + TerminateThread(timer_thread, 1); + // shouldn't happen, but we're destroying + // all objects it might have held anyway. + } + CloseHandle(timer_thread); + timer_thread = NULL; + timer_thread_id = 0; + } +} + +/* +* Monotonic and real time functions +*/ +static unsigned __stdcall windows_clock_gettime_threaded(void *param) +{ + struct timer_request *request; + LARGE_INTEGER hires_counter; + MSG msg; + + // The following call will create this thread's message queue + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx + pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + + // Signal windows_init_clock() that we're ready to service requests + if (!SetEvent((HANDLE)param)) + usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0)); + param = NULL; + + // Main loop - wait for requests + while (1) { + if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) { + usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0)); + return 1; + } + + switch (msg.message) { + case WM_TIMER_REQUEST: + // Requests to this thread are for hires always + // Microsoft says that this function always succeeds on XP and later + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx + request = (struct timer_request *)msg.lParam; + QueryPerformanceCounter(&hires_counter); + request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency); + request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps); + if (!SetEvent(request->event)) + usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0)); + break; + case WM_TIMER_EXIT: + usbi_dbg("timer thread quitting"); + return 0; + } + } +} + +int windows_clock_gettime(int clk_id, struct timespec *tp) +{ + struct timer_request request; +#if !defined(_MSC_VER) || (_MSC_VER < 1900) + FILETIME filetime; + ULARGE_INTEGER rtime; +#endif + DWORD r; + + switch (clk_id) { + case USBI_CLOCK_MONOTONIC: + if (timer_thread) { + request.tp = tp; + request.event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (request.event == NULL) + return LIBUSB_ERROR_NO_MEM; + + if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) { + usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0)); + CloseHandle(request.event); + return LIBUSB_ERROR_OTHER; + } + + do { + r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS); + if (r == WAIT_TIMEOUT) + usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?"); + else if (r == WAIT_FAILED) + usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0)); + } while (r == WAIT_TIMEOUT); + CloseHandle(request.event); + + if (r == WAIT_OBJECT_0) + return LIBUSB_SUCCESS; + else + return LIBUSB_ERROR_OTHER; + } + // Fall through and return real-time if monotonic was not detected @ timer init + case USBI_CLOCK_REALTIME: +#if defined(_MSC_VER) && (_MSC_VER >= 1900) + timespec_get(tp, TIME_UTC); +#else + // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx + // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00 + // Note however that our resolution is bounded by the Windows system time + // functions and is at best of the order of 1 ms (or, usually, worse) + GetSystemTimeAsFileTime(&filetime); + rtime.LowPart = filetime.dwLowDateTime; + rtime.HighPart = filetime.dwHighDateTime; + rtime.QuadPart -= EPOCH_TIME; + tp->tv_sec = (long)(rtime.QuadPart / 10000000); + tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100); +#endif + return LIBUSB_SUCCESS; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size) +{ + int status, istatus; + + usbi_dbg("handling I/O completion with errcode %u, size %u", io_result, io_size); + + switch (io_result) { + case NO_ERROR: + status = windows_copy_transfer_data(itransfer, io_size); + break; + case ERROR_GEN_FAILURE: + usbi_dbg("detected endpoint stall"); + status = LIBUSB_TRANSFER_STALL; + break; + case ERROR_SEM_TIMEOUT: + usbi_dbg("detected semaphore timeout"); + status = LIBUSB_TRANSFER_TIMED_OUT; + break; + case ERROR_OPERATION_ABORTED: + istatus = windows_copy_transfer_data(itransfer, io_size); + if (istatus != LIBUSB_TRANSFER_COMPLETED) + usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus); + + usbi_dbg("detected operation aborted"); + status = LIBUSB_TRANSFER_CANCELLED; + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", io_result, windows_error_str(io_result)); + status = LIBUSB_TRANSFER_ERROR; + break; + } + windows_clear_transfer_priv(itransfer); // Cancel polling + if (status == LIBUSB_TRANSFER_CANCELLED) + usbi_handle_transfer_cancellation(itransfer); + else + usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); +} + +void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + windows_transfer_callback(itransfer, io_result, io_size); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform"); + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + } +} + +int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) +{ + POLL_NFDS_TYPE i; + bool found = false; + struct usbi_transfer *transfer; + struct winfd *pollable_fd = NULL; + DWORD io_size, io_result; + int r = LIBUSB_SUCCESS; + + usbi_mutex_lock(&ctx->open_devs_lock); + for (i = 0; i < nfds && num_ready > 0; i++) { + + usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents); + + if (!fds[i].revents) + continue; + + num_ready--; + + // Because a Windows OVERLAPPED is used for poll emulation, + // a pollable fd is created and stored with each transfer + usbi_mutex_lock(&ctx->flying_transfers_lock); + found = false; + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + pollable_fd = windows_get_fd(transfer); + if (pollable_fd->fd == fds[i].fd) { + found = true; + break; + } + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + if (found) { + windows_get_overlapped_result(transfer, pollable_fd, &io_result, &io_size); + + usbi_remove_pollfd(ctx, pollable_fd->fd); + // let handle_callback free the event using the transfer wfd + // If you don't use the transfer wfd, you run a risk of trying to free a + // newly allocated wfd that took the place of the one from the transfer. + windows_handle_callback(transfer, io_result, io_size); + } else { + usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]); + r = LIBUSB_ERROR_NOT_FOUND; + break; + } + } + usbi_mutex_unlock(&ctx->open_devs_lock); + + return r; +} + +int windows_common_init(struct libusb_context *ctx) +{ + if (!windows_init_clock(ctx)) + goto error_roll_back; + + if (!htab_create(ctx)) + goto error_roll_back; + + return LIBUSB_SUCCESS; + +error_roll_back: + windows_common_exit(); + return LIBUSB_ERROR_NO_MEM; +} + +void windows_common_exit(void) +{ + htab_destroy(); + windows_destroy_clock(); + windows_exit_dlls(); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.h new file mode 100644 index 00000000..52ea8708 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.h @@ -0,0 +1,63 @@ +/* + * Windows backend common header for libusb 1.0 + * + * This file brings together header code common between + * the desktop Windows backends. + * Copyright © 2012-2013 RealVNC Ltd. + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +// Missing from MinGW +#if !defined(FACILITY_SETUPAPI) +#define FACILITY_SETUPAPI 15 +#endif + +typedef struct USB_CONFIGURATION_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + USHORT wTotalLength; + UCHAR bNumInterfaces; + UCHAR bConfigurationValue; + UCHAR iConfiguration; + UCHAR bmAttributes; + UCHAR MaxPower; +} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR; + +typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; + +int windows_common_init(struct libusb_context *ctx); +void windows_common_exit(void); + +unsigned long htab_hash(const char *str); +int windows_clock_gettime(int clk_id, struct timespec *tp); + +void windows_clear_transfer_priv(struct usbi_transfer *itransfer); +int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size); +struct winfd *windows_get_fd(struct usbi_transfer *transfer); +void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size); + +void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size); +int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready); + +#if defined(ENABLE_LOGGING) +const char *windows_error_str(DWORD error_code); +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.c new file mode 100644 index 00000000..7cc57938 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.c @@ -0,0 +1,905 @@ +/* + * windows UsbDk backend for libusb 1.0 + * Copyright © 2014 Red Hat, Inc. + + * Authors: + * Dmitry Fleytman + * Pavel Gurvich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#if defined(USE_USBDK) + +#include +#include +#include + +#include "libusbi.h" +#include "windows_common.h" +#include "windows_nt_common.h" + +#define ULONG64 uint64_t +#define PVOID64 uint64_t + +typedef CONST WCHAR *PCWCHAR; +#define wcsncpy_s wcsncpy + +#include "windows_usbdk.h" + +#if !defined(STATUS_SUCCESS) +typedef LONG NTSTATUS; +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#endif + +#if !defined(STATUS_CANCELLED) +#define STATUS_CANCELLED ((NTSTATUS)0xC0000120L) +#endif + +#if !defined(STATUS_REQUEST_CANCELED) +#define STATUS_REQUEST_CANCELED ((NTSTATUS)0xC0000703L) +#endif + +#if !defined(USBD_SUCCESS) +typedef int32_t USBD_STATUS; +#define USBD_SUCCESS(Status) ((USBD_STATUS) (Status) >= 0) +#define USBD_PENDING(Status) ((ULONG) (Status) >> 30 == 1) +#define USBD_ERROR(Status) ((USBD_STATUS) (Status) < 0) +#define USBD_STATUS_STALL_PID ((USBD_STATUS) 0xc0000004) +#define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS) 0xc0000030) +#define USBD_STATUS_BAD_START_FRAME ((USBD_STATUS) 0xc0000a00) +#define USBD_STATUS_TIMEOUT ((USBD_STATUS) 0xc0006000) +#define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000) +#endif + +static int concurrent_usage = -1; + +struct usbdk_device_priv { + USB_DK_DEVICE_INFO info; + PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors; + HANDLE redirector_handle; + uint8_t active_configuration; +}; + +struct usbdk_transfer_priv { + USB_DK_TRANSFER_REQUEST request; + struct winfd pollable_fd; + PULONG64 IsochronousPacketsArray; + PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray; +}; + +static inline struct usbdk_device_priv *_usbdk_device_priv(struct libusb_device *dev) +{ + return (struct usbdk_device_priv *)dev->os_priv; +} + +static inline struct usbdk_transfer_priv *_usbdk_transfer_priv(struct usbi_transfer *itransfer) +{ + return (struct usbdk_transfer_priv *)usbi_transfer_get_os_priv(itransfer); +} + +static struct { + HMODULE module; + + USBDK_GET_DEVICES_LIST GetDevicesList; + USBDK_RELEASE_DEVICES_LIST ReleaseDevicesList; + USBDK_START_REDIRECT StartRedirect; + USBDK_STOP_REDIRECT StopRedirect; + USBDK_GET_CONFIGURATION_DESCRIPTOR GetConfigurationDescriptor; + USBDK_RELEASE_CONFIGURATION_DESCRIPTOR ReleaseConfigurationDescriptor; + USBDK_READ_PIPE ReadPipe; + USBDK_WRITE_PIPE WritePipe; + USBDK_ABORT_PIPE AbortPipe; + USBDK_RESET_PIPE ResetPipe; + USBDK_SET_ALTSETTING SetAltsetting; + USBDK_RESET_DEVICE ResetDevice; + USBDK_GET_REDIRECTOR_SYSTEM_HANDLE GetRedirectorSystemHandle; +} usbdk_helper; + +static FARPROC get_usbdk_proc_addr(struct libusb_context *ctx, LPCSTR api_name) +{ + FARPROC api_ptr = GetProcAddress(usbdk_helper.module, api_name); + + if (api_ptr == NULL) + usbi_err(ctx, "UsbDkHelper API %s not found, error %d", api_name, GetLastError()); + + return api_ptr; +} + +static void unload_usbdk_helper_dll(void) +{ + if (usbdk_helper.module != NULL) { + FreeLibrary(usbdk_helper.module); + usbdk_helper.module = NULL; + } +} + +static int load_usbdk_helper_dll(struct libusb_context *ctx) +{ + usbdk_helper.module = LoadLibraryA("UsbDkHelper"); + if (usbdk_helper.module == NULL) { + usbi_err(ctx, "Failed to load UsbDkHelper.dll, error %d", GetLastError()); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbdk_helper.GetDevicesList = (USBDK_GET_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_GetDevicesList"); + if (usbdk_helper.GetDevicesList == NULL) + goto error_unload; + + usbdk_helper.ReleaseDevicesList = (USBDK_RELEASE_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseDevicesList"); + if (usbdk_helper.ReleaseDevicesList == NULL) + goto error_unload; + + usbdk_helper.StartRedirect = (USBDK_START_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StartRedirect"); + if (usbdk_helper.StartRedirect == NULL) + goto error_unload; + + usbdk_helper.StopRedirect = (USBDK_STOP_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StopRedirect"); + if (usbdk_helper.StopRedirect == NULL) + goto error_unload; + + usbdk_helper.GetConfigurationDescriptor = (USBDK_GET_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_GetConfigurationDescriptor"); + if (usbdk_helper.GetConfigurationDescriptor == NULL) + goto error_unload; + + usbdk_helper.ReleaseConfigurationDescriptor = (USBDK_RELEASE_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseConfigurationDescriptor"); + if (usbdk_helper.ReleaseConfigurationDescriptor == NULL) + goto error_unload; + + usbdk_helper.ReadPipe = (USBDK_READ_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ReadPipe"); + if (usbdk_helper.ReadPipe == NULL) + goto error_unload; + + usbdk_helper.WritePipe = (USBDK_WRITE_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_WritePipe"); + if (usbdk_helper.WritePipe == NULL) + goto error_unload; + + usbdk_helper.AbortPipe = (USBDK_ABORT_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_AbortPipe"); + if (usbdk_helper.AbortPipe == NULL) + goto error_unload; + + usbdk_helper.ResetPipe = (USBDK_RESET_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ResetPipe"); + if (usbdk_helper.ResetPipe == NULL) + goto error_unload; + + usbdk_helper.SetAltsetting = (USBDK_SET_ALTSETTING)get_usbdk_proc_addr(ctx, "UsbDk_SetAltsetting"); + if (usbdk_helper.SetAltsetting == NULL) + goto error_unload; + + usbdk_helper.ResetDevice = (USBDK_RESET_DEVICE)get_usbdk_proc_addr(ctx, "UsbDk_ResetDevice"); + if (usbdk_helper.ResetDevice == NULL) + goto error_unload; + + usbdk_helper.GetRedirectorSystemHandle = (USBDK_GET_REDIRECTOR_SYSTEM_HANDLE)get_usbdk_proc_addr(ctx, "UsbDk_GetRedirectorSystemHandle"); + if (usbdk_helper.GetRedirectorSystemHandle == NULL) + goto error_unload; + + return LIBUSB_SUCCESS; + +error_unload: + FreeLibrary(usbdk_helper.module); + usbdk_helper.module = NULL; + return LIBUSB_ERROR_NOT_FOUND; +} + +static int usbdk_init(struct libusb_context *ctx) +{ + int r; + + if (++concurrent_usage == 0) { // First init? + r = load_usbdk_helper_dll(ctx); + if (r) + goto init_exit; + + init_polling(); + + r = windows_common_init(ctx); + if (r) + goto init_exit; + } + // At this stage, either we went through full init successfully, or didn't need to + r = LIBUSB_SUCCESS; + +init_exit: + if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed? + exit_polling(); + windows_common_exit(); + unload_usbdk_helper_dll(); + } + + if (r != LIBUSB_SUCCESS) + --concurrent_usage; // Not expected to call libusb_exit if we failed. + + return r; +} + +static int usbdk_get_session_id_for_device(struct libusb_context *ctx, + PUSB_DK_DEVICE_ID id, unsigned long *session_id) +{ + char dev_identity[ARRAYSIZE(id->DeviceID) + ARRAYSIZE(id->InstanceID)]; + + if (sprintf(dev_identity, "%S%S", id->DeviceID, id->InstanceID) == -1) { + usbi_warn(ctx, "cannot form device identity", id->DeviceID); + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + *session_id = htab_hash(dev_identity); + + return LIBUSB_SUCCESS; +} + +static void usbdk_release_config_descriptors(struct usbdk_device_priv *p, uint8_t count) +{ + uint8_t i; + + for (i = 0; i < count; i++) + usbdk_helper.ReleaseConfigurationDescriptor(p->config_descriptors[i]); + + free(p->config_descriptors); + p->config_descriptors = NULL; +} + +static int usbdk_cache_config_descriptors(struct libusb_context *ctx, + struct usbdk_device_priv *p, PUSB_DK_DEVICE_INFO info) +{ + uint8_t i; + USB_DK_CONFIG_DESCRIPTOR_REQUEST Request; + Request.ID = info->ID; + + p->config_descriptors = calloc(info->DeviceDescriptor.bNumConfigurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR)); + if (p->config_descriptors == NULL) { + usbi_err(ctx, "failed to allocate configuration descriptors holder"); + return LIBUSB_ERROR_NO_MEM; + } + + for (i = 0; i < info->DeviceDescriptor.bNumConfigurations; i++) { + ULONG Length; + + Request.Index = i; + if (!usbdk_helper.GetConfigurationDescriptor(&Request, &p->config_descriptors[i], &Length)) { + usbi_err(ctx, "failed to retrieve configuration descriptors"); + usbdk_release_config_descriptors(p, i); + return LIBUSB_ERROR_OTHER; + } + } + + return LIBUSB_SUCCESS; +} + +static inline int usbdk_device_priv_init(struct libusb_context *ctx, struct libusb_device *dev, PUSB_DK_DEVICE_INFO info) +{ + struct usbdk_device_priv *p = _usbdk_device_priv(dev); + + p->info = *info; + p->active_configuration = 0; + + return usbdk_cache_config_descriptors(ctx, p, info); +} + +static void usbdk_device_init(libusb_device *dev, PUSB_DK_DEVICE_INFO info) +{ + dev->bus_number = (uint8_t)info->FilterID; + dev->port_number = (uint8_t)info->Port; + dev->parent_dev = NULL; + + //Addresses in libusb are 1-based + dev->device_address = (uint8_t)(info->Port + 1); + + dev->num_configurations = info->DeviceDescriptor.bNumConfigurations; + dev->device_descriptor = info->DeviceDescriptor; + + switch (info->Speed) { + case LowSpeed: + dev->speed = LIBUSB_SPEED_LOW; + break; + case FullSpeed: + dev->speed = LIBUSB_SPEED_FULL; + break; + case HighSpeed: + dev->speed = LIBUSB_SPEED_HIGH; + break; + case SuperSpeed: + dev->speed = LIBUSB_SPEED_SUPER; + break; + case NoSpeed: + default: + dev->speed = LIBUSB_SPEED_UNKNOWN; + break; + } +} + +static int usbdk_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs) +{ + int r = LIBUSB_SUCCESS; + ULONG i; + struct discovered_devs *discdevs = NULL; + ULONG dev_number; + PUSB_DK_DEVICE_INFO devices; + + if(!usbdk_helper.GetDevicesList(&devices, &dev_number)) + return LIBUSB_ERROR_OTHER; + + for (i = 0; i < dev_number; i++) { + unsigned long session_id; + struct libusb_device *dev = NULL; + + if (usbdk_get_session_id_for_device(ctx, &devices[i].ID, &session_id)) + continue; + + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev == NULL) { + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) { + usbi_err(ctx, "failed to allocate a new device structure"); + continue; + } + + usbdk_device_init(dev, &devices[i]); + if (usbdk_device_priv_init(ctx, dev, &devices[i]) != LIBUSB_SUCCESS) { + libusb_unref_device(dev); + continue; + } + } + + discdevs = discovered_devs_append(*_discdevs, dev); + libusb_unref_device(dev); + if (!discdevs) { + usbi_err(ctx, "cannot append new device to list"); + r = LIBUSB_ERROR_NO_MEM; + goto func_exit; + } + + *_discdevs = discdevs; + } + +func_exit: + usbdk_helper.ReleaseDevicesList(devices); + return r; +} + +static void usbdk_exit(void) +{ + if (--concurrent_usage < 0) { + windows_common_exit(); + exit_polling(); + unload_usbdk_helper_dll(); + } +} + +static int usbdk_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev); + + memcpy(buffer, &priv->info.DeviceDescriptor, DEVICE_DESC_LENGTH); + *host_endian = 0; + + return LIBUSB_SUCCESS; +} + +static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev); + PUSB_CONFIGURATION_DESCRIPTOR config_header; + size_t size; + + if (config_index >= dev->num_configurations) + return LIBUSB_ERROR_INVALID_PARAM; + + config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptors[config_index]; + + size = min(config_header->wTotalLength, len); + memcpy(buffer, config_header, size); + *host_endian = 0; + + return (int)size; +} + +static inline int usbdk_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) +{ + return usbdk_get_config_descriptor(dev, _usbdk_device_priv(dev)->active_configuration, + buffer, len, host_endian); +} + +static int usbdk_open(struct libusb_device_handle *dev_handle) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + priv->redirector_handle = usbdk_helper.StartRedirect(&priv->info.ID); + if (priv->redirector_handle == INVALID_HANDLE_VALUE) { + usbi_err(DEVICE_CTX(dev_handle->dev), "Redirector startup failed"); + return LIBUSB_ERROR_OTHER; + } + + return LIBUSB_SUCCESS; +} + +static void usbdk_close(struct libusb_device_handle *dev_handle) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.StopRedirect(priv->redirector_handle)) { + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + usbi_err(ctx, "Redirector shutdown failed"); + } +} + +static int usbdk_get_configuration(struct libusb_device_handle *dev_handle, int *config) +{ + *config = _usbdk_device_priv(dev_handle->dev)->active_configuration; + + return LIBUSB_SUCCESS; +} + +static int usbdk_set_configuration(struct libusb_device_handle *dev_handle, int config) +{ + UNUSED(dev_handle); + UNUSED(config); + return LIBUSB_SUCCESS; +} + +static int usbdk_claim_interface(struct libusb_device_handle *dev_handle, int iface) +{ + UNUSED(dev_handle); + UNUSED(iface); + return LIBUSB_SUCCESS; +} + +static int usbdk_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.SetAltsetting(priv->redirector_handle, iface, altsetting)) { + usbi_err(ctx, "SetAltsetting failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_release_interface(struct libusb_device_handle *dev_handle, int iface) +{ + UNUSED(dev_handle); + UNUSED(iface); + return LIBUSB_SUCCESS; +} + +static int usbdk_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.ResetPipe(priv->redirector_handle, endpoint)) { + usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_reset_device(struct libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.ResetDevice(priv->redirector_handle)) { + usbi_err(ctx, "ResetDevice failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface) +{ + UNUSED(dev_handle); + UNUSED(iface); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static int usbdk_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface) +{ + UNUSED(dev_handle); + UNUSED(iface); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static int usbdk_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface) +{ + UNUSED(dev_handle); + UNUSED(iface); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static void usbdk_destroy_device(struct libusb_device *dev) +{ + struct usbdk_device_priv* p = _usbdk_device_priv(dev); + + if (p->config_descriptors != NULL) + usbdk_release_config_descriptors(p, p->info.DeviceDescriptor.bNumConfigurations); +} + +void windows_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + usbi_free_fd(&transfer_priv->pollable_fd); + + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { + safe_free(transfer_priv->IsochronousPacketsArray); + safe_free(transfer_priv->IsochronousResultsArray); + } +} + +static int usbdk_do_control_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winfd wfd; + ULONG Length; + TransferResult transResult; + HANDLE sysHandle; + + sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); + + wfd = usbi_create_fd(sysHandle, RW_READ, NULL, NULL); + // Always use the handle returned from usbi_create_fd (wfd.handle) + if (wfd.fd < 0) + return LIBUSB_ERROR_NO_MEM; + + transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; + transfer_priv->request.BufferLength = transfer->length; + transfer_priv->request.TransferType = ControlTransferType; + transfer_priv->pollable_fd = INVALID_WINFD; + Length = (ULONG)transfer->length; + + if (IS_XFERIN(transfer)) + transResult = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); + else + transResult = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); + + switch (transResult) { + case TransferSuccess: + wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; + wfd.overlapped->InternalHigh = (DWORD)Length; + break; + case TransferSuccessAsync: + break; + case TransferFailure: + usbi_err(ctx, "ControlTransfer failed: %s", windows_error_str(0)); + usbi_free_fd(&wfd); + return LIBUSB_ERROR_IO; + } + + // Use priv_transfer to store data needed for async polling + transfer_priv->pollable_fd = wfd; + usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN); + + return LIBUSB_SUCCESS; +} + +static int usbdk_do_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winfd wfd; + TransferResult transferRes; + HANDLE sysHandle; + + transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; + transfer_priv->request.BufferLength = transfer->length; + transfer_priv->request.EndpointAddress = transfer->endpoint; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + transfer_priv->request.TransferType = BulkTransferType; + break; + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + transfer_priv->request.TransferType = IntertuptTransferType; + break; + default: + usbi_err(ctx, "Wrong transfer type (%d) in usbdk_do_bulk_transfer. %s", transfer->type, windows_error_str(0)); + return LIBUSB_ERROR_INVALID_PARAM; + } + + transfer_priv->pollable_fd = INVALID_WINFD; + + sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); + + wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL); + // Always use the handle returned from usbi_create_fd (wfd.handle) + if (wfd.fd < 0) + return LIBUSB_ERROR_NO_MEM; + + if (IS_XFERIN(transfer)) + transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); + else + transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); + + switch (transferRes) { + case TransferSuccess: + wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; + break; + case TransferSuccessAsync: + break; + case TransferFailure: + usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); + usbi_free_fd(&wfd); + return LIBUSB_ERROR_IO; + } + + transfer_priv->pollable_fd = wfd; + usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT); + + return LIBUSB_SUCCESS; +} + +static int usbdk_do_iso_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winfd wfd; + TransferResult transferRes; + int i; + HANDLE sysHandle; + + transfer_priv->request.Buffer = (PVOID64)(uintptr_t)transfer->buffer; + transfer_priv->request.BufferLength = transfer->length; + transfer_priv->request.EndpointAddress = transfer->endpoint; + transfer_priv->request.TransferType = IsochronousTransferType; + transfer_priv->request.IsochronousPacketsArraySize = transfer->num_iso_packets; + transfer_priv->IsochronousPacketsArray = malloc(transfer->num_iso_packets * sizeof(ULONG64)); + transfer_priv->request.IsochronousPacketsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousPacketsArray; + if (!transfer_priv->IsochronousPacketsArray) { + usbi_err(ctx, "Allocation of IsochronousPacketsArray is failed, %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + + transfer_priv->IsochronousResultsArray = malloc(transfer->num_iso_packets * sizeof(USB_DK_ISO_TRANSFER_RESULT)); + transfer_priv->request.Result.IsochronousResultsArray = (PVOID64)(uintptr_t)transfer_priv->IsochronousResultsArray; + if (!transfer_priv->IsochronousResultsArray) { + usbi_err(ctx, "Allocation of isochronousResultsArray is failed, %s", windows_error_str(0)); + free(transfer_priv->IsochronousPacketsArray); + return LIBUSB_ERROR_IO; + } + + for (i = 0; i < transfer->num_iso_packets; i++) + transfer_priv->IsochronousPacketsArray[i] = transfer->iso_packet_desc[i].length; + + transfer_priv->pollable_fd = INVALID_WINFD; + + sysHandle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); + + wfd = usbi_create_fd(sysHandle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL); + // Always use the handle returned from usbi_create_fd (wfd.handle) + if (wfd.fd < 0) { + free(transfer_priv->IsochronousPacketsArray); + free(transfer_priv->IsochronousResultsArray); + return LIBUSB_ERROR_NO_MEM; + } + + if (IS_XFERIN(transfer)) + transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); + else + transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, wfd.overlapped); + + switch (transferRes) { + case TransferSuccess: + wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; + break; + case TransferSuccessAsync: + break; + case TransferFailure: + usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); + usbi_free_fd(&wfd); + free(transfer_priv->IsochronousPacketsArray); + free(transfer_priv->IsochronousResultsArray); + return LIBUSB_ERROR_IO; + } + + transfer_priv->pollable_fd = wfd; + usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, IS_XFERIN(transfer) ? POLLIN : POLLOUT); + + return LIBUSB_SUCCESS; +} + +static int usbdk_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return usbdk_do_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)) + return LIBUSB_ERROR_NOT_SUPPORTED; //TODO: Check whether we can support this in UsbDk + else + return usbdk_do_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return usbdk_do_iso_transfer(itransfer); + default: + usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int usbdk_abort_transfers(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + + if (!usbdk_helper.AbortPipe(priv->redirector_handle, transfer->endpoint)) { + usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + // Control transfers cancelled by IoCancelXXX() API + // No special treatment needed + return LIBUSB_SUCCESS; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return usbdk_abort_transfers(itransfer); + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) +{ + itransfer->transferred += io_size; + return LIBUSB_TRANSFER_COMPLETED; +} + +struct winfd *windows_get_fd(struct usbi_transfer *transfer) +{ + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(transfer); + return &transfer_priv->pollable_fd; +} + +static DWORD usbdk_translate_usbd_status(USBD_STATUS UsbdStatus) +{ + if (USBD_SUCCESS(UsbdStatus)) + return NO_ERROR; + + switch (UsbdStatus) { + case USBD_STATUS_STALL_PID: + case USBD_STATUS_ENDPOINT_HALTED: + case USBD_STATUS_BAD_START_FRAME: + return ERROR_GEN_FAILURE; + case USBD_STATUS_TIMEOUT: + return ERROR_SEM_TIMEOUT; + case USBD_STATUS_CANCELED: + return ERROR_OPERATION_ABORTED; + default: + return ERROR_FUNCTION_FAILED; + } +} + +void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size) +{ + if (HasOverlappedIoCompletedSync(pollable_fd->overlapped) // Handle async requests that completed synchronously first + || GetOverlappedResult(pollable_fd->handle, pollable_fd->overlapped, io_size, false)) { // Regular async overlapped + struct libusb_transfer *ltransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(transfer); + + if (ltransfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { + int i; + for (i = 0; i < transfer_priv->request.IsochronousPacketsArraySize; i++) { + struct libusb_iso_packet_descriptor *lib_desc = <ransfer->iso_packet_desc[i]; + + switch (transfer_priv->IsochronousResultsArray[i].TransferResult) { + case STATUS_SUCCESS: + case STATUS_CANCELLED: + case STATUS_REQUEST_CANCELED: + lib_desc->status = LIBUSB_TRANSFER_COMPLETED; // == ERROR_SUCCESS + break; + default: + lib_desc->status = LIBUSB_TRANSFER_ERROR; // ERROR_UNKNOWN_EXCEPTION; + break; + } + + lib_desc->actual_length = (unsigned int)transfer_priv->IsochronousResultsArray[i].ActualLength; + } + } + + *io_size = (DWORD) transfer_priv->request.Result.GenResult.BytesTransferred; + *io_result = usbdk_translate_usbd_status((USBD_STATUS) transfer_priv->request.Result.GenResult.UsbdStatus); + } + else { + *io_result = GetLastError(); + } +} + +static int usbdk_clock_gettime(int clk_id, struct timespec *tp) +{ + return windows_clock_gettime(clk_id, tp); +} + +const struct usbi_os_backend usbdk_backend = { + "Windows", + USBI_CAP_HAS_HID_ACCESS, + usbdk_init, + usbdk_exit, + + usbdk_get_device_list, + NULL, + usbdk_open, + usbdk_close, + + usbdk_get_device_descriptor, + usbdk_get_active_config_descriptor, + usbdk_get_config_descriptor, + NULL, + + usbdk_get_configuration, + usbdk_set_configuration, + usbdk_claim_interface, + usbdk_release_interface, + + usbdk_set_interface_altsetting, + usbdk_clear_halt, + usbdk_reset_device, + + NULL, + NULL, + + NULL, // dev_mem_alloc() + NULL, // dev_mem_free() + + usbdk_kernel_driver_active, + usbdk_detach_kernel_driver, + usbdk_attach_kernel_driver, + + usbdk_destroy_device, + + usbdk_submit_transfer, + usbdk_cancel_transfer, + windows_clear_transfer_priv, + + windows_handle_events, + NULL, + + usbdk_clock_gettime, +#if defined(USBI_TIMERFD_AVAILABLE) + NULL, +#endif + sizeof(struct usbdk_device_priv), + 0, + sizeof(struct usbdk_transfer_priv), +}; + +#endif /* USE_USBDK */ diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.h new file mode 100644 index 00000000..04a9787f --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.h @@ -0,0 +1,146 @@ +/* +* windows UsbDk backend for libusb 1.0 +* Copyright © 2014 Red Hat, Inc. + +* Authors: +* Dmitry Fleytman +* Pavel Gurvich +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +typedef struct tag_USB_DK_DEVICE_ID { + WCHAR DeviceID[MAX_DEVICE_ID_LEN]; + WCHAR InstanceID[MAX_DEVICE_ID_LEN]; +} USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID; + +static inline void UsbDkFillIDStruct(USB_DK_DEVICE_ID *ID, PCWCHAR DeviceID, PCWCHAR InstanceID) +{ + wcsncpy_s(ID->DeviceID, DeviceID, MAX_DEVICE_ID_LEN); + wcsncpy_s(ID->InstanceID, InstanceID, MAX_DEVICE_ID_LEN); +} + +typedef struct tag_USB_DK_DEVICE_INFO { + USB_DK_DEVICE_ID ID; + ULONG64 FilterID; + ULONG64 Port; + ULONG64 Speed; + USB_DEVICE_DESCRIPTOR DeviceDescriptor; +} USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO; + +typedef struct tag_USB_DK_CONFIG_DESCRIPTOR_REQUEST { + USB_DK_DEVICE_ID ID; + ULONG64 Index; +} USB_DK_CONFIG_DESCRIPTOR_REQUEST, *PUSB_DK_CONFIG_DESCRIPTOR_REQUEST; + +typedef struct tag_USB_DK_ISO_TRANSFER_RESULT { + ULONG64 ActualLength; + ULONG64 TransferResult; +} USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT; + +typedef struct tag_USB_DK_GEN_TRANSFER_RESULT { + ULONG64 BytesTransferred; + ULONG64 UsbdStatus; // USBD_STATUS code +} USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT; + +typedef struct tag_USB_DK_TRANSFER_RESULT { + USB_DK_GEN_TRANSFER_RESULT GenResult; + PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT +} USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT; + +typedef struct tag_USB_DK_TRANSFER_REQUEST { + ULONG64 EndpointAddress; + PVOID64 Buffer; + ULONG64 BufferLength; + ULONG64 TransferType; + ULONG64 IsochronousPacketsArraySize; + PVOID64 IsochronousPacketsArray; + + USB_DK_TRANSFER_RESULT Result; +} USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST; + +typedef enum { + TransferFailure = 0, + TransferSuccess, + TransferSuccessAsync +} TransferResult; + +typedef enum { + NoSpeed = 0, + LowSpeed, + FullSpeed, + HighSpeed, + SuperSpeed +} USB_DK_DEVICE_SPEED; + +typedef enum { + ControlTransferType, + BulkTransferType, + IntertuptTransferType, + IsochronousTransferType +} USB_DK_TRANSFER_TYPE; + +typedef BOOL (__cdecl *USBDK_GET_DEVICES_LIST)( + PUSB_DK_DEVICE_INFO *DeviceInfo, + PULONG DeviceNumber +); +typedef void (__cdecl *USBDK_RELEASE_DEVICES_LIST)( + PUSB_DK_DEVICE_INFO DeviceInfo +); +typedef HANDLE (__cdecl *USBDK_START_REDIRECT)( + PUSB_DK_DEVICE_ID DeviceId +); +typedef BOOL (__cdecl *USBDK_STOP_REDIRECT)( + HANDLE DeviceHandle +); +typedef BOOL (__cdecl *USBDK_GET_CONFIGURATION_DESCRIPTOR)( + PUSB_DK_CONFIG_DESCRIPTOR_REQUEST Request, + PUSB_CONFIGURATION_DESCRIPTOR *Descriptor, + PULONG Length +); +typedef void (__cdecl *USBDK_RELEASE_CONFIGURATION_DESCRIPTOR)( + PUSB_CONFIGURATION_DESCRIPTOR Descriptor +); +typedef TransferResult (__cdecl *USBDK_WRITE_PIPE)( + HANDLE DeviceHandle, + PUSB_DK_TRANSFER_REQUEST Request, + LPOVERLAPPED lpOverlapped +); +typedef TransferResult (__cdecl *USBDK_READ_PIPE)( + HANDLE DeviceHandle, + PUSB_DK_TRANSFER_REQUEST Request, + LPOVERLAPPED lpOverlapped +); +typedef BOOL (__cdecl *USBDK_ABORT_PIPE)( + HANDLE DeviceHandle, + ULONG64 PipeAddress +); +typedef BOOL (__cdecl *USBDK_RESET_PIPE)( + HANDLE DeviceHandle, + ULONG64 PipeAddress +); +typedef BOOL (__cdecl *USBDK_SET_ALTSETTING)( + HANDLE DeviceHandle, + ULONG64 InterfaceIdx, + ULONG64 AltSettingIdx +); +typedef BOOL (__cdecl *USBDK_RESET_DEVICE)( + HANDLE DeviceHandle +); +typedef HANDLE (__cdecl *USBDK_GET_REDIRECTOR_SYSTEM_HANDLE)( + HANDLE DeviceHandle +); diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.c b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.c new file mode 100644 index 00000000..b6b08c2f --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.c @@ -0,0 +1,3182 @@ +/* + * windows backend for libusb 1.0 + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software + * Hash table functions adapted from glibc, by Ulrich Drepper et al. + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#if !defined(USE_USBDK) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "poll_windows.h" +#include "windows_winusb.h" + +#define HANDLE_VALID(h) (((h) != 0) && ((h) != INVALID_HANDLE_VALUE)) + +// The 2 macros below are used in conjunction with safe loops. +#define LOOP_CHECK(fcall) \ + { \ + r = fcall; \ + if (r != LIBUSB_SUCCESS) \ + continue; \ + } +#define LOOP_BREAK(err) \ + { \ + r = err; \ + continue; \ + } + +// WinUSB-like API prototypes +static int winusbx_init(int sub_api, struct libusb_context *ctx); +static int winusbx_exit(int sub_api); +static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle); +static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle); +static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting); +static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint); +static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle); +static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); +// Composite API prototypes +static int composite_init(int sub_api, struct libusb_context *ctx); +static int composite_exit(int sub_api); +static int composite_open(int sub_api, struct libusb_device_handle *dev_handle); +static void composite_close(int sub_api, struct libusb_device_handle *dev_handle); +static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting); +static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer); +static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer); +static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer); +static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint); +static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer); +static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer); +static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle); +static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); + +#if defined(interface) +#undef interface +#endif + +// Global variables +int windows_version = WINDOWS_UNDEFINED; +static char windows_version_str[128] = "Undefined"; +// Concurrency +static int concurrent_usage = -1; +static usbi_mutex_t autoclaim_lock; +// API globals +#define CHECK_WINUSBX_AVAILABLE(sub_api) \ + do { \ + if (sub_api == SUB_API_NOTSET) \ + sub_api = priv->sub_api; \ + if (!WinUSBX[sub_api].initialized) \ + return LIBUSB_ERROR_ACCESS; \ + } while(0) + +static HMODULE WinUSBX_handle = NULL; +static struct winusb_interface WinUSBX[SUB_API_MAX]; +static const char *sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES; + +static bool api_hid_available = false; + +static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) +{ + if ((guid1 != NULL) && (guid2 != NULL)) + return (memcmp(guid1, guid2, sizeof(GUID)) == 0); + + return false; +} + +#if defined(ENABLE_LOGGING) +static char *guid_to_string(const GUID *guid) +{ + static char guid_string[MAX_GUID_STRING_LENGTH]; + + if (guid == NULL) + return NULL; + + sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + (unsigned int)guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); + + return guid_string; +} +#endif + +/* + * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes. + * Return an allocated sanitized string or NULL on error. + */ +static char *sanitize_path(const char *path) +{ + const char root_prefix[] = { '\\', '\\', '.', '\\' }; + size_t j, size; + char *ret_path; + size_t add_root = 0; + + if (path == NULL) + return NULL; + + size = strlen(path) + 1; + + // Microsoft indiscriminately uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes. + if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) + || ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) { + add_root = sizeof(root_prefix); + size += add_root; + } + + ret_path = malloc(size); + if (ret_path == NULL) + return NULL; + + strcpy(&ret_path[add_root], path); + + // Ensure consistency with root prefix + memcpy(ret_path, root_prefix, sizeof(root_prefix)); + + // Same goes for '\' and '#' after the root prefix. Ensure '#' is used + for (j = sizeof(root_prefix); j < size; j++) { + ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too + if (ret_path[j] == '\\') + ret_path[j] = '#'; + } + + return ret_path; +} + +/* + * Cfgmgr32, OLE32 and SetupAPI DLL functions + */ +static int init_dlls(void) +{ + DLL_GET_HANDLE(Cfgmgr32); + DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Parent, TRUE); + DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Child, TRUE); + DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Sibling, TRUE); + DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Device_IDA, TRUE); + + // Prefixed to avoid conflict with header files + DLL_GET_HANDLE(AdvAPI32); + DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExW, TRUE); + DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegCloseKey, TRUE); + + DLL_GET_HANDLE(Kernel32); + DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE); + + DLL_GET_HANDLE(OLE32); + DLL_LOAD_FUNC_PREFIXED(OLE32, p, CLSIDFromString, TRUE); + + DLL_GET_HANDLE(SetupAPI); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetClassDevsA, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInterfaces, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInterfaceDetailA, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiDestroyDeviceInfoList, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDevRegKey, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDeviceInterfaceRegKey, TRUE); + + return LIBUSB_SUCCESS; +} + +static void exit_dlls(void) +{ + DLL_FREE_HANDLE(Cfgmgr32); + DLL_FREE_HANDLE(AdvAPI32); + DLL_FREE_HANDLE(Kernel32); + DLL_FREE_HANDLE(OLE32); + DLL_FREE_HANDLE(SetupAPI); +} + +/* + * enumerate interfaces for the whole USB class + * + * Parameters: + * dev_info: a pointer to a dev_info list + * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed) + * usb_class: the generic USB class for which to retrieve interface details + * index: zero based index of the interface in the device info list + * + * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA + * structure returned and call this function repeatedly using the same guid (with an + * incremented index starting at zero) until all interfaces have been returned. + */ +static bool get_devinfo_data(struct libusb_context *ctx, + HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char *usb_class, unsigned _index) +{ + if (_index <= 0) { + *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); + if (*dev_info == INVALID_HANDLE_VALUE) + return false; + } + + dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); + if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "Could not obtain device info data for index %u: %s", + _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return false; + } + return true; +} + +/* + * enumerate interfaces for a specific GUID + * + * Parameters: + * dev_info: a pointer to a dev_info list + * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed) + * guid: the GUID for which to retrieve interface details + * index: zero based index of the interface in the device info list + * + * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA + * structure returned and call this function repeatedly using the same guid (with an + * incremented index starting at zero) until all interfaces have been returned. + */ +static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details(struct libusb_context *ctx, + HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID *guid, unsigned _index) +{ + SP_DEVICE_INTERFACE_DATA dev_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details; + DWORD size; + + if (_index <= 0) + *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); + + if (dev_info_data != NULL) { + dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); + if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "Could not obtain device info data for index %u: %s", + _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; + } + } + + dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "Could not obtain interface data for index %u: %s", + _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; + } + + // Read interface data (dummy + actual) to access the device path + if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { + // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + usbi_err(ctx, "could not access interface data (dummy) for index %u: %s", + _index, windows_error_str(0)); + goto err_exit; + } + } else { + usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong."); + goto err_exit; + } + + dev_interface_details = calloc(1, size); + if (dev_interface_details == NULL) { + usbi_err(ctx, "could not allocate interface data for index %u.", _index); + goto err_exit; + } + + dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, + dev_interface_details, size, &size, NULL)) { + usbi_err(ctx, "could not access interface data (actual) for index %u: %s", + _index, windows_error_str(0)); + } + + return dev_interface_details; + +err_exit: + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; +} + +/* For libusb0 filter */ +static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx, + HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID *guid, unsigned _index, char *filter_path) +{ + SP_DEVICE_INTERFACE_DATA dev_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details; + DWORD size; + + if (_index <= 0) + *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); + + if (dev_info_data != NULL) { + dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); + if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "Could not obtain device info data for index %u: %s", + _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; + } + } + + dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "Could not obtain interface data for index %u: %s", + _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; + } + + // Read interface data (dummy + actual) to access the device path + if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { + // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + usbi_err(ctx, "could not access interface data (dummy) for index %u: %s", + _index, windows_error_str(0)); + goto err_exit; + } + } else { + usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong."); + goto err_exit; + } + + dev_interface_details = calloc(1, size); + if (dev_interface_details == NULL) { + usbi_err(ctx, "could not allocate interface data for index %u.", _index); + goto err_exit; + } + + dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, dev_interface_details, size, &size, NULL)) + usbi_err(ctx, "could not access interface data (actual) for index %u: %s", + _index, windows_error_str(0)); + + // [trobinso] lookup the libusb0 symbolic index. + if (dev_interface_details) { + HKEY hkey_device_interface = pSetupDiOpenDeviceInterfaceRegKey(*dev_info, &dev_interface_data, 0, KEY_READ); + if (hkey_device_interface != INVALID_HANDLE_VALUE) { + DWORD libusb0_symboliclink_index = 0; + DWORD value_length = sizeof(DWORD); + DWORD value_type = 0; + LONG status; + + status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type, + (LPBYTE)&libusb0_symboliclink_index, &value_length); + if (status == ERROR_SUCCESS) { + if (libusb0_symboliclink_index < 256) { + // libusb0.sys is connected to this device instance. + // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter. + sprintf(filter_path, "\\\\.\\libusb0-%04u", (unsigned int)libusb0_symboliclink_index); + usbi_dbg("assigned libusb0 symbolic link %s", filter_path); + } else { + // libusb0.sys was connected to this device instance at one time; but not anymore. + } + } + pRegCloseKey(hkey_device_interface); + } + } + + return dev_interface_details; + +err_exit: + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; +} + +/* + * Returns the session ID of a device's nth level ancestor + * If there's no device at the nth level, return 0 + */ +static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level) +{ + DWORD parent_devinst; + unsigned long session_id; + char *sanitized_path; + char path[MAX_PATH_LENGTH]; + unsigned i; + + if (level < 1) + return 0; + + for (i = 0; i < level; i++) { + if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) + return 0; + devinst = parent_devinst; + } + + if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) + return 0; + + // TODO: (post hotplug): try without sanitizing + sanitized_path = sanitize_path(path); + if (sanitized_path == NULL) + return 0; + + session_id = htab_hash(sanitized_path); + free(sanitized_path); + return session_id; +} + +/* + * Determine which interface the given endpoint address belongs to + */ +static int get_interface_by_endpoint(struct libusb_config_descriptor *conf_desc, uint8_t ep) +{ + const struct libusb_interface *intf; + const struct libusb_interface_descriptor *intf_desc; + int i, j, k; + + for (i = 0; i < conf_desc->bNumInterfaces; i++) { + intf = &conf_desc->interface[i]; + for (j = 0; j < intf->num_altsetting; j++) { + intf_desc = &intf->altsetting[j]; + for (k = 0; k < intf_desc->bNumEndpoints; k++) { + if (intf_desc->endpoint[k].bEndpointAddress == ep) { + usbi_dbg("found endpoint %02X on interface %d", intf_desc->bInterfaceNumber, i); + return intf_desc->bInterfaceNumber; + } + } + } + } + + usbi_dbg("endpoint %02X not found on any interface", ep); + return LIBUSB_ERROR_NOT_FOUND; +} + +/* + * Populate the endpoints addresses of the device_priv interface helper structs + */ +static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + int i, r; + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + struct libusb_config_descriptor *conf_desc; + const struct libusb_interface_descriptor *if_desc; + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + + r = libusb_get_active_config_descriptor(dev_handle->dev, &conf_desc); + if (r != LIBUSB_SUCCESS) { + usbi_warn(ctx, "could not read config descriptor: error %d", r); + return r; + } + + if_desc = &conf_desc->interface[iface].altsetting[altsetting]; + safe_free(priv->usb_interface[iface].endpoint); + + if (if_desc->bNumEndpoints == 0) { + usbi_dbg("no endpoints found for interface %d", iface); + libusb_free_config_descriptor(conf_desc); + return LIBUSB_SUCCESS; + } + + priv->usb_interface[iface].endpoint = malloc(if_desc->bNumEndpoints); + if (priv->usb_interface[iface].endpoint == NULL) { + libusb_free_config_descriptor(conf_desc); + return LIBUSB_ERROR_NO_MEM; + } + + priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints; + for (i = 0; i < if_desc->bNumEndpoints; i++) { + priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress; + usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface); + } + libusb_free_config_descriptor(conf_desc); + + // Extra init may be required to configure endpoints + return priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface); +} + +// Lookup for a match in the list of API driver names +// return -1 if not found, driver match number otherwise +static int get_sub_api(char *driver, int api) +{ + int i; + const char sep_str[2] = {LIST_SEPARATOR, 0}; + char *tok, *tmp_str; + size_t len = strlen(driver); + + if (len == 0) + return SUB_API_NOTSET; + + tmp_str = _strdup(driver); + if (tmp_str == NULL) + return SUB_API_NOTSET; + + tok = strtok(tmp_str, sep_str); + while (tok != NULL) { + for (i = 0; i < usb_api_backend[api].nb_driver_names; i++) { + if (_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) { + free(tmp_str); + return i; + } + } + tok = strtok(NULL, sep_str); + } + + free(tmp_str); + return SUB_API_NOTSET; +} + +/* + * auto-claiming and auto-release helper functions + */ +static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type) +{ + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv( + transfer->dev_handle); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface = *interface_number; + int r = LIBUSB_SUCCESS; + + switch(api_type) { + case USB_API_WINUSBX: + break; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } + + usbi_mutex_lock(&autoclaim_lock); + if (current_interface < 0) { // No serviceable interface was found + for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) { + // Must claim an interface of the same API type + if ((priv->usb_interface[current_interface].apib->id == api_type) + && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS)) { + usbi_dbg("auto-claimed interface %d for control request", current_interface); + if (handle_priv->autoclaim_count[current_interface] != 0) + usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero"); + handle_priv->autoclaim_count[current_interface]++; + break; + } + } + if (current_interface == USB_MAXINTERFACES) { + usbi_err(ctx, "could not auto-claim any interface"); + r = LIBUSB_ERROR_NOT_FOUND; + } + } else { + // If we have a valid interface that was autoclaimed, we must increment + // its autoclaim count so that we can prevent an early release. + if (handle_priv->autoclaim_count[current_interface] != 0) + handle_priv->autoclaim_count[current_interface]++; + } + usbi_mutex_unlock(&autoclaim_lock); + + *interface_number = current_interface; + return r; +} + +static void auto_release(struct usbi_transfer *itransfer) +{ + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + libusb_device_handle *dev_handle = transfer->dev_handle; + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + int r; + + usbi_mutex_lock(&autoclaim_lock); + if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) { + handle_priv->autoclaim_count[transfer_priv->interface_number]--; + if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) { + r = libusb_release_interface(dev_handle, transfer_priv->interface_number); + if (r == LIBUSB_SUCCESS) + usbi_dbg("auto-released interface %d", transfer_priv->interface_number); + else + usbi_dbg("failed to auto-release interface %d (%s)", + transfer_priv->interface_number, libusb_error_name((enum libusb_error)r)); + } + } + usbi_mutex_unlock(&autoclaim_lock); +} + +/* Windows version dtection */ +static BOOL is_x64(void) +{ + BOOL ret = FALSE; + + // Detect if we're running a 32 or 64 bit system + if (sizeof(uintptr_t) < 8) { + if (pIsWow64Process != NULL) + pIsWow64Process(GetCurrentProcess(), &ret); + } else { + ret = TRUE; + } + + return ret; +} + +static void get_windows_version(void) +{ + OSVERSIONINFOEXA vi, vi2; + const char *arch, *w = NULL; + unsigned major, minor; + ULONGLONG major_equal, minor_equal; + BOOL ws; + + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(vi); + if (!GetVersionExA((OSVERSIONINFOA *)&vi)) { + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!GetVersionExA((OSVERSIONINFOA *)&vi)) + return; + } + + if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) { + if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) { + // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version + // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx + + major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); + for (major = vi.dwMajorVersion; major <= 9; major++) { + memset(&vi2, 0, sizeof(vi2)); + vi2.dwOSVersionInfoSize = sizeof(vi2); + vi2.dwMajorVersion = major; + if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal)) + continue; + + if (vi.dwMajorVersion < major) { + vi.dwMajorVersion = major; + vi.dwMinorVersion = 0; + } + + minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL); + for (minor = vi.dwMinorVersion; minor <= 9; minor++) { + memset(&vi2, 0, sizeof(vi2)); + vi2.dwOSVersionInfoSize = sizeof(vi2); + vi2.dwMinorVersion = minor; + if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal)) + continue; + + vi.dwMinorVersion = minor; + break; + } + + break; + } + } + + if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) { + ws = (vi.wProductType <= VER_NT_WORKSTATION); + windows_version = vi.dwMajorVersion << 4 | vi.dwMinorVersion; + switch (windows_version) { + case 0x50: w = "2000"; break; + case 0x51: w = "XP"; break; + case 0x52: w = "2003"; break; + case 0x60: w = (ws ? "Vista" : "2008"); break; + case 0x61: w = (ws ? "7" : "2008_R2"); break; + case 0x62: w = (ws ? "8" : "2012"); break; + case 0x63: w = (ws ? "8.1" : "2012_R2"); break; + case 0x64: w = (ws ? "10" : "2015"); break; + default: + if (windows_version < 0x50) + windows_version = WINDOWS_UNSUPPORTED; + else + w = "11 or later"; + break; + } + } + } + + arch = is_x64() ? "64-bit" : "32-bit"; + + if (w == NULL) + snprintf(windows_version_str, sizeof(windows_version_str), "%s %u.%u %s", + (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"), + (unsigned int)vi.dwMajorVersion, (unsigned int)vi.dwMinorVersion, arch); + else if (vi.wServicePackMinor) + snprintf(windows_version_str, sizeof(windows_version_str), "%s SP%u.%u %s", + w, vi.wServicePackMajor, vi.wServicePackMinor, arch); + else if (vi.wServicePackMajor) + snprintf(windows_version_str, sizeof(windows_version_str), "%s SP%u %s", + w, vi.wServicePackMajor, arch); + else + snprintf(windows_version_str, sizeof(windows_version_str), "%s %s", + w, arch); +} + +/* + * init: libusb backend init function + * + * This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list + * In our implementation, we equate Windows' "HCD" to libusb's "bus". Note that bus is zero indexed. + * HCDs are not expected to change after init (might not hold true for hot pluggable USB PCI card?) + */ +static int windows_init(struct libusb_context *ctx) +{ + int i, r = LIBUSB_ERROR_OTHER; + HANDLE semaphore; + char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + + sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name); + if (semaphore == NULL) { + usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_MEM; + } + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore's release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0)); + CloseHandle(semaphore); + return LIBUSB_ERROR_NO_MEM; + } + + // NB: concurrent usage supposes that init calls are equally balanced with + // exit calls. If init is called more than exit, we will not exit properly + if (++concurrent_usage == 0) { // First init? + get_windows_version(); + usbi_dbg("Windows %s", windows_version_str); + + if (windows_version == WINDOWS_UNSUPPORTED) { + usbi_err(ctx, "This version of Windows is NOT supported"); + r = LIBUSB_ERROR_NOT_SUPPORTED; + goto init_exit; + } + + // We need a lock for proper auto-release + usbi_mutex_init(&autoclaim_lock); + + // Initialize pollable file descriptors + init_polling(); + + // Load DLL imports + if (init_dlls() != LIBUSB_SUCCESS) { + usbi_err(ctx, "could not resolve DLL functions"); + goto init_exit; + } + + // Initialize the low level APIs (we don't care about errors at this stage) + for (i = 0; i < USB_API_MAX; i++) + usb_api_backend[i].init(SUB_API_NOTSET, ctx); + + r = windows_common_init(ctx); + if (r) + goto init_exit; + } + // At this stage, either we went through full init successfully, or didn't need to + r = LIBUSB_SUCCESS; + +init_exit: // Holds semaphore here. + if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed? + for (i = 0; i < USB_API_MAX; i++) + usb_api_backend[i].exit(SUB_API_NOTSET); + exit_dlls(); + exit_polling(); + windows_common_exit(); + usbi_mutex_destroy(&autoclaim_lock); + } + + if (r != LIBUSB_SUCCESS) + --concurrent_usage; // Not expected to call libusb_exit if we failed. + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); + return r; +} + +/* + * HCD (root) hubs need to have their device descriptor manually populated + * + * Note that, like Microsoft does in the device manager, we populate the + * Vendor and Device ID for HCD hubs with the ones from the PCI HCD device. + */ +static int force_hcd_device_descriptor(struct libusb_device *dev) +{ + struct windows_device_priv *parent_priv, *priv = _device_priv(dev); + struct libusb_context *ctx = DEVICE_CTX(dev); + int vid, pid; + + dev->num_configurations = 1; + priv->dev_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR); + priv->dev_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE; + priv->dev_descriptor.bNumConfigurations = 1; + priv->active_config = 1; + + if (dev->parent_dev == NULL) { + usbi_err(ctx, "program assertion failed - HCD hub has no parent"); + return LIBUSB_ERROR_NO_DEVICE; + } + + parent_priv = _device_priv(dev->parent_dev); + if (sscanf(parent_priv->path, "\\\\.\\PCI#VEN_%04x&DEV_%04x%*s", &vid, &pid) == 2) { + priv->dev_descriptor.idVendor = (uint16_t)vid; + priv->dev_descriptor.idProduct = (uint16_t)pid; + } else { + usbi_warn(ctx, "could not infer VID/PID of HCD hub from '%s'", parent_priv->path); + priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub + priv->dev_descriptor.idProduct = 1; + } + + return LIBUSB_SUCCESS; +} + +/* + * fetch and cache all the config descriptors through I/O + */ +static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle, char *device_id) +{ + DWORD size, ret_size; + struct libusb_context *ctx = DEVICE_CTX(dev); + struct windows_device_priv *priv = _device_priv(dev); + int r; + uint8_t i; + + USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request + PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request + PUSB_CONFIGURATION_DESCRIPTOR cd_data = NULL; + + if (dev->num_configurations == 0) + return LIBUSB_ERROR_INVALID_PARAM; + + priv->config_descriptor = calloc(dev->num_configurations, sizeof(unsigned char *)); + if (priv->config_descriptor == NULL) + return LIBUSB_ERROR_NO_MEM; + + for (i = 0; i < dev->num_configurations; i++) + priv->config_descriptor[i] = NULL; + + for (i = 0, r = LIBUSB_SUCCESS; ; i++) { + // safe loop: release all dynamic resources + safe_free(cd_buf_actual); + + // safe loop: end of loop condition + if ((i >= dev->num_configurations) || (r != LIBUSB_SUCCESS)) + break; + + size = sizeof(USB_CONFIGURATION_DESCRIPTOR_SHORT); + memset(&cd_buf_short, 0, size); + + cd_buf_short.req.ConnectionIndex = (ULONG)priv->port; + cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN; + cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; + cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i; + cd_buf_short.req.SetupPacket.wIndex = 0; + cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST)); + + // Dummy call to get the required data size. Initial failures are reported as info rather + // than error as they can occur for non-penalizing situations, such as with some hubs. + // coverity[tainted_data_argument] + if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size, + &cd_buf_short, size, &ret_size, NULL)) { + usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0)); + LOOP_BREAK(LIBUSB_ERROR_IO); + } + + if ((ret_size != size) || (cd_buf_short.data.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) { + usbi_info(ctx, "unexpected configuration descriptor size (dummy) for '%s'.", device_id); + LOOP_BREAK(LIBUSB_ERROR_IO); + } + + size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.data.wTotalLength; + cd_buf_actual = calloc(1, size); + if (cd_buf_actual == NULL) { + usbi_err(ctx, "could not allocate configuration descriptor buffer for '%s'.", device_id); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } + + // Actual call + cd_buf_actual->ConnectionIndex = (ULONG)priv->port; + cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN; + cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; + cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i; + cd_buf_actual->SetupPacket.wIndex = 0; + cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST)); + + if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size, + cd_buf_actual, size, &ret_size, NULL)) { + usbi_err(ctx, "could not access configuration descriptor (actual) for '%s': %s", device_id, windows_error_str(0)); + LOOP_BREAK(LIBUSB_ERROR_IO); + } + + cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR *)cd_buf_actual + sizeof(USB_DESCRIPTOR_REQUEST)); + + if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.data.wTotalLength)) { + usbi_err(ctx, "unexpected configuration descriptor size (actual) for '%s'.", device_id); + LOOP_BREAK(LIBUSB_ERROR_IO); + } + + if (cd_data->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE) { + usbi_err(ctx, "not a configuration descriptor for '%s'", device_id); + LOOP_BREAK(LIBUSB_ERROR_IO); + } + + usbi_dbg("cached config descriptor %d (bConfigurationValue=%u, %u bytes)", + i, cd_data->bConfigurationValue, cd_data->wTotalLength); + + // Cache the descriptor + priv->config_descriptor[i] = malloc(cd_data->wTotalLength); + if (priv->config_descriptor[i] == NULL) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength); + } + return LIBUSB_SUCCESS; +} + +/* + * Populate a libusb device structure + */ +static int init_device(struct libusb_device *dev, struct libusb_device *parent_dev, + uint8_t port_number, char *device_id, DWORD devinst) +{ + HANDLE handle; + DWORD size; + USB_NODE_CONNECTION_INFORMATION_EX conn_info; + USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2; + struct windows_device_priv *priv, *parent_priv; + struct libusb_context *ctx; + struct libusb_device *tmp_dev; + unsigned long tmp_id; + unsigned i; + + if ((dev == NULL) || (parent_dev == NULL)) + return LIBUSB_ERROR_NOT_FOUND; + + ctx = DEVICE_CTX(dev); + priv = _device_priv(dev); + parent_priv = _device_priv(parent_dev); + if (parent_priv->apib->id != USB_API_HUB) { + usbi_warn(ctx, "parent for device '%s' is not a hub", device_id); + return LIBUSB_ERROR_NOT_FOUND; + } + + // It is possible for the parent hub not to have been initialized yet + // If that's the case, lookup the ancestors to set the bus number + if (parent_dev->bus_number == 0) { + for (i = 2; ; i++) { + tmp_id = get_ancestor_session_id(devinst, i); + if (tmp_id == 0) + break; + + tmp_dev = usbi_get_device_by_session_id(ctx, tmp_id); + if (tmp_dev == NULL) + continue; + + if (tmp_dev->bus_number != 0) { + usbi_dbg("got bus number from ancestor #%u", i); + parent_dev->bus_number = tmp_dev->bus_number; + libusb_unref_device(tmp_dev); + break; + } + + libusb_unref_device(tmp_dev); + } + } + + if (parent_dev->bus_number == 0) { + usbi_err(ctx, "program assertion failed: unable to find ancestor bus number for '%s'", device_id); + return LIBUSB_ERROR_NOT_FOUND; + } + + dev->bus_number = parent_dev->bus_number; + priv->port = port_number; + dev->port_number = port_number; + priv->depth = parent_priv->depth + 1; + dev->parent_dev = parent_dev; + + // If the device address is already set, we can stop here + if (dev->device_address != 0) + return LIBUSB_SUCCESS; + + memset(&conn_info, 0, sizeof(conn_info)); + if (priv->depth != 0) { // Not a HCD hub + handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + if (handle == INVALID_HANDLE_VALUE) { + usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0)); + return LIBUSB_ERROR_ACCESS; + } + + size = sizeof(conn_info); + conn_info.ConnectionIndex = (ULONG)port_number; + // coverity[tainted_data_argument] + if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size, + &conn_info, size, &size, NULL)) { + usbi_warn(ctx, "could not get node connection information for device '%s': %s", + device_id, windows_error_str(0)); + CloseHandle(handle); + return LIBUSB_ERROR_NO_DEVICE; + } + + if (conn_info.ConnectionStatus == NoDeviceConnected) { + usbi_err(ctx, "device '%s' is no longer connected!", device_id); + CloseHandle(handle); + return LIBUSB_ERROR_NO_DEVICE; + } + + memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR)); + dev->num_configurations = priv->dev_descriptor.bNumConfigurations; + priv->active_config = conn_info.CurrentConfigurationValue; + usbi_dbg("found %u configurations (active conf: %u)", dev->num_configurations, priv->active_config); + + // If we can't read the config descriptors, just set the number of confs to zero + if (cache_config_descriptors(dev, handle, device_id) != LIBUSB_SUCCESS) { + dev->num_configurations = 0; + priv->dev_descriptor.bNumConfigurations = 0; + } + + // In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8 + if (windows_version >= WINDOWS_8) { + memset(&conn_info_v2, 0, sizeof(conn_info_v2)); + size = sizeof(conn_info_v2); + conn_info_v2.ConnectionIndex = (ULONG)port_number; + conn_info_v2.Length = size; + conn_info_v2.SupportedUsbProtocols.Usb300 = 1; + if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, + &conn_info_v2, size, &conn_info_v2, size, &size, NULL)) { + usbi_warn(ctx, "could not get node connection information (V2) for device '%s': %s", + device_id, windows_error_str(0)); + } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) { + conn_info.Speed = 3; + } + } + + CloseHandle(handle); + + if (conn_info.DeviceAddress > UINT8_MAX) + usbi_err(ctx, "program assertion failed: device address overflow"); + + dev->device_address = (uint8_t)conn_info.DeviceAddress + 1; + if (dev->device_address == 1) + usbi_err(ctx, "program assertion failed: device address collision with root hub"); + + switch (conn_info.Speed) { + case 0: dev->speed = LIBUSB_SPEED_LOW; break; + case 1: dev->speed = LIBUSB_SPEED_FULL; break; + case 2: dev->speed = LIBUSB_SPEED_HIGH; break; + case 3: dev->speed = LIBUSB_SPEED_SUPER; break; + default: + usbi_warn(ctx, "Got unknown device speed %u", conn_info.Speed); + break; + } + } else { + dev->device_address = 1; // root hubs are set to use device number 1 + force_hcd_device_descriptor(dev); + } + + usbi_sanitize_device(dev); + + usbi_dbg("(bus: %u, addr: %u, depth: %u, port: %u): '%s'", + dev->bus_number, dev->device_address, priv->depth, priv->port, device_id); + + return LIBUSB_SUCCESS; +} + +// Returns the api type, or 0 if not found/unsupported +static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info, + SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api) +{ + // Precedence for filter drivers vs driver is in the order of this array + struct driver_lookup lookup[3] = { + {"\0\0", SPDRP_SERVICE, "driver"}, + {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"}, + {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"} + }; + DWORD size, reg_type; + unsigned k, l; + int i, j; + + *api = USB_API_UNSUPPORTED; + *sub_api = SUB_API_NOTSET; + + // Check the service & filter names to know the API we should use + for (k = 0; k < 3; k++) { + if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop, + ®_type, (BYTE *)lookup[k].list, MAX_KEY_LENGTH, &size)) { + // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ + if (lookup[k].reg_prop == SPDRP_SERVICE) + // our buffers are MAX_KEY_LENGTH + 1 so we can overflow if needed + lookup[k].list[strlen(lookup[k].list) + 1] = 0; + + // MULTI_SZ is a pain to work with. Turn it into something much more manageable + // NB: none of the driver names we check against contain LIST_SEPARATOR, + // (currently ';'), so even if an unsuported one does, it's not an issue + for (l = 0; (lookup[k].list[l] != 0) || (lookup[k].list[l + 1] != 0); l++) { + if (lookup[k].list[l] == 0) + lookup[k].list[l] = LIST_SEPARATOR; + } + usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list); + } else { + if (GetLastError() != ERROR_INVALID_DATA) + usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0)); + lookup[k].list[0] = 0; + } + } + + for (i = 1; i < USB_API_MAX; i++) { + for (k = 0; k < 3; k++) { + j = get_sub_api(lookup[k].list, i); + if (j >= 0) { + usbi_dbg("matched %s name against %s", lookup[k].designation, + (i != USB_API_WINUSBX) ? usb_api_backend[i].designation : sub_api_name[j]); + *api = i; + *sub_api = j; + return; + } + } + } +} + +static int set_composite_interface(struct libusb_context *ctx, struct libusb_device *dev, + char *dev_interface_path, char *device_id, int api, int sub_api) +{ + unsigned i; + struct windows_device_priv *priv = _device_priv(dev); + int interface_number; + + if (priv->apib->id != USB_API_COMPOSITE) { + usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id); + return LIBUSB_ERROR_NO_DEVICE; + } + + // Because MI_## are not necessarily in sequential order (some composite + // devices will have only MI_00 & MI_03 for instance), we retrieve the actual + // interface number from the path's MI value + interface_number = 0; + for (i = 0; device_id[i] != 0; ) { + if ((device_id[i++] == 'M') && (device_id[i++] == 'I') + && (device_id[i++] == '_')) { + interface_number = (device_id[i++] - '0') * 10; + interface_number += device_id[i] - '0'; + break; + } + } + + if (device_id[i] == 0) + usbi_warn(ctx, "failure to read interface number for %s. Using default value %d", + device_id, interface_number); + + if (priv->usb_interface[interface_number].path != NULL) { + if (api == USB_API_HID) { + // HID devices can have multiple collections (COL##) for each MI_## interface + usbi_dbg("interface[%d] already set - ignoring HID collection: %s", + interface_number, device_id); + return LIBUSB_ERROR_ACCESS; + } + // In other cases, just use the latest data + safe_free(priv->usb_interface[interface_number].path); + } + + usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path); + priv->usb_interface[interface_number].path = dev_interface_path; + priv->usb_interface[interface_number].apib = &usb_api_backend[api]; + priv->usb_interface[interface_number].sub_api = sub_api; + if ((api == USB_API_HID) && (priv->hid == NULL)) { + priv->hid = calloc(1, sizeof(struct hid_device_priv)); + if (priv->hid == NULL) + return LIBUSB_ERROR_NO_MEM; + } + + return LIBUSB_SUCCESS; +} + +/* + * get_device_list: libusb backend device enumeration function + */ +static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs) +{ + struct discovered_devs *discdevs; + HDEVINFO dev_info = { 0 }; + const char *usb_class[] = {"USB", "NUSB3", "IUSB3", "IARUSB3"}; + SP_DEVINFO_DATA dev_info_data = { 0 }; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL; +#define MAX_ENUM_GUIDS 64 + const GUID *guid[MAX_ENUM_GUIDS]; +#define HCD_PASS 0 +#define HUB_PASS 1 +#define GEN_PASS 2 +#define DEV_PASS 3 + int r = LIBUSB_SUCCESS; + int api, sub_api; + size_t class_index = 0; + unsigned int nb_guids, pass, i, j, ancestor; + char path[MAX_PATH_LENGTH]; + char strbuf[MAX_PATH_LENGTH]; + struct libusb_device *dev, *parent_dev; + struct windows_device_priv *priv, *parent_priv; + char *dev_interface_path = NULL; + char *dev_id_path = NULL; + unsigned long session_id; + DWORD size, reg_type, port_nr, install_state; + HKEY key; + WCHAR guid_string_w[MAX_GUID_STRING_LENGTH]; + GUID *if_guid; + LONG s; + // Keep a list of newly allocated devs to unref + libusb_device **unref_list, **new_unref_list; + unsigned int unref_size = 64; + unsigned int unref_cur = 0; + + // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug) + // PASS 2 : (re)enumerate HUBS + // PASS 3 : (re)enumerate generic USB devices (including driverless) + // and list additional USB device interface GUIDs to explore + // PASS 4 : (re)enumerate master USB devices that have a device interface + // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and + // set the device interfaces. + + // Init the GUID table + guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER; + guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB; + guid[GEN_PASS] = NULL; + guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE; + nb_guids = DEV_PASS + 1; + + unref_list = calloc(unref_size, sizeof(libusb_device *)); + if (unref_list == NULL) + return LIBUSB_ERROR_NO_MEM; + + for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) { +//#define ENUM_DEBUG +#if defined(ENABLE_LOGGING) && defined(ENUM_DEBUG) + const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" }; + usbi_dbg("#### PROCESSING %ss %s", passname[(pass <= HID_PASS) ? pass : (HID_PASS + 1)], + (pass != GEN_PASS) ? guid_to_string(guid[pass]) : ""); +#endif + for (i = 0; ; i++) { + // safe loop: free up any (unprotected) dynamic resource + // NB: this is always executed before breaking the loop + safe_free(dev_interface_details); + safe_free(dev_interface_path); + safe_free(dev_id_path); + priv = parent_priv = NULL; + dev = parent_dev = NULL; + + // Safe loop: end of loop conditions + if (r != LIBUSB_SUCCESS) + break; + + if ((pass == HCD_PASS) && (i == UINT8_MAX)) { + usbi_warn(ctx, "program assertion failed - found more than %d buses, skipping the rest.", UINT8_MAX); + break; + } + + if (pass != GEN_PASS) { + // Except for GEN, all passes deal with device interfaces + dev_interface_details = get_interface_details(ctx, &dev_info, &dev_info_data, guid[pass], i); + if (dev_interface_details == NULL) + break; + + dev_interface_path = sanitize_path(dev_interface_details->DevicePath); + if (dev_interface_path == NULL) { + usbi_warn(ctx, "could not sanitize device interface path for '%s'", dev_interface_details->DevicePath); + continue; + } + } else { + // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are + // being listed under the "NUSB3" PnP Symbolic Name rather than "USB". + // The Intel USB 3.0 driver behaves similar, but uses "IUSB3" + // The Intel Alpine Ridge USB 3.1 driver uses "IARUSB3" + for (; class_index < ARRAYSIZE(usb_class); class_index++) { + if (get_devinfo_data(ctx, &dev_info, &dev_info_data, usb_class[class_index], i)) + break; + i = 0; + } + if (class_index >= ARRAYSIZE(usb_class)) + break; + } + + // Read the Device ID path. This is what we'll use as UID + // Note that if the device is plugged in a different port or hub, the Device ID changes + if (CM_Get_Device_IDA(dev_info_data.DevInst, path, sizeof(path), 0) != CR_SUCCESS) { + usbi_warn(ctx, "could not read the device id path for devinst %X, skipping", + (unsigned int)dev_info_data.DevInst); + continue; + } + + dev_id_path = sanitize_path(path); + if (dev_id_path == NULL) { + usbi_warn(ctx, "could not sanitize device id path for devinst %X, skipping", + (unsigned int)dev_info_data.DevInst); + continue; + } +#ifdef ENUM_DEBUG + usbi_dbg("PRO: %s", dev_id_path); +#endif + + // The SPDRP_ADDRESS for USB devices is the device port number on the hub + port_nr = 0; + if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) { + if ((!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS, + ®_type, (BYTE *)&port_nr, 4, &size)) || (size != 4)) { + usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s", + dev_id_path, windows_error_str(0)); + continue; + } + } + + // Set API to use or get additional data from generic pass + api = USB_API_UNSUPPORTED; + sub_api = SUB_API_NOTSET; + switch (pass) { + case HCD_PASS: + break; + case GEN_PASS: + // We use the GEN pass to detect driverless devices... + size = sizeof(strbuf); + if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER, + ®_type, (BYTE *)strbuf, size, &size)) { + usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path); + usbi_info(ctx, "libusb will not be able to access it."); + } + // ...and to add the additional device interface GUIDs + key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + if (key != INVALID_HANDLE_VALUE) { + size = sizeof(guid_string_w); + s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type, + (BYTE *)guid_string_w, &size); + pRegCloseKey(key); + if (s == ERROR_SUCCESS) { + if (nb_guids >= MAX_ENUM_GUIDS) { + // If this assert is ever reported, grow a GUID table dynamically + usbi_err(ctx, "program assertion failed: too many GUIDs"); + LOOP_BREAK(LIBUSB_ERROR_OVERFLOW); + } + if_guid = calloc(1, sizeof(GUID)); + if (if_guid == NULL) { + usbi_err(ctx, "could not calloc for if_guid: not enough memory"); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } + pCLSIDFromString(guid_string_w, if_guid); + guid[nb_guids++] = if_guid; + usbi_dbg("extra GUID: %s", guid_to_string(if_guid)); + } + } + break; + default: + // Get the API type (after checking that the driver installation is OK) + if ((!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE, + ®_type, (BYTE *)&install_state, 4, &size)) || (size != 4)) { + usbi_warn(ctx, "could not detect installation state of driver for '%s': %s", + dev_id_path, windows_error_str(0)); + } else if (install_state != 0) { + usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %u) - skipping", + dev_id_path, (unsigned int)install_state); + continue; + } + get_api_type(ctx, &dev_info, &dev_info_data, &api, &sub_api); + break; + } + + // Find parent device (for the passes that need it) + switch (pass) { + case HCD_PASS: + case DEV_PASS: + case HUB_PASS: + break; + default: + // Go through the ancestors until we see a face we recognize + parent_dev = NULL; + for (ancestor = 1; parent_dev == NULL; ancestor++) { + session_id = get_ancestor_session_id(dev_info_data.DevInst, ancestor); + if (session_id == 0) + break; + + parent_dev = usbi_get_device_by_session_id(ctx, session_id); + } + + if (parent_dev == NULL) { + usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path); + continue; + } + + parent_priv = _device_priv(parent_dev); + // virtual USB devices are also listed during GEN - don't process these yet + if ((pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB)) { + libusb_unref_device(parent_dev); + continue; + } + + break; + } + + // Create new or match existing device, using the (hashed) device_id as session id + if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent + // These are the passes that create "new" devices + session_id = htab_hash(dev_id_path); + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev == NULL) { + if (pass == DEV_PASS) { + // This can occur if the OS only reports a newly plugged device after we started enum + usbi_warn(ctx, "'%s' was only detected in late pass (newly connected device?)" + " - ignoring", dev_id_path); + continue; + } + + usbi_dbg("allocating new device for session [%lX]", session_id); + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + + priv = windows_device_priv_init(dev); + } else { + usbi_dbg("found existing device for session [%lX] (%u.%u)", + session_id, dev->bus_number, dev->device_address); + + priv = _device_priv(dev); + if ((parent_dev != NULL) && (dev->parent_dev != NULL)) { + if (dev->parent_dev != parent_dev) { + // It is possible for the actual parent device to not have existed at the + // time of enumeration, so the currently assigned parent may in fact be a + // grandparent. If the devices differ, we assume the "new" parent device + // is in fact closer to the device. + usbi_dbg("updating parent device [session %lX -> %lX]", + dev->parent_dev->session_data, parent_dev->session_data); + libusb_unref_device(dev->parent_dev); + dev->parent_dev = parent_dev; + } else { + // We hold a reference to parent_dev instance, but this device already + // has a parent_dev reference (only one per child) + libusb_unref_device(parent_dev); + } + } + } + + // Keep track of devices that need unref + unref_list[unref_cur++] = dev; + if (unref_cur >= unref_size) { + unref_size += 64; + new_unref_list = usbi_reallocf(unref_list, unref_size * sizeof(libusb_device *)); + if (new_unref_list == NULL) { + usbi_err(ctx, "could not realloc list for unref - aborting."); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } else { + unref_list = new_unref_list; + } + } + } + + // Setup device + switch (pass) { + case HCD_PASS: + // If the hcd has already been setup, don't do it again + if (priv->path != NULL) + break; + dev->bus_number = (uint8_t)(i + 1); // bus 0 is reserved for disconnected + dev->device_address = 0; + dev->num_configurations = 0; + priv->apib = &usb_api_backend[USB_API_HUB]; + priv->sub_api = SUB_API_NOTSET; + priv->depth = UINT8_MAX; // Overflow to 0 for HCD Hubs + priv->path = dev_interface_path; + dev_interface_path = NULL; + break; + case HUB_PASS: + case DEV_PASS: + // If the device has already been setup, don't do it again + if (priv->path != NULL) + break; + // Take care of API initialization + priv->path = dev_interface_path; + dev_interface_path = NULL; + priv->apib = &usb_api_backend[api]; + priv->sub_api = sub_api; + switch(api) { + case USB_API_COMPOSITE: + case USB_API_HUB: + break; + case USB_API_HID: + priv->hid = calloc(1, sizeof(struct hid_device_priv)); + if (priv->hid == NULL) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + + priv->hid->nb_interfaces = 0; + break; + default: + // For other devices, the first interface is the same as the device + priv->usb_interface[0].path = _strdup(priv->path); + if (priv->usb_interface[0].path == NULL) + usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path); + // The following is needed if we want API calls to work for both simple + // and composite devices. + for (j = 0; j < USB_MAXINTERFACES; j++) + priv->usb_interface[j].apib = &usb_api_backend[api]; + + break; + } + break; + case GEN_PASS: + r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_id_path, dev_info_data.DevInst); + if (r == LIBUSB_SUCCESS) { + // Append device to the list of discovered devices + discdevs = discovered_devs_append(*_discdevs, dev); + if (!discdevs) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + + *_discdevs = discdevs; + } else if (r == LIBUSB_ERROR_NO_DEVICE) { + // This can occur if the device was disconnected but Windows hasn't + // refreshed its enumeration yet - in that case, we ignore the device + r = LIBUSB_SUCCESS; + } + break; + default: // HID_PASS and later + if (parent_priv->apib->id == USB_API_HID || parent_priv->apib->id == USB_API_COMPOSITE) { + { + usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data); + r = set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api); + } + switch (r) { + case LIBUSB_SUCCESS: + dev_interface_path = NULL; + break; + case LIBUSB_ERROR_ACCESS: + // interface has already been set => make sure dev_interface_path is freed then + r = LIBUSB_SUCCESS; + break; + default: + LOOP_BREAK(r); + break; + } + } + libusb_unref_device(parent_dev); + break; + } + } + } + + // Free any additional GUIDs + for (pass = DEV_PASS + 1; pass < nb_guids; pass++) + free((void *)guid[pass]); + + // Unref newly allocated devs + for (i = 0; i < unref_cur; i++) + libusb_unref_device(unref_list[i]); + free(unref_list); + + return r; +} + +/* + * exit: libusb backend deinitialization function + */ +static void windows_exit(void) +{ + int i; + HANDLE semaphore; + char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + + sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name); + if (semaphore == NULL) + return; + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + CloseHandle(semaphore); + return; + } + + // Only works if exits and inits are balanced exactly + if (--concurrent_usage < 0) { // Last exit + for (i = 0; i < USB_API_MAX; i++) + usb_api_backend[i].exit(SUB_API_NOTSET); + exit_dlls(); + exit_polling(); + windows_common_exit(); + usbi_mutex_destroy(&autoclaim_lock); + } + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); +} + +static int windows_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) +{ + struct windows_device_priv *priv = _device_priv(dev); + + memcpy(buffer, &priv->dev_descriptor, DEVICE_DESC_LENGTH); + *host_endian = 0; + + return LIBUSB_SUCCESS; +} + +static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + struct windows_device_priv *priv = _device_priv(dev); + PUSB_CONFIGURATION_DESCRIPTOR config_header; + size_t size; + + // config index is zero based + if (config_index >= dev->num_configurations) + return LIBUSB_ERROR_INVALID_PARAM; + + if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL)) + return LIBUSB_ERROR_NOT_FOUND; + + config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index]; + + size = MIN(config_header->wTotalLength, len); + memcpy(buffer, priv->config_descriptor[config_index], size); + *host_endian = 0; + + return (int)size; +} + +static int windows_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue, + unsigned char **buffer, int *host_endian) +{ + struct windows_device_priv *priv = _device_priv(dev); + PUSB_CONFIGURATION_DESCRIPTOR config_header; + uint8_t index; + + *buffer = NULL; + *host_endian = 0; + + if (priv->config_descriptor == NULL) + return LIBUSB_ERROR_NOT_FOUND; + + for (index = 0; index < dev->num_configurations; index++) { + config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[index]; + if (config_header->bConfigurationValue == bConfigurationValue) { + *buffer = priv->config_descriptor[index]; + return (int)config_header->wTotalLength; + } + } + + return LIBUSB_ERROR_NOT_FOUND; +} + +/* + * return the cached copy of the active config descriptor + */ +static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) +{ + struct windows_device_priv *priv = _device_priv(dev); + unsigned char *config_desc; + int r; + + if (priv->active_config == 0) + return LIBUSB_ERROR_NOT_FOUND; + + r = windows_get_config_descriptor_by_value(dev, priv->active_config, &config_desc, host_endian); + if (r < 0) + return r; + + len = MIN((size_t)r, len); + memcpy(buffer, config_desc, len); + return (int)len; +} + +static int windows_open(struct libusb_device_handle *dev_handle) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + + if (priv->apib == NULL) { + usbi_err(ctx, "program assertion failed - device is not initialized"); + return LIBUSB_ERROR_NO_DEVICE; + } + + return priv->apib->open(SUB_API_NOTSET, dev_handle); +} + +static void windows_close(struct libusb_device_handle *dev_handle) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + priv->apib->close(SUB_API_NOTSET, dev_handle); +} + +static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + if (priv->active_config == 0) { + *config = 0; + return LIBUSB_ERROR_NOT_FOUND; + } + + *config = priv->active_config; + return LIBUSB_SUCCESS; +} + +/* + * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver + * does not currently expose a service that allows higher-level drivers to set + * the configuration." + */ +static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + int r = LIBUSB_SUCCESS; + + if (config >= USB_MAXCONFIG) + return LIBUSB_ERROR_INVALID_PARAM; + + r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT | + LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, + LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config, + 0, NULL, 0, 1000); + + if (r == LIBUSB_SUCCESS) + priv->active_config = (uint8_t)config; + + return r; +} + +static int windows_claim_interface(struct libusb_device_handle *dev_handle, int iface) +{ + int r = LIBUSB_SUCCESS; + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + safe_free(priv->usb_interface[iface].endpoint); + priv->usb_interface[iface].nb_endpoints = 0; + + r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface); + + if (r == LIBUSB_SUCCESS) + r = windows_assign_endpoints(dev_handle, iface, 0); + + return r; +} + +static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + int r = LIBUSB_SUCCESS; + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + safe_free(priv->usb_interface[iface].endpoint); + priv->usb_interface[iface].nb_endpoints = 0; + + r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting); + + if (r == LIBUSB_SUCCESS) + r = windows_assign_endpoints(dev_handle, iface, altsetting); + + return r; +} + +static int windows_release_interface(struct libusb_device_handle *dev_handle, int iface) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface); +} + +static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint); +} + +static int windows_reset_device(struct libusb_device_handle *dev_handle) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + return priv->apib->reset_device(SUB_API_NOTSET, dev_handle); +} + +// The 3 functions below are unlikely to ever get supported on Windows +static int windows_kernel_driver_active(struct libusb_device_handle *dev_handle, int iface) +{ + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static int windows_attach_kernel_driver(struct libusb_device_handle *dev_handle, int iface) +{ + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static int windows_detach_kernel_driver(struct libusb_device_handle *dev_handle, int iface) +{ + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static void windows_destroy_device(struct libusb_device *dev) +{ + windows_device_priv_release(dev); +} + +void windows_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + + usbi_free_fd(&transfer_priv->pollable_fd); + safe_free(transfer_priv->hid_buffer); + // When auto claim is in use, attempt to release the auto-claimed interface + auto_release(itransfer); +} + +static int submit_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int r; + + r = priv->apib->submit_bulk_transfer(SUB_API_NOTSET, itransfer); + if (r != LIBUSB_SUCCESS) + return r; + + usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, + (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT)); + + return LIBUSB_SUCCESS; +} + +static int submit_iso_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int r; + + r = priv->apib->submit_iso_transfer(SUB_API_NOTSET, itransfer); + if (r != LIBUSB_SUCCESS) + return r; + + usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, + (short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT)); + + return LIBUSB_SUCCESS; +} + +static int submit_control_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int r; + + r = priv->apib->submit_control_transfer(SUB_API_NOTSET, itransfer); + if (r != LIBUSB_SUCCESS) + return r; + + usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN); + + return LIBUSB_SUCCESS; +} + +static int windows_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return submit_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)) + return LIBUSB_ERROR_NOT_SUPPORTED; + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return submit_iso_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return LIBUSB_ERROR_NOT_SUPPORTED; + default: + usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int windows_abort_control(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + + return priv->apib->abort_control(SUB_API_NOTSET, itransfer); +} + +static int windows_abort_transfers(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + + return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer); +} + +static int windows_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return windows_abort_control(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return windows_abort_transfers(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return LIBUSB_ERROR_NOT_SUPPORTED; + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +int windows_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + return priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size); +} + +struct winfd *windows_get_fd(struct usbi_transfer *transfer) +{ + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(transfer); + return &transfer_priv->pollable_fd; +} + +void windows_get_overlapped_result(struct usbi_transfer *transfer, struct winfd *pollable_fd, DWORD *io_result, DWORD *io_size) +{ + if (HasOverlappedIoCompletedSync(pollable_fd->overlapped)) { + *io_result = NO_ERROR; + *io_size = (DWORD)pollable_fd->overlapped->InternalHigh; + } else if (GetOverlappedResult(pollable_fd->handle, pollable_fd->overlapped, io_size, false)) { + // Regular async overlapped + *io_result = NO_ERROR; + } else { + *io_result = GetLastError(); + } +} + +// NB: MSVC6 does not support named initializers. +const struct usbi_os_backend windows_backend = { + "Windows", + USBI_CAP_HAS_HID_ACCESS, + windows_init, + windows_exit, + + windows_get_device_list, + NULL, /* hotplug_poll */ + windows_open, + windows_close, + + windows_get_device_descriptor, + windows_get_active_config_descriptor, + windows_get_config_descriptor, + windows_get_config_descriptor_by_value, + + windows_get_configuration, + windows_set_configuration, + windows_claim_interface, + windows_release_interface, + + windows_set_interface_altsetting, + windows_clear_halt, + windows_reset_device, + + NULL, /* alloc_streams */ + NULL, /* free_streams */ + + NULL, /* dev_mem_alloc */ + NULL, /* dev_mem_free */ + + windows_kernel_driver_active, + windows_detach_kernel_driver, + windows_attach_kernel_driver, + + windows_destroy_device, + + windows_submit_transfer, + windows_cancel_transfer, + windows_clear_transfer_priv, + + windows_handle_events, + NULL, + + windows_clock_gettime, +#if defined(USBI_TIMERFD_AVAILABLE) + NULL, +#endif + sizeof(struct windows_device_priv), + sizeof(struct windows_device_handle_priv), + sizeof(struct windows_transfer_priv), +}; + + +/* + * USB API backends + */ +static int unsupported_init(int sub_api, struct libusb_context *ctx) +{ + return LIBUSB_SUCCESS; +} + +static int unsupported_exit(int sub_api) +{ + return LIBUSB_SUCCESS; +} + +static int unsupported_open(int sub_api, struct libusb_device_handle *dev_handle) +{ + PRINT_UNSUPPORTED_API(open); +} + +static void unsupported_close(int sub_api, struct libusb_device_handle *dev_handle) +{ + usbi_dbg("unsupported API call for 'close'"); +} + +static int unsupported_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + PRINT_UNSUPPORTED_API(configure_endpoints); +} + +static int unsupported_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + PRINT_UNSUPPORTED_API(claim_interface); +} + +static int unsupported_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + PRINT_UNSUPPORTED_API(set_interface_altsetting); +} + +static int unsupported_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + PRINT_UNSUPPORTED_API(release_interface); +} + +static int unsupported_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + PRINT_UNSUPPORTED_API(clear_halt); +} + +static int unsupported_reset_device(int sub_api, struct libusb_device_handle *dev_handle) +{ + PRINT_UNSUPPORTED_API(reset_device); +} + +static int unsupported_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + PRINT_UNSUPPORTED_API(submit_bulk_transfer); +} + +static int unsupported_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + PRINT_UNSUPPORTED_API(submit_iso_transfer); +} + +static int unsupported_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + PRINT_UNSUPPORTED_API(submit_control_transfer); +} + +static int unsupported_abort_control(int sub_api, struct usbi_transfer *itransfer) +{ + PRINT_UNSUPPORTED_API(abort_control); +} + +static int unsupported_abort_transfers(int sub_api, struct usbi_transfer *itransfer) +{ + PRINT_UNSUPPORTED_API(abort_transfers); +} + +static int unsupported_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) +{ + PRINT_UNSUPPORTED_API(copy_transfer_data); +} + +static int common_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + return LIBUSB_SUCCESS; +} + +// These names must be uppercase +static const char *hub_driver_names[] = {"USBHUB", "USBHUB3", "USB3HUB", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB", "VUSB3HUB", "AMDHUB30", "VHHUB", "AUSB3HUB"}; +static const char *composite_driver_names[] = {"USBCCGP"}; +static const char *winusbx_driver_names[] = WINUSBX_DRV_NAMES; +static const char *hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"}; +const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { + { + USB_API_UNSUPPORTED, + "Unsupported API", + NULL, + 0, + unsupported_init, + unsupported_exit, + unsupported_open, + unsupported_close, + unsupported_configure_endpoints, + unsupported_claim_interface, + unsupported_set_interface_altsetting, + unsupported_release_interface, + unsupported_clear_halt, + unsupported_reset_device, + unsupported_submit_bulk_transfer, + unsupported_submit_iso_transfer, + unsupported_submit_control_transfer, + unsupported_abort_control, + unsupported_abort_transfers, + unsupported_copy_transfer_data, + }, + { + USB_API_HUB, + "HUB API", + hub_driver_names, + ARRAYSIZE(hub_driver_names), + unsupported_init, + unsupported_exit, + unsupported_open, + unsupported_close, + unsupported_configure_endpoints, + unsupported_claim_interface, + unsupported_set_interface_altsetting, + unsupported_release_interface, + unsupported_clear_halt, + unsupported_reset_device, + unsupported_submit_bulk_transfer, + unsupported_submit_iso_transfer, + unsupported_submit_control_transfer, + unsupported_abort_control, + unsupported_abort_transfers, + unsupported_copy_transfer_data, + }, + { + USB_API_COMPOSITE, + "Composite API", + composite_driver_names, + ARRAYSIZE(composite_driver_names), + composite_init, + composite_exit, + composite_open, + composite_close, + common_configure_endpoints, + composite_claim_interface, + composite_set_interface_altsetting, + composite_release_interface, + composite_clear_halt, + composite_reset_device, + composite_submit_bulk_transfer, + composite_submit_iso_transfer, + composite_submit_control_transfer, + composite_abort_control, + composite_abort_transfers, + composite_copy_transfer_data, + }, + { + USB_API_WINUSBX, + "WinUSB-like APIs", + winusbx_driver_names, + ARRAYSIZE(winusbx_driver_names), + winusbx_init, + winusbx_exit, + winusbx_open, + winusbx_close, + winusbx_configure_endpoints, + winusbx_claim_interface, + winusbx_set_interface_altsetting, + winusbx_release_interface, + winusbx_clear_halt, + winusbx_reset_device, + winusbx_submit_bulk_transfer, + unsupported_submit_iso_transfer, + winusbx_submit_control_transfer, + winusbx_abort_control, + winusbx_abort_transfers, + winusbx_copy_transfer_data, + } +}; + + +/* + * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions + */ +#define WinUSBX_Set(fn) \ + do { \ + if (native_winusb) \ + WinUSBX[i].fn = (WinUsb_##fn##_t)GetProcAddress(h, "WinUsb_" #fn); \ + else \ + pLibK_GetProcAddress((PVOID *)&WinUSBX[i].fn, i, KUSB_FNID_##fn); \ + } while (0) + +static int winusbx_init(int sub_api, struct libusb_context *ctx) +{ + HMODULE h; + bool native_winusb; + int i; + KLIB_VERSION LibK_Version; + LibK_GetProcAddress_t pLibK_GetProcAddress = NULL; + LibK_GetVersion_t pLibK_GetVersion; + + h = LoadLibraryA("libusbK"); + + if (h == NULL) { + usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB"); + h = LoadLibraryA("WinUSB"); + + if (h == NULL) { + usbi_warn(ctx, "WinUSB DLL is not available either, " + "you will not be able to access devices outside of enumeration"); + return LIBUSB_ERROR_NOT_FOUND; + } + } else { + usbi_dbg("using libusbK DLL for universal access"); + pLibK_GetVersion = (LibK_GetVersion_t)GetProcAddress(h, "LibK_GetVersion"); + if (pLibK_GetVersion != NULL) { + pLibK_GetVersion(&LibK_Version); + usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor, + LibK_Version.Micro, LibK_Version.Nano); + } + pLibK_GetProcAddress = (LibK_GetProcAddress_t)GetProcAddress(h, "LibK_GetProcAddress"); + if (pLibK_GetProcAddress == NULL) { + usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL"); + FreeLibrary(h); + return LIBUSB_ERROR_NOT_FOUND; + } + } + + native_winusb = (pLibK_GetProcAddress == NULL); + for (i = SUB_API_LIBUSBK; i < SUB_API_MAX; i++) { + WinUSBX_Set(AbortPipe); + WinUSBX_Set(ControlTransfer); + WinUSBX_Set(FlushPipe); + WinUSBX_Set(Free); + WinUSBX_Set(GetAssociatedInterface); + WinUSBX_Set(GetCurrentAlternateSetting); + WinUSBX_Set(GetDescriptor); + WinUSBX_Set(GetOverlappedResult); + WinUSBX_Set(GetPipePolicy); + WinUSBX_Set(GetPowerPolicy); + WinUSBX_Set(Initialize); + WinUSBX_Set(QueryDeviceInformation); + WinUSBX_Set(QueryInterfaceSettings); + WinUSBX_Set(QueryPipe); + WinUSBX_Set(ReadPipe); + WinUSBX_Set(ResetPipe); + WinUSBX_Set(SetCurrentAlternateSetting); + WinUSBX_Set(SetPipePolicy); + WinUSBX_Set(SetPowerPolicy); + WinUSBX_Set(WritePipe); + if (!native_winusb) + WinUSBX_Set(ResetDevice); + + if (WinUSBX[i].Initialize != NULL) { + WinUSBX[i].initialized = true; + usbi_dbg("initalized sub API %s", sub_api_name[i]); + } else { + usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]); + WinUSBX[i].initialized = false; + } + } + + WinUSBX_handle = h; + return LIBUSB_SUCCESS; +} + +static int winusbx_exit(int sub_api) +{ + if (WinUSBX_handle != NULL) { + FreeLibrary(WinUSBX_handle); + WinUSBX_handle = NULL; + + /* Reset the WinUSBX API structures */ + memset(&WinUSBX, 0, sizeof(WinUSBX)); + } + + return LIBUSB_SUCCESS; +} + +// NB: open and close must ensure that they only handle interface of +// the right API type, as these functions can be called wholesale from +// composite_open(), with interfaces belonging to different APIs +static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + + HANDLE file_handle; + int i; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // WinUSB requires a separate handle for each interface + for (i = 0; i < USB_MAXINTERFACES; i++) { + if ((priv->usb_interface[i].path != NULL) + && (priv->usb_interface[i].apib->id == USB_API_WINUSBX)) { + file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (file_handle == INVALID_HANDLE_VALUE) { + usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0)); + switch(GetLastError()) { + case ERROR_FILE_NOT_FOUND: // The device was disconnected + return LIBUSB_ERROR_NO_DEVICE; + case ERROR_ACCESS_DENIED: + return LIBUSB_ERROR_ACCESS; + default: + return LIBUSB_ERROR_IO; + } + } + handle_priv->interface_handle[i].dev_handle = file_handle; + } + } + + return LIBUSB_SUCCESS; +} + +static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE handle; + int i; + + if (sub_api == SUB_API_NOTSET) + sub_api = priv->sub_api; + + if (!WinUSBX[sub_api].initialized) + return; + + if (priv->apib->id == USB_API_COMPOSITE) { + // If this is a composite device, just free and close all WinUSB-like + // interfaces directly (each is independent and not associated with another) + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) { + handle = handle_priv->interface_handle[i].api_handle; + if (HANDLE_VALID(handle)) + WinUSBX[sub_api].Free(handle); + + handle = handle_priv->interface_handle[i].dev_handle; + if (HANDLE_VALID(handle)) + CloseHandle(handle); + } + } + } else { + // If this is a WinUSB device, free all interfaces above interface 0, + // then free and close interface 0 last + for (i = 1; i < USB_MAXINTERFACES; i++) { + handle = handle_priv->interface_handle[i].api_handle; + if (HANDLE_VALID(handle)) + WinUSBX[sub_api].Free(handle); + } + handle = handle_priv->interface_handle[0].api_handle; + if (HANDLE_VALID(handle)) + WinUSBX[sub_api].Free(handle); + + handle = handle_priv->interface_handle[0].dev_handle; + if (HANDLE_VALID(handle)) + CloseHandle(handle); + } +} + +static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle; + UCHAR policy; + ULONG timeout = 0; + uint8_t endpoint_address; + int i; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // With handle and enpoints set (in parent), we can setup the default pipe properties + // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx + for (i = -1; i < priv->usb_interface[iface].nb_endpoints; i++) { + endpoint_address = (i == -1) ? 0 : priv->usb_interface[iface].endpoint[i]; + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) + usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address); + + if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) + continue; // Other policies don't apply to control endpoint or libusb0 + + policy = false; + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) + usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address); + + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) + usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address); + + policy = true; + /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See: + https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */ + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) + usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address); + + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) + usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address); + } + + return LIBUSB_SUCCESS; +} + +static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE); + SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL; + HDEVINFO dev_info = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA dev_info_data; + char *dev_path_no_guid = NULL; + char filter_path[] = "\\\\.\\libusb0-0000"; + bool found_filter = false; + HANDLE file_handle, winusb_handle; + DWORD err; + int i; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // If the device is composite, but using the default Windows composite parent driver (usbccgp) + // or if it's the first WinUSB-like interface, we get a handle through Initialize(). + if ((is_using_usbccgp) || (iface == 0)) { + // composite device (independent interfaces) or interface 0 + file_handle = handle_priv->interface_handle[iface].dev_handle; + if (!HANDLE_VALID(file_handle)) + return LIBUSB_ERROR_NOT_FOUND; + + if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; + err = GetLastError(); + switch(err) { + case ERROR_BAD_COMMAND: + // The device was disconnected + usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + default: + // it may be that we're using the libusb0 filter driver. + // TODO: can we move this whole business into the K/0 DLL? + for (i = 0; ; i++) { + safe_free(dev_interface_details); + safe_free(dev_path_no_guid); + + dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path); + if ((found_filter) || (dev_interface_details == NULL)) + break; + + // ignore GUID part + dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{")); + if (dev_path_no_guid == NULL) + continue; + + if (strncmp(dev_path_no_guid, priv->usb_interface[iface].path, strlen(dev_path_no_guid)) == 0) { + file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (file_handle != INVALID_HANDLE_VALUE) { + if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + // Replace the existing file handle with the working one + CloseHandle(handle_priv->interface_handle[iface].dev_handle); + handle_priv->interface_handle[iface].dev_handle = file_handle; + found_filter = true; + } else { + usbi_err(ctx, "could not initialize filter driver for %s", filter_path); + CloseHandle(file_handle); + } + } else { + usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0)); + } + } + } + free(dev_interface_details); + if (!found_filter) { + usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err)); + return LIBUSB_ERROR_ACCESS; + } + } + } + handle_priv->interface_handle[iface].api_handle = winusb_handle; + } else { + // For all other interfaces, use GetAssociatedInterface() + winusb_handle = handle_priv->interface_handle[0].api_handle; + // It is a requirement for multiple interface devices on Windows that, to you + // must first claim the first interface before you claim the others + if (!HANDLE_VALID(winusb_handle)) { + file_handle = handle_priv->interface_handle[0].dev_handle; + if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + handle_priv->interface_handle[0].api_handle = winusb_handle; + usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface); + } else { + usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0)); + return LIBUSB_ERROR_ACCESS; + } + } + if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface - 1), + &handle_priv->interface_handle[iface].api_handle)) { + handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; + switch(GetLastError()) { + case ERROR_NO_MORE_ITEMS: // invalid iface + return LIBUSB_ERROR_NOT_FOUND; + case ERROR_BAD_COMMAND: // The device was disconnected + return LIBUSB_ERROR_NO_DEVICE; + case ERROR_ALREADY_EXISTS: // already claimed + return LIBUSB_ERROR_BUSY; + default: + usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0)); + return LIBUSB_ERROR_ACCESS; + } + } + } + usbi_dbg("claimed interface %d", iface); + handle_priv->active_interface = iface; + + return LIBUSB_SUCCESS; +} + +static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + winusb_handle = handle_priv->interface_handle[iface].api_handle; + if (!HANDLE_VALID(winusb_handle)) + return LIBUSB_ERROR_NOT_FOUND; + + WinUSBX[sub_api].Free(winusb_handle); + handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; + + return LIBUSB_SUCCESS; +} + +/* + * Return the first valid interface (of the same API type), for control transfers + */ +static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id) +{ + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + int i; + + if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) { + usbi_dbg("unsupported API ID"); + return -1; + } + + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (HANDLE_VALID(handle_priv->interface_handle[i].dev_handle) + && HANDLE_VALID(handle_priv->interface_handle[i].api_handle) + && (priv->usb_interface[i].apib->id == api_id)) + return i; + } + + return -1; +} + +/* + * Lookup interface by endpoint address. -1 if not found + */ +static int interface_by_endpoint(struct windows_device_priv *priv, + struct windows_device_handle_priv *handle_priv, uint8_t endpoint_address) +{ + int i, j; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (!HANDLE_VALID(handle_priv->interface_handle[i].api_handle)) + continue; + if (priv->usb_interface[i].endpoint == NULL) + continue; + for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) { + if (priv->usb_interface[i].endpoint[j] == endpoint_address) + return i; + } + } + + return -1; +} + +static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer; + ULONG size; + HANDLE winusb_handle; + int current_interface; + struct winfd wfd; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + transfer_priv->pollable_fd = INVALID_WINFD; + size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; + + // Windows places upper limits on the control transfer size + // See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff538112.aspx + if (size > MAX_CTRL_BUFFER_LENGTH) + return LIBUSB_ERROR_INVALID_PARAM; + + current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX); + if (current_interface < 0) { + if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("will use interface %d", current_interface); + winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + + wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL); + // Always use the handle returned from usbi_create_fd (wfd.handle) + if (wfd.fd < 0) + return LIBUSB_ERROR_NO_MEM; + + // Sending of set configuration control requests from WinUSB creates issues + if (((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD) + && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION)) { + if (setup->value != priv->active_config) { + usbi_warn(ctx, "cannot set configuration other than the default one"); + usbi_free_fd(&wfd); + return LIBUSB_ERROR_INVALID_PARAM; + } + wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; + wfd.overlapped->InternalHigh = 0; + } else { + if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) { + if (GetLastError() != ERROR_IO_PENDING) { + usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0)); + usbi_free_fd(&wfd); + return LIBUSB_ERROR_IO; + } + } else { + wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; + wfd.overlapped->InternalHigh = (DWORD)size; + } + } + + // Use priv_transfer to store data needed for async polling + transfer_priv->pollable_fd = wfd; + transfer_priv->interface_number = (uint8_t)current_interface; + + return LIBUSB_SUCCESS; +} + +static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + if (altsetting > 255) + return LIBUSB_ERROR_INVALID_PARAM; + + winusb_handle = handle_priv->interface_handle[iface].api_handle; + if (!HANDLE_VALID(winusb_handle)) { + usbi_err(ctx, "interface must be claimed first"); + return LIBUSB_ERROR_NOT_FOUND; + } + + if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) { + usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + + return LIBUSB_SUCCESS; +} + +static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + HANDLE winusb_handle; + bool ret; + int current_interface; + struct winfd wfd; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + transfer_priv->pollable_fd = INVALID_WINFD; + + current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface); + + winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + + wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL); + // Always use the handle returned from usbi_create_fd (wfd.handle) + if (wfd.fd < 0) + return LIBUSB_ERROR_NO_MEM; + + if (IS_XFERIN(transfer)) { + usbi_dbg("reading %d bytes", transfer->length); + ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + } else { + usbi_dbg("writing %d bytes", transfer->length); + ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + } + + if (!ret) { + if (GetLastError() != ERROR_IO_PENDING) { + usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); + usbi_free_fd(&wfd); + return LIBUSB_ERROR_IO; + } + } else { + wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; + wfd.overlapped->InternalHigh = (DWORD)transfer->length; + } + + transfer_priv->pollable_fd = wfd; + transfer_priv->interface_number = (uint8_t)current_interface; + + return LIBUSB_SUCCESS; +} + +static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle; + int current_interface; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + current_interface = interface_by_endpoint(priv, handle_priv, endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear"); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface); + winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + + if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) { + usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +/* + * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed + * through testing as well): + * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel + * the control transfer using CancelIo" + */ +static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer) +{ + // Cancelling of the I/O is done in the parent + return LIBUSB_SUCCESS; +} + +static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + HANDLE winusb_handle; + int current_interface; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + current_interface = transfer_priv->interface_number; + if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) { + usbi_err(ctx, "program assertion failed: invalid interface_number"); + return LIBUSB_ERROR_NOT_FOUND; + } + usbi_dbg("will use interface %d", current_interface); + + winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + + if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) { + usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +/* + * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper + * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx): + * "WinUSB does not support host-initiated reset port and cycle port operations" and + * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the + * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is + * cycle the pipes (and even then, the control pipe can not be reset using WinUSB) + */ +// TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?) +static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + struct winfd wfd; + HANDLE winusb_handle; + int i, j; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // Reset any available pipe (except control) + for (i = 0; i < USB_MAXINTERFACES; i++) { + winusb_handle = handle_priv->interface_handle[i].api_handle; + for (wfd = handle_to_winfd(winusb_handle); wfd.fd > 0; ) { + // Cancel any pollable I/O + usbi_remove_pollfd(ctx, wfd.fd); + usbi_free_fd(&wfd); + wfd = handle_to_winfd(winusb_handle); + } + + if (HANDLE_VALID(winusb_handle)) { + for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) { + usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]); + if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) + usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s", + priv->usb_interface[i].endpoint[j], windows_error_str(0)); + + // FlushPipe seems to fail on OUT pipes + if (IS_EPIN(priv->usb_interface[i].endpoint[j]) + && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))) + usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s", + priv->usb_interface[i].endpoint[j], windows_error_str(0)); + + if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) + usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s", + priv->usb_interface[i].endpoint[j], windows_error_str(0)); + } + } + } + + // libusbK & libusb0 have the ability to issue an actual device reset + if (WinUSBX[sub_api].ResetDevice != NULL) { + winusb_handle = handle_priv->interface_handle[0].api_handle; + if (HANDLE_VALID(winusb_handle)) + WinUSBX[sub_api].ResetDevice(winusb_handle); + } + + return LIBUSB_SUCCESS; +} + +static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) +{ + itransfer->transferred += io_size; + return LIBUSB_TRANSFER_COMPLETED; +} + +/* + * Composite API functions + */ +static int composite_init(int sub_api, struct libusb_context *ctx) +{ + return LIBUSB_SUCCESS; +} + +static int composite_exit(int sub_api) +{ + return LIBUSB_SUCCESS; +} + +static int composite_open(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + int r = LIBUSB_ERROR_NOT_FOUND; + uint8_t i; + // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID + bool available[SUB_API_MAX + 1] = { 0 }; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + switch (priv->usb_interface[i].apib->id) { + case USB_API_WINUSBX: + if (priv->usb_interface[i].sub_api != SUB_API_NOTSET) + available[priv->usb_interface[i].sub_api] = true; + break; + case USB_API_HID: + available[SUB_API_MAX] = true; + break; + default: + break; + } + } + + for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers + if (available[i]) { + r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle); + if (r != LIBUSB_SUCCESS) + return r; + } + } + + return r; +} + +static void composite_close(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + uint8_t i; + // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID + bool available[SUB_API_MAX + 1] = { 0 }; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + switch (priv->usb_interface[i].apib->id) { + case USB_API_WINUSBX: + if (priv->usb_interface[i].sub_api != SUB_API_NOTSET) + available[priv->usb_interface[i].sub_api] = true; + break; + case USB_API_HID: + available[SUB_API_MAX] = true; + break; + default: + break; + } + } + + for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers + if (available[i]) + usb_api_backend[USB_API_WINUSBX].close(i, dev_handle); + } +} + +static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + return priv->usb_interface[iface].apib-> + claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface); +} + +static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + return priv->usb_interface[iface].apib-> + set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting); +} + +static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + + return priv->usb_interface[iface].apib-> + release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface); +} + +static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + struct libusb_config_descriptor *conf_desc; + WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer; + int iface, pass, r; + + // Interface shouldn't matter for control, but it does in practice, with Windows' + // restrictions with regards to accessing HID keyboards and mice. Try to target + // a specific interface first, if possible. + switch (LIBUSB_REQ_RECIPIENT(setup->request_type)) { + case LIBUSB_RECIPIENT_INTERFACE: + iface = setup->index & 0xFF; + break; + case LIBUSB_RECIPIENT_ENDPOINT: + r = libusb_get_active_config_descriptor(transfer->dev_handle->dev, &conf_desc); + if (r == LIBUSB_SUCCESS) { + iface = get_interface_by_endpoint(conf_desc, (setup->index & 0xFF)); + libusb_free_config_descriptor(conf_desc); + break; + } + // Fall through if not able to determine interface + default: + iface = -1; + break; + } + + // Try and target a specific interface if the control setup indicates such + if ((iface >= 0) && (iface < USB_MAXINTERFACES)) { + usbi_dbg("attempting control transfer targeted to interface %d", iface); + if (priv->usb_interface[iface].path != NULL) { + r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer); + if (r == LIBUSB_SUCCESS) + return r; + } + } + + // Either not targeted to a specific interface or no luck in doing so. + // Try a 2 pass approach with all interfaces. + for (pass = 0; pass < 2; pass++) { + for (iface = 0; iface < USB_MAXINTERFACES; iface++) { + if (priv->usb_interface[iface].path != NULL) { + if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) { + usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", iface); + continue; + } + usbi_dbg("using interface %d", iface); + r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer); + // If not supported on this API, it may be supported on another, so don't give up yet!! + if (r == LIBUSB_ERROR_NOT_SUPPORTED) + continue; + return r; + } + } + } + + usbi_err(ctx, "no libusb supported interfaces to complete request"); + return LIBUSB_ERROR_NOT_FOUND; +} + +static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface; + + current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); + return LIBUSB_ERROR_NOT_FOUND; + } + + return priv->usb_interface[current_interface].apib-> + submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer); +} + +static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface; + + current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); + return LIBUSB_ERROR_NOT_FOUND; + } + + return priv->usb_interface[current_interface].apib-> + submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer); +} + +static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + int current_interface; + + current_interface = interface_by_endpoint(priv, handle_priv, endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear"); + return LIBUSB_ERROR_NOT_FOUND; + } + + return priv->usb_interface[current_interface].apib-> + clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint); +} + +static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + + return priv->usb_interface[transfer_priv->interface_number].apib-> + abort_control(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer); +} + +static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + + return priv->usb_interface[transfer_priv->interface_number].apib-> + abort_transfers(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer); +} + +static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct windows_device_priv *priv = _device_priv(dev_handle->dev); + int r; + uint8_t i; + bool available[SUB_API_MAX]; + + for (i = 0; i < SUB_API_MAX; i++) + available[i] = false; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + if ((priv->usb_interface[i].apib->id == USB_API_WINUSBX) + && (priv->usb_interface[i].sub_api != SUB_API_NOTSET)) + available[priv->usb_interface[i].sub_api] = true; + } + + for (i = 0; i < SUB_API_MAX; i++) { + if (available[i]) { + r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle); + if (r != LIBUSB_SUCCESS) + return r; + } + } + + return LIBUSB_SUCCESS; +} + +static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); + + return priv->usb_interface[transfer_priv->interface_number].apib-> + copy_transfer_data(priv->usb_interface[transfer_priv->interface_number].sub_api, itransfer, io_size); +} + +#endif /* !USE_USBDK */ diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.h b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.h new file mode 100644 index 00000000..0c1580cd --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.h @@ -0,0 +1,833 @@ +/* + * Windows backend for libusb 1.0 + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "windows_common.h" +#include "windows_nt_common.h" + +#if defined(_MSC_VER) +// disable /W4 MSVC warnings that are benign +#pragma warning(disable:4100) // unreferenced formal parameter +#pragma warning(disable:4127) // conditional expression is constant +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int +#pragma warning(disable:4996) // deprecated API calls +#pragma warning(disable:28159) // more deprecated API calls +#endif + +// Missing from MSVC6 setupapi.h +#if !defined(SPDRP_ADDRESS) +#define SPDRP_ADDRESS 28 +#endif +#if !defined(SPDRP_INSTALL_STATE) +#define SPDRP_INSTALL_STATE 34 +#endif + +#define MAX_CTRL_BUFFER_LENGTH 4096 +#define MAX_USB_DEVICES 256 +#define MAX_USB_STRING_LENGTH 128 +#define MAX_HID_REPORT_SIZE 1024 +#define MAX_HID_DESCRIPTOR_SIZE 256 +#define MAX_GUID_STRING_LENGTH 40 +#define MAX_PATH_LENGTH 128 +#define MAX_KEY_LENGTH 256 +#define LIST_SEPARATOR ';' + +// Handle code for HID interface that have been claimed ("dibs") +#define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5) +// Additional return code for HID operations that completed synchronously +#define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1) + +// http://msdn.microsoft.com/en-us/library/ff545978.aspx +// http://msdn.microsoft.com/en-us/library/ff545972.aspx +// http://msdn.microsoft.com/en-us/library/ff545982.aspx +#if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER) +const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} }; +#endif +#if !defined(GUID_DEVINTERFACE_USB_DEVICE) +const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} }; +#endif +#if !defined(GUID_DEVINTERFACE_USB_HUB) +const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} }; +#endif +#if !defined(GUID_DEVINTERFACE_LIBUSB0_FILTER) +const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9} }; +#endif + + +/* + * Multiple USB API backend support + */ +#define USB_API_UNSUPPORTED 0 +#define USB_API_HUB 1 +#define USB_API_COMPOSITE 2 +#define USB_API_WINUSBX 3 +#define USB_API_HID 4 +#define USB_API_MAX 4 // hid is dead +// The following is used to indicate if the HID or composite extra props have already been set. +#define USB_API_SET (1 << USB_API_MAX) + +// Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL) +// Must have the same values as the KUSB_DRVID enum from libusbk.h +#define SUB_API_NOTSET -1 +#define SUB_API_LIBUSBK 0 +#define SUB_API_LIBUSB0 1 +#define SUB_API_WINUSB 2 +#define SUB_API_MAX 3 + +#define WINUSBX_DRV_NAMES {"libusbK", "libusb0", "WinUSB"} + +struct windows_usb_api_backend { + const uint8_t id; + const char *designation; + const char **driver_name_list; // Driver name, without .sys, e.g. "usbccgp" + const uint8_t nb_driver_names; + int (*init)(int sub_api, struct libusb_context *ctx); + int (*exit)(int sub_api); + int (*open)(int sub_api, struct libusb_device_handle *dev_handle); + void (*close)(int sub_api, struct libusb_device_handle *dev_handle); + int (*configure_endpoints)(int sub_api, struct libusb_device_handle *dev_handle, int iface); + int (*claim_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface); + int (*set_interface_altsetting)(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting); + int (*release_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface); + int (*clear_halt)(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint); + int (*reset_device)(int sub_api, struct libusb_device_handle *dev_handle); + int (*submit_bulk_transfer)(int sub_api, struct usbi_transfer *itransfer); + int (*submit_iso_transfer)(int sub_api, struct usbi_transfer *itransfer); + int (*submit_control_transfer)(int sub_api, struct usbi_transfer *itransfer); + int (*abort_control)(int sub_api, struct usbi_transfer *itransfer); + int (*abort_transfers)(int sub_api, struct usbi_transfer *itransfer); + int (*copy_transfer_data)(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); +}; + +extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX]; + +#define PRINT_UNSUPPORTED_API(fname) \ + usbi_dbg("unsupported API call for '" \ + #fname "' (unrecognized device driver)"); \ + return LIBUSB_ERROR_NOT_SUPPORTED; + +/* + * private structures definition + * with inline pseudo constructors/destructors + */ + +#define LIBUSB_DT_HID_SIZE 9 +#define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \ + + LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE) +#define HID_MAX_REPORT_SIZE 1024 +#define HID_IN_EP 0x81 +#define HID_OUT_EP 0x02 +#define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F) +#define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5)) +#define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN) +#define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type)) + +// The following are used for HID reports IOCTLs +#define HID_CTL_CODE(id) \ + CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS) +#define HID_BUFFER_CTL_CODE(id) \ + CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_BUFFERED, FILE_ANY_ACCESS) +#define HID_IN_CTL_CODE_HIDHACK(id) \ + CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS) + +#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) +#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104) +#define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE_HIDHACK(100) +#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE_HIDHACK(101) + +enum libusb_hid_request_type { + HID_REQ_GET_REPORT = 0x01, + HID_REQ_GET_IDLE = 0x02, + HID_REQ_GET_PROTOCOL = 0x03, + HID_REQ_SET_REPORT = 0x09, + HID_REQ_SET_IDLE = 0x0A, + HID_REQ_SET_PROTOCOL = 0x0B +}; + +enum libusb_hid_report_type { + HID_REPORT_TYPE_INPUT = 0x01, + HID_REPORT_TYPE_OUTPUT = 0x02, + HID_REPORT_TYPE_FEATURE = 0x03 +}; + +struct hid_device_priv { + uint16_t vid; + uint16_t pid; + uint8_t config; + uint8_t nb_interfaces; + bool uses_report_ids[3]; // input, ouptput, feature + uint16_t input_report_size; + uint16_t output_report_size; + uint16_t feature_report_size; + WCHAR string[3][MAX_USB_STRING_LENGTH]; + uint8_t string_index[3]; // man, prod, ser +}; + +struct windows_device_priv { + uint8_t depth; // distance to HCD + uint8_t port; // port number on the hub + uint8_t active_config; + struct windows_usb_api_backend const *apib; + char *path; // device interface path + int sub_api; // for WinUSB-like APIs + struct { + char *path; // each interface needs a device interface path, + struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support), + int sub_api; + int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS) + uint8_t *endpoint; + bool restricted_functionality; // indicates if the interface functionality is restricted + // by Windows (eg. HID keyboards or mice cannot do R/W) + } usb_interface[USB_MAXINTERFACES]; + struct hid_device_priv *hid; + USB_DEVICE_DESCRIPTOR dev_descriptor; + unsigned char **config_descriptor; // list of pointers to the cached config descriptors +}; + +static inline struct windows_device_priv *_device_priv(struct libusb_device *dev) +{ + return (struct windows_device_priv *)dev->os_priv; +} + +static inline struct windows_device_priv *windows_device_priv_init(struct libusb_device *dev) +{ + struct windows_device_priv *p = _device_priv(dev); + int i; + + p->apib = &usb_api_backend[USB_API_UNSUPPORTED]; + p->sub_api = SUB_API_NOTSET; + for (i = 0; i < USB_MAXINTERFACES; i++) { + p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED]; + p->usb_interface[i].sub_api = SUB_API_NOTSET; + } + + return p; +} + +static inline void windows_device_priv_release(struct libusb_device *dev) +{ + struct windows_device_priv *p = _device_priv(dev); + int i; + + free(p->path); + if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) { + for (i = 0; i < dev->num_configurations; i++) + free(p->config_descriptor[i]); + } + free(p->config_descriptor); + free(p->hid); + for (i = 0; i < USB_MAXINTERFACES; i++) { + free(p->usb_interface[i].path); + free(p->usb_interface[i].endpoint); + } +} + +struct interface_handle_t { + HANDLE dev_handle; // WinUSB needs an extra handle for the file + HANDLE api_handle; // used by the API to communicate with the device +}; + +struct windows_device_handle_priv { + int active_interface; + struct interface_handle_t interface_handle[USB_MAXINTERFACES]; + int autoclaim_count[USB_MAXINTERFACES]; // For auto-release +}; + +static inline struct windows_device_handle_priv *_device_handle_priv( + struct libusb_device_handle *handle) +{ + return (struct windows_device_handle_priv *)handle->os_priv; +} + +// used for async polling functions +struct windows_transfer_priv { + struct winfd pollable_fd; + uint8_t interface_number; + uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID + uint8_t *hid_dest; // transfer buffer destination, required for HID + size_t hid_expected_size; +}; + +// used to match a device driver (including filter drivers) against a supported API +struct driver_lookup { + char list[MAX_KEY_LENGTH + 1]; // REG_MULTI_SZ list of services (driver) names + const DWORD reg_prop; // SPDRP registry key to use to retrieve list + const char* designation; // internal designation (for debug output) +}; + +/* OLE32 dependency */ +DLL_DECLARE_HANDLE(OLE32); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID)); + +/* Kernel32 dependencies */ +DLL_DECLARE_HANDLE(Kernel32); +/* This call is only available from XP SP2 */ +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL)); + +/* SetupAPI dependencies */ +DLL_DECLARE_HANDLE(SetupAPI); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA, + const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, + PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO, + PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD)); + +/* AdvAPI32 dependencies */ +DLL_DECLARE_HANDLE(AdvAPI32); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY)); + +/* + * Windows DDK API definitions. Most of it copied from MinGW's includes + */ +typedef DWORD DEVNODE, DEVINST; +typedef DEVNODE *PDEVNODE, *PDEVINST; +typedef DWORD RETURN_TYPE; +typedef RETURN_TYPE CONFIGRET; + +#define CR_SUCCESS 0x00000000 +#define CR_NO_SUCH_DEVNODE 0x0000000D + +#define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE +#define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG +#define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING +#define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE +#define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT + +#define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS +#define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE +#define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE +#define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS +#define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR +#define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR +#define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION +#define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION +#define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE +#define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE +#define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME + +#define USB_GET_NODE_INFORMATION 258 +#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260 +#define USB_GET_NODE_CONNECTION_NAME 261 +#define USB_GET_HUB_CAPABILITIES 271 +#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX) +#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274 +#endif +#if !defined(USB_GET_HUB_CAPABILITIES_EX) +#define USB_GET_HUB_CAPABILITIES_EX 276 +#endif +#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX_V2) +#define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279 +#endif + +#ifndef METHOD_BUFFERED +#define METHOD_BUFFERED 0 +#endif +#ifndef FILE_ANY_ACCESS +#define FILE_ANY_ACCESS 0x00000000 +#endif +#ifndef FILE_DEVICE_UNKNOWN +#define FILE_DEVICE_UNKNOWN 0x00000022 +#endif +#ifndef FILE_DEVICE_USB +#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN +#endif + +#ifndef CTL_CODE +#define CTL_CODE(DeviceType, Function, Method, Access) \ + (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) +#endif + +typedef enum USB_CONNECTION_STATUS { + NoDeviceConnected, + DeviceConnected, + DeviceFailedEnumeration, + DeviceGeneralFailure, + DeviceCausedOvercurrent, + DeviceNotEnoughPower, + DeviceNotEnoughBandwidth, + DeviceHubNestedTooDeeply, + DeviceInLegacyHub +} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS; + +typedef enum USB_HUB_NODE { + UsbHub, + UsbMIParent +} USB_HUB_NODE; + +/* Cfgmgr32.dll interface */ +DLL_DECLARE_HANDLE(Cfgmgr32); +DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG)); +DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG)); +DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG)); +DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG)); + +#define IOCTL_USB_GET_HUB_CAPABILITIES_EX \ + CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_HUB_CAPABILITIES \ + CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \ + CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_ROOT_HUB_NAME \ + CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_NODE_INFORMATION \ + CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \ + CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \ + CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES \ + CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_ATTRIBUTES, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_NODE_CONNECTION_NAME \ + CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS) + +// Most of the structures below need to be packed +#pragma pack(push, 1) + +typedef struct USB_INTERFACE_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bInterfaceNumber; + UCHAR bAlternateSetting; + UCHAR bNumEndpoints; + UCHAR bInterfaceClass; + UCHAR bInterfaceSubClass; + UCHAR bInterfaceProtocol; + UCHAR iInterface; +} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR; + +typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT { + struct { + ULONG ConnectionIndex; + struct { + UCHAR bmRequest; + UCHAR bRequest; + USHORT wValue; + USHORT wIndex; + USHORT wLength; + } SetupPacket; + } req; + USB_CONFIGURATION_DESCRIPTOR data; +} USB_CONFIGURATION_DESCRIPTOR_SHORT; + +typedef struct USB_ENDPOINT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bEndpointAddress; + UCHAR bmAttributes; + USHORT wMaxPacketSize; + UCHAR bInterval; +} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR; + +typedef struct USB_DESCRIPTOR_REQUEST { + ULONG ConnectionIndex; + struct { + UCHAR bmRequest; + UCHAR bRequest; + USHORT wValue; + USHORT wIndex; + USHORT wLength; + } SetupPacket; +// UCHAR Data[0]; +} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST; + +typedef struct USB_HUB_DESCRIPTOR { + UCHAR bDescriptorLength; + UCHAR bDescriptorType; + UCHAR bNumberOfPorts; + USHORT wHubCharacteristics; + UCHAR bPowerOnToPowerGood; + UCHAR bHubControlCurrent; + UCHAR bRemoveAndPowerMask[64]; +} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR; + +typedef struct USB_ROOT_HUB_NAME { + ULONG ActualLength; + WCHAR RootHubName[1]; +} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME; + +typedef struct USB_ROOT_HUB_NAME_FIXED { + ULONG ActualLength; + WCHAR RootHubName[MAX_PATH_LENGTH]; +} USB_ROOT_HUB_NAME_FIXED; + +typedef struct USB_NODE_CONNECTION_NAME { + ULONG ConnectionIndex; + ULONG ActualLength; + WCHAR NodeName[1]; +} USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME; + +typedef struct USB_NODE_CONNECTION_NAME_FIXED { + ULONG ConnectionIndex; + ULONG ActualLength; + WCHAR NodeName[MAX_PATH_LENGTH]; +} USB_NODE_CONNECTION_NAME_FIXED; + +typedef struct USB_HUB_NAME_FIXED { + union { + USB_ROOT_HUB_NAME_FIXED root; + USB_NODE_CONNECTION_NAME_FIXED node; + } u; +} USB_HUB_NAME_FIXED; + +typedef struct USB_HUB_INFORMATION { + USB_HUB_DESCRIPTOR HubDescriptor; + BOOLEAN HubIsBusPowered; +} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION; + +typedef struct USB_MI_PARENT_INFORMATION { + ULONG NumberOfInterfaces; +} USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION; + +typedef struct USB_NODE_INFORMATION { + USB_HUB_NODE NodeType; + union { + USB_HUB_INFORMATION HubInformation; + USB_MI_PARENT_INFORMATION MiParentInformation; + } u; +} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION; + +typedef struct USB_PIPE_INFO { + USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; + ULONG ScheduleOffset; +} USB_PIPE_INFO, *PUSB_PIPE_INFO; + +typedef struct USB_NODE_CONNECTION_INFORMATION_EX { + ULONG ConnectionIndex; + USB_DEVICE_DESCRIPTOR DeviceDescriptor; + UCHAR CurrentConfigurationValue; + UCHAR Speed; + BOOLEAN DeviceIsHub; + USHORT DeviceAddress; + ULONG NumberOfOpenPipes; + USB_CONNECTION_STATUS ConnectionStatus; +// USB_PIPE_INFO PipeList[0]; +} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX; + +typedef union _USB_PROTOCOLS { + ULONG ul; + struct { + ULONG Usb110:1; + ULONG Usb200:1; + ULONG Usb300:1; + ULONG ReservedMBZ:29; + }; +} USB_PROTOCOLS, *PUSB_PROTOCOLS; + +typedef union _USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS { + ULONG ul; + struct { + ULONG DeviceIsOperatingAtSuperSpeedOrHigher:1; + ULONG DeviceIsSuperSpeedCapableOrHigher:1; + ULONG ReservedMBZ:30; + }; +} USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS; + +typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2 { + ULONG ConnectionIndex; + ULONG Length; + USB_PROTOCOLS SupportedUsbProtocols; + USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags; +} USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2; + +typedef struct USB_HUB_CAP_FLAGS { + ULONG HubIsHighSpeedCapable:1; + ULONG HubIsHighSpeed:1; + ULONG HubIsMultiTtCapable:1; + ULONG HubIsMultiTt:1; + ULONG HubIsRoot:1; + ULONG HubIsArmedWakeOnConnect:1; + ULONG ReservedMBZ:26; +} USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS; + +typedef struct USB_HUB_CAPABILITIES { + ULONG HubIs2xCapable:1; +} USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES; + +typedef struct USB_HUB_CAPABILITIES_EX { + USB_HUB_CAP_FLAGS CapabilityFlags; +} USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX; + +#pragma pack(pop) + +/* winusb.dll interface */ + +#define SHORT_PACKET_TERMINATE 0x01 +#define AUTO_CLEAR_STALL 0x02 +#define PIPE_TRANSFER_TIMEOUT 0x03 +#define IGNORE_SHORT_PACKETS 0x04 +#define ALLOW_PARTIAL_READS 0x05 +#define AUTO_FLUSH 0x06 +#define RAW_IO 0x07 +#define MAXIMUM_TRANSFER_SIZE 0x08 +#define AUTO_SUSPEND 0x81 +#define SUSPEND_DELAY 0x83 +#define DEVICE_SPEED 0x01 +#define LowSpeed 0x01 +#define FullSpeed 0x02 +#define HighSpeed 0x03 + +typedef enum USBD_PIPE_TYPE { + UsbdPipeTypeControl, + UsbdPipeTypeIsochronous, + UsbdPipeTypeBulk, + UsbdPipeTypeInterrupt +} USBD_PIPE_TYPE; + +typedef struct { + USBD_PIPE_TYPE PipeType; + UCHAR PipeId; + USHORT MaximumPacketSize; + UCHAR Interval; +} WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION; + +#pragma pack(1) +typedef struct { + UCHAR request_type; + UCHAR request; + USHORT value; + USHORT index; + USHORT length; +} WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET; +#pragma pack() + +typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE; + +typedef BOOL (WINAPI *WinUsb_AbortPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID +); +typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + WINUSB_SETUP_PACKET SetupPacket, + PUCHAR Buffer, + ULONG BufferLength, + PULONG LengthTransferred, + LPOVERLAPPED Overlapped +); +typedef BOOL (WINAPI *WinUsb_FlushPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID +); +typedef BOOL (WINAPI *WinUsb_Free_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle +); +typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR AssociatedInterfaceIndex, + PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle +); +typedef BOOL (WINAPI *WinUsb_GetCurrentAlternateSetting_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + PUCHAR AlternateSetting +); +typedef BOOL (WINAPI *WinUsb_GetDescriptor_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR DescriptorType, + UCHAR Index, + USHORT LanguageID, + PUCHAR Buffer, + ULONG BufferLength, + PULONG LengthTransferred +); +typedef BOOL (WINAPI *WinUsb_GetOverlappedResult_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + LPOVERLAPPED lpOverlapped, + LPDWORD lpNumberOfBytesTransferred, + BOOL bWait +); +typedef BOOL (WINAPI *WinUsb_GetPipePolicy_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + ULONG PolicyType, + PULONG ValueLength, + PVOID Value +); +typedef BOOL (WINAPI *WinUsb_GetPowerPolicy_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + ULONG PolicyType, + PULONG ValueLength, + PVOID Value +); +typedef BOOL (WINAPI *WinUsb_Initialize_t)( + HANDLE DeviceHandle, + PWINUSB_INTERFACE_HANDLE InterfaceHandle +); +typedef BOOL (WINAPI *WinUsb_QueryDeviceInformation_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + ULONG InformationType, + PULONG BufferLength, + PVOID Buffer +); +typedef BOOL (WINAPI *WinUsb_QueryInterfaceSettings_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR AlternateSettingNumber, + PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor +); +typedef BOOL (WINAPI *WinUsb_QueryPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR AlternateInterfaceNumber, + UCHAR PipeIndex, + PWINUSB_PIPE_INFORMATION PipeInformation +); +typedef BOOL (WINAPI *WinUsb_ReadPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + PUCHAR Buffer, + ULONG BufferLength, + PULONG LengthTransferred, + LPOVERLAPPED Overlapped +); +typedef BOOL (WINAPI *WinUsb_ResetPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID +); +typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR AlternateSetting +); +typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + ULONG PolicyType, + ULONG ValueLength, + PVOID Value +); +typedef BOOL (WINAPI *WinUsb_SetPowerPolicy_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + ULONG PolicyType, + ULONG ValueLength, + PVOID Value +); +typedef BOOL (WINAPI *WinUsb_WritePipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + PUCHAR Buffer, + ULONG BufferLength, + PULONG LengthTransferred, + LPOVERLAPPED Overlapped +); +typedef BOOL (WINAPI *WinUsb_ResetDevice_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle +); + +/* /!\ These must match the ones from the official libusbk.h */ +typedef enum _KUSB_FNID { + KUSB_FNID_Init, + KUSB_FNID_Free, + KUSB_FNID_ClaimInterface, + KUSB_FNID_ReleaseInterface, + KUSB_FNID_SetAltInterface, + KUSB_FNID_GetAltInterface, + KUSB_FNID_GetDescriptor, + KUSB_FNID_ControlTransfer, + KUSB_FNID_SetPowerPolicy, + KUSB_FNID_GetPowerPolicy, + KUSB_FNID_SetConfiguration, + KUSB_FNID_GetConfiguration, + KUSB_FNID_ResetDevice, + KUSB_FNID_Initialize, + KUSB_FNID_SelectInterface, + KUSB_FNID_GetAssociatedInterface, + KUSB_FNID_Clone, + KUSB_FNID_QueryInterfaceSettings, + KUSB_FNID_QueryDeviceInformation, + KUSB_FNID_SetCurrentAlternateSetting, + KUSB_FNID_GetCurrentAlternateSetting, + KUSB_FNID_QueryPipe, + KUSB_FNID_SetPipePolicy, + KUSB_FNID_GetPipePolicy, + KUSB_FNID_ReadPipe, + KUSB_FNID_WritePipe, + KUSB_FNID_ResetPipe, + KUSB_FNID_AbortPipe, + KUSB_FNID_FlushPipe, + KUSB_FNID_IsoReadPipe, + KUSB_FNID_IsoWritePipe, + KUSB_FNID_GetCurrentFrameNumber, + KUSB_FNID_GetOverlappedResult, + KUSB_FNID_GetProperty, + KUSB_FNID_COUNT, +} KUSB_FNID; + +typedef struct _KLIB_VERSION { + INT Major; + INT Minor; + INT Micro; + INT Nano; +} KLIB_VERSION; +typedef KLIB_VERSION* PKLIB_VERSION; + +typedef BOOL (WINAPI *LibK_GetProcAddress_t)( + PVOID *ProcAddress, + ULONG DriverID, + ULONG FunctionID +); + +typedef VOID (WINAPI *LibK_GetVersion_t)( + PKLIB_VERSION Version +); + +struct winusb_interface { + bool initialized; + WinUsb_AbortPipe_t AbortPipe; + WinUsb_ControlTransfer_t ControlTransfer; + WinUsb_FlushPipe_t FlushPipe; + WinUsb_Free_t Free; + WinUsb_GetAssociatedInterface_t GetAssociatedInterface; + WinUsb_GetCurrentAlternateSetting_t GetCurrentAlternateSetting; + WinUsb_GetDescriptor_t GetDescriptor; + WinUsb_GetOverlappedResult_t GetOverlappedResult; + WinUsb_GetPipePolicy_t GetPipePolicy; + WinUsb_GetPowerPolicy_t GetPowerPolicy; + WinUsb_Initialize_t Initialize; + WinUsb_QueryDeviceInformation_t QueryDeviceInformation; + WinUsb_QueryInterfaceSettings_t QueryInterfaceSettings; + WinUsb_QueryPipe_t QueryPipe; + WinUsb_ReadPipe_t ReadPipe; + WinUsb_ResetPipe_t ResetPipe; + WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting; + WinUsb_SetPipePolicy_t SetPipePolicy; + WinUsb_SetPowerPolicy_t SetPowerPolicy; + WinUsb_WritePipe_t WritePipe; + WinUsb_ResetDevice_t ResetDevice; +}; + +/* hid.dll interface */ + +typedef USHORT USAGE; diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/strerror.c b/go-api-for-hardware-wallet/usbhid/c/libusb/strerror.c new file mode 100644 index 00000000..d2be0e2a --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/strerror.c @@ -0,0 +1,202 @@ +/* + * libusb strerror code + * Copyright © 2013 Hans de Goede + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#if defined(HAVE_STRINGS_H) +#include +#endif + +#include "libusbi.h" + +#if defined(_MSC_VER) +#define strncasecmp _strnicmp +#endif + +static size_t usbi_locale = 0; + +/** \ingroup libusb_misc + * How to add a new \ref libusb_strerror() translation: + *
    + *
  1. Download the latest \c strerror.c from:
    + * https://raw.github.com/libusb/libusb/master/libusb/sterror.c
  2. + *
  3. Open the file in an UTF-8 capable editor
  4. + *
  5. Add the 2 letter ISO 639-1 + * code for your locale at the end of \c usbi_locale_supported[]
    + * Eg. for Chinese, you would add "zh" so that: + * \code... usbi_locale_supported[] = { "en", "nl", "fr" };\endcode + * becomes: + * \code... usbi_locale_supported[] = { "en", "nl", "fr", "zh" };\endcode
  6. + *
  7. Copy the { / * English (en) * / ... } section and add it at the end of \c usbi_localized_errors
    + * Eg. for Chinese, the last section of \c usbi_localized_errors could look like: + * \code + * }, { / * Chinese (zh) * / + * "Success", + * ... + * "Other error", + * } + * };\endcode
  8. + *
  9. Translate each of the English messages from the section you copied into your language
  10. + *
  11. Save the file (in UTF-8 format) and send it to \c libusb-devel\@lists.sourceforge.net
  12. + *
+ */ + +static const char* usbi_locale_supported[] = { "en", "nl", "fr", "ru" }; +static const char* usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT] = { + { /* English (en) */ + "Success", + "Input/Output Error", + "Invalid parameter", + "Access denied (insufficient permissions)", + "No such device (it may have been disconnected)", + "Entity not found", + "Resource busy", + "Operation timed out", + "Overflow", + "Pipe error", + "System call interrupted (perhaps due to signal)", + "Insufficient memory", + "Operation not supported or unimplemented on this platform", + "Other error", + }, { /* Dutch (nl) */ + "Gelukt", + "Invoer-/uitvoerfout", + "Ongeldig argument", + "Toegang geweigerd (onvoldoende toegangsrechten)", + "Apparaat bestaat niet (verbinding met apparaat verbroken?)", + "Niet gevonden", + "Apparaat of hulpbron is bezig", + "Bewerking verlopen", + "Waarde is te groot", + "Gebroken pijp", + "Onderbroken systeemaanroep", + "Onvoldoende geheugen beschikbaar", + "Bewerking wordt niet ondersteund", + "Andere fout", + }, { /* French (fr) */ + "Succès", + "Erreur d'entrée/sortie", + "Paramètre invalide", + "Accès refusé (permissions insuffisantes)", + "Périphérique introuvable (peut-être déconnecté)", + "Elément introuvable", + "Resource déjà occupée", + "Operation expirée", + "Débordement", + "Erreur de pipe", + "Appel système abandonné (peut-être à cause d’un signal)", + "Mémoire insuffisante", + "Opération non supportée or non implémentée sur cette plateforme", + "Autre erreur", + }, { /* Russian (ru) */ + "Успех", + "Ошибка ввода/вывода", + "Неверный параметр", + "Доступ запрещён (не хватает прав)", + "Устройство отсутствует (возможно, оно было отсоединено)", + "Элемент не найден", + "Ресурс занят", + "Истекло время ожидания операции", + "Переполнение", + "Ошибка канала", + "Системный вызов прерван (возможно, сигналом)", + "Память исчерпана", + "Операция не поддерживается данной платформой", + "Неизвестная ошибка" + } +}; + +/** \ingroup libusb_misc + * Set the language, and only the language, not the encoding! used for + * translatable libusb messages. + * + * This takes a locale string in the default setlocale format: lang[-region] + * or lang[_country_region][.codeset]. Only the lang part of the string is + * used, and only 2 letter ISO 639-1 codes are accepted for it, such as "de". + * The optional region, country_region or codeset parts are ignored. This + * means that functions which return translatable strings will NOT honor the + * specified encoding. + * All strings returned are encoded as UTF-8 strings. + * + * If libusb_setlocale() is not called, all messages will be in English. + * + * The following functions return translatable strings: libusb_strerror(). + * Note that the libusb log messages controlled through libusb_set_debug() + * are not translated, they are always in English. + * + * For POSIX UTF-8 environments if you want libusb to follow the standard + * locale settings, call libusb_setlocale(setlocale(LC_MESSAGES, NULL)), + * after your app has done its locale setup. + * + * \param locale locale-string in the form of lang[_country_region][.codeset] + * or lang[-region], where lang is a 2 letter ISO 639-1 code + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_INVALID_PARAM if the locale doesn't meet the requirements + * \returns LIBUSB_ERROR_NOT_FOUND if the requested language is not supported + * \returns a LIBUSB_ERROR code on other errors + */ + +int API_EXPORTED libusb_setlocale(const char *locale) +{ + size_t i; + + if ( (locale == NULL) || (strlen(locale) < 2) + || ((strlen(locale) > 2) && (locale[2] != '-') && (locale[2] != '_') && (locale[2] != '.')) ) + return LIBUSB_ERROR_INVALID_PARAM; + + for (i=0; i= ARRAYSIZE(usbi_locale_supported)) { + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_locale = i; + + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_misc + * Returns a constant string with a short description of the given error code, + * this description is intended for displaying to the end user and will be in + * the language set by libusb_setlocale(). + * + * The returned string is encoded in UTF-8. + * + * The messages always start with a capital letter and end without any dot. + * The caller must not free() the returned string. + * + * \param errcode the error code whose description is desired + * \returns a short description of the error code in UTF-8 encoding + */ +DEFAULT_VISIBILITY const char* LIBUSB_CALL libusb_strerror(enum libusb_error errcode) +{ + int errcode_index = -errcode; + + if ((errcode_index < 0) || (errcode_index >= LIBUSB_ERROR_COUNT)) { + /* "Other Error", which should always be our last message, is returned */ + errcode_index = LIBUSB_ERROR_COUNT - 1; + } + + return usbi_localized_errors[usbi_locale][errcode_index]; +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/sync.c b/go-api-for-hardware-wallet/usbhid/c/libusb/sync.c new file mode 100644 index 00000000..a609f65f --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/sync.c @@ -0,0 +1,327 @@ +/* + * Synchronous I/O functions for libusb + * Copyright © 2007-2008 Daniel Drake + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +/** + * @defgroup libusb_syncio Synchronous device I/O + * + * This page documents libusb's synchronous (blocking) API for USB device I/O. + * This interface is easy to use but has some limitations. More advanced users + * may wish to consider using the \ref libusb_asyncio "asynchronous I/O API" instead. + */ + +static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer) +{ + int *completed = transfer->user_data; + *completed = 1; + usbi_dbg("actual_length=%d", transfer->actual_length); + /* caller interprets result and frees transfer */ +} + +static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer) +{ + int r, *completed = transfer->user_data; + struct libusb_context *ctx = HANDLE_CTX(transfer->dev_handle); + + while (!*completed) { + r = libusb_handle_events_completed(ctx, completed); + if (r < 0) { + if (r == LIBUSB_ERROR_INTERRUPTED) + continue; + usbi_err(ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying", + libusb_error_name(r)); + libusb_cancel_transfer(transfer); + continue; + } + } +} + +/** \ingroup libusb_syncio + * Perform a USB control transfer. + * + * The direction of the transfer is inferred from the bmRequestType field of + * the setup packet. + * + * The wValue, wIndex and wLength fields values should be given in host-endian + * byte order. + * + * \param dev_handle a handle for the device to communicate with + * \param bmRequestType the request type field for the setup packet + * \param bRequest the request field for the setup packet + * \param wValue the value field for the setup packet + * \param wIndex the index field for the setup packet + * \param data a suitably-sized data buffer for either input or output + * (depending on direction bits within bmRequestType) + * \param wLength the length field for the setup packet. The data buffer should + * be at least this size. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * \returns on success, the number of bytes actually transferred + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out + * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the + * device + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than + * the operating system and/or hardware can support + * \returns another LIBUSB_ERROR code on other failures + */ +int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout) +{ + struct libusb_transfer *transfer; + unsigned char *buffer; + int completed = 0; + int r; + + if (usbi_handling_events(HANDLE_CTX(dev_handle))) + return LIBUSB_ERROR_BUSY; + + transfer = libusb_alloc_transfer(0); + if (!transfer) + return LIBUSB_ERROR_NO_MEM; + + buffer = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength); + if (!buffer) { + libusb_free_transfer(transfer); + return LIBUSB_ERROR_NO_MEM; + } + + libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, + wLength); + if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) + memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); + + libusb_fill_control_transfer(transfer, dev_handle, buffer, + sync_transfer_cb, &completed, timeout); + transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + return r; + } + + sync_transfer_wait_for_completion(transfer); + + if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) + memcpy(data, libusb_control_transfer_get_data(transfer), + transfer->actual_length); + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + r = transfer->actual_length; + break; + case LIBUSB_TRANSFER_TIMED_OUT: + r = LIBUSB_ERROR_TIMEOUT; + break; + case LIBUSB_TRANSFER_STALL: + r = LIBUSB_ERROR_PIPE; + break; + case LIBUSB_TRANSFER_NO_DEVICE: + r = LIBUSB_ERROR_NO_DEVICE; + break; + case LIBUSB_TRANSFER_OVERFLOW: + r = LIBUSB_ERROR_OVERFLOW; + break; + case LIBUSB_TRANSFER_ERROR: + case LIBUSB_TRANSFER_CANCELLED: + r = LIBUSB_ERROR_IO; + break; + default: + usbi_warn(HANDLE_CTX(dev_handle), + "unrecognised status code %d", transfer->status); + r = LIBUSB_ERROR_OTHER; + } + + libusb_free_transfer(transfer); + return r; +} + +static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + int *transferred, unsigned int timeout, unsigned char type) +{ + struct libusb_transfer *transfer; + int completed = 0; + int r; + + if (usbi_handling_events(HANDLE_CTX(dev_handle))) + return LIBUSB_ERROR_BUSY; + + transfer = libusb_alloc_transfer(0); + if (!transfer) + return LIBUSB_ERROR_NO_MEM; + + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length, + sync_transfer_cb, &completed, timeout); + transfer->type = type; + + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + return r; + } + + sync_transfer_wait_for_completion(transfer); + + if (transferred) + *transferred = transfer->actual_length; + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + r = 0; + break; + case LIBUSB_TRANSFER_TIMED_OUT: + r = LIBUSB_ERROR_TIMEOUT; + break; + case LIBUSB_TRANSFER_STALL: + r = LIBUSB_ERROR_PIPE; + break; + case LIBUSB_TRANSFER_OVERFLOW: + r = LIBUSB_ERROR_OVERFLOW; + break; + case LIBUSB_TRANSFER_NO_DEVICE: + r = LIBUSB_ERROR_NO_DEVICE; + break; + case LIBUSB_TRANSFER_ERROR: + case LIBUSB_TRANSFER_CANCELLED: + r = LIBUSB_ERROR_IO; + break; + default: + usbi_warn(HANDLE_CTX(dev_handle), + "unrecognised status code %d", transfer->status); + r = LIBUSB_ERROR_OTHER; + } + + libusb_free_transfer(transfer); + return r; +} + +/** \ingroup libusb_syncio + * Perform a USB bulk transfer. The direction of the transfer is inferred from + * the direction bits of the endpoint address. + * + * For bulk reads, the length field indicates the maximum length of + * data you are expecting to receive. If less data arrives than expected, + * this function will return that data, so be sure to check the + * transferred output parameter. + * + * You should also check the transferred parameter for bulk writes. + * Not all of the data may have been written. + * + * Also check transferred when dealing with a timeout error code. + * libusb may have to split your transfer into a number of chunks to satisfy + * underlying O/S requirements, meaning that the timeout may expire after + * the first few chunks have completed. libusb is careful not to lose any data + * that may have been transferred; do not assume that timeout conditions + * indicate a complete lack of I/O. + * + * \param dev_handle a handle for the device to communicate with + * \param endpoint the address of a valid endpoint to communicate with + * \param data a suitably-sized data buffer for either input or output + * (depending on endpoint) + * \param length for bulk writes, the number of bytes from data to be sent. for + * bulk reads, the maximum number of bytes to receive into the data buffer. + * \param transferred output location for the number of bytes actually + * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), + * it is legal to pass a NULL pointer if you do not wish to receive this + * information. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * + * \returns 0 on success (and populates transferred) + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates + * transferred) + * \returns LIBUSB_ERROR_PIPE if the endpoint halted + * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see + * \ref libusb_packetoverflow + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns another LIBUSB_ERROR code on other failures + */ +int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, int *transferred, + unsigned int timeout) +{ + return do_sync_bulk_transfer(dev_handle, endpoint, data, length, + transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK); +} + +/** \ingroup libusb_syncio + * Perform a USB interrupt transfer. The direction of the transfer is inferred + * from the direction bits of the endpoint address. + * + * For interrupt reads, the length field indicates the maximum length + * of data you are expecting to receive. If less data arrives than expected, + * this function will return that data, so be sure to check the + * transferred output parameter. + * + * You should also check the transferred parameter for interrupt + * writes. Not all of the data may have been written. + * + * Also check transferred when dealing with a timeout error code. + * libusb may have to split your transfer into a number of chunks to satisfy + * underlying O/S requirements, meaning that the timeout may expire after + * the first few chunks have completed. libusb is careful not to lose any data + * that may have been transferred; do not assume that timeout conditions + * indicate a complete lack of I/O. + * + * The default endpoint bInterval value is used as the polling interval. + * + * \param dev_handle a handle for the device to communicate with + * \param endpoint the address of a valid endpoint to communicate with + * \param data a suitably-sized data buffer for either input or output + * (depending on endpoint) + * \param length for bulk writes, the number of bytes from data to be sent. for + * bulk reads, the maximum number of bytes to receive into the data buffer. + * \param transferred output location for the number of bytes actually + * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), + * it is legal to pass a NULL pointer if you do not wish to receive this + * information. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * + * \returns 0 on success (and populates transferred) + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out + * \returns LIBUSB_ERROR_PIPE if the endpoint halted + * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see + * \ref libusb_packetoverflow + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns another LIBUSB_ERROR code on other error + */ +int API_EXPORTED libusb_interrupt_transfer( + struct libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *data, int length, int *transferred, unsigned int timeout) +{ + return do_sync_bulk_transfer(dev_handle, endpoint, data, length, + transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); +} diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/version.h b/go-api-for-hardware-wallet/usbhid/c/libusb/version.h new file mode 100644 index 00000000..6ce48a7d --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/version.h @@ -0,0 +1,18 @@ +/* This file is parsed by m4 and windres and RC.EXE so please keep it simple. */ +#include "version_nano.h" +#ifndef LIBUSB_MAJOR +#define LIBUSB_MAJOR 1 +#endif +#ifndef LIBUSB_MINOR +#define LIBUSB_MINOR 0 +#endif +#ifndef LIBUSB_MICRO +#define LIBUSB_MICRO 21 +#endif +#ifndef LIBUSB_NANO +#define LIBUSB_NANO 0 +#endif +/* LIBUSB_RC is the release candidate suffix. Should normally be empty. */ +#ifndef LIBUSB_RC +#define LIBUSB_RC "" +#endif diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/version_nano.h b/go-api-for-hardware-wallet/usbhid/c/libusb/version_nano.h new file mode 100644 index 00000000..0a5d1c99 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/c/libusb/version_nano.h @@ -0,0 +1 @@ +#define LIBUSB_NANO 11182 diff --git a/go-api-for-hardware-wallet/usbhid/hid.go b/go-api-for-hardware-wallet/usbhid/hid.go new file mode 100644 index 00000000..8a37928e --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/hid.go @@ -0,0 +1,270 @@ +// hid - Gopher Interface Devices (USB HID) +// Copyright (c) 2017 Péter Szilágyi. All rights reserved. +// +// This file is released under the 3-clause BSD license. Note however that Linux +// support depends on libusb, released under GNU LGPL 2.1 or later. + +// Package hid provides an interface for USB HID devices. + +// +build linux,cgo darwin,!ios,cgo windows,cgo + +package usbhid + +/* +#cgo CFLAGS: -I./c/hidapi -I./c/libusb + +#cgo linux CFLAGS: -DDEFAULT_VISIBILITY="" -DOS_LINUX -D_GNU_SOURCE -DPOLL_NFDS_TYPE=int +#cgo linux,!android LDFLAGS: -lrt +#cgo darwin CFLAGS: -DOS_DARWIN -DDEFAULT_VISIBILITY="" -DPOLL_NFDS_TYPE="unsigned int" +#cgo darwin LDFLAGS: -framework CoreFoundation -framework IOKit -lobjc +#cgo windows CFLAGS: -DOS_WINDOWS -DDEFAULT_VISIBILITY="" -DPOLL_NFDS_TYPE="unsigned int" +#cgo windows LDFLAGS: -lsetupapi + + +#ifdef OS_LINUX + #include + + #include "os/threads_posix.c" + #include "os/poll_posix.c" + #include "os/linux_usbfs.c" + #include "os/linux_netlink.c" +#elif OS_DARWIN + #include + + #include "os/threads_posix.c" + #include "os/poll_posix.c" + #include "os/darwin_usb.c" +#elif OS_WINDOWS + #include + + #include "os/poll_windows.c" + #include "os/threads_windows.c" +#endif + +#include "core.c" +#include "descriptor.c" +#include "hotplug.c" +#include "io.c" +#include "strerror.c" +#include "sync.c" + +#ifdef OS_LINUX + #include "linux/hid.c" +#elif OS_DARWIN + #include "mac/hid.c" +#elif OS_WINDOWS + #include "windows/hid.c" + + #include "os/windows_nt_common.c" + #include "os/windows_winusb.c" +#endif + +*/ +import "C" + +import ( + "errors" + "runtime" + "sync" + "unsafe" +) + +// ErrDeviceClosed is returned for operations where the device closed before or +// during the execution. +var ErrDeviceClosed = errors.New("hid: device closed") + +// ErrUnsupportedPlatform is returned for all operations where the underlying +// operating system is not supported by the library. +var ErrUnsupportedPlatform = errors.New("hid: unsupported platform") + +// HidDeviceInfo is a hidapi info structure. +type HidDeviceInfo struct { + Path string // Platform-specific device path + VendorID uint16 // Device Vendor ID + ProductID uint16 // Device Product ID + Release uint16 // Device Release Number in binary-coded decimal, also known as Device Version Number + Serial string // Serial Number + Manufacturer string // Manufacturer String + Product string // Product string + UsagePage uint16 // Usage Page for this Device/Interface (Windows/Mac only) + Usage uint16 // Usage for this Device/Interface (Windows/Mac only) + + // The USB interface which this logical device + // represents. Valid on both Linux implementations + // in all cases, and valid on the Windows implementation + // only if the device contains more than one interface. + Interface int +} + +// enumerateLock is a mutex serializing access to USB device enumeration needed +// by the macOS USB HID system calls, which require 2 consecutive method calls +// for enumeration, causing crashes if called concurrently. +// +// For more details, see: +// https://developer.apple.com/documentation/iokit/1438371-iohidmanagersetdevicematching +// > "subsequent calls will cause the hid manager to release previously enumerated devices" +var enumerateLock sync.Mutex + +func init() { + // Initialize the HIDAPI library + C.hid_init() +} + +// Enumerate returns a list of all the HID devices attached to the system which +// match the vendor and product id: +// - If the vendor id is set to 0 then any vendor matches. +// - If the product id is set to 0 then any product matches. +// - If the vendor and product id are both 0, all HID devices are returned. +func HidEnumerate(vendorID uint16, productID uint16) []HidDeviceInfo { + enumerateLock.Lock() + defer enumerateLock.Unlock() + + // Gather all device infos and ensure they are freed before returning + head := C.hid_enumerate(C.ushort(vendorID), C.ushort(productID)) + if head == nil { + return nil + } + defer C.hid_free_enumeration(head) + + // Iterate the list and retrieve the device details + var infos []HidDeviceInfo + for ; head != nil; head = head.next { + info := HidDeviceInfo{ + Path: C.GoString(head.path), + VendorID: uint16(head.vendor_id), + ProductID: uint16(head.product_id), + Release: uint16(head.release_number), + UsagePage: uint16(head.usage_page), + Usage: uint16(head.usage), + Interface: int(head.interface_number), + } + if head.serial_number != nil { + info.Serial, _ = wcharTToString(head.serial_number) + } + if head.product_string != nil { + info.Product, _ = wcharTToString(head.product_string) + } + if head.manufacturer_string != nil { + info.Manufacturer, _ = wcharTToString(head.manufacturer_string) + } + infos = append(infos, info) + } + return infos +} + +// Open connects to an HID device by its path name. +func (info HidDeviceInfo) Open() (*HidDevice, error) { + path := C.CString(info.Path) + defer C.free(unsafe.Pointer(path)) + + device := C.hid_open_path(path) + if device == nil { + return nil, errors.New("hidapi: failed to open device") + } + return &HidDevice{ + HidDeviceInfo: info, + device: device, + }, nil +} + +// Device is a live HID USB connected device handle. +type HidDevice struct { + HidDeviceInfo // Embed the infos for easier access + + device *C.hid_device // Low level HID device to communicate through + lock sync.Mutex +} + +// Close releases the HID USB device handle. +func (dev *HidDevice) Close() error { + dev.lock.Lock() + defer dev.lock.Unlock() + + if dev.device != nil { + C.hid_close(dev.device) + dev.device = nil + } + return nil +} + +// Write sends an output report to a HID device. +// +// Write will send the data on the first OUT endpoint, if one exists. If it does +// not, it will send the data through the Control Endpoint (Endpoint 0). +func (dev *HidDevice) Write(b []byte, prepend bool) (int, error) { + // Abort if nothing to write + if len(b) == 0 { + return 0, nil + } + // Abort if device closed in between + dev.lock.Lock() + device := dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Prepend a HID report ID on Windows, other OSes don't need it + var report []byte + if prepend && runtime.GOOS == "windows" { + report = append([]byte{0x00}, b...) + } else { + report = b + } + // Execute the write operation + written := int(C.hid_write(device, (*C.uchar)(&report[0]), C.size_t(len(report)))) + if written == -1 { + // If the write failed, verify if closed or other error + dev.lock.Lock() + device = dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Device not closed, some other error occurred + message := C.hid_error(device) + if message == nil { + return 0, errors.New("hidapi: unknown failure") + } + failure, _ := wcharTToString(message) + return 0, errors.New("hidapi: " + failure) + } + return written, nil +} + +// Read retrieves an input report from a HID device. +func (dev *HidDevice) Read(b []byte) (int, error) { + // Aborth if nothing to read + if len(b) == 0 { + return 0, nil + } + // Abort if device closed in between + dev.lock.Lock() + device := dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Execute the read operation + read := int(C.hid_read(device, (*C.uchar)(&b[0]), C.size_t(len(b)))) + if read == -1 { + // If the read failed, verify if closed or other error + dev.lock.Lock() + device = dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Device not closed, some other error occurred + message := C.hid_error(device) + if message == nil { + return 0, errors.New("hidapi: unknown failure") + } + failure, _ := wcharTToString(message) + return 0, errors.New("hidapi: " + failure) + } + return read, nil +} diff --git a/go-api-for-hardware-wallet/usbhid/libusb.go b/go-api-for-hardware-wallet/usbhid/libusb.go new file mode 100644 index 00000000..13a2a663 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/libusb.go @@ -0,0 +1,1361 @@ +//----------------------------------------------------------------------------- +/* + +Golang wrapper for libusb-1.0 + +Copyright (c) 2017 Jason T. Harris + +*/ +//----------------------------------------------------------------------------- + +// Package libusb provides go wrappers for libusb-1.0 +package usbhid + +/* +// +build linux,cgo darwin,!ios,cgo windows,cgo + +#include "./c/libusb/libusb.h" + +// When a C struct ends with a zero-sized field, but the struct itself is not zero-sized, +// Go code can no longer refer to the zero-sized field. Any such references will have to be rewritten. +// https://golang.org/doc/go1.5#cgo +// https://github.com/golang/go/issues/11925 + +static uint8_t *dev_capability_data_ptr(struct libusb_bos_dev_capability_descriptor *x) { + return &x->dev_capability_data[0]; +} + +static struct libusb_bos_dev_capability_descriptor **dev_capability_ptr(struct libusb_bos_descriptor *x) { + return &x->dev_capability[0]; +} + +*/ +import "C" + +import ( + "fmt" + "reflect" + "strings" + "unsafe" +) + +//----------------------------------------------------------------------------- +// utilities + +func bcd2str(x uint16) string { + if (x>>12)&15 != 0 { + return fmt.Sprintf("%d%d.%d%d", (x>>12)&15, (x>>8)&15, (x>>4)&15, (x>>0)&15) + } else { + return fmt.Sprintf("%d.%d%d", (x>>8)&15, (x>>4)&15, (x>>0)&15) + } +} + +func indent(s string) string { + x := strings.Split(s, "\n") + for i, _ := range x { + x[i] = fmt.Sprintf("%s%s", " ", x[i]) + } + return strings.Join(x, "\n") +} + +// return a string for the extra buffer +func Extra_str(x []byte) string { + s := make([]string, len(x)) + for i, v := range x { + s[i] = fmt.Sprintf("%02x", v) + } + return fmt.Sprintf("[%s]", strings.Join(s, " ")) +} + +//----------------------------------------------------------------------------- + +// libusb API version. +const API_VERSION = C.LIBUSB_API_VERSION + +// Device and/or Interface Class codes. +const ( + CLASS_PER_INTERFACE = C.LIBUSB_CLASS_PER_INTERFACE + CLASS_AUDIO = C.LIBUSB_CLASS_AUDIO + CLASS_COMM = C.LIBUSB_CLASS_COMM + CLASS_HID = C.LIBUSB_CLASS_HID + CLASS_PHYSICAL = C.LIBUSB_CLASS_PHYSICAL + CLASS_PRINTER = C.LIBUSB_CLASS_PRINTER + CLASS_PTP = C.LIBUSB_CLASS_PTP + CLASS_IMAGE = C.LIBUSB_CLASS_IMAGE + CLASS_MASS_STORAGE = C.LIBUSB_CLASS_MASS_STORAGE + CLASS_HUB = C.LIBUSB_CLASS_HUB + CLASS_DATA = C.LIBUSB_CLASS_DATA + CLASS_SMART_CARD = C.LIBUSB_CLASS_SMART_CARD + CLASS_CONTENT_SECURITY = C.LIBUSB_CLASS_CONTENT_SECURITY + CLASS_VIDEO = C.LIBUSB_CLASS_VIDEO + CLASS_PERSONAL_HEALTHCARE = C.LIBUSB_CLASS_PERSONAL_HEALTHCARE + CLASS_DIAGNOSTIC_DEVICE = C.LIBUSB_CLASS_DIAGNOSTIC_DEVICE + CLASS_WIRELESS = C.LIBUSB_CLASS_WIRELESS + CLASS_APPLICATION = C.LIBUSB_CLASS_APPLICATION + CLASS_VENDOR_SPEC = C.LIBUSB_CLASS_VENDOR_SPEC +) + +// Descriptor types as defined by the USB specification. +const ( + DT_DEVICE = C.LIBUSB_DT_DEVICE + DT_CONFIG = C.LIBUSB_DT_CONFIG + DT_STRING = C.LIBUSB_DT_STRING + DT_INTERFACE = C.LIBUSB_DT_INTERFACE + DT_ENDPOINT = C.LIBUSB_DT_ENDPOINT + DT_BOS = C.LIBUSB_DT_BOS + DT_DEVICE_CAPABILITY = C.LIBUSB_DT_DEVICE_CAPABILITY + DT_HID = C.LIBUSB_DT_HID + DT_REPORT = C.LIBUSB_DT_REPORT + DT_PHYSICAL = C.LIBUSB_DT_PHYSICAL + DT_HUB = C.LIBUSB_DT_HUB + DT_SUPERSPEED_HUB = C.LIBUSB_DT_SUPERSPEED_HUB + DT_SS_ENDPOINT_COMPANION = C.LIBUSB_DT_SS_ENDPOINT_COMPANION +) + +// Descriptor sizes per descriptor type. +const DT_DEVICE_SIZE = C.LIBUSB_DT_DEVICE_SIZE +const DT_CONFIG_SIZE = C.LIBUSB_DT_CONFIG_SIZE +const DT_INTERFACE_SIZE = C.LIBUSB_DT_INTERFACE_SIZE +const DT_ENDPOINT_SIZE = C.LIBUSB_DT_ENDPOINT_SIZE +const DT_ENDPOINT_AUDIO_SIZE = C.LIBUSB_DT_ENDPOINT_AUDIO_SIZE +const DT_HUB_NONVAR_SIZE = C.LIBUSB_DT_HUB_NONVAR_SIZE +const DT_SS_ENDPOINT_COMPANION_SIZE = C.LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE +const DT_BOS_SIZE = C.LIBUSB_DT_BOS_SIZE +const DT_DEVICE_CAPABILITY_SIZE = C.LIBUSB_DT_DEVICE_CAPABILITY_SIZE + +// BOS descriptor sizes. +const BT_USB_2_0_EXTENSION_SIZE = C.LIBUSB_BT_USB_2_0_EXTENSION_SIZE +const BT_SS_USB_DEVICE_CAPABILITY_SIZE = C.LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE +const BT_CONTAINER_ID_SIZE = C.LIBUSB_BT_CONTAINER_ID_SIZE +const DT_BOS_MAX_SIZE = C.LIBUSB_DT_BOS_MAX_SIZE +const ENDPOINT_ADDRESS_MASK = C.LIBUSB_ENDPOINT_ADDRESS_MASK +const ENDPOINT_DIR_MASK = C.LIBUSB_ENDPOINT_DIR_MASK + +// Endpoint direction. Values for bit 7 of Endpoint_Descriptor.BEndpointAddress. +const ( + ENDPOINT_IN = C.LIBUSB_ENDPOINT_IN // In: device-to-host. + ENDPOINT_OUT = C.LIBUSB_ENDPOINT_OUT // Out: host-to-device. +) + +// in BmAttributes +const TRANSFER_TYPE_MASK = C.LIBUSB_TRANSFER_TYPE_MASK + +// Endpoint transfer type. Values for bits 0:1 of Endpoint_Descriptor.BmAttributes. +const ( + TRANSFER_TYPE_CONTROL = C.LIBUSB_TRANSFER_TYPE_CONTROL + TRANSFER_TYPE_ISOCHRONOUS = C.LIBUSB_TRANSFER_TYPE_ISOCHRONOUS + TRANSFER_TYPE_BULK = C.LIBUSB_TRANSFER_TYPE_BULK + TRANSFER_TYPE_INTERRUPT = C.LIBUSB_TRANSFER_TYPE_INTERRUPT + TRANSFER_TYPE_BULK_STREAM = C.LIBUSB_TRANSFER_TYPE_BULK_STREAM +) + +// Standard requests, as defined in table 9-5 of the USB 3.0 specifications. +const ( + REQUEST_GET_STATUS = C.LIBUSB_REQUEST_GET_STATUS + REQUEST_CLEAR_FEATURE = C.LIBUSB_REQUEST_CLEAR_FEATURE + REQUEST_SET_FEATURE = C.LIBUSB_REQUEST_SET_FEATURE + REQUEST_SET_ADDRESS = C.LIBUSB_REQUEST_SET_ADDRESS + REQUEST_GET_DESCRIPTOR = C.LIBUSB_REQUEST_GET_DESCRIPTOR + REQUEST_SET_DESCRIPTOR = C.LIBUSB_REQUEST_SET_DESCRIPTOR + REQUEST_GET_CONFIGURATION = C.LIBUSB_REQUEST_GET_CONFIGURATION + REQUEST_SET_CONFIGURATION = C.LIBUSB_REQUEST_SET_CONFIGURATION + REQUEST_GET_INTERFACE = C.LIBUSB_REQUEST_GET_INTERFACE + REQUEST_SET_INTERFACE = C.LIBUSB_REQUEST_SET_INTERFACE + REQUEST_SYNCH_FRAME = C.LIBUSB_REQUEST_SYNCH_FRAME + REQUEST_SET_SEL = C.LIBUSB_REQUEST_SET_SEL + SET_ISOCH_DELAY = C.LIBUSB_SET_ISOCH_DELAY +) + +// Request type bits of Control_Setup.BmRequestType. +const ( + REQUEST_TYPE_STANDARD = C.LIBUSB_REQUEST_TYPE_STANDARD + REQUEST_TYPE_CLASS = C.LIBUSB_REQUEST_TYPE_CLASS + REQUEST_TYPE_VENDOR = C.LIBUSB_REQUEST_TYPE_VENDOR + REQUEST_TYPE_RESERVED = C.LIBUSB_REQUEST_TYPE_RESERVED +) + +// Recipient bits of Control_Setup.BmRequestType in control transfers. +// Values 4 through 31 are reserved. +const ( + RECIPIENT_DEVICE = C.LIBUSB_RECIPIENT_DEVICE + RECIPIENT_INTERFACE = C.LIBUSB_RECIPIENT_INTERFACE + RECIPIENT_ENDPOINT = C.LIBUSB_RECIPIENT_ENDPOINT + RECIPIENT_OTHER = C.LIBUSB_RECIPIENT_OTHER +) + +const ISO_SYNC_TYPE_MASK = C.LIBUSB_ISO_SYNC_TYPE_MASK + +// Synchronization type for isochronous endpoints. +// Values for bits 2:3 of Endpoint_Descriptor.BmAttributes. +const ( + ISO_SYNC_TYPE_NONE = C.LIBUSB_ISO_SYNC_TYPE_NONE + ISO_SYNC_TYPE_ASYNC = C.LIBUSB_ISO_SYNC_TYPE_ASYNC + ISO_SYNC_TYPE_ADAPTIVE = C.LIBUSB_ISO_SYNC_TYPE_ADAPTIVE + ISO_SYNC_TYPE_SYNC = C.LIBUSB_ISO_SYNC_TYPE_SYNC +) + +const ISO_USAGE_TYPE_MASK = C.LIBUSB_ISO_USAGE_TYPE_MASK + +// Usage type for isochronous endpoints. +// Values for bits 4:5 of Endpoint_Descriptor.BmAttributes. +const ( + ISO_USAGE_TYPE_DATA = C.LIBUSB_ISO_USAGE_TYPE_DATA + ISO_USAGE_TYPE_FEEDBACK = C.LIBUSB_ISO_USAGE_TYPE_FEEDBACK + ISO_USAGE_TYPE_IMPLICIT = C.LIBUSB_ISO_USAGE_TYPE_IMPLICIT +) + +const CONTROL_SETUP_SIZE = C.LIBUSB_CONTROL_SETUP_SIZE + +// Speed codes. Indicates the speed at which the device is operating. +const ( + SPEED_UNKNOWN = C.LIBUSB_SPEED_UNKNOWN + SPEED_LOW = C.LIBUSB_SPEED_LOW + SPEED_FULL = C.LIBUSB_SPEED_FULL + SPEED_HIGH = C.LIBUSB_SPEED_HIGH + SPEED_SUPER = C.LIBUSB_SPEED_SUPER +) + +// Supported speeds (WSpeedSupported) bitfield. Indicates what speeds the device supports. +const ( + LOW_SPEED_OPERATION = C.LIBUSB_LOW_SPEED_OPERATION + FULL_SPEED_OPERATION = C.LIBUSB_FULL_SPEED_OPERATION + HIGH_SPEED_OPERATION = C.LIBUSB_HIGH_SPEED_OPERATION + SUPER_SPEED_OPERATION = C.LIBUSB_SUPER_SPEED_OPERATION +) + +// Bitmasks for USB_2_0_Extension_Descriptor.BmAttributes. +const ( + BM_LPM_SUPPORT = C.LIBUSB_BM_LPM_SUPPORT +) + +// Bitmasks for SS_USB_Device_Capability_Descriptor.BmAttributes. +const ( + BM_LTM_SUPPORT = C.LIBUSB_BM_LTM_SUPPORT +) + +// USB capability types. +const ( + BT_WIRELESS_USB_DEVICE_CAPABILITY = C.LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY + BT_USB_2_0_EXTENSION = C.LIBUSB_BT_USB_2_0_EXTENSION + BT_SS_USB_DEVICE_CAPABILITY = C.LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + BT_CONTAINER_ID = C.LIBUSB_BT_CONTAINER_ID +) + +// Error codes. +const ( + SUCCESS = C.LIBUSB_SUCCESS + ERROR_IO = C.LIBUSB_ERROR_IO + ERROR_INVALID_PARAM = C.LIBUSB_ERROR_INVALID_PARAM + ERROR_ACCESS = C.LIBUSB_ERROR_ACCESS + ERROR_NO_DEVICE = C.LIBUSB_ERROR_NO_DEVICE + ERROR_NOT_FOUND = C.LIBUSB_ERROR_NOT_FOUND + ERROR_BUSY = C.LIBUSB_ERROR_BUSY + ERROR_TIMEOUT = C.LIBUSB_ERROR_TIMEOUT + ERROR_OVERFLOW = C.LIBUSB_ERROR_OVERFLOW + ERROR_PIPE = C.LIBUSB_ERROR_PIPE + ERROR_INTERRUPTED = C.LIBUSB_ERROR_INTERRUPTED + ERROR_NO_MEM = C.LIBUSB_ERROR_NO_MEM + ERROR_NOT_SUPPORTED = C.LIBUSB_ERROR_NOT_SUPPORTED + ERROR_OTHER = C.LIBUSB_ERROR_OTHER +) + +// Total number of error codes. +const ERROR_COUNT = C.LIBUSB_ERROR_COUNT + +// Transfer status codes. +const ( + TRANSFER_COMPLETED = C.LIBUSB_TRANSFER_COMPLETED + TRANSFER_ERROR = C.LIBUSB_TRANSFER_ERROR + TRANSFER_TIMED_OUT = C.LIBUSB_TRANSFER_TIMED_OUT + TRANSFER_CANCELLED = C.LIBUSB_TRANSFER_CANCELLED + TRANSFER_STALL = C.LIBUSB_TRANSFER_STALL + TRANSFER_NO_DEVICE = C.LIBUSB_TRANSFER_NO_DEVICE + TRANSFER_OVERFLOW = C.LIBUSB_TRANSFER_OVERFLOW +) + +// Transfer.Flags values. +const ( + TRANSFER_SHORT_NOT_OK = C.LIBUSB_TRANSFER_SHORT_NOT_OK + TRANSFER_FREE_BUFFER = C.LIBUSB_TRANSFER_FREE_BUFFER + TRANSFER_FREE_TRANSFER = C.LIBUSB_TRANSFER_FREE_TRANSFER + TRANSFER_ADD_ZERO_PACKET = C.LIBUSB_TRANSFER_ADD_ZERO_PACKET +) + +// Capabilities supported by an instance of libusb on the current running platform. +// Test if the loaded library supports a given capability by calling Has_Capability(). +const ( + CAP_HAS_CAPABILITY = C.LIBUSB_CAP_HAS_CAPABILITY + CAP_HAS_HOTPLUG = C.LIBUSB_CAP_HAS_HOTPLUG + CAP_HAS_HID_ACCESS = C.LIBUSB_CAP_HAS_HID_ACCESS + CAP_SUPPORTS_DETACH_KERNEL_DRIVER = C.LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER +) + +// Log message levels. +const ( + LOG_LEVEL_NONE = C.LIBUSB_LOG_LEVEL_NONE + LOG_LEVEL_ERROR = C.LIBUSB_LOG_LEVEL_ERROR + LOG_LEVEL_WARNING = C.LIBUSB_LOG_LEVEL_WARNING + LOG_LEVEL_INFO = C.LIBUSB_LOG_LEVEL_INFO + LOG_LEVEL_DEBUG = C.LIBUSB_LOG_LEVEL_DEBUG +) + +// Flags for hotplug events. +const ( + //HOTPLUG_NO_FLAGS = C.LIBUSB_HOTPLUG_NO_FLAGS + HOTPLUG_ENUMERATE = C.LIBUSB_HOTPLUG_ENUMERATE +) + +// Hotplug events. +const ( + HOTPLUG_EVENT_DEVICE_ARRIVED = C.LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED + HOTPLUG_EVENT_DEVICE_LEFT = C.LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT +) + +// Wildcard matching for hotplug events. +const HOTPLUG_MATCH_ANY = C.LIBUSB_HOTPLUG_MATCH_ANY + +//----------------------------------------------------------------------------- + +// A structure representing the standard USB endpoint descriptor. +// This descriptor is documented in section 9.6.6 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type Endpoint_Descriptor struct { + ptr *C.struct_libusb_endpoint_descriptor + BLength uint8 + BDescriptorType uint8 + BEndpointAddress uint8 + BmAttributes uint8 + WMaxPacketSize uint16 + BInterval uint8 + BRefresh uint8 + BSynchAddress uint8 + Extra []byte +} + +func (x *C.struct_libusb_endpoint_descriptor) c2go() *Endpoint_Descriptor { + return &Endpoint_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BEndpointAddress: uint8(x.bEndpointAddress), + BmAttributes: uint8(x.bmAttributes), + WMaxPacketSize: uint16(x.wMaxPacketSize), + BInterval: uint8(x.bInterval), + BRefresh: uint8(x.bRefresh), + BSynchAddress: uint8(x.bSynchAddress), + Extra: C.GoBytes(unsafe.Pointer(x.extra), x.extra_length), + } +} + +// return a string for an Endpoint_Descriptor +func (x *Endpoint_Descriptor) String() string { + s := make([]string, 0, 16) + s = append(s, fmt.Sprintf("bLength %d", x.BLength)) + s = append(s, fmt.Sprintf("bDescriptorType %d", x.BDescriptorType)) + s = append(s, fmt.Sprintf("bEndpointAddress 0x%02x", x.BEndpointAddress)) + s = append(s, fmt.Sprintf("bmAttributes %d", x.BmAttributes)) + s = append(s, fmt.Sprintf("wMaxPacketSize %d", x.WMaxPacketSize)) + s = append(s, fmt.Sprintf("bInterval %d", x.BInterval)) + s = append(s, fmt.Sprintf("bRefresh %d", x.BRefresh)) + s = append(s, fmt.Sprintf("bSynchAddress %d", x.BSynchAddress)) + s = append(s, fmt.Sprintf("extra %s", Extra_str(x.Extra))) + return strings.Join(s, "\n") +} + +//----------------------------------------------------------------------------- + +// A structure representing the standard USB interface descriptor. +// This descriptor is documented in section 9.6.5 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type Interface_Descriptor struct { + ptr *C.struct_libusb_interface_descriptor + BLength uint8 + BDescriptorType uint8 + BInterfaceNumber uint8 + BAlternateSetting uint8 + BNumEndpoints uint8 + BInterfaceClass uint8 + BInterfaceSubClass uint8 + BInterfaceProtocol uint8 + IInterface uint8 + Endpoint []*Endpoint_Descriptor + Extra []byte +} + +func (x *C.struct_libusb_interface_descriptor) c2go() *Interface_Descriptor { + var list []C.struct_libusb_endpoint_descriptor + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&list)) + hdr.Cap = int(x.bNumEndpoints) + hdr.Len = int(x.bNumEndpoints) + hdr.Data = uintptr(unsafe.Pointer(x.endpoint)) + endpoints := make([]*Endpoint_Descriptor, x.bNumEndpoints) + for i, _ := range endpoints { + endpoints[i] = (&list[i]).c2go() + } + return &Interface_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BInterfaceNumber: uint8(x.bInterfaceNumber), + BAlternateSetting: uint8(x.bAlternateSetting), + BNumEndpoints: uint8(x.bNumEndpoints), + BInterfaceClass: uint8(x.bInterfaceClass), + BInterfaceSubClass: uint8(x.bInterfaceSubClass), + BInterfaceProtocol: uint8(x.bInterfaceProtocol), + IInterface: uint8(x.iInterface), + Endpoint: endpoints, + Extra: C.GoBytes(unsafe.Pointer(x.extra), x.extra_length), + } +} + +// return a string for an Interface_Descriptor +func (x *Interface_Descriptor) String() string { + s := make([]string, 0, 16) + s = append(s, fmt.Sprintf("bLength %d", x.BLength)) + s = append(s, fmt.Sprintf("bDescriptorType %d", x.BDescriptorType)) + s = append(s, fmt.Sprintf("bInterfaceNumber %d", x.BInterfaceNumber)) + s = append(s, fmt.Sprintf("bAlternateSetting %d", x.BAlternateSetting)) + s = append(s, fmt.Sprintf("bNumEndpoints %d", x.BNumEndpoints)) + s = append(s, fmt.Sprintf("bInterfaceClass %d", x.BInterfaceClass)) + s = append(s, fmt.Sprintf("bInterfaceSubClass %d", x.BInterfaceSubClass)) + s = append(s, fmt.Sprintf("bInterfaceProtocol %d", x.BInterfaceProtocol)) + s = append(s, fmt.Sprintf("iInterface %d", x.IInterface)) + for i, v := range x.Endpoint { + s = append(s, fmt.Sprintf("Endpoint %d:", i)) + s = append(s, indent(v.String())) + } + s = append(s, fmt.Sprintf("extra %s", Extra_str(x.Extra))) + return strings.Join(s, "\n") +} + +//----------------------------------------------------------------------------- + +// A collection of alternate settings for a particular USB interface. +type Interface struct { + ptr *C.struct_libusb_interface + Num_altsetting int + Altsetting []*Interface_Descriptor +} + +func (x *C.struct_libusb_interface) c2go() *Interface { + var list []C.struct_libusb_interface_descriptor + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&list)) + hdr.Cap = int(x.num_altsetting) + hdr.Len = int(x.num_altsetting) + hdr.Data = uintptr(unsafe.Pointer(x.altsetting)) + altsetting := make([]*Interface_Descriptor, x.num_altsetting) + for i, _ := range altsetting { + altsetting[i] = (&list[i]).c2go() + } + return &Interface{ + ptr: x, + Num_altsetting: int(x.num_altsetting), + Altsetting: altsetting, + } +} + +// return a string for an Interface +func Interface_str(x *Interface) string { + s := make([]string, 0, 1) + s = append(s, fmt.Sprintf("num_altsetting %d", x.Num_altsetting)) + for i, v := range x.Altsetting { + s = append(s, fmt.Sprintf("Interface Descriptor %d:", i)) + s = append(s, indent(v.String())) + } + return strings.Join(s, "\n") +} + +//----------------------------------------------------------------------------- + +// A structure representing the standard USB configuration descriptor. +// This descriptor is documented in section 9.6.3 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type Config_Descriptor struct { + ptr *C.struct_libusb_config_descriptor + BLength uint8 + BDescriptorType uint8 + WTotalLength uint16 + BNumInterfaces uint8 + BConfigurationValue uint8 + IConfiguration uint8 + BmAttributes uint8 + MaxPower uint8 + Interface []*Interface + Extra []byte +} + +func (x *C.struct_libusb_config_descriptor) c2go() *Config_Descriptor { + var list []C.struct_libusb_interface + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&list)) + hdr.Cap = int(x.bNumInterfaces) + hdr.Len = int(x.bNumInterfaces) + hdr.Data = uintptr(unsafe.Pointer(x._interface)) + interfaces := make([]*Interface, x.bNumInterfaces) + for i, _ := range interfaces { + interfaces[i] = (&list[i]).c2go() + } + return &Config_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + WTotalLength: uint16(x.wTotalLength), + BNumInterfaces: uint8(x.bNumInterfaces), + BConfigurationValue: uint8(x.bConfigurationValue), + IConfiguration: uint8(x.iConfiguration), + BmAttributes: uint8(x.bmAttributes), + MaxPower: uint8(x.MaxPower), + Interface: interfaces, + Extra: C.GoBytes(unsafe.Pointer(x.extra), x.extra_length), + } +} + +// return a string for a Config_Descriptor +func (x *Config_Descriptor) String() string { + s := make([]string, 0, 16) + s = append(s, fmt.Sprintf("bLength %d", x.BLength)) + s = append(s, fmt.Sprintf("bDescriptorType %d", x.BDescriptorType)) + s = append(s, fmt.Sprintf("wTotalLength %d", x.WTotalLength)) + s = append(s, fmt.Sprintf("bNumInterfaces %d", x.BNumInterfaces)) + s = append(s, fmt.Sprintf("bConfigurationValue %d", x.BConfigurationValue)) + s = append(s, fmt.Sprintf("iConfiguration %d", x.IConfiguration)) + s = append(s, fmt.Sprintf("bmAttributes %d", x.BmAttributes)) + s = append(s, fmt.Sprintf("MaxPower %d", x.MaxPower)) + for i, v := range x.Interface { + s = append(s, fmt.Sprintf("Interface %d:", i)) + s = append(s, indent(fmt.Sprintf(Interface_str(v)))) + } + s = append(s, fmt.Sprintf("extra %s", Extra_str(x.Extra))) + return strings.Join(s, "\n") +} + +//----------------------------------------------------------------------------- + +// A structure representing the superspeed endpoint companion descriptor. +// This descriptor is documented in section 9.6.7 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type SS_Endpoint_Companion_Descriptor struct { + ptr *C.struct_libusb_ss_endpoint_companion_descriptor + BLength uint8 + BDescriptorType uint8 + BMaxBurst uint8 + BmAttributes uint8 + WBytesPerInterval uint16 +} + +func (x *C.struct_libusb_ss_endpoint_companion_descriptor) c2go() *SS_Endpoint_Companion_Descriptor { + return &SS_Endpoint_Companion_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BMaxBurst: uint8(x.bMaxBurst), + BmAttributes: uint8(x.bmAttributes), + WBytesPerInterval: uint16(x.wBytesPerInterval), + } +} + +//----------------------------------------------------------------------------- + +// A generic representation of a BOS Device Capability descriptor. +// It is advised to check BDevCapabilityType and call the matching +// Get_*_Descriptor function to get a structure fully matching the type. +type BOS_Dev_Capability_Descriptor struct { + ptr *C.struct_libusb_bos_dev_capability_descriptor + BLength uint8 + BDescriptorType uint8 + BDevCapabilityType uint8 + Dev_capability_data []byte +} + +func (x *C.struct_libusb_bos_dev_capability_descriptor) c2go() *BOS_Dev_Capability_Descriptor { + return &BOS_Dev_Capability_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BDevCapabilityType: uint8(x.bDevCapabilityType), + Dev_capability_data: C.GoBytes(unsafe.Pointer(C.dev_capability_data_ptr(x)), C.int(x.bLength-3)), + } +} + +//----------------------------------------------------------------------------- + +// A structure representing the Binary Device Object Store (BOS) descriptor. +// This descriptor is documented in section 9.6.2 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type BOS_Descriptor struct { + ptr *C.struct_libusb_bos_descriptor + BLength uint8 + BDescriptorType uint8 + WTotalLength uint16 + Dev_capability []*BOS_Dev_Capability_Descriptor +} + +func (x *C.struct_libusb_bos_descriptor) c2go() *BOS_Descriptor { + var list []*C.struct_libusb_bos_dev_capability_descriptor + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&list)) + hdr.Cap = int(x.bNumDeviceCaps) + hdr.Len = int(x.bNumDeviceCaps) + hdr.Data = uintptr(unsafe.Pointer(C.dev_capability_ptr(x))) + dev_capability := make([]*BOS_Dev_Capability_Descriptor, x.bNumDeviceCaps) + for i, _ := range dev_capability { + dev_capability[i] = list[i].c2go() + } + return &BOS_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + WTotalLength: uint16(x.wTotalLength), + Dev_capability: dev_capability, + } +} + +//----------------------------------------------------------------------------- + +// A structure representing the USB 2.0 Extension descriptor +// This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type USB_2_0_Extension_Descriptor struct { + ptr *C.struct_libusb_usb_2_0_extension_descriptor + BLength uint8 + BDescriptorType uint8 + BDevCapabilityType uint8 + BmAttributes uint32 +} + +func (x *C.struct_libusb_usb_2_0_extension_descriptor) c2go() *USB_2_0_Extension_Descriptor { + return &USB_2_0_Extension_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BDevCapabilityType: uint8(x.bDevCapabilityType), + BmAttributes: uint32(x.bmAttributes), + } +} + +//----------------------------------------------------------------------------- + +// A structure representing the SuperSpeed USB Device Capability descriptor +// This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type SS_USB_Device_Capability_Descriptor struct { + ptr *C.struct_libusb_ss_usb_device_capability_descriptor + BLength uint8 + BDescriptorType uint8 + BDevCapabilityType uint8 + BmAttributes uint8 + WSpeedSupported uint16 + BFunctionalitySupport uint8 + BU1DevExitLat uint8 + BU2DevExitLat uint16 +} + +func (x *C.struct_libusb_ss_usb_device_capability_descriptor) c2go() *SS_USB_Device_Capability_Descriptor { + return &SS_USB_Device_Capability_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BDevCapabilityType: uint8(x.bDevCapabilityType), + BmAttributes: uint8(x.bmAttributes), + WSpeedSupported: uint16(x.wSpeedSupported), + BFunctionalitySupport: uint8(x.bFunctionalitySupport), + BU1DevExitLat: uint8(x.bU1DevExitLat), + BU2DevExitLat: uint16(x.bU2DevExitLat), + } +} + +//----------------------------------------------------------------------------- + +// A structure representing the Container ID descriptor. +// This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification. +// All multiple-byte fields, except UUIDs, are represented in host-endian format. +type Container_ID_Descriptor struct { + ptr *C.struct_libusb_container_id_descriptor + BLength uint8 + BDescriptorType uint8 + BDevCapabilityType uint8 + BReserved uint8 + ContainerID []byte +} + +func (x *C.struct_libusb_container_id_descriptor) c2go() *Container_ID_Descriptor { + return &Container_ID_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BDevCapabilityType: uint8(x.bDevCapabilityType), + BReserved: uint8(x.bReserved), + ContainerID: C.GoBytes(unsafe.Pointer(&x.ContainerID[0]), 16), + } +} + +//----------------------------------------------------------------------------- + +/* +// Setup packet for control transfers. +struct libusb_control_setup { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +}; +*/ + +//----------------------------------------------------------------------------- + +// A structure representing the standard USB device descriptor. +// This descriptor is documented in section 9.6.1 of the USB 3.0 specification. +// All multiple-byte fields are represented in host-endian format. +type Device_Descriptor struct { + ptr *C.struct_libusb_device_descriptor + BLength uint8 + BDescriptorType uint8 + BcdUSB uint16 + BDeviceClass uint8 + BDeviceSubClass uint8 + BDeviceProtocol uint8 + BMaxPacketSize0 uint8 + IdVendor uint16 + IdProduct uint16 + BcdDevice uint16 + IManufacturer uint8 + IProduct uint8 + ISerialNumber uint8 + BNumConfigurations uint8 +} + +func (x *C.struct_libusb_device_descriptor) c2go() *Device_Descriptor { + return &Device_Descriptor{ + ptr: x, + BLength: uint8(x.bLength), + BDescriptorType: uint8(x.bDescriptorType), + BcdUSB: uint16(x.bcdUSB), + BDeviceClass: uint8(x.bDeviceClass), + BDeviceSubClass: uint8(x.bDeviceSubClass), + BDeviceProtocol: uint8(x.bDeviceProtocol), + BMaxPacketSize0: uint8(x.bMaxPacketSize0), + IdVendor: uint16(x.idVendor), + IdProduct: uint16(x.idProduct), + BcdDevice: uint16(x.bcdDevice), + IManufacturer: uint8(x.iManufacturer), + IProduct: uint8(x.iProduct), + ISerialNumber: uint8(x.iSerialNumber), + BNumConfigurations: uint8(x.bNumConfigurations), + } +} + +// return a string for a Device_Descriptor +func (x *Device_Descriptor) String() string { + s := make([]string, 0, 16) + s = append(s, fmt.Sprintf("bLength %d", x.BLength)) + s = append(s, fmt.Sprintf("bDescriptorType %d", x.BDescriptorType)) + s = append(s, fmt.Sprintf("bcdUSB %s", bcd2str(x.BcdUSB))) + s = append(s, fmt.Sprintf("bDeviceClass %d", x.BDeviceClass)) + s = append(s, fmt.Sprintf("bDeviceSubClass %d", x.BDeviceSubClass)) + s = append(s, fmt.Sprintf("bDeviceProtocol %d", x.BDeviceProtocol)) + s = append(s, fmt.Sprintf("bMaxPacketSize0 %d", x.BMaxPacketSize0)) + s = append(s, fmt.Sprintf("idVendor 0x%04x", x.IdVendor)) + s = append(s, fmt.Sprintf("idProduct 0x%04x", x.IdProduct)) + s = append(s, fmt.Sprintf("bcdDevice %s", bcd2str(x.BcdDevice))) + s = append(s, fmt.Sprintf("iManufacturer %d", x.IManufacturer)) + s = append(s, fmt.Sprintf("iProduct %d", x.IProduct)) + s = append(s, fmt.Sprintf("iSerialNumber %d", x.ISerialNumber)) + s = append(s, fmt.Sprintf("bNumConfigurations %d", x.BNumConfigurations)) + return strings.Join(s, "\n") +} + +//----------------------------------------------------------------------------- + +/* + +struct libusb_transfer { + libusb_device_handle *dev_handle; + uint8_t flags; + unsigned char endpoint; + unsigned char type; + unsigned int timeout; + enum libusb_transfer_status status; + int length; + int actual_length; + libusb_transfer_cb_fn callback; + void *user_data; + unsigned char *buffer; + int num_iso_packets; + struct libusb_iso_packet_descriptor iso_packet_desc[]; +}; + +*/ + +// The generic USB transfer structure. The user populates this structure and +// then submits it in order to request a transfer. After the transfer has +// completed, the library populates the transfer with the results and passes +// it back to the user. +type Transfer struct { + ptr *C.struct_libusb_transfer +} + +func (x *C.struct_libusb_transfer) c2go() *Transfer { + return &Transfer{ + ptr: x, + } +} + +func (x *Transfer) go2c() *C.struct_libusb_transfer { + return x.ptr +} + +// return a string for a Device_Descriptor +func (x *Transfer) String() string { + s := make([]string, 0, 1) + return strings.Join(s, "\n") +} + +//----------------------------------------------------------------------------- + +// Structure providing the version of the libusb runtime. +type Version struct { + ptr *C.struct_libusb_version + Major uint16 + Minor uint16 + Micro uint16 + Nano uint16 + Rc string + Describe string +} + +func (x *C.struct_libusb_version) c2go() *Version { + return &Version{ + ptr: x, + Major: uint16(x.major), + Minor: uint16(x.minor), + Micro: uint16(x.micro), + Nano: uint16(x.nano), + Rc: C.GoString(x.rc), + Describe: C.GoString(x.describe), + } +} + +//----------------------------------------------------------------------------- + +// Structure representing a libusb session. +type Context *C.struct_libusb_context + +// Structure representing a USB device detected on the system. +type Device *C.struct_libusb_device + +// Structure representing a handle on a USB device. +type Device_Handle *C.struct_libusb_device_handle + +//type Hotplug_Callback *C.struct_libusb_hotplug_callback + +//----------------------------------------------------------------------------- +// errors + +type libusb_error struct { + Code int +} + +func (e *libusb_error) Error() string { + return Error_Name(e.Code) +} + +//----------------------------------------------------------------------------- +// Library initialization/deinitialization + +func Set_Debug(ctx Context, level int) { + C.libusb_set_debug(ctx, C.int(level)) +} + +func Init(ctx *Context) error { + rc := int(C.libusb_init((**C.struct_libusb_context)(ctx))) + if rc != 0 { + return &libusb_error{rc} + } + return nil +} + +func Exit(ctx Context) { + C.libusb_exit(ctx) +} + +//----------------------------------------------------------------------------- +// Device handling and enumeration + +func Get_Device_List(ctx Context) ([]Device, error) { + var hdl **C.struct_libusb_device + rc := int(C.libusb_get_device_list(ctx, (***C.struct_libusb_device)(&hdl))) + if rc < 0 { + return nil, &libusb_error{rc} + } + // turn the c array into a slice of device pointers + var list []Device + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&list)) + hdr.Cap = rc + hdr.Len = rc + hdr.Data = uintptr(unsafe.Pointer(hdl)) + return list, nil +} + +func Free_Device_List(list []Device, unref_devices int) { + if list == nil { + return + } + if len(list) == 0 { + return + } + C.libusb_free_device_list((**C.struct_libusb_device)(&list[0]), C.int(unref_devices)) +} + +func Get_Bus_Number(dev Device) uint8 { + return uint8(C.libusb_get_bus_number(dev)) +} + +func Get_Port_Number(dev Device) uint8 { + return uint8(C.libusb_get_port_number(dev)) +} + +func Get_Port_Numbers(dev Device, ports []byte) ([]byte, error) { + rc := int(C.libusb_get_port_numbers(dev, (*C.uint8_t)(&ports[0]), (C.int)(len(ports)))) + if rc < 0 { + return nil, &libusb_error{rc} + } + return ports[:rc], nil +} + +func Get_Parent(dev Device) Device { + return C.libusb_get_parent(dev) +} + +func Get_Device_Address(dev Device) uint8 { + return uint8(C.libusb_get_device_address(dev)) +} + +func Get_Device_Speed(dev Device) int { + return int(C.libusb_get_device_speed(dev)) +} + +func Get_Max_Packet_Size(dev Device, endpoint uint8) int { + return int(C.libusb_get_max_packet_size(dev, (C.uchar)(endpoint))) +} + +func Get_Max_ISO_Packet_Size(dev Device, endpoint uint8) int { + return int(C.libusb_get_max_iso_packet_size(dev, (C.uchar)(endpoint))) +} + +func Ref_Device(dev Device) Device { + return C.libusb_ref_device(dev) +} + +func Unref_Device(dev Device) { + C.libusb_unref_device(dev) +} + +func Open(dev Device) (Device_Handle, error) { + var hdl Device_Handle + rc := int(C.libusb_open(dev, (**C.struct_libusb_device_handle)(&hdl))) + if rc < 0 { + return nil, &libusb_error{rc} + } + return hdl, nil +} + +func Open_Device_With_VID_PID(ctx Context, vendor_id uint16, product_id uint16) Device_Handle { + return C.libusb_open_device_with_vid_pid(ctx, (C.uint16_t)(vendor_id), (C.uint16_t)(product_id)) +} + +func Close(hdl Device_Handle) { + C.libusb_close(hdl) +} + +func Get_Device(hdl Device_Handle) Device { + return C.libusb_get_device(hdl) +} + +func Get_Configuration(hdl Device_Handle) (int, error) { + var config C.int + rc := int(C.libusb_get_configuration(hdl, &config)) + if rc < 0 { + return 0, &libusb_error{rc} + } + return int(config), nil +} + +func Set_Configuration(hdl Device_Handle, configuration int) error { + rc := int(C.libusb_set_configuration(hdl, (C.int)(configuration))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Claim_Interface(hdl Device_Handle, interface_number int) error { + rc := int(C.libusb_claim_interface(hdl, (C.int)(interface_number))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Release_Interface(hdl Device_Handle, interface_number int) error { + rc := int(C.libusb_release_interface(hdl, (C.int)(interface_number))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Set_Interface_Alt_Setting(hdl Device_Handle, interface_number int, alternate_setting int) error { + rc := int(C.libusb_set_interface_alt_setting(hdl, (C.int)(interface_number), (C.int)(alternate_setting))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Clear_Halt(hdl Device_Handle, endpoint uint8) error { + rc := int(C.libusb_clear_halt(hdl, (C.uchar)(endpoint))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Reset_Device(hdl Device_Handle) error { + rc := int(C.libusb_reset_device(hdl)) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Kernel_Driver_Active(hdl Device_Handle, interface_number int) (bool, error) { + rc := int(C.libusb_kernel_driver_active(hdl, (C.int)(interface_number))) + if rc < 0 { + return false, &libusb_error{rc} + } + return rc != 0, nil +} + +func Detach_Kernel_Driver(hdl Device_Handle, interface_number int) error { + rc := int(C.libusb_detach_kernel_driver(hdl, (C.int)(interface_number))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Attach_Kernel_Driver(hdl Device_Handle, interface_number int) error { + rc := int(C.libusb_attach_kernel_driver(hdl, (C.int)(interface_number))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Set_Auto_Detach_Kernel_Driver(hdl Device_Handle, enable bool) error { + enable_int := 0 + if enable { + enable_int = 1 + } + rc := int(C.libusb_set_auto_detach_kernel_driver(hdl, (C.int)(enable_int))) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +//----------------------------------------------------------------------------- +// Miscellaneous + +func Has_Capability(capability uint32) bool { + rc := int(C.libusb_has_capability((C.uint32_t)(capability))) + return rc != 0 +} + +func Error_Name(code int) string { + return C.GoString(C.libusb_error_name(C.int(code))) +} + +func Get_Version() *Version { + ver := (*C.struct_libusb_version)(unsafe.Pointer(C.libusb_get_version())) + return ver.c2go() +} + +func CPU_To_LE16(x uint16) uint16 { + return uint16(C.libusb_cpu_to_le16((C.uint16_t)(x))) +} + +func Setlocale(locale string) error { + cstr := C.CString(locale) + rc := int(C.libusb_setlocale(cstr)) + if rc < 0 { + return &libusb_error{rc} + } + return nil +} + +func Strerror(errcode int) string { + return C.GoString(C.libusb_strerror(int32(errcode))) +} + +//----------------------------------------------------------------------------- +// USB descriptors + +func Get_Device_Descriptor(dev Device) (*Device_Descriptor, error) { + var desc C.struct_libusb_device_descriptor + rc := int(C.libusb_get_device_descriptor(dev, &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return (&desc).c2go(), nil +} + +func Get_Active_Config_Descriptor(dev Device) (*Config_Descriptor, error) { + var desc *C.struct_libusb_config_descriptor + rc := int(C.libusb_get_active_config_descriptor(dev, &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Get_Config_Descriptor(dev Device, config_index uint8) (*Config_Descriptor, error) { + var desc *C.struct_libusb_config_descriptor + rc := int(C.libusb_get_config_descriptor(dev, (C.uint8_t)(config_index), &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Get_Config_Descriptor_By_Value(dev Device, bConfigurationValue uint8) (*Config_Descriptor, error) { + var desc *C.struct_libusb_config_descriptor + rc := int(C.libusb_get_config_descriptor_by_value(dev, (C.uint8_t)(bConfigurationValue), &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Free_Config_Descriptor(config *Config_Descriptor) { + C.libusb_free_config_descriptor(config.ptr) +} + +func Get_SS_Endpoint_Companion_Descriptor(ctx Context, endpoint *Endpoint_Descriptor) (*SS_Endpoint_Companion_Descriptor, error) { + var desc *C.struct_libusb_ss_endpoint_companion_descriptor + rc := int(C.libusb_get_ss_endpoint_companion_descriptor(ctx, endpoint.ptr, &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Free_SS_Endpoint_Companion_Descriptor(ep_comp *SS_Endpoint_Companion_Descriptor) { + C.libusb_free_ss_endpoint_companion_descriptor(ep_comp.ptr) +} + +func Get_BOS_Descriptor(hdl Device_Handle) (*BOS_Descriptor, error) { + var desc *C.struct_libusb_bos_descriptor + rc := int(C.libusb_get_bos_descriptor(hdl, &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Free_BOS_Descriptor(bos *BOS_Descriptor) { + C.libusb_free_bos_descriptor(bos.ptr) +} + +func Get_USB_2_0_Extension_Descriptor(ctx Context, dev_cap *BOS_Dev_Capability_Descriptor) (*USB_2_0_Extension_Descriptor, error) { + var desc *C.struct_libusb_usb_2_0_extension_descriptor + rc := int(C.libusb_get_usb_2_0_extension_descriptor(ctx, dev_cap.ptr, &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Free_USB_2_0_Extension_Descriptor(usb_2_0_extension *USB_2_0_Extension_Descriptor) { + C.libusb_free_usb_2_0_extension_descriptor(usb_2_0_extension.ptr) +} + +func Get_SS_USB_Device_Capability_Descriptor(ctx Context, dev_cap *BOS_Dev_Capability_Descriptor) (*SS_USB_Device_Capability_Descriptor, error) { + var desc *C.struct_libusb_ss_usb_device_capability_descriptor + rc := int(C.libusb_get_ss_usb_device_capability_descriptor(ctx, dev_cap.ptr, &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Free_SS_USB_Device_Capability_Descriptor(ss_usb_device_cap *SS_USB_Device_Capability_Descriptor) { + C.libusb_free_ss_usb_device_capability_descriptor(ss_usb_device_cap.ptr) +} + +func Get_Container_ID_Descriptor(ctx Context, dev_cap *BOS_Dev_Capability_Descriptor) (*Container_ID_Descriptor, error) { + var desc *C.struct_libusb_container_id_descriptor + rc := int(C.libusb_get_container_id_descriptor(ctx, dev_cap.ptr, &desc)) + if rc != 0 { + return nil, &libusb_error{rc} + } + return desc.c2go(), nil +} + +func Free_Container_ID_Descriptor(container_id *Container_ID_Descriptor) { + C.libusb_free_container_id_descriptor(container_id.ptr) +} + +func Get_String_Descriptor_ASCII(hdl Device_Handle, desc_index uint8, data []byte) ([]byte, error) { + rc := int(C.libusb_get_string_descriptor_ascii(hdl, (C.uint8_t)(desc_index), (*C.uchar)(&data[0]), (C.int)(len(data)))) + if rc < 0 { + return nil, &libusb_error{rc} + } + return data[:rc], nil +} + +func Get_Descriptor(hdl Device_Handle, desc_type uint8, desc_index uint8, data []byte) ([]byte, error) { + rc := int(C.libusb_get_descriptor(hdl, (C.uint8_t)(desc_type), (C.uint8_t)(desc_index), (*C.uchar)(&data[0]), (C.int)(len(data)))) + if rc < 0 { + return nil, &libusb_error{rc} + } + return data[:rc], nil +} + +func Get_String_Descriptor(hdl Device_Handle, desc_index uint8, langid uint16, data []byte) ([]byte, error) { + rc := int(C.libusb_get_string_descriptor(hdl, (C.uint8_t)(desc_index), (C.uint16_t)(langid), (*C.uchar)(&data[0]), (C.int)(len(data)))) + if rc < 0 { + return nil, &libusb_error{rc} + } + return data[:rc], nil +} + +//----------------------------------------------------------------------------- +// Device hotplug event notification + +//int libusb_hotplug_register_callback (libusb_context *ctx, libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *handle) +//void libusb_hotplug_deregister_callback (libusb_context *ctx, libusb_hotplug_callback_handle handle) + +//----------------------------------------------------------------------------- +//Asynchronous device I/O + +func Alloc_Streams(dev Device_Handle, num_streams uint32, endpoints []byte) (int, error) { + rc := int(C.libusb_alloc_streams(dev, (C.uint32_t)(num_streams), (*C.uchar)(&endpoints[0]), (C.int)(len(endpoints)))) + if rc < 0 { + return 0, &libusb_error{rc} + } + return rc, nil +} + +func Free_Streams(dev Device_Handle, endpoints []byte) error { + rc := int(C.libusb_free_streams(dev, (*C.uchar)(&endpoints[0]), (C.int)(len(endpoints)))) + if rc != 0 { + return &libusb_error{rc} + } + return nil +} + +func Alloc_Transfer(iso_packets int) (*Transfer, error) { + ptr := C.libusb_alloc_transfer((C.int)(iso_packets)) + if ptr == nil { + return nil, &libusb_error{ERROR_OTHER} + } + return ptr.c2go(), nil +} + +func Free_Transfer(transfer *Transfer) { + C.libusb_free_transfer(transfer.ptr) +} + +func Submit_Transfer(transfer *Transfer) error { + rc := int(C.libusb_submit_transfer(transfer.go2c())) + if rc != 0 { + return &libusb_error{rc} + } + return nil +} + +func Cancel_Transfer(transfer *Transfer) error { + rc := int(C.libusb_cancel_transfer(transfer.go2c())) + if rc != 0 { + return &libusb_error{rc} + } + return nil +} + +func Transfer_Set_Stream_ID(transfer *Transfer, stream_id uint32) { + C.libusb_transfer_set_stream_id(transfer.go2c(), (C.uint32_t)(stream_id)) +} + +func Transfer_Get_Stream_ID(transfer *Transfer) uint32 { + return uint32(C.libusb_transfer_get_stream_id(transfer.go2c())) +} + +func Control_Transfer_Get_Data(transfer *Transfer) *byte { + // should this return a slice? - what's the length? + return (*byte)(C.libusb_control_transfer_get_data(transfer.go2c())) +} + +// static struct libusb_control_setup * libusb_control_transfer_get_setup (struct libusb_transfer *transfer) +// static void libusb_fill_control_setup (unsigned char *buffer, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) +// static void libusb_fill_control_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +// static void libusb_fill_bulk_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *buffer, int length, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +// static void libusb_fill_bulk_stream_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, uint32_t stream_id, unsigned char *buffer, int length, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +// static void libusb_fill_interrupt_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *buffer, int length, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +// static void libusb_fill_iso_transfer (struct libusb_transfer *transfer, libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *buffer, int length, int num_iso_packets, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +// static void libusb_set_iso_packet_lengths (struct libusb_transfer *transfer, unsigned int length) +// static unsigned char * libusb_get_iso_packet_buffer (struct libusb_transfer *transfer, unsigned int packet) +// static unsigned char * libusb_get_iso_packet_buffer_simple (struct libusb_transfer *transfer, unsigned int packet) + +//----------------------------------------------------------------------------- +// Polling and timing + +// int libusb_try_lock_events (libusb_context *ctx) +// void libusb_lock_events (libusb_context *ctx) +// void libusb_unlock_events (libusb_context *ctx) +// int libusb_event_handling_ok (libusb_context *ctx) +// int libusb_event_handler_active (libusb_context *ctx) +// void libusb_lock_event_waiters (libusb_context *ctx) +// void libusb_unlock_event_waiters (libusb_context *ctx) +// int libusb_wait_for_event (libusb_context *ctx, struct timeval *tv) +// int libusb_handle_events_timeout_completed (libusb_context *ctx, struct timeval *tv, int *completed) +// int libusb_handle_events_timeout (libusb_context *ctx, struct timeval *tv) +// int libusb_handle_events (libusb_context *ctx) +// int libusb_handle_events_completed (libusb_context *ctx, int *completed) +// int libusb_handle_events_locked (libusb_context *ctx, struct timeval *tv) +// int libusb_pollfds_handle_timeouts (libusb_context *ctx) +// int libusb_get_next_timeout (libusb_context *ctx, struct timeval *tv) +// void libusb_set_pollfd_notifiers (libusb_context *ctx, libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, void *user_data) +// const struct libusb_pollfd ** libusb_get_pollfds (libusb_context *ctx) +// void libusb_free_pollfds (const struct libusb_pollfd **pollfds) + +//----------------------------------------------------------------------------- +// Synchronous device I/O + +func Control_Transfer(hdl Device_Handle, bmRequestType uint8, bRequest uint8, wValue uint16, wIndex uint16, data []byte, timeout uint) ([]byte, error) { + rc := int(C.libusb_control_transfer(hdl, (C.uint8_t)(bmRequestType), (C.uint8_t)(bRequest), (C.uint16_t)(wValue), (C.uint16_t)(wIndex), + (*C.uchar)(&data[0]), (C.uint16_t)(len(data)), (C.uint)(timeout))) + if rc < 0 { + return nil, &libusb_error{rc} + } + return data[:rc], nil +} + +func Bulk_Transfer(hdl Device_Handle, endpoint uint8, data []byte, timeout uint) ([]byte, error) { + var transferred C.int + rc := int(C.libusb_bulk_transfer(hdl, (C.uchar)(endpoint), (*C.uchar)(&data[0]), (C.int)(len(data)), &transferred, (C.uint)(timeout))) + if rc != 0 { + return nil, &libusb_error{rc} + } + return data[:int(transferred)], nil +} + +func Interrupt_Transfer(hdl Device_Handle, endpoint uint8, data []byte, timeout uint) ([]byte, error) { + var transferred C.int + rc := int(C.libusb_interrupt_transfer(hdl, (C.uchar)(endpoint), (*C.uchar)(&data[0]), (C.int)(len(data)), &transferred, (C.uint)(timeout))) + if rc != 0 { + return nil, &libusb_error{rc} + } + return data[:int(transferred)], nil +} + +//----------------------------------------------------------------------------- diff --git a/go-api-for-hardware-wallet/usbhid/wchar.go b/go-api-for-hardware-wallet/usbhid/wchar.go new file mode 100644 index 00000000..16941d14 --- /dev/null +++ b/go-api-for-hardware-wallet/usbhid/wchar.go @@ -0,0 +1,227 @@ +// This file is https://github.com/orofarne/gowchar/blob/master/gowchar.go +// +// It was vendored inline to work around CGO limitations that don't allow C types +// to directly cross package API boundaries. +// +// The vendored file is licensed under the 3-clause BSD license, according to: +// https://github.com/orofarne/gowchar/blob/master/LICENSE + +// +build !ios +// +build linux darwin windows + +package usbhid + +/* +#include + +const size_t SIZEOF_WCHAR_T = sizeof(wchar_t); + +void gowchar_set (wchar_t *arr, int pos, wchar_t val) +{ + arr[pos] = val; +} + +wchar_t gowchar_get (wchar_t *arr, int pos) +{ + return arr[pos]; +} +*/ +import "C" + +import ( + "fmt" + "unicode/utf16" + "unicode/utf8" +) + +var sizeofWcharT C.size_t = C.size_t(C.SIZEOF_WCHAR_T) + +func stringToWcharT(s string) (*C.wchar_t, C.size_t) { + switch sizeofWcharT { + case 2: + return stringToWchar2(s) // Windows + case 4: + return stringToWchar4(s) // Unix + default: + panic(fmt.Sprintf("Invalid sizeof(wchar_t) = %v", sizeofWcharT)) + } +} + +func wcharTToString(s *C.wchar_t) (string, error) { + switch sizeofWcharT { + case 2: + return wchar2ToString(s) // Windows + case 4: + return wchar4ToString(s) // Unix + default: + panic(fmt.Sprintf("Invalid sizeof(wchar_t) = %v", sizeofWcharT)) + } +} + +func wcharTNToString(s *C.wchar_t, size C.size_t) (string, error) { + switch sizeofWcharT { + case 2: + return wchar2NToString(s, size) // Windows + case 4: + return wchar4NToString(s, size) // Unix + default: + panic(fmt.Sprintf("Invalid sizeof(wchar_t) = %v", sizeofWcharT)) + } +} + +// Windows +func stringToWchar2(s string) (*C.wchar_t, C.size_t) { + var slen int + s1 := s + for len(s1) > 0 { + r, size := utf8.DecodeRuneInString(s1) + if er, _ := utf16.EncodeRune(r); er == '\uFFFD' { + slen += 1 + } else { + slen += 2 + } + s1 = s1[size:] + } + slen++ // \0 + res := C.malloc(C.size_t(slen) * sizeofWcharT) + var i int + for len(s) > 0 { + r, size := utf8.DecodeRuneInString(s) + if r1, r2 := utf16.EncodeRune(r); r1 != '\uFFFD' { + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r1)) + i++ + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r2)) + i++ + } else { + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r)) + i++ + } + s = s[size:] + } + C.gowchar_set((*C.wchar_t)(res), C.int(slen-1), C.wchar_t(0)) // \0 + return (*C.wchar_t)(res), C.size_t(slen) +} + +// Unix +func stringToWchar4(s string) (*C.wchar_t, C.size_t) { + slen := utf8.RuneCountInString(s) + slen++ // \0 + res := C.malloc(C.size_t(slen) * sizeofWcharT) + var i int + for len(s) > 0 { + r, size := utf8.DecodeRuneInString(s) + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r)) + s = s[size:] + i++ + } + C.gowchar_set((*C.wchar_t)(res), C.int(slen-1), C.wchar_t(0)) // \0 + return (*C.wchar_t)(res), C.size_t(slen) +} + +// Windows +func wchar2ToString(s *C.wchar_t) (string, error) { + var i int + var res string + for { + ch := C.gowchar_get(s, C.int(i)) + if ch == 0 { + break + } + r := rune(ch) + i++ + if !utf16.IsSurrogate(r) { + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + res += string(r) + } else { + ch2 := C.gowchar_get(s, C.int(i)) + r2 := rune(ch2) + r12 := utf16.DecodeRune(r, r2) + if r12 == '\uFFFD' { + err := fmt.Errorf("Invalid surrogate pair at position %v", i-1) + return "", err + } + res += string(r12) + i++ + } + } + return res, nil +} + +// Unix +func wchar4ToString(s *C.wchar_t) (string, error) { + var i int + var res string + for { + ch := C.gowchar_get(s, C.int(i)) + if ch == 0 { + break + } + r := rune(ch) + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + res += string(r) + i++ + } + return res, nil +} + +// Windows +func wchar2NToString(s *C.wchar_t, size C.size_t) (string, error) { + var i int + var res string + N := int(size) + for i < N { + ch := C.gowchar_get(s, C.int(i)) + if ch == 0 { + break + } + r := rune(ch) + i++ + if !utf16.IsSurrogate(r) { + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + + res += string(r) + } else { + if i >= N { + err := fmt.Errorf("Invalid surrogate pair at position %v", i-1) + return "", err + } + ch2 := C.gowchar_get(s, C.int(i)) + r2 := rune(ch2) + r12 := utf16.DecodeRune(r, r2) + if r12 == '\uFFFD' { + err := fmt.Errorf("Invalid surrogate pair at position %v", i-1) + return "", err + } + res += string(r12) + i++ + } + } + return res, nil +} + +// Unix +func wchar4NToString(s *C.wchar_t, size C.size_t) (string, error) { + var i int + var res string + N := int(size) + for i < N { + ch := C.gowchar_get(s, C.int(i)) + r := rune(ch) + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + res += string(r) + i++ + } + return res, nil +} From caed4f4c7a9088fb4ed2bf916cb42a8e8a038746 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 8 Apr 2018 11:44:53 +0900 Subject: [PATCH 40/73] Moving usbhid adding wire for google protobuf and updating go import accordingly --- go-api-for-hardware-wallet/trezor.go | 6 +- go-api-for-hardware-wallet/usb/hidapi.go | 2 +- .../{ => usb}/usbhid/.gitignore | 0 .../{ => usb}/usbhid/.travis.yml | 0 .../{ => usb}/usbhid/README.md | 0 .../{ => usb}/usbhid/c/hidapi/AUTHORS.txt | 0 .../{ => usb}/usbhid/c/hidapi/LICENSE-bsd.txt | 0 .../usbhid/c/hidapi/LICENSE-gpl3.txt | 0 .../usbhid/c/hidapi/LICENSE-orig.txt | 0 .../{ => usb}/usbhid/c/hidapi/LICENSE.txt | 0 .../{ => usb}/usbhid/c/hidapi/README.txt | 0 .../{ => usb}/usbhid/c/hidapi/hidapi/hidapi.h | 0 .../{ => usb}/usbhid/c/hidapi/linux/hid.c | 0 .../{ => usb}/usbhid/c/hidapi/mac/hid.c | 0 .../{ => usb}/usbhid/c/hidapi/windows/hid.c | 0 .../{ => usb}/usbhid/c/libusb/AUTHORS | 0 .../{ => usb}/usbhid/c/libusb/COPYING | 0 .../{ => usb}/usbhid/c/libusb/config.h | 0 .../{ => usb}/usbhid/c/libusb/core.c | 0 .../{ => usb}/usbhid/c/libusb/descriptor.c | 0 .../{ => usb}/usbhid/c/libusb/hotplug.c | 0 .../{ => usb}/usbhid/c/libusb/hotplug.h | 0 .../{ => usb}/usbhid/c/libusb/io.c | 0 .../{ => usb}/usbhid/c/libusb/libusb.h | 0 .../{ => usb}/usbhid/c/libusb/libusbi.h | 0 .../{ => usb}/usbhid/c/libusb/os/darwin_usb.c | 0 .../{ => usb}/usbhid/c/libusb/os/darwin_usb.h | 0 .../usbhid/c/libusb/os/haiku_pollfs.cpp | 0 .../{ => usb}/usbhid/c/libusb/os/haiku_usb.h | 0 .../usbhid/c/libusb/os/haiku_usb_backend.cpp | 0 .../usbhid/c/libusb/os/haiku_usb_raw.cpp | 0 .../usbhid/c/libusb/os/haiku_usb_raw.h | 0 .../usbhid/c/libusb/os/linux_netlink.c | 0 .../{ => usb}/usbhid/c/libusb/os/linux_udev.c | 0 .../usbhid/c/libusb/os/linux_usbfs.c | 0 .../usbhid/c/libusb/os/linux_usbfs.h | 0 .../{ => usb}/usbhid/c/libusb/os/netbsd_usb.c | 0 .../usbhid/c/libusb/os/openbsd_usb.c | 0 .../{ => usb}/usbhid/c/libusb/os/poll_posix.c | 0 .../{ => usb}/usbhid/c/libusb/os/poll_posix.h | 0 .../usbhid/c/libusb/os/poll_windows.c | 0 .../usbhid/c/libusb/os/poll_windows.h | 0 .../{ => usb}/usbhid/c/libusb/os/sunos_usb.c | 0 .../{ => usb}/usbhid/c/libusb/os/sunos_usb.h | 0 .../usbhid/c/libusb/os/threads_posix.c | 0 .../usbhid/c/libusb/os/threads_posix.h | 0 .../usbhid/c/libusb/os/threads_windows.c | 0 .../usbhid/c/libusb/os/threads_windows.h | 0 .../{ => usb}/usbhid/c/libusb/os/wince_usb.c | 0 .../{ => usb}/usbhid/c/libusb/os/wince_usb.h | 0 .../usbhid/c/libusb/os/windows_common.h | 0 .../usbhid/c/libusb/os/windows_nt_common.c | 0 .../usbhid/c/libusb/os/windows_nt_common.h | 0 .../usbhid/c/libusb/os/windows_usbdk.c | 0 .../usbhid/c/libusb/os/windows_usbdk.h | 0 .../usbhid/c/libusb/os/windows_winusb.c | 0 .../usbhid/c/libusb/os/windows_winusb.h | 0 .../{ => usb}/usbhid/c/libusb/strerror.c | 0 .../{ => usb}/usbhid/c/libusb/sync.c | 0 .../{ => usb}/usbhid/c/libusb/version.h | 0 .../{ => usb}/usbhid/c/libusb/version_nano.h | 0 .../{ => usb}/usbhid/hid.go | 0 .../{ => usb}/usbhid/libusb.go | 0 .../{ => usb}/usbhid/wchar.go | 0 go-api-for-hardware-wallet/usb/webusb.go | 2 +- go-api-for-hardware-wallet/wire/protobuf.go | 54 +++++++++ go-api-for-hardware-wallet/wire/v1.go | 106 ++++++++++++++++++ 67 files changed, 165 insertions(+), 5 deletions(-) rename go-api-for-hardware-wallet/{ => usb}/usbhid/.gitignore (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/.travis.yml (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/README.md (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/AUTHORS.txt (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/LICENSE-bsd.txt (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/LICENSE-gpl3.txt (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/LICENSE-orig.txt (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/LICENSE.txt (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/README.txt (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/hidapi/hidapi.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/linux/hid.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/mac/hid.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/hidapi/windows/hid.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/AUTHORS (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/COPYING (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/config.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/core.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/descriptor.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/hotplug.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/hotplug.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/io.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/libusb.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/libusbi.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/darwin_usb.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/darwin_usb.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/haiku_pollfs.cpp (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/haiku_usb.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/haiku_usb_backend.cpp (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/haiku_usb_raw.cpp (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/haiku_usb_raw.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/linux_netlink.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/linux_udev.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/linux_usbfs.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/linux_usbfs.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/netbsd_usb.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/openbsd_usb.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/poll_posix.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/poll_posix.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/poll_windows.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/poll_windows.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/sunos_usb.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/sunos_usb.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/threads_posix.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/threads_posix.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/threads_windows.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/threads_windows.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/wince_usb.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/wince_usb.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/windows_common.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/windows_nt_common.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/windows_nt_common.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/windows_usbdk.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/windows_usbdk.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/windows_winusb.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/os/windows_winusb.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/strerror.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/sync.c (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/version.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/c/libusb/version_nano.h (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/hid.go (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/libusb.go (100%) rename go-api-for-hardware-wallet/{ => usb}/usbhid/wchar.go (100%) create mode 100644 go-api-for-hardware-wallet/wire/protobuf.go create mode 100644 go-api-for-hardware-wallet/wire/v1.go diff --git a/go-api-for-hardware-wallet/trezor.go b/go-api-for-hardware-wallet/trezor.go index 1ba7e452..a569222c 100644 --- a/go-api-for-hardware-wallet/trezor.go +++ b/go-api-for-hardware-wallet/trezor.go @@ -1,4 +1,4 @@ -package harwareWallet +package hardwareWallet import ( "bytes" @@ -7,9 +7,9 @@ import ( "log" "time" - "github.com/skycoin/skycoin/src/hardware-wallet/usb" + "./usb" - messages "github.com/skycoin/skycoin/protob" + messages "./protob" ) func GetTrezorDevice() (usb.Device, error) { diff --git a/go-api-for-hardware-wallet/usb/hidapi.go b/go-api-for-hardware-wallet/usb/hidapi.go index 01370af1..3888a1b5 100644 --- a/go-api-for-hardware-wallet/usb/hidapi.go +++ b/go-api-for-hardware-wallet/usb/hidapi.go @@ -6,7 +6,7 @@ import ( "errors" "strings" - "github.com/usbhid" + "./usbhid" ) const ( diff --git a/go-api-for-hardware-wallet/usbhid/.gitignore b/go-api-for-hardware-wallet/usb/usbhid/.gitignore similarity index 100% rename from go-api-for-hardware-wallet/usbhid/.gitignore rename to go-api-for-hardware-wallet/usb/usbhid/.gitignore diff --git a/go-api-for-hardware-wallet/usbhid/.travis.yml b/go-api-for-hardware-wallet/usb/usbhid/.travis.yml similarity index 100% rename from go-api-for-hardware-wallet/usbhid/.travis.yml rename to go-api-for-hardware-wallet/usb/usbhid/.travis.yml diff --git a/go-api-for-hardware-wallet/usbhid/README.md b/go-api-for-hardware-wallet/usb/usbhid/README.md similarity index 100% rename from go-api-for-hardware-wallet/usbhid/README.md rename to go-api-for-hardware-wallet/usb/usbhid/README.md diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/AUTHORS.txt b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/AUTHORS.txt similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/AUTHORS.txt rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/AUTHORS.txt diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-bsd.txt b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-bsd.txt similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-bsd.txt rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-bsd.txt diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-gpl3.txt b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-gpl3.txt similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-gpl3.txt rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-gpl3.txt diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-orig.txt b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-orig.txt similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE-orig.txt rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-orig.txt diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE.txt b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE.txt similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/LICENSE.txt rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE.txt diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/README.txt b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/README.txt similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/README.txt rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/README.txt diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/hidapi/hidapi.h b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/hidapi/hidapi.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/hidapi/hidapi.h rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/hidapi/hidapi.h diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/linux/hid.c b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/linux/hid.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/linux/hid.c rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/linux/hid.c diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/mac/hid.c b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/mac/hid.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/mac/hid.c rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/mac/hid.c diff --git a/go-api-for-hardware-wallet/usbhid/c/hidapi/windows/hid.c b/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/windows/hid.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/hidapi/windows/hid.c rename to go-api-for-hardware-wallet/usb/usbhid/c/hidapi/windows/hid.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/AUTHORS b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/AUTHORS similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/AUTHORS rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/AUTHORS diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/COPYING b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/COPYING similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/COPYING rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/COPYING diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/config.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/config.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/config.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/config.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/core.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/core.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/core.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/core.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/descriptor.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/descriptor.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/descriptor.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/descriptor.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/hotplug.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/io.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/io.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/io.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/io.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/libusb.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusb.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/libusb.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusb.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/libusbi.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusbi.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/libusbi.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusbi.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/darwin_usb.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_pollfs.cpp b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_pollfs.cpp similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_pollfs.cpp rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_pollfs.cpp diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_backend.cpp b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_backend.cpp similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_backend.cpp rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_backend.cpp diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.cpp b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.cpp similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.cpp rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.cpp diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/haiku_usb_raw.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_netlink.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_netlink.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_netlink.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_netlink.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_udev.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_udev.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_udev.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_udev.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/linux_usbfs.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/netbsd_usb.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/netbsd_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/netbsd_usb.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/netbsd_usb.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/openbsd_usb.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/openbsd_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/openbsd_usb.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/openbsd_usb.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_posix.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/poll_windows.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/sunos_usb.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_posix.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/threads_windows.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/wince_usb.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_common.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_common.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_common.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_common.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_nt_common.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_usbdk.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/os/windows_winusb.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/strerror.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/strerror.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/strerror.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/strerror.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/sync.c b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/sync.c similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/sync.c rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/sync.c diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/version.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/version.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/version.h diff --git a/go-api-for-hardware-wallet/usbhid/c/libusb/version_nano.h b/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version_nano.h similarity index 100% rename from go-api-for-hardware-wallet/usbhid/c/libusb/version_nano.h rename to go-api-for-hardware-wallet/usb/usbhid/c/libusb/version_nano.h diff --git a/go-api-for-hardware-wallet/usbhid/hid.go b/go-api-for-hardware-wallet/usb/usbhid/hid.go similarity index 100% rename from go-api-for-hardware-wallet/usbhid/hid.go rename to go-api-for-hardware-wallet/usb/usbhid/hid.go diff --git a/go-api-for-hardware-wallet/usbhid/libusb.go b/go-api-for-hardware-wallet/usb/usbhid/libusb.go similarity index 100% rename from go-api-for-hardware-wallet/usbhid/libusb.go rename to go-api-for-hardware-wallet/usb/usbhid/libusb.go diff --git a/go-api-for-hardware-wallet/usbhid/wchar.go b/go-api-for-hardware-wallet/usb/usbhid/wchar.go similarity index 100% rename from go-api-for-hardware-wallet/usbhid/wchar.go rename to go-api-for-hardware-wallet/usb/usbhid/wchar.go diff --git a/go-api-for-hardware-wallet/usb/webusb.go b/go-api-for-hardware-wallet/usb/webusb.go index 9311f3d1..4e24de2e 100644 --- a/go-api-for-hardware-wallet/usb/webusb.go +++ b/go-api-for-hardware-wallet/usb/webusb.go @@ -6,7 +6,7 @@ import ( "sync" "sync/atomic" - "github.com/usbhid" + "./usbhid" ) const ( diff --git a/go-api-for-hardware-wallet/wire/protobuf.go b/go-api-for-hardware-wallet/wire/protobuf.go new file mode 100644 index 00000000..0808ce6c --- /dev/null +++ b/go-api-for-hardware-wallet/wire/protobuf.go @@ -0,0 +1,54 @@ +package wire + +import ( + "bytes" + "encoding/binary" + "errors" + "io" +) + +var ( + ErrMalformedProtobuf = errors.New("malformed protobuf") +) + +func Validate(buf []byte) error { + const ( + wireVarint = 0 // int32, int64, uint32, uint64, sint32, sint64, bool, enum + wireData = 2 // string, bytes, embedded messages, packed repeated fields + maxFieldSize = 1024 * 1024 * 4 // 4mb field size + ) + + r := bytes.NewReader(buf) + + for r.Len() > 0 { + // read the field key (combination of tag and type) + key, err := binary.ReadUvarint(r) + if err != nil { + return err + } + + // validate the field type + typ := key & 7 + if typ != wireVarint && typ != wireData { + return ErrMalformedProtobuf + } + + // read the field value + val, err := binary.ReadUvarint(r) + if err != nil { + return err + } + if typ == wireData { + // field is length-delimited data, skip the data + if val > maxFieldSize || int64(val) < 0 { + return ErrMalformedProtobuf + } + _, err = r.Seek(int64(val), io.SeekCurrent) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/go-api-for-hardware-wallet/wire/v1.go b/go-api-for-hardware-wallet/wire/v1.go new file mode 100644 index 00000000..9362084a --- /dev/null +++ b/go-api-for-hardware-wallet/wire/v1.go @@ -0,0 +1,106 @@ +package wire + +import ( + "encoding/binary" + "errors" + "io" +) + +const ( + repMarker = '?' + repMagic = '#' + packetLen = 64 +) + +type Message struct { + Kind uint16 + Data []byte +} + +func (m *Message) WriteTo(w io.Writer) (int64, error) { + var ( + rep [packetLen]byte + kind = m.Kind + size = uint32(len(m.Data)) + ) + // pack header + rep[0] = repMarker + rep[1] = repMagic + rep[2] = repMagic + binary.BigEndian.PutUint16(rep[3:], kind) + binary.BigEndian.PutUint32(rep[5:], size) + + var ( + written = 0 // number of written bytes + offset = 9 // just after the header + ) + for written < len(m.Data) { + n := copy(rep[offset:], m.Data[written:]) + written += n + offset += n + if offset >= len(rep) { + _, err := w.Write(rep[:]) + if err != nil { + return int64(written), err + } + offset = 1 // just after the marker + } + } + if offset != 1 { + for offset < len(rep) { + rep[offset] = 0x00 + offset++ + } + _, err := w.Write(rep[:]) + if err != nil { + return int64(written), err + } + } + + return int64(written), nil +} + +var ( + ErrMalformedMessage = errors.New("malformed wire format") +) + +func (m *Message) ReadFrom(r io.Reader) (int64, error) { + var ( + rep [packetLen]byte + read = 0 // number of read bytes + ) + n, err := r.Read(rep[:]) + if err != nil { + return int64(read), err + } + read += n + if rep[0] != repMarker || rep[1] != repMagic || rep[2] != repMagic { + return int64(read), ErrMalformedMessage + } + + // parse header + var ( + kind = binary.BigEndian.Uint16(rep[3:]) + size = binary.BigEndian.Uint32(rep[5:]) + data = make([]byte, 0, size) + ) + data = append(data, rep[9:]...) // read data after header + + for uint32(len(data)) < size { + n, err := r.Read(rep[:]) + if err != nil { + return int64(read), err + } + if rep[0] != repMarker { + return int64(read), ErrMalformedMessage + } + read += n + data = append(data, rep[1:]...) // read data after marker + } + data = data[:size] + + m.Kind = kind + m.Data = data + + return int64(read), nil +} From 1928b10e693e4a7ede94ce7a2dd5bca1c5c14056 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 8 Apr 2018 12:07:55 +0900 Subject: [PATCH 41/73] Library usage example --- go-api-for-hardware-wallet/README.md | 6 ++++ .../{ => hardware-wallet}/trezor.go | 4 +-- go-api-for-hardware-wallet/main.go | 31 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 go-api-for-hardware-wallet/README.md rename go-api-for-hardware-wallet/{ => hardware-wallet}/trezor.go (97%) create mode 100644 go-api-for-hardware-wallet/main.go diff --git a/go-api-for-hardware-wallet/README.md b/go-api-for-hardware-wallet/README.md new file mode 100644 index 00000000..0923ac65 --- /dev/null +++ b/go-api-for-hardware-wallet/README.md @@ -0,0 +1,6 @@ +# Before use + + # generate protobuf files + protoc -I ./protob --go_out=./protob protob/messages.proto protob/types.proto + go build + go run main.go #code example in main.go diff --git a/go-api-for-hardware-wallet/trezor.go b/go-api-for-hardware-wallet/hardware-wallet/trezor.go similarity index 97% rename from go-api-for-hardware-wallet/trezor.go rename to go-api-for-hardware-wallet/hardware-wallet/trezor.go index a569222c..bd365a33 100644 --- a/go-api-for-hardware-wallet/trezor.go +++ b/go-api-for-hardware-wallet/hardware-wallet/trezor.go @@ -7,9 +7,9 @@ import ( "log" "time" - "./usb" + "../usb" - messages "./protob" + messages "../protob" ) func GetTrezorDevice() (usb.Device, error) { diff --git a/go-api-for-hardware-wallet/main.go b/go-api-for-hardware-wallet/main.go new file mode 100644 index 00000000..515dd9f1 --- /dev/null +++ b/go-api-for-hardware-wallet/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "./hardware-wallet" + + messages "./protob" + "./wire" + "github.com/golang/protobuf/proto" +) + +func main() { + dev, _ := hardwareWallet.GetTrezorDevice() + + skycoinAddress := &messages.SkycoinAddress{ + Seed: proto.String("seed"), + AddressType: messages.SkycoinAddressType_AddressTypeSkycoin.Enum(), + } + data, _ := proto.Marshal(skycoinAddress) + + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_SkycoinAddress) + + for _, element := range chunks { + _, _ = dev.Write(element[:]) + } + + var msg wire.Message + msg.ReadFrom(dev) + + fmt.Printf("Success %d! Address is: %s\n", msg.Kind, msg.Data) +} \ No newline at end of file From b8bbd2cfe9727c3b8d092141ba10d385b1fe7286 Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 12 Apr 2018 18:44:56 +0900 Subject: [PATCH 42/73] First version of ecdsa_skycoin_sign that returns satisfying signature with a fixed nonce --- hardware-wallet/skycoin_crypto.c | 112 ++++++++++++++++++++++++++ hardware-wallet/skycoin_crypto.h | 1 + hardware-wallet/test_skycoin_crypto.c | 24 ++++++ 3 files changed, 137 insertions(+) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 06565867..ad78efd8 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -250,3 +250,115 @@ int recover_pubkey_from_signed_message(const char* message, const uint8_t* signa } return res; } + +// uses secp256k1 curve +// priv_key is a 32 byte big endian stored number +// sig is 64 bytes long array for the signature +// digest is 32 bytes of digest +// is_canonical is an optional function that checks if the signature +// conforms to additional coin-specific rules. +int ecdsa_skycoin_sign(const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby) +{ + int i; + curve_point R; + bignum256 nonce, z, randk; + bignum256 *s = &R.y; + uint8_t by; // signature recovery byte + + HDNode dummy_node; + char seed_str[256] = "dummy seed"; + create_node(seed_str, &dummy_node); + bn_read_be(digest, &z); + + for (i = 0; i < 1; i++) { + + + // generate random number nonce + // generate_k_random(&nonce, &dummy_node.curve->params->order); + bn_one(&nonce); + // compute nonce*G + scalar_multiply(dummy_node.curve->params, &nonce, &R); + by = R.y.val[0] & 1; + // r = (rx mod n) + if (!bn_is_less(&R.x, &dummy_node.curve->params->order)) { + bn_subtract(&R.x, &dummy_node.curve->params->order, &R.x); + by |= 2; + } + // if r is zero, we retry + if (bn_is_zero(&R.x)) { + printf("Premature exit 1"); + continue; + } +////////////////////// + printf("R.x: "); + bn_print(&R.x); + printf("\n"); +////////////////////// + printf("R.y: "); + bn_print(&R.y); + printf("\n"); +////////////////////// + + // randomize operations to counter side-channel attacks + // generate_k_random(&randk, &dummy_node.curve->params->order); + // bn_one(&randk); + // bn_multiply(&randk, &nonce, &dummy_node.curve->params->order); // nonce*rand + bn_inverse(&nonce, &dummy_node.curve->params->order); // (nonce*rand)^-1 + bn_read_be(priv_key, s); // priv +////////////////////// + printf("s: "); + bn_print(s); + printf("\n"); +////////////////////// + bn_multiply(&R.x, s, &dummy_node.curve->params->order); // R.x*priv +////////////////////// + printf("s: "); + bn_print(s); + printf("\n"); +////////////////////// + bn_add(s, &z); // R.x*priv + z +////////////////////// + printf("z: "); + bn_print(&z); + printf("\n"); +////////////////////// + // bn_multiply(&nonce, s, &dummy_node.curve->params->order); // (nonce*rand)^-1 (R.x*priv + z) + // bn_multiply(&randk, s, &dummy_node.curve->params->order); // nonce^-1 (R.x*priv + z) + bn_mod(s, &dummy_node.curve->params->order); +////////////////////// + printf("s: "); + bn_print(s); + printf("\n"); +////////////////////// + // if s is zero, we retry + if (bn_is_zero(s)) { + printf("Premature exit 2"); + continue; + } + + // if S > order/2 => S = -S + if (bn_is_less(&dummy_node.curve->params->order_half, s)) { + bn_subtract(&dummy_node.curve->params->order, s, s); + by ^= 1; + } + // we are done, R.x and s is the result signature + bn_write_be(&R.x, sig); + bn_write_be(s, sig + 32); + + if (pby) { + *pby = by; + } + + memset(&nonce, 0, sizeof(nonce)); + memset(&randk, 0, sizeof(randk)); + + return 0; + } + + // Too many retries without a valid signature + // -> fail with an error + memset(&nonce, 0, sizeof(nonce)); + memset(&randk, 0, sizeof(randk)); + + return -1; +} diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index e16ec7cd..7916a1d0 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -15,5 +15,6 @@ void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, s void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_private_address_from_seckey(const uint8_t* pubkey, char* address, size_t *size_address); int recover_pubkey_from_signed_message(const char* message, const uint8_t* signature, uint8_t* pubkey); +int ecdsa_skycoin_sign(const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby); void tohex(char * str, const uint8_t* buffer, int bufferLength); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index daa2bba6..aba0a38b 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -6,6 +6,8 @@ #include "check.h" #include "sha2.h" //SHA256_DIGEST_LENGTH #include "base58.h" +#include "ecdsa.h" +#include "secp256k1.h" #define FROMHEX_MAXLEN 512 @@ -318,6 +320,27 @@ START_TEST(test_recover_pubkey_from_signed_message) } END_TEST +START_TEST(test_signature) +{ + int res; + uint8_t digest[32]; + // const ecdsa_curve *curve = &secp256k1; + uint8_t my_seckey[32]; + uint8_t by = 0; + uint8_t signature[65]; + memcpy(my_seckey, fromhex("597e27368656cab3c82bfcf2fb074cefd8b6101781a27709ba1b326b738d2c5a"), sizeof(my_seckey)); + // sha2(sha2("\x18Bitcoin Signed Message:\n\x0cHello World!")) + memcpy(digest, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); + + res = ecdsa_skycoin_sign(my_seckey, digest, signature, &by); + // res = ecdsa_sign_digest(curve, my_seckey, digest, signature, &by, NULL); + ck_assert_int_eq(res, 0); + ck_assert_int_eq(by, 1); + ck_assert_mem_eq(signature, fromhex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), 32); + ck_assert_mem_eq(&signature[32], fromhex("04641a7472bb90647fa60b4d30aef8c7279e4b68226f7b2713dab712ef122f8b01"), 32); +} +END_TEST + // define test suite and cases Suite *test_suite(void) { @@ -336,6 +359,7 @@ Suite *test_suite(void) tcase_add_test(tc, test_compute_ecdh); tcase_add_test(tc, test_recover_pubkey_from_signed_message); tcase_add_test(tc, test_base58_decode); + tcase_add_test(tc, test_signature); suite_add_tcase(s, tc); return s; From 25eea87218a7455d57aeff01f2ea13e537ecdf3d Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 12 Apr 2018 18:52:29 +0900 Subject: [PATCH 43/73] adding nonce manual setting for test purposes --- hardware-wallet/skycoin_crypto.c | 4 ++-- hardware-wallet/skycoin_crypto.h | 2 +- hardware-wallet/test_skycoin_crypto.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index ad78efd8..5c8bdabc 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -257,7 +257,7 @@ int recover_pubkey_from_signed_message(const char* message, const uint8_t* signa // digest is 32 bytes of digest // is_canonical is an optional function that checks if the signature // conforms to additional coin-specific rules. -int ecdsa_skycoin_sign(const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby) +int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby) { int i; curve_point R; @@ -275,7 +275,7 @@ int ecdsa_skycoin_sign(const uint8_t *priv_key, const uint8_t *digest, uint8_t * // generate random number nonce // generate_k_random(&nonce, &dummy_node.curve->params->order); - bn_one(&nonce); + bn_read_uint32(nonce_value, &nonce); // compute nonce*G scalar_multiply(dummy_node.curve->params, &nonce, &R); by = R.y.val[0] & 1; diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index 7916a1d0..f410ff9c 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -15,6 +15,6 @@ void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, s void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_private_address_from_seckey(const uint8_t* pubkey, char* address, size_t *size_address); int recover_pubkey_from_signed_message(const char* message, const uint8_t* signature, uint8_t* pubkey); -int ecdsa_skycoin_sign(const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby); +int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby); void tohex(char * str, const uint8_t* buffer, int bufferLength); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index aba0a38b..3d8ca5de 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -332,7 +332,7 @@ START_TEST(test_signature) // sha2(sha2("\x18Bitcoin Signed Message:\n\x0cHello World!")) memcpy(digest, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); - res = ecdsa_skycoin_sign(my_seckey, digest, signature, &by); + res = ecdsa_skycoin_sign(1, my_seckey, digest, signature, &by); // res = ecdsa_sign_digest(curve, my_seckey, digest, signature, &by, NULL); ck_assert_int_eq(res, 0); ck_assert_int_eq(by, 1); From 4c7193234bc86c9828853186079af0b7f38de4e2 Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 12 Apr 2018 18:55:02 +0900 Subject: [PATCH 44/73] Fixing the nounce problem --- hardware-wallet/skycoin_crypto.c | 2 +- hardware-wallet/test_skycoin_crypto.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 5c8bdabc..b7cf8224 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -322,7 +322,7 @@ int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, cons bn_print(&z); printf("\n"); ////////////////////// - // bn_multiply(&nonce, s, &dummy_node.curve->params->order); // (nonce*rand)^-1 (R.x*priv + z) + bn_multiply(&nonce, s, &dummy_node.curve->params->order); // (nonce*rand)^-1 (R.x*priv + z) // bn_multiply(&randk, s, &dummy_node.curve->params->order); // nonce^-1 (R.x*priv + z) bn_mod(s, &dummy_node.curve->params->order); ////////////////////// diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 3d8ca5de..e41f5161 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -338,6 +338,21 @@ START_TEST(test_signature) ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), 32); ck_assert_mem_eq(&signature[32], fromhex("04641a7472bb90647fa60b4d30aef8c7279e4b68226f7b2713dab712ef122f8b01"), 32); + + + res = ecdsa_skycoin_sign(0xfe25, my_seckey, digest, signature, &by); + // res = ecdsa_sign_digest(curve, my_seckey, digest, signature, &by, NULL); + ck_assert_int_eq(res, 0); + ck_assert_int_eq(by, 1); + ck_assert_mem_eq(signature, fromhex("ee38f27be5f3c4b8db875c0ffbc0232e93f622d16ede888508a4920ab51c3c99"), 32); + ck_assert_mem_eq(&signature[32], fromhex("06ea7426c5e251e4bea76f06f554fa7798a49b7968b400fa981c51531a5748d801"), 32); + + res = ecdsa_skycoin_sign(0xfe250100, my_seckey, digest, signature, &by); + // res = ecdsa_sign_digest(curve, my_seckey, digest, signature, &by, NULL); + ck_assert_int_eq(res, 0); + ck_assert_int_eq(by, 0); + ck_assert_mem_eq(signature, fromhex("d4d869ad39cb3a64fa1980b47d1f19bd568430d3f929e01c00f1e5b7c6840ba8"), 32); + ck_assert_mem_eq(&signature[32], fromhex("5e08d5781986ee72d1e8ebd4dd050386a64eee0256005626d2acbe3aefee9e2500"), 32); } END_TEST From 00c722d5c0591a150b5ff307410d578609ab1424 Mon Sep 17 00:00:00 2001 From: mpsido Date: Thu, 12 Apr 2018 19:00:24 +0900 Subject: [PATCH 45/73] removing commented out code in test_skycoin_crypto.c --- hardware-wallet/test_skycoin_crypto.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index e41f5161..3b2b0144 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -324,32 +324,27 @@ START_TEST(test_signature) { int res; uint8_t digest[32]; - // const ecdsa_curve *curve = &secp256k1; uint8_t my_seckey[32]; uint8_t by = 0; uint8_t signature[65]; memcpy(my_seckey, fromhex("597e27368656cab3c82bfcf2fb074cefd8b6101781a27709ba1b326b738d2c5a"), sizeof(my_seckey)); - // sha2(sha2("\x18Bitcoin Signed Message:\n\x0cHello World!")) - memcpy(digest, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); + memcpy(digest, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); res = ecdsa_skycoin_sign(1, my_seckey, digest, signature, &by); - // res = ecdsa_sign_digest(curve, my_seckey, digest, signature, &by, NULL); - ck_assert_int_eq(res, 0); + ck_assert_int_eq(res, 0); ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), 32); ck_assert_mem_eq(&signature[32], fromhex("04641a7472bb90647fa60b4d30aef8c7279e4b68226f7b2713dab712ef122f8b01"), 32); res = ecdsa_skycoin_sign(0xfe25, my_seckey, digest, signature, &by); - // res = ecdsa_sign_digest(curve, my_seckey, digest, signature, &by, NULL); - ck_assert_int_eq(res, 0); + ck_assert_int_eq(res, 0); ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("ee38f27be5f3c4b8db875c0ffbc0232e93f622d16ede888508a4920ab51c3c99"), 32); ck_assert_mem_eq(&signature[32], fromhex("06ea7426c5e251e4bea76f06f554fa7798a49b7968b400fa981c51531a5748d801"), 32); res = ecdsa_skycoin_sign(0xfe250100, my_seckey, digest, signature, &by); - // res = ecdsa_sign_digest(curve, my_seckey, digest, signature, &by, NULL); - ck_assert_int_eq(res, 0); + ck_assert_int_eq(res, 0); ck_assert_int_eq(by, 0); ck_assert_mem_eq(signature, fromhex("d4d869ad39cb3a64fa1980b47d1f19bd568430d3f929e01c00f1e5b7c6840ba8"), 32); ck_assert_mem_eq(&signature[32], fromhex("5e08d5781986ee72d1e8ebd4dd050386a64eee0256005626d2acbe3aefee9e2500"), 32); From 0cf525fdaca7b7d36525811e264d8aee0ded2a0f Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 13 Apr 2018 15:12:06 +0900 Subject: [PATCH 46/73] recover_pubkey_from_signed_message in test_signature --- hardware-wallet/test_skycoin_crypto.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 3b2b0144..0a76a53d 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -327,6 +327,8 @@ START_TEST(test_signature) uint8_t my_seckey[32]; uint8_t by = 0; uint8_t signature[65]; + uint8_t pubkey[33]; + char* message = (char*)digest; memcpy(my_seckey, fromhex("597e27368656cab3c82bfcf2fb074cefd8b6101781a27709ba1b326b738d2c5a"), sizeof(my_seckey)); memcpy(digest, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); @@ -335,19 +337,30 @@ START_TEST(test_signature) ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), 32); ck_assert_mem_eq(&signature[32], fromhex("04641a7472bb90647fa60b4d30aef8c7279e4b68226f7b2713dab712ef122f8b01"), 32); - + signature[64] = by; + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); res = ecdsa_skycoin_sign(0xfe25, my_seckey, digest, signature, &by); ck_assert_int_eq(res, 0); ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("ee38f27be5f3c4b8db875c0ffbc0232e93f622d16ede888508a4920ab51c3c99"), 32); ck_assert_mem_eq(&signature[32], fromhex("06ea7426c5e251e4bea76f06f554fa7798a49b7968b400fa981c51531a5748d801"), 32); + signature[64] = by; + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); res = ecdsa_skycoin_sign(0xfe250100, my_seckey, digest, signature, &by); ck_assert_int_eq(res, 0); ck_assert_int_eq(by, 0); ck_assert_mem_eq(signature, fromhex("d4d869ad39cb3a64fa1980b47d1f19bd568430d3f929e01c00f1e5b7c6840ba8"), 32); ck_assert_mem_eq(&signature[32], fromhex("5e08d5781986ee72d1e8ebd4dd050386a64eee0256005626d2acbe3aefee9e2500"), 32); + signature[64] = by; + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); } END_TEST From b4381ec0d42a80b0e5c2263180ed9bef49f8f64f Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 13 Apr 2018 15:14:36 +0900 Subject: [PATCH 47/73] write recey as last byte of signature inside ecdsa_skycoin_sign function --- hardware-wallet/skycoin_crypto.c | 3 ++- hardware-wallet/test_skycoin_crypto.c | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index b7cf8224..305f5a75 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -253,7 +253,7 @@ int recover_pubkey_from_signed_message(const char* message, const uint8_t* signa // uses secp256k1 curve // priv_key is a 32 byte big endian stored number -// sig is 64 bytes long array for the signature +// sig is 65 bytes long array for the signature // digest is 32 bytes of digest // is_canonical is an optional function that checks if the signature // conforms to additional coin-specific rules. @@ -348,6 +348,7 @@ int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, cons if (pby) { *pby = by; } + sig[64] = by; memset(&nonce, 0, sizeof(nonce)); memset(&randk, 0, sizeof(randk)); diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 0a76a53d..8341a971 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -337,7 +337,6 @@ START_TEST(test_signature) ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), 32); ck_assert_mem_eq(&signature[32], fromhex("04641a7472bb90647fa60b4d30aef8c7279e4b68226f7b2713dab712ef122f8b01"), 32); - signature[64] = by; res = recover_pubkey_from_signed_message(message, signature, pubkey); ck_assert_int_eq(res, 0); ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); @@ -347,7 +346,6 @@ START_TEST(test_signature) ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("ee38f27be5f3c4b8db875c0ffbc0232e93f622d16ede888508a4920ab51c3c99"), 32); ck_assert_mem_eq(&signature[32], fromhex("06ea7426c5e251e4bea76f06f554fa7798a49b7968b400fa981c51531a5748d801"), 32); - signature[64] = by; res = recover_pubkey_from_signed_message(message, signature, pubkey); ck_assert_int_eq(res, 0); ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); @@ -357,7 +355,6 @@ START_TEST(test_signature) ck_assert_int_eq(by, 0); ck_assert_mem_eq(signature, fromhex("d4d869ad39cb3a64fa1980b47d1f19bd568430d3f929e01c00f1e5b7c6840ba8"), 32); ck_assert_mem_eq(&signature[32], fromhex("5e08d5781986ee72d1e8ebd4dd050386a64eee0256005626d2acbe3aefee9e2500"), 32); - signature[64] = by; res = recover_pubkey_from_signed_message(message, signature, pubkey); ck_assert_int_eq(res, 0); ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); From 2675e35f6fea7d1ec6abda46fcdfc750a329235d Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 13 Apr 2018 15:19:23 +0900 Subject: [PATCH 48/73] test_signature with another key pair --- hardware-wallet/test_skycoin_crypto.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 8341a971..271a96ca 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -358,6 +358,16 @@ START_TEST(test_signature) res = recover_pubkey_from_signed_message(message, signature, pubkey); ck_assert_int_eq(res, 0); ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); + + // try of another key pair + memcpy(my_seckey, fromhex("67a331669081d22624f16512ea61e1d44cb3f26af3333973d17e0e8d03733b78"), sizeof(my_seckey)); + + res = ecdsa_skycoin_sign(0x1e2501ac, my_seckey, digest, signature, &by); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(signature, fromhex("eeee743d79b40aaa52d9eeb48791b0ae81a2f425bf99cdbc84180e8ed429300d457e8d669dbff1716b123552baf6f6f0ef67f16c1d9ccd44e6785d424002212601"), 65); + res = recover_pubkey_from_signed_message(message, signature, pubkey); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("0270b763664593c5f84dfb20d23ef79530fc317e5ee2ece0d9c50f432f62426ff9"), 33); } END_TEST From 1226fed9d205a0c2cd00146d1b2aaf106b4cba19 Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 13 Apr 2018 15:21:37 +0900 Subject: [PATCH 49/73] Remove by or recid from ecdsa_skycoin_sign parameters --- hardware-wallet/skycoin_crypto.c | 5 +---- hardware-wallet/skycoin_crypto.h | 2 +- hardware-wallet/test_skycoin_crypto.c | 12 ++++-------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 305f5a75..74db6f8d 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -257,7 +257,7 @@ int recover_pubkey_from_signed_message(const char* message, const uint8_t* signa // digest is 32 bytes of digest // is_canonical is an optional function that checks if the signature // conforms to additional coin-specific rules. -int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby) +int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig) { int i; curve_point R; @@ -345,9 +345,6 @@ int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, cons bn_write_be(&R.x, sig); bn_write_be(s, sig + 32); - if (pby) { - *pby = by; - } sig[64] = by; memset(&nonce, 0, sizeof(nonce)); diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin_crypto.h index f410ff9c..5409b0fa 100644 --- a/hardware-wallet/skycoin_crypto.h +++ b/hardware-wallet/skycoin_crypto.h @@ -15,6 +15,6 @@ void generate_base58_address_from_pubkey(const uint8_t* pubkey, char* address, s void generate_bitcoin_address_from_pubkey(const uint8_t* pubkey, char* address, size_t *size_address); void generate_bitcoin_private_address_from_seckey(const uint8_t* pubkey, char* address, size_t *size_address); int recover_pubkey_from_signed_message(const char* message, const uint8_t* signature, uint8_t* pubkey); -int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby); +int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig); void tohex(char * str, const uint8_t* buffer, int bufferLength); #endif diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/test_skycoin_crypto.c index 271a96ca..aae95f75 100644 --- a/hardware-wallet/test_skycoin_crypto.c +++ b/hardware-wallet/test_skycoin_crypto.c @@ -325,34 +325,30 @@ START_TEST(test_signature) int res; uint8_t digest[32]; uint8_t my_seckey[32]; - uint8_t by = 0; uint8_t signature[65]; uint8_t pubkey[33]; char* message = (char*)digest; memcpy(my_seckey, fromhex("597e27368656cab3c82bfcf2fb074cefd8b6101781a27709ba1b326b738d2c5a"), sizeof(my_seckey)); memcpy(digest, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); - res = ecdsa_skycoin_sign(1, my_seckey, digest, signature, &by); + res = ecdsa_skycoin_sign(1, my_seckey, digest, signature); ck_assert_int_eq(res, 0); - ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), 32); ck_assert_mem_eq(&signature[32], fromhex("04641a7472bb90647fa60b4d30aef8c7279e4b68226f7b2713dab712ef122f8b01"), 32); res = recover_pubkey_from_signed_message(message, signature, pubkey); ck_assert_int_eq(res, 0); ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); - res = ecdsa_skycoin_sign(0xfe25, my_seckey, digest, signature, &by); + res = ecdsa_skycoin_sign(0xfe25, my_seckey, digest, signature); ck_assert_int_eq(res, 0); - ck_assert_int_eq(by, 1); ck_assert_mem_eq(signature, fromhex("ee38f27be5f3c4b8db875c0ffbc0232e93f622d16ede888508a4920ab51c3c99"), 32); ck_assert_mem_eq(&signature[32], fromhex("06ea7426c5e251e4bea76f06f554fa7798a49b7968b400fa981c51531a5748d801"), 32); res = recover_pubkey_from_signed_message(message, signature, pubkey); ck_assert_int_eq(res, 0); ck_assert_mem_eq(pubkey, fromhex("02df09821cff4874198a1dbdc462d224bd99728eeed024185879225762376132c7"), 33); - res = ecdsa_skycoin_sign(0xfe250100, my_seckey, digest, signature, &by); + res = ecdsa_skycoin_sign(0xfe250100, my_seckey, digest, signature); ck_assert_int_eq(res, 0); - ck_assert_int_eq(by, 0); ck_assert_mem_eq(signature, fromhex("d4d869ad39cb3a64fa1980b47d1f19bd568430d3f929e01c00f1e5b7c6840ba8"), 32); ck_assert_mem_eq(&signature[32], fromhex("5e08d5781986ee72d1e8ebd4dd050386a64eee0256005626d2acbe3aefee9e2500"), 32); res = recover_pubkey_from_signed_message(message, signature, pubkey); @@ -362,7 +358,7 @@ START_TEST(test_signature) // try of another key pair memcpy(my_seckey, fromhex("67a331669081d22624f16512ea61e1d44cb3f26af3333973d17e0e8d03733b78"), sizeof(my_seckey)); - res = ecdsa_skycoin_sign(0x1e2501ac, my_seckey, digest, signature, &by); + res = ecdsa_skycoin_sign(0x1e2501ac, my_seckey, digest, signature); ck_assert_int_eq(res, 0); ck_assert_mem_eq(signature, fromhex("eeee743d79b40aaa52d9eeb48791b0ae81a2f425bf99cdbc84180e8ed429300d457e8d669dbff1716b123552baf6f6f0ef67f16c1d9ccd44e6785d424002212601"), 65); res = recover_pubkey_from_signed_message(message, signature, pubkey); From 6169cc08936d89b251e33710800c59c6e8aa51a7 Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 13 Apr 2018 15:23:52 +0900 Subject: [PATCH 50/73] clean ecdsa_skycoin_sign from logs and commented out code --- hardware-wallet/skycoin_crypto.c | 38 +------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin_crypto.c index 74db6f8d..27ea5760 100644 --- a/hardware-wallet/skycoin_crypto.c +++ b/hardware-wallet/skycoin_crypto.c @@ -271,8 +271,6 @@ int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, cons bn_read_be(digest, &z); for (i = 0; i < 1; i++) { - - // generate random number nonce // generate_k_random(&nonce, &dummy_node.curve->params->order); bn_read_uint32(nonce_value, &nonce); @@ -289,47 +287,13 @@ int ecdsa_skycoin_sign(const uint32_t nonce_value, const uint8_t *priv_key, cons printf("Premature exit 1"); continue; } -////////////////////// - printf("R.x: "); - bn_print(&R.x); - printf("\n"); -////////////////////// - printf("R.y: "); - bn_print(&R.y); - printf("\n"); -////////////////////// - - // randomize operations to counter side-channel attacks - // generate_k_random(&randk, &dummy_node.curve->params->order); - // bn_one(&randk); - // bn_multiply(&randk, &nonce, &dummy_node.curve->params->order); // nonce*rand bn_inverse(&nonce, &dummy_node.curve->params->order); // (nonce*rand)^-1 bn_read_be(priv_key, s); // priv -////////////////////// - printf("s: "); - bn_print(s); - printf("\n"); -////////////////////// bn_multiply(&R.x, s, &dummy_node.curve->params->order); // R.x*priv -////////////////////// - printf("s: "); - bn_print(s); - printf("\n"); -////////////////////// bn_add(s, &z); // R.x*priv + z -////////////////////// - printf("z: "); - bn_print(&z); - printf("\n"); -////////////////////// bn_multiply(&nonce, s, &dummy_node.curve->params->order); // (nonce*rand)^-1 (R.x*priv + z) - // bn_multiply(&randk, s, &dummy_node.curve->params->order); // nonce^-1 (R.x*priv + z) bn_mod(s, &dummy_node.curve->params->order); -////////////////////// - printf("s: "); - bn_print(s); - printf("\n"); -////////////////////// + // if s is zero, we retry if (bn_is_zero(s)) { printf("Premature exit 2"); From fdf20811a43b11116e020ac222fa71b440d05182 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 15 Apr 2018 12:58:57 +0900 Subject: [PATCH 51/73] Move request creation in a separate function --- go-api-for-hardware-wallet/main.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/go-api-for-hardware-wallet/main.go b/go-api-for-hardware-wallet/main.go index 515dd9f1..d9f920be 100644 --- a/go-api-for-hardware-wallet/main.go +++ b/go-api-for-hardware-wallet/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "./hardware-wallet" messages "./protob" @@ -9,9 +10,7 @@ import ( "github.com/golang/protobuf/proto" ) -func main() { - dev, _ := hardwareWallet.GetTrezorDevice() - +func MessageSkycoinAddress() [][64]byte { skycoinAddress := &messages.SkycoinAddress{ Seed: proto.String("seed"), AddressType: messages.SkycoinAddressType_AddressTypeSkycoin.Enum(), @@ -19,6 +18,13 @@ func main() { data, _ := proto.Marshal(skycoinAddress) chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_SkycoinAddress) + return chunks +} + +func main() { + dev, _ := hardwareWallet.GetTrezorDevice() + + chunks := MessageSkycoinAddress() for _, element := range chunks { _, _ = dev.Write(element[:]) @@ -27,5 +33,5 @@ func main() { var msg wire.Message msg.ReadFrom(dev) - fmt.Printf("Success %d! Address is: %s\n", msg.Kind, msg.Data) -} \ No newline at end of file + fmt.Printf("Success %d! Address is: %s\n", msg.Kind, msg.Data) +} From 95068351afbd15c24bf2f89a2045302932f2f87c Mon Sep 17 00:00:00 2001 From: mpsido Date: Sun, 15 Apr 2018 13:02:29 +0900 Subject: [PATCH 52/73] Adding function MessageCheckMessageSignature --- go-api-for-hardware-wallet/main.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/go-api-for-hardware-wallet/main.go b/go-api-for-hardware-wallet/main.go index d9f920be..e04d95a7 100644 --- a/go-api-for-hardware-wallet/main.go +++ b/go-api-for-hardware-wallet/main.go @@ -21,10 +21,24 @@ func MessageSkycoinAddress() [][64]byte { return chunks } + +func MessageCheckMessageSignature() [][64]byte { + skycoinCheckMessageSignature := &messages.SkycoinCheckMessageSignature{ + Address: proto.String("2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"), + Message: proto.String("Hello World!"), + Signature: proto.String("GA82nXSwVEPV5soMjCiQkJb4oLEAo6FMK8CAE2n2YBTm7xjhAknUxtZrhs3RPVMfQsEoLwkJCEgvGj8a2vzthBQ1M"), + } + + data, _ := proto.Marshal(skycoinCheckMessageSignature) + + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_SkycoinCheckMessageSignature) + return chunks +} + func main() { dev, _ := hardwareWallet.GetTrezorDevice() - chunks := MessageSkycoinAddress() + chunks := MessageCheckMessageSignature() for _, element := range chunks { _, _ = dev.Write(element[:]) From 0a2907742803a3dbd3b91ceedc62cdbc059f0a76 Mon Sep 17 00:00:00 2001 From: mpsido Date: Tue, 17 Apr 2018 15:09:07 +0700 Subject: [PATCH 53/73] Adding message MessageSkycoinSignMessage --- go-api-for-hardware-wallet/main.go | 39 +++++++++++++++---- .../protob/messages.options | 2 + .../protob/messages.proto | 9 +++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/go-api-for-hardware-wallet/main.go b/go-api-for-hardware-wallet/main.go index e04d95a7..b19de6a5 100644 --- a/go-api-for-hardware-wallet/main.go +++ b/go-api-for-hardware-wallet/main.go @@ -7,6 +7,7 @@ import ( messages "./protob" "./wire" + "./usb" "github.com/golang/protobuf/proto" ) @@ -24,10 +25,10 @@ func MessageSkycoinAddress() [][64]byte { func MessageCheckMessageSignature() [][64]byte { skycoinCheckMessageSignature := &messages.SkycoinCheckMessageSignature{ - Address: proto.String("2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"), - Message: proto.String("Hello World!"), - Signature: proto.String("GA82nXSwVEPV5soMjCiQkJb4oLEAo6FMK8CAE2n2YBTm7xjhAknUxtZrhs3RPVMfQsEoLwkJCEgvGj8a2vzthBQ1M"), - } + Address: proto.String("2EVNa4CK9SKosT4j1GEn8SuuUUEAXaHAMbM"), + Message: proto.String("Hello World!"), + Signature: proto.String("Bk7jnoMj6W6Zd46AFSqKn5KFfdENKK5nx9qEqHdViWwz6n8RVRXVWnsdPMX5BCze5Lq1HerKTgKHPnzToL3XpHyuh"), + } data, _ := proto.Marshal(skycoinCheckMessageSignature) @@ -35,17 +36,39 @@ func MessageCheckMessageSignature() [][64]byte { return chunks } -func main() { - dev, _ := hardwareWallet.GetTrezorDevice() - chunks := MessageCheckMessageSignature() +func MessageSkycoinSignMessage() [][64]byte { + skycoinSignMessage := &messages.SkycoinSignMessage{ + SecretKey: proto.String("Qaj1vWfVPGUvX9dgmTWMRCzqUMcnxzT2M11K5yDMsc"), + Message: proto.String("Hello World!"), + } + + data, _ := proto.Marshal(skycoinSignMessage) + + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_SkycoinSignMessage) + return chunks +} +func SendToDevice(dev usb.Device, chunks [][64]byte) wire.Message { for _, element := range chunks { _, _ = dev.Write(element[:]) } var msg wire.Message msg.ReadFrom(dev) + return msg +} + +func main() { + dev, _ := hardwareWallet.GetTrezorDevice() + var msg wire.Message + var chunks [][64]byte + + chunks = MessageSkycoinSignMessage() + msg = SendToDevice(dev, chunks) + fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - fmt.Printf("Success %d! Address is: %s\n", msg.Kind, msg.Data) + chunks = MessageCheckMessageSignature() + msg = SendToDevice(dev, chunks) + fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) } diff --git a/go-api-for-hardware-wallet/protob/messages.options b/go-api-for-hardware-wallet/protob/messages.options index 687d5c50..e607587a 100644 --- a/go-api-for-hardware-wallet/protob/messages.options +++ b/go-api-for-hardware-wallet/protob/messages.options @@ -21,6 +21,8 @@ SkycoinAddress.seed max_size:256 SkycoinCheckMessageSignature.address max_size:36 SkycoinCheckMessageSignature.message max_size:256 SkycoinCheckMessageSignature.signature max_size:90 +SkycoinSignMessage.message max_size:256 +SkycoinSignMessage.secretKey max_size:45 Success.message max_size:256 diff --git a/go-api-for-hardware-wallet/protob/messages.proto b/go-api-for-hardware-wallet/protob/messages.proto index 2768282f..939dcdca 100644 --- a/go-api-for-hardware-wallet/protob/messages.proto +++ b/go-api-for-hardware-wallet/protob/messages.proto @@ -101,6 +101,7 @@ enum MessageType { MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; MessageType_SkycoinAddress = 114 [(wire_in) = true]; MessageType_SkycoinCheckMessageSignature = 115 [(wire_in) = true]; + MessageType_SkycoinSignMessage = 116 [(wire_in) = true]; } //////////////////// @@ -215,6 +216,14 @@ message SkycoinCheckMessageSignature { required string signature = 3; //electronic signature of the message } +/** + * Request: Sign a message digest using the given secret key. + * @next Success + */ +message SkycoinSignMessage { + required string secretKey = 1; //private address used to produce signature + required string message = 2; //message that we want to sign +} /** * Request: Test if the device is alive, device sends back the message in Success response * @next Success From c7cc3018e756c597c88536abe0d514a394a6d8aa Mon Sep 17 00:00:00 2001 From: mpsido Date: Tue, 17 Apr 2018 16:03:50 +0700 Subject: [PATCH 54/73] Moving files, everything related to firware had been moved in hardware-wallet folder --- .../go-api-for-hardware-wallet}/README.md | 0 .../go-api-for-hardware-wallet}/hardware-wallet/trezor.go | 0 .../go-api-for-hardware-wallet}/main.go | 0 .../go-api-for-hardware-wallet}/protob/messages.options | 0 .../go-api-for-hardware-wallet}/protob/messages.proto | 0 .../go-api-for-hardware-wallet}/protob/types.options | 0 .../go-api-for-hardware-wallet}/protob/types.proto | 0 .../go-api-for-hardware-wallet}/usb/bus.go | 0 .../go-api-for-hardware-wallet}/usb/hidapi.go | 0 .../go-api-for-hardware-wallet}/usb/udp.go | 0 .../go-api-for-hardware-wallet}/usb/usbhid/.gitignore | 0 .../go-api-for-hardware-wallet}/usb/usbhid/.travis.yml | 0 .../go-api-for-hardware-wallet}/usb/usbhid/README.md | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/AUTHORS.txt | 0 .../usb/usbhid/c/hidapi/LICENSE-bsd.txt | 0 .../usb/usbhid/c/hidapi/LICENSE-gpl3.txt | 0 .../usb/usbhid/c/hidapi/LICENSE-orig.txt | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/LICENSE.txt | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/README.txt | 0 .../usb/usbhid/c/hidapi/hidapi/hidapi.h | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/linux/hid.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/mac/hid.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/windows/hid.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/AUTHORS | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/COPYING | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/config.h | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/core.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/descriptor.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/hotplug.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/hotplug.h | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/io.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/libusb.h | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/libusbi.h | 0 .../usb/usbhid/c/libusb/os/darwin_usb.c | 0 .../usb/usbhid/c/libusb/os/darwin_usb.h | 0 .../usb/usbhid/c/libusb/os/haiku_pollfs.cpp | 0 .../usb/usbhid/c/libusb/os/haiku_usb.h | 0 .../usb/usbhid/c/libusb/os/haiku_usb_backend.cpp | 0 .../usb/usbhid/c/libusb/os/haiku_usb_raw.cpp | 0 .../usb/usbhid/c/libusb/os/haiku_usb_raw.h | 0 .../usb/usbhid/c/libusb/os/linux_netlink.c | 0 .../usb/usbhid/c/libusb/os/linux_udev.c | 0 .../usb/usbhid/c/libusb/os/linux_usbfs.c | 0 .../usb/usbhid/c/libusb/os/linux_usbfs.h | 0 .../usb/usbhid/c/libusb/os/netbsd_usb.c | 0 .../usb/usbhid/c/libusb/os/openbsd_usb.c | 0 .../usb/usbhid/c/libusb/os/poll_posix.c | 0 .../usb/usbhid/c/libusb/os/poll_posix.h | 0 .../usb/usbhid/c/libusb/os/poll_windows.c | 0 .../usb/usbhid/c/libusb/os/poll_windows.h | 0 .../usb/usbhid/c/libusb/os/sunos_usb.c | 0 .../usb/usbhid/c/libusb/os/sunos_usb.h | 0 .../usb/usbhid/c/libusb/os/threads_posix.c | 0 .../usb/usbhid/c/libusb/os/threads_posix.h | 0 .../usb/usbhid/c/libusb/os/threads_windows.c | 0 .../usb/usbhid/c/libusb/os/threads_windows.h | 0 .../usb/usbhid/c/libusb/os/wince_usb.c | 0 .../usb/usbhid/c/libusb/os/wince_usb.h | 0 .../usb/usbhid/c/libusb/os/windows_common.h | 0 .../usb/usbhid/c/libusb/os/windows_nt_common.c | 0 .../usb/usbhid/c/libusb/os/windows_nt_common.h | 0 .../usb/usbhid/c/libusb/os/windows_usbdk.c | 0 .../usb/usbhid/c/libusb/os/windows_usbdk.h | 0 .../usb/usbhid/c/libusb/os/windows_winusb.c | 0 .../usb/usbhid/c/libusb/os/windows_winusb.h | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/strerror.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/sync.c | 0 .../go-api-for-hardware-wallet}/usb/usbhid/c/libusb/version.h | 0 .../usb/usbhid/c/libusb/version_nano.h | 0 .../go-api-for-hardware-wallet}/usb/usbhid/hid.go | 0 .../go-api-for-hardware-wallet}/usb/usbhid/libusb.go | 0 .../go-api-for-hardware-wallet}/usb/usbhid/wchar.go | 0 .../go-api-for-hardware-wallet}/usb/webusb.go | 0 .../go-api-for-hardware-wallet}/wire/protobuf.go | 0 .../go-api-for-hardware-wallet}/wire/v1.go | 0 hardware-wallet/{ => skycoin-api}/Makefile | 0 hardware-wallet/{ => skycoin-api}/README.md | 0 hardware-wallet/{ => skycoin-api}/skycoin_crypto.c | 0 hardware-wallet/{ => skycoin-api}/skycoin_crypto.h | 0 hardware-wallet/{ => skycoin-api}/test_skycoin_crypto.c | 0 80 files changed, 0 insertions(+), 0 deletions(-) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/README.md (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/hardware-wallet/trezor.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/main.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/protob/messages.options (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/protob/messages.proto (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/protob/types.options (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/protob/types.proto (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/bus.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/hidapi.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/udp.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/.gitignore (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/.travis.yml (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/README.md (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/AUTHORS.txt (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/LICENSE-bsd.txt (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/LICENSE-gpl3.txt (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/LICENSE-orig.txt (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/LICENSE.txt (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/README.txt (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/hidapi/hidapi.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/linux/hid.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/mac/hid.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/hidapi/windows/hid.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/AUTHORS (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/COPYING (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/config.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/core.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/descriptor.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/hotplug.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/hotplug.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/io.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/libusb.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/libusbi.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/darwin_usb.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/darwin_usb.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/haiku_pollfs.cpp (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/haiku_usb.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/haiku_usb_backend.cpp (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/haiku_usb_raw.cpp (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/haiku_usb_raw.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/linux_netlink.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/linux_udev.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/linux_usbfs.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/linux_usbfs.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/netbsd_usb.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/openbsd_usb.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/poll_posix.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/poll_posix.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/poll_windows.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/poll_windows.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/sunos_usb.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/sunos_usb.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/threads_posix.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/threads_posix.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/threads_windows.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/threads_windows.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/wince_usb.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/wince_usb.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/windows_common.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/windows_nt_common.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/windows_nt_common.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/windows_usbdk.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/windows_usbdk.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/windows_winusb.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/os/windows_winusb.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/strerror.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/sync.c (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/version.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/c/libusb/version_nano.h (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/hid.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/libusb.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/usbhid/wchar.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/usb/webusb.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/wire/protobuf.go (100%) rename {go-api-for-hardware-wallet => hardware-wallet/go-api-for-hardware-wallet}/wire/v1.go (100%) rename hardware-wallet/{ => skycoin-api}/Makefile (100%) rename hardware-wallet/{ => skycoin-api}/README.md (100%) rename hardware-wallet/{ => skycoin-api}/skycoin_crypto.c (100%) rename hardware-wallet/{ => skycoin-api}/skycoin_crypto.h (100%) rename hardware-wallet/{ => skycoin-api}/test_skycoin_crypto.c (100%) diff --git a/go-api-for-hardware-wallet/README.md b/hardware-wallet/go-api-for-hardware-wallet/README.md similarity index 100% rename from go-api-for-hardware-wallet/README.md rename to hardware-wallet/go-api-for-hardware-wallet/README.md diff --git a/go-api-for-hardware-wallet/hardware-wallet/trezor.go b/hardware-wallet/go-api-for-hardware-wallet/hardware-wallet/trezor.go similarity index 100% rename from go-api-for-hardware-wallet/hardware-wallet/trezor.go rename to hardware-wallet/go-api-for-hardware-wallet/hardware-wallet/trezor.go diff --git a/go-api-for-hardware-wallet/main.go b/hardware-wallet/go-api-for-hardware-wallet/main.go similarity index 100% rename from go-api-for-hardware-wallet/main.go rename to hardware-wallet/go-api-for-hardware-wallet/main.go diff --git a/go-api-for-hardware-wallet/protob/messages.options b/hardware-wallet/go-api-for-hardware-wallet/protob/messages.options similarity index 100% rename from go-api-for-hardware-wallet/protob/messages.options rename to hardware-wallet/go-api-for-hardware-wallet/protob/messages.options diff --git a/go-api-for-hardware-wallet/protob/messages.proto b/hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto similarity index 100% rename from go-api-for-hardware-wallet/protob/messages.proto rename to hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto diff --git a/go-api-for-hardware-wallet/protob/types.options b/hardware-wallet/go-api-for-hardware-wallet/protob/types.options similarity index 100% rename from go-api-for-hardware-wallet/protob/types.options rename to hardware-wallet/go-api-for-hardware-wallet/protob/types.options diff --git a/go-api-for-hardware-wallet/protob/types.proto b/hardware-wallet/go-api-for-hardware-wallet/protob/types.proto similarity index 100% rename from go-api-for-hardware-wallet/protob/types.proto rename to hardware-wallet/go-api-for-hardware-wallet/protob/types.proto diff --git a/go-api-for-hardware-wallet/usb/bus.go b/hardware-wallet/go-api-for-hardware-wallet/usb/bus.go similarity index 100% rename from go-api-for-hardware-wallet/usb/bus.go rename to hardware-wallet/go-api-for-hardware-wallet/usb/bus.go diff --git a/go-api-for-hardware-wallet/usb/hidapi.go b/hardware-wallet/go-api-for-hardware-wallet/usb/hidapi.go similarity index 100% rename from go-api-for-hardware-wallet/usb/hidapi.go rename to hardware-wallet/go-api-for-hardware-wallet/usb/hidapi.go diff --git a/go-api-for-hardware-wallet/usb/udp.go b/hardware-wallet/go-api-for-hardware-wallet/usb/udp.go similarity index 100% rename from go-api-for-hardware-wallet/usb/udp.go rename to hardware-wallet/go-api-for-hardware-wallet/usb/udp.go diff --git a/go-api-for-hardware-wallet/usb/usbhid/.gitignore b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/.gitignore similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/.gitignore rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/.gitignore diff --git a/go-api-for-hardware-wallet/usb/usbhid/.travis.yml b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/.travis.yml similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/.travis.yml rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/.travis.yml diff --git a/go-api-for-hardware-wallet/usb/usbhid/README.md b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/README.md similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/README.md rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/README.md diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/AUTHORS.txt b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/AUTHORS.txt similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/AUTHORS.txt rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/AUTHORS.txt diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-bsd.txt b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-bsd.txt similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-bsd.txt rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-bsd.txt diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-gpl3.txt b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-gpl3.txt similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-gpl3.txt rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-gpl3.txt diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-orig.txt b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-orig.txt similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-orig.txt rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE-orig.txt diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE.txt b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE.txt similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE.txt rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/LICENSE.txt diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/README.txt b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/README.txt similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/README.txt rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/README.txt diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/hidapi/hidapi.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/hidapi/hidapi.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/hidapi/hidapi.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/hidapi/hidapi.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/linux/hid.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/linux/hid.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/linux/hid.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/linux/hid.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/mac/hid.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/mac/hid.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/mac/hid.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/mac/hid.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/windows/hid.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/windows/hid.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/hidapi/windows/hid.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/hidapi/windows/hid.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/AUTHORS b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/AUTHORS similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/AUTHORS rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/AUTHORS diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/COPYING b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/COPYING similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/COPYING rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/COPYING diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/config.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/config.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/config.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/config.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/core.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/core.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/core.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/core.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/descriptor.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/descriptor.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/descriptor.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/descriptor.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/hotplug.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/io.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/io.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/io.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/io.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusb.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusb.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusb.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusb.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusbi.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusbi.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusbi.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/libusbi.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/darwin_usb.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_pollfs.cpp b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_pollfs.cpp similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_pollfs.cpp rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_pollfs.cpp diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_backend.cpp b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_backend.cpp similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_backend.cpp rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_backend.cpp diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.cpp b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.cpp similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.cpp rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.cpp diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/haiku_usb_raw.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_netlink.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_netlink.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_netlink.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_netlink.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_udev.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_udev.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_udev.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_udev.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/linux_usbfs.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/netbsd_usb.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/netbsd_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/netbsd_usb.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/netbsd_usb.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/openbsd_usb.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/openbsd_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/openbsd_usb.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/openbsd_usb.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_posix.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/poll_windows.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/sunos_usb.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_posix.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/threads_windows.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/wince_usb.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_common.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_common.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_common.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_common.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_nt_common.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_usbdk.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/os/windows_winusb.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/strerror.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/strerror.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/strerror.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/strerror.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/sync.c b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/sync.c similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/sync.c rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/sync.c diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/version.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version_nano.h b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version_nano.h similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/c/libusb/version_nano.h rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/c/libusb/version_nano.h diff --git a/go-api-for-hardware-wallet/usb/usbhid/hid.go b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/hid.go similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/hid.go rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/hid.go diff --git a/go-api-for-hardware-wallet/usb/usbhid/libusb.go b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/libusb.go similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/libusb.go rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/libusb.go diff --git a/go-api-for-hardware-wallet/usb/usbhid/wchar.go b/hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/wchar.go similarity index 100% rename from go-api-for-hardware-wallet/usb/usbhid/wchar.go rename to hardware-wallet/go-api-for-hardware-wallet/usb/usbhid/wchar.go diff --git a/go-api-for-hardware-wallet/usb/webusb.go b/hardware-wallet/go-api-for-hardware-wallet/usb/webusb.go similarity index 100% rename from go-api-for-hardware-wallet/usb/webusb.go rename to hardware-wallet/go-api-for-hardware-wallet/usb/webusb.go diff --git a/go-api-for-hardware-wallet/wire/protobuf.go b/hardware-wallet/go-api-for-hardware-wallet/wire/protobuf.go similarity index 100% rename from go-api-for-hardware-wallet/wire/protobuf.go rename to hardware-wallet/go-api-for-hardware-wallet/wire/protobuf.go diff --git a/go-api-for-hardware-wallet/wire/v1.go b/hardware-wallet/go-api-for-hardware-wallet/wire/v1.go similarity index 100% rename from go-api-for-hardware-wallet/wire/v1.go rename to hardware-wallet/go-api-for-hardware-wallet/wire/v1.go diff --git a/hardware-wallet/Makefile b/hardware-wallet/skycoin-api/Makefile similarity index 100% rename from hardware-wallet/Makefile rename to hardware-wallet/skycoin-api/Makefile diff --git a/hardware-wallet/README.md b/hardware-wallet/skycoin-api/README.md similarity index 100% rename from hardware-wallet/README.md rename to hardware-wallet/skycoin-api/README.md diff --git a/hardware-wallet/skycoin_crypto.c b/hardware-wallet/skycoin-api/skycoin_crypto.c similarity index 100% rename from hardware-wallet/skycoin_crypto.c rename to hardware-wallet/skycoin-api/skycoin_crypto.c diff --git a/hardware-wallet/skycoin_crypto.h b/hardware-wallet/skycoin-api/skycoin_crypto.h similarity index 100% rename from hardware-wallet/skycoin_crypto.h rename to hardware-wallet/skycoin-api/skycoin_crypto.h diff --git a/hardware-wallet/test_skycoin_crypto.c b/hardware-wallet/skycoin-api/test_skycoin_crypto.c similarity index 100% rename from hardware-wallet/test_skycoin_crypto.c rename to hardware-wallet/skycoin-api/test_skycoin_crypto.c From 9e0f3a138822677c0c80b88a210eb81e31ed7b90 Mon Sep 17 00:00:00 2001 From: mpsido Date: Tue, 17 Apr 2018 16:24:11 +0700 Subject: [PATCH 55/73] Copying trezor-mcu firmware --- hardware-wallet/firmware/.gitignore | 14 + hardware-wallet/firmware/.gitmodules | 18 + hardware-wallet/firmware/.travis.yml | 60 + hardware-wallet/firmware/COPYING | 165 + hardware-wallet/firmware/Dockerfile | 16 + hardware-wallet/firmware/Dockerfile.emulator | 18 + hardware-wallet/firmware/Makefile | 33 + hardware-wallet/firmware/Makefile.include | 196 + hardware-wallet/firmware/README.md | 66 + .../firmware/bootloader/.gitignore | 9 + hardware-wallet/firmware/bootloader/ChangeLog | 27 + hardware-wallet/firmware/bootloader/Makefile | 21 + .../firmware/bootloader/bootloader.c | 165 + .../firmware/bootloader/bootloader.h | 40 + .../firmware/bootloader/combine/prepare.py | 12 + .../firmware/bootloader/combine/write.sh | 2 + .../firmware/bootloader/firmware_align.py | 11 + .../firmware/bootloader/firmware_sign.py | 198 + .../bootloader/firmware_sign_split.py | 34 + .../firmware/bootloader/signatures.c | 75 + .../firmware/bootloader/signatures.h | 28 + hardware-wallet/firmware/bootloader/usb.c | 726 ++ hardware-wallet/firmware/bootloader/usb.h | 25 + hardware-wallet/firmware/build-bootloader.sh | 30 + hardware-wallet/firmware/build-emulator.sh | 19 + hardware-wallet/firmware/build-firmware.sh | 33 + hardware-wallet/firmware/buttons.c | 74 + hardware-wallet/firmware/buttons.h | 50 + hardware-wallet/firmware/demo/Makefile | 18 + hardware-wallet/firmware/demo/demo.c | 291 + hardware-wallet/firmware/emulator/Makefile | 17 + hardware-wallet/firmware/emulator/buttons.c | 40 + hardware-wallet/firmware/emulator/emulator.h | 40 + hardware-wallet/firmware/emulator/flash.c | 114 + hardware-wallet/firmware/emulator/oled.c | 121 + hardware-wallet/firmware/emulator/rng.c | 32 + hardware-wallet/firmware/emulator/setup.c | 95 + hardware-wallet/firmware/emulator/strl.c | 41 + hardware-wallet/firmware/emulator/strl.h | 28 + hardware-wallet/firmware/emulator/timer.c | 32 + hardware-wallet/firmware/emulator/udp.c | 85 + hardware-wallet/firmware/fastflash/Makefile | 22 + .../firmware/fastflash/bootloader.c | 1 + .../firmware/fastflash/signatures.c | 28 + hardware-wallet/firmware/fastflash/usb.c | 1 + hardware-wallet/firmware/firmware/.gitignore | 4 + hardware-wallet/firmware/firmware/ChangeLog | 126 + hardware-wallet/firmware/firmware/Makefile | 127 + .../firmware/firmware/coins-gen.py | 75 + hardware-wallet/firmware/firmware/coins.c | 87 + hardware-wallet/firmware/firmware/coins.h | 60 + hardware-wallet/firmware/firmware/coins.json | 1 + hardware-wallet/firmware/firmware/crypto.c | 424 + hardware-wallet/firmware/firmware/crypto.h | 62 + hardware-wallet/firmware/firmware/debug.c | 68 + hardware-wallet/firmware/firmware/debug.h | 38 + hardware-wallet/firmware/firmware/ethereum.c | 671 ++ hardware-wallet/firmware/firmware/ethereum.h | 35 + .../firmware/firmware/ethereum_tokens.c | 143 + .../firmware/firmware/ethereum_tokens.h | 40 + hardware-wallet/firmware/firmware/fastflash.c | 41 + hardware-wallet/firmware/firmware/fastflash.h | 25 + hardware-wallet/firmware/firmware/fsm.c | 1795 +++++ hardware-wallet/firmware/firmware/fsm.h | 96 + hardware-wallet/firmware/firmware/gettext.h | 25 + hardware-wallet/firmware/firmware/layout2.c | 859 ++ hardware-wallet/firmware/firmware/layout2.h | 72 + hardware-wallet/firmware/firmware/messages.c | 373 + hardware-wallet/firmware/firmware/messages.h | 53 + hardware-wallet/firmware/firmware/nem2.c | 812 ++ hardware-wallet/firmware/firmware/nem2.h | 111 + .../firmware/firmware/nem_mosaics.json | 57 + .../firmware/firmware/nem_mosaics.py | 105 + hardware-wallet/firmware/firmware/pinmatrix.c | 82 + hardware-wallet/firmware/firmware/pinmatrix.h | 27 + hardware-wallet/firmware/firmware/protect.c | 276 + hardware-wallet/firmware/firmware/protect.h | 33 + .../firmware/firmware/protob/.gitignore | 7 + .../firmware/firmware/protob/Makefile | 18 + .../firmware/firmware/protob/messages.options | 210 + .../firmware/firmware/protob/messages.proto | 1 + .../firmware/firmware/protob/messages_map.py | 64 + .../firmware/firmware/protob/types.options | 74 + .../firmware/firmware/protob/types.proto | 1 + .../firmware/firmware/recovery-table.h | 112 + hardware-wallet/firmware/firmware/recovery.c | 530 ++ hardware-wallet/firmware/firmware/recovery.h | 32 + hardware-wallet/firmware/firmware/reset.c | 171 + hardware-wallet/firmware/firmware/reset.h | 32 + hardware-wallet/firmware/firmware/signing.c | 1161 +++ hardware-wallet/firmware/firmware/signing.h | 34 + hardware-wallet/firmware/firmware/storage.c | 902 +++ hardware-wallet/firmware/firmware/storage.h | 147 + .../firmware/firmware/transaction.c | 664 ++ .../firmware/firmware/transaction.h | 78 + hardware-wallet/firmware/firmware/trezor.c | 129 + hardware-wallet/firmware/firmware/trezor.h | 43 + hardware-wallet/firmware/firmware/u2f.c | 763 ++ hardware-wallet/firmware/firmware/u2f.h | 62 + .../firmware/firmware/u2f/genkeys.sh | 46 + .../firmware/firmware/u2f/trezordevkey.pem | 5 + hardware-wallet/firmware/firmware/u2f/u2f.h | 143 + .../firmware/firmware/u2f/u2f_hid.h | 142 + .../firmware/firmware/u2f/u2f_keys.h | 40 + .../firmware/firmware/u2f_knownapps.h | 136 + hardware-wallet/firmware/firmware/udp.c | 70 + hardware-wallet/firmware/firmware/usb.c | 454 ++ hardware-wallet/firmware/firmware/usb.h | 29 + hardware-wallet/firmware/gen/Makefile | 9 + hardware-wallet/firmware/gen/bitmaps.c | 69 + hardware-wallet/firmware/gen/bitmaps.h | 45 + .../firmware/gen/bitmaps/digit0.png | Bin 0 -> 121 bytes .../firmware/gen/bitmaps/digit1.png | Bin 0 -> 112 bytes .../firmware/gen/bitmaps/digit2.png | Bin 0 -> 129 bytes .../firmware/gen/bitmaps/digit3.png | Bin 0 -> 125 bytes .../firmware/gen/bitmaps/digit4.png | Bin 0 -> 137 bytes .../firmware/gen/bitmaps/digit5.png | Bin 0 -> 128 bytes .../firmware/gen/bitmaps/digit6.png | Bin 0 -> 133 bytes .../firmware/gen/bitmaps/digit7.png | Bin 0 -> 127 bytes .../firmware/gen/bitmaps/digit8.png | Bin 0 -> 125 bytes .../firmware/gen/bitmaps/digit9.png | Bin 0 -> 132 bytes .../firmware/gen/bitmaps/gears0.png | Bin 0 -> 301 bytes .../firmware/gen/bitmaps/gears1.png | Bin 0 -> 326 bytes .../firmware/gen/bitmaps/gears2.png | Bin 0 -> 293 bytes .../firmware/gen/bitmaps/gears3.png | Bin 0 -> 330 bytes .../firmware/gen/bitmaps/generate.py | 59 + .../firmware/gen/bitmaps/icon_error.png | Bin 0 -> 152 bytes .../firmware/gen/bitmaps/icon_info.png | Bin 0 -> 138 bytes .../firmware/gen/bitmaps/icon_ok.png | Bin 0 -> 167 bytes .../firmware/gen/bitmaps/icon_question.png | Bin 0 -> 153 bytes .../firmware/gen/bitmaps/icon_warning.png | Bin 0 -> 138 bytes .../firmware/gen/bitmaps/logo48.png | Bin 0 -> 283 bytes .../firmware/gen/bitmaps/logo48_empty.png | Bin 0 -> 310 bytes .../firmware/gen/bitmaps/logo64.png | Bin 0 -> 317 bytes .../firmware/gen/bitmaps/logo64_empty.png | Bin 0 -> 444 bytes .../firmware/gen/bitmaps/u2f_bitbucket.png | Bin 0 -> 292 bytes .../firmware/gen/bitmaps/u2f_bitfinex.png | Bin 0 -> 285 bytes .../firmware/gen/bitmaps/u2f_dropbox.png | Bin 0 -> 263 bytes .../firmware/gen/bitmaps/u2f_fastmail.png | Bin 0 -> 226 bytes .../firmware/gen/bitmaps/u2f_gandi.png | Bin 0 -> 250 bytes .../firmware/gen/bitmaps/u2f_github.png | Bin 0 -> 236 bytes .../firmware/gen/bitmaps/u2f_gitlab.png | Bin 0 -> 229 bytes .../firmware/gen/bitmaps/u2f_google.png | Bin 0 -> 240 bytes .../firmware/gen/bitmaps/u2f_slushpool.png | Bin 0 -> 214 bytes .../firmware/gen/bitmaps/u2f_yubico.png | Bin 0 -> 253 bytes hardware-wallet/firmware/gen/font.inc | 128 + hardware-wallet/firmware/gen/fontfixed.inc | 128 + hardware-wallet/firmware/gen/fonts.c | 18 + hardware-wallet/firmware/gen/fonts.h | 16 + hardware-wallet/firmware/gen/fonts/font.png | Bin 0 -> 1795 bytes .../firmware/gen/fonts/fontfixed.png | Bin 0 -> 1794 bytes .../firmware/gen/fonts/generate.py | 40 + .../firmware/gen/handlers/handlers.py | 100 + hardware-wallet/firmware/gen/strwidth.c | 35 + .../gen/wordlist/build-recovery-table.pl | 110 + .../gen/wordlist/recovery_english.txt | 630 ++ hardware-wallet/firmware/gitian/gitian.yml | 19 + hardware-wallet/firmware/layout.c | 116 + hardware-wallet/firmware/layout.h | 33 + hardware-wallet/firmware/make-firmware.sh | 19 + hardware-wallet/firmware/memory.c | 57 + hardware-wallet/firmware/memory.h | 108 + hardware-wallet/firmware/memory.ld | 22 + hardware-wallet/firmware/memory_app_0.0.0.ld | 9 + hardware-wallet/firmware/memory_app_1.0.0.ld | 22 + .../firmware/memory_app_fastflash.ld | 22 + hardware-wallet/firmware/oled.c | 422 + hardware-wallet/firmware/oled.h | 59 + hardware-wallet/firmware/rng.c | 38 + hardware-wallet/firmware/rng.h | 25 + hardware-wallet/firmware/script/bootstrap | 10 + hardware-wallet/firmware/script/cibuild | 25 + hardware-wallet/firmware/script/setup | 13 + hardware-wallet/firmware/script/test | 15 + hardware-wallet/firmware/serialno.c | 36 + hardware-wallet/firmware/serialno.h | 26 + hardware-wallet/firmware/setup.c | 199 + hardware-wallet/firmware/setup.h | 32 + hardware-wallet/firmware/startup.s | 63 + hardware-wallet/firmware/timer.c | 62 + hardware-wallet/firmware/timer.h | 38 + hardware-wallet/firmware/usb21_standard.c | 95 + hardware-wallet/firmware/usb21_standard.h | 63 + hardware-wallet/firmware/util.c | 68 + hardware-wallet/firmware/util.h | 75 + .../firmware/vendor/libopencm3/.gitignore | 44 + .../firmware/vendor/libopencm3/COPYING.GPL3 | 676 ++ .../firmware/vendor/libopencm3/COPYING.LGPL3 | 165 + .../firmware/vendor/libopencm3/HACKING | 85 + .../vendor/libopencm3/HACKING_COMMON_DOC | 76 + .../firmware/vendor/libopencm3/Makefile | 111 + .../firmware/vendor/libopencm3/README.md | 187 + .../firmware/vendor/libopencm3/doc/Doxyfile | 21 + .../vendor/libopencm3/doc/Doxyfile_common | 1809 +++++ .../vendor/libopencm3/doc/DoxygenLayout.xml | 199 + .../firmware/vendor/libopencm3/doc/HACKING | 114 + .../firmware/vendor/libopencm3/doc/Makefile | 39 + .../firmware/vendor/libopencm3/doc/README | 34 + .../vendor/libopencm3/doc/cm3/Doxyfile | 24 + .../libopencm3/doc/cm3/DoxygenLayout_cm3.xml | 209 + .../vendor/libopencm3/doc/efm32g/Doxyfile | 30 + .../libopencm3/doc/efm32g/Doxyfile_latex | 32 + .../doc/efm32g/DoxygenLayout_efm32g.xml | 210 + .../libopencm3/doc/efm32g/header_efm32g.tex | 61 + .../vendor/libopencm3/doc/efm32gg/Doxyfile | 30 + .../libopencm3/doc/efm32gg/Doxyfile_latex | 32 + .../doc/efm32gg/DoxygenLayout_efm32gg.xml | 210 + .../libopencm3/doc/efm32gg/header_efm32gg.tex | 61 + .../vendor/libopencm3/doc/efm32lg/Doxyfile | 30 + .../libopencm3/doc/efm32lg/Doxyfile_latex | 32 + .../doc/efm32lg/DoxygenLayout_efm32lg.xml | 210 + .../libopencm3/doc/efm32lg/header_efm32lg.tex | 61 + .../vendor/libopencm3/doc/efm32tg/Doxyfile | 30 + .../libopencm3/doc/efm32tg/Doxyfile_latex | 32 + .../doc/efm32tg/DoxygenLayout_efm32tg.xml | 210 + .../libopencm3/doc/efm32tg/header_efm32tg.tex | 61 + .../firmware/vendor/libopencm3/doc/index.html | 8 + .../vendor/libopencm3/doc/lm3s/Doxyfile | 28 + .../vendor/libopencm3/doc/lm3s/Doxyfile_latex | 32 + .../doc/lm3s/DoxygenLayout_lm3s.xml | 210 + .../libopencm3/doc/lm3s/header_lm3s.tex | 61 + .../vendor/libopencm3/doc/lm4f/Doxyfile | 28 + .../vendor/libopencm3/doc/lm4f/Doxyfile_latex | 33 + .../doc/lm4f/DoxygenLayout_lm4f.xml | 210 + .../libopencm3/doc/lm4f/header_lm4f.tex | 61 + .../vendor/libopencm3/doc/lpc13xx/Doxyfile | 28 + .../libopencm3/doc/lpc13xx/Doxyfile_latex | 32 + .../doc/lpc13xx/DoxygenLayout_lpc13xx.xml | 209 + .../libopencm3/doc/lpc13xx/header_lpc13xx.tex | 61 + .../vendor/libopencm3/doc/lpc17xx/Doxyfile | 28 + .../libopencm3/doc/lpc17xx/Doxyfile_latex | 32 + .../doc/lpc17xx/DoxygenLayout_lpc17xx.xml | 209 + .../libopencm3/doc/lpc17xx/header_lpc17xx.tex | 61 + .../vendor/libopencm3/doc/lpc43xx/Doxyfile | 28 + .../libopencm3/doc/lpc43xx/Doxyfile_latex | 32 + .../doc/lpc43xx/DoxygenLayout_lpc43xx.xml | 209 + .../libopencm3/doc/lpc43xx/header_lpc43xx.tex | 61 + .../vendor/libopencm3/doc/sam3a/Doxyfile | 37 + .../libopencm3/doc/sam3a/Doxyfile_latex | 39 + .../doc/sam3a/DoxygenLayout_sam3a.xml | 210 + .../libopencm3/doc/sam3a/header_sam3a.tex | 61 + .../vendor/libopencm3/doc/sam3n/Doxyfile | 37 + .../libopencm3/doc/sam3n/Doxyfile_latex | 39 + .../doc/sam3n/DoxygenLayout_sam3n.xml | 210 + .../libopencm3/doc/sam3n/header_sam3a.tex | 61 + .../vendor/libopencm3/doc/sam3s/Doxyfile | 37 + .../libopencm3/doc/sam3s/Doxyfile_latex | 39 + .../doc/sam3s/DoxygenLayout_sam3s.xml | 210 + .../libopencm3/doc/sam3s/header_sam3a.tex | 61 + .../vendor/libopencm3/doc/sam3u/Doxyfile | 37 + .../libopencm3/doc/sam3u/Doxyfile_latex | 39 + .../doc/sam3u/DoxygenLayout_sam3u.xml | 210 + .../libopencm3/doc/sam3u/header_sam3a.tex | 61 + .../vendor/libopencm3/doc/sam3x/Doxyfile | 37 + .../libopencm3/doc/sam3x/Doxyfile_latex | 39 + .../doc/sam3x/DoxygenLayout_sam3x.xml | 210 + .../libopencm3/doc/sam3x/header_sam3a.tex | 61 + .../vendor/libopencm3/doc/stm32f0/Doxyfile | 38 + .../libopencm3/doc/stm32f0/Doxyfile_latex | 40 + .../doc/stm32f0/DoxygenLayout_stm32f0.xml | 210 + .../libopencm3/doc/stm32f0/header_stm32f0.tex | 61 + .../vendor/libopencm3/doc/stm32f0/index.html | 8 + .../vendor/libopencm3/doc/stm32f1/Doxyfile | 46 + .../libopencm3/doc/stm32f1/Doxyfile_latex | 40 + .../doc/stm32f1/DoxygenLayout_stm32f1.xml | 210 + .../libopencm3/doc/stm32f1/header_stm32f1.tex | 61 + .../vendor/libopencm3/doc/stm32f1/index.html | 8 + .../vendor/libopencm3/doc/stm32f2/Doxyfile | 39 + .../libopencm3/doc/stm32f2/Doxyfile_latex | 37 + .../doc/stm32f2/DoxygenLayout_stm32f2.xml | 210 + .../libopencm3/doc/stm32f2/header_stm32f2.tex | 61 + .../vendor/libopencm3/doc/stm32f2/index.html | 8 + .../vendor/libopencm3/doc/stm32f3/Doxyfile | 36 + .../libopencm3/doc/stm32f3/Doxyfile_latex | 40 + .../doc/stm32f3/DoxygenLayout_stm32f3.xml | 210 + .../libopencm3/doc/stm32f3/header_stm32f3.tex | 61 + .../vendor/libopencm3/doc/stm32f3/index.html | 8 + .../vendor/libopencm3/doc/stm32f4/Doxyfile | 39 + .../libopencm3/doc/stm32f4/Doxyfile_latex | 37 + .../doc/stm32f4/DoxygenLayout_stm32f4.xml | 210 + .../libopencm3/doc/stm32f4/header_stm32f4.tex | 61 + .../vendor/libopencm3/doc/stm32f4/index.html | 8 + .../vendor/libopencm3/doc/stm32f7/Doxyfile | 39 + .../libopencm3/doc/stm32f7/Doxyfile_latex | 37 + .../doc/stm32f7/DoxygenLayout_stm32f7.xml | 209 + .../libopencm3/doc/stm32f7/header_stm32f7.tex | 61 + .../vendor/libopencm3/doc/stm32f7/index.html | 8 + .../vendor/libopencm3/doc/stm32l0/Doxyfile | 43 + .../libopencm3/doc/stm32l0/Doxyfile_latex | 38 + .../doc/stm32l0/DoxygenLayout_stm32l0.xml | 209 + .../libopencm3/doc/stm32l0/header_stm32l0.tex | 61 + .../vendor/libopencm3/doc/stm32l0/index.html | 8 + .../vendor/libopencm3/doc/stm32l1/Doxyfile | 48 + .../libopencm3/doc/stm32l1/Doxyfile_latex | 40 + .../doc/stm32l1/DoxygenLayout_stm32l1.xml | 210 + .../libopencm3/doc/stm32l1/header_stm32l1.tex | 61 + .../vendor/libopencm3/doc/stm32l1/index.html | 8 + .../vendor/libopencm3/doc/stm32l4/Doxyfile | 46 + .../libopencm3/doc/stm32l4/Doxyfile_latex | 38 + .../doc/stm32l4/DoxygenLayout_stm32l4.xml | 210 + .../libopencm3/doc/stm32l4/header_stm32l4.tex | 61 + .../vendor/libopencm3/doc/stm32l4/index.html | 8 + .../vendor/libopencm3/doc/usb/Doxyfile | 31 + .../vendor/libopencm3/doc/usb/Doxyfile_latex | 40 + .../libopencm3/doc/usb/DoxygenLayout_usb.xml | 209 + .../vendor/libopencm3/doc/usb/header_usb.tex | 61 + .../vendor/libopencm3/doc/vf6xx/Doxyfile | 31 + .../libopencm3/doc/vf6xx/Doxyfile_latex | 35 + .../doc/vf6xx/DoxygenLayout_vf6xx.xml | 209 + .../libopencm3/doc/vf6xx/header_vf6xx.tex | 61 + .../vendor/libopencm3/doc/vf6xx/index.html | 8 + .../include/libopencm3/cm3/assert.h | 137 + .../include/libopencm3/cm3/common.h | 96 + .../include/libopencm3/cm3/cortex.h | 281 + .../include/libopencm3/cm3/doc-cm3.h | 22 + .../libopencm3/include/libopencm3/cm3/dwt.h | 152 + .../libopencm3/include/libopencm3/cm3/fpb.h | 87 + .../libopencm3/include/libopencm3/cm3/itm.h | 88 + .../include/libopencm3/cm3/memorymap.h | 85 + .../libopencm3/include/libopencm3/cm3/mpu.h | 143 + .../libopencm3/include/libopencm3/cm3/scb.h | 450 ++ .../libopencm3/include/libopencm3/cm3/scs.h | 350 + .../libopencm3/include/libopencm3/cm3/sync.h | 59 + .../include/libopencm3/cm3/systick.h | 134 + .../libopencm3/include/libopencm3/cm3/tpiu.h | 97 + .../include/libopencm3/cm3/vector.h | 64 + .../libopencm3/include/libopencm3/docmain.dox | 21 + .../include/libopencm3/efm32/acmp.h | 24 + .../libopencm3/include/libopencm3/efm32/adc.h | 24 + .../include/libopencm3/efm32/burtc.h | 24 + .../libopencm3/include/libopencm3/efm32/cmu.h | 24 + .../libopencm3/include/libopencm3/efm32/dac.h | 24 + .../libopencm3/include/libopencm3/efm32/dma.h | 24 + .../libopencm3/include/libopencm3/efm32/emu.h | 24 + .../include/libopencm3/efm32/g/doc-efm32g.h | 32 + .../include/libopencm3/efm32/g/irq.json | 38 + .../include/libopencm3/efm32/gg/doc-efm32gg.h | 32 + .../include/libopencm3/efm32/gg/irq.json | 46 + .../include/libopencm3/efm32/gpio.h | 24 + .../libopencm3/include/libopencm3/efm32/i2c.h | 24 + .../include/libopencm3/efm32/letimer.h | 24 + .../include/libopencm3/efm32/lg/acmp.h | 185 + .../include/libopencm3/efm32/lg/adc.h | 457 ++ .../include/libopencm3/efm32/lg/burtc.h | 170 + .../include/libopencm3/efm32/lg/cmu.h | 705 ++ .../include/libopencm3/efm32/lg/dac.h | 512 ++ .../include/libopencm3/efm32/lg/dma.h | 912 +++ .../include/libopencm3/efm32/lg/doc-efm32lg.h | 33 + .../include/libopencm3/efm32/lg/emu.h | 189 + .../include/libopencm3/efm32/lg/gpio.h | 330 + .../include/libopencm3/efm32/lg/i2c.h | 269 + .../include/libopencm3/efm32/lg/irq.json | 46 + .../include/libopencm3/efm32/lg/letimer.h | 165 + .../include/libopencm3/efm32/lg/memorymap.h | 117 + .../include/libopencm3/efm32/lg/msc.h | 154 + .../include/libopencm3/efm32/lg/opamp.h | 21 + .../include/libopencm3/efm32/lg/prs.h | 363 + .../include/libopencm3/efm32/lg/rmu.h | 56 + .../include/libopencm3/efm32/lg/rtc.h | 71 + .../include/libopencm3/efm32/lg/timer.h | 610 ++ .../include/libopencm3/efm32/lg/uart.h | 100 + .../include/libopencm3/efm32/lg/usart.h | 512 ++ .../include/libopencm3/efm32/lg/usb.h | 369 + .../include/libopencm3/efm32/lg/wdog.h | 76 + .../include/libopencm3/efm32/memorymap.h | 36 + .../libopencm3/include/libopencm3/efm32/msc.h | 24 + .../include/libopencm3/efm32/opamp.h | 24 + .../libopencm3/include/libopencm3/efm32/prs.h | 24 + .../libopencm3/include/libopencm3/efm32/rmu.h | 24 + .../libopencm3/include/libopencm3/efm32/rtc.h | 24 + .../include/libopencm3/efm32/tg/doc-efm32tg.h | 32 + .../include/libopencm3/efm32/tg/irq.json | 31 + .../include/libopencm3/efm32/tg/memorymap.h | 76 + .../include/libopencm3/efm32/timer.h | 24 + .../include/libopencm3/efm32/uart.h | 24 + .../include/libopencm3/efm32/usart.h | 24 + .../libopencm3/include/libopencm3/efm32/usb.h | 24 + .../include/libopencm3/efm32/wdog.h | 24 + .../include/libopencm3/ethernet/mac.h | 46 + .../libopencm3/ethernet/mac_stm32fxx7.h | 752 ++ .../include/libopencm3/ethernet/phy.h | 93 + .../libopencm3/ethernet/phy_ksz8051mll.h | 60 + .../libopencm3/include/libopencm3/license.dox | 16 + .../include/libopencm3/lm3s/doc-lm3s.h | 32 + .../libopencm3/include/libopencm3/lm3s/gpio.h | 99 + .../include/libopencm3/lm3s/irq.json | 126 + .../include/libopencm3/lm3s/memorymap.h | 47 + .../libopencm3/include/libopencm3/lm3s/rcc.h | 107 + .../include/libopencm3/lm3s/systemcontrol.h | 81 + .../include/libopencm3/lm3s/usart.h | 123 + .../include/libopencm3/lm4f/doc-lm4f.h | 32 + .../libopencm3/include/libopencm3/lm4f/gpio.h | 380 + .../include/libopencm3/lm4f/memorymap.h | 71 + .../libopencm3/include/libopencm3/lm4f/rcc.h | 133 + .../libopencm3/include/libopencm3/lm4f/ssi.h | 118 + .../include/libopencm3/lm4f/systemcontrol.h | 743 ++ .../libopencm3/include/libopencm3/lm4f/uart.h | 550 ++ .../libopencm3/include/libopencm3/lm4f/usb.h | 422 + .../include/libopencm3/lpc13xx/doc-lpc13xx.h | 32 + .../include/libopencm3/lpc13xx/gpio.h | 124 + .../include/libopencm3/lpc13xx/irq.json | 63 + .../include/libopencm3/lpc13xx/memorymap.h | 58 + .../include/libopencm3/lpc17xx/clock.h | 160 + .../include/libopencm3/lpc17xx/doc-lpc17xx.h | 32 + .../include/libopencm3/lpc17xx/gpio.h | 160 + .../include/libopencm3/lpc17xx/irq.json | 42 + .../include/libopencm3/lpc17xx/memorymap.h | 93 + .../include/libopencm3/lpc17xx/pwr.h | 102 + .../include/libopencm3/lpc43xx/adc.h | 113 + .../include/libopencm3/lpc43xx/atimer.h | 70 + .../include/libopencm3/lpc43xx/ccu.h | 402 + .../include/libopencm3/lpc43xx/cgu.h | 964 +++ .../include/libopencm3/lpc43xx/creg.h | 354 + .../include/libopencm3/lpc43xx/doc-lpc43xx.h | 32 + .../include/libopencm3/lpc43xx/eventrouter.h | 70 + .../include/libopencm3/lpc43xx/gima.h | 137 + .../include/libopencm3/lpc43xx/gpdma.h | 552 ++ .../include/libopencm3/lpc43xx/gpio.h | 784 ++ .../include/libopencm3/lpc43xx/i2c.h | 164 + .../include/libopencm3/lpc43xx/i2s.h | 122 + .../include/libopencm3/lpc43xx/ipc.h | 30 + .../include/libopencm3/lpc43xx/m0/irq.json | 36 + .../include/libopencm3/lpc43xx/m4/irq.json | 54 + .../include/libopencm3/lpc43xx/memorymap.h | 138 + .../include/libopencm3/lpc43xx/rgu.h | 1206 +++ .../include/libopencm3/lpc43xx/ritimer.h | 59 + .../include/libopencm3/lpc43xx/scu.h | 780 ++ .../include/libopencm3/lpc43xx/sdio.h | 151 + .../include/libopencm3/lpc43xx/sgpio.h | 691 ++ .../include/libopencm3/lpc43xx/ssp.h | 209 + .../include/libopencm3/lpc43xx/timer.h | 270 + .../include/libopencm3/lpc43xx/uart.h | 438 + .../include/libopencm3/lpc43xx/usb.h | 1337 ++++ .../include/libopencm3/lpc43xx/wwdt.h | 65 + .../include/libopencm3/sam/3a/gpio.h | 28 + .../include/libopencm3/sam/3a/irq.json | 52 + .../include/libopencm3/sam/3a/memorymap.h | 77 + .../include/libopencm3/sam/3a/pio.h | 27 + .../include/libopencm3/sam/3a/pmc.h | 64 + .../include/libopencm3/sam/3n/gpio.h | 28 + .../include/libopencm3/sam/3n/irq.json | 39 + .../include/libopencm3/sam/3n/memorymap.h | 60 + .../include/libopencm3/sam/3n/periph.h | 52 + .../include/libopencm3/sam/3n/pio.h | 27 + .../include/libopencm3/sam/3n/pmc.h | 139 + .../include/libopencm3/sam/3s/gpio.h | 28 + .../include/libopencm3/sam/3s/irq.json | 42 + .../include/libopencm3/sam/3s/memorymap.h | 66 + .../include/libopencm3/sam/3s/periph.h | 59 + .../include/libopencm3/sam/3s/pio.h | 47 + .../include/libopencm3/sam/3s/pmc.h | 138 + .../include/libopencm3/sam/3s/smc.h | 204 + .../include/libopencm3/sam/3u/gpio.h | 28 + .../include/libopencm3/sam/3u/irq.json | 37 + .../include/libopencm3/sam/3u/memorymap.h | 63 + .../include/libopencm3/sam/3u/periph.h | 56 + .../include/libopencm3/sam/3u/pio.h | 27 + .../include/libopencm3/sam/3u/pmc.h | 38 + .../include/libopencm3/sam/3x/gpio.h | 28 + .../include/libopencm3/sam/3x/irq.json | 52 + .../include/libopencm3/sam/3x/memorymap.h | 78 + .../include/libopencm3/sam/3x/pio.h | 27 + .../include/libopencm3/sam/3x/pmc.h | 64 + .../sam/common/gpio_common_3a3u3x.h | 52 + .../libopencm3/sam/common/gpio_common_3n3s.h | 54 + .../libopencm3/sam/common/gpio_common_all.h | 41 + .../sam/common/periph_common_3a3x.h | 71 + .../libopencm3/sam/common/pio_common_3a3u3x.h | 50 + .../libopencm3/sam/common/pio_common_3n3s.h | 65 + .../libopencm3/sam/common/pio_common_all.h | 168 + .../libopencm3/sam/common/pmc_common_3a3s3x.h | 68 + .../libopencm3/sam/common/pmc_common_3a3u3x.h | 100 + .../libopencm3/sam/common/pmc_common_3n3u.h | 39 + .../libopencm3/sam/common/pmc_common_all.h | 501 ++ .../libopencm3/sam/common/smc_common_3a3u3x.h | 559 ++ .../include/libopencm3/sam/d/irq.json | 26 + .../include/libopencm3/sam/d/memorymap.h | 51 + .../include/libopencm3/sam/d/port.h | 68 + .../libopencm3/include/libopencm3/sam/eefc.h | 83 + .../libopencm3/include/libopencm3/sam/gpio.h | 34 + .../include/libopencm3/sam/memorymap.h | 41 + .../include/libopencm3/sam/periph.h | 32 + .../libopencm3/include/libopencm3/sam/pio.h | 34 + .../libopencm3/include/libopencm3/sam/pmc.h | 32 + .../libopencm3/include/libopencm3/sam/pwm.h | 109 + .../libopencm3/include/libopencm3/sam/smc.h | 32 + .../libopencm3/include/libopencm3/sam/tc.h | 52 + .../libopencm3/include/libopencm3/sam/uart.h | 85 + .../libopencm3/include/libopencm3/sam/usart.h | 217 + .../libopencm3/include/libopencm3/sam/wdt.h | 57 + .../libopencm3/include/libopencm3/stm32/adc.h | 40 + .../libopencm3/include/libopencm3/stm32/can.h | 679 ++ .../libopencm3/include/libopencm3/stm32/cec.h | 28 + .../libopencm3/stm32/common/adc_common_v1.h | 412 + .../libopencm3/stm32/common/adc_common_v2.h | 215 + .../stm32/common/adc_common_v2_multi.h | 184 + .../stm32/common/adc_common_v2_single.h | 74 + .../libopencm3/stm32/common/crc_common_all.h | 118 + .../libopencm3/stm32/common/crs_common_all.h | 133 + .../stm32/common/crypto_common_f24.h | 290 + .../libopencm3/stm32/common/dac_common_all.h | 422 + .../libopencm3/stm32/common/dma_common_f24.h | 626 ++ .../stm32/common/dma_common_l1f013.h | 425 + .../libopencm3/stm32/common/exti_common_all.h | 106 + .../stm32/common/flash_common_f01.h | 130 + .../stm32/common/flash_common_f234.h | 94 + .../stm32/common/flash_common_f24.h | 149 + .../stm32/common/flash_common_l01.h | 137 + .../libopencm3/stm32/common/gpio_common_all.h | 91 + .../stm32/common/gpio_common_f234.h | 272 + .../libopencm3/stm32/common/gpio_common_f24.h | 133 + .../libopencm3/stm32/common/hash_common_f24.h | 181 + .../libopencm3/stm32/common/i2c_common_v1.h | 419 + .../libopencm3/stm32/common/i2c_common_v2.h | 455 ++ .../libopencm3/stm32/common/iwdg_common_all.h | 121 + .../libopencm3/stm32/common/pwr_common_v1.h | 132 + .../libopencm3/stm32/common/pwr_common_v2.h | 98 + .../libopencm3/stm32/common/rcc_common_all.h | 79 + .../libopencm3/stm32/common/rng_common_v1.h | 91 + .../stm32/common/rtc_common_l1f024.h | 347 + .../libopencm3/stm32/common/spi_common_all.h | 406 + .../libopencm3/stm32/common/spi_common_f03.h | 124 + .../libopencm3/stm32/common/spi_common_f24.h | 66 + .../stm32/common/spi_common_l1f124.h | 65 + .../libopencm3/stm32/common/st_usbfs_common.h | 302 + .../libopencm3/stm32/common/st_usbfs_v1.h | 67 + .../libopencm3/stm32/common/st_usbfs_v2.h | 109 + .../stm32/common/syscfg_common_l1f234.h | 61 + .../stm32/common/timer_common_all.h | 1269 +++ .../stm32/common/timer_common_f24.h | 114 + .../stm32/common/usart_common_all.h | 140 + .../stm32/common/usart_common_f124.h | 288 + .../stm32/common/usart_common_f24.h | 98 + .../libopencm3/stm32/common/usart_common_v2.h | 73 + .../include/libopencm3/stm32/comparator.h | 28 + .../libopencm3/include/libopencm3/stm32/crc.h | 38 + .../libopencm3/include/libopencm3/stm32/crs.h | 30 + .../include/libopencm3/stm32/crypto.h | 30 + .../libopencm3/include/libopencm3/stm32/dac.h | 38 + .../include/libopencm3/stm32/dbgmcu.h | 72 + .../include/libopencm3/stm32/desig.h | 65 + .../libopencm3/include/libopencm3/stm32/dma.h | 38 + .../include/libopencm3/stm32/dma2d.h | 28 + .../libopencm3/include/libopencm3/stm32/dsi.h | 25 + .../include/libopencm3/stm32/exti.h | 42 + .../include/libopencm3/stm32/f0/adc.h | 196 + .../include/libopencm3/stm32/f0/cec.h | 125 + .../include/libopencm3/stm32/f0/comparator.h | 124 + .../include/libopencm3/stm32/f0/crc.h | 89 + .../include/libopencm3/stm32/f0/dac.h | 117 + .../include/libopencm3/stm32/f0/dma.h | 37 + .../include/libopencm3/stm32/f0/doc-stm32f0.h | 32 + .../include/libopencm3/stm32/f0/exti.h | 40 + .../include/libopencm3/stm32/f0/flash.h | 118 + .../include/libopencm3/stm32/f0/gpio.h | 75 + .../include/libopencm3/stm32/f0/i2c.h | 38 + .../include/libopencm3/stm32/f0/irq.json | 39 + .../include/libopencm3/stm32/f0/iwdg.h | 70 + .../include/libopencm3/stm32/f0/memorymap.h | 116 + .../include/libopencm3/stm32/f0/pwr.h | 67 + .../include/libopencm3/stm32/f0/rcc.h | 539 ++ .../include/libopencm3/stm32/f0/rtc.h | 36 + .../include/libopencm3/stm32/f0/spi.h | 36 + .../include/libopencm3/stm32/f0/st_usbfs.h | 27 + .../include/libopencm3/stm32/f0/syscfg.h | 121 + .../include/libopencm3/stm32/f0/timer.h | 37 + .../include/libopencm3/stm32/f0/tsc.h | 159 + .../include/libopencm3/stm32/f0/usart.h | 333 + .../include/libopencm3/stm32/f1/adc.h | 425 + .../include/libopencm3/stm32/f1/bkp.h | 205 + .../include/libopencm3/stm32/f1/crc.h | 38 + .../include/libopencm3/stm32/f1/dac.h | 37 + .../include/libopencm3/stm32/f1/dma.h | 37 + .../include/libopencm3/stm32/f1/doc-stm32f1.h | 32 + .../include/libopencm3/stm32/f1/exti.h | 41 + .../include/libopencm3/stm32/f1/flash.h | 120 + .../include/libopencm3/stm32/f1/gpio.h | 979 +++ .../include/libopencm3/stm32/f1/i2c.h | 37 + .../include/libopencm3/stm32/f1/irq.json | 75 + .../include/libopencm3/stm32/f1/iwdg.h | 39 + .../include/libopencm3/stm32/f1/memorymap.h | 128 + .../include/libopencm3/stm32/f1/pwr.h | 37 + .../include/libopencm3/stm32/f1/rcc.h | 726 ++ .../include/libopencm3/stm32/f1/rtc.h | 176 + .../include/libopencm3/stm32/f1/spi.h | 37 + .../include/libopencm3/stm32/f1/st_usbfs.h | 27 + .../include/libopencm3/stm32/f1/timer.h | 56 + .../include/libopencm3/stm32/f1/usart.h | 37 + .../include/libopencm3/stm32/f2/crc.h | 38 + .../include/libopencm3/stm32/f2/crypto.h | 36 + .../include/libopencm3/stm32/f2/dac.h | 37 + .../include/libopencm3/stm32/f2/dma.h | 37 + .../include/libopencm3/stm32/f2/doc-stm32f2.h | 33 + .../include/libopencm3/stm32/f2/exti.h | 41 + .../include/libopencm3/stm32/f2/flash.h | 37 + .../include/libopencm3/stm32/f2/gpio.h | 37 + .../include/libopencm3/stm32/f2/hash.h | 36 + .../include/libopencm3/stm32/f2/i2c.h | 43 + .../include/libopencm3/stm32/f2/irq.json | 88 + .../include/libopencm3/stm32/f2/iwdg.h | 39 + .../include/libopencm3/stm32/f2/memorymap.h | 141 + .../include/libopencm3/stm32/f2/pwr.h | 59 + .../include/libopencm3/stm32/f2/rcc.h | 766 ++ .../include/libopencm3/stm32/f2/rng.h | 23 + .../include/libopencm3/stm32/f2/rtc.h | 36 + .../include/libopencm3/stm32/f2/spi.h | 37 + .../include/libopencm3/stm32/f2/syscfg.h | 44 + .../include/libopencm3/stm32/f2/timer.h | 39 + .../include/libopencm3/stm32/f2/usart.h | 37 + .../include/libopencm3/stm32/f3/adc.h | 555 ++ .../include/libopencm3/stm32/f3/crc.h | 70 + .../include/libopencm3/stm32/f3/dac.h | 37 + .../include/libopencm3/stm32/f3/dma.h | 37 + .../include/libopencm3/stm32/f3/doc-stm32f3.h | 32 + .../include/libopencm3/stm32/f3/exti.h | 51 + .../include/libopencm3/stm32/f3/flash.h | 73 + .../include/libopencm3/stm32/f3/gpio.h | 38 + .../include/libopencm3/stm32/f3/i2c.h | 37 + .../include/libopencm3/stm32/f3/irq.json | 88 + .../include/libopencm3/stm32/f3/iwdg.h | 53 + .../include/libopencm3/stm32/f3/memorymap.h | 129 + .../include/libopencm3/stm32/f3/pwr.h | 69 + .../include/libopencm3/stm32/f3/rcc.h | 618 ++ .../include/libopencm3/stm32/f3/rtc.h | 42 + .../include/libopencm3/stm32/f3/spi.h | 36 + .../include/libopencm3/stm32/f3/st_usbfs.h | 27 + .../include/libopencm3/stm32/f3/syscfg.h | 41 + .../include/libopencm3/stm32/f3/timer.h | 39 + .../include/libopencm3/stm32/f3/usart.h | 520 ++ .../include/libopencm3/stm32/f4/adc.h | 590 ++ .../include/libopencm3/stm32/f4/crc.h | 38 + .../include/libopencm3/stm32/f4/crypto.h | 97 + .../include/libopencm3/stm32/f4/dac.h | 37 + .../include/libopencm3/stm32/f4/dma.h | 37 + .../include/libopencm3/stm32/f4/dma2d.h | 187 + .../include/libopencm3/stm32/f4/doc-stm32f4.h | 32 + .../include/libopencm3/stm32/f4/dsi.h | 817 ++ .../include/libopencm3/stm32/f4/exti.h | 41 + .../include/libopencm3/stm32/f4/flash.h | 37 + .../include/libopencm3/stm32/f4/fmc.h | 249 + .../include/libopencm3/stm32/f4/gpio.h | 37 + .../include/libopencm3/stm32/f4/hash.h | 36 + .../include/libopencm3/stm32/f4/i2c.h | 43 + .../include/libopencm3/stm32/f4/irq.json | 98 + .../include/libopencm3/stm32/f4/iwdg.h | 39 + .../include/libopencm3/stm32/f4/ltdc.h | 502 ++ .../include/libopencm3/stm32/f4/memorymap.h | 173 + .../include/libopencm3/stm32/f4/pwr.h | 86 + .../include/libopencm3/stm32/f4/quadspi.h | 159 + .../include/libopencm3/stm32/f4/rcc.h | 966 +++ .../include/libopencm3/stm32/f4/rng.h | 23 + .../include/libopencm3/stm32/f4/rtc.h | 45 + .../include/libopencm3/stm32/f4/spi.h | 37 + .../include/libopencm3/stm32/f4/syscfg.h | 41 + .../include/libopencm3/stm32/f4/timer.h | 39 + .../include/libopencm3/stm32/f4/usart.h | 37 + .../include/libopencm3/stm32/f7/doc-stm32f7.h | 32 + .../include/libopencm3/stm32/f7/flash.h | 37 + .../include/libopencm3/stm32/f7/gpio.h | 37 + .../include/libopencm3/stm32/f7/irq.json | 103 + .../include/libopencm3/stm32/f7/memorymap.h | 164 + .../include/libopencm3/stm32/f7/pwr.h | 295 + .../include/libopencm3/stm32/f7/rcc.h | 938 +++ .../include/libopencm3/stm32/f7/rng.h | 23 + .../include/libopencm3/stm32/flash.h | 44 + .../include/libopencm3/stm32/fsmc.h | 308 + .../include/libopencm3/stm32/gpio.h | 44 + .../include/libopencm3/stm32/hash.h | 30 + .../libopencm3/include/libopencm3/stm32/i2c.h | 44 + .../include/libopencm3/stm32/iwdg.h | 38 + .../include/libopencm3/stm32/l0/adc.h | 76 + .../include/libopencm3/stm32/l0/doc-stm32l0.h | 32 + .../include/libopencm3/stm32/l0/exti.h | 41 + .../include/libopencm3/stm32/l0/flash.h | 62 + .../include/libopencm3/stm32/l0/gpio.h | 75 + .../include/libopencm3/stm32/l0/i2c.h | 37 + .../include/libopencm3/stm32/l0/irq.json | 39 + .../include/libopencm3/stm32/l0/memorymap.h | 95 + .../include/libopencm3/stm32/l0/pwr.h | 37 + .../include/libopencm3/stm32/l0/rcc.h | 699 ++ .../include/libopencm3/stm32/l0/rng.h | 23 + .../include/libopencm3/stm32/l0/st_usbfs.h | 27 + .../include/libopencm3/stm32/l0/syscfg.h | 134 + .../include/libopencm3/stm32/l0/timer.h | 211 + .../include/libopencm3/stm32/l1/adc.h | 230 + .../include/libopencm3/stm32/l1/crc.h | 38 + .../include/libopencm3/stm32/l1/dac.h | 37 + .../include/libopencm3/stm32/l1/dma.h | 42 + .../include/libopencm3/stm32/l1/doc-stm32l1.h | 32 + .../include/libopencm3/stm32/l1/exti.h | 41 + .../include/libopencm3/stm32/l1/flash.h | 68 + .../include/libopencm3/stm32/l1/gpio.h | 263 + .../include/libopencm3/stm32/l1/i2c.h | 37 + .../include/libopencm3/stm32/l1/irq.json | 64 + .../include/libopencm3/stm32/l1/iwdg.h | 39 + .../include/libopencm3/stm32/l1/lcd.h | 231 + .../include/libopencm3/stm32/l1/memorymap.h | 121 + .../include/libopencm3/stm32/l1/pwr.h | 52 + .../include/libopencm3/stm32/l1/rcc.h | 636 ++ .../include/libopencm3/stm32/l1/ri.h | 386 + .../include/libopencm3/stm32/l1/rtc.h | 36 + .../include/libopencm3/stm32/l1/spi.h | 37 + .../include/libopencm3/stm32/l1/st_usbfs.h | 27 + .../include/libopencm3/stm32/l1/syscfg.h | 41 + .../include/libopencm3/stm32/l1/timer.h | 89 + .../include/libopencm3/stm32/l1/usart.h | 37 + .../include/libopencm3/stm32/l4/adc.h | 89 + .../include/libopencm3/stm32/l4/doc-stm32l4.h | 32 + .../include/libopencm3/stm32/l4/flash.h | 254 + .../include/libopencm3/stm32/l4/gpio.h | 92 + .../include/libopencm3/stm32/l4/i2c.h | 43 + .../include/libopencm3/stm32/l4/irq.json | 89 + .../include/libopencm3/stm32/l4/memorymap.h | 126 + .../include/libopencm3/stm32/l4/pwr.h | 177 + .../include/libopencm3/stm32/l4/rcc.h | 955 +++ .../include/libopencm3/stm32/l4/rng.h | 23 + .../include/libopencm3/stm32/l4/timer.h | 44 + .../include/libopencm3/stm32/ltdc.h | 27 + .../include/libopencm3/stm32/memorymap.h | 45 + .../include/libopencm3/stm32/otg_common.h | 497 ++ .../include/libopencm3/stm32/otg_fs.h | 98 + .../include/libopencm3/stm32/otg_hs.h | 163 + .../libopencm3/include/libopencm3/stm32/pwr.h | 44 + .../include/libopencm3/stm32/quadspi.h | 28 + .../libopencm3/include/libopencm3/stm32/rcc.h | 44 + .../libopencm3/include/libopencm3/stm32/rng.h | 35 + .../libopencm3/include/libopencm3/stm32/rtc.h | 36 + .../include/libopencm3/stm32/sdio.h | 425 + .../libopencm3/include/libopencm3/stm32/spi.h | 38 + .../include/libopencm3/stm32/st_usbfs.h | 40 + .../include/libopencm3/stm32/syscfg.h | 38 + .../include/libopencm3/stm32/timer.h | 44 + .../include/libopencm3/stm32/tools.h | 66 + .../libopencm3/include/libopencm3/stm32/tsc.h | 28 + .../include/libopencm3/stm32/usart.h | 38 + .../include/libopencm3/stm32/wwdg.h | 83 + .../libopencm3/include/libopencm3/usb/audio.h | 94 + .../libopencm3/include/libopencm3/usb/cdc.h | 162 + .../libopencm3/include/libopencm3/usb/dfu.h | 102 + .../include/libopencm3/usb/doc-usb.h | 32 + .../libopencm3/include/libopencm3/usb/hid.h | 59 + .../libopencm3/include/libopencm3/usb/midi.h | 190 + .../libopencm3/include/libopencm3/usb/msc.h | 93 + .../libopencm3/include/libopencm3/usb/usbd.h | 196 + .../include/libopencm3/usb/usbstd.h | 277 + .../include/libopencm3/vf6xx/anadig.h | 224 + .../libopencm3/include/libopencm3/vf6xx/ccm.h | 351 + .../include/libopencm3/vf6xx/doc-vf6xx.h | 32 + .../include/libopencm3/vf6xx/gpio.h | 80 + .../include/libopencm3/vf6xx/iomuxc.h | 256 + .../include/libopencm3/vf6xx/irq.json | 119 + .../include/libopencm3/vf6xx/memorymap.h | 65 + .../include/libopencm3/vf6xx/uart.h | 182 + .../include/libopencmsis/core_cm3.h | 183 + .../libopencmsis/dispatch/irqhandlers.h | 50 + .../vendor/libopencm3/ld/Makefile.example | 46 + .../vendor/libopencm3/ld/Makefile.linker | 71 + .../firmware/vendor/libopencm3/ld/README | 157 + .../vendor/libopencm3/ld/devices.data | 474 ++ .../firmware/vendor/libopencm3/ld/linker.ld.S | 186 + .../vendor/libopencm3/ld/tests/dash.data | 1 + .../vendor/libopencm3/ld/tests/dash.result | 1 + .../vendor/libopencm3/ld/tests/longline.data | 2 + .../libopencm3/ld/tests/longline.result | 1 + .../vendor/libopencm3/ld/tests/single.data | 1 + .../vendor/libopencm3/ld/tests/single.result | 1 + .../vendor/libopencm3/ld/tests/tree1.data | 2 + .../vendor/libopencm3/ld/tests/tree1.result | 1 + .../vendor/libopencm3/ld/tests/tree5.data | 5 + .../vendor/libopencm3/ld/tests/tree5.result | 1 + .../vendor/libopencm3/ld/tests/twomatch.data | 4 + .../libopencm3/ld/tests/twomatch.result | 1 + .../vendor/libopencm3/lib/Makefile.include | 56 + .../vendor/libopencm3/lib/cm3/assert.c | 34 + .../firmware/vendor/libopencm3/lib/cm3/dwt.c | 77 + .../firmware/vendor/libopencm3/lib/cm3/nvic.c | 199 + .../firmware/vendor/libopencm3/lib/cm3/scb.c | 47 + .../firmware/vendor/libopencm3/lib/cm3/sync.c | 79 + .../vendor/libopencm3/lib/cm3/systick.c | 203 + .../vendor/libopencm3/lib/cm3/vector.c | 126 + .../libopencm3/lib/dispatch/vector_chipset.c | 20 + .../vendor/libopencm3/lib/efm32/g/Makefile | 45 + .../lib/efm32/g/libopencm3_efm32g.ld | 106 + .../lib/efm32/g/libopencm3_efm32g880f128.ld | 15 + .../vendor/libopencm3/lib/efm32/gg/Makefile | 45 + .../lib/efm32/gg/libopencm3_efm32gg.ld | 106 + .../efm32/gg/libopencm3_efm32gg990f1024.ld | 15 + .../vendor/libopencm3/lib/efm32/lg/Makefile | 49 + .../vendor/libopencm3/lib/efm32/lg/adc.c | 667 ++ .../vendor/libopencm3/lib/efm32/lg/cmu.c | 272 + .../vendor/libopencm3/lib/efm32/lg/dac.c | 168 + .../vendor/libopencm3/lib/efm32/lg/dma.c | 621 ++ .../vendor/libopencm3/lib/efm32/lg/gpio.c | 175 + .../lib/efm32/lg/libopencm3_efm32lg.ld | 106 + .../vendor/libopencm3/lib/efm32/lg/prs.c | 140 + .../vendor/libopencm3/lib/efm32/lg/timer.c | 62 + .../vendor/libopencm3/lib/efm32/tg/Makefile | 45 + .../lib/efm32/tg/libopencm3_efm32tg.ld | 106 + .../lib/efm32/tg/libopencm3_efm32tg840f32.ld | 15 + .../vendor/libopencm3/lib/ethernet/mac.c | 43 + .../libopencm3/lib/ethernet/mac_stm32fxx7.c | 379 + .../vendor/libopencm3/lib/ethernet/phy.c | 65 + .../libopencm3/lib/ethernet/phy_ksz8051mll.c | 93 + .../vendor/libopencm3/lib/lm3s/Makefile | 42 + .../vendor/libopencm3/lib/lm3s/gpio.c | 52 + .../libopencm3/lib/lm3s/libopencm3_lm3s.ld | 106 + .../vendor/libopencm3/lib/lm3s/lm3s6965.ld | 31 + .../firmware/vendor/libopencm3/lib/lm3s/rcc.c | 77 + .../vendor/libopencm3/lib/lm3s/usart.c | 88 + .../vendor/libopencm3/lib/lm4f/Makefile | 45 + .../vendor/libopencm3/lib/lm4f/gpio.c | 598 ++ .../libopencm3/lib/lm4f/libopencm3_lm4f.ld | 2 + .../firmware/vendor/libopencm3/lib/lm4f/rcc.c | 499 ++ .../libopencm3/lib/lm4f/systemcontrol.c | 40 + .../vendor/libopencm3/lib/lm4f/uart.c | 627 ++ .../libopencm3/lib/lm4f/vector_chipset.c | 24 + .../vendor/libopencm3/lib/lpc13xx/Makefile | 42 + .../vendor/libopencm3/lib/lpc13xx/gpio.c | 42 + .../lib/lpc13xx/libopencm3_lpc13xx.ld | 106 + .../vendor/libopencm3/lib/lpc17xx/Makefile | 42 + .../vendor/libopencm3/lib/lpc17xx/gpio.c | 48 + .../lib/lpc17xx/libopencm3_lpc17xx.ld | 106 + .../vendor/libopencm3/lib/lpc17xx/pwr.c | 48 + .../vendor/libopencm3/lib/lpc43xx/gpio.c | 53 + .../vendor/libopencm3/lib/lpc43xx/i2c.c | 102 + .../vendor/libopencm3/lib/lpc43xx/ipc.c | 58 + .../vendor/libopencm3/lib/lpc43xx/m0/Makefile | 45 + .../lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld | 0 .../m0/libopencm3_lpc43xx_ram_only_m0.ld | 96 + .../vendor/libopencm3/lib/lpc43xx/m4/Makefile | 52 + .../lib/lpc43xx/m4/libopencm3_lpc43xx.ld | 127 + .../lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld | 139 + .../m4/libopencm3_lpc43xx_rom_to_ram.ld | 128 + .../lib/lpc43xx/m4/vector_chipset.c | 48 + .../vendor/libopencm3/lib/lpc43xx/scu.c | 52 + .../vendor/libopencm3/lib/lpc43xx/ssp.c | 140 + .../vendor/libopencm3/lib/lpc43xx/timer.c | 72 + .../vendor/libopencm3/lib/lpc43xx/uart.c | 243 + .../vendor/libopencm3/lib/sam/3a/Makefile | 39 + .../libopencm3/lib/sam/3a/libopencm3_sam3a.ld | 106 + .../vendor/libopencm3/lib/sam/3n/Makefile | 39 + .../libopencm3/lib/sam/3n/libopencm3_sam3n.ld | 106 + .../vendor/libopencm3/lib/sam/3s/Makefile | 40 + .../libopencm3/lib/sam/3s/libopencm3_sam3s.ld | 106 + .../vendor/libopencm3/lib/sam/3u/Makefile | 40 + .../libopencm3/lib/sam/3u/libopencm3_sam3u.ld | 106 + .../vendor/libopencm3/lib/sam/3x/Makefile | 39 + .../libopencm3/lib/sam/3x/libopencm3_sam3x.ld | 106 + .../lib/sam/common/gpio_common_3a3u3x.c | 73 + .../lib/sam/common/gpio_common_3n3s.c | 86 + .../lib/sam/common/gpio_common_all.c | 66 + .../vendor/libopencm3/lib/sam/common/pmc.c | 106 + .../vendor/libopencm3/lib/sam/common/usart.c | 110 + .../vendor/libopencm3/lib/sam/d/Makefile | 39 + .../libopencm3/lib/sam/d/libopencm3_samd.ld | 106 + .../vendor/libopencm3/lib/stm32/can.c | 555 ++ .../lib/stm32/common/adc_common_v1.c | 752 ++ .../lib/stm32/common/adc_common_v2.c | 392 + .../lib/stm32/common/adc_common_v2_multi.c | 132 + .../lib/stm32/common/crc_common_all.c | 81 + .../lib/stm32/common/crs_common_all.c | 48 + .../lib/stm32/common/crypto_common_f24.c | 175 + .../lib/stm32/common/dac_common_all.c | 503 ++ .../lib/stm32/common/dma_common_f24.c | 794 ++ .../lib/stm32/common/dma_common_l1f013.c | 435 + .../lib/stm32/common/exti_common_all.c | 164 + .../lib/stm32/common/flash_common_f01.c | 235 + .../lib/stm32/common/flash_common_f234.c | 120 + .../lib/stm32/common/flash_common_f24.c | 414 + .../lib/stm32/common/flash_common_l01.c | 191 + .../lib/stm32/common/gpio_common_all.c | 151 + .../lib/stm32/common/gpio_common_f0234.c | 206 + .../lib/stm32/common/hash_common_f24.c | 163 + .../lib/stm32/common/i2c_common_v1.c | 570 ++ .../lib/stm32/common/i2c_common_v2.c | 477 ++ .../lib/stm32/common/iwdg_common_all.c | 149 + .../lib/stm32/common/pwr_common_v1.c | 205 + .../lib/stm32/common/pwr_common_v2.c | 48 + .../lib/stm32/common/rcc_common_all.c | 263 + .../lib/stm32/common/rng_common_v1.c | 91 + .../lib/stm32/common/rtc_common_l1f024.c | 123 + .../lib/stm32/common/spi_common_all.c | 741 ++ .../lib/stm32/common/spi_common_f03.c | 177 + .../lib/stm32/common/spi_common_l1f124.c | 138 + .../lib/stm32/common/st_usbfs_core.c | 277 + .../lib/stm32/common/st_usbfs_core.h | 76 + .../lib/stm32/common/timer_common_all.c | 2191 +++++ .../lib/stm32/common/timer_common_f0234.c | 58 + .../lib/stm32/common/timer_common_f24.c | 53 + .../lib/stm32/common/usart_common_all.c | 367 + .../lib/stm32/common/usart_common_f124.c | 113 + .../lib/stm32/common/usart_common_v2.c | 228 + .../vendor/libopencm3/lib/stm32/desig.c | 88 + .../vendor/libopencm3/lib/stm32/f0/Makefile | 58 + .../vendor/libopencm3/lib/stm32/f0/adc.c | 536 ++ .../libopencm3/lib/stm32/f0/comparator.c | 64 + .../vendor/libopencm3/lib/stm32/f0/crc.c | 31 + .../vendor/libopencm3/lib/stm32/f0/dac.c | 31 + .../vendor/libopencm3/lib/stm32/f0/dma.c | 31 + .../vendor/libopencm3/lib/stm32/f0/flash.c | 157 + .../vendor/libopencm3/lib/stm32/f0/gpio.c | 31 + .../vendor/libopencm3/lib/stm32/f0/i2c.c | 32 + .../vendor/libopencm3/lib/stm32/f0/iwdg.c | 31 + .../lib/stm32/f0/libopencm3_stm32f0.ld | 106 + .../vendor/libopencm3/lib/stm32/f0/pwr.c | 38 + .../vendor/libopencm3/lib/stm32/f0/rcc.c | 606 ++ .../vendor/libopencm3/lib/stm32/f0/rtc.c | 31 + .../vendor/libopencm3/lib/stm32/f0/spi.c | 31 + .../libopencm3/lib/stm32/f0/stm32f03xz6.ld | 31 + .../libopencm3/lib/stm32/f0/stm32f04xz6.ld | 31 + .../libopencm3/lib/stm32/f0/stm32f05xz6.ld | 31 + .../libopencm3/lib/stm32/f0/stm32f05xz8.ld | 31 + .../libopencm3/lib/stm32/f0/stm32f07xz8.ld | 31 + .../libopencm3/lib/stm32/f0/stm32f07xzb.ld | 31 + .../vendor/libopencm3/lib/stm32/f0/syscfg.c | 31 + .../vendor/libopencm3/lib/stm32/f0/timer.c | 34 + .../vendor/libopencm3/lib/stm32/f0/usart.c | 375 + .../vendor/libopencm3/lib/stm32/f1/Makefile | 57 + .../vendor/libopencm3/lib/stm32/f1/adc.c | 461 ++ .../vendor/libopencm3/lib/stm32/f1/crc.c | 31 + .../vendor/libopencm3/lib/stm32/f1/dac.c | 31 + .../vendor/libopencm3/lib/stm32/f1/dma.c | 31 + .../vendor/libopencm3/lib/stm32/f1/flash.c | 317 + .../vendor/libopencm3/lib/stm32/f1/gpio.c | 200 + .../vendor/libopencm3/lib/stm32/f1/i2c.c | 31 + .../vendor/libopencm3/lib/stm32/f1/iwdg.c | 31 + .../lib/stm32/f1/libopencm3_stm32f1.ld | 106 + .../vendor/libopencm3/lib/stm32/f1/pwr.c | 43 + .../vendor/libopencm3/lib/stm32/f1/rcc.c | 1107 +++ .../vendor/libopencm3/lib/stm32/f1/rtc.c | 418 + .../vendor/libopencm3/lib/stm32/f1/spi.c | 31 + .../libopencm3/lib/stm32/f1/stm32f100x4.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f100x6.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f100x8.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f100xb.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f100xc.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f100xd.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f100xe.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f103x8.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f103xb.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f103xc.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f103xd.ld | 31 + .../libopencm3/lib/stm32/f1/stm32f103xe.ld | 31 + .../vendor/libopencm3/lib/stm32/f1/timer.c | 57 + .../vendor/libopencm3/lib/stm32/f1/usart.c | 31 + .../vendor/libopencm3/lib/stm32/f2/Makefile | 55 + .../vendor/libopencm3/lib/stm32/f2/crc.c | 33 + .../vendor/libopencm3/lib/stm32/f2/crypto.c | 31 + .../vendor/libopencm3/lib/stm32/f2/dac.c | 31 + .../vendor/libopencm3/lib/stm32/f2/dma.c | 31 + .../vendor/libopencm3/lib/stm32/f2/flash.c | 53 + .../vendor/libopencm3/lib/stm32/f2/gpio.c | 31 + .../vendor/libopencm3/lib/stm32/f2/hash.c | 31 + .../vendor/libopencm3/lib/stm32/f2/i2c.c | 32 + .../vendor/libopencm3/lib/stm32/f2/iwdg.c | 31 + .../lib/stm32/f2/libopencm3_stm32f2.ld | 106 + .../vendor/libopencm3/lib/stm32/f2/pwr.c | 39 + .../vendor/libopencm3/lib/stm32/f2/rcc.c | 388 + .../vendor/libopencm3/lib/stm32/f2/rng.c | 31 + .../vendor/libopencm3/lib/stm32/f2/rtc.c | 31 + .../vendor/libopencm3/lib/stm32/f2/spi.c | 31 + .../vendor/libopencm3/lib/stm32/f2/timer.c | 38 + .../vendor/libopencm3/lib/stm32/f2/usart.c | 31 + .../vendor/libopencm3/lib/stm32/f3/Makefile | 56 + .../vendor/libopencm3/lib/stm32/f3/adc.c | 740 ++ .../vendor/libopencm3/lib/stm32/f3/crc.c | 33 + .../vendor/libopencm3/lib/stm32/f3/dac.c | 31 + .../vendor/libopencm3/lib/stm32/f3/dma.c | 31 + .../vendor/libopencm3/lib/stm32/f3/flash.c | 62 + .../vendor/libopencm3/lib/stm32/f3/i2c.c | 32 + .../vendor/libopencm3/lib/stm32/f3/iwdg.c | 31 + .../lib/stm32/f3/libopencm3_stm32f3.ld | 106 + .../vendor/libopencm3/lib/stm32/f3/pwr.c | 40 + .../vendor/libopencm3/lib/stm32/f3/rcc.c | 446 ++ .../vendor/libopencm3/lib/stm32/f3/rtc.c | 38 + .../vendor/libopencm3/lib/stm32/f3/spi.c | 31 + .../libopencm3/lib/stm32/f3/stm32f303xc.ld | 31 + .../vendor/libopencm3/lib/stm32/f3/timer.c | 33 + .../vendor/libopencm3/lib/stm32/f3/usart.c | 110 + .../libopencm3/lib/stm32/f3/vector_chipset.c | 27 + .../vendor/libopencm3/lib/stm32/f4/Makefile | 65 + .../vendor/libopencm3/lib/stm32/f4/adc.c | 437 + .../vendor/libopencm3/lib/stm32/f4/crc.c | 33 + .../vendor/libopencm3/lib/stm32/f4/crypto.c | 66 + .../vendor/libopencm3/lib/stm32/f4/dac.c | 31 + .../vendor/libopencm3/lib/stm32/f4/dma.c | 31 + .../vendor/libopencm3/lib/stm32/f4/flash.c | 53 + .../vendor/libopencm3/lib/stm32/f4/fmc.c | 99 + .../vendor/libopencm3/lib/stm32/f4/gpio.c | 31 + .../vendor/libopencm3/lib/stm32/f4/hash.c | 31 + .../vendor/libopencm3/lib/stm32/f4/i2c.c | 31 + .../vendor/libopencm3/lib/stm32/f4/iwdg.c | 31 + .../lib/stm32/f4/libopencm3_stm32f4.ld | 106 + .../vendor/libopencm3/lib/stm32/f4/ltdc.c | 89 + .../vendor/libopencm3/lib/stm32/f4/pwr.c | 46 + .../vendor/libopencm3/lib/stm32/f4/rcc.c | 732 ++ .../vendor/libopencm3/lib/stm32/f4/rng.c | 31 + .../vendor/libopencm3/lib/stm32/f4/rtc.c | 97 + .../vendor/libopencm3/lib/stm32/f4/spi.c | 31 + .../libopencm3/lib/stm32/f4/stm32f405x6.ld | 34 + .../vendor/libopencm3/lib/stm32/f4/timer.c | 38 + .../vendor/libopencm3/lib/stm32/f4/usart.c | 31 + .../libopencm3/lib/stm32/f4/vector_chipset.c | 27 + .../vendor/libopencm3/lib/stm32/f7/Makefile | 76 + .../vendor/libopencm3/lib/stm32/f7/gpio.c | 31 + .../lib/stm32/f7/libopencm3_stm32f7.ld | 106 + .../vendor/libopencm3/lib/stm32/f7/pwr.c | 66 + .../vendor/libopencm3/lib/stm32/f7/rcc.c | 345 + .../libopencm3/lib/stm32/f7/vector_chipset.c | 27 + .../vendor/libopencm3/lib/stm32/l0/Makefile | 57 + .../vendor/libopencm3/lib/stm32/l0/flash.c | 27 + .../vendor/libopencm3/lib/stm32/l0/gpio.c | 31 + .../vendor/libopencm3/lib/stm32/l0/i2c.c | 32 + .../lib/stm32/l0/libopencm3_stm32l0.ld | 106 + .../vendor/libopencm3/lib/stm32/l0/rcc.c | 423 + .../vendor/libopencm3/lib/stm32/l0/rng.c | 31 + .../libopencm3/lib/stm32/l0/stm32l0xx6.ld | 32 + .../libopencm3/lib/stm32/l0/stm32l0xx8.ld | 32 + .../vendor/libopencm3/lib/stm32/l1/Makefile | 57 + .../vendor/libopencm3/lib/stm32/l1/adc.c | 201 + .../vendor/libopencm3/lib/stm32/l1/crc.c | 33 + .../vendor/libopencm3/lib/stm32/l1/dac.c | 31 + .../vendor/libopencm3/lib/stm32/l1/dma.c | 31 + .../vendor/libopencm3/lib/stm32/l1/flash.c | 74 + .../vendor/libopencm3/lib/stm32/l1/gpio.c | 31 + .../vendor/libopencm3/lib/stm32/l1/i2c.c | 31 + .../vendor/libopencm3/lib/stm32/l1/iwdg.c | 31 + .../vendor/libopencm3/lib/stm32/l1/lcd.c | 154 + .../lib/stm32/l1/libopencm3_stm32l1.ld | 106 + .../vendor/libopencm3/lib/stm32/l1/rcc.c | 554 ++ .../vendor/libopencm3/lib/stm32/l1/rtc.c | 31 + .../vendor/libopencm3/lib/stm32/l1/spi.c | 31 + .../libopencm3/lib/stm32/l1/stm32l100xc.ld | 33 + .../libopencm3/lib/stm32/l1/stm32l15xx6.ld | 32 + .../libopencm3/lib/stm32/l1/stm32l15xx8.ld | 32 + .../libopencm3/lib/stm32/l1/stm32l15xxb.ld | 32 + .../libopencm3/lib/stm32/l1/stm32l15xxc.ld | 32 + .../libopencm3/lib/stm32/l1/stm32l15xxd.ld | 32 + .../vendor/libopencm3/lib/stm32/l1/timer.c | 59 + .../vendor/libopencm3/lib/stm32/l1/usart.c | 31 + .../vendor/libopencm3/lib/stm32/l4/Makefile | 54 + .../vendor/libopencm3/lib/stm32/l4/adc.c | 59 + .../vendor/libopencm3/lib/stm32/l4/flash.c | 344 + .../vendor/libopencm3/lib/stm32/l4/i2c.c | 32 + .../lib/stm32/l4/libopencm3_stm32l4.ld | 106 + .../vendor/libopencm3/lib/stm32/l4/pwr.c | 55 + .../vendor/libopencm3/lib/stm32/l4/rcc.c | 352 + .../libopencm3/lib/stm32/l4/vector_chipset.c | 27 + .../vendor/libopencm3/lib/stm32/st_usbfs_v1.c | 86 + .../vendor/libopencm3/lib/stm32/st_usbfs_v2.c | 101 + .../firmware/vendor/libopencm3/lib/usb/usb.c | 157 + .../vendor/libopencm3/lib/usb/usb_control.c | 320 + .../vendor/libopencm3/lib/usb/usb_efm32lg.c | 426 + .../vendor/libopencm3/lib/usb/usb_f107.c | 100 + .../vendor/libopencm3/lib/usb/usb_f207.c | 92 + .../libopencm3/lib/usb/usb_fx07_common.c | 395 + .../libopencm3/lib/usb/usb_fx07_common.h | 39 + .../vendor/libopencm3/lib/usb/usb_lm4f.c | 651 ++ .../vendor/libopencm3/lib/usb/usb_msc.c | 829 ++ .../vendor/libopencm3/lib/usb/usb_private.h | 163 + .../vendor/libopencm3/lib/usb/usb_standard.c | 600 ++ .../vendor/libopencm3/lib/vf6xx/Makefile | 43 + .../vendor/libopencm3/lib/vf6xx/ccm.c | 202 + .../vendor/libopencm3/lib/vf6xx/gpio.c | 131 + .../vendor/libopencm3/lib/vf6xx/iomuxc.c | 57 + .../libopencm3/lib/vf6xx/libopencm3_vf6xx.ld | 109 + .../vendor/libopencm3/lib/vf6xx/uart.c | 225 + .../libopencm3/lib/vf6xx/vector_chipset.c | 39 + .../vendor/libopencm3/locm3.sublime-project | 35 + .../firmware/vendor/libopencm3/mk/README | 121 + .../vendor/libopencm3/mk/gcc-config.mk | 37 + .../vendor/libopencm3/mk/gcc-rules.mk | 56 + .../vendor/libopencm3/mk/genlink-config.mk | 79 + .../vendor/libopencm3/mk/genlink-rules.mk | 22 + .../vendor/libopencm3/scripts/checkpatch.pl | 3731 +++++++++ .../libopencm3/scripts/data/lpc43xx/README | 23 + .../libopencm3/scripts/data/lpc43xx/adc.yaml | 607 ++ .../scripts/data/lpc43xx/atimer.yaml | 71 + .../libopencm3/scripts/data/lpc43xx/ccu.yaml | 2391 ++++++ .../libopencm3/scripts/data/lpc43xx/cgu.yaml | 937 +++ .../libopencm3/scripts/data/lpc43xx/creg.yaml | 312 + .../scripts/data/lpc43xx/csv2yaml.py | 36 + .../scripts/data/lpc43xx/eventrouter.yaml | 959 +++ .../libopencm3/scripts/data/lpc43xx/gen.py | 25 + .../libopencm3/scripts/data/lpc43xx/gima.yaml | 961 +++ .../scripts/data/lpc43xx/gpdma.yaml | 1498 ++++ .../libopencm3/scripts/data/lpc43xx/gpio.yaml | 4926 ++++++++++++ .../libopencm3/scripts/data/lpc43xx/i2c.yaml | 415 + .../libopencm3/scripts/data/lpc43xx/i2s.yaml | 619 ++ .../libopencm3/scripts/data/lpc43xx/rgu.yaml | 1199 +++ .../scripts/data/lpc43xx/ritimer.yaml | 51 + .../libopencm3/scripts/data/lpc43xx/scu.yaml | 7063 +++++++++++++++++ .../scripts/data/lpc43xx/sgpio.yaml | 1953 +++++ .../libopencm3/scripts/data/lpc43xx/ssp.yaml | 445 ++ .../libopencm3/scripts/data/lpc43xx/usb.yaml | 1416 ++++ .../scripts/data/lpc43xx/yaml_odict.py | 81 + .../vendor/libopencm3/scripts/genlink.awk | 77 + .../vendor/libopencm3/scripts/genlinktest.sh | 39 + .../vendor/libopencm3/scripts/irq2nvic_h | 176 + .../vendor/libopencm3/scripts/lpcvtcksum | 51 + .../libopencm3/tests/gadget-zero/.gitignore | 1 + .../tests/gadget-zero/Makefile.stm32f072disco | 44 + .../gadget-zero/Makefile.stm32f103-generic | 43 + .../gadget-zero/Makefile.stm32f429i-disco | 44 + .../tests/gadget-zero/Makefile.stm32f4disco | 44 + .../tests/gadget-zero/Makefile.stm32l053disco | 44 + .../gadget-zero/Makefile.stm32l1-generic | 43 + .../libopencm3/tests/gadget-zero/README.md | 51 + .../libopencm3/tests/gadget-zero/delay.c | 50 + .../libopencm3/tests/gadget-zero/delay.h | 39 + .../tests/gadget-zero/main-stm32f072disco.c | 66 + .../gadget-zero/main-stm32f103-generic.c | 71 + .../tests/gadget-zero/main-stm32f429i-disco.c | 59 + .../tests/gadget-zero/main-stm32f4disco.c | 59 + .../tests/gadget-zero/main-stm32l053disco.c | 90 + .../tests/gadget-zero/main-stm32l1-generic.c | 70 + .../tests/gadget-zero/openocd.common.cfg | 10 + .../gadget-zero/openocd.stm32f072disco.cfg | 14 + .../gadget-zero/openocd.stm32f103-generic.cfg | 15 + .../gadget-zero/openocd.stm32f429i-disco.cfg | 13 + .../gadget-zero/openocd.stm32f4disco.cfg | 13 + .../gadget-zero/openocd.stm32l053disco.cfg | 14 + .../gadget-zero/openocd.stm32l1-generic.cfg | 13 + .../libopencm3/tests/gadget-zero/stub.py | 4 + .../tests/gadget-zero/test_gadget0.py | 397 + .../tests/gadget-zero/usb-gadget0.c | 357 + .../tests/gadget-zero/usb-gadget0.h | 42 + .../firmware/vendor/libopencm3/tests/rules.mk | 171 + .../vendor/libopencm3/tests/shared/trace.c | 57 + .../vendor/libopencm3/tests/shared/trace.h | 32 + .../libopencm3/tests/shared/trace_stdio.c | 34 + .../firmware/vendor/nanopb/.gitignore | 28 + .../firmware/vendor/nanopb/.travis.yml | 60 + .../firmware/vendor/nanopb/AUTHORS.txt | 39 + hardware-wallet/firmware/vendor/nanopb/BUILD | 21 + .../firmware/vendor/nanopb/CHANGELOG.txt | 288 + .../firmware/vendor/nanopb/CMakeLists.txt | 90 + .../firmware/vendor/nanopb/CONTRIBUTING.md | 32 + .../firmware/vendor/nanopb/LICENSE.txt | 20 + .../firmware/vendor/nanopb/README.md | 71 + .../firmware/vendor/nanopb/WORKSPACE | 1 + .../firmware/vendor/nanopb/docs/Makefile | 9 + .../firmware/vendor/nanopb/docs/concepts.rst | 392 + .../vendor/nanopb/docs/generator_flow.svg | 2869 +++++++ .../firmware/vendor/nanopb/docs/index.rst | 127 + .../firmware/vendor/nanopb/docs/logo/logo.png | Bin 0 -> 14973 bytes .../firmware/vendor/nanopb/docs/logo/logo.svg | 1470 ++++ .../vendor/nanopb/docs/logo/logo16px.png | Bin 0 -> 854 bytes .../vendor/nanopb/docs/logo/logo48px.png | Bin 0 -> 2577 bytes .../firmware/vendor/nanopb/docs/lsr.css | 240 + .../firmware/vendor/nanopb/docs/menu.rst | 13 + .../firmware/vendor/nanopb/docs/migration.rst | 304 + .../firmware/vendor/nanopb/docs/reference.rst | 773 ++ .../firmware/vendor/nanopb/docs/security.rst | 84 + .../examples/cmake_relpath/CMakeLists.txt | 18 + .../nanopb/examples/cmake_relpath/README.txt | 18 + .../examples/cmake_relpath/proto/simple.proto | 11 + .../cmake_relpath/proto/sub/unlucky.proto | 5 + .../nanopb/examples/cmake_relpath/simple.c | 73 + .../examples/cmake_simple/CMakeLists.txt | 16 + .../nanopb/examples/cmake_simple/README.txt | 18 + .../nanopb/examples/cmake_simple/simple.c | 71 + .../nanopb/examples/cmake_simple/simple.proto | 9 + .../nanopb/examples/network_server/Makefile | 17 + .../nanopb/examples/network_server/README.txt | 60 + .../nanopb/examples/network_server/client.c | 138 + .../nanopb/examples/network_server/common.c | 40 + .../nanopb/examples/network_server/common.h | 9 + .../examples/network_server/fileproto.options | 13 + .../examples/network_server/fileproto.proto | 20 + .../nanopb/examples/network_server/server.c | 162 + .../vendor/nanopb/examples/simple/Makefile | 22 + .../vendor/nanopb/examples/simple/README.txt | 29 + .../vendor/nanopb/examples/simple/simple.c | 71 + .../nanopb/examples/simple/simple.proto | 9 + .../examples/using_double_on_avr/Makefile | 24 + .../examples/using_double_on_avr/README.txt | 25 + .../using_double_on_avr/decode_double.c | 33 + .../using_double_on_avr/double_conversion.c | 123 + .../using_double_on_avr/double_conversion.h | 26 + .../using_double_on_avr/doubleproto.proto | 15 + .../using_double_on_avr/encode_double.c | 25 + .../using_double_on_avr/test_conversions.c | 56 + .../examples/using_union_messages/Makefile | 20 + .../examples/using_union_messages/README.txt | 55 + .../examples/using_union_messages/decode.c | 96 + .../examples/using_union_messages/encode.c | 85 + .../using_union_messages/unionproto.proto | 32 + .../vendor/nanopb/extra/FindNanopb.cmake | 313 + .../extra/nanopb-config-version.cmake.in | 11 + .../vendor/nanopb/extra/nanopb-config.cmake | 1 + .../firmware/vendor/nanopb/extra/nanopb.mk | 37 + .../firmware/vendor/nanopb/extra/pb_syshdr.h | 112 + .../nanopb/generator/nanopb/options.proto | 120 + .../nanopb/generator/nanopb_generator.py | 1680 ++++ .../vendor/nanopb/generator/proto/Makefile | 4 + .../vendor/nanopb/generator/proto/__init__.py | 0 .../proto/google/protobuf/descriptor.proto | 714 ++ .../nanopb/generator/proto/nanopb.proto | 112 + .../nanopb/generator/proto/plugin.proto | 148 + .../vendor/nanopb/generator/protoc-gen-nanopb | 13 + .../nanopb/generator/protoc-gen-nanopb.bat | 12 + .../firmware/vendor/nanopb/library.json | 26 + hardware-wallet/firmware/vendor/nanopb/pb.h | 585 ++ .../firmware/vendor/nanopb/pb_common.c | 97 + .../firmware/vendor/nanopb/pb_common.h | 42 + .../firmware/vendor/nanopb/pb_decode.c | 1458 ++++ .../firmware/vendor/nanopb/pb_decode.h | 175 + .../firmware/vendor/nanopb/pb_encode.c | 828 ++ .../firmware/vendor/nanopb/pb_encode.h | 170 + .../firmware/vendor/nanopb/tests/Makefile | 21 + .../firmware/vendor/nanopb/tests/SConstruct | 157 + .../vendor/nanopb/tests/alltypes/SConscript | 35 + .../nanopb/tests/alltypes/alltypes.options | 3 + .../nanopb/tests/alltypes/alltypes.proto | 125 + .../nanopb/tests/alltypes/decode_alltypes.c | 229 + .../nanopb/tests/alltypes/encode_alltypes.c | 155 + .../nanopb/tests/alltypes_callback/SConscript | 28 + .../tests/alltypes_callback/alltypes.options | 8 + .../decode_alltypes_callback.c | 442 ++ .../encode_alltypes_callback.c | 411 + .../nanopb/tests/alltypes_pointer/SConscript | 40 + .../tests/alltypes_pointer/alltypes.options | 4 + .../decode_alltypes_pointer.c | 186 + .../encode_alltypes_pointer.c | 200 + .../nanopb/tests/alltypes_proto3/SConscript | 45 + .../tests/alltypes_proto3/alltypes.options | 4 + .../tests/alltypes_proto3/alltypes.proto | 100 + .../tests/alltypes_proto3/decode_alltypes.c | 167 + .../tests/alltypes_proto3/encode_alltypes.c | 111 + .../tests/alltypes_proto3_callback/SConscript | 23 + .../alltypes_proto3_callback/alltypes.options | 8 + .../decode_alltypes_callback.c | 376 + .../encode_alltypes_callback.c | 343 + .../nanopb/tests/anonymous_oneof/SConscript | 30 + .../tests/anonymous_oneof/decode_oneof.c | 88 + .../nanopb/tests/anonymous_oneof/oneof.proto | 23 + .../tests/backwards_compatibility/SConscript | 11 + .../backwards_compatibility/alltypes_legacy.c | 153 + .../backwards_compatibility/alltypes_legacy.h | 274 + .../alltypes_legacy.options | 3 + .../alltypes_legacy.proto | 110 + .../backwards_compatibility/decode_legacy.c | 199 + .../backwards_compatibility/encode_legacy.c | 135 + .../nanopb/tests/basic_buffer/SConscript | 12 + .../nanopb/tests/basic_buffer/decode_buffer.c | 88 + .../nanopb/tests/basic_buffer/encode_buffer.c | 38 + .../nanopb/tests/basic_stream/SConscript | 12 + .../nanopb/tests/basic_stream/decode_stream.c | 84 + .../nanopb/tests/basic_stream/encode_stream.c | 40 + .../nanopb/tests/buffer_only/SConscript | 28 + .../vendor/nanopb/tests/callbacks/SConscript | 14 + .../nanopb/tests/callbacks/callbacks.proto | 18 + .../nanopb/tests/callbacks/decode_callbacks.c | 97 + .../nanopb/tests/callbacks/encode_callbacks.c | 92 + .../vendor/nanopb/tests/common/SConscript | 48 + .../nanopb/tests/common/malloc_wrappers.c | 54 + .../nanopb/tests/common/malloc_wrappers.h | 7 + .../tests/common/malloc_wrappers_syshdr.h | 15 + .../vendor/nanopb/tests/common/person.proto | 22 + .../vendor/nanopb/tests/common/test_helpers.h | 17 + .../nanopb/tests/common/unittestproto.proto | 43 + .../vendor/nanopb/tests/common/unittests.h | 14 + .../nanopb/tests/cxx_main_program/SConscript | 25 + .../nanopb/tests/cyclic_messages/SConscript | 11 + .../nanopb/tests/cyclic_messages/cyclic.proto | 27 + .../cyclic_messages/cyclic_callback.options | 7 + .../cyclic_messages/encode_cyclic_callback.c | 148 + .../nanopb/tests/decode_unittests/SConscript | 4 + .../tests/decode_unittests/decode_unittests.c | 399 + .../nanopb/tests/encode_unittests/SConscript | 5 + .../tests/encode_unittests/encode_unittests.c | 355 + .../vendor/nanopb/tests/enum_sizes/SConscript | 12 + .../nanopb/tests/enum_sizes/enumsizes.proto | 86 + .../tests/enum_sizes/enumsizes_unittests.c | 72 + .../nanopb/tests/enum_to_string/SConscript | 7 + .../nanopb/tests/enum_to_string/enum.proto | 19 + .../tests/enum_to_string/enum_to_string.c | 19 + .../vendor/nanopb/tests/extensions/SConscript | 16 + .../tests/extensions/decode_extensions.c | 60 + .../tests/extensions/encode_extensions.c | 54 + .../tests/extensions/extensions.options | 1 + .../nanopb/tests/extensions/extensions.proto | 19 + .../nanopb/tests/extra_fields/SConscript | 16 + .../person_with_extra_field.expected | 14 + .../nanopb/tests/field_size_16/SConscript | 32 + .../tests/field_size_16/alltypes.options | 4 + .../nanopb/tests/field_size_16/alltypes.proto | 123 + .../tests/field_size_16_proto3/SConscript | 34 + .../field_size_16_proto3/alltypes.options | 4 + .../tests/field_size_16_proto3/alltypes.proto | 100 + .../field_size_16_proto3/decode_alltypes.c | 167 + .../field_size_16_proto3/encode_alltypes.c | 111 + .../nanopb/tests/field_size_32/SConscript | 32 + .../tests/field_size_32/alltypes.options | 3 + .../nanopb/tests/field_size_32/alltypes.proto | 123 + .../vendor/nanopb/tests/fuzztest/SConscript | 43 + .../tests/fuzztest/alltypes_pointer.options | 3 + .../tests/fuzztest/alltypes_static.options | 4 + .../vendor/nanopb/tests/fuzztest/fuzzstub.c | 189 + .../vendor/nanopb/tests/fuzztest/fuzztest.c | 432 + .../nanopb/tests/fuzztest/generate_message.c | 101 + .../nanopb/tests/fuzztest/run_radamsa.sh | 12 + .../vendor/nanopb/tests/inline/SConscript | 16 + .../nanopb/tests/inline/inline.expected | 3 + .../vendor/nanopb/tests/inline/inline.proto | 17 + .../nanopb/tests/inline/inline_unittests.c | 73 + .../vendor/nanopb/tests/intsizes/SConscript | 12 + .../nanopb/tests/intsizes/intsizes.proto | 41 + .../tests/intsizes/intsizes_unittests.c | 122 + .../vendor/nanopb/tests/io_errors/SConscript | 15 + .../nanopb/tests/io_errors/alltypes.options | 3 + .../vendor/nanopb/tests/io_errors/io_errors.c | 140 + .../tests/io_errors_pointers/SConscript | 26 + .../tests/io_errors_pointers/alltypes.options | 3 + .../nanopb/tests/mem_release/SConscript | 13 + .../nanopb/tests/mem_release/mem_release.c | 187 + .../tests/mem_release/mem_release.proto | 35 + .../nanopb/tests/message_sizes/SConscript | 11 + .../vendor/nanopb/tests/message_sizes/dummy.c | 9 + .../tests/message_sizes/messages1.proto | 29 + .../tests/message_sizes/messages2.proto | 10 + .../nanopb/tests/missing_fields/SConscript | 8 + .../tests/missing_fields/missing_fields.c | 53 + .../tests/missing_fields/missing_fields.proto | 140 + .../nanopb/tests/multiple_files/SConscript | 16 + .../tests/multiple_files/multifile1.options | 1 + .../tests/multiple_files/multifile1.proto | 34 + .../tests/multiple_files/multifile2.proto | 22 + .../multiple_files/subdir/multifile2.proto | 25 + .../multiple_files/test_multiple_files.c | 30 + .../vendor/nanopb/tests/no_errmsg/SConscript | 28 + .../nanopb/tests/no_messages/SConscript | 7 + .../tests/no_messages/no_messages.proto | 9 + .../vendor/nanopb/tests/oneof/SConscript | 33 + .../vendor/nanopb/tests/oneof/decode_oneof.c | 131 + .../vendor/nanopb/tests/oneof/encode_oneof.c | 64 + .../vendor/nanopb/tests/oneof/oneof.proto | 32 + .../vendor/nanopb/tests/options/SConscript | 12 + .../nanopb/tests/options/options.expected | 20 + .../vendor/nanopb/tests/options/options.proto | 98 + .../tests/options/proto3_options.expected | 4 + .../nanopb/tests/options/proto3_options.proto | 11 + .../nanopb/tests/package_name/SConscript | 38 + .../tests/regression/issue_118/SConscript | 12 + .../tests/regression/issue_118/enumdef.proto | 8 + .../tests/regression/issue_118/enumuse.proto | 7 + .../tests/regression/issue_125/SConscript | 9 + .../issue_125/extensionbug.expected | 3 + .../regression/issue_125/extensionbug.options | 4 + .../regression/issue_125/extensionbug.proto | 18 + .../tests/regression/issue_141/SConscript | 8 + .../regression/issue_141/testproto.expected | 7 + .../regression/issue_141/testproto.proto | 52 + .../tests/regression/issue_145/SConscript | 9 + .../regression/issue_145/comments.expected | 3 + .../regression/issue_145/comments.options | 6 + .../tests/regression/issue_145/comments.proto | 7 + .../tests/regression/issue_166/SConscript | 13 + .../regression/issue_166/enum_encoded_size.c | 43 + .../tests/regression/issue_166/enums.proto | 18 + .../tests/regression/issue_172/SConscript | 16 + .../tests/regression/issue_172/msg_size.c | 9 + .../issue_172/submessage/submessage.options | 1 + .../issue_172/submessage/submessage.proto | 4 + .../tests/regression/issue_172/test.proto | 6 + .../tests/regression/issue_188/SConscript | 6 + .../tests/regression/issue_188/oneof.proto | 29 + .../tests/regression/issue_195/SConscript | 10 + .../tests/regression/issue_195/test.expected | 1 + .../tests/regression/issue_195/test.proto | 8 + .../tests/regression/issue_203/SConscript | 9 + .../tests/regression/issue_203/file1.proto | 10 + .../tests/regression/issue_203/file2.proto | 10 + .../tests/regression/issue_205/SConscript | 14 + .../regression/issue_205/size_corruption.c | 12 + .../issue_205/size_corruption.proto | 11 + .../tests/regression/issue_227/SConscript | 14 + .../regression/issue_227/unaligned_uint64.c | 14 + .../issue_227/unaligned_uint64.proto | 8 + .../tests/regression/issue_229/SConscript | 13 + .../regression/issue_229/multiple_oneof.c | 35 + .../regression/issue_229/multiple_oneof.proto | 11 + .../tests/regression/issue_242/SConscript | 13 + .../tests/regression/issue_242/zero_value.c | 51 + .../regression/issue_242/zero_value.proto | 15 + .../tests/regression/issue_247/SConscript | 14 + .../tests/regression/issue_247/padding.c | 32 + .../tests/regression/issue_247/padding.proto | 12 + .../tests/regression/issue_249/SConscript | 12 + .../nanopb/tests/regression/issue_249/test.c | 59 + .../tests/regression/issue_249/test.proto | 10 + .../tests/regression/issue_253/SConscript | 15 + .../tests/regression/issue_253/short_array.c | 24 + .../regression/issue_253/short_array.proto | 7 + .../tests/regression/issue_256/SConscript | 16 + .../tests/regression/issue_256/submsg_array.c | 38 + .../regression/issue_256/submsg_array.proto | 11 + .../tests/regression/issue_259/SConscript | 22 + .../regression/issue_259/callback_pointer.c | 30 + .../issue_259/callback_pointer.proto | 11 + .../nanopb/tests/site_scons/site_init.py | 109 + .../tests/site_scons/site_tools/nanopb.py | 126 + .../tests/special_characters/SConscript | 6 + .../funny-proto+name has.characters.proto | 1 + .../vendor/nanopb/tests/splint/SConscript | 16 + .../vendor/nanopb/tests/splint/splint.rc | 37 + .../nanopb/tests/without_64bit/SConscript | 30 + .../tests/without_64bit/alltypes.options | 3 + .../nanopb/tests/without_64bit/alltypes.proto | 100 + .../tests/without_64bit/decode_alltypes.c | 185 + .../tests/without_64bit/encode_alltypes.c | 124 + .../tests/without_64bit/no_64bit_syshdr.h | 14 + .../vendor/nanopb/tools/make_linux_package.sh | 52 + .../vendor/nanopb/tools/make_mac_package.sh | 49 + .../nanopb/tools/make_windows_package.sh | 55 + .../vendor/nanopb/tools/set_version.sh | 14 + .../firmware/vendor/skycoin-crypto | 1 + .../firmware/vendor/trezor-common/.travis.yml | 23 + .../firmware/vendor/trezor-common/COPYING | 165 + .../firmware/vendor/trezor-common/README.md | 12 + .../vendor/trezor-common/coins-check.py | 44 + .../firmware/vendor/trezor-common/coins.json | 547 ++ .../trezor-common/ethereum_tokens-gen.py | 67 + .../trezor-common/keys/public_trezor1.h | 6 + .../trezor-common/keys/public_trezor1.pem | 24 + .../trezor-common/keys/public_trezor1.txt | 5 + .../vendor/trezor-common/keys/sample.h | 2 + .../vendor/trezor-common/keys/sample.pem | 4 + .../vendor/trezor-common/keys/sample.txt | 1 + .../vendor/trezor-common/protob/.gitignore | 1 + .../vendor/trezor-common/protob/Makefile | 7 + .../vendor/trezor-common/protob/config.proto | 32 + .../trezor-common/protob/messages.proto | 1082 +++ .../vendor/trezor-common/protob/protocol.md | 21 + .../vendor/trezor-common/protob/storage.proto | 31 + .../vendor/trezor-common/protob/types.proto | 445 ++ .../vendor/trezor-common/signer/.gitignore | 4 + .../vendor/trezor-common/signer/config.json | 29 + .../vendor/trezor-common/signer/sample.key | 5 + .../vendor/trezor-common/signer/sign.py | 101 + .../vendor/trezor-common/udev/51-trezor.rules | 12 + .../vendor/trezor-common/udev/dist/.gitignore | 3 + .../vendor/trezor-common/udev/dist/Dockerfile | 17 + .../vendor/trezor-common/udev/dist/Makefile | 18 + .../vendor/trezor-common/udev/dist/release.sh | 32 + .../firmware/vendor/trezor-crypto/.gitignore | 13 + .../firmware/vendor/trezor-crypto/.travis.yml | 37 + .../firmware/vendor/trezor-crypto/AUTHORS | 2 + .../vendor/trezor-crypto/CMakeLists.txt | 44 + .../vendor/trezor-crypto/CONTRIBUTORS | 15 + .../firmware/vendor/trezor-crypto/LICENSE | 22 + .../firmware/vendor/trezor-crypto/Makefile | 94 + .../firmware/vendor/trezor-crypto/README.md | 43 + .../firmware/vendor/trezor-crypto/address.c | 78 + .../firmware/vendor/trezor-crypto/address.h | 39 + .../firmware/vendor/trezor-crypto/aes/aes.h | 215 + .../vendor/trezor-crypto/aes/aes_modes.c | 957 +++ .../vendor/trezor-crypto/aes/aescrypt.c | 307 + .../vendor/trezor-crypto/aes/aeskey.c | 562 ++ .../vendor/trezor-crypto/aes/aesopt.h | 778 ++ .../vendor/trezor-crypto/aes/aestab.c | 418 + .../vendor/trezor-crypto/aes/aestab.h | 173 + .../vendor/trezor-crypto/aes/aestst.c | 178 + .../vendor/trezor-crypto/aes/aestst.h | 85 + .../vendor/trezor-crypto/aes/brg_types.h | 191 + .../firmware/vendor/trezor-crypto/base32.c | 233 + .../firmware/vendor/trezor-crypto/base32.h | 41 + .../firmware/vendor/trezor-crypto/base58.c | 278 + .../firmware/vendor/trezor-crypto/base58.h | 46 + .../firmware/vendor/trezor-crypto/bignum.c | 1095 +++ .../firmware/vendor/trezor-crypto/bignum.h | 167 + .../firmware/vendor/trezor-crypto/bip32.c | 686 ++ .../firmware/vendor/trezor-crypto/bip32.h | 100 + .../firmware/vendor/trezor-crypto/bip39.c | 260 + .../firmware/vendor/trezor-crypto/bip39.h | 44 + .../vendor/trezor-crypto/bip39_english.h | 2074 +++++ .../firmware/vendor/trezor-crypto/blake256.c | 235 + .../firmware/vendor/trezor-crypto/blake256.h | 53 + .../vendor/trezor-crypto/blake2_common.h | 39 + .../firmware/vendor/trezor-crypto/blake2b.c | 303 + .../firmware/vendor/trezor-crypto/blake2b.h | 40 + .../firmware/vendor/trezor-crypto/blake2s.c | 295 + .../firmware/vendor/trezor-crypto/blake2s.h | 40 + .../chacha20poly1305/chacha20poly1305.c | 59 + .../chacha20poly1305/chacha20poly1305.h | 19 + .../chacha20poly1305/chacha_merged.c | 245 + .../chacha20poly1305/ecrypt-config.h | 316 + .../chacha20poly1305/ecrypt-machine.h | 49 + .../chacha20poly1305/ecrypt-portable.h | 310 + .../chacha20poly1305/ecrypt-sync.h | 281 + .../chacha20poly1305/poly1305-donna-32.h | 219 + .../chacha20poly1305/poly1305-donna.c | 179 + .../chacha20poly1305/poly1305-donna.h | 20 + .../trezor-crypto/chacha20poly1305/rfc7539.c | 44 + .../trezor-crypto/chacha20poly1305/rfc7539.h | 10 + .../firmware/vendor/trezor-crypto/check_mem.h | 30 + .../firmware/vendor/trezor-crypto/curves.c | 33 + .../firmware/vendor/trezor-crypto/curves.h | 38 + .../firmware/vendor/trezor-crypto/ecdsa.c | 1191 +++ .../firmware/vendor/trezor-crypto/ecdsa.h | 97 + .../trezor-crypto/ed25519-donna/README.md | 183 + .../ed25519-donna/curve25519-donna-32bit.c | 545 ++ .../ed25519-donna/curve25519-donna-32bit.h | 53 + .../ed25519-donna/curve25519-donna-helpers.c | 66 + .../ed25519-donna/curve25519-donna-helpers.h | 22 + .../curve25519-donna-scalarmult-base.c | 67 + .../curve25519-donna-scalarmult-base.h | 8 + .../ed25519-donna-32bit-tables.c | 63 + .../ed25519-donna-32bit-tables.h | 17 + .../ed25519-donna-basepoint-table.c | 261 + .../ed25519-donna-basepoint-table.h | 2 + .../ed25519-donna/ed25519-donna-impl-base.c | 454 ++ .../ed25519-donna/ed25519-donna-impl-base.h | 60 + .../ed25519-donna/ed25519-donna-portable.h | 26 + .../ed25519-donna/ed25519-donna.h | 47 + .../ed25519-hash-custom-keccak.h | 23 + .../ed25519-donna/ed25519-hash-custom-sha3.h | 23 + .../ed25519-donna/ed25519-hash-custom.h | 23 + .../ed25519-donna/ed25519-keccak.c | 8 + .../ed25519-donna/ed25519-keccak.h | 21 + .../ed25519-donna/ed25519-sha3.c | 8 + .../ed25519-donna/ed25519-sha3.h | 21 + .../trezor-crypto/ed25519-donna/ed25519.c | 253 + .../trezor-crypto/ed25519-donna/ed25519.h | 40 + .../ed25519-donna/modm-donna-32bit.c | 358 + .../ed25519-donna/modm-donna-32bit.h | 45 + .../vendor/trezor-crypto/gui/.gitignore | 4 + .../firmware/vendor/trezor-crypto/gui/gui.pro | 32 + .../vendor/trezor-crypto/gui/main.cpp | 10 + .../vendor/trezor-crypto/gui/mainwindow.cpp | 78 + .../vendor/trezor-crypto/gui/mainwindow.h | 27 + .../vendor/trezor-crypto/gui/mainwindow.ui | 161 + .../firmware/vendor/trezor-crypto/hasher.c | 75 + .../firmware/vendor/trezor-crypto/hasher.h | 56 + .../firmware/vendor/trezor-crypto/hmac.c | 178 + .../firmware/vendor/trezor-crypto/hmac.h | 52 + .../firmware/vendor/trezor-crypto/memzero.c | 6 + .../firmware/vendor/trezor-crypto/memzero.h | 8 + .../firmware/vendor/trezor-crypto/nem.c | 617 ++ .../firmware/vendor/trezor-crypto/nem.h | 191 + .../vendor/trezor-crypto/nem_serialize.h | 23 + .../firmware/vendor/trezor-crypto/nist256p1.c | 62 + .../firmware/vendor/trezor-crypto/nist256p1.h | 35 + .../vendor/trezor-crypto/nist256p1.table | 1664 ++++ .../firmware/vendor/trezor-crypto/options.h | 84 + .../firmware/vendor/trezor-crypto/pbkdf2.c | 147 + .../firmware/vendor/trezor-crypto/pbkdf2.h | 56 + .../firmware/vendor/trezor-crypto/rand.c | 88 + .../firmware/vendor/trezor-crypto/rand.h | 35 + .../firmware/vendor/trezor-crypto/rc4.c | 56 + .../firmware/vendor/trezor-crypto/rc4.h | 37 + .../firmware/vendor/trezor-crypto/rfc6979.c | 78 + .../firmware/vendor/trezor-crypto/rfc6979.h | 40 + .../firmware/vendor/trezor-crypto/ripemd160.c | 343 + .../firmware/vendor/trezor-crypto/ripemd160.h | 20 + .../firmware/vendor/trezor-crypto/script.c | 64 + .../firmware/vendor/trezor-crypto/script.h | 30 + .../firmware/vendor/trezor-crypto/secp256k1.c | 68 + .../firmware/vendor/trezor-crypto/secp256k1.h | 36 + .../vendor/trezor-crypto/secp256k1.table | 1664 ++++ .../vendor/trezor-crypto/segwit_addr.c | 191 + .../vendor/trezor-crypto/segwit_addr.h | 101 + .../firmware/vendor/trezor-crypto/setup.py | 37 + .../firmware/vendor/trezor-crypto/sha2.c | 1319 +++ .../firmware/vendor/trezor-crypto/sha2.h | 116 + .../firmware/vendor/trezor-crypto/sha3.c | 397 + .../firmware/vendor/trezor-crypto/sha3.h | 89 + .../vendor/trezor-crypto/test_check.c | 4633 +++++++++++ .../vendor/trezor-crypto/test_curves.py | 438 + .../vendor/trezor-crypto/test_openssl.c | 155 + .../vendor/trezor-crypto/test_segwit.c | 190 + .../vendor/trezor-crypto/test_speed.c | 215 + .../vendor/trezor-crypto/tools/.gitignore | 3 + .../vendor/trezor-crypto/tools/README.md | 54 + .../trezor-crypto/tools/bip39bruteforce.c | 87 + .../vendor/trezor-crypto/tools/mktable.c | 68 + .../trezor-crypto/tools/nem_test_vectors.erb | 18 + .../trezor-crypto/tools/nem_test_vectors.rb | 126 + .../vendor/trezor-crypto/tools/xpubaddrgen.c | 47 + .../firmware/vendor/trezor-qrenc/.gitignore | 4 + .../firmware/vendor/trezor-qrenc/.travis.yml | 23 + .../firmware/vendor/trezor-qrenc/AUTHORS | 3 + .../firmware/vendor/trezor-qrenc/LICENSE | 23 + .../firmware/vendor/trezor-qrenc/Makefile | 50 + .../firmware/vendor/trezor-qrenc/README.md | 13 + .../firmware/vendor/trezor-qrenc/bower.json | 34 + .../vendor/trezor-qrenc/compiled/example.html | 25 + .../vendor/trezor-qrenc/compiled/qr.js | 473 ++ .../trezor-qrenc/compiled/test_arg.js.mem | Bin 0 -> 57520 bytes .../firmware/vendor/trezor-qrenc/qr.js.foot | 4 + .../firmware/vendor/trezor-qrenc/qr.js.head | 453 ++ .../firmware/vendor/trezor-qrenc/qr_consts.h | 136 + .../firmware/vendor/trezor-qrenc/qr_encode.c | 1085 +++ .../firmware/vendor/trezor-qrenc/qr_encode.h | 87 + .../firmware/vendor/trezor-qrenc/test.c | 61 + .../firmware/vendor/trezor-qrenc/test_arg.c | 61 + .../firmware/vendor/trezor-qrenc/tests.c | 158 + .../vendor/trezor-qrenc/tests_results.h | 16 + .../firmware/visual_firmware.code-workspace | 20 + 1600 files changed, 234587 insertions(+) create mode 100644 hardware-wallet/firmware/.gitignore create mode 100644 hardware-wallet/firmware/.gitmodules create mode 100644 hardware-wallet/firmware/.travis.yml create mode 100644 hardware-wallet/firmware/COPYING create mode 100644 hardware-wallet/firmware/Dockerfile create mode 100644 hardware-wallet/firmware/Dockerfile.emulator create mode 100644 hardware-wallet/firmware/Makefile create mode 100644 hardware-wallet/firmware/Makefile.include create mode 100644 hardware-wallet/firmware/README.md create mode 100644 hardware-wallet/firmware/bootloader/.gitignore create mode 100644 hardware-wallet/firmware/bootloader/ChangeLog create mode 100644 hardware-wallet/firmware/bootloader/Makefile create mode 100644 hardware-wallet/firmware/bootloader/bootloader.c create mode 100644 hardware-wallet/firmware/bootloader/bootloader.h create mode 100755 hardware-wallet/firmware/bootloader/combine/prepare.py create mode 100755 hardware-wallet/firmware/bootloader/combine/write.sh create mode 100755 hardware-wallet/firmware/bootloader/firmware_align.py create mode 100755 hardware-wallet/firmware/bootloader/firmware_sign.py create mode 100755 hardware-wallet/firmware/bootloader/firmware_sign_split.py create mode 100644 hardware-wallet/firmware/bootloader/signatures.c create mode 100644 hardware-wallet/firmware/bootloader/signatures.h create mode 100644 hardware-wallet/firmware/bootloader/usb.c create mode 100644 hardware-wallet/firmware/bootloader/usb.h create mode 100755 hardware-wallet/firmware/build-bootloader.sh create mode 100755 hardware-wallet/firmware/build-emulator.sh create mode 100755 hardware-wallet/firmware/build-firmware.sh create mode 100644 hardware-wallet/firmware/buttons.c create mode 100644 hardware-wallet/firmware/buttons.h create mode 100644 hardware-wallet/firmware/demo/Makefile create mode 100644 hardware-wallet/firmware/demo/demo.c create mode 100644 hardware-wallet/firmware/emulator/Makefile create mode 100644 hardware-wallet/firmware/emulator/buttons.c create mode 100644 hardware-wallet/firmware/emulator/emulator.h create mode 100644 hardware-wallet/firmware/emulator/flash.c create mode 100644 hardware-wallet/firmware/emulator/oled.c create mode 100644 hardware-wallet/firmware/emulator/rng.c create mode 100644 hardware-wallet/firmware/emulator/setup.c create mode 100644 hardware-wallet/firmware/emulator/strl.c create mode 100644 hardware-wallet/firmware/emulator/strl.h create mode 100644 hardware-wallet/firmware/emulator/timer.c create mode 100644 hardware-wallet/firmware/emulator/udp.c create mode 100644 hardware-wallet/firmware/fastflash/Makefile create mode 120000 hardware-wallet/firmware/fastflash/bootloader.c create mode 100644 hardware-wallet/firmware/fastflash/signatures.c create mode 120000 hardware-wallet/firmware/fastflash/usb.c create mode 100644 hardware-wallet/firmware/firmware/.gitignore create mode 100644 hardware-wallet/firmware/firmware/ChangeLog create mode 100644 hardware-wallet/firmware/firmware/Makefile create mode 100755 hardware-wallet/firmware/firmware/coins-gen.py create mode 100644 hardware-wallet/firmware/firmware/coins.c create mode 100644 hardware-wallet/firmware/firmware/coins.h create mode 120000 hardware-wallet/firmware/firmware/coins.json create mode 100644 hardware-wallet/firmware/firmware/crypto.c create mode 100644 hardware-wallet/firmware/firmware/crypto.h create mode 100644 hardware-wallet/firmware/firmware/debug.c create mode 100644 hardware-wallet/firmware/firmware/debug.h create mode 100644 hardware-wallet/firmware/firmware/ethereum.c create mode 100644 hardware-wallet/firmware/firmware/ethereum.h create mode 100644 hardware-wallet/firmware/firmware/ethereum_tokens.c create mode 100644 hardware-wallet/firmware/firmware/ethereum_tokens.h create mode 100644 hardware-wallet/firmware/firmware/fastflash.c create mode 100644 hardware-wallet/firmware/firmware/fastflash.h create mode 100644 hardware-wallet/firmware/firmware/fsm.c create mode 100644 hardware-wallet/firmware/firmware/fsm.h create mode 100644 hardware-wallet/firmware/firmware/gettext.h create mode 100644 hardware-wallet/firmware/firmware/layout2.c create mode 100644 hardware-wallet/firmware/firmware/layout2.h create mode 100644 hardware-wallet/firmware/firmware/messages.c create mode 100644 hardware-wallet/firmware/firmware/messages.h create mode 100644 hardware-wallet/firmware/firmware/nem2.c create mode 100644 hardware-wallet/firmware/firmware/nem2.h create mode 100644 hardware-wallet/firmware/firmware/nem_mosaics.json create mode 100755 hardware-wallet/firmware/firmware/nem_mosaics.py create mode 100644 hardware-wallet/firmware/firmware/pinmatrix.c create mode 100644 hardware-wallet/firmware/firmware/pinmatrix.h create mode 100644 hardware-wallet/firmware/firmware/protect.c create mode 100644 hardware-wallet/firmware/firmware/protect.h create mode 100644 hardware-wallet/firmware/firmware/protob/.gitignore create mode 100644 hardware-wallet/firmware/firmware/protob/Makefile create mode 100644 hardware-wallet/firmware/firmware/protob/messages.options create mode 120000 hardware-wallet/firmware/firmware/protob/messages.proto create mode 100755 hardware-wallet/firmware/firmware/protob/messages_map.py create mode 100644 hardware-wallet/firmware/firmware/protob/types.options create mode 120000 hardware-wallet/firmware/firmware/protob/types.proto create mode 100644 hardware-wallet/firmware/firmware/recovery-table.h create mode 100644 hardware-wallet/firmware/firmware/recovery.c create mode 100644 hardware-wallet/firmware/firmware/recovery.h create mode 100644 hardware-wallet/firmware/firmware/reset.c create mode 100644 hardware-wallet/firmware/firmware/reset.h create mode 100644 hardware-wallet/firmware/firmware/signing.c create mode 100644 hardware-wallet/firmware/firmware/signing.h create mode 100644 hardware-wallet/firmware/firmware/storage.c create mode 100644 hardware-wallet/firmware/firmware/storage.h create mode 100644 hardware-wallet/firmware/firmware/transaction.c create mode 100644 hardware-wallet/firmware/firmware/transaction.h create mode 100644 hardware-wallet/firmware/firmware/trezor.c create mode 100644 hardware-wallet/firmware/firmware/trezor.h create mode 100644 hardware-wallet/firmware/firmware/u2f.c create mode 100644 hardware-wallet/firmware/firmware/u2f.h create mode 100755 hardware-wallet/firmware/firmware/u2f/genkeys.sh create mode 100644 hardware-wallet/firmware/firmware/u2f/trezordevkey.pem create mode 100644 hardware-wallet/firmware/firmware/u2f/u2f.h create mode 100644 hardware-wallet/firmware/firmware/u2f/u2f_hid.h create mode 100644 hardware-wallet/firmware/firmware/u2f/u2f_keys.h create mode 100644 hardware-wallet/firmware/firmware/u2f_knownapps.h create mode 100644 hardware-wallet/firmware/firmware/udp.c create mode 100644 hardware-wallet/firmware/firmware/usb.c create mode 100644 hardware-wallet/firmware/firmware/usb.h create mode 100644 hardware-wallet/firmware/gen/Makefile create mode 100644 hardware-wallet/firmware/gen/bitmaps.c create mode 100644 hardware-wallet/firmware/gen/bitmaps.h create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit0.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit1.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit2.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit3.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit4.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit5.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit6.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit7.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit8.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/digit9.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/gears0.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/gears1.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/gears2.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/gears3.png create mode 100755 hardware-wallet/firmware/gen/bitmaps/generate.py create mode 100644 hardware-wallet/firmware/gen/bitmaps/icon_error.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/icon_info.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/icon_ok.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/icon_question.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/icon_warning.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/logo48.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/logo48_empty.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/logo64.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/logo64_empty.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_bitbucket.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_bitfinex.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_dropbox.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_fastmail.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_gandi.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_github.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_gitlab.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_google.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_slushpool.png create mode 100644 hardware-wallet/firmware/gen/bitmaps/u2f_yubico.png create mode 100644 hardware-wallet/firmware/gen/font.inc create mode 100644 hardware-wallet/firmware/gen/fontfixed.inc create mode 100644 hardware-wallet/firmware/gen/fonts.c create mode 100644 hardware-wallet/firmware/gen/fonts.h create mode 100644 hardware-wallet/firmware/gen/fonts/font.png create mode 100644 hardware-wallet/firmware/gen/fonts/fontfixed.png create mode 100755 hardware-wallet/firmware/gen/fonts/generate.py create mode 100755 hardware-wallet/firmware/gen/handlers/handlers.py create mode 100644 hardware-wallet/firmware/gen/strwidth.c create mode 100644 hardware-wallet/firmware/gen/wordlist/build-recovery-table.pl create mode 100644 hardware-wallet/firmware/gen/wordlist/recovery_english.txt create mode 100644 hardware-wallet/firmware/gitian/gitian.yml create mode 100644 hardware-wallet/firmware/layout.c create mode 100644 hardware-wallet/firmware/layout.h create mode 100755 hardware-wallet/firmware/make-firmware.sh create mode 100644 hardware-wallet/firmware/memory.c create mode 100644 hardware-wallet/firmware/memory.h create mode 100644 hardware-wallet/firmware/memory.ld create mode 100644 hardware-wallet/firmware/memory_app_0.0.0.ld create mode 100644 hardware-wallet/firmware/memory_app_1.0.0.ld create mode 100644 hardware-wallet/firmware/memory_app_fastflash.ld create mode 100644 hardware-wallet/firmware/oled.c create mode 100644 hardware-wallet/firmware/oled.h create mode 100644 hardware-wallet/firmware/rng.c create mode 100644 hardware-wallet/firmware/rng.h create mode 100755 hardware-wallet/firmware/script/bootstrap create mode 100755 hardware-wallet/firmware/script/cibuild create mode 100755 hardware-wallet/firmware/script/setup create mode 100755 hardware-wallet/firmware/script/test create mode 100644 hardware-wallet/firmware/serialno.c create mode 100644 hardware-wallet/firmware/serialno.h create mode 100644 hardware-wallet/firmware/setup.c create mode 100644 hardware-wallet/firmware/setup.h create mode 100644 hardware-wallet/firmware/startup.s create mode 100644 hardware-wallet/firmware/timer.c create mode 100644 hardware-wallet/firmware/timer.h create mode 100644 hardware-wallet/firmware/usb21_standard.c create mode 100644 hardware-wallet/firmware/usb21_standard.h create mode 100644 hardware-wallet/firmware/util.c create mode 100644 hardware-wallet/firmware/util.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/.gitignore create mode 100644 hardware-wallet/firmware/vendor/libopencm3/COPYING.GPL3 create mode 100644 hardware-wallet/firmware/vendor/libopencm3/COPYING.LGPL3 create mode 100644 hardware-wallet/firmware/vendor/libopencm3/HACKING create mode 100644 hardware-wallet/firmware/vendor/libopencm3/HACKING_COMMON_DOC create mode 100644 hardware-wallet/firmware/vendor/libopencm3/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/README.md create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile_common create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/DoxygenLayout.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/HACKING create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/README create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/cm3/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/cm3/DoxygenLayout_cm3.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/DoxygenLayout_efm32g.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/header_efm32g.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/DoxygenLayout_efm32gg.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/header_efm32gg.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/DoxygenLayout_efm32lg.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/header_efm32lg.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/DoxygenLayout_efm32tg.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/header_efm32tg.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/DoxygenLayout_lm3s.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/header_lm3s.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/DoxygenLayout_lm4f.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/header_lm4f.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/DoxygenLayout_lpc13xx.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/header_lpc13xx.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/DoxygenLayout_lpc17xx.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/header_lpc17xx.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/DoxygenLayout_lpc43xx.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/header_lpc43xx.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/DoxygenLayout_sam3a.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/header_sam3a.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/DoxygenLayout_sam3n.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/header_sam3a.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/DoxygenLayout_sam3s.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/header_sam3a.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/DoxygenLayout_sam3u.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/header_sam3a.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/DoxygenLayout_sam3x.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/header_sam3a.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/DoxygenLayout_stm32f0.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/header_stm32f0.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/DoxygenLayout_stm32f1.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/header_stm32f1.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/DoxygenLayout_stm32f2.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/header_stm32f2.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/DoxygenLayout_stm32f3.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/header_stm32f3.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/DoxygenLayout_stm32f4.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/header_stm32f4.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/DoxygenLayout_stm32f7.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/header_stm32f7.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/DoxygenLayout_stm32l0.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/header_stm32l0.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/DoxygenLayout_stm32l1.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/header_stm32l1.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/DoxygenLayout_stm32l4.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/header_stm32l4.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/usb/DoxygenLayout_usb.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/usb/header_usb.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile_latex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/DoxygenLayout_vf6xx.xml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/header_vf6xx.tex create mode 100644 hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/index.html create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/assert.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/common.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/cortex.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/doc-cm3.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/dwt.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/fpb.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/itm.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/mpu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scb.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/sync.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/systick.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/tpiu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/vector.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/docmain.dox create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/acmp.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/burtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/cmu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/emu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/doc-efm32g.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/doc-efm32gg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/letimer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/acmp.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/burtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/cmu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/doc-efm32lg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/emu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/letimer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/msc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/opamp.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/prs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rmu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/uart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usb.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/wdog.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/msc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/opamp.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/prs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rmu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/doc-efm32tg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/uart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usb.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/wdog.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac_stm32fxx7.h create mode 100755 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/phy.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/phy_ksz8051mll.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/license.dox create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/doc-lm3s.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/systemcontrol.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/doc-lm4f.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/ssi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/systemcontrol.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/uart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/usb.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/doc-lpc13xx.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/clock.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/doc-lpc17xx.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/atimer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ccu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/cgu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/creg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/doc-lpc43xx.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/eventrouter.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gima.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpdma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2s.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ipc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m0/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m4/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/rgu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ritimer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/scu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sdio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sgpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ssp.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/uart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/usb.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/wwdt.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/periph.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/periph.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/smc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/periph.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3a3u3x.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3n3s.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/periph_common_3a3x.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3a3u3x.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3n3s.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3s3x.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3u3x.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3n3u.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/smc_common_3a3u3x.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/port.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/eefc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/periph.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pwm.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/smc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/tc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/uart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/wdt.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/can.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/cec.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v1.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_multi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_single.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crc_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crs_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crypto_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dac_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_l1f013.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/exti_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f01.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f234.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_l01.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f234.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/hash_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v1.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v2.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/iwdg_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v1.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v2.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rcc_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rng_common_v1.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rtc_common_l1f024.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f03.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_l1f124.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_common.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v1.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v2.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/syscfg_common_l1f234.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_all.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f124.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f24.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_v2.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/comparator.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crypto.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dbgmcu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/desig.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma2d.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dsi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/cec.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/comparator.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/crc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/doc-stm32f0.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/iwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/spi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/st_usbfs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/syscfg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/tsc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/bkp.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/crc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/doc-stm32f1.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/iwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/spi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/st_usbfs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crypto.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/doc-stm32f2.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/hash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/iwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rng.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/spi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/syscfg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/crc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/doc-stm32f3.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/iwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/spi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/st_usbfs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/syscfg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crypto.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma2d.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/doc-stm32f4.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dsi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/fmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/hash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/iwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/ltdc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/quadspi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rng.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/spi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/syscfg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/doc-stm32f7.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rng.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/fsmc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/hash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/iwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/doc-stm32l0.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rng.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/st_usbfs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/syscfg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/crc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dac.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dma.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/doc-stm32l1.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/exti.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/iwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/lcd.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/ri.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/spi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/st_usbfs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/syscfg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/adc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/doc-stm32l4.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/flash.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/i2c.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rng.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/ltdc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_common.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_fs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_hs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/pwr.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/quadspi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rcc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rng.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rtc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/sdio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/spi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/st_usbfs.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/syscfg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/timer.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tools.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tsc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/usart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/wwdg.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/audio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/cdc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/dfu.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/doc-usb.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/hid.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/midi.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/msc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbd.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbstd.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/anadig.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/ccm.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/doc-vf6xx.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/gpio.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/iomuxc.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/irq.json create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/memorymap.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/uart.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/core_cm3.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/dispatch/irqhandlers.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.example create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.linker create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/README create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/devices.data create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/linker.ld.S create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.data create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.result create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.data create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.result create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.data create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.result create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.data create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.result create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.data create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.result create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.data create mode 100644 hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.result create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/Makefile.include create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/cm3/assert.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/cm3/dwt.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/cm3/nvic.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/cm3/scb.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/cm3/sync.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/cm3/systick.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/cm3/vector.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/dispatch/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g880f128.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg990f1024.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/adc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/cmu.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dma.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/libopencm3_efm32lg.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/prs.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg840f32.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac_stm32fxx7.c create mode 100755 hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy.c create mode 100755 hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy_ksz8051mll.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/libopencm3_lm3s.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/lm3s6965.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/usart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/libopencm3_lm4f.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/systemcontrol.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/uart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/libopencm3_lpc13xx.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/libopencm3_lpc17xx.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ipc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/scu.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ssp.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/uart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/libopencm3_sam3a.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/libopencm3_sam3n.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/libopencm3_sam3s.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/libopencm3_sam3u.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/libopencm3_sam3x.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3a3u3x.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3n3s.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/pmc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/usart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/libopencm3_samd.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/can.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v1.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2_multi.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crc_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crs_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crypto_common_f24.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dac_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_f24.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_l1f013.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/exti_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f01.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f234.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f24.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_l01.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_f0234.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/hash_common_f24.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v1.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v2.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/iwdg_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v1.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v2.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rcc_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rng_common_v1.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rtc_common_l1f024.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_f03.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_l1f124.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f0234.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f24.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_all.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_f124.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_v2.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/desig.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/adc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/comparator.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/crc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dma.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/iwdg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rtc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/spi.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f03xz6.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f04xz6.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz6.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz8.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xz8.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xzb.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/syscfg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/usart.c create mode 100755 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/adc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/crc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dma.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/iwdg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/libopencm3_stm32f1.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rtc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/spi.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x4.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x6.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x8.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xb.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xc.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xd.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xe.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103x8.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xb.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xc.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xd.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xe.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/usart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crypto.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dma.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/hash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/iwdg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/libopencm3_stm32f2.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rng.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rtc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/spi.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/usart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/adc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/crc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dma.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/iwdg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/libopencm3_stm32f3.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rtc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/spi.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/stm32f303xc.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/usart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/adc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crypto.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dma.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/fmc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/hash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/iwdg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/ltdc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rng.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rtc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/spi.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/stm32f405x6.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/usart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/libopencm3_stm32f7.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/libopencm3_stm32l0.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rng.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx6.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx8.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/adc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/crc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dac.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dma.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/iwdg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/lcd.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/libopencm3_stm32l1.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rtc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/spi.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l100xc.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx6.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx8.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxb.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxc.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxd.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/timer.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/usart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/adc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/flash.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/i2c.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/libopencm3_stm32l4.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/pwr.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/rcc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v1.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v2.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_control.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_efm32lg.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f107.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f207.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_lm4f.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_msc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_private.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_standard.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/Makefile create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/ccm.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/gpio.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/iomuxc.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/libopencm3_vf6xx.ld create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/uart.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/vector_chipset.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/locm3.sublime-project create mode 100644 hardware-wallet/firmware/vendor/libopencm3/mk/README create mode 100644 hardware-wallet/firmware/vendor/libopencm3/mk/gcc-config.mk create mode 100644 hardware-wallet/firmware/vendor/libopencm3/mk/gcc-rules.mk create mode 100644 hardware-wallet/firmware/vendor/libopencm3/mk/genlink-config.mk create mode 100644 hardware-wallet/firmware/vendor/libopencm3/mk/genlink-rules.mk create mode 100755 hardware-wallet/firmware/vendor/libopencm3/scripts/checkpatch.pl create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/README create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/adc.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/atimer.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ccu.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/cgu.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/creg.yaml create mode 100755 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/csv2yaml.py create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/eventrouter.yaml create mode 100755 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gen.py create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gima.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpdma.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpio.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2c.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2s.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/rgu.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ritimer.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/scu.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/sgpio.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ssp.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/usb.yaml create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/yaml_odict.py create mode 100644 hardware-wallet/firmware/vendor/libopencm3/scripts/genlink.awk create mode 100755 hardware-wallet/firmware/vendor/libopencm3/scripts/genlinktest.sh create mode 100755 hardware-wallet/firmware/vendor/libopencm3/scripts/irq2nvic_h create mode 100755 hardware-wallet/firmware/vendor/libopencm3/scripts/lpcvtcksum create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/.gitignore create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f072disco create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f103-generic create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f429i-disco create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f4disco create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l053disco create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l1-generic create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/README.md create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f072disco.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f103-generic.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f429i-disco.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f4disco.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l053disco.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l1-generic.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.common.cfg create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f072disco.cfg create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f103-generic.cfg create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f429i-disco.cfg create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f4disco.cfg create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l053disco.cfg create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l1-generic.cfg create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/stub.py create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/test_gadget0.py create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/rules.mk create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace.c create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace.h create mode 100644 hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace_stdio.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/.gitignore create mode 100644 hardware-wallet/firmware/vendor/nanopb/.travis.yml create mode 100644 hardware-wallet/firmware/vendor/nanopb/AUTHORS.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/BUILD create mode 100644 hardware-wallet/firmware/vendor/nanopb/CHANGELOG.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/CMakeLists.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/CONTRIBUTING.md create mode 100644 hardware-wallet/firmware/vendor/nanopb/LICENSE.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/README.md create mode 100644 hardware-wallet/firmware/vendor/nanopb/WORKSPACE create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/Makefile create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/concepts.rst create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/generator_flow.svg create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/index.rst create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/logo/logo.png create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/logo/logo.svg create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/logo/logo16px.png create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/logo/logo48px.png create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/lsr.css create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/menu.rst create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/migration.rst create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/reference.rst create mode 100644 hardware-wallet/firmware/vendor/nanopb/docs/security.rst create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/CMakeLists.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/README.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/simple.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/sub/unlucky.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/simple.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/CMakeLists.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/README.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/Makefile create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/README.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/client.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/network_server/server.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/simple/Makefile create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/simple/README.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/Makefile create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/README.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/decode_double.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/doubleproto.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/encode_double.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/test_conversions.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/Makefile create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/README.txt create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/decode.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/encode.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/unionproto.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/extra/FindNanopb.cmake create mode 100644 hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config-version.cmake.in create mode 100644 hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config.cmake create mode 100644 hardware-wallet/firmware/vendor/nanopb/extra/nanopb.mk create mode 100644 hardware-wallet/firmware/vendor/nanopb/extra/pb_syshdr.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/generator/nanopb/options.proto create mode 100755 hardware-wallet/firmware/vendor/nanopb/generator/nanopb_generator.py create mode 100644 hardware-wallet/firmware/vendor/nanopb/generator/proto/Makefile create mode 100644 hardware-wallet/firmware/vendor/nanopb/generator/proto/__init__.py create mode 100644 hardware-wallet/firmware/vendor/nanopb/generator/proto/google/protobuf/descriptor.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/generator/proto/nanopb.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/generator/proto/plugin.proto create mode 100755 hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb create mode 100644 hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb.bat create mode 100644 hardware-wallet/firmware/vendor/nanopb/library.json create mode 100644 hardware-wallet/firmware/vendor/nanopb/pb.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/pb_common.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/pb_common.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/pb_decode.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/pb_decode.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/pb_encode.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/pb_encode.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/Makefile create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/SConstruct create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes/decode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes/encode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/decode_alltypes_callback.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/encode_alltypes_callback.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/decode_alltypes_pointer.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/encode_alltypes_pointer.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/decode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/encode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/decode_alltypes_callback.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/encode_alltypes_callback.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/decode_oneof.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/oneof.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/decode_legacy.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/encode_legacy.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/decode_buffer.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/encode_buffer.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/decode_stream.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/encode_stream.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/buffer_only/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/callbacks/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/callbacks/callbacks.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/callbacks/decode_callbacks.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/callbacks/encode_callbacks.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers_syshdr.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/person.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/test_helpers.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/unittestproto.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/common/unittests.h create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/cxx_main_program/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic_callback.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/encode_cyclic_callback.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/decode_unittests.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/encode_unittests.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes_unittests.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum_to_string.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/extensions/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/extensions/decode_extensions.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/extensions/encode_extensions.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/person_with_extra_field.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/decode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/encode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_pointer.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_static.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzzstub.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzztest.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/generate_message.c create mode 100755 hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/run_radamsa.sh create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/inline/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/inline/inline_unittests.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/intsizes/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes_unittests.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/io_errors/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/io_errors/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/io_errors/io_errors.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/mem_release/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/dummy.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages1.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages2.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile2.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/subdir/multifile2.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/test_multiple_files.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/no_errmsg/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/no_messages/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/no_messages/no_messages.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/oneof/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/oneof/decode_oneof.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/oneof/encode_oneof.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/oneof/oneof.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/options/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/options/options.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/options/options.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/package_name/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumdef.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumuse.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enum_encoded_size.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enums.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/msg_size.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/test.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/oneof.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.expected create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file1.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file2.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_init.py create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_tools/nanopb.py create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/special_characters/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/special_characters/funny-proto+name has.characters.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/splint/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/splint/splint.rc create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/SConscript create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.options create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.proto create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/decode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/encode_alltypes.c create mode 100644 hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/no_64bit_syshdr.h create mode 100755 hardware-wallet/firmware/vendor/nanopb/tools/make_linux_package.sh create mode 100755 hardware-wallet/firmware/vendor/nanopb/tools/make_mac_package.sh create mode 100755 hardware-wallet/firmware/vendor/nanopb/tools/make_windows_package.sh create mode 100755 hardware-wallet/firmware/vendor/nanopb/tools/set_version.sh create mode 160000 hardware-wallet/firmware/vendor/skycoin-crypto create mode 100644 hardware-wallet/firmware/vendor/trezor-common/.travis.yml create mode 100644 hardware-wallet/firmware/vendor/trezor-common/COPYING create mode 100644 hardware-wallet/firmware/vendor/trezor-common/README.md create mode 100755 hardware-wallet/firmware/vendor/trezor-common/coins-check.py create mode 100644 hardware-wallet/firmware/vendor/trezor-common/coins.json create mode 100755 hardware-wallet/firmware/vendor/trezor-common/ethereum_tokens-gen.py create mode 100644 hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.h create mode 100644 hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.pem create mode 100644 hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.txt create mode 100644 hardware-wallet/firmware/vendor/trezor-common/keys/sample.h create mode 100644 hardware-wallet/firmware/vendor/trezor-common/keys/sample.pem create mode 100644 hardware-wallet/firmware/vendor/trezor-common/keys/sample.txt create mode 100644 hardware-wallet/firmware/vendor/trezor-common/protob/.gitignore create mode 100644 hardware-wallet/firmware/vendor/trezor-common/protob/Makefile create mode 100644 hardware-wallet/firmware/vendor/trezor-common/protob/config.proto create mode 100644 hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto create mode 100644 hardware-wallet/firmware/vendor/trezor-common/protob/protocol.md create mode 100644 hardware-wallet/firmware/vendor/trezor-common/protob/storage.proto create mode 100644 hardware-wallet/firmware/vendor/trezor-common/protob/types.proto create mode 100644 hardware-wallet/firmware/vendor/trezor-common/signer/.gitignore create mode 100644 hardware-wallet/firmware/vendor/trezor-common/signer/config.json create mode 100644 hardware-wallet/firmware/vendor/trezor-common/signer/sample.key create mode 100755 hardware-wallet/firmware/vendor/trezor-common/signer/sign.py create mode 100644 hardware-wallet/firmware/vendor/trezor-common/udev/51-trezor.rules create mode 100644 hardware-wallet/firmware/vendor/trezor-common/udev/dist/.gitignore create mode 100644 hardware-wallet/firmware/vendor/trezor-common/udev/dist/Dockerfile create mode 100644 hardware-wallet/firmware/vendor/trezor-common/udev/dist/Makefile create mode 100755 hardware-wallet/firmware/vendor/trezor-common/udev/dist/release.sh create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/.gitignore create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/.travis.yml create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/AUTHORS create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/CMakeLists.txt create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/CONTRIBUTORS create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/LICENSE create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/Makefile create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/README.md create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/address.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/address.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aes.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aes_modes.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aescrypt.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aeskey.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aesopt.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/aes/brg_types.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/base32.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/base32.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/base58.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/base58.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/bignum.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/bignum.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/bip32.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/bip32.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/bip39.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/bip39.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/bip39_english.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/blake256.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/blake256.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/blake2_common.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/blake2b.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/blake2b.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/blake2s.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/blake2s.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha_merged.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-config.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-machine.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-portable.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-sync.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna-32.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/check_mem.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/curves.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/curves.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/README.md create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-portable.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-keccak.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-sha3.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/gui/.gitignore create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/gui/gui.pro create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/gui/main.cpp create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.cpp create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.ui create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/hasher.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/hasher.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/hmac.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/hmac.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/memzero.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/memzero.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/nem.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/nem.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/nem_serialize.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.table create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/options.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/rand.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/rand.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/rc4.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/rc4.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/script.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/script.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.table create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.h create mode 100755 hardware-wallet/firmware/vendor/trezor-crypto/setup.py create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/sha2.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/sha2.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/sha3.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/sha3.h create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/test_check.c create mode 100755 hardware-wallet/firmware/vendor/trezor-crypto/test_curves.py create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/test_openssl.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/test_segwit.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/test_speed.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/tools/.gitignore create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/tools/README.md create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/tools/bip39bruteforce.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/tools/mktable.c create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.erb create mode 100755 hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.rb create mode 100644 hardware-wallet/firmware/vendor/trezor-crypto/tools/xpubaddrgen.c create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/.gitignore create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/.travis.yml create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/AUTHORS create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/LICENSE create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/Makefile create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/README.md create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/bower.json create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/compiled/example.html create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/compiled/qr.js create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/compiled/test_arg.js.mem create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/qr.js.foot create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/qr.js.head create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/qr_consts.h create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.c create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.h create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/test.c create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/test_arg.c create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/tests.c create mode 100644 hardware-wallet/firmware/vendor/trezor-qrenc/tests_results.h create mode 100644 hardware-wallet/firmware/visual_firmware.code-workspace diff --git a/hardware-wallet/firmware/.gitignore b/hardware-wallet/firmware/.gitignore new file mode 100644 index 00000000..ddd05a19 --- /dev/null +++ b/hardware-wallet/firmware/.gitignore @@ -0,0 +1,14 @@ +.cache/ +.vscode/ +_attic/ +build/ +*.o +*.a +*.d +*.bin +*.elf +*.hex +*.img +*.list +*.srec +*.log diff --git a/hardware-wallet/firmware/.gitmodules b/hardware-wallet/firmware/.gitmodules new file mode 100644 index 00000000..a745a710 --- /dev/null +++ b/hardware-wallet/firmware/.gitmodules @@ -0,0 +1,18 @@ +[submodule "trezor-crypto"] + path = vendor/trezor-crypto + url = https://github.com/trezor/trezor-crypto.git +[submodule "trezor-common"] + path = vendor/trezor-common + url = https://github.com/mpsido/trezor-common.git +[submodule "trezor-qrenc"] + path = vendor/trezor-qrenc + url = https://github.com/trezor/trezor-qrenc.git +[submodule "libopencm3"] + path = vendor/libopencm3 + url = https://github.com/libopencm3/libopencm3.git +[submodule "vendor/nanopb"] + path = vendor/nanopb + url = https://github.com/nanopb/nanopb.git +[submodule "skycoin-crypto"] + path = vendor/skycoin-crypto + url = https://github.com/mpsido/skycoin-crypto.git diff --git a/hardware-wallet/firmware/.travis.yml b/hardware-wallet/firmware/.travis.yml new file mode 100644 index 00000000..89fd55be --- /dev/null +++ b/hardware-wallet/firmware/.travis.yml @@ -0,0 +1,60 @@ +sudo: false +dist: trusty +language: c + +addons: + apt: + packages: + - build-essential + - gcc-arm-none-eabi + - libnewlib-arm-none-eabi + - python3-pip + +env: + global: + - MAKEFLAGS=-j2 + - PYTHON=python3 + - PROTOBUF_VERSION=3.4.0 + matrix: + - DEBUG_LINK=0 FASTFLASH=0 + - DEBUG_LINK=1 FASTFLASH=0 + - DEBUG_LINK=0 FASTFLASH=1 + - DEBUG_LINK=1 FASTFLASH=1 + +matrix: + include: + - addons: + apt: + packages: + - gcc-multilib + - python3-pip + env: + - EMULATOR=1 HEADLESS=1 + - DEBUG_LINK=1 + before_script: + - $PYTHON -m pip install --user pytest + - $PYTHON -m pip install --user ecdsa mnemonic + - $PYTHON -m pip install --user rlp + - $PYTHON -m pip install --user --no-deps git+https://github.com/trezor/python-trezor@master + script: + - script/cibuild + - script/test -k 'not skip_t1' + +install: + - curl -LO "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" + - unzip "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -d protoc + - export PATH="$(pwd)/protoc/bin:$PATH" + - $PYTHON -m pip install --user "protobuf==${PROTOBUF_VERSION}" + +script: + - script/cibuild + - make -C bootloader + - make -C demo + +notifications: + webhooks: + urls: + - http://ci-bot.satoshilabs.com:5000/travis + on_success: always + on_failure: always + on_start: always diff --git a/hardware-wallet/firmware/COPYING b/hardware-wallet/firmware/COPYING new file mode 100644 index 00000000..65c5ca88 --- /dev/null +++ b/hardware-wallet/firmware/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/hardware-wallet/firmware/Dockerfile b/hardware-wallet/firmware/Dockerfile new file mode 100644 index 00000000..4debc36f --- /dev/null +++ b/hardware-wallet/firmware/Dockerfile @@ -0,0 +1,16 @@ +# initialize from the image + +FROM debian:9 + +# install build tools and dependencies + +RUN apt-get update && \ + apt-get install -y \ + build-essential curl unzip git python3 python3-pip gcc-arm-none-eabi libnewlib-arm-none-eabi + +ENV PROTOBUF_VERSION=3.4.0 +RUN curl -LO "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" +RUN unzip "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -d /usr +RUN pip3 install "protobuf==${PROTOBUF_VERSION}" ecdsa + +RUN ln -s python3 /usr/bin/python diff --git a/hardware-wallet/firmware/Dockerfile.emulator b/hardware-wallet/firmware/Dockerfile.emulator new file mode 100644 index 00000000..90fe6817 --- /dev/null +++ b/hardware-wallet/firmware/Dockerfile.emulator @@ -0,0 +1,18 @@ +# initialize from the image + +FROM debian:9 + +# install build tools and dependencies + +RUN dpkg --add-architecture i386 && \ + apt-get update && \ + apt-get install -y \ + build-essential curl unzip git python3 python3-pip \ + libsdl2-dev:i386 libsdl2-image-dev:i386 gcc-multilib + +ENV PROTOBUF_VERSION=3.4.0 +RUN curl -LO "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" +RUN unzip "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -d /usr +RUN pip3 install "protobuf==${PROTOBUF_VERSION}" ecdsa + +RUN ln -s python3 /usr/bin/python diff --git a/hardware-wallet/firmware/Makefile b/hardware-wallet/firmware/Makefile new file mode 100644 index 00000000..81d418d9 --- /dev/null +++ b/hardware-wallet/firmware/Makefile @@ -0,0 +1,33 @@ +ifneq ($(EMULATOR),1) +OBJS += startup.o +endif + +OBJS += buttons.o +OBJS += layout.o +OBJS += oled.o +OBJS += rng.o +OBJS += serialno.o + +ifneq ($(EMULATOR),1) +OBJS += setup.o +endif + +OBJS += util.o +OBJS += memory.o + +ifneq ($(EMULATOR),1) +OBJS += timer.o +endif + +OBJS += gen/bitmaps.o +OBJS += gen/fonts.o + +libtrezor.a: $(OBJS) + $(AR) rcs libtrezor.a $(OBJS) + +include Makefile.include + +.PHONY: vendor + +vendor: + git submodule update --init diff --git a/hardware-wallet/firmware/Makefile.include b/hardware-wallet/firmware/Makefile.include new file mode 100644 index 00000000..eededf5d --- /dev/null +++ b/hardware-wallet/firmware/Makefile.include @@ -0,0 +1,196 @@ +TOP_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +TOOLCHAIN_DIR ?= $(TOP_DIR)vendor/libopencm3 + +PYTHON ?= python + +ifeq ($(EMULATOR),1) +CC ?= gcc +LD := $(CC) +OBJCOPY := objcopy +OBJDUMP := objdump +AR := ar +AS := as + +OPTFLAGS ?= -O3 +DBGFLAGS ?= -g3 -ggdb3 +CPUFLAGS ?= -m32 +FPUFLAGS ?= +else +PREFIX ?= arm-none-eabi- +CC := $(PREFIX)gcc +LD := $(PREFIX)gcc +OBJCOPY := $(PREFIX)objcopy +OBJDUMP := $(PREFIX)objdump +AR := $(PREFIX)ar +AS := $(PREFIX)as +OPENOCD := openocd -f interface/stlink-v2.cfg -c "transport select hla_swd" -f target/stm32f2x.cfg + +OPTFLAGS ?= -O3 +DBGFLAGS ?= -g -DNDEBUG +CPUFLAGS ?= -mcpu=cortex-m3 -mthumb +FPUFLAGS ?= -msoft-float +endif + +CFLAGS += $(OPTFLAGS) \ + $(DBGFLAGS) \ + -std=gnu99 \ + -W \ + -Wall \ + -Wextra \ + -Wimplicit-function-declaration \ + -Wredundant-decls \ + -Wstrict-prototypes \ + -Wundef \ + -Wshadow \ + -Wpointer-arith \ + -Wformat \ + -Wreturn-type \ + -Wsign-compare \ + -Wmultichar \ + -Wformat-nonliteral \ + -Winit-self \ + -Wuninitialized \ + -Wformat-security \ + -Werror \ + -fno-common \ + -fno-exceptions \ + -fvisibility=internal \ + -ffunction-sections \ + -fdata-sections \ + -fstack-protector-all \ + $(CPUFLAGS) \ + $(FPUFLAGS) \ + -DSTM32F2 \ + -DCONFIDENTIAL='__attribute__((section("confidential")))' \ + -DRAND_PLATFORM_INDEPENDENT=1 \ + -I$(TOOLCHAIN_DIR)/include \ + -I$(TOP_DIR) \ + -I$(TOP_DIR)gen \ + -I$(TOP_DIR)vendor/trezor-crypto \ + -I$(TOP_DIR)vendor/trezor-qrenc \ + -I$(TOP_DIR)vendor/skycoin-crypto + +LDFLAGS += -L$(TOP_DIR) \ + $(DBGFLAGS) \ + $(CPUFLAGS) \ + $(FPUFLAGS) + +ifeq ($(EMULATOR),1) +CFLAGS += -DEMULATOR=1 + +CFLAGS += -include $(TOP_DIR)emulator/emulator.h +CFLAGS += -include stdio.h + +LDFLAGS += -L$(TOP_DIR)emulator + +LDLIBS += -ltrezor -lemulator +LIBDEPS += $(TOP_DIR)/libtrezor.a $(TOP_DIR)emulator/libemulator.a + +ifeq ($(HEADLESS),1) +CFLAGS += -DHEADLESS=1 +else +CFLAGS += -DHEADLESS=0 + +CFLAGS += -I/usr/include/SDL2 -D_REENTRANT +LDLIBS += -lSDL2 +endif + +else +ifdef APPVER +CFLAGS += -DAPPVER=$(APPVER) +LDSCRIPT = $(TOP_DIR)/memory_app_$(APPVER).ld +else +LDSCRIPT = $(TOP_DIR)/memory.ld +endif + +CFLAGS += -DEMULATOR=0 + +LDFLAGS += --static \ + -Wl,--start-group \ + -lc \ + -lgcc \ + -lnosys \ + -Wl,--end-group \ + -L$(TOOLCHAIN_DIR)/lib \ + -T$(LDSCRIPT) \ + -nostartfiles \ + -Wl,--gc-sections + +LDLIBS += -ltrezor +LIBDEPS += $(TOP_DIR)/libtrezor.a + +LDLIBS += -lopencm3_stm32f2 +LIBDEPS += $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a +endif + +ifeq ($(MEMORY_PROTECT), 0) +CFLAGS += -DMEMORY_PROTECT=0 +else +CFLAGS += -DMEMORY_PROTECT=1 +endif + +ifeq ($(DEBUG_RNG), 1) +CFLAGS += -DDEBUG_RNG=1 +else +CFLAGS += -DDEBUG_RNG=0 +endif + +all: $(NAME).bin + +flash: $(NAME).bin + $(OPENOCD) -c "init; reset halt; flash write_image erase $(NAME).bin 0x8000000; exit" + +upload: sign + trezorctl firmware_update -f $(NAME).bin + +sign: $(NAME).bin + ../bootloader/firmware_sign.py -f $(NAME).bin + +release: $(NAME).bin + ../bootloader/firmware_sign.py -f $(NAME).bin + cp $(NAME).bin $(NAME)-$(APPVER).bin + chmod -x $(NAME)-$(APPVER).bin + xxd -p $(NAME)-$(APPVER).bin | tr -d '\n' > $(NAME)-$(APPVER).bin.hex + +$(NAME).bin: $(NAME).elf + $(OBJCOPY) -Obinary $(NAME).elf $(NAME).bin + +$(NAME).hex: $(NAME).elf + $(OBJCOPY) -Oihex $(NAME).elf $(NAME).hex + +$(NAME).srec: $(NAME).elf + $(OBJCOPY) -Osrec $(NAME).elf $(NAME).srec + +$(NAME).list: $(NAME).elf + $(OBJDUMP) -S $(NAME).elf > $(NAME).list + +$(NAME).elf: $(OBJS) $(LDSCRIPT) $(LIBDEPS) + $(LD) -o $(NAME).elf $(OBJS) $(LDLIBS) $(LDFLAGS) + +%.o: %.s Makefile + $(AS) $(CPUFLAGS) -o $@ $< + +%.o: %.c Makefile + $(CC) $(CFLAGS) -MMD -MP -o $@ -c $< + +%.small.o: %.c Makefile + $(CC) $(CFLAGS) -MMD -MP -o $@ -c $< + +%.d: %.c Makefile + @$(CC) $(CFLAGS) -MM -MP -MG -o $@ $< + +%.small.d: %.c Makefile + @$(CC) $(CFLAGS) -MM -MP -MG -o $@ $< + +clean:: + rm -f $(OBJS) + rm -f *.a + rm -f *.bin + rm -f *.d + rm -f *.elf + rm -f *.hex + rm -f *.list + rm -f *.log + rm -f *.srec + +-include $(OBJS:.o=.d) diff --git a/hardware-wallet/firmware/README.md b/hardware-wallet/firmware/README.md new file mode 100644 index 00000000..bc8d47ea --- /dev/null +++ b/hardware-wallet/firmware/README.md @@ -0,0 +1,66 @@ +# TREZOR Firmware + +[![Build Status](https://travis-ci.org/trezor/trezor-mcu.svg?branch=master)](https://travis-ci.org/trezor/trezor-mcu) [![gitter](https://badges.gitter.im/trezor/community.svg)](https://gitter.im/trezor/community) + +https://trezor.io/ + +## How to build TREZOR firmware? + +1. [Install Docker](https://docs.docker.com/engine/installation/) +2. `git clone https://github.com/trezor/trezor-mcu.git` +3. `cd trezor-mcu` +4. `./build-firmware.sh TAG` (where TAG is v1.5.0 for example, if left blank the script builds latest commit in master branch) + +This creates file `build/trezor-TAG.bin` and prints its fingerprint and size at the end of the build log. + +## How to build TREZOR emulator for Linux? + +1. [Install Docker](https://docs.docker.com/engine/installation/) +2. `git clone https://github.com/trezor/trezor-mcu.git` +3. `cd trezor-mcu` +4. `./build-emulator.sh TAG` (where TAG is v1.5.0 for example, if left blank the script builds latest commit in master branch) + +This creates binary file `build/trezor-emulator-TAG`, which can be run and works as a trezor emulator. (Use `TREZOR_OLED_SCALE` env. variable to make screen bigger.) + +## How to build TREZOR bootloader? + +1. [Install Docker](https://docs.docker.com/engine/installation/) +2. `git clone https://github.com/trezor/trezor-mcu.git` +3. `cd trezor-mcu` +4. `./build-bootloader.sh TAG` (where TAG is bl1.3.2 for example, if left blank the script builds latest commit in master branch) + +This creates file `build/bootloader-TAG.bin` and prints its fingerprint and size at the end of the build log. + +## How to get fingerprint of firmware signed and distributed by SatoshiLabs? + +1. Pick version of firmware binary listed on https://wallet.trezor.io/data/firmware/releases.json +2. Download it: `wget -O trezor.signed.bin https://wallet.trezor.io/data/firmware/trezor-1.3.6.bin` +3. Compute fingerprint: `tail -c +257 trezor.signed.bin | sha256sum` + +Step 3 should produce the same sha256 fingerprint like your local build (for the same version tag). Firmware has a special header (of length 256 bytes) holding signatures themselves, which must be avoided while calculating the fingerprint, that's why tail command has to be used. + +## How to install custom built firmware? + +**WARNING: This will erase the recovery seed stored on the device! You should never do this on TREZOR that contains coins!** + +1. Install python-trezor: `pip install trezor` ([more info](https://github.com/trezor/python-trezor)) +2. `trezorctl firmware_update -f build/trezor-TAG.bin` + +## Building for development + +If you want to build device firmware, make sure you have the +[GNU ARM Embedded toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads) installed. + +* If you want to build the emulator instead of the firmware, run `export EMULATOR=1 TREZOR_TRANSPORT_V1=1` +* If you want to build with the debug link, run `export DEBUG_LINK=1`. Use this if you want to run the device tests. +* When you change these variables, use `script/setup` to clean the repository + +1. To initialize the repository, run `script/setup` +2. To build the firmware or emulator, run `script/cibuild` + +If you are building device firmware, the firmware will be in `firmware/trezor.bin`. + +You can launch the emulator using `firmware/trezor.elf`. To use `trezorctl` with the emulator, use +`trezorctl -t udp` (for example, `trezorctl -t udp get_features`). + +If `trezorctl -t udp` appears to hang, make sure you have run `export TREZOR_TRANSPORT_V1=1`. diff --git a/hardware-wallet/firmware/bootloader/.gitignore b/hardware-wallet/firmware/bootloader/.gitignore new file mode 100644 index 00000000..e0baf9ab --- /dev/null +++ b/hardware-wallet/firmware/bootloader/.gitignore @@ -0,0 +1,9 @@ +*.o +*.a +*.d +*.bin +*.elf +*.hex +*.list +*.srec +*.log diff --git a/hardware-wallet/firmware/bootloader/ChangeLog b/hardware-wallet/firmware/bootloader/ChangeLog new file mode 100644 index 00000000..9bc863fe --- /dev/null +++ b/hardware-wallet/firmware/bootloader/ChangeLog @@ -0,0 +1,27 @@ +Version 1.3.2 +* Don't show recovery seed warning if firmware is flashed for the first time +* Don't show fingerprint if firmware is flashed for the first time +* Compute firmware hash before checking signatures +* Add self-test +* Fix usage of RNG before setup +* Fix stack protector fault + +Version 1.3.1 +* Fix button testing so it does not break USB communication + +Version 1.3.0 +* Add test for buttons +* Clean USB descriptor +* Return firmware_present in Features response +* Don't halt on broken firware, stay in bootloader + +Version 1.2.7 +* Optimize speed of firmware update + +Version 1.2.6 +* Show hash of unofficial firmware +* Use stack protector +* Clean USB descriptor + +Version 1.2.5 +* Initial import of code diff --git a/hardware-wallet/firmware/bootloader/Makefile b/hardware-wallet/firmware/bootloader/Makefile new file mode 100644 index 00000000..72b251ae --- /dev/null +++ b/hardware-wallet/firmware/bootloader/Makefile @@ -0,0 +1,21 @@ +NAME = bootloader + +OBJS += bootloader.o +OBJS += signatures.o +OBJS += usb.o + +OBJS += ../vendor/trezor-crypto/bignum.small.o +OBJS += ../vendor/trezor-crypto/ecdsa.small.o +OBJS += ../vendor/trezor-crypto/secp256k1.small.o +OBJS += ../vendor/trezor-crypto/sha2.small.o +OBJS += ../vendor/trezor-crypto/memzero.small.o + +CFLAGS += -DUSE_PRECOMPUTED_IV=0 +CFLAGS += -DUSE_PRECOMPUTED_CP=0 + +OPTFLAGS ?= -Os + +include ../Makefile.include + +align: $(NAME).bin + ./firmware_align.py $(NAME).bin diff --git a/hardware-wallet/firmware/bootloader/bootloader.c b/hardware-wallet/firmware/bootloader/bootloader.c new file mode 100644 index 00000000..47b7997e --- /dev/null +++ b/hardware-wallet/firmware/bootloader/bootloader.c @@ -0,0 +1,165 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include +#include +#include + +#include "bootloader.h" +#include "buttons.h" +#include "setup.h" +#include "usb.h" +#include "oled.h" +#include "util.h" +#include "signatures.h" +#include "layout.h" +#include "serialno.h" +#include "rng.h" + +void layoutFirmwareHash(const uint8_t *hash) +{ + char str[4][17]; + for (int i = 0; i < 4; i++) { + data2hex(hash + i * 8, 8, str[i]); + } + layoutDialog(&bmp_icon_question, "Abort", "Continue", "Compare fingerprints", str[0], str[1], str[2], str[3], NULL, NULL); +} + +void show_halt(void) +{ + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Unofficial firmware", "aborted.", NULL, "Unplug your TREZOR", "contact our support.", NULL); + shutdown(); +} + +void show_unofficial_warning(const uint8_t *hash) +{ + layoutDialog(&bmp_icon_warning, "Abort", "I'll take the risk", NULL, "WARNING!", NULL, "Unofficial firmware", "detected.", NULL, NULL); + + do { + delay(100000); + buttonUpdate(); + } while (!button.YesUp && !button.NoUp); + + if (button.NoUp) { + show_halt(); // no button was pressed -> halt + } + + layoutFirmwareHash(hash); + + do { + delay(100000); + buttonUpdate(); + } while (!button.YesUp && !button.NoUp); + + if (button.NoUp) { + show_halt(); // no button was pressed -> halt + } + + // everything is OK, user pressed 2x Continue -> continue program +} + +void __attribute__((noreturn)) load_app(int signed_firmware) +{ + (void)signed_firmware; + + // zero out SRAM + memset_reg(_ram_start, _ram_end, 0); + + load_vector_table((const vector_table_t *) FLASH_APP_START); +} + +bool firmware_present(void) +{ +#ifndef APPVER + if (memcmp((const void *)FLASH_META_MAGIC, "TRZR", 4)) { // magic does not match + return false; + } + if (*((const uint32_t *)FLASH_META_CODELEN) < 4096) { // firmware reports smaller size than 4kB + return false; + } + if (*((const uint32_t *)FLASH_META_CODELEN) > FLASH_TOTAL_SIZE - (FLASH_APP_START - FLASH_ORIGIN)) { // firmware reports bigger size than flash size + return false; + } +#endif + return true; +} + +void bootloader_loop(void) +{ + oledClear(); + oledDrawBitmap(0, 0, &bmp_logo64); + if (firmware_present()) { + oledDrawString(52, 0, "TREZOR", FONT_STANDARD); + static char serial[25]; + fill_serialno_fixed(serial); + oledDrawString(52, 20, "Serial No.", FONT_STANDARD); + oledDrawString(52, 40, serial + 12, FONT_STANDARD); // second part of serial + serial[12] = 0; + oledDrawString(52, 30, serial, FONT_STANDARD); // first part of serial + oledDrawStringRight(OLED_WIDTH - 1, OLED_HEIGHT - 8, "Loader " VERSTR(VERSION_MAJOR) "." VERSTR(VERSION_MINOR) "." VERSTR(VERSION_PATCH), FONT_STANDARD); + } else { + oledDrawString(52, 10, "Welcome!", FONT_STANDARD); + oledDrawString(52, 30, "Please visit", FONT_STANDARD); + oledDrawString(52, 50, "trezor.io/start", FONT_STANDARD); + } + oledRefresh(); + + usbLoop(firmware_present()); +} + +int main(void) +{ +#ifndef APPVER + setup(); +#endif + __stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks +#ifndef APPVER + memory_protect(); + oledInit(); +#endif + +#ifndef APPVER + // at least one button is unpressed + uint16_t state = gpio_port_read(BTN_PORT); + int unpressed = ((state & BTN_PIN_YES) == BTN_PIN_YES || (state & BTN_PIN_NO) == BTN_PIN_NO); + + if (firmware_present() && unpressed) { + + oledClear(); + oledDrawBitmap(40, 0, &bmp_logo64_empty); + oledRefresh(); + + uint8_t hash[32]; + int signed_firmware = signatures_ok(hash); + if (SIG_OK != signed_firmware) { + show_unofficial_warning(hash); + } + + delay(100000); + + load_app(signed_firmware); + } +#endif + + bootloader_loop(); + + return 0; +} diff --git a/hardware-wallet/firmware/bootloader/bootloader.h b/hardware-wallet/firmware/bootloader/bootloader.h new file mode 100644 index 00000000..064f270e --- /dev/null +++ b/hardware-wallet/firmware/bootloader/bootloader.h @@ -0,0 +1,40 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __BOOTLOADER_H__ +#define __BOOTLOADER_H__ + +#define VERSION_MAJOR 1 +#define VERSION_MINOR 4 +#define VERSION_PATCH 0 + +#define STR(X) #X +#define VERSTR(X) STR(X) + +#define VERSION_MAJOR_CHAR "\x01" +#define VERSION_MINOR_CHAR "\x04" +#define VERSION_PATCH_CHAR "\x00" + +#include +#include "memory.h" + +void layoutFirmwareHash(const uint8_t *hash); +bool firmware_present(void); + +#endif diff --git a/hardware-wallet/firmware/bootloader/combine/prepare.py b/hardware-wallet/firmware/bootloader/combine/prepare.py new file mode 100755 index 00000000..eb073e98 --- /dev/null +++ b/hardware-wallet/firmware/bootloader/combine/prepare.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +from __future__ import print_function + +bl = open('bl.bin').read() +fw = open('fw.bin').read() +combined = bl + fw[:256] + (32768-256)*'\x00' + fw[256:] + +open('combined.bin', 'w').write(combined) + +print('bootloader : %d bytes' % len(bl)) +print('firmware : %d bytes' % len(fw)) +print('combined : %d bytes' % len(combined)) diff --git a/hardware-wallet/firmware/bootloader/combine/write.sh b/hardware-wallet/firmware/bootloader/combine/write.sh new file mode 100755 index 00000000..6854ee60 --- /dev/null +++ b/hardware-wallet/firmware/bootloader/combine/write.sh @@ -0,0 +1,2 @@ +#!/bin/bash +st-flash write combined.bin 0x8000000 diff --git a/hardware-wallet/firmware/bootloader/firmware_align.py b/hardware-wallet/firmware/bootloader/firmware_align.py new file mode 100755 index 00000000..b07bf0eb --- /dev/null +++ b/hardware-wallet/firmware/bootloader/firmware_align.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +import sys +import os + +fn = sys.argv[1] +fs = os.stat(fn).st_size +if fs > 32768: + raise Exception('bootloader has to be smaller than 32768 bytes') +with open(fn, 'ab') as f: + f.write(b'\xFF' * (32768 - fs)) + f.close() diff --git a/hardware-wallet/firmware/bootloader/firmware_sign.py b/hardware-wallet/firmware/bootloader/firmware_sign.py new file mode 100755 index 00000000..a14bfaf6 --- /dev/null +++ b/hardware-wallet/firmware/bootloader/firmware_sign.py @@ -0,0 +1,198 @@ +#!/usr/bin/python +from __future__ import print_function +import argparse +import hashlib +import struct +import binascii +import ecdsa + +try: + raw_input +except: + raw_input = input + +SLOTS = 3 + +pubkeys = { + 1: '04d571b7f148c5e4232c3814f777d8faeaf1a84216c78d569b71041ffc768a5b2d810fc3bb134dd026b57e65005275aedef43e155f48fc11a32ec790a93312bd58', + 2: '0463279c0c0866e50c05c799d32bd6bab0188b6de06536d1109d2ed9ce76cb335c490e55aee10cc901215132e853097d5432eda06b792073bd7740c94ce4516cb1', + 3: '0443aedbb6f7e71c563f8ed2ef64ec9981482519e7ef4f4aa98b27854e8c49126d4956d300ab45fdc34cd26bc8710de0a31dbdf6de7435fd0b492be70ac75fde58', + 4: '04877c39fd7c62237e038235e9c075dab261630f78eeb8edb92487159fffedfdf6046c6f8b881fa407c4a4ce6c28de0b19c1f4e29f1fcbc5a58ffd1432a3e0938a', + 5: '047384c51ae81add0a523adbb186c91b906ffb64c2c765802bf26dbd13bdf12c319e80c2213a136c8ee03d7874fd22b70d68e7dee469decfbbb510ee9a460cda45', +} + +INDEXES_START = len('TRZR') + struct.calcsize(' SLOTS: + raise Exception("Invalid slot") + + if is_pem: + print("Paste ECDSA private key in PEM format and press Enter:") + print("(blank private key removes the signature on given index)") + pem_key = '' + while True: + key = raw_input() + pem_key += key + "\n" + if key == '': + break + if pem_key.strip() == '': + # Blank key,let's remove existing signature from slot + return modify(data, slot, 0, '\x00' * 64) + key = ecdsa.SigningKey.from_pem(pem_key) + else: + print("Paste SECEXP (in hex) and press Enter:") + print("(blank private key removes the signature on given index)") + secexp = raw_input() + if secexp.strip() == '': + # Blank key,let's remove existing signature from slot + return modify(data, slot, 0, '\x00' * 64) + key = ecdsa.SigningKey.from_secret_exponent(secexp = int(secexp, 16), curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256) + + to_sign = prepare(data)[256:] # without meta + + # Locate proper index of current signing key + pubkey = b'04' + binascii.hexlify(key.get_verifying_key().to_string()) + index = None + for i, pk in pubkeys.items(): + if pk == pubkey: + index = i + break + + if index == None: + raise Exception("Unable to find private key index. Unknown private key?") + + signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256) + + return modify(data, slot, index, signature) + +def main(args): + if args.generate: + key = ecdsa.SigningKey.generate( + curve=ecdsa.curves.SECP256k1, + hashfunc=hashlib.sha256) + + print("PRIVATE KEY (SECEXP):") + print(binascii.hexlify(key.to_string())) + print() + + print("PRIVATE KEY (PEM):") + print(key.to_pem()) + + print("PUBLIC KEY:") + print('04' + binascii.hexlify(key.get_verifying_key().to_string())) + return + + if not args.path: + raise Exception("-f/--file is required") + + data = open(args.path, 'rb').read() + assert len(data) % 4 == 0 + + if data[:4] != b'TRZR': + print("Metadata has been added...") + data = prepare(data) + + if data[:4] != b'TRZR': + raise Exception("Firmware header expected") + + print("Firmware size %d bytes" % len(data)) + + check_signatures(data) + + if args.sign: + data = sign(data, args.pem) + check_signatures(data) + + fp = open(args.path, 'wb') + fp.write(data) + fp.close() + +if __name__ == '__main__': + args = parse_args() + main(args) diff --git a/hardware-wallet/firmware/bootloader/firmware_sign_split.py b/hardware-wallet/firmware/bootloader/firmware_sign_split.py new file mode 100755 index 00000000..47b18e49 --- /dev/null +++ b/hardware-wallet/firmware/bootloader/firmware_sign_split.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +from __future__ import print_function +import hashlib +import os +import subprocess +import ecdsa +from binascii import hexlify, unhexlify + +print('master secret:', end='') +try: + h = raw_input() +except: + h = input() +if h: + h = unhexlify(h).encode('ascii') +else: + h = hashlib.sha256(os.urandom(1024)).digest() + +print() +print('master secret:', hexlify(h)) +print() + +for i in range(1, 6): + se = hashlib.sha256(h + chr(i).encode('ascii')).hexdigest() + print('seckey', i, ':', se) + sk = ecdsa.SigningKey.from_secret_exponent(secexp = int(se, 16), curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256) + print('pubkey', i, ':', (b'04' + hexlify(sk.get_verifying_key().to_string())).decode('ascii')) + print(sk.to_pem().decode('ascii')) + +p = subprocess.Popen('ssss-split -t 3 -n 5 -x'.split(' '), stdin = subprocess.PIPE) +p.communicate(input = hexlify(h) + '\n') + +# to recover use: +# $ ssss-combine -t 3 -x diff --git a/hardware-wallet/firmware/bootloader/signatures.c b/hardware-wallet/firmware/bootloader/signatures.c new file mode 100644 index 00000000..9f9e540f --- /dev/null +++ b/hardware-wallet/firmware/bootloader/signatures.c @@ -0,0 +1,75 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#include "signatures.h" +#include "ecdsa.h" +#include "secp256k1.h" +#include "sha2.h" +#include "bootloader.h" + +#define PUBKEYS 5 + +static const uint8_t * const pubkey[PUBKEYS] = { + (const uint8_t *)"\x04\xd5\x71\xb7\xf1\x48\xc5\xe4\x23\x2c\x38\x14\xf7\x77\xd8\xfa\xea\xf1\xa8\x42\x16\xc7\x8d\x56\x9b\x71\x04\x1f\xfc\x76\x8a\x5b\x2d\x81\x0f\xc3\xbb\x13\x4d\xd0\x26\xb5\x7e\x65\x00\x52\x75\xae\xde\xf4\x3e\x15\x5f\x48\xfc\x11\xa3\x2e\xc7\x90\xa9\x33\x12\xbd\x58", + (const uint8_t *)"\x04\x63\x27\x9c\x0c\x08\x66\xe5\x0c\x05\xc7\x99\xd3\x2b\xd6\xba\xb0\x18\x8b\x6d\xe0\x65\x36\xd1\x10\x9d\x2e\xd9\xce\x76\xcb\x33\x5c\x49\x0e\x55\xae\xe1\x0c\xc9\x01\x21\x51\x32\xe8\x53\x09\x7d\x54\x32\xed\xa0\x6b\x79\x20\x73\xbd\x77\x40\xc9\x4c\xe4\x51\x6c\xb1", + (const uint8_t *)"\x04\x43\xae\xdb\xb6\xf7\xe7\x1c\x56\x3f\x8e\xd2\xef\x64\xec\x99\x81\x48\x25\x19\xe7\xef\x4f\x4a\xa9\x8b\x27\x85\x4e\x8c\x49\x12\x6d\x49\x56\xd3\x00\xab\x45\xfd\xc3\x4c\xd2\x6b\xc8\x71\x0d\xe0\xa3\x1d\xbd\xf6\xde\x74\x35\xfd\x0b\x49\x2b\xe7\x0a\xc7\x5f\xde\x58", + (const uint8_t *)"\x04\x87\x7c\x39\xfd\x7c\x62\x23\x7e\x03\x82\x35\xe9\xc0\x75\xda\xb2\x61\x63\x0f\x78\xee\xb8\xed\xb9\x24\x87\x15\x9f\xff\xed\xfd\xf6\x04\x6c\x6f\x8b\x88\x1f\xa4\x07\xc4\xa4\xce\x6c\x28\xde\x0b\x19\xc1\xf4\xe2\x9f\x1f\xcb\xc5\xa5\x8f\xfd\x14\x32\xa3\xe0\x93\x8a", + (const uint8_t *)"\x04\x73\x84\xc5\x1a\xe8\x1a\xdd\x0a\x52\x3a\xdb\xb1\x86\xc9\x1b\x90\x6f\xfb\x64\xc2\xc7\x65\x80\x2b\xf2\x6d\xbd\x13\xbd\xf1\x2c\x31\x9e\x80\xc2\x21\x3a\x13\x6c\x8e\xe0\x3d\x78\x74\xfd\x22\xb7\x0d\x68\xe7\xde\xe4\x69\xde\xcf\xbb\xb5\x10\xee\x9a\x46\x0c\xda\x45", +}; + +#define SIGNATURES 3 + +int signatures_ok(uint8_t *store_hash) +{ + if (!firmware_present()) return SIG_FAIL; // no firmware present + + const uint32_t codelen = *((const uint32_t *)FLASH_META_CODELEN); + const uint8_t sigindex1 = *((const uint8_t *)FLASH_META_SIGINDEX1); + const uint8_t sigindex2 = *((const uint8_t *)FLASH_META_SIGINDEX2); + const uint8_t sigindex3 = *((const uint8_t *)FLASH_META_SIGINDEX3); + + uint8_t hash[32]; + sha256_Raw((const uint8_t *)FLASH_APP_START, codelen, hash); + if (store_hash) { + memcpy(store_hash, hash, 32); + } + + if (sigindex1 < 1 || sigindex1 > PUBKEYS) return SIG_FAIL; // invalid index + if (sigindex2 < 1 || sigindex2 > PUBKEYS) return SIG_FAIL; // invalid index + if (sigindex3 < 1 || sigindex3 > PUBKEYS) return SIG_FAIL; // invalid index + + if (sigindex1 == sigindex2) return SIG_FAIL; // duplicate use + if (sigindex1 == sigindex3) return SIG_FAIL; // duplicate use + if (sigindex2 == sigindex3) return SIG_FAIL; // duplicate use + + if (0 != ecdsa_verify_digest(&secp256k1, pubkey[sigindex1 - 1], (const uint8_t *)FLASH_META_SIG1, hash)) { // failure + return SIG_FAIL; + } + if (0 != ecdsa_verify_digest(&secp256k1, pubkey[sigindex2 - 1], (const uint8_t *)FLASH_META_SIG2, hash)) { // failure + return SIG_FAIL; + } + if (0 != ecdsa_verify_digest(&secp256k1, pubkey[sigindex3 - 1], (const uint8_t *)FLASH_META_SIG3, hash)) { // failture + return SIG_FAIL; + } + + return SIG_OK; +} diff --git a/hardware-wallet/firmware/bootloader/signatures.h b/hardware-wallet/firmware/bootloader/signatures.h new file mode 100644 index 00000000..01b5f308 --- /dev/null +++ b/hardware-wallet/firmware/bootloader/signatures.h @@ -0,0 +1,28 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __SIGNATURES_H__ +#define __SIGNATURES_H__ + +#define SIG_OK 0x5A3CA5C3 +#define SIG_FAIL 0x00000000 + +int signatures_ok(uint8_t *store_hash); + +#endif diff --git a/hardware-wallet/firmware/bootloader/usb.c b/hardware-wallet/firmware/bootloader/usb.c new file mode 100644 index 00000000..4fbf0881 --- /dev/null +++ b/hardware-wallet/firmware/bootloader/usb.c @@ -0,0 +1,726 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +#include + +#include "buttons.h" +#include "bootloader.h" +#include "oled.h" +#include "rng.h" +#include "usb.h" +#include "serialno.h" +#include "layout.h" +#include "util.h" +#include "signatures.h" +#include "sha2.h" +#include "ecdsa.h" +#include "secp256k1.h" +#include "memzero.h" + +#define FIRMWARE_MAGIC "TRZR" + +#define ENDPOINT_ADDRESS_IN (0x81) +#define ENDPOINT_ADDRESS_OUT (0x01) + +static bool brand_new_firmware; +static bool old_was_unsigned; + +static const struct usb_device_descriptor dev_descr = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x534c, + .idProduct = 0x0001, + .bcdDevice = 0x0100, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +static const uint8_t hid_report_descriptor[] = { + 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined) + 0x09, 0x01, // USAGE (1) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x20, // USAGE (Input Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x21, // USAGE (Output Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION +}; + +static const struct { + struct usb_hid_descriptor hid_descriptor; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report; +} __attribute__((packed)) hid_function = { + .hid_descriptor = { + .bLength = sizeof(hid_function), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0111, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor), + } +}; + +static const struct usb_endpoint_descriptor hid_endpoints[2] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_IN, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_OUT, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}}; + +static const struct usb_interface_descriptor hid_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + .endpoint = hid_endpoints, + .extra = &hid_function, + .extralen = sizeof(hid_function), +}}; + +static const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = hid_iface, +}}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + .interface = ifaces, +}; + +static const char *usb_strings[] = { + "SatoshiLabs", + "TREZOR", + "", // empty serial +}; + +static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) +{ + (void)complete; + (void)dev; + + if ((req->bmRequestType != 0x81) || + (req->bRequest != USB_REQ_GET_DESCRIPTOR) || + (req->wValue != 0x2200)) + return 0; + + /* Handle the HID report descriptor. */ + *buf = (uint8_t *)hid_report_descriptor; + *len = sizeof(hid_report_descriptor); + + return 1; +} + +enum { + STATE_READY, + STATE_OPEN, + STATE_FLASHSTART, + STATE_FLASHING, + STATE_CHECK, + STATE_END, +}; + +static uint32_t flash_pos = 0, flash_len = 0; +static char flash_state = STATE_READY; +static uint8_t flash_anim = 0; +static uint16_t msg_id = 0xFFFF; +static uint32_t msg_size = 0; + +static uint8_t meta_backup[FLASH_META_LEN]; + +static void send_msg_success(usbd_device *dev) +{ + // response: Success message (id 2), payload len 0 + while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN, + // header + "?##" + // msg_id + "\x00\x02" + // msg_size + "\x00\x00\x00\x00" + // padding + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64) != 64) {} +} + +static void send_msg_failure(usbd_device *dev) +{ + // response: Failure message (id 3), payload len 2 + // - code = 99 (Failure_FirmwareError) + while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN, + // header + "?##" + // msg_id + "\x00\x03" + // msg_size + "\x00\x00\x00\x02" + // data + "\x08" "\x63" + // padding + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64) != 64) {} +} + +static void send_msg_features(usbd_device *dev) +{ + // response: Features message (id 17), payload len 30 + // - vendor = "bitcointrezor.com" + // - major_version = VERSION_MAJOR + // - minor_version = VERSION_MINOR + // - patch_version = VERSION_PATCH + // - bootloader_mode = True + // - firmware_present = True/False + // - model = "1" + if (brand_new_firmware) { + while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN, + // header + "?##" + // msg_id + "\x00\x11" + // msg_size + "\x00\x00\x00\x1e" + // data + "\x0a" "\x11" "bitcointrezor.com" + "\x10" VERSION_MAJOR_CHAR + "\x18" VERSION_MINOR_CHAR + "\x20" VERSION_PATCH_CHAR + "\x28" "\x01" + "\x90\x01" "\x00" + "\xaa" "\x01" "1" + // padding + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64) != 64) {} + } else { + while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN, + // header + "?##" + // msg_id + "\x00\x11" + // msg_size + "\x00\x00\x00\x1e" + // data + "\x0a\x11" "bitcointrezor.com" + "\x10" VERSION_MAJOR_CHAR + "\x18" VERSION_MINOR_CHAR + "\x20" VERSION_PATCH_CHAR + "\x28" "\x01" + "\x90\x01" "\x01" + "\xaa" "\x01" "1" + // padding + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64) != 64) {} + } +} + +static void send_msg_buttonrequest_firmwarecheck(usbd_device *dev) +{ + // response: ButtonRequest message (id 26), payload len 2 + // - code = ButtonRequest_FirmwareCheck (9) + while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN, + // header + "?##" + // msg_id + "\x00\x1a" + // msg_size + "\x00\x00\x00\x02" + // data + "\x08" "\x09" + // padding + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64) != 64) {} +} + +static void erase_metadata_sectors(void) +{ + flash_unlock(); + for (int i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) { + flash_erase_sector(i, FLASH_CR_PROGRAM_X32); + } + flash_lock(); +} + +static void backup_metadata(uint8_t *backup) +{ + memcpy(backup, (void *)FLASH_META_START, FLASH_META_LEN); +} + +static void restore_metadata(const uint8_t *backup) +{ + flash_unlock(); + for (int i = 0; i < FLASH_META_LEN / 4; i++) { + const uint32_t *w = (const uint32_t *)(backup + i * 4); + flash_program_word(FLASH_META_START + i * 4, *w); + } + flash_lock(); +} + +static void hid_rx_callback(usbd_device *dev, uint8_t ep) +{ + (void)ep; + static uint8_t buf[64] __attribute__((aligned(4))); + static uint8_t towrite[4] __attribute__((aligned(4))); + static int wi; + + if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_OUT, buf, 64) != 64) return; + + if (flash_state == STATE_END) { + return; + } + + if (flash_state == STATE_READY || flash_state == STATE_OPEN || flash_state == STATE_FLASHSTART || flash_state == STATE_CHECK) { + if (buf[0] != '?' || buf[1] != '#' || buf[2] != '#') { // invalid start - discard + return; + } + // struct.unpack(">HL") => msg, size + msg_id = (buf[3] << 8) + buf[4]; + msg_size = (buf[5] << 24) + (buf[6] << 16) + (buf[7] << 8) + buf[8]; + } + + if (flash_state == STATE_READY || flash_state == STATE_OPEN) { + if (msg_id == 0x0000) { // Initialize message (id 0) + send_msg_features(dev); + flash_state = STATE_OPEN; + return; + } + if (msg_id == 0x0037) { // GetFeatures message (id 55) + send_msg_features(dev); + return; + } + if (msg_id == 0x0001) { // Ping message (id 1) + send_msg_success(dev); + return; + } + if (msg_id == 0x0005) { // WipeDevice message (id 5) + layoutDialog(&bmp_icon_question, "Cancel", "Confirm", NULL, "Do you really want to", "wipe the device?", NULL, "All data will be lost.", NULL, NULL); + do { + delay(100000); + buttonUpdate(); + } while (!button.YesUp && !button.NoUp); + if (button.YesUp) { + flash_wait_for_last_operation(); + flash_clear_status_flags(); + flash_unlock(); + // erase metadata area + for (int i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) { + layoutProgress("ERASING ... Please wait", 1000 * (i - FLASH_META_SECTOR_FIRST) / (FLASH_CODE_SECTOR_LAST - FLASH_META_SECTOR_FIRST)); + flash_erase_sector(i, FLASH_CR_PROGRAM_X32); + } + // erase code area + for (int i = FLASH_CODE_SECTOR_FIRST; i <= FLASH_CODE_SECTOR_LAST; i++) { + layoutProgress("ERASING ... Please wait", 1000 * (i - FLASH_META_SECTOR_FIRST) / (FLASH_CODE_SECTOR_LAST - FLASH_META_SECTOR_FIRST)); + flash_erase_sector(i, FLASH_CR_PROGRAM_X32); + } + flash_wait_for_last_operation(); + flash_lock(); + flash_state = STATE_END; + layoutDialog(&bmp_icon_ok, NULL, NULL, NULL, "Device", "successfully wiped.", NULL, "You may now", "unplug your TREZOR.", NULL); + send_msg_success(dev); + } else { + flash_state = STATE_END; + layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, "Device wipe", "aborted.", NULL, "You may now", "unplug your TREZOR.", NULL); + send_msg_failure(dev); + } + return; + } + if (msg_id == 0x0020) { // SelfTest message (id 32) + + // USB TEST + layoutProgress("TESTING USB ...", 0); + bool status_usb = (buf[9] == 0x0a) && (buf[10] == 53) && (0 == memcmp(buf + 11, "\x00\xFF\x55\xAA\x66\x99\x33\xCC" "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!" "\x00\xFF\x55\xAA\x66\x99\x33\xCC", 53)); + + // RNG TEST + layoutProgress("TESTING RNG ...", 250); + uint32_t cnt[256]; + memset(cnt, 0, sizeof(cnt)); + for (int i = 0; i < (256 * 2000); i++) { + uint32_t r = random32(); + cnt[r & 0xFF]++; + cnt[(r >> 8) & 0xFF]++; + cnt[(r >> 16) & 0xFF]++; + cnt[(r >> 24) & 0xFF]++; + } + bool status_rng = true; + for (int i = 0; i < 256; i++) { + status_rng = status_rng && (cnt[i] >= 7600) && (cnt[i] <= 8400); + } + + // CPU TEST + layoutProgress("TESTING CPU ...", 500); + // privkey : e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + // pubkey : 04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd + // 5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235 + // digest : c84a4cc264100070c8be2acf4072efaadaedfef3d6209c0fe26387e6b1262bbf + // sig: : f7869c679bbed1817052affd0264ccc6486795f6d06d0c187651b8f3863670c8 + // 2ccf89be32a53eb65ea7c007859783d46717986fead0833ec60c5729cdc4a9ee + bool status_cpu = (0 == ecdsa_verify_digest(&secp256k1, + (const uint8_t *)"\x04\xa3\x4b\x99\xf2\x2c\x79\x0c\x4e\x36\xb2\xb3\xc2\xc3\x5a\x36\xdb\x06\x22\x6e\x41\xc6\x92\xfc\x82\xb8\xb5\x6a\xc1\xc5\x40\xc5\xbd\x5b\x8d\xec\x52\x35\xa0\xfa\x87\x22\x47\x6c\x77\x09\xc0\x25\x59\xe3\xaa\x73\xaa\x03\x91\x8b\xa2\xd4\x92\xee\xa7\x5a\xbe\xa2\x35", + (const uint8_t *)"\xf7\x86\x9c\x67\x9b\xbe\xd1\x81\x70\x52\xaf\xfd\x02\x64\xcc\xc6\x48\x67\x95\xf6\xd0\x6d\x0c\x18\x76\x51\xb8\xf3\x86\x36\x70\xc8\x2c\xcf\x89\xbe\x32\xa5\x3e\xb6\x5e\xa7\xc0\x07\x85\x97\x83\xd4\x67\x17\x98\x6f\xea\xd0\x83\x3e\xc6\x0c\x57\x29\xcd\xc4\xa9\xee", + (const uint8_t *)"\xc8\x4a\x4c\xc2\x64\x10\x00\x70\xc8\xbe\x2a\xcf\x40\x72\xef\xaa\xda\xed\xfe\xf3\xd6\x20\x9c\x0f\xe2\x63\x87\xe6\xb1\x26\x2b\xbf")); + + // FLASH TEST + layoutProgress("TESTING FLASH ...", 750); + + // backup metadata + backup_metadata(meta_backup); + + // write test pattern + erase_metadata_sectors(); + flash_unlock(); + for (int i = 0; i < FLASH_META_LEN / 4; i++) { + flash_program_word(FLASH_META_START + i * 4, 0x3C695A0F); + } + flash_lock(); + + // compute hash of written test pattern + uint8_t hash[32]; + sha256_Raw((unsigned char *)FLASH_META_START, FLASH_META_LEN, hash); + + // restore metadata from backup + erase_metadata_sectors(); + restore_metadata(meta_backup); + memzero(meta_backup, sizeof(meta_backup)); + + // compare against known hash computed via the following Python3 script: + // hashlib.sha256(binascii.unhexlify('0F5A693C' * 8192)).hexdigest() + bool status_flash = (0 == memcmp(hash, "\xa6\xc2\x25\xa4\x76\xa1\xde\x76\x09\xe0\xb0\x07\xf8\xe2\x5a\xec\x1d\x75\x8d\x5c\x36\xc8\x4a\x6b\x75\x4e\xd5\x3d\xe6\x99\x97\x64", 32)); + + bool status_all = status_usb && status_rng && status_cpu && status_flash; + + if (status_all) { + send_msg_success(dev); + } else { + send_msg_failure(dev); + } + layoutDialog(status_all ? &bmp_icon_info : &bmp_icon_error, + NULL, NULL, NULL, + status_usb ? "Test USB ... OK" : "Test USB ... Failed", + status_rng ? "Test RNG ... OK" : "Test RNG ... Failed", + status_cpu ? "Test CPU ... OK" : "Test CPU ... Failed", + status_flash ? "Test FLASH ... OK" : "Test FLASH ... Failed", + NULL, + NULL + ); + return; + } + } + + if (flash_state == STATE_OPEN) { + if (msg_id == 0x0006) { // FirmwareErase message (id 6) + if (!brand_new_firmware) { + layoutDialog(&bmp_icon_question, "Abort", "Continue", NULL, "Install new", "firmware?", NULL, "Never do this without", "your recovery card!", NULL); + do { + delay(100000); + buttonUpdate(); + } while (!button.YesUp && !button.NoUp); + } + if (brand_new_firmware || button.YesUp) { + // check whether current firmware is signed + if (!brand_new_firmware && SIG_OK == signatures_ok(NULL)) { + old_was_unsigned = false; + // backup metadata + backup_metadata(meta_backup); + } else { + old_was_unsigned = true; + } + flash_wait_for_last_operation(); + flash_clear_status_flags(); + flash_unlock(); + // erase metadata area + for (int i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) { + layoutProgress("ERASING ... Please wait", 1000 * (i - FLASH_META_SECTOR_FIRST) / (FLASH_CODE_SECTOR_LAST - FLASH_META_SECTOR_FIRST)); + flash_erase_sector(i, FLASH_CR_PROGRAM_X32); + } + // erase code area + for (int i = FLASH_CODE_SECTOR_FIRST; i <= FLASH_CODE_SECTOR_LAST; i++) { + layoutProgress("ERASING ... Please wait", 1000 * (i - FLASH_META_SECTOR_FIRST) / (FLASH_CODE_SECTOR_LAST - FLASH_META_SECTOR_FIRST)); + flash_erase_sector(i, FLASH_CR_PROGRAM_X32); + } + layoutProgress("INSTALLING ... Please wait", 0); + flash_wait_for_last_operation(); + flash_lock(); + + // check that metadata was succesfully erased + // flash status register should show now error and + // the config block should contain only \xff. + uint8_t hash[32]; + sha256_Raw((unsigned char *)FLASH_META_START, FLASH_META_LEN, hash); + if ((FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) != 0 + || memcmp(hash, "\x2d\x86\x4c\x0b\x78\x9a\x43\x21\x4e\xee\x85\x24\xd3\x18\x20\x75\x12\x5e\x5c\xa2\xcd\x52\x7f\x35\x82\xec\x87\xff\xd9\x40\x76\xbc", 32) != 0) { + send_msg_failure(dev); + flash_state = STATE_END; + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); + return; + } + + send_msg_success(dev); + flash_state = STATE_FLASHSTART; + return; + } + send_msg_failure(dev); + flash_state = STATE_END; + layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, "Firmware installation", "aborted.", NULL, "You may now", "unplug your TREZOR.", NULL); + return; + } + return; + } + + if (flash_state == STATE_FLASHSTART) { + if (msg_id == 0x0007) { // FirmwareUpload message (id 7) + if (buf[9] != 0x0a) { // invalid contents + send_msg_failure(dev); + flash_state = STATE_END; + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); + return; + } + // read payload length + uint8_t *p = buf + 10; + flash_len = readprotobufint(&p); + if (flash_len > FLASH_TOTAL_SIZE + FLASH_META_DESC_LEN - (FLASH_APP_START - FLASH_ORIGIN)) { // firmware is too big + send_msg_failure(dev); + flash_state = STATE_END; + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Firmware is too big.", NULL, "Get official firmware", "from trezor.io/start", NULL, NULL); + return; + } + // check firmware magic + if (memcmp(p, FIRMWARE_MAGIC, 4) != 0) { + send_msg_failure(dev); + flash_state = STATE_END; + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Wrong firmware header.", NULL, "Get official firmware", "from trezor.io/start", NULL, NULL); + return; + } + flash_state = STATE_FLASHING; + p += 4; // Don't flash firmware header yet. + flash_pos = 4; + wi = 0; + flash_unlock(); + while (p < buf + 64) { + towrite[wi] = *p; + wi++; + if (wi == 4) { + const uint32_t *w = (uint32_t *)towrite; + flash_program_word(FLASH_META_START + flash_pos, *w); + flash_pos += 4; + wi = 0; + } + p++; + } + flash_lock(); + return; + } + return; + } + + if (flash_state == STATE_FLASHING) { + if (buf[0] != '?') { // invalid contents + send_msg_failure(dev); + flash_state = STATE_END; + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Error installing ", "firmware.", NULL, "Unplug your TREZOR", "and try again.", NULL); + return; + } + const uint8_t *p = buf + 1; + if (flash_anim % 32 == 4) { + layoutProgress("INSTALLING ... Please wait", 1000 * flash_pos / flash_len); + } + flash_anim++; + flash_unlock(); + while (p < buf + 64 && flash_pos < flash_len) { + towrite[wi] = *p; + wi++; + if (wi == 4) { + const uint32_t *w = (const uint32_t *)towrite; + if (flash_pos < FLASH_META_DESC_LEN) { + flash_program_word(FLASH_META_START + flash_pos, *w); // the first 256 bytes of firmware is metadata descriptor + } else { + flash_program_word(FLASH_APP_START + (flash_pos - FLASH_META_DESC_LEN), *w); // the rest is code + } + flash_pos += 4; + wi = 0; + } + p++; + } + flash_lock(); + // flashing done + if (flash_pos == flash_len) { + flash_state = STATE_CHECK; + if (!brand_new_firmware) { + send_msg_buttonrequest_firmwarecheck(dev); + return; + } + } else { + return; + } + } + + if (flash_state == STATE_CHECK) { + + if (!brand_new_firmware) { + if (msg_id != 0x001B) { // ButtonAck message (id 27) + return; + } + uint8_t hash[32]; + sha256_Raw((unsigned char *)FLASH_APP_START, flash_len - FLASH_META_DESC_LEN, hash); + layoutFirmwareHash(hash); + do { + delay(100000); + buttonUpdate(); + } while (!button.YesUp && !button.NoUp); + } + + bool hash_check_ok = brand_new_firmware || button.YesUp; + + layoutProgress("INSTALLING ... Please wait", 1000); + uint8_t flags = *((uint8_t *)FLASH_META_FLAGS); + // wipe storage if: + // 0) there was no firmware + // 1) old firmware was unsigned + // 2) firmware restore flag isn't set + // 3) signatures are not ok + if (brand_new_firmware || old_was_unsigned || (flags & 0x01) == 0 || SIG_OK != signatures_ok(NULL)) { + memzero(meta_backup, sizeof(meta_backup)); + } + // copy new firmware header + memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_DESC_LEN); + // write "TRZR" in header only when hash was confirmed + if (hash_check_ok) { + memcpy(meta_backup, FIRMWARE_MAGIC, 4); + } else { + memzero(meta_backup, 4); + } + + // no need to erase, because we are not changing any already flashed byte. + restore_metadata(meta_backup); + memzero(meta_backup, sizeof(meta_backup)); + + flash_state = STATE_END; + if (hash_check_ok) { + layoutDialog(&bmp_icon_ok, NULL, NULL, NULL, "New firmware", "successfully installed.", NULL, "You may now", "unplug your TREZOR.", NULL); + send_msg_success(dev); + } else { + layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, "Firmware installation", "aborted.", NULL, "You need to repeat", "the procedure with", "the correct firmware."); + send_msg_failure(dev); + } + return; + } + +} + +static void hid_set_config(usbd_device *dev, uint16_t wValue) +{ + (void)wValue; + + usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback); + + usbd_register_control_callback( + dev, + USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + hid_control_request + ); +} + +static usbd_device *usbd_dev; +static uint8_t usbd_control_buffer[128]; + +void checkButtons(void) +{ + static bool btn_left = false, btn_right = false, btn_final = false; + if (btn_final) { + return; + } + uint16_t state = gpio_port_read(BTN_PORT); + if ((state & (BTN_PIN_YES | BTN_PIN_NO)) != (BTN_PIN_YES | BTN_PIN_NO)) { + if ((state & BTN_PIN_NO) != BTN_PIN_NO) { + btn_left = true; + } + if ((state & BTN_PIN_YES) != BTN_PIN_YES) { + btn_right = true; + } + } + if (btn_left) { + oledBox(0, 0, 3, 3, true); + } + if (btn_right) { + oledBox(OLED_WIDTH - 4, 0, OLED_WIDTH - 1, 3, true); + } + if (btn_left || btn_right) { + oledRefresh(); + } + if (btn_left && btn_right) { + btn_final = true; + } +} + +void usbLoop(bool firmware_present) +{ + brand_new_firmware = !firmware_present; + usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); + usbd_register_set_config_callback(usbd_dev, hid_set_config); + for (;;) { + usbd_poll(usbd_dev); + if (brand_new_firmware && (flash_state == STATE_READY || flash_state == STATE_OPEN)) { + checkButtons(); + } + } +} diff --git a/hardware-wallet/firmware/bootloader/usb.h b/hardware-wallet/firmware/bootloader/usb.h new file mode 100644 index 00000000..fea6e680 --- /dev/null +++ b/hardware-wallet/firmware/bootloader/usb.h @@ -0,0 +1,25 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __USB_H__ +#define __USB_H__ + +void usbLoop(bool firmware_present); + +#endif diff --git a/hardware-wallet/firmware/build-bootloader.sh b/hardware-wallet/firmware/build-bootloader.sh new file mode 100755 index 00000000..fe413566 --- /dev/null +++ b/hardware-wallet/firmware/build-bootloader.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -e + +IMAGE=trezor-mcu-build +TAG=${1:-master} +BINFILE=build/bootloader-$TAG.bin +ELFFILE=build/bootloader-$TAG.elf + +docker build -t $IMAGE . +docker run -t -v $(pwd)/build:/build:z $IMAGE /bin/sh -c "\ + git clone https://github.com/trezor/trezor-mcu && \ + cd trezor-mcu && \ + git checkout $TAG && \ + git submodule update --init && \ + make -C vendor/libopencm3 && \ + make && \ + make -C bootloader align && \ + cp bootloader/bootloader.bin /$BINFILE && \ + cp bootloader/bootloader.elf /$ELFFILE" +/usr/bin/env python -c " +from __future__ import print_function +import hashlib +import sys +fn = sys.argv[1] +data = open(fn, 'rb').read() +print('\n\n') +print('Filename :', fn) +print('Fingerprint :', hashlib.sha256(hashlib.sha256(data).digest()).hexdigest()) +print('Size : %d bytes (out of %d maximum)' % (len(data), 32768)) +" $BINFILE diff --git a/hardware-wallet/firmware/build-emulator.sh b/hardware-wallet/firmware/build-emulator.sh new file mode 100755 index 00000000..37b16952 --- /dev/null +++ b/hardware-wallet/firmware/build-emulator.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +IMAGE=trezor-mcu-build-emulator +TAG=${1:-master} +ELFFILE=build/trezor-emulator-$TAG + +docker build -f Dockerfile.emulator -t $IMAGE . +docker run -t -v $(pwd)/build:/build:z $IMAGE /bin/sh -c "\ + git clone https://github.com/trezor/trezor-mcu && \ + cd trezor-mcu && \ + git checkout $TAG && \ + git submodule update --init && \ + make -C vendor/nanopb/generator/proto && \ + make -C firmware/protob && \ + EMULATOR=1 make && \ + EMULATOR=1 make -C emulator && \ + EMULATOR=1 make -C firmware && \ + cp firmware/trezor.elf /$ELFFILE" diff --git a/hardware-wallet/firmware/build-firmware.sh b/hardware-wallet/firmware/build-firmware.sh new file mode 100755 index 00000000..6543b7fc --- /dev/null +++ b/hardware-wallet/firmware/build-firmware.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e + +IMAGE=trezor-mcu-build +TAG=${1:-master} +BINFILE=build/trezor-$TAG.bin +ELFFILE=build/trezor-$TAG.elf + +docker build -t $IMAGE . +docker run -t -v $(pwd)/build:/build:z $IMAGE /bin/sh -c "\ + git clone https://github.com/trezor/trezor-mcu && \ + cd trezor-mcu && \ + git checkout $TAG && \ + git submodule update --init && \ + make -C vendor/libopencm3 && \ + make -C vendor/nanopb/generator/proto && \ + make -C firmware/protob && \ + make && \ + make -C firmware sign && \ + cp firmware/trezor.bin /$BINFILE && \ + cp firmware/trezor.elf /$ELFFILE" + +/usr/bin/env python -c " +from __future__ import print_function +import hashlib +import sys +fn = sys.argv[1] +data = open(fn, 'rb').read() +print('\n\n') +print('Filename :', fn) +print('Fingerprint :', hashlib.sha256(data[256:]).hexdigest()) +print('Size : %d bytes (out of %d maximum)' % (len(data), 491520)) +" $BINFILE diff --git a/hardware-wallet/firmware/buttons.c b/hardware-wallet/firmware/buttons.c new file mode 100644 index 00000000..a6e64b5a --- /dev/null +++ b/hardware-wallet/firmware/buttons.c @@ -0,0 +1,74 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "buttons.h" + +struct buttonState button; + +#if !EMULATOR +uint16_t buttonRead(void) { + return gpio_port_read(BTN_PORT); +} +#endif + +void buttonUpdate() +{ + uint16_t state; + static uint16_t last_state = BTN_PIN_YES | BTN_PIN_NO; + + state = buttonRead(); + + if ((state & BTN_PIN_YES) == 0) { // Yes button is down + if ((last_state & BTN_PIN_YES) == 0) { // last Yes was down + if (button.YesDown < 2000000000) button.YesDown++; + button.YesUp = false; + } else { // last Yes was up + button.YesDown = 0; + button.YesUp = false; + } + } else { // Yes button is up + if ((last_state & BTN_PIN_YES) == 0) { // last Yes was down + button.YesDown = 0; + button.YesUp = true; + } else { // last Yes was up + button.YesDown = 0; + button.YesUp = false; + } + } + + if ((state & BTN_PIN_NO) == 0) { // No button is down + if ((last_state & BTN_PIN_NO) == 0) { // last No was down + if (button.NoDown < 2000000000) button.NoDown++; + button.NoUp = false; + } else { // last No was up + button.NoDown = 0; + button.NoUp = false; + } + } else { // No button is up + if ((last_state & BTN_PIN_NO) == 0) { // last No was down + button.NoDown = 0; + button.NoUp = true; + } else { // last No was up + button.NoDown = 0; + button.NoUp = false; + } + } + + last_state = state; +} diff --git a/hardware-wallet/firmware/buttons.h b/hardware-wallet/firmware/buttons.h new file mode 100644 index 00000000..fb24d58d --- /dev/null +++ b/hardware-wallet/firmware/buttons.h @@ -0,0 +1,50 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __BUTTONS_H__ +#define __BUTTONS_H__ + +#include +#include + +struct buttonState { + volatile bool YesUp; + volatile int YesDown; + volatile bool NoUp; + volatile int NoDown; +}; + +extern struct buttonState button; + +uint16_t buttonRead(void); +void buttonUpdate(void); + +#ifndef BTN_PORT +#define BTN_PORT GPIOC +#endif + +#ifndef BTN_PIN_YES +#define BTN_PIN_YES GPIO2 +#endif + +#ifndef BTN_PIN_NO +#define BTN_PIN_NO GPIO5 +#endif + +#endif diff --git a/hardware-wallet/firmware/demo/Makefile b/hardware-wallet/firmware/demo/Makefile new file mode 100644 index 00000000..306597b7 --- /dev/null +++ b/hardware-wallet/firmware/demo/Makefile @@ -0,0 +1,18 @@ +APPVER = 1.0.0 + +NAME = demo + +OBJS += demo.o + +OBJS += ../vendor/trezor-crypto/bignum.o +OBJS += ../vendor/trezor-crypto/bip32.o +OBJS += ../vendor/trezor-crypto/ecdsa.o +OBJS += ../vendor/trezor-crypto/hmac.o +OBJS += ../vendor/trezor-crypto/ripemd160.o +OBJS += ../vendor/trezor-crypto/secp256k1.o +OBJS += ../vendor/trezor-crypto/sha2.o +OBJS += ../vendor/trezor-crypto/bip39.o +OBJS += ../vendor/trezor-crypto/pbkdf2.o +OBJS += ../vendor/trezor-crypto/memzero.o + +include ../Makefile.include diff --git a/hardware-wallet/firmware/demo/demo.c b/hardware-wallet/firmware/demo/demo.c new file mode 100644 index 00000000..7a92d15b --- /dev/null +++ b/hardware-wallet/firmware/demo/demo.c @@ -0,0 +1,291 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include "bitmaps.h" +#include "buttons.h" +#include "layout.h" +#include "oled.h" +#include "setup.h" +#include "hmac.h" +#include "pbkdf2.h" +#include "rng.h" + +const int states = 2; +int state = 0; +int frame = 0; + +uint8_t seed[128]; +uint8_t *pass = (uint8_t *)"meadow"; +uint32_t passlen; +uint8_t *salt = (uint8_t *)"TREZOR"; +uint32_t saltlen; + +static const struct usb_device_descriptor dev_descr = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x534c, + .idProduct = 0x0001, + .bcdDevice = 0x0100, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +/* got via usbhid-dump from CP2110 */ +static const uint8_t hid_report_descriptor[] = { + 0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x09, 0x01, 0x75, 0x08, 0x95, 0x40, 0x26, 0xFF, 0x00, + 0x15, 0x00, 0x85, 0x01, 0x95, 0x01, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x02, + 0x95, 0x02, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x03, 0x95, 0x03, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x04, 0x95, 0x04, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x05, 0x95, 0x05, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x06, + 0x95, 0x06, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x07, 0x95, 0x07, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x08, 0x95, 0x08, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x09, 0x95, 0x09, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0A, + 0x95, 0x0A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0B, 0x95, 0x0B, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0C, 0x95, 0x0C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x0D, 0x95, 0x0D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0E, + 0x95, 0x0E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0F, 0x95, 0x0F, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x10, 0x95, 0x10, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x11, 0x95, 0x11, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x12, + 0x95, 0x12, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x13, 0x95, 0x13, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x14, 0x95, 0x14, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x15, 0x95, 0x15, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x16, + 0x95, 0x16, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x17, 0x95, 0x17, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x18, 0x95, 0x18, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x19, 0x95, 0x19, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1A, + 0x95, 0x1A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1B, 0x95, 0x1B, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1C, 0x95, 0x1C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x1D, 0x95, 0x1D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1E, + 0x95, 0x1E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1F, 0x95, 0x1F, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x20, 0x95, 0x20, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x21, 0x95, 0x21, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x22, + 0x95, 0x22, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x23, 0x95, 0x23, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x24, 0x95, 0x24, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x25, 0x95, 0x25, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x26, + 0x95, 0x26, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x27, 0x95, 0x27, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x28, 0x95, 0x28, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x29, 0x95, 0x29, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2A, + 0x95, 0x2A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2B, 0x95, 0x2B, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2C, 0x95, 0x2C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x2D, 0x95, 0x2D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2E, + 0x95, 0x2E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2F, 0x95, 0x2F, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x30, 0x95, 0x30, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x31, 0x95, 0x31, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x32, + 0x95, 0x32, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x33, 0x95, 0x33, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x34, 0x95, 0x34, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x35, 0x95, 0x35, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x36, + 0x95, 0x36, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x37, 0x95, 0x37, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x38, 0x95, 0x38, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x39, 0x95, 0x39, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3A, + 0x95, 0x3A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3B, 0x95, 0x3B, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3C, 0x95, 0x3C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, + 0x91, 0x02, 0x85, 0x3D, 0x95, 0x3D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3E, + 0x95, 0x3E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3F, 0x95, 0x3F, 0x09, 0x01, + 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x40, 0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x41, + 0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x42, 0x95, 0x06, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x43, + 0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x44, 0x95, 0x02, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x45, + 0x95, 0x04, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x46, 0x95, 0x02, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x47, + 0x95, 0x02, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x50, 0x95, 0x08, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x51, + 0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x52, 0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x60, + 0x95, 0x0A, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x61, 0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x62, + 0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x63, 0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x64, + 0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x65, 0x95, 0x3E, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x66, + 0x95, 0x13, 0x09, 0x01, 0xB1, 0x02, 0xC0, +}; + +static const struct { + struct usb_hid_descriptor hid_descriptor; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report; +} __attribute__((packed)) hid_function = { + .hid_descriptor = { + .bLength = sizeof(hid_function), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0111, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor), + } +}; + +static const struct usb_endpoint_descriptor hid_endpoints[2] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x81, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x02, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}}; + +static const struct usb_interface_descriptor hid_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + .endpoint = hid_endpoints, + .extra = &hid_function, + .extralen = sizeof(hid_function), +}}; + +static const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = hid_iface, +}}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + .interface = ifaces, +}; + +static const char *usb_strings[] = { + "SatoshiLabs", + "TREZOR", + "01234567", +}; + +static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) +{ + (void)complete; + (void)dev; + + if ((req->bmRequestType != 0x81) || + (req->bRequest != USB_REQ_GET_DESCRIPTOR) || + (req->wValue != 0x2200)) + return 0; + + /* Handle the HID report descriptor. */ + *buf = (uint8_t *)hid_report_descriptor; + *len = sizeof(hid_report_descriptor); + + return 1; +} + +static void hid_rx_callback(usbd_device *dev, uint8_t ep) +{ + (void)dev; + (void)ep; +} + +static void hid_set_config(usbd_device *dev, uint16_t wValue) +{ + (void)wValue; + + usbd_ep_setup(dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, 0x02, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback); + + usbd_register_control_callback( + dev, + USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + hid_control_request); +} + +static usbd_device *usbd_dev; +static uint8_t usbd_control_buffer[128]; + +void usbInit(void) +{ + usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); + usbd_register_set_config_callback(usbd_dev, hid_set_config); +} + +int main(void) +{ +#ifndef APPVER + setup(); + __stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks + oledInit(); +#else + setupApp(); + __stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks +#endif + + usbInit(); + + passlen = strlen((char *)pass); + saltlen = strlen((char *)salt); + + for (;;) { + frame = 0; + switch (state) { + case 0: + oledClear(); + oledDrawBitmap(40, 0, &bmp_logo64); + break; + } + oledRefresh(); + + do { + usbd_poll(usbd_dev); + switch (state) { + case 1: + layoutProgress("WORKING", frame % 41 * 25); + pbkdf2_hmac_sha512(pass, passlen, salt, saltlen, 100, seed); + usbd_ep_write_packet(usbd_dev, 0x81, seed, 64); + break; + } + + buttonUpdate(); + frame += 1; + } while (!button.YesUp && !button.NoUp); + + if (button.YesUp) { + state = (state + 1) % states; + oledSwipeLeft(); + } else { + state = (state + states - 1) % states; + oledSwipeRight(); + } + } + + return 0; +} diff --git a/hardware-wallet/firmware/emulator/Makefile b/hardware-wallet/firmware/emulator/Makefile new file mode 100644 index 00000000..1f2976dd --- /dev/null +++ b/hardware-wallet/firmware/emulator/Makefile @@ -0,0 +1,17 @@ +EMULATOR := 1 + +OBJS += setup.o + +OBJS += buttons.o +OBJS += flash.o +OBJS += oled.o +OBJS += rng.o +OBJS += timer.o +OBJS += udp.o + +OBJS += strl.o + +libemulator.a: $(OBJS) + $(AR) rcs $@ $(OBJS) + +include ../Makefile.include diff --git a/hardware-wallet/firmware/emulator/buttons.c b/hardware-wallet/firmware/emulator/buttons.c new file mode 100644 index 00000000..71b94a44 --- /dev/null +++ b/hardware-wallet/firmware/emulator/buttons.c @@ -0,0 +1,40 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "buttons.h" + +#if !HEADLESS +#include +#endif + +uint16_t buttonRead(void) { + uint16_t state = 0; + +#if !HEADLESS + const uint8_t *scancodes = SDL_GetKeyboardState(NULL); + if (scancodes[SDL_SCANCODE_LEFT]) { + state |= BTN_PIN_NO; + } + if (scancodes[SDL_SCANCODE_RIGHT]) { + state |= BTN_PIN_YES; + } +#endif + + return ~state; +} diff --git a/hardware-wallet/firmware/emulator/emulator.h b/hardware-wallet/firmware/emulator/emulator.h new file mode 100644 index 00000000..deaa73de --- /dev/null +++ b/hardware-wallet/firmware/emulator/emulator.h @@ -0,0 +1,40 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __EMULATOR_H__ +#define __EMULATOR_H__ + +#if EMULATOR + +#include "strl.h" + +#include + +extern void *emulator_flash_base; + +void emulatorPoll(void); +void emulatorRandom(void *buffer, size_t size); + +void emulatorSocketInit(void); +size_t emulatorSocketRead(void *buffer, size_t size); +size_t emulatorSocketWrite(const void *buffer, size_t size); + +#endif + +#endif diff --git a/hardware-wallet/firmware/emulator/flash.c b/hardware-wallet/firmware/emulator/flash.c new file mode 100644 index 00000000..708dd259 --- /dev/null +++ b/hardware-wallet/firmware/emulator/flash.c @@ -0,0 +1,114 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include + +#include "memory.h" + +void flash_lock(void) {} +void flash_unlock(void) {} + +void flash_clear_status_flags(void) {} + +void flash_lock_option_bytes(void) {} +void flash_unlock_option_bytes(void) {} + +void flash_program_option_bytes(uint32_t data) { + (void) data; +} + +static ssize_t sector_to_offset(uint8_t sector) { + switch (sector) { + case 0: + return 0x0; + case 1: + return 0x4000; + case 2: + return 0x8000; + case 3: + return 0xC000; + case 4: + return 0x10000; + case 5: + return 0x20000; + case 6: + return 0x40000; + case 7: + return 0x60000; + case 8: + return 0x80000; + default: + return -1; + } +} + +static void *sector_to_address(uint8_t sector) { + ssize_t offset = sector_to_offset(sector); + if (offset < 0) { + return NULL; + } + + return (void *) (FLASH_ORIGIN + offset); +} + +static ssize_t sector_to_size(uint8_t sector) { + ssize_t start = sector_to_offset(sector); + if (start < 0) { + return -1; + } + + ssize_t end = sector_to_offset(sector + 1); + if (end < 0) { + return -1; + } + + return end - start; +} + +void flash_erase_sector(uint8_t sector, uint32_t program_size) { + (void) program_size; + + void *address = sector_to_address(sector); + if (address == NULL) { + return; + } + + ssize_t size = sector_to_size(sector); + if (size < 0) { + return; + } + + memset(address, 0xFF, size); +} + +void flash_erase_all_sectors(uint32_t program_size) { + (void) program_size; + + memset(emulator_flash_base, 0xFF, FLASH_TOTAL_SIZE); +} + +void flash_program_word(uint32_t address, uint32_t data) { + MMIO32(address) = data; +} + +void flash_program_byte(uint32_t address, uint8_t data) { + MMIO8(address) = data; +} diff --git a/hardware-wallet/firmware/emulator/oled.c b/hardware-wallet/firmware/emulator/oled.c new file mode 100644 index 00000000..26babdb5 --- /dev/null +++ b/hardware-wallet/firmware/emulator/oled.c @@ -0,0 +1,121 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "oled.h" + +#if HEADLESS + +void oledInit(void) {} +void oledRefresh(void) {} +void emulatorPoll(void) {} + +#else + +#include + +static SDL_Renderer *renderer = NULL; +static SDL_Texture *texture = NULL; + +#define ENV_OLED_SCALE "TREZOR_OLED_SCALE" + +static int emulatorScale(void) { + const char *variable = getenv(ENV_OLED_SCALE); + if (!variable) { + return 1; + } + int scale = atoi(variable); + if (scale >= 1 && scale <= 16) { + return scale; + } + return 1; +} + +void oledInit(void) { + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + + int scale = emulatorScale(); + + SDL_Window *window = SDL_CreateWindow("TREZOR", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + OLED_WIDTH * scale, + OLED_HEIGHT * scale, + 0); + + if (window == NULL) { + fprintf(stderr, "Failed to create window: %s\n", SDL_GetError()); + exit(1); + } + + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (!renderer) { + fprintf(stderr, "Failed to create renderer: %s\n", SDL_GetError()); + exit(1); + } + + /* Use unscaled coordinate system */ + SDL_RenderSetLogicalSize(renderer, OLED_WIDTH, OLED_HEIGHT); + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, OLED_WIDTH, OLED_HEIGHT); + + oledClear(); + oledRefresh(); +} + +void oledRefresh(void) { + /* Draw triangle in upper right corner */ + oledInvertDebugLink(); + + const uint8_t *buffer = oledGetBuffer(); + + static uint32_t data[OLED_HEIGHT][OLED_WIDTH]; + + for (size_t i = 0; i < OLED_BUFSIZE; i++) { + int x = (OLED_BUFSIZE - 1 - i) % OLED_WIDTH; + int y = (OLED_BUFSIZE - 1 - i) / OLED_WIDTH * 8 + 7; + + for (uint8_t shift = 0; shift < 8; shift++, y--) { + bool set = (buffer[i] >> shift) & 1; + data[y][x] = set ? 0xFFFFFFFF : 0xFF000000; + } + } + + SDL_UpdateTexture(texture, NULL, data, OLED_WIDTH * sizeof(uint32_t)); + SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderPresent(renderer); + + /* Return it back */ + oledInvertDebugLink(); +} + +void emulatorPoll(void) { + SDL_Event event; + + if (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + exit(1); + } + } +} + +#endif diff --git a/hardware-wallet/firmware/emulator/rng.c b/hardware-wallet/firmware/emulator/rng.c new file mode 100644 index 00000000..8d53de28 --- /dev/null +++ b/hardware-wallet/firmware/emulator/rng.c @@ -0,0 +1,32 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "rng.h" + +uint32_t random32(void) { + static uint32_t last = 0; + uint32_t new; + + do { + emulatorRandom(&new, sizeof(new)); + } while (last == new); + + last = new; + return new; +} diff --git a/hardware-wallet/firmware/emulator/setup.c b/hardware-wallet/firmware/emulator/setup.c new file mode 100644 index 00000000..f994916d --- /dev/null +++ b/hardware-wallet/firmware/emulator/setup.c @@ -0,0 +1,95 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "memory.h" +#include "oled.h" +#include "rng.h" +#include "setup.h" +#include "timer.h" + +#define EMULATOR_FLASH_FILE "emulator.img" + +void *emulator_flash_base = NULL; + +uint32_t __stack_chk_guard; + +static int urandom = -1; + +static void setup_urandom(void); +static void setup_flash(void); + +void setup(void) { + setup_urandom(); + setup_flash(); +} + +void emulatorRandom(void *buffer, size_t size) { + ssize_t n = read(urandom, buffer, size); + if (n < 0 || ((size_t) n) != size) { + perror("Failed to read /dev/urandom"); + exit(1); + } +} + +static void setup_urandom(void) { + urandom = open("/dev/urandom", O_RDONLY); + if (urandom < 0) { + perror("Failed to open /dev/urandom"); + exit(1); + } +} + +static void setup_flash(void) { + int fd = open(EMULATOR_FLASH_FILE, O_RDWR | O_SYNC | O_CREAT, 0644); + if (fd < 0) { + perror("Failed to open flash emulation file"); + exit(1); + } + + off_t length = lseek(fd, 0, SEEK_END); + if (length < 0) { + perror("Failed to read length of flash emulation file"); + exit(1); + } + + emulator_flash_base = mmap(NULL, FLASH_TOTAL_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (emulator_flash_base == MAP_FAILED) { + perror("Failed to map flash emulation file"); + exit(1); + } + + if (length < FLASH_TOTAL_SIZE) { + if (ftruncate(fd, FLASH_TOTAL_SIZE) != 0) { + perror("Failed to initialize flash emulation file"); + exit(1); + } + + /* Initialize the flash */ + flash_erase_all_sectors(FLASH_CR_PROGRAM_X32); + } +} diff --git a/hardware-wallet/firmware/emulator/strl.c b/hardware-wallet/firmware/emulator/strl.c new file mode 100644 index 00000000..6c87be93 --- /dev/null +++ b/hardware-wallet/firmware/emulator/strl.c @@ -0,0 +1,41 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "strl.h" +#include "util.h" + +#include + +size_t strlcpy(char *dst, const char *src, size_t size) { + size_t ret = strlen(src); + + if (size) { + size_t len = MIN(ret, size - 1); + memcpy(dst, src, len); + dst[len] = '\0'; + } + + return ret; +} + +size_t strlcat(char *dst, const char *src, size_t size) { + size_t n = strnlen(dst, size); + + return n + strlcpy(&dst[n], src, size - n); +} diff --git a/hardware-wallet/firmware/emulator/strl.h b/hardware-wallet/firmware/emulator/strl.h new file mode 100644 index 00000000..8b44e045 --- /dev/null +++ b/hardware-wallet/firmware/emulator/strl.h @@ -0,0 +1,28 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __STRL_H__ +#define __STRL_H__ + +#include + +size_t strlcpy(char *dst, const char *src, size_t size); +size_t strlcat(char *dst, const char *src, size_t size); + +#endif diff --git a/hardware-wallet/firmware/emulator/timer.c b/hardware-wallet/firmware/emulator/timer.c new file mode 100644 index 00000000..eadbf76c --- /dev/null +++ b/hardware-wallet/firmware/emulator/timer.c @@ -0,0 +1,32 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include "timer.h" + +void timer_init(void) {} + +uint32_t timer_ms(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + uint32_t msec = t.tv_sec * 1000 + (t.tv_nsec / 1000000); + return msec; +} diff --git a/hardware-wallet/firmware/emulator/udp.c b/hardware-wallet/firmware/emulator/udp.c new file mode 100644 index 00000000..b01ec66b --- /dev/null +++ b/hardware-wallet/firmware/emulator/udp.c @@ -0,0 +1,85 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define TREZOR_UDP_PORT 21324 + +static int fd = -1; +static struct sockaddr_in from; +static socklen_t fromlen; + +void emulatorSocketInit(void) { + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) { + perror("Failed to create socket"); + exit(1); + } + + fromlen = 0; + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(TREZOR_UDP_PORT); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { + perror("Failed to bind socket"); + exit(1); + } +} + +size_t emulatorSocketRead(void *buffer, size_t size) { + fromlen = sizeof(from); + ssize_t n = recvfrom(fd, buffer, size, MSG_DONTWAIT, (struct sockaddr *) &from, &fromlen); + + if (n < 0) { + if (errno != EAGAIN && errno != EWOULDBLOCK) { + perror("Failed to read socket"); + } + return 0; + } + + static const char msg_ping[] = { 'P', 'I', 'N', 'G', 'P', 'I', 'N', 'G' }; + static const char msg_pong[] = { 'P', 'O', 'N', 'G', 'P', 'O', 'N', 'G' }; + + if (n == sizeof(msg_ping) && memcmp(buffer, msg_ping, sizeof(msg_ping)) == 0) { + emulatorSocketWrite(msg_pong, sizeof(msg_pong)); + return 0; + } + + return n; +} + +size_t emulatorSocketWrite(const void *buffer, size_t size) { + if (fromlen > 0) { + ssize_t n = sendto(fd, buffer, size, MSG_DONTWAIT, (const struct sockaddr *) &from, fromlen); + if (n < 0 || ((size_t) n) != size) { + perror("Failed to write socket"); + return 0; + } + } + + return size; +} diff --git a/hardware-wallet/firmware/fastflash/Makefile b/hardware-wallet/firmware/fastflash/Makefile new file mode 100644 index 00000000..5b768eb4 --- /dev/null +++ b/hardware-wallet/firmware/fastflash/Makefile @@ -0,0 +1,22 @@ +APPVER = fastflash + +NAME = bootloader + +OBJS += bootloader.o +OBJS += signatures.o +OBJS += usb.o + +OBJS += ../vendor/trezor-crypto/bignum.small.o +OBJS += ../vendor/trezor-crypto/ecdsa.small.o +OBJS += ../vendor/trezor-crypto/secp256k1.small.o +OBJS += ../vendor/trezor-crypto/sha2.small.o +OBJS += ../vendor/trezor-crypto/memzero.small.o + +CFLAGS += -DUSE_PRECOMPUTED_IV=0 +CFLAGS += -DUSE_PRECOMPUTED_CP=0 + +OPTFLAGS ?= -Os + +include ../Makefile.include + +CFLAGS += -I../bootloader diff --git a/hardware-wallet/firmware/fastflash/bootloader.c b/hardware-wallet/firmware/fastflash/bootloader.c new file mode 120000 index 00000000..3c60d798 --- /dev/null +++ b/hardware-wallet/firmware/fastflash/bootloader.c @@ -0,0 +1 @@ +../bootloader/bootloader.c \ No newline at end of file diff --git a/hardware-wallet/firmware/fastflash/signatures.c b/hardware-wallet/firmware/fastflash/signatures.c new file mode 100644 index 00000000..556dd6a9 --- /dev/null +++ b/hardware-wallet/firmware/fastflash/signatures.c @@ -0,0 +1,28 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +int signatures_ok(uint8_t *store_hash) +{ + (void) store_hash; + + return false; +} diff --git a/hardware-wallet/firmware/fastflash/usb.c b/hardware-wallet/firmware/fastflash/usb.c new file mode 120000 index 00000000..13b2a33e --- /dev/null +++ b/hardware-wallet/firmware/fastflash/usb.c @@ -0,0 +1 @@ +../bootloader/usb.c \ No newline at end of file diff --git a/hardware-wallet/firmware/firmware/.gitignore b/hardware-wallet/firmware/firmware/.gitignore new file mode 100644 index 00000000..be84b50d --- /dev/null +++ b/hardware-wallet/firmware/firmware/.gitignore @@ -0,0 +1,4 @@ +coins_array.h +coins_count.h + +nem_mosaics.[ch] diff --git a/hardware-wallet/firmware/firmware/ChangeLog b/hardware-wallet/firmware/firmware/ChangeLog new file mode 100644 index 00000000..5ca85f1a --- /dev/null +++ b/hardware-wallet/firmware/firmware/ChangeLog @@ -0,0 +1,126 @@ +Version 1.6.1 +* Stable release, optional update +* Use fixed-width font for addresses +* Lots of under-the-hood improvements + +Version 1.6.0 +* Stable release, optional update +* Native SegWit (Bech32) address support +* Show recognized BIP44/BIP49 paths in GetAddress dialog +* NEM support +* Expanse and UBIQ chains support +* Bitcoin Gold, DigiByte, Monacoin support +* Ed25519 collective signatures (CoSi) support + +Version 1.5.2 +* Stable release, required update +* Clean memory on start +* Fix storage import from older versions + +Version 1.5.1 +* Stable release, optional update +* Wipe storage after 16 wrong PIN attempts +* Enable Segwit for Bitcoin +* Bcash aka Bitcoin Cash support +* Message signing/verification for Ethereum and Segwit +* Make address dialog nicer (switch text/QR via button) +* Use checksum for Ethereum addresses +* Add more ERC-20 tokens, handle unrecognized ERC-20 tokens +* Allow "dry run" recovery procedure +* Allow separated backup procedure + +Version 1.5.0 +* Stable release, optional update +* Enable Segwit for Testnet and Litecoin +* Enable ERC-20 tokens for Ethereum chains + +Version 1.4.2 +* Stable release, optional update +* New Matrix-based recovery method +* Minor Ethereum fixes (including EIP-155 replay protection) +* Minor USB, U2F and GPG fixes + +Version 1.4.1 +* Stable release, optional update +* Support for Zcash JoinSplit transactions +* Enable device lock after 10 minutes of inactivity +* Enable device lock by pressing left button for 2 seconds +* Confirm dialog for U2F counter change + +Version 1.4.0 +* Stable release, optional update +* U2F support +* Ethereum support +* GPG decryption support +* Zcash support + +Version 1.3.6 +* Stable release, optional update +* Enable advanced transactions such as ones with REPLACE-BY-FEE and CHECKLOCKTIMEVERIFY +* Fix message signing for altcoins +* Message verification now shows address +* Enable GPG signing support +* Enable Ed25519 curve (for SSH and GPG) +* Use separate deterministic hierarchy for NIST256P1 and Ed25519 curves +* Users using SSH already need to regenerate their keys using the new firmware!!! + +Version 1.3.5 +* Stable release, optional update +* Double size font for recovery words during the device setup +* Optimizations for simultaneous access when more applications try communicate with the device + +Version 1.3.4 +* Stable release, optional update +* Screensaver active on ClearSession message +* Support for NIST P-256 curve +* Updated SignIdentity to v2 format +* Show seconds counter during PIN lockdown +* Updated maxfee per kb for coins + +Version 1.3.3 +* Stable release, mandatory update +* Ask for PIN on GetAddress and GetPublicKey +* Signing speed improved + +Version 1.3.2 +* Stable release, optional update +* Fix check during transaction streaming +* Login feature via SignIdentity message +* GetAddress for multisig shows M of N description +* PIN checking in constant time + +Version 1.3.1 +* Stable release, optional update +* Optimized signing speed +* Enabled OP_RETURN +* Added option to change home screen +* Moved fee calculation before any signing +* Made PIN delay increase immune against hardware hacking + +Version 1.3.0 +* Stable release, optional update +* Added multisig support +* Added visual validation of receiving address +* Added ECIES encryption capabilities + +Version 1.2.1 +* Stable release, mandatory update +* Added stack overflow protection +* Added compatibility with TREZOR Bridge + +Version 1.2.0 +* Stable release, optional update +* Fix false positives for fee warning +* Better UI for signing/verifying messages +* Smaller firmware size + +Version 1.1.0 +* Stable release, optional update +* Minor UI fixes +* Better handling of unexpected messages +* Added AES support + +Version 1.0.0 +* Stable release, mandatory update +* Added support for streaming of transactions into the device +* Removed all current limits on size of signed transaction diff --git a/hardware-wallet/firmware/firmware/Makefile b/hardware-wallet/firmware/firmware/Makefile new file mode 100644 index 00000000..198bbb90 --- /dev/null +++ b/hardware-wallet/firmware/firmware/Makefile @@ -0,0 +1,127 @@ +APPVER = 1.0.0 + +ifeq ($(FASTFLASH),1) +OBJS += fastflash.o +OBJS += bootloader.o +endif + +NAME = trezor + +ifeq ($(EMULATOR),1) +OBJS += udp.o +else +OBJS += usb.o +endif + +OBJS += u2f.o +OBJS += messages.o +OBJS += storage.o +OBJS += trezor.o +OBJS += pinmatrix.o +OBJS += fsm.o +OBJS += coins.o +OBJS += transaction.o +OBJS += protect.o +OBJS += layout2.o +OBJS += recovery.o +OBJS += reset.o +OBJS += signing.o +OBJS += crypto.o +OBJS += ethereum.o +OBJS += ethereum_tokens.o +OBJS += nem2.o +OBJS += nem_mosaics.o + +OBJS += debug.o + +OBJS += ../vendor/trezor-crypto/address.o +OBJS += ../vendor/trezor-crypto/bignum.o +OBJS += ../vendor/trezor-crypto/ecdsa.o +OBJS += ../vendor/trezor-crypto/curves.o +OBJS += ../vendor/trezor-crypto/secp256k1.o +OBJS += ../vendor/trezor-crypto/nist256p1.o +OBJS += ../vendor/trezor-crypto/rand.o +OBJS += ../vendor/trezor-crypto/memzero.o + +OBJS += ../vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/ed25519.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/ed25519-sha3.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/ed25519-keccak.o + +OBJS += ../vendor/trezor-crypto/hmac.o +OBJS += ../vendor/trezor-crypto/bip32.o +OBJS += ../vendor/trezor-crypto/bip39.o +OBJS += ../vendor/trezor-crypto/pbkdf2.o +OBJS += ../vendor/trezor-crypto/base32.o +OBJS += ../vendor/trezor-crypto/base58.o +OBJS += ../vendor/trezor-crypto/segwit_addr.o + +OBJS += ../vendor/trezor-crypto/ripemd160.o +OBJS += ../vendor/trezor-crypto/sha2.o +OBJS += ../vendor/trezor-crypto/sha3.o +OBJS += ../vendor/trezor-crypto/blake256.o +OBJS += ../vendor/trezor-crypto/hasher.o + +OBJS += ../vendor/trezor-crypto/aes/aescrypt.o +OBJS += ../vendor/trezor-crypto/aes/aeskey.o +OBJS += ../vendor/trezor-crypto/aes/aestab.o +OBJS += ../vendor/trezor-crypto/aes/aes_modes.o + +OBJS += ../vendor/trezor-crypto/nem.o + +OBJS += ../vendor/trezor-qrenc/qr_encode.o + +OBJS += ../vendor/nanopb/pb_common.o +OBJS += ../vendor/nanopb/pb_decode.o +OBJS += ../vendor/nanopb/pb_encode.o + +OBJS += protob/messages.pb.o +OBJS += protob/types.pb.o + +OBJS += ../vendor/skycoin-crypto/skycoin_crypto.o + +include ../Makefile.include + +ifeq ($(FASTFLASH),1) +CFLAGS += -DFASTFLASH=1 +else +CFLAGS += -DFASTFLASH=0 +endif + +DEBUG_LINK ?= 0 +DEBUG_LOG ?= 0 + +CFLAGS += -Wno-sequence-point +CFLAGS += -I../vendor/nanopb -Iprotob -DPB_FIELD_16BIT=1 +CFLAGS += -DQR_MAX_VERSION=0 +CFLAGS += -DDEBUG_LINK=$(DEBUG_LINK) +CFLAGS += -DDEBUG_LOG=$(DEBUG_LOG) +CFLAGS += -DSCM_REVISION='"$(shell git rev-parse HEAD | sed 's:\(..\):\\x\1:g')"' +CFLAGS += -DUSE_ETHEREUM=1 +CFLAGS += -DUSE_NEM=1 + +bootloader.o: ../fastflash/bootloader.bin + $(OBJCOPY) -I binary -O elf32-littlearm -B arm \ + --redefine-sym _binary_$(shell echo -n "$<" | tr -c "[:alnum:]" "_")_start=__bootloader_start__ \ + --redefine-sym _binary_$(shell echo -n "$<" | tr -c "[:alnum:]" "_")_size=__bootloader_size__ \ + --rename-section .data=.rodata \ + $< $@ + +coins_count.h: coins-gen.py coins.json + $(PYTHON) $< count > $@ + +coins_array.h: coins-gen.py coins.json + $(PYTHON) $< array > $@ + +nem_mosaics.c nem_mosaics.h: nem_mosaics.py nem_mosaics.json + $(PYTHON) $< + +clean:: + rm -f coins_count.h coins_array.h + rm -f nem_mosaics.c nem_mosaics.h diff --git a/hardware-wallet/firmware/firmware/coins-gen.py b/hardware-wallet/firmware/firmware/coins-gen.py new file mode 100755 index 00000000..a184ccd9 --- /dev/null +++ b/hardware-wallet/firmware/firmware/coins-gen.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +from __future__ import print_function +import json, sys + +coins_json = json.load(open('coins.json', 'r')) + +coins_stable, coins_debug = [], [] + +if len(sys.argv) != 2 or sys.argv[1] not in ("count", "array"): + print("usage: coins-gen.py [count|array]\n", file=sys.stderr) + sys.exit(1) + + +def get_fields(coin): + return [ + '"%s"' % coin['coin_name'] if coin['coin_name'] is not None else 'NULL', + '" %s"' % coin['coin_shortcut'] if coin['coin_shortcut'] is not None else 'NULL', + '%d' % coin['maxfee_kb'] if coin['maxfee_kb'] is not None else '0', + '"\\x%02x" "%s"' % (len(coin['signed_message_header']), coin['signed_message_header'].replace('\n', '\\n')) if coin['signed_message_header'] is not None else 'NULL', + 'true' if coin['address_type'] is not None else 'false', + 'true' if coin['address_type_p2sh'] is not None else 'false', + 'true' if coin['segwit'] else 'false', + 'true' if coin['forkid'] is not None else 'false', + 'true' if coin['force_bip143'] else 'false', + '%d' % coin['address_type'] if coin['address_type'] is not None else '0', + '%d' % coin['address_type_p2sh'] if coin['address_type_p2sh'] is not None else '0', + '0x%s' % coin['xpub_magic'] if coin['xpub_magic'] is not None else '0x00000000', + '0x%s' % coin['xprv_magic'] if coin['xprv_magic'] is not None else '0x00000000', + '%d' % coin['forkid'] if coin['forkid'] else '0', + '"%s"' % coin['bech32_prefix'] if coin.get('bech32_prefix') is not None else 'NULL', + '0x%08x' % (0x80000000 + coin['bip44']), + '%s_NAME' % 'secp256k1'.upper(), + '&%s_info' % 'secp256k1', + ] + + +def justify_width(coins): + for j in range(len(coins[0])): + l = max([len(x[j]) for x in coins]) + 1 + for i in range(len(coins)): + if coins[i][j][0] in '0123456789': + coins[i][j] = (coins[i][j] + ',').rjust(l) + else: + coins[i][j] = (coins[i][j] + ',').ljust(l) + + +for coin in coins_json: + if coin['firmware'] == 'stable': + coins_stable.append(get_fields(coin)) + if coin['firmware'] == 'debug': + coins_debug.append(get_fields(coin)) + +justify_width(coins_stable) +justify_width(coins_debug) + +print("// THIS IS A GENERATED FILE - DO NOT HAND EDIT\n\n") + +if sys.argv[1] == "array": + for row in coins_stable: + print('\t{' + ' '.join(row) + ' },') + + print('#if DEBUG_LINK') + + for row in coins_debug: + print('\t{' + ' '.join(row) + ' },') + + print('#endif') + + +if sys.argv[1] == "count": + print('#if DEBUG_LINK') + print('#define COINS_COUNT %d' % (len(coins_stable) + len(coins_debug))) + print('#else') + print('#define COINS_COUNT %d' % (len(coins_stable))) + print('#endif') diff --git a/hardware-wallet/firmware/firmware/coins.c b/hardware-wallet/firmware/firmware/coins.c new file mode 100644 index 00000000..0618c60d --- /dev/null +++ b/hardware-wallet/firmware/firmware/coins.c @@ -0,0 +1,87 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include "coins.h" +#include "address.h" +#include "curves.h" +#include "ecdsa.h" +#include "base58.h" +#include "secp256k1.h" + +// filled CoinInfo structure defined in coins.h +const CoinInfo coins[COINS_COUNT] = { +#include "coins_array.h" +}; + +const CoinInfo *coinByName(const char *name) +{ + if (!name) return 0; + for (int i = 0; i < COINS_COUNT; i++) { + if (strcmp(name, coins[i].coin_name) == 0) { + return &(coins[i]); + } + } + return 0; +} + +const CoinInfo *coinByAddressType(uint32_t address_type) +{ + for (int i = 0; i < COINS_COUNT; i++) { + if (address_type == coins[i].address_type) { + return &(coins[i]); + } + } + return 0; +} + +const CoinInfo *coinByCoinType(uint32_t coin_type) +{ + for (int i = 0; i < COINS_COUNT; i++) { + if (coin_type == coins[i].coin_type) { + return &(coins[i]); + } + } + return 0; +} + +bool coinExtractAddressType(const CoinInfo *coin, const char *addr, uint32_t *address_type) +{ + if (!addr) return false; + uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; + int len = base58_decode_check(addr, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + if (len >= 21) { + return coinExtractAddressTypeRaw(coin, addr_raw, address_type); + } + return false; +} + +bool coinExtractAddressTypeRaw(const CoinInfo *coin, const uint8_t *addr_raw, uint32_t *address_type) +{ + if (coin->has_address_type && address_check_prefix(addr_raw, coin->address_type)) { + *address_type = coin->address_type; + return true; + } + if (coin->has_address_type_p2sh && address_check_prefix(addr_raw, coin->address_type_p2sh)) { + *address_type = coin->address_type_p2sh; + return true; + } + *address_type = 0; + return false; +} diff --git a/hardware-wallet/firmware/firmware/coins.h b/hardware-wallet/firmware/firmware/coins.h new file mode 100644 index 00000000..eae9bbd6 --- /dev/null +++ b/hardware-wallet/firmware/firmware/coins.h @@ -0,0 +1,60 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __COINS_H__ +#define __COINS_H__ + +#include +#include + +#include "bip32.h" +#include "coins_count.h" +#include "hasher.h" + +typedef struct _CoinInfo { + const char *coin_name; + const char *coin_shortcut; + uint64_t maxfee_kb; + const char *signed_message_header; + bool has_address_type; + bool has_address_type_p2sh; + bool has_segwit; + bool has_forkid; + bool force_bip143; + // address types > 0xFF represent a two-byte prefix in big-endian order + uint32_t address_type; + uint32_t address_type_p2sh; + uint32_t xpub_magic; + uint32_t xprv_magic; + uint32_t forkid; + const char *bech32_prefix; + uint32_t coin_type; + const char *curve_name; + const curve_info *curve; +} CoinInfo; + +extern const CoinInfo coins[COINS_COUNT]; + +const CoinInfo *coinByName(const char *name); +const CoinInfo *coinByAddressType(uint32_t address_type); +const CoinInfo *coinByCoinType(uint32_t coin_type); +bool coinExtractAddressType(const CoinInfo *coin, const char *addr, uint32_t *address_type); +bool coinExtractAddressTypeRaw(const CoinInfo *coin, const uint8_t *addr_raw, uint32_t *address_type); + +#endif diff --git a/hardware-wallet/firmware/firmware/coins.json b/hardware-wallet/firmware/firmware/coins.json new file mode 120000 index 00000000..a13f2d9c --- /dev/null +++ b/hardware-wallet/firmware/firmware/coins.json @@ -0,0 +1 @@ +../vendor/trezor-common/coins.json \ No newline at end of file diff --git a/hardware-wallet/firmware/firmware/crypto.c b/hardware-wallet/firmware/firmware/crypto.c new file mode 100644 index 00000000..dae6c4fe --- /dev/null +++ b/hardware-wallet/firmware/firmware/crypto.c @@ -0,0 +1,424 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include "crypto.h" +#include "sha2.h" +#include "ripemd160.h" +#include "pbkdf2.h" +#include "aes/aes.h" +#include "hmac.h" +#include "bip32.h" +#include "layout.h" +#include "curves.h" +#include "secp256k1.h" +#include "address.h" +#include "coins.h" +#include "base58.h" +#include "segwit_addr.h" + +uint32_t ser_length(uint32_t len, uint8_t *out) +{ + if (len < 253) { + out[0] = len & 0xFF; + return 1; + } + if (len < 0x10000) { + out[0] = 253; + out[1] = len & 0xFF; + out[2] = (len >> 8) & 0xFF; + return 3; + } + out[0] = 254; + out[1] = len & 0xFF; + out[2] = (len >> 8) & 0xFF; + out[3] = (len >> 16) & 0xFF; + out[4] = (len >> 24) & 0xFF; + return 5; +} + +uint32_t ser_length_hash(Hasher *hasher, uint32_t len) +{ + if (len < 253) { + hasher_Update(hasher, (const uint8_t *)&len, 1); + return 1; + } + if (len < 0x10000) { + uint8_t d = 253; + hasher_Update(hasher, &d, 1); + hasher_Update(hasher, (const uint8_t *)&len, 2); + return 3; + } + uint8_t d = 254; + hasher_Update(hasher, &d, 1); + hasher_Update(hasher, (const uint8_t *)&len, 4); + return 5; +} + +uint32_t deser_length(const uint8_t *in, uint32_t *out) +{ + if (in[0] < 253) { + *out = in[0]; + return 1; + } + if (in[0] == 253) { + *out = in[1] + (in[2] << 8); + return 1 + 2; + } + if (in[0] == 254) { + *out = in[1] + (in[2] << 8) + (in[3] << 16) + (in[4] << 24); + return 1 + 4; + } + *out = 0; // ignore 64 bit + return 1 + 8; +} + +int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature) +{ + signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes + return hdnode_sign(node, message, message_len, signature + 1, NULL, NULL); +} + +int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature) +{ + signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes + const curve_info *ed25519_curve_info = get_curve_by_name(ED25519_NAME); + if (ed25519_curve_info && node->curve == ed25519_curve_info) { + // GPG supports variable size digest for Ed25519 signatures + return hdnode_sign(node, message, message_len, signature + 1, NULL, NULL); + } else { + // Ensure 256-bit digest before proceeding + if (message_len != 32) { + return 1; + } + return hdnode_sign_digest(node, message, signature + 1, NULL, NULL); + } +} + +static void cryptoMessageHash(const CoinInfo *coin, const uint8_t *message, size_t message_len, uint8_t hash[HASHER_DIGEST_LENGTH]) { + Hasher hasher; + hasher_Init(&hasher, coin->curve->hasher_type); + hasher_Update(&hasher, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header)); + uint8_t varint[5]; + uint32_t l = ser_length(message_len, varint); + hasher_Update(&hasher, varint, l); + hasher_Update(&hasher, message, message_len); + hasher_Double(&hasher, hash); +} + +int cryptoMessageSign(const CoinInfo *coin, HDNode *node, InputScriptType script_type, const uint8_t *message, size_t message_len, uint8_t *signature) +{ + uint8_t hash[HASHER_DIGEST_LENGTH]; + cryptoMessageHash(coin, message, message_len, hash); + + uint8_t pby; + int result = hdnode_sign_digest(node, hash, signature + 1, &pby, NULL); + if (result == 0) { + switch (script_type) { + case InputScriptType_SPENDP2SHWITNESS: + // segwit-in-p2sh + signature[0] = 35 + pby; + break; + case InputScriptType_SPENDWITNESS: + // segwit + signature[0] = 39 + pby; + break; + default: + // p2pkh + signature[0] = 31 + pby; + break; + } + } + return result; +} + +int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t message_len, const char *address, const uint8_t *signature) +{ + // check for invalid signature prefix + if (signature[0] < 27 || signature[0] > 43) { + return 1; + } + + uint8_t hash[HASHER_DIGEST_LENGTH]; + cryptoMessageHash(coin, message, message_len, hash); + + uint8_t recid = (signature[0] - 27) % 4; + bool compressed = signature[0] >= 31; + + // check if signature verifies the digest and recover the public key + uint8_t pubkey[65]; + if (ecdsa_verify_digest_recover(&secp256k1, pubkey, signature + 1, hash, recid) != 0) { + return 3; + } + // convert public key to compressed pubkey if necessary + if (compressed) { + pubkey[0] = 0x02 | (pubkey[64] & 1); + } + + // check if the address is correct + uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; + uint8_t recovered_raw[MAX_ADDR_RAW_SIZE]; + + // p2pkh + if (signature[0] >= 27 && signature[0] <= 34) { + size_t len = base58_decode_check(address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + ecdsa_get_address_raw(pubkey, coin->address_type, coin->curve->hasher_type, recovered_raw); + if (memcmp(recovered_raw, addr_raw, len) != 0 + || len != address_prefix_bytes_len(coin->address_type) + 20) { + return 2; + } + } else + // segwit-in-p2sh + if (signature[0] >= 35 && signature[0] <= 38) { + size_t len = base58_decode_check(address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + ecdsa_get_address_segwit_p2sh_raw(pubkey, coin->address_type_p2sh, coin->curve->hasher_type, recovered_raw); + if (memcmp(recovered_raw, addr_raw, len) != 0 + || len != address_prefix_bytes_len(coin->address_type_p2sh) + 20) { + return 2; + } + } else + // segwit + if (signature[0] >= 39 && signature[0] <= 42) { + int witver; + size_t len; + if (!coin->bech32_prefix + || !segwit_addr_decode(&witver, recovered_raw, &len, coin->bech32_prefix, address)) { + return 4; + } + ecdsa_get_pubkeyhash(pubkey, coin->curve->hasher_type, addr_raw); + if (memcmp(recovered_raw, addr_raw, len) != 0 + || witver != 0 || len != 20) { + return 2; + } + } else { + return 4; + } + + return 0; +} + +/* ECIES disabled +int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, size_t msg_size, bool display_only, uint8_t *nonce, size_t *nonce_len, uint8_t *payload, size_t *payload_len, uint8_t *hmac, size_t *hmac_len, const uint8_t *privkey, const uint8_t *address_raw) +{ + if (privkey && address_raw) { // signing == true + HDNode node; + payload[0] = display_only ? 0x81 : 0x01; + uint32_t l = ser_length(msg_size, payload + 1); + memcpy(payload + 1 + l, msg, msg_size); + memcpy(payload + 1 + l + msg_size, address_raw, 21); + hdnode_from_xprv(0, 0, 0, privkey, privkey, SECP256K1_NAME, &node); + if (cryptoMessageSign(&node, msg, msg_size, payload + 1 + l + msg_size + 21) != 0) { + return 1; + } + *payload_len = 1 + l + msg_size + 21 + 65; + } else { + payload[0] = display_only ? 0x80 : 0x00; + uint32_t l = ser_length(msg_size, payload + 1); + memcpy(payload + 1 + l, msg, msg_size); + *payload_len = 1 + l + msg_size; + } + // generate random nonce + curve_point R; + bignum256 k; + if (generate_k_random(&secp256k1, &k) != 0) { + return 2; + } + // compute k*G + scalar_multiply(&secp256k1, &k, &R); + nonce[0] = 0x02 | (R.y.val[0] & 0x01); + bn_write_be(&R.x, nonce + 1); + *nonce_len = 33; + // compute shared secret + point_multiply(&secp256k1, &k, pubkey, &R); + uint8_t shared_secret[33]; + shared_secret[0] = 0x02 | (R.y.val[0] & 0x01); + bn_write_be(&R.x, shared_secret + 1); + // generate keying bytes + uint8_t keying_bytes[80]; + uint8_t salt[22 + 33]; + memcpy(salt, "Bitcoin Secure Message", 22); + memcpy(salt + 22, nonce, 33); + pbkdf2_hmac_sha256(shared_secret, 33, salt, 22 + 33, 2048, keying_bytes, 80); + // encrypt payload + aes_encrypt_ctx ctx; + aes_encrypt_key256(keying_bytes, &ctx); + aes_cfb_encrypt(payload, payload, *payload_len, keying_bytes + 64, &ctx); + // compute hmac + uint8_t out[32]; + hmac_sha256(keying_bytes + 32, 32, payload, *payload_len, out); + memcpy(hmac, out, 8); + *hmac_len = 8; + + return 0; +} + +int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, size_t payload_len, const uint8_t *hmac, size_t hmac_len, const uint8_t *privkey, uint8_t *msg, size_t *msg_len, bool *display_only, bool *signing, uint8_t *address_raw) +{ + if (hmac_len != 8) { + return 1; + } + // compute shared secret + curve_point R; + bignum256 k; + bn_read_be(privkey, &k); + point_multiply(&secp256k1, &k, nonce, &R); + uint8_t shared_secret[33]; + shared_secret[0] = 0x02 | (R.y.val[0] & 0x01); + bn_write_be(&R.x, shared_secret + 1); + // generate keying bytes + uint8_t keying_bytes[80]; + uint8_t salt[22 + 33]; + memcpy(salt, "Bitcoin Secure Message", 22); + salt[22] = 0x02 | (nonce->y.val[0] & 0x01); + bn_write_be(&(nonce->x), salt + 23); + pbkdf2_hmac_sha256(shared_secret, 33, salt, 22 + 33, 2048, keying_bytes, 80); + // compute hmac + uint8_t out[32]; + hmac_sha256(keying_bytes + 32, 32, payload, payload_len, out); + if (memcmp(hmac, out, 8) != 0) { + return 2; + } + // decrypt payload + aes_encrypt_ctx ctx; + aes_encrypt_key256(keying_bytes, &ctx); + aes_cfb_decrypt(payload, payload, payload_len, keying_bytes + 64, &ctx); + // check first byte + if (payload[0] != 0x00 && payload[0] != 0x01 && payload[0] != 0x80 && payload[0] != 0x81) { + return 3; + } + *signing = payload[0] & 0x01; + *display_only = payload[0] & 0x80; + uint32_t l, o; + l = deser_length(payload + 1, &o); + if (*signing) { + // FIXME: assumes a raw address is 21 bytes (also below). + if (1 + l + o + 21 + 65 != payload_len) { + return 4; + } + // FIXME: cryptoMessageVerify changed to take the address_type as a parameter. + if (cryptoMessageVerify(payload + 1 + l, o, payload + 1 + l + o, payload + 1 + l + o + 21) != 0) { + return 5; + } + memcpy(address_raw, payload + 1 + l + o, 21); + } else { + if (1 + l + o != payload_len) { + return 4; + } + } + memcpy(msg, payload + 1 + l, o); + *msg_len = o; + return 0; +} +*/ + +uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath) +{ + if (!hdnodepath->node.has_public_key || hdnodepath->node.public_key.size != 33) return 0; + static HDNode node; + if (hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, SECP256K1_NAME, &node) == 0) { + return 0; + } + layoutProgressUpdate(true); + for (uint32_t i = 0; i < hdnodepath->address_n_count; i++) { + if (hdnode_public_ckd(&node, hdnodepath->address_n[i]) == 0) { + return 0; + } + layoutProgressUpdate(true); + } + return node.public_key; +} + +int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey) +{ + for (size_t i = 0; i < multisig->pubkeys_count; i++) { + const uint8_t *node_pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])); + if (node_pubkey && memcmp(node_pubkey, pubkey, 33) == 0) { + return i; + } + } + return -1; +} + +int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, uint8_t *hash) +{ + static const HDNodePathType *ptr[15], *swap; + const uint32_t n = multisig->pubkeys_count; + if (n < 1 || n > 15) { + return 0; + } + // check sanity + if (!multisig->has_m || multisig->m < 1 || multisig->m > 15) return 0; + for (uint32_t i = 0; i < n; i++) { + ptr[i] = &(multisig->pubkeys[i]); + if (!ptr[i]->node.has_public_key || ptr[i]->node.public_key.size != 33) return 0; + if (ptr[i]->node.chain_code.size != 32) return 0; + } + // minsort according to pubkey + for (uint32_t i = 0; i < n - 1; i++) { + for (uint32_t j = n - 1; j > i; j--) { + if (memcmp(ptr[i]->node.public_key.bytes, ptr[j]->node.public_key.bytes, 33) > 0) { + swap = ptr[i]; + ptr[i] = ptr[j]; + ptr[j] = swap; + } + } + } + // hash sorted nodes + SHA256_CTX ctx; + sha256_Init(&ctx); + sha256_Update(&ctx, (const uint8_t *)&(multisig->m), sizeof(uint32_t)); + for (uint32_t i = 0; i < n; i++) { + sha256_Update(&ctx, (const uint8_t *)&(ptr[i]->node.depth), sizeof(uint32_t)); + sha256_Update(&ctx, (const uint8_t *)&(ptr[i]->node.fingerprint), sizeof(uint32_t)); + sha256_Update(&ctx, (const uint8_t *)&(ptr[i]->node.child_num), sizeof(uint32_t)); + sha256_Update(&ctx, ptr[i]->node.chain_code.bytes, 32); + sha256_Update(&ctx, ptr[i]->node.public_key.bytes, 33); + } + sha256_Update(&ctx, (const uint8_t *)&n, sizeof(uint32_t)); + sha256_Final(&ctx, hash); + layoutProgressUpdate(true); + return 1; +} + +int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash) +{ + SHA256_CTX ctx; + sha256_Init(&ctx); + sha256_Update(&ctx, (const uint8_t *)&(identity->index), sizeof(uint32_t)); + if (identity->has_proto && identity->proto[0]) { + sha256_Update(&ctx, (const uint8_t *)(identity->proto), strlen(identity->proto)); + sha256_Update(&ctx, (const uint8_t *)"://", 3); + } + if (identity->has_user && identity->user[0]) { + sha256_Update(&ctx, (const uint8_t *)(identity->user), strlen(identity->user)); + sha256_Update(&ctx, (const uint8_t *)"@", 1); + } + if (identity->has_host && identity->host[0]) { + sha256_Update(&ctx, (const uint8_t *)(identity->host), strlen(identity->host)); + } + if (identity->has_port && identity->port[0]) { + sha256_Update(&ctx, (const uint8_t *)":", 1); + sha256_Update(&ctx, (const uint8_t *)(identity->port), strlen(identity->port)); + } + if (identity->has_path && identity->path[0]) { + sha256_Update(&ctx, (const uint8_t *)(identity->path), strlen(identity->path)); + } + sha256_Final(&ctx, hash); + return 1; +} diff --git a/hardware-wallet/firmware/firmware/crypto.h b/hardware-wallet/firmware/firmware/crypto.h new file mode 100644 index 00000000..7744c290 --- /dev/null +++ b/hardware-wallet/firmware/firmware/crypto.h @@ -0,0 +1,62 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __CRYPTO_H__ +#define __CRYPTO_H__ + +#include +#include +#include +#include +#include +#include +#include +#include "coins.h" +#include "hasher.h" +#include "types.pb.h" + +#define ser_length_size(len) ((len) < 253 ? 1 : (len) < 0x10000 ? 3 : 5) + +uint32_t ser_length(uint32_t len, uint8_t *out); + +uint32_t ser_length_hash(Hasher *hasher, uint32_t len); + +int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature); + +int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature); + +int cryptoMessageSign(const CoinInfo *coin, HDNode *node, InputScriptType script_type, const uint8_t *message, size_t message_len, uint8_t *signature); + +int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message, size_t message_len, const char *address, const uint8_t *signature); + +/* ECIES disabled +int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, size_t msg_size, bool display_only, uint8_t *nonce, size_t *nonce_len, uint8_t *payload, size_t *payload_len, uint8_t *hmac, size_t *hmac_len, const uint8_t *privkey, const uint8_t *address_raw); + +int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, size_t payload_len, const uint8_t *hmac, size_t hmac_len, const uint8_t *privkey, uint8_t *msg, size_t *msg_len, bool *display_only, bool *signing, uint8_t *address_raw); +*/ + +uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath); + +int cryptoMultisigPubkeyIndex(const MultisigRedeemScriptType *multisig, const uint8_t *pubkey); + +int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, uint8_t *hash); + +int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash); + +#endif diff --git a/hardware-wallet/firmware/firmware/debug.c b/hardware-wallet/firmware/firmware/debug.c new file mode 100644 index 00000000..eb273149 --- /dev/null +++ b/hardware-wallet/firmware/firmware/debug.c @@ -0,0 +1,68 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "trezor.h" +#include "debug.h" +#include "oled.h" +#include "util.h" + +#if DEBUG_LOG + +void oledDebug(const char *line) +{ + static const char *lines[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + static char id = 3; + for (int i = 0; i < 7; i++) { + lines[i] = lines[i + 1]; + } + lines[7] = line; + oledClear(); + for (int i = 0; i < 8; i++) { + if (lines[i]) { + oledDrawChar(0, i * 8, '0' + (id + i) % 10, FONT_STANDARD); + oledDrawString(8, i * 8, lines[i], FONT_STANDARD); + } + } + oledRefresh(); + id = (id + 1) % 10; +} + +void debugLog(int level, const char *bucket, const char *text) +{ + (void)level; + (void)bucket; +#if EMULATOR + puts(text); +#else + oledDebug(text); +#endif +} + +char *debugInt(const uint32_t i) +{ + static uint8_t n = 0; + static char id[8][9]; + uint32hex(i, id[n]); + debugLog(0, "", id[n]); + char *ret = (char *)id[n]; + n = (n + 1) % 8; + return ret; +} + +#endif diff --git a/hardware-wallet/firmware/firmware/debug.h b/hardware-wallet/firmware/firmware/debug.h new file mode 100644 index 00000000..94f9a064 --- /dev/null +++ b/hardware-wallet/firmware/firmware/debug.h @@ -0,0 +1,38 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include "trezor.h" +#include + +#if DEBUG_LOG + +void debugLog(int level, const char *bucket, const char *text); +char *debugInt(const uint32_t i); + +#else + +#define debugLog(L, B, T) do{}while(0) +#define debugInt(I) do{}while(0) + +#endif + +#endif diff --git a/hardware-wallet/firmware/firmware/ethereum.c b/hardware-wallet/firmware/firmware/ethereum.c new file mode 100644 index 00000000..d2aff49d --- /dev/null +++ b/hardware-wallet/firmware/firmware/ethereum.c @@ -0,0 +1,671 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2016 Alex Beregszaszi + * Copyright (C) 2016 Pavol Rusnak + * Copyright (C) 2016 Jochen Hoenicke + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "ethereum.h" +#include "fsm.h" +#include "layout2.h" +#include "messages.h" +#include "transaction.h" +#include "ecdsa.h" +#include "protect.h" +#include "crypto.h" +#include "secp256k1.h" +#include "sha3.h" +#include "address.h" +#include "util.h" +#include "gettext.h" +#include "ethereum_tokens.h" +#include "memzero.h" + +/* maximum supported chain id. v must fit in an uint32_t. */ +#define MAX_CHAIN_ID 2147483630 + +static bool ethereum_signing = false; +static uint32_t data_total, data_left; +static EthereumTxRequest msg_tx_request; +static CONFIDENTIAL uint8_t privkey[32]; +static uint32_t chain_id; +struct SHA3_CTX keccak_ctx; + +static inline void hash_data(const uint8_t *buf, size_t size) +{ + sha3_Update(&keccak_ctx, buf, size); +} + +/* + * Push an RLP encoded length to the hash buffer. + */ +static void hash_rlp_length(uint32_t length, uint8_t firstbyte) +{ + uint8_t buf[4]; + if (length == 1 && firstbyte <= 0x7f) { + /* empty length header */ + } else if (length <= 55) { + buf[0] = 0x80 + length; + hash_data(buf, 1); + } else if (length <= 0xff) { + buf[0] = 0xb7 + 1; + buf[1] = length; + hash_data(buf, 2); + } else if (length <= 0xffff) { + buf[0] = 0xb7 + 2; + buf[1] = length >> 8; + buf[2] = length & 0xff; + hash_data(buf, 3); + } else { + buf[0] = 0xb7 + 3; + buf[1] = length >> 16; + buf[2] = length >> 8; + buf[3] = length & 0xff; + hash_data(buf, 4); + } +} + +/* + * Push an RLP encoded list length to the hash buffer. + */ +static void hash_rlp_list_length(uint32_t length) +{ + uint8_t buf[4]; + if (length <= 55) { + buf[0] = 0xc0 + length; + hash_data(buf, 1); + } else if (length <= 0xff) { + buf[0] = 0xf7 + 1; + buf[1] = length; + hash_data(buf, 2); + } else if (length <= 0xffff) { + buf[0] = 0xf7 + 2; + buf[1] = length >> 8; + buf[2] = length & 0xff; + hash_data(buf, 3); + } else { + buf[0] = 0xf7 + 3; + buf[1] = length >> 16; + buf[2] = length >> 8; + buf[3] = length & 0xff; + hash_data(buf, 4); + } +} + +/* + * Push an RLP encoded length field and data to the hash buffer. + */ +static void hash_rlp_field(const uint8_t *buf, size_t size) +{ + hash_rlp_length(size, buf[0]); + hash_data(buf, size); +} + +/* + * Push an RLP encoded number to the hash buffer. + * Ethereum yellow paper says to convert to big endian and strip leading zeros. + */ +static void hash_rlp_number(uint32_t number) +{ + if (!number) { + return; + } + uint8_t data[4]; + data[0] = (number >> 24) & 0xff; + data[1] = (number >> 16) & 0xff; + data[2] = (number >> 8) & 0xff; + data[3] = (number) & 0xff; + int offset = 0; + while (!data[offset]) { + offset++; + } + hash_rlp_field(data + offset, 4 - offset); +} + +/* + * Calculate the number of bytes needed for an RLP length header. + * NOTE: supports up to 16MB of data (how unlikely...) + * FIXME: improve + */ +static int rlp_calculate_length(int length, uint8_t firstbyte) +{ + if (length == 1 && firstbyte <= 0x7f) { + return 1; + } else if (length <= 55) { + return 1 + length; + } else if (length <= 0xff) { + return 2 + length; + } else if (length <= 0xffff) { + return 3 + length; + } else { + return 4 + length; + } +} + +static void send_request_chunk(void) +{ + int progress = 1000 - (data_total > 1000000 + ? data_left / (data_total/800) + : data_left * 800 / data_total); + layoutProgress(_("Signing"), progress); + msg_tx_request.has_data_length = true; + msg_tx_request.data_length = data_left <= 1024 ? data_left : 1024; + msg_write(MessageType_MessageType_EthereumTxRequest, &msg_tx_request); +} + +static int ethereum_is_canonic(uint8_t v, uint8_t signature[64]) +{ + (void) signature; + return (v & 2) == 0; +} + +static void send_signature(void) +{ + uint8_t hash[32], sig[64]; + uint8_t v; + layoutProgress(_("Signing"), 1000); + + /* eip-155 replay protection */ + if (chain_id != 0) { + /* hash v=chain_id, r=0, s=0 */ + hash_rlp_number(chain_id); + hash_rlp_length(0, 0); + hash_rlp_length(0, 0); + } + + keccak_Final(&keccak_ctx, hash); + if (ecdsa_sign_digest(&secp256k1, privkey, hash, sig, &v, ethereum_is_canonic) != 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed")); + ethereum_signing_abort(); + return; + } + + memzero(privkey, sizeof(privkey)); + + /* Send back the result */ + msg_tx_request.has_data_length = false; + + msg_tx_request.has_signature_v = true; + if (chain_id) { + msg_tx_request.signature_v = v + 2 * chain_id + 35; + } else { + msg_tx_request.signature_v = v + 27; + } + + msg_tx_request.has_signature_r = true; + msg_tx_request.signature_r.size = 32; + memcpy(msg_tx_request.signature_r.bytes, sig, 32); + + msg_tx_request.has_signature_s = true; + msg_tx_request.signature_s.size = 32; + memcpy(msg_tx_request.signature_s.bytes, sig + 32, 32); + + msg_write(MessageType_MessageType_EthereumTxRequest, &msg_tx_request); + + ethereum_signing_abort(); +} +/* Format a 256 bit number (amount in wei) into a human readable format + * using standard ethereum units. + * The buffer must be at least 25 bytes. + */ +static void ethereumFormatAmount(const bignum256 *amnt, const TokenType *token, char *buf, int buflen) +{ + bignum256 bn1e9; + bn_read_uint32(1000000000, &bn1e9); + const char *suffix = NULL; + int decimals = 18; + if (token == UnknownToken) { + strlcpy(buf, "Unknown token value", buflen); + return; + } else + if (token != NULL) { + suffix = token->ticker; + decimals = token->decimals; + } else + if (bn_is_less(amnt, &bn1e9)) { + suffix = " Wei"; + decimals = 0; + } else { + switch (chain_id) { + case 1: suffix = " ETH"; break; // Ethereum Mainnet + case 61: suffix = " ETC"; break; // Ethereum Classic Mainnet + case 62: suffix = " tETC"; break; // Ethereum Classic Testnet + case 30: suffix = " RSK"; break; // Rootstock Mainnet + case 31: suffix = " tRSK"; break; // Rootstock Testnet + case 3: suffix = " tETH"; break; // Ethereum Testnet: Ropsten + case 4: suffix = " tETH"; break; // Ethereum Testnet: Rinkeby + case 42: suffix = " tETH"; break; // Ethereum Testnet: Kovan + case 2: suffix = " EXP"; break; // Expanse + case 8: suffix = " UBQ"; break; // UBIQ + default: suffix = " UNKN"; break; // unknown chain + } + } + bn_format(amnt, NULL, suffix, decimals, 0, false, buf, buflen); +} + +static void layoutEthereumConfirmTx(const uint8_t *to, uint32_t to_len, const uint8_t *value, uint32_t value_len, const TokenType *token) +{ + bignum256 val; + uint8_t pad_val[32]; + memset(pad_val, 0, sizeof(pad_val)); + memcpy(pad_val + (32 - value_len), value, value_len); + bn_read_be(pad_val, &val); + + char amount[32]; + if (token == NULL) { + if (bn_is_zero(&val)) { + strcpy(amount, _("message")); + } else { + ethereumFormatAmount(&val, NULL, amount, sizeof(amount)); + } + } else { + ethereumFormatAmount(&val, token, amount, sizeof(amount)); + } + + char _to1[] = "to 0x__________"; + char _to2[] = "_______________"; + char _to3[] = "_______________?"; + + if (to_len) { + char to_str[41]; + ethereum_address_checksum(to, to_str); + memcpy(_to1 + 5, to_str, 10); + memcpy(_to2, to_str + 10, 15); + memcpy(_to3, to_str + 25, 15); + } else { + strlcpy(_to1, _("to new contract?"), sizeof(_to1)); + strlcpy(_to2, "", sizeof(_to2)); + strlcpy(_to3, "", sizeof(_to3)); + } + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + NULL, + _("Send"), + amount, + _to1, + _to2, + _to3, + NULL + ); +} + +static void layoutEthereumData(const uint8_t *data, uint32_t len, uint32_t total_len) +{ + char hexdata[3][17]; + char summary[20]; + uint32_t printed = 0; + for (int i = 0; i < 3; i++) { + uint32_t linelen = len - printed; + if (linelen > 8) { + linelen = 8; + } + data2hex(data, linelen, hexdata[i]); + data += linelen; + printed += linelen; + } + + strcpy(summary, "... bytes"); + char *p = summary + 11; + uint32_t number = total_len; + while (number > 0) { + *p-- = '0' + number % 10; + number = number / 10; + } + char *summarystart = summary; + if (total_len == printed) + summarystart = summary + 4; + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + NULL, + _("Transaction data:"), + hexdata[0], + hexdata[1], + hexdata[2], + summarystart, + NULL + ); +} + +static void layoutEthereumFee(const uint8_t *value, uint32_t value_len, + const uint8_t *gas_price, uint32_t gas_price_len, + const uint8_t *gas_limit, uint32_t gas_limit_len, + bool is_token) +{ + bignum256 val, gas; + uint8_t pad_val[32]; + char tx_value[32]; + char gas_value[32]; + + memset(pad_val, 0, sizeof(pad_val)); + memcpy(pad_val + (32 - gas_price_len), gas_price, gas_price_len); + bn_read_be(pad_val, &val); + + memset(pad_val, 0, sizeof(pad_val)); + memcpy(pad_val + (32 - gas_limit_len), gas_limit, gas_limit_len); + bn_read_be(pad_val, &gas); + bn_multiply(&val, &gas, &secp256k1.prime); + + ethereumFormatAmount(&gas, NULL, gas_value, sizeof(gas_value)); + + memset(pad_val, 0, sizeof(pad_val)); + memcpy(pad_val + (32 - value_len), value, value_len); + bn_read_be(pad_val, &val); + + if (bn_is_zero(&val)) { + strcpy(tx_value, is_token ? _("token") : _("message")); + } else { + ethereumFormatAmount(&val, NULL, tx_value, sizeof(tx_value)); + } + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + NULL, + _("Really send"), + tx_value, + _("paying up to"), + gas_value, + _("for gas?"), + NULL + ); +} + +/* + * RLP fields: + * - nonce (0 .. 32) + * - gas_price (0 .. 32) + * - gas_limit (0 .. 32) + * - to (0, 20) + * - value (0 .. 32) + * - data (0 ..) + */ + +static bool ethereum_signing_check(EthereumSignTx *msg) +{ + if (!msg->has_gas_price || !msg->has_gas_limit) { + return false; + } + + if (msg->to.size != 20 && msg->to.size != 0) { + /* Address has wrong length */ + return false; + } + + // sending transaction to address 0 (contract creation) without a data field + if (msg->to.size == 0 && (!msg->has_data_length || msg->data_length == 0)) { + return false; + } + + if (msg->gas_price.size + msg->gas_limit.size > 30) { + // sanity check that fee doesn't overflow + return false; + } + + return true; +} + +void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node) +{ + ethereum_signing = true; + sha3_256_Init(&keccak_ctx); + + memset(&msg_tx_request, 0, sizeof(EthereumTxRequest)); + /* set fields to 0, to avoid conditions later */ + if (!msg->has_value) + msg->value.size = 0; + if (!msg->has_data_initial_chunk) + msg->data_initial_chunk.size = 0; + if (!msg->has_to) + msg->to.size = 0; + if (!msg->has_nonce) + msg->nonce.size = 0; + + /* eip-155 chain id */ + if (msg->has_chain_id) { + if (msg->chain_id < 1 || msg->chain_id > MAX_CHAIN_ID) { + fsm_sendFailure(FailureType_Failure_DataError, _("Chain Id out of bounds")); + ethereum_signing_abort(); + return; + } + chain_id = msg->chain_id; + } else { + chain_id = 0; + } + + if (msg->has_data_length && msg->data_length > 0) { + if (!msg->has_data_initial_chunk || msg->data_initial_chunk.size == 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Data length provided, but no initial chunk")); + ethereum_signing_abort(); + return; + } + /* Our encoding only supports transactions up to 2^24 bytes. To + * prevent exceeding the limit we use a stricter limit on data length. + */ + if (msg->data_length > 16000000) { + fsm_sendFailure(FailureType_Failure_DataError, _("Data length exceeds limit")); + ethereum_signing_abort(); + return; + } + data_total = msg->data_length; + } else { + data_total = 0; + } + if (msg->data_initial_chunk.size > data_total) { + fsm_sendFailure(FailureType_Failure_DataError, _("Invalid size of initial chunk")); + ethereum_signing_abort(); + return; + } + + // safety checks + if (!ethereum_signing_check(msg)) { + fsm_sendFailure(FailureType_Failure_DataError, _("Safety check failed")); + ethereum_signing_abort(); + return; + } + + const TokenType *token = NULL; + + // detect ERC-20 token + if (msg->to.size == 20 && msg->value.size == 0 && data_total == 68 && msg->data_initial_chunk.size == 68 + && memcmp(msg->data_initial_chunk.bytes, "\xa9\x05\x9c\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) { + token = tokenByChainAddress(chain_id, msg->to.bytes); + } + + if (token != NULL) { + layoutEthereumConfirmTx(msg->data_initial_chunk.bytes + 16, 20, msg->data_initial_chunk.bytes + 36, 32, token); + } else { + layoutEthereumConfirmTx(msg->to.bytes, msg->to.size, msg->value.bytes, msg->value.size, NULL); + } + + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + ethereum_signing_abort(); + return; + } + + if (token == NULL && data_total > 0) { + layoutEthereumData(msg->data_initial_chunk.bytes, msg->data_initial_chunk.size, data_total); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + ethereum_signing_abort(); + return; + } + } + + layoutEthereumFee(msg->value.bytes, msg->value.size, + msg->gas_price.bytes, msg->gas_price.size, + msg->gas_limit.bytes, msg->gas_limit.size, token != NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + ethereum_signing_abort(); + return; + } + + /* Stage 1: Calculate total RLP length */ + uint32_t rlp_length = 0; + + layoutProgress(_("Signing"), 0); + + rlp_length += rlp_calculate_length(msg->nonce.size, msg->nonce.bytes[0]); + rlp_length += rlp_calculate_length(msg->gas_price.size, msg->gas_price.bytes[0]); + rlp_length += rlp_calculate_length(msg->gas_limit.size, msg->gas_limit.bytes[0]); + rlp_length += rlp_calculate_length(msg->to.size, msg->to.bytes[0]); + rlp_length += rlp_calculate_length(msg->value.size, msg->value.bytes[0]); + rlp_length += rlp_calculate_length(data_total, msg->data_initial_chunk.bytes[0]); + if (chain_id) { + rlp_length += rlp_calculate_length(1, chain_id); + rlp_length += rlp_calculate_length(0, 0); + rlp_length += rlp_calculate_length(0, 0); + } + + /* Stage 2: Store header fields */ + hash_rlp_list_length(rlp_length); + + layoutProgress(_("Signing"), 100); + + hash_rlp_field(msg->nonce.bytes, msg->nonce.size); + hash_rlp_field(msg->gas_price.bytes, msg->gas_price.size); + hash_rlp_field(msg->gas_limit.bytes, msg->gas_limit.size); + hash_rlp_field(msg->to.bytes, msg->to.size); + hash_rlp_field(msg->value.bytes, msg->value.size); + hash_rlp_length(data_total, msg->data_initial_chunk.bytes[0]); + hash_data(msg->data_initial_chunk.bytes, msg->data_initial_chunk.size); + data_left = data_total - msg->data_initial_chunk.size; + + memcpy(privkey, node->private_key, 32); + + if (data_left > 0) { + send_request_chunk(); + } else { + send_signature(); + } +} + +void ethereum_signing_txack(EthereumTxAck *tx) +{ + if (!ethereum_signing) { + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Not in Ethereum signing mode")); + layoutHome(); + return; + } + + if (tx->data_chunk.size > data_left) { + fsm_sendFailure(FailureType_Failure_DataError, _("Too much data")); + ethereum_signing_abort(); + return; + } + + if (data_left > 0 && (!tx->has_data_chunk || tx->data_chunk.size == 0)) { + fsm_sendFailure(FailureType_Failure_DataError, _("Empty data chunk received")); + ethereum_signing_abort(); + return; + } + + hash_data(tx->data_chunk.bytes, tx->data_chunk.size); + + data_left -= tx->data_chunk.size; + + if (data_left > 0) { + send_request_chunk(); + } else { + send_signature(); + } +} + +void ethereum_signing_abort(void) +{ + if (ethereum_signing) { + memzero(privkey, sizeof(privkey)); + layoutHome(); + ethereum_signing = false; + } +} + +static void ethereum_message_hash(const uint8_t *message, size_t message_len, uint8_t hash[32]) +{ + struct SHA3_CTX ctx; + sha3_256_Init(&ctx); + sha3_Update(&ctx, (const uint8_t *)"\x19" "Ethereum Signed Message:\n", 26); + uint8_t varint[5]; + uint32_t l = ser_length(message_len, varint); + sha3_Update(&ctx, varint, l); + sha3_Update(&ctx, message, message_len); + keccak_Final(&ctx, hash); +} + +void ethereum_message_sign(EthereumSignMessage *msg, const HDNode *node, EthereumMessageSignature *resp) +{ + uint8_t hash[32]; + + if (!hdnode_get_ethereum_pubkeyhash(node, resp->address.bytes)) { + return; + } + resp->has_address = true; + resp->address.size = 20; + ethereum_message_hash(msg->message.bytes, msg->message.size, hash); + + uint8_t v; + if (ecdsa_sign_digest(&secp256k1, node->private_key, hash, resp->signature.bytes, &v, ethereum_is_canonic) != 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed")); + return; + } + + resp->has_signature = true; + resp->signature.bytes[64] = 27 + v; + resp->signature.size = 65; + msg_write(MessageType_MessageType_EthereumMessageSignature, resp); +} + +int ethereum_message_verify(EthereumVerifyMessage *msg) +{ + if (msg->signature.size != 65 || msg->address.size != 20) { + fsm_sendFailure(FailureType_Failure_DataError, _("Malformed data")); + return 1; + } + + uint8_t pubkey[65]; + uint8_t hash[32]; + + ethereum_message_hash(msg->message.bytes, msg->message.size, hash); + + /* v should be 27, 28 but some implementations use 0,1. We are + * compatible with both. + */ + uint8_t v = msg->signature.bytes[64]; + if (v >= 27) { + v -= 27; + } + if (v >= 2 || + ecdsa_verify_digest_recover(&secp256k1, pubkey, msg->signature.bytes, hash, v) != 0) { + return 2; + } + + struct SHA3_CTX ctx; + sha3_256_Init(&ctx); + sha3_Update(&ctx, pubkey + 1, 64); + keccak_Final(&ctx, hash); + + /* result are the least significant 160 bits */ + if (memcmp(msg->address.bytes, hash + 12, 20) != 0) { + return 2; + } + return 0; +} diff --git a/hardware-wallet/firmware/firmware/ethereum.h b/hardware-wallet/firmware/firmware/ethereum.h new file mode 100644 index 00000000..5327b845 --- /dev/null +++ b/hardware-wallet/firmware/firmware/ethereum.h @@ -0,0 +1,35 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2016 Alex Beregszaszi + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __ETHEREUM_H__ +#define __ETHEREUM_H__ + +#include +#include +#include "bip32.h" +#include "messages.pb.h" + +void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node); +void ethereum_signing_abort(void); +void ethereum_signing_txack(EthereumTxAck *msg); + +void ethereum_message_sign(EthereumSignMessage *msg, const HDNode *node, EthereumMessageSignature *resp); +int ethereum_message_verify(EthereumVerifyMessage *msg); + +#endif diff --git a/hardware-wallet/firmware/firmware/ethereum_tokens.c b/hardware-wallet/firmware/firmware/ethereum_tokens.c new file mode 100644 index 00000000..d1e60526 --- /dev/null +++ b/hardware-wallet/firmware/firmware/ethereum_tokens.c @@ -0,0 +1,143 @@ +#include +#include "ethereum_tokens.h" + +const TokenType tokens[TOKENS_COUNT] = { + { 1, "\xaf\x30\xd2\xa7\xe9\x0d\x7d\xc3\x61\xc8\xc4\x58\x5e\x9b\xb7\xd2\xf6\xf1\x5b\xc7", " 1ST", 18}, + { 1, "\xae\xc9\x8a\x70\x88\x10\x41\x48\x78\xc3\xbc\xdf\x46\xaa\xd3\x1d\xed\x4a\x45\x57", " 300", 18}, + { 1, "\x42\x28\x66\xa8\xf0\xb0\x32\xc5\xcf\x1d\xfb\xde\xf3\x1a\x20\xf4\x50\x95\x62\xb0", " ADST", 0}, + { 1, "\xd0\xd6\xd6\xc5\xfe\x4a\x67\x7d\x34\x3c\xc4\x33\x53\x6b\xb7\x17\xba\xe1\x67\xdd", " ADT", 9}, + { 1, "\x44\x70\xbb\x87\xd7\x7b\x96\x3a\x01\x3d\xb9\x39\xbe\x33\x2f\x92\x7f\x2b\x99\x2e", " ADX", 4}, + { 1, "\x96\x0b\x23\x6a\x07\xcf\x12\x26\x63\xc4\x30\x33\x50\x60\x9a\x66\xa7\xb2\x88\xc0", " ANT", 18}, + { 1, "\x23\xae\x3c\x5b\x39\xb1\x2f\x06\x93\xe0\x54\x35\xee\xaa\x1e\x51\xd8\xc6\x15\x30", " APT", 18}, + { 1, "\xac\x70\x9f\xcb\x44\xa4\x3c\x35\xf0\xda\x4e\x31\x63\xb1\x17\xa1\x7f\x37\x70\xf5", " ARC", 18}, + { 1, "\x17\x05\x2d\x51\xe9\x54\x59\x2c\x10\x46\x32\x0c\x23\x71\xab\xab\x6c\x73\xef\x10", " ATH", 18}, + { 1, "\xed\x24\x79\x80\x39\x6b\x10\x16\x9b\xb1\xd3\x6f\x6e\x27\x8e\xd1\x67\x00\xa6\x0f", " AVA", 4}, + { 1, "\x0d\x87\x75\xf6\x48\x43\x06\x79\xa7\x09\xe9\x8d\x2b\x0c\xb6\x25\x0d\x28\x87\xef", " BAT", 18}, + { 1, "\x1e\x79\x7c\xe9\x86\xc3\xcf\xf4\x47\x2f\x7d\x38\xd5\xc4\xab\xa5\x5d\xfe\xfe\x40", " BCDN", 15}, + { 1, "\x74\xc1\xe4\xb8\xca\xe5\x92\x69\xec\x1d\x85\xd3\xd4\xf3\x24\x39\x60\x48\xf4\xac", " BEER", 0}, + { 1, "\x72\x58\x03\x31\x55\x19\xde\x78\xd2\x32\x26\x5a\x8f\x10\x40\xf0\x54\xe7\x0b\x98", " BET", 18}, + { 1, "\x6d\xc7\x0d\x22\xee\x85\x40\x79\x6a\xb5\xb0\x2f\x98\xf9\xf2\x4d\xc8\x79\xe1\x0a", " BLX", 18}, + { 1, "\xdd\x6b\xf5\x6c\xa2\xad\xa2\x4c\x68\x3f\xac\x50\xe3\x77\x83\xe5\x5b\x57\xaf\x9f", " BNC", 12}, + { 1, "\x1f\x57\x3d\x6f\xb3\xf1\x3d\x68\x9f\xf8\x44\xb4\xce\x37\x79\x4d\x79\xa7\xff\x1c", " BNT", 18}, + { 1, "\x5a\xf2\xbe\x19\x3a\x6a\xbc\xa9\xc8\x81\x70\x01\xf4\x57\x44\x77\x7d\xb3\x07\x56", " BQX", 8}, + { 1, "\x56\xba\x2e\xe7\x89\x04\x61\xf4\x63\xf7\xbe\x02\xaa\xc3\x09\x9f\x6d\x58\x11\xa8", " CAT", 18}, + { 1, "\x12\xfe\xf5\xe5\x7b\xf4\x58\x73\xcd\x9b\x62\xe9\xdb\xd7\xbf\xb9\x9e\x32\xd7\x3e", " CFI", 18}, + { 1, "\xae\xf3\x8f\xbf\xbf\x93\x2d\x1a\xef\x3b\x80\x8b\xc8\xfb\xd8\xcd\x8e\x1f\x8b\xc5", " CRB", 8}, + { 1, "\x4e\x06\x03\xe2\xa2\x7a\x30\x48\x0e\x5e\x3a\x4f\xe5\x48\xe2\x9e\xf1\x2f\x64\xbe", " CREDO", 18}, + { 1, "\xe4\xc9\x4d\x45\xf7\xae\xf7\x01\x8a\x5d\x66\xf4\x4a\xf7\x80\xec\x60\x23\x37\x8e", " CCRB", 6}, + { 1, "\xbf\x4c\xfd\x7d\x1e\xde\xee\xa5\xf6\x60\x08\x27\x41\x1b\x41\xa2\x1e\xb0\x8a\xbd", " CTL", 2}, + { 1, "\x41\xe5\x56\x00\x54\x82\x4e\xa6\xb0\x73\x2e\x65\x6e\x3a\xd6\x4e\x20\xe9\x4e\x45", " CVC", 8}, + { 1, "\xbb\x9b\xc2\x44\xd7\x98\x12\x3f\xde\x78\x3f\xcc\x1c\x72\xd3\xbb\x8c\x18\x94\x13", " DAO", 16}, + { 1, "\xcc\x4e\xf9\xee\xaf\x65\x6a\xc1\xa2\xab\x88\x67\x43\xe9\x8e\x97\xe0\x90\xed\x38", " DDF", 18}, + { 1, "\x35\x97\xbf\xd5\x33\xa9\x9c\x9a\xa0\x83\x58\x7b\x07\x44\x34\xe6\x1e\xb0\xa2\x58", " DENT", 8}, + { 1, "\xe0\xb7\x92\x7c\x4a\xf2\x37\x65\xcb\x51\x31\x4a\x0e\x05\x21\xa9\x64\x5f\x0e\x2a", " DGD", 9}, + { 1, "\x55\xb9\xa1\x1c\x2e\x83\x51\xb4\xff\xc7\xb1\x15\x61\x14\x8b\xfa\xc9\x97\x78\x55", " DGX1", 9}, + { 1, "\x2e\x07\x1d\x29\x66\xaa\x7d\x8d\xec\xb1\x00\x58\x85\xba\x19\x77\xd6\x03\x8a\x65", " DICE", 16}, + { 1, "\x0a\xbd\xac\xe7\x0d\x37\x90\x23\x5a\xf4\x48\xc8\x85\x47\x60\x3b\x94\x56\x04\xea", " DNT", 18}, + { 1, "\x3c\x75\x22\x65\x55\xfc\x49\x61\x68\xd4\x8b\x88\xdf\x83\xb9\x5f\x16\x77\x1f\x37", " DROP", 0}, + { 1, "\x62\x1d\x78\xf2\xef\x2f\xd9\x37\xbf\xca\x69\x6c\xab\xaf\x9a\x77\x9f\x59\xb3\xed", " DRP", 2}, + { 1, "\xa5\x78\xac\xc0\xcb\x78\x75\x78\x1b\x78\x80\x90\x3f\x45\x94\xd1\x3c\xfa\x8b\x98", " ECN", 2}, + { 1, "\x08\x71\x1d\x3b\x02\xc8\x75\x8f\x2f\xb3\xab\x4e\x80\x22\x84\x18\xa7\xf8\xe3\x9c", " EDG", 0}, + { 1, "\xb8\x02\xb2\x4e\x06\x37\xc2\xb8\x7d\x2e\x8b\x77\x84\xc0\x55\xbb\xe9\x21\x01\x1a", " EMV", 2}, + { 1, "\x86\xfa\x04\x98\x57\xe0\x20\x9a\xa7\xd9\xe6\x16\xf7\xeb\x3b\x3b\x78\xec\xfd\xb0", " EOS", 18}, + { 1, "\x19\x0e\x56\x9b\xe0\x71\xf4\x0c\x70\x4e\x15\x82\x5f\x28\x54\x81\xcb\x74\xb6\xcc", " FAM", 12}, + { 1, "\x41\x9d\x0d\x8b\xdd\x9a\xf5\xe6\x06\xae\x22\x32\xed\x28\x5a\xff\x19\x0e\x71\x1b", " FUN", 8}, + { 1, "\x88\xfc\xfb\xc2\x2c\x6d\x3d\xba\xa2\x5a\xf4\x78\xc5\x78\x97\x83\x39\xbd\xe7\x7a", " FYN", 18}, + { 1, "\x24\x08\x3b\xb3\x00\x72\x64\x3c\x3b\xb9\x0b\x44\xb7\x28\x58\x60\xa7\x55\xe6\x87", " GELD", 18}, + { 1, "\x68\x10\xe7\x76\x88\x0c\x02\x93\x3d\x47\xdb\x1b\x9f\xc0\x59\x08\xe5\x38\x6b\x96", " GNO", 18}, + { 1, "\xa7\x44\x76\x44\x31\x19\xa9\x42\xde\x49\x85\x90\xfe\x1f\x24\x54\xd7\xd4\xac\x0d", " GNT", 18}, + { 1, "\x02\x5a\xba\xd9\xe5\x18\x51\x6f\xda\xaf\xbd\xcd\xb9\x70\x1b\x37\xfb\x7e\xf0\xfa", " GTKT", 0}, + { 1, "\xf7\xb0\x98\x29\x8f\x7c\x69\xfc\x14\x61\x0b\xf7\x1d\x5e\x02\xc6\x07\x92\x89\x4c", " GUP", 3}, + { 1, "\x14\xf3\x7b\x57\x42\x42\xd3\x66\x55\x8d\xb6\x1f\x33\x35\x28\x9a\x50\x35\xc5\x06", " HKG", 3}, + { 1, "\xcb\xcc\x0f\x03\x6e\xd4\x78\x8f\x63\xfc\x0f\xee\x32\x87\x3d\x6a\x74\x87\xb9\x08", " HMQ", 8}, + { 1, "\x5a\x84\x96\x9b\xb6\x63\xfb\x64\xf6\xd0\x15\xdc\xf9\xf6\x22\xae\xdc\x79\x67\x50", " ICE", 18}, + { 1, "\x88\x86\x66\xca\x69\xe0\xf1\x78\xde\xd6\xd7\x5b\x57\x26\xce\xe9\x9a\x87\xd6\x98", " ICN", 18}, + { 1, "\xed\x19\x69\x8c\x0a\xbd\xe8\x63\x54\x13\xae\x7a\xd7\x22\x4d\xf6\xee\x30\xbf\x22", " IMT", 0}, + { 1, "\xc1\xe6\xc6\xc6\x81\xb2\x86\xfb\x50\x3b\x36\xa9\xdd\x6c\x1d\xbf\xf8\x5e\x73\xcf", " JET", 18}, + { 1, "\x77\x34\x50\x33\x5e\xd4\xec\x3d\xb4\x5a\xf7\x4f\x34\xf2\xc8\x53\x48\x64\x5d\x39", " JTC", 18}, + { 1, "\x21\xae\x23\xb8\x82\xa3\x40\xa2\x22\x82\x16\x20\x86\xbc\x98\xd3\xe2\xb7\x30\x18", " LOK", 18}, + { 1, "\xfb\x12\xe3\xcc\xa9\x83\xb9\xf5\x9d\x90\x91\x2f\xd1\x7f\x8d\x74\x5a\x8b\x29\x53", " LUCK", 0}, + { 1, "\xfa\x05\xa7\x3f\xfe\x78\xef\x8f\x1a\x73\x94\x73\xe4\x62\xc5\x4b\xae\x65\x67\xd9", " LUN", 18}, + { 1, "\x93\xe6\x82\x10\x7d\x1e\x9d\xef\xb0\xb5\xee\x70\x1c\x71\x70\x7a\x4b\x2e\x46\xbc", " MCAP", 8}, + { 1, "\xb6\x3b\x60\x6a\xc8\x10\xa5\x2c\xca\x15\xe4\x4b\xb6\x30\xfd\x42\xd8\xd1\xd8\x3d", " MCO", 8}, + { 1, "\xd0\xb1\x71\xeb\x0b\x0f\x2c\xbd\x35\xcc\xd9\x7c\xdc\x5e\xdc\x3f\xfe\x48\x71\xaa", " MDA", 18}, + { 1, "\x40\x39\x50\x44\xac\x3c\x0c\x57\x05\x19\x06\xda\x93\x8b\x54\xbd\x65\x57\xf2\x12", " MGO", 8}, + { 1, "\xe2\x3c\xd1\x60\x76\x1f\x63\xfc\x3a\x1c\xf7\x8a\xa0\x34\xb6\xcd\xf9\x7d\x3e\x0c", " MIT", 18}, + { 1, "\xc6\x6e\xa8\x02\x71\x7b\xfb\x98\x33\x40\x02\x64\xdd\x12\xc2\xbc\xea\xa3\x4a\x6d", " MKR", 18}, + { 1, "\xbe\xb9\xef\x51\x4a\x37\x9b\x99\x7e\x07\x98\xfd\xcc\x90\x1e\xe4\x74\xb6\xd9\xa1", " MLN", 18}, + { 1, "\x1a\x95\xb2\x71\xb0\x53\x5d\x15\xfa\x49\x93\x2d\xab\xa3\x1b\xa6\x12\xb5\x29\x46", " MNE", 8}, + { 1, "\xab\x6c\xf8\x7a\x50\xf1\x7d\x7f\x5e\x1f\xea\xf8\x1b\x6f\xe9\xff\xbe\x8e\xbf\x84", " MRV", 18}, + { 1, "\x68\xaa\x3f\x23\x2d\xa9\xbd\xc2\x34\x34\x65\x54\x57\x94\xef\x3e\xea\x52\x09\xbd", " MSP", 18}, + { 1, "\xf4\x33\x08\x93\x66\x89\x9d\x83\xa9\xf2\x6a\x77\x3d\x59\xec\x7e\xcf\x30\x35\x5e", " MTL", 8}, + { 1, "\xf7\xe9\x83\x78\x16\x09\x01\x23\x07\xf2\x51\x4f\x63\xd5\x26\xd8\x3d\x24\xf4\x66", " MYD", 16}, + { 1, "\xa6\x45\x26\x4c\x56\x03\xe9\x6c\x3b\x0b\x07\x8c\xda\xb6\x87\x33\x79\x4b\x0a\x71", " MYST", 8}, + { 1, "\xcf\xb9\x86\x37\xbc\xae\x43\xc1\x33\x23\xea\xa1\x73\x1c\xed\x2b\x71\x69\x62\xfd", " NET", 18}, + { 1, "\x17\x76\xe1\xf2\x6f\x98\xb1\xa5\xdf\x9c\xd3\x47\x95\x3a\x26\xdd\x3c\xb4\x66\x71", " NMR", 18}, + { 1, "\x45\xe4\x2d\x65\x9d\x9f\x94\x66\xcd\x5d\xf6\x22\x50\x60\x33\x14\x5a\x9b\x89\xbc", " NxC", 3}, + { 1, "\x5c\x61\x83\xd1\x0a\x00\xcd\x74\x7a\x6d\xbb\x5f\x65\x8a\xd5\x14\x38\x3e\x94\x19", " NXX", 8}, + { 1, "\x70\x1c\x24\x4b\x98\x8a\x51\x3c\x94\x59\x73\xde\xfa\x05\xde\x93\x3b\x23\xfe\x1d", " OAX", 18}, + { 1, "\x7f\x21\x76\xce\xb1\x6d\xcb\x64\x8d\xc9\x24\xef\xf6\x17\xc3\xdc\x2b\xef\xd3\x0d", " OHNI", 0}, + { 1, "\xd2\x61\x14\xcd\x6e\xe2\x89\xac\xcf\x82\x35\x0c\x8d\x84\x87\xfe\xdb\x8a\x0c\x07", " OMG", 18}, + { 1, "\xb9\x70\x48\x62\x8d\xb6\xb6\x61\xd4\xc2\xaa\x83\x3e\x95\xdb\xe1\xa9\x05\xb2\x80", " PAY", 18}, + { 1, "\x0a\xff\xa0\x6e\x7f\xbe\x5b\xc9\xa7\x64\xc9\x79\xaa\x66\xe8\x25\x6a\x63\x1f\x02", " PLBT", 6}, + { 1, "\xe3\x81\x85\x04\xc1\xb3\x2b\xf1\x55\x7b\x16\xc2\x38\xb2\xe0\x1f\xd3\x14\x9c\x17", " PLR", 18}, + { 1, "\xd8\x91\x2c\x10\x68\x1d\x8b\x21\xfd\x37\x42\x24\x4f\x44\x65\x8d\xba\x12\x26\x4e", " PLU", 18}, + { 1, "\xd4\xfa\x14\x60\xf5\x37\xbb\x90\x85\xd2\x2c\x7b\xcc\xb5\xdd\x45\x0e\xf2\x8e\x3a", " PPT", 8}, + { 1, "\x22\x6b\xb5\x99\xa1\x2c\x82\x64\x76\xe3\xa7\x71\x45\x46\x97\xea\x52\xe9\xe2\x20", " PRO", 8}, + { 1, "\x16\x37\x33\xbc\xc2\x8d\xbf\x26\xb4\x1a\x8c\xfa\x83\xe3\x69\xb5\xb3\xaf\x74\x1b", " PRS", 18}, + { 1, "\x8a\xe4\xbf\x2c\x33\xa8\xe6\x67\xde\x34\xb5\x49\x38\xb0\xcc\xd0\x3e\xb8\xcc\x06", " PTOY", 8}, + { 1, "\x67\x1a\xbb\xe5\xce\x65\x24\x91\x98\x53\x42\xe8\x54\x28\xeb\x1b\x07\xbc\x6c\x64", " QAU", 8}, + { 1, "\x69\x7b\xea\xc2\x8b\x09\xe1\x22\xc4\x33\x2d\x16\x39\x85\xe8\xa7\x31\x21\xb9\x7f", " QRL", 8}, + { 1, "\xe9\x43\x27\xd0\x7f\xc1\x79\x07\xb4\xdb\x78\x8e\x5a\xdf\x2e\xd4\x24\xad\xdf\xf6", " REP", 18}, + { 1, "\xf0\x5a\x93\x82\xa4\xc3\xf2\x9e\x27\x84\x50\x27\x54\x29\x3d\x88\xb8\x35\x10\x9c", " REX", 18}, + { 1, "\x60\x7f\x4c\x5b\xb6\x72\x23\x0e\x86\x72\x08\x55\x32\xf7\xe9\x01\x54\x4a\x73\x75", " RLC", 9}, + { 1, "\xcc\xed\x5b\x82\x88\x08\x6b\xe8\xc3\x8e\x23\x56\x7e\x68\x4c\x37\x40\xbe\x4d\x48", " RLT", 10}, + { 1, "\x49\x93\xcb\x95\xc7\x44\x3b\xdc\x06\x15\x5c\x5f\x56\x88\xbe\x9d\x8f\x69\x99\xa5", " ROUND", 18}, + { 1, "\x7c\x5a\x0c\xe9\x26\x7e\xd1\x9b\x22\xf8\xca\xe6\x53\xf1\x98\xe3\xe8\xda\xf0\x98", " SAN", 18}, + { 1, "\xd7\x63\x17\x87\xb4\xdc\xc8\x7b\x12\x54\xcf\xd1\xe5\xce\x48\xe9\x68\x23\xde\xe8", " SCL", 8}, + { 1, "\xa1\xcc\xc1\x66\xfa\xf0\xe9\x98\xb3\xe3\x32\x25\xa1\xa0\x30\x1b\x1c\x86\x11\x9d", " SGEL", 18}, + { 1, "\xd2\x48\xb0\xd4\x8e\x44\xaa\xf9\xc4\x9a\xea\x03\x12\xbe\x7e\x13\xa6\xdc\x14\x68", " SGT", 1}, + { 1, "\xef\x2e\x99\x66\xeb\x61\xbb\x49\x4e\x53\x75\xd5\xdf\x8d\x67\xb7\xdb\x8a\x78\x0d", " SHIT", 0}, + { 1, "\x2b\xdc\x0d\x42\x99\x60\x17\xfc\xe2\x14\xb2\x16\x07\xa5\x15\xda\x41\xa9\xe0\xc5", " SKIN", 6}, + { 1, "\x49\x94\xe8\x18\x97\xa9\x20\xc0\xfe\xa2\x35\xeb\x8c\xed\xee\xd3\xc6\xff\xf6\x97", " SKO1", 18}, + { 1, "\xf4\x13\x41\x46\xaf\x2d\x51\x1d\xd5\xea\x8c\xdb\x1c\x4a\xc8\x8c\x57\xd6\x04\x04", " SNC", 18}, + { 1, "\xae\xc2\xe8\x7e\x0a\x23\x52\x66\xd9\xc5\xad\xc9\xde\xb4\xb2\xe2\x9b\x54\xd0\x09", " SNGLS", 0}, + { 1, "\x98\x3f\x6d\x60\xdb\x79\xea\x8c\xa4\xeb\x99\x68\xc6\xaf\xf8\xcf\xa0\x4b\x3c\x63", " SNM", 18}, + { 1, "\x74\x4d\x70\xfd\xbe\x2b\xa4\xcf\x95\x13\x16\x26\x61\x4a\x17\x63\xdf\x80\x5b\x9e", " SNT", 18}, + { 1, "\x58\xbf\x7d\xf5\x7d\x9d\xa7\x11\x3c\x4c\xcb\x49\xd8\x46\x3d\x49\x08\xc7\x35\xcb", " SPARC", 18}, + { 1, "\xb6\x4e\xf5\x1c\x88\x89\x72\xc9\x08\xcf\xac\xf5\x9b\x47\xc1\xaf\xbc\x0a\xb8\xac", " STORJ", 8}, + { 1, "\x46\x49\x24\x73\x75\x5e\x8d\xf9\x60\xf8\x03\x48\x77\xf6\x17\x32\xd7\x18\xce\x96", " STRC", 8}, + { 1, "\x00\x6b\xea\x43\xba\xa3\xf7\xa6\xf7\x65\xf1\x4f\x10\xa1\xa1\xb0\x83\x34\xef\x45", " STX", 18}, + { 1, "\xb9\xe7\xf8\x56\x8e\x08\xd5\x65\x9f\x5d\x29\xc4\x99\x71\x73\xd8\x4c\xdf\x26\x07", " SWT", 18}, + { 1, "\xe7\x77\x5a\x6e\x9b\xcf\x90\x4e\xb3\x9d\xa2\xb6\x8c\x5e\xfb\x4f\x93\x60\xe0\x8c", " TaaS", 6}, + { 1, "\xa7\xf9\x76\xc3\x60\xeb\xbe\xd4\x46\x5c\x28\x55\x68\x4d\x1a\xae\x52\x71\xef\xa9", " TFL", 8}, + { 1, "\x65\x31\xf1\x33\xe6\xde\xeb\xe7\xf2\xdc\xe5\xa0\x44\x1a\xa7\xef\x33\x0b\x4e\x53", " TIME", 8}, + { 1, "\xea\x1f\x34\x6f\xaf\x02\x3f\x97\x4e\xb5\xad\xaf\x08\x8b\xbc\xdf\x02\xd7\x61\xf4", " TIX", 18}, + { 1, "\xaa\xaf\x91\xd9\xb9\x0d\xf8\x00\xdf\x4f\x55\xc2\x05\xfd\x69\x89\xc9\x77\xe7\x3a", " TKN", 8}, + { 1, "\xcb\x94\xbe\x6f\x13\xa1\x18\x2e\x4a\x4b\x61\x40\xcb\x7b\xf2\x02\x5d\x28\xe4\x1b", " TRST", 6}, + { 1, "\x89\x20\x5a\x3a\x3b\x2a\x69\xde\x6d\xbf\x7f\x01\xed\x13\xb2\x10\x8b\x2c\x43\xe7", " UNCRN", 0}, + { 1, "\x8f\x34\x70\xa7\x38\x8c\x05\xee\x4e\x7a\xf3\xd0\x1d\x8c\x72\x2b\x0f\xf5\x23\x74", " VERI", 18}, + { 1, "\xed\xba\xf3\xc5\x10\x03\x02\xdc\xdd\xa5\x32\x69\x32\x2f\x37\x30\xb1\xf0\x41\x6d", " VRS", 5}, + { 1, "\x5c\x54\x3e\x7a\xe0\xa1\x10\x4f\x78\x40\x6c\x34\x0e\x9c\x64\xfd\x9f\xce\x51\x70", " VSL", 18}, + { 1, "\x82\x66\x57\x64\xea\x0b\x58\x15\x7e\x1e\x5e\x9b\xab\x32\xf6\x8c\x76\xec\x0c\xdf", " VSM", 0}, + { 1, "\x6a\x0a\x97\xe4\x7d\x15\xaa\xd1\xd1\x32\xa1\xac\x79\xa4\x80\xe3\xf2\x07\x90\x63", " WCT", 18}, + { 1, "\x66\x70\x88\xb2\x12\xce\x3d\x06\xa1\xb5\x53\xa7\x22\x1e\x1f\xd1\x90\x00\xd9\xaf", " WINGS", 18}, + { 1, "\x4d\xf8\x12\xf6\x06\x4d\xef\x1e\x5e\x02\x9f\x1c\xa8\x58\x77\x7c\xc9\x8d\x2d\x81", " XAUR", 8}, + { 1, "\xb1\x10\xec\x7b\x1d\xcb\x8f\xab\x8d\xed\xbf\x28\xf5\x3b\xc6\x3e\xa5\xbe\xdd\x84", " XID", 8}, + { 1, "\xb2\x47\x54\xbe\x79\x28\x15\x53\xdc\x1a\xdc\x16\x0d\xdf\x5c\xd9\xb7\x43\x61\xa4", " XRL", 9}, + { 1, "\xe4\x1d\x24\x89\x57\x1d\x32\x21\x89\x24\x6d\xaf\xa5\xeb\xde\x1f\x46\x99\xf4\x98", " ZRX", 18}, + {61, "\x08\x5f\xb4\xf2\x40\x31\xea\xed\xbc\x2b\x61\x1a\xa5\x28\xf2\x23\x43\xeb\x52\xdb", " BEC", 8}, +}; + +const TokenType *UnknownToken = (const TokenType *)1; + +const TokenType *tokenByChainAddress(uint8_t chain_id, const uint8_t *address) +{ + if (!address) return 0; + for (int i = 0; i < TOKENS_COUNT; i++) { + if (chain_id == tokens[i].chain_id && memcmp(address, tokens[i].address, 20) == 0) { + return &(tokens[i]); + } + } + return UnknownToken; +} diff --git a/hardware-wallet/firmware/firmware/ethereum_tokens.h b/hardware-wallet/firmware/firmware/ethereum_tokens.h new file mode 100644 index 00000000..5f3499f4 --- /dev/null +++ b/hardware-wallet/firmware/firmware/ethereum_tokens.h @@ -0,0 +1,40 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __ETHEREUM_TOKENS_H__ +#define __ETHEREUM_TOKENS_H__ + +#include + +#define TOKENS_COUNT 125 + +typedef struct { + uint8_t chain_id; + const char * const address; + const char * const ticker; + int decimals; +} TokenType; + +extern const TokenType tokens[TOKENS_COUNT]; + +extern const TokenType *UnknownToken; + +const TokenType *tokenByChainAddress(uint8_t chain_id, const uint8_t *address); + +#endif diff --git a/hardware-wallet/firmware/firmware/fastflash.c b/hardware-wallet/firmware/firmware/fastflash.c new file mode 100644 index 00000000..7d7d8600 --- /dev/null +++ b/hardware-wallet/firmware/firmware/fastflash.c @@ -0,0 +1,41 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "fastflash.h" +#include "util.h" + +#include +#include +#include + +#define bootloader_vec ((vector_table_t *) 0x20000000) + +void __attribute__((noreturn)) run_bootloader(void) +{ + extern uint8_t __bootloader_start__[]; + extern uint8_t __bootloader_size__[]; + + // zero out SRAM + memset_reg(_ram_start, _ram_end, 0); + + // copy bootloader + memcpy(bootloader_vec, __bootloader_start__, (size_t) __bootloader_size__); + + load_vector_table(bootloader_vec); +} diff --git a/hardware-wallet/firmware/firmware/fastflash.h b/hardware-wallet/firmware/firmware/fastflash.h new file mode 100644 index 00000000..fe8bc05a --- /dev/null +++ b/hardware-wallet/firmware/firmware/fastflash.h @@ -0,0 +1,25 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __FASTFLASH_H__ +#define __FASTFLASH_H__ + +void __attribute__((noreturn)) run_bootloader(void); + +#endif diff --git a/hardware-wallet/firmware/firmware/fsm.c b/hardware-wallet/firmware/firmware/fsm.c new file mode 100644 index 00000000..40e8c781 --- /dev/null +++ b/hardware-wallet/firmware/firmware/fsm.c @@ -0,0 +1,1795 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include "trezor.h" +#include "fsm.h" +#include "messages.h" +#include "bip32.h" +#include "storage.h" +#include "coins.h" +#include "debug.h" +#include "transaction.h" +#include "rng.h" +#include "storage.h" +#include "oled.h" +#include "protect.h" +#include "pinmatrix.h" +#include "layout2.h" +#include "address.h" +#include "base58.h" +#include "ecdsa.h" +#include "reset.h" +#include "recovery.h" +#include "memory.h" +#include "usb.h" +#include "util.h" +#include "signing.h" +#include "aes/aes.h" +#include "hmac.h" +#include "crypto.h" +#include "base58.h" +#include "bip39.h" +#include "ripemd160.h" +#include "curves.h" +#include "secp256k1.h" +#include "ethereum.h" +#include "nem.h" +#include "nem2.h" +#include "rfc6979.h" +#include "gettext.h" +#include "skycoin_crypto.h" + +// message methods + +static uint8_t msg_resp[MSG_OUT_SIZE] __attribute__ ((aligned)); + +#define RESP_INIT(TYPE) \ + TYPE *resp = (TYPE *) (void *) msg_resp; \ + _Static_assert(sizeof(msg_resp) >= sizeof(TYPE), #TYPE " is too large"); \ + memset(resp, 0, sizeof(TYPE)); + +#define CHECK_INITIALIZED \ + if (!storage_isInitialized()) { \ + fsm_sendFailure(FailureType_Failure_NotInitialized, NULL); \ + return; \ + } + +#define CHECK_NOT_INITIALIZED \ + if (storage_isInitialized()) { \ + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Device is already initialized. Use Wipe first.")); \ + return; \ + } + +#define CHECK_PIN \ + if (!protectPin(true)) { \ + layoutHome(); \ + return; \ + } + +#define CHECK_PIN_UNCACHED \ + if (!protectPin(false)) { \ + layoutHome(); \ + return; \ + } + +#define CHECK_PARAM(cond, errormsg) \ + if (!(cond)) { \ + fsm_sendFailure(FailureType_Failure_DataError, (errormsg)); \ + layoutHome(); \ + return; \ + } + +void fsm_sendSuccess(const char *text) +{ + RESP_INIT(Success); + if (text) { + resp->has_message = true; + strlcpy(resp->message, text, sizeof(resp->message)); + } + msg_write(MessageType_MessageType_Success, resp); +} + +#if DEBUG_LINK +void fsm_sendFailureDebug(FailureType code, const char *text, const char *source) +#else +void fsm_sendFailure(FailureType code, const char *text) +#endif +{ + if (protectAbortedByInitialize) { + fsm_msgInitialize((Initialize *)0); + protectAbortedByInitialize = false; + return; + } + RESP_INIT(Failure); + resp->has_code = true; + resp->code = code; + if (!text) { + switch (code) { + case FailureType_Failure_UnexpectedMessage: + text = _("Unexpected message"); + break; + case FailureType_Failure_ButtonExpected: + text = _("Button expected"); + break; + case FailureType_Failure_DataError: + text = _("Data error"); + break; + case FailureType_Failure_ActionCancelled: + text = _("Action cancelled by user"); + break; + case FailureType_Failure_PinExpected: + text = _("PIN expected"); + break; + case FailureType_Failure_PinCancelled: + text = _("PIN cancelled"); + break; + case FailureType_Failure_PinInvalid: + text = _("PIN invalid"); + break; + case FailureType_Failure_InvalidSignature: + text = _("Invalid signature"); + break; + case FailureType_Failure_ProcessError: + text = _("Process error"); + break; + case FailureType_Failure_NotEnoughFunds: + text = _("Not enough funds"); + break; + case FailureType_Failure_NotInitialized: + text = _("Device not initialized"); + break; + case FailureType_Failure_PinMismatch: + text = _("PIN mismatch"); + break; + case FailureType_Failure_FirmwareError: + text = _("Firmware error"); + break; + } + } +#if DEBUG_LINK + resp->has_message = true; + strlcpy(resp->message, source, sizeof(resp->message)); + if (text) { + strlcat(resp->message, text, sizeof(resp->message)); + } +#else + if (text) { + resp->has_message = true; + strlcpy(resp->message, text, sizeof(resp->message)); + } +#endif + msg_write(MessageType_MessageType_Failure, resp); +} + +static const CoinInfo *fsm_getCoin(bool has_name, const char *name) +{ + const CoinInfo *coin; + if (has_name) { + coin = coinByName(name); + } else { + coin = coinByName("Bitcoin"); + } + if (!coin) { + fsm_sendFailure(FailureType_Failure_DataError, _("Invalid coin name")); + layoutHome(); + return 0; + } + return coin; +} + +static HDNode *fsm_getDerivedNode(const char *curve, const uint32_t *address_n, size_t address_n_count, uint32_t *fingerprint) +{ + static CONFIDENTIAL HDNode node; + if (fingerprint) { + *fingerprint = 0; + } + if (!storage_getRootNode(&node, curve, true)) { + fsm_sendFailure(FailureType_Failure_NotInitialized, _("Device not initialized or passphrase request cancelled or unsupported curve")); + layoutHome(); + return 0; + } + if (!address_n || address_n_count == 0) { + return &node; + } + if (hdnode_private_ckd_cached(&node, address_n, address_n_count, fingerprint) == 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to derive private key")); + layoutHome(); + return 0; + } + return &node; +} + +static bool fsm_layoutAddress(const char *address, const char *desc, bool ignorecase, const uint32_t *address_n, size_t address_n_count) +{ + bool qrcode = false; + for (;;) { + layoutAddress(address, desc, qrcode, ignorecase, address_n, address_n_count); + if (protectButton(ButtonRequestType_ButtonRequest_Address, false)) { + return true; + } + if (protectAbortedByInitialize) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return false; + } + qrcode = !qrcode; + } +} + +void fsm_msgInitialize(Initialize *msg) +{ + recovery_abort(); + signing_abort(); + if (msg && msg->has_state && msg->state.size == 64) { + uint8_t i_state[64]; + if (!session_getState(msg->state.bytes, i_state, NULL)) { + session_clear(false); // do not clear PIN + } else { + if (0 != memcmp(msg->state.bytes, i_state, 64)) { + session_clear(false); // do not clear PIN + } + } + } else { + session_clear(false); // do not clear PIN + } + layoutHome(); + fsm_msgGetFeatures(0); +} + +void fsm_msgGetFeatures(GetFeatures *msg) +{ + (void)msg; + RESP_INIT(Features); + resp->has_vendor = true; strlcpy(resp->vendor, "bitcointrezor.com", sizeof(resp->vendor)); + resp->has_major_version = true; resp->major_version = VERSION_MAJOR; + resp->has_minor_version = true; resp->minor_version = VERSION_MINOR; + resp->has_patch_version = true; resp->patch_version = VERSION_PATCH; + resp->has_device_id = true; strlcpy(resp->device_id, storage_uuid_str, sizeof(resp->device_id)); + resp->has_pin_protection = true; resp->pin_protection = storage_hasPin(); + resp->has_passphrase_protection = true; resp->passphrase_protection = storage_hasPassphraseProtection(); +#ifdef SCM_REVISION + int len = sizeof(SCM_REVISION) - 1; + resp->has_revision = true; memcpy(resp->revision.bytes, SCM_REVISION, len); resp->revision.size = len; +#endif + resp->has_bootloader_hash = true; resp->bootloader_hash.size = memory_bootloader_hash(resp->bootloader_hash.bytes); + if (storage_getLanguage()) { + resp->has_language = true; + strlcpy(resp->language, storage_getLanguage(), sizeof(resp->language)); + } + if (storage_getLabel()) { + resp->has_label = true; + strlcpy(resp->label, storage_getLabel(), sizeof(resp->label)); + } + + _Static_assert(pb_arraysize(Features, coins) >= COINS_COUNT, "Features.coins max_count not large enough"); + + resp->coins_count = COINS_COUNT; + for (int i = 0; i < COINS_COUNT; i++) { + if (coins[i].coin_name) { + resp->coins[i].has_coin_name = true; + strlcpy(resp->coins[i].coin_name, coins[i].coin_name, sizeof(resp->coins[i].coin_name)); + } + if (coins[i].coin_shortcut) { + resp->coins[i].has_coin_shortcut = true; + strlcpy(resp->coins[i].coin_shortcut, coins[i].coin_shortcut + 1, sizeof(resp->coins[i].coin_shortcut)); + } + resp->coins[i].has_address_type = coins[i].has_address_type; + resp->coins[i].address_type = coins[i].address_type; + resp->coins[i].has_maxfee_kb = true; + resp->coins[i].maxfee_kb = coins[i].maxfee_kb; + resp->coins[i].has_address_type_p2sh = coins[i].has_address_type_p2sh; + resp->coins[i].address_type_p2sh = coins[i].address_type_p2sh; + resp->coins[i].has_xpub_magic = coins[i].xpub_magic != 0; + resp->coins[i].xpub_magic = coins[i].xpub_magic; + resp->coins[i].has_xprv_magic = coins[i].xprv_magic != 0; + resp->coins[i].xprv_magic = coins[i].xprv_magic; + resp->coins[i].has_segwit = true; + resp->coins[i].segwit = coins[i].has_segwit; + resp->coins[i].has_forkid = coins[i].has_forkid; + resp->coins[i].forkid = coins[i].forkid; + resp->coins[i].has_force_bip143 = true; + resp->coins[i].force_bip143 = coins[i].force_bip143; + } + resp->has_initialized = true; resp->initialized = storage_isInitialized(); + resp->has_imported = true; resp->imported = storage_isImported(); + resp->has_pin_cached = true; resp->pin_cached = session_isPinCached(); + resp->has_passphrase_cached = true; resp->passphrase_cached = session_isPassphraseCached(); + resp->has_needs_backup = true; resp->needs_backup = storage_needsBackup(); + resp->has_flags = true; resp->flags = storage_getFlags(); + resp->has_model = true; strlcpy(resp->model, "1", sizeof(resp->model)); + + msg_write(MessageType_MessageType_Features, resp); +} + +void fsm_msgSkycoinCheckMessageSignature(SkycoinCheckMessageSignature* msg) +{ + uint8_t sign[65]; + size_t size_sign = sizeof(sign); + char pubkeybase58[36]; + uint8_t pubkey[33] = {0}; + uint8_t digest[32] = {0}; + + RESP_INIT(Success); + compute_sha256sum(msg->message, digest, strlen(msg->message)); + size_sign = sizeof(sign); + b58tobin(sign, &size_sign, msg->signature); + recover_pubkey_from_signed_message((char*)digest, sign, pubkey); + size_sign = sizeof(pubkeybase58); + generate_base58_address_from_pubkey(pubkey, pubkeybase58, &size_sign); + if (memcmp(pubkeybase58, msg->address, size_sign) == 0) + { + layoutRawMessage("Verification success"); + } + else { + layoutRawMessage("Wrong signature"); + } + memcpy(resp->message, pubkeybase58, size_sign); + resp->has_message = true; + msg_write(MessageType_MessageType_Success, resp); +} + +void fsm_msgSkycoinSignMessage(SkycoinSignMessage* msg) +{ + uint8_t seckey[32] = {0}; + uint8_t digest[32] = {0}; + uint8_t signature[65]; + char sign58[90] = {0}; + int res = 0; + RESP_INIT(Success); + size_t size_seckey = sizeof(seckey); + b58tobin(seckey, &size_seckey, msg->secretKey); + compute_sha256sum(msg->message, digest, strlen(msg->message)); + res = ecdsa_skycoin_sign(1, seckey, digest, signature); + if (res == 0) + { + layoutRawMessage("Signature success"); + } + else + { + layoutRawMessage("Signature failed"); + } + size_seckey = sizeof(sign58); + b58enc(sign58, &size_seckey, signature, sizeof(signature)); + memcpy(resp->message, sign58, size_seckey); + resp->has_message = true; + msg_write(MessageType_MessageType_Success, resp); +} + +void fsm_msgSkycoinAddress(SkycoinAddress* msg) +{ + uint8_t seckey[32] = {0}; + uint8_t pubkey[33] = {0}; + + RESP_INIT(Success); + if (msg->has_address_type) + { + char address[256] = {0}; + size_t size_address = sizeof(address); + generate_deterministic_key_pair_iterator(msg->seed, seckey, pubkey); + switch (msg->address_type) + { + case SkycoinAddressType_AddressTypeSkycoin: + layoutRawMessage("Skycoin address"); + generate_base58_address_from_pubkey(pubkey, address, &size_address); + memcpy(resp->message, address, size_address); + break; + case SkycoinAddressType_AddressTypeBitcoin: + layoutRawMessage("Bitcoin address"); + generate_bitcoin_address_from_pubkey(pubkey, address, &size_address); + memcpy(resp->message, address, size_address); + break; + default: + layoutRawMessage("Unknown address type"); + break; + } + } + else { + generate_deterministic_key_pair_iterator(msg->seed, seckey, pubkey); + tohex(resp->message, pubkey, 33); + layoutRawMessage(resp->message); + } + resp->has_message = true; + msg_write(MessageType_MessageType_Success, resp); +} + +void fsm_msgPing(Ping *msg) +{ + RESP_INIT(Success); + + if (msg->has_button_protection && msg->button_protection) { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("answer to ping?"), NULL, NULL, NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + + if (msg->has_pin_protection && msg->pin_protection) { + CHECK_PIN + } + + if (msg->has_passphrase_protection && msg->passphrase_protection) { + if (!protectPassphrase()) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + return; + } + } + + if (msg->has_message) { + resp->has_message = true; + memcpy(&(resp->message), &(msg->message), sizeof(resp->message)); + } + msg_write(MessageType_MessageType_Success, resp); + layoutHome(); +} + +void fsm_msgChangePin(ChangePin *msg) +{ + bool removal = msg->has_remove && msg->remove; + if (removal) { + if (storage_hasPin()) { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("remove current PIN?"), NULL, NULL, NULL, NULL); + } else { + fsm_sendSuccess(_("PIN removed")); + return; + } + } else { + if (storage_hasPin()) { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("change current PIN?"), NULL, NULL, NULL, NULL); + } else { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("set new PIN?"), NULL, NULL, NULL, NULL); + } + } + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN_UNCACHED + + if (removal) { + storage_setPin(""); + storage_update(); + fsm_sendSuccess(_("PIN removed")); + } else { + if (protectChangePin()) { + fsm_sendSuccess(_("PIN changed")); + } else { + fsm_sendFailure(FailureType_Failure_PinMismatch, NULL); + } + } + layoutHome(); +} + +void fsm_msgWipeDevice(WipeDevice *msg) +{ + (void)msg; + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("wipe the device?"), NULL, _("All data will be lost."), NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_WipeDevice, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + storage_wipe(); + // the following does not work on Mac anyway :-/ Linux/Windows are fine, so it is not needed + // usbReconnect(); // force re-enumeration because of the serial number change + fsm_sendSuccess(_("Device wiped")); + layoutHome(); +} + +void fsm_msgGetEntropy(GetEntropy *msg) +{ +#if !DEBUG_RNG + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("send entropy?"), NULL, NULL, NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } +#endif + RESP_INIT(Entropy); + uint32_t len = msg->size; + if (len > 1024) { + len = 1024; + } + resp->entropy.size = len; + random_buffer(resp->entropy.bytes, len); + msg_write(MessageType_MessageType_Entropy, resp); + layoutHome(); +} + +void fsm_msgGetPublicKey(GetPublicKey *msg) +{ + RESP_INIT(PublicKey); + + CHECK_INITIALIZED + + CHECK_PIN + + const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name); + if (!coin) return; + + const char *curve = coin->curve_name; + if (msg->has_ecdsa_curve_name) { + curve = msg->ecdsa_curve_name; + } + uint32_t fingerprint; + HDNode *node = node = fsm_getDerivedNode(curve, msg->address_n, msg->address_n_count, &fingerprint); + if (!node) return; + hdnode_fill_public_key(node); + + if (msg->has_show_display && msg->show_display) { + layoutPublicKey(node->public_key); + if (!protectButton(ButtonRequestType_ButtonRequest_PublicKey, true)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + + resp->node.depth = node->depth; + resp->node.fingerprint = fingerprint; + resp->node.child_num = node->child_num; + resp->node.chain_code.size = 32; + memcpy(resp->node.chain_code.bytes, node->chain_code, 32); + resp->node.has_private_key = false; + resp->node.has_public_key = true; + resp->node.public_key.size = 33; + memcpy(resp->node.public_key.bytes, node->public_key, 33); + if (node->public_key[0] == 1) { + /* ed25519 public key */ + resp->node.public_key.bytes[0] = 0; + } + resp->has_xpub = true; + hdnode_serialize_public(node, fingerprint, coin->xpub_magic, resp->xpub, sizeof(resp->xpub)); + msg_write(MessageType_MessageType_PublicKey, resp); + layoutHome(); +} + +void fsm_msgLoadDevice(LoadDevice *msg) +{ + CHECK_NOT_INITIALIZED + + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("I take the risk"), NULL, _("Loading private seed"), _("is not recommended."), _("Continue only if you"), _("know what you are"), _("doing!"), NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + if (msg->has_mnemonic && !(msg->has_skip_checksum && msg->skip_checksum) ) { + if (!mnemonic_check(msg->mnemonic)) { + fsm_sendFailure(FailureType_Failure_DataError, _("Mnemonic with wrong checksum provided")); + layoutHome(); + return; + } + } + + storage_loadDevice(msg); + fsm_sendSuccess(_("Device loaded")); + layoutHome(); +} + +void fsm_msgResetDevice(ResetDevice *msg) +{ + CHECK_NOT_INITIALIZED + + CHECK_PARAM(!msg->has_strength || msg->strength == 128 || msg->strength == 192 || msg->strength == 256, _("Invalid seed strength")); + + reset_init( + msg->has_display_random && msg->display_random, + msg->has_strength ? msg->strength : 128, + msg->has_passphrase_protection && msg->passphrase_protection, + msg->has_pin_protection && msg->pin_protection, + msg->has_language ? msg->language : 0, + msg->has_label ? msg->label : 0, + msg->has_u2f_counter ? msg->u2f_counter : 0, + msg->has_skip_backup ? msg->skip_backup : false + ); +} + +void fsm_msgBackupDevice(BackupDevice *msg) +{ + CHECK_INITIALIZED + + CHECK_PIN_UNCACHED + + (void)msg; + reset_backup(true); +} + +void fsm_msgSignTx(SignTx *msg) +{ + CHECK_INITIALIZED + + CHECK_PARAM(msg->inputs_count > 0, _("Transaction must have at least one input")); + CHECK_PARAM(msg->outputs_count > 0, _("Transaction must have at least one output")); + + CHECK_PIN + + const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name); + if (!coin) return; + const HDNode *node = fsm_getDerivedNode(coin->curve_name, NULL, 0, NULL); + if (!node) return; + + signing_init(msg->inputs_count, msg->outputs_count, coin, node, msg->version, msg->lock_time); +} + +void fsm_msgTxAck(TxAck *msg) +{ + CHECK_PARAM(msg->has_tx, _("No transaction provided")); + + signing_txack(&(msg->tx)); +} + +void fsm_msgCancel(Cancel *msg) +{ + (void)msg; + recovery_abort(); + signing_abort(); + ethereum_signing_abort(); + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); +} + +void fsm_msgEthereumSignTx(EthereumSignTx *msg) +{ + CHECK_INITIALIZED + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + ethereum_signing_init(msg, node); +} + +void fsm_msgEthereumTxAck(EthereumTxAck *msg) +{ + ethereum_signing_txack(msg); +} + +void fsm_msgCipherKeyValue(CipherKeyValue *msg) +{ + CHECK_INITIALIZED + + CHECK_PARAM(msg->has_key, _("No key provided")); + CHECK_PARAM(msg->has_value, _("No value provided")); + CHECK_PARAM(msg->value.size % 16 == 0, _("Value length must be a multiple of 16")); + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + bool encrypt = msg->has_encrypt && msg->encrypt; + bool ask_on_encrypt = msg->has_ask_on_encrypt && msg->ask_on_encrypt; + bool ask_on_decrypt = msg->has_ask_on_decrypt && msg->ask_on_decrypt; + if ((encrypt && ask_on_encrypt) || (!encrypt && ask_on_decrypt)) { + layoutCipherKeyValue(encrypt, msg->key); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + + uint8_t data[256 + 4]; + strlcpy((char *)data, msg->key, sizeof(data)); + strlcat((char *)data, ask_on_encrypt ? "E1" : "E0", sizeof(data)); + strlcat((char *)data, ask_on_decrypt ? "D1" : "D0", sizeof(data)); + + hmac_sha512(node->private_key, 32, data, strlen((char *)data), data); + + RESP_INIT(CipheredKeyValue); + if (encrypt) { + aes_encrypt_ctx ctx; + aes_encrypt_key256(data, &ctx); + aes_cbc_encrypt(msg->value.bytes, resp->value.bytes, msg->value.size, ((msg->iv.size == 16) ? (msg->iv.bytes) : (data + 32)), &ctx); + } else { + aes_decrypt_ctx ctx; + aes_decrypt_key256(data, &ctx); + aes_cbc_decrypt(msg->value.bytes, resp->value.bytes, msg->value.size, ((msg->iv.size == 16) ? (msg->iv.bytes) : (data + 32)), &ctx); + } + resp->has_value = true; + resp->value.size = msg->value.size; + msg_write(MessageType_MessageType_CipheredKeyValue, resp); + layoutHome(); +} + +void fsm_msgClearSession(ClearSession *msg) +{ + (void)msg; + session_clear(true); // clear PIN as well + layoutScreensaver(); + fsm_sendSuccess(_("Session cleared")); +} + +void fsm_msgApplySettings(ApplySettings *msg) +{ + CHECK_PARAM(msg->has_label || msg->has_language || msg->has_use_passphrase || msg->has_homescreen, _("No setting provided")); + + CHECK_PIN + + if (msg->has_label) { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("change name to"), msg->label, "?", NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + if (msg->has_language) { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("change language to"), msg->language, "?", NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + if (msg->has_use_passphrase) { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), msg->use_passphrase ? _("enable passphrase") : _("disable passphrase"), _("encryption?"), NULL, NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + if (msg->has_homescreen) { + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you really want to"), _("change the home"), _("screen?"), NULL, NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + + if (msg->has_label) { + storage_setLabel(msg->label); + } + if (msg->has_language) { + storage_setLanguage(msg->language); + } + if (msg->has_use_passphrase) { + storage_setPassphraseProtection(msg->use_passphrase); + } + if (msg->has_homescreen) { + storage_setHomescreen(msg->homescreen.bytes, msg->homescreen.size); + } + storage_update(); + fsm_sendSuccess(_("Settings applied")); + layoutHome(); +} + +void fsm_msgApplyFlags(ApplyFlags *msg) +{ + if (msg->has_flags) { + storage_applyFlags(msg->flags); + } + fsm_sendSuccess(_("Flags applied")); +} + +static bool path_mismatched(const CoinInfo *coin, const GetAddress *msg) +{ + bool mismatch = false; + + // m : no path + if (msg->address_n_count == 0) { + return false; + } + + // m/44' : BIP44 Legacy + // m / purpose' / coin_type' / account' / change / address_index + if (msg->address_n[0] == (0x80000000 + 44)) { + mismatch |= (msg->script_type != InputScriptType_SPENDADDRESS); + mismatch |= (msg->address_n_count != 5); + mismatch |= (msg->address_n[1] != coin->coin_type); + mismatch |= (msg->address_n[2] & 0x80000000) == 0; + mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; + mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; + return mismatch; + } + + // m/45' - BIP45 Copay Abandoned Multisig P2SH + // m / purpose' / cosigner_index / change / address_index + if (msg->address_n[0] == (0x80000000 + 45)) { + mismatch |= (msg->script_type != InputScriptType_SPENDMULTISIG); + mismatch |= (msg->address_n_count != 4); + mismatch |= (msg->address_n[1] & 0x80000000) == 0x80000000; + mismatch |= (msg->address_n[2] & 0x80000000) == 0x80000000; + mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; + return mismatch; + } + + // m/48' - BIP48 Copay Multisig P2SH + // m / purpose' / coin_type' / account' / change / address_index + if (msg->address_n[0] == (0x80000000 + 48)) { + mismatch |= (msg->script_type != InputScriptType_SPENDMULTISIG); + mismatch |= (msg->address_n_count != 5); + mismatch |= (msg->address_n[1] != coin->coin_type); + mismatch |= (msg->address_n[2] & 0x80000000) == 0; + mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; + mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; + return mismatch; + } + + // m/49' : BIP49 SegWit + // m / purpose' / coin_type' / account' / change / address_index + if (msg->address_n[0] == (0x80000000 + 49)) { + mismatch |= (msg->script_type != InputScriptType_SPENDP2SHWITNESS); + mismatch |= !coin->has_segwit; + mismatch |= !coin->has_address_type_p2sh; + mismatch |= (msg->address_n_count != 5); + mismatch |= (msg->address_n[1] != coin->coin_type); + mismatch |= (msg->address_n[2] & 0x80000000) == 0; + mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; + mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; + return mismatch; + } + + // m/84' : BIP84 Native SegWit + // m / purpose' / coin_type' / account' / change / address_index + if (msg->address_n[0] == (0x80000000 + 84)) { + mismatch |= (msg->script_type != InputScriptType_SPENDWITNESS); + mismatch |= !coin->has_segwit; + mismatch |= !coin->bech32_prefix; + mismatch |= (msg->address_n_count != 5); + mismatch |= (msg->address_n[1] != coin->coin_type); + mismatch |= (msg->address_n[2] & 0x80000000) == 0; + mismatch |= (msg->address_n[3] & 0x80000000) == 0x80000000; + mismatch |= (msg->address_n[4] & 0x80000000) == 0x80000000; + return mismatch; + } + + return false; +} + +void fsm_msgGetAddress(GetAddress *msg) +{ + RESP_INIT(Address); + + CHECK_INITIALIZED + + CHECK_PIN + + const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name); + if (!coin) return; + HDNode *node = fsm_getDerivedNode(coin->curve_name, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + hdnode_fill_public_key(node); + + char address[MAX_ADDR_SIZE]; + layoutProgress(_("Computing address"), 0); + if (!compute_address(coin, msg->script_type, node, msg->has_multisig, &msg->multisig, address)) { + fsm_sendFailure(FailureType_Failure_DataError, _("Can't encode address")); + layoutHome(); + return; + } + + if (msg->has_show_display && msg->show_display) { + char desc[20]; + if (msg->has_multisig) { + strlcpy(desc, "Multisig __ of __:", sizeof(desc)); + const uint32_t m = msg->multisig.m; + const uint32_t n = msg->multisig.pubkeys_count; + desc[9] = (m < 10) ? ' ': ('0' + (m / 10)); + desc[10] = '0' + (m % 10); + desc[15] = (n < 10) ? ' ': ('0' + (n / 10)); + desc[16] = '0' + (n % 10); + } else { + strlcpy(desc, _("Address:"), sizeof(desc)); + } + + bool mismatch = path_mismatched(coin, msg); + + if (mismatch) { + layoutDialogSwipe(&bmp_icon_warning, _("Abort"), _("Continue"), NULL, _("Wrong address path"), _("for selected coin."), NULL, _("Continue at your"), _("own risk!"), NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + + if (!fsm_layoutAddress(address, desc, msg->script_type == InputScriptType_SPENDWITNESS, msg->address_n, msg->address_n_count)) { + return; + } + } + + strlcpy(resp->address, address, sizeof(resp->address)); + msg_write(MessageType_MessageType_Address, resp); + layoutHome(); +} + +void fsm_msgEthereumGetAddress(EthereumGetAddress *msg) +{ + RESP_INIT(EthereumAddress); + + CHECK_INITIALIZED + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + resp->address.size = 20; + + if (!hdnode_get_ethereum_pubkeyhash(node, resp->address.bytes)) + return; + + if (msg->has_show_display && msg->show_display) { + char desc[16]; + strlcpy(desc, "Address:", sizeof(desc)); + + char address[43] = { '0', 'x' }; + ethereum_address_checksum(resp->address.bytes, address + 2); + + if (!fsm_layoutAddress(address, desc, false, msg->address_n, msg->address_n_count)) { + return; + } + } + + msg_write(MessageType_MessageType_EthereumAddress, resp); + layoutHome(); +} + +void fsm_msgEthereumSignMessage(EthereumSignMessage *msg) +{ + RESP_INIT(EthereumMessageSignature); + + CHECK_INITIALIZED + + layoutSignMessage(msg->message.bytes, msg->message.size); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + ethereum_message_sign(msg, node, resp); + layoutHome(); +} + +void fsm_msgEthereumVerifyMessage(EthereumVerifyMessage *msg) +{ + CHECK_PARAM(msg->has_address, _("No address provided")); + CHECK_PARAM(msg->has_message, _("No message provided")); + + if (ethereum_message_verify(msg) != 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Invalid signature")); + return; + } + + char address[43] = { '0', 'x' }; + ethereum_address_checksum(msg->address.bytes, address + 2); + layoutVerifyAddress(address); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + layoutVerifyMessage(msg->message.bytes, msg->message.size); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + fsm_sendSuccess(_("Message verified")); + + layoutHome(); +} + +void fsm_msgEntropyAck(EntropyAck *msg) +{ + if (msg->has_entropy) { + reset_entropy(msg->entropy.bytes, msg->entropy.size); + } else { + reset_entropy(0, 0); + } +} + +void fsm_msgSignMessage(SignMessage *msg) +{ + RESP_INIT(MessageSignature); + + CHECK_INITIALIZED + + layoutSignMessage(msg->message.bytes, msg->message.size); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name); + if (!coin) return; + HDNode *node = fsm_getDerivedNode(coin->curve_name, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + layoutProgressSwipe(_("Signing"), 0); + if (cryptoMessageSign(coin, node, msg->script_type, msg->message.bytes, msg->message.size, resp->signature.bytes) == 0) { + resp->has_address = true; + hdnode_fill_public_key(node); + if (!compute_address(coin, msg->script_type, node, false, NULL, resp->address)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Error computing address")); + layoutHome(); + return; + } + resp->has_signature = true; + resp->signature.size = 65; + msg_write(MessageType_MessageType_MessageSignature, resp); + } else { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Error signing message")); + } + layoutHome(); +} + +void fsm_msgVerifyMessage(VerifyMessage *msg) +{ + CHECK_PARAM(msg->has_address, _("No address provided")); + CHECK_PARAM(msg->has_message, _("No message provided")); + + const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name); + if (!coin) return; + layoutProgressSwipe(_("Verifying"), 0); + if (msg->signature.size == 65 && cryptoMessageVerify(coin, msg->message.bytes, msg->message.size, msg->address, msg->signature.bytes) == 0) { + layoutVerifyAddress(msg->address); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + layoutVerifyMessage(msg->message.bytes, msg->message.size); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + fsm_sendSuccess(_("Message verified")); + } else { + fsm_sendFailure(FailureType_Failure_DataError, _("Invalid signature")); + } + layoutHome(); +} + +void fsm_msgSignIdentity(SignIdentity *msg) +{ + RESP_INIT(SignedIdentity); + + CHECK_INITIALIZED + + layoutSignIdentity(&(msg->identity), msg->has_challenge_visual ? msg->challenge_visual : 0); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + uint8_t hash[32]; + if (!msg->has_identity || cryptoIdentityFingerprint(&(msg->identity), hash) == 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Invalid identity")); + layoutHome(); + return; + } + + uint32_t address_n[5]; + address_n[0] = 0x80000000 | 13; + address_n[1] = 0x80000000 | hash[ 0] | (hash[ 1] << 8) | (hash[ 2] << 16) | (hash[ 3] << 24); + address_n[2] = 0x80000000 | hash[ 4] | (hash[ 5] << 8) | (hash[ 6] << 16) | (hash[ 7] << 24); + address_n[3] = 0x80000000 | hash[ 8] | (hash[ 9] << 8) | (hash[10] << 16) | (hash[11] << 24); + address_n[4] = 0x80000000 | hash[12] | (hash[13] << 8) | (hash[14] << 16) | (hash[15] << 24); + + const char *curve = SECP256K1_NAME; + if (msg->has_ecdsa_curve_name) { + curve = msg->ecdsa_curve_name; + } + HDNode *node = fsm_getDerivedNode(curve, address_n, 5, NULL); + if (!node) return; + + bool sign_ssh = msg->identity.has_proto && (strcmp(msg->identity.proto, "ssh") == 0); + bool sign_gpg = msg->identity.has_proto && (strcmp(msg->identity.proto, "gpg") == 0); + + int result = 0; + layoutProgressSwipe(_("Signing"), 0); + if (sign_ssh) { // SSH does not sign visual challenge + result = sshMessageSign(node, msg->challenge_hidden.bytes, msg->challenge_hidden.size, resp->signature.bytes); + } else if (sign_gpg) { // GPG should sign a message digest + result = gpgMessageSign(node, msg->challenge_hidden.bytes, msg->challenge_hidden.size, resp->signature.bytes); + } else { + uint8_t digest[64]; + sha256_Raw(msg->challenge_hidden.bytes, msg->challenge_hidden.size, digest); + sha256_Raw((const uint8_t *)msg->challenge_visual, strlen(msg->challenge_visual), digest + 32); + result = cryptoMessageSign(&(coins[0]), node, InputScriptType_SPENDADDRESS, digest, 64, resp->signature.bytes); + } + + if (result == 0) { + hdnode_fill_public_key(node); + if (strcmp(curve, SECP256K1_NAME) != 0) { + resp->has_address = false; + } else { + resp->has_address = true; + hdnode_get_address(node, 0x00, resp->address, sizeof(resp->address)); // hardcoded Bitcoin address type + } + resp->has_public_key = true; + resp->public_key.size = 33; + memcpy(resp->public_key.bytes, node->public_key, 33); + if (node->public_key[0] == 1) { + /* ed25519 public key */ + resp->public_key.bytes[0] = 0; + } + resp->has_signature = true; + resp->signature.size = 65; + msg_write(MessageType_MessageType_SignedIdentity, resp); + } else { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Error signing identity")); + } + layoutHome(); +} + +void fsm_msgGetECDHSessionKey(GetECDHSessionKey *msg) +{ + RESP_INIT(ECDHSessionKey); + + CHECK_INITIALIZED + + layoutDecryptIdentity(&msg->identity); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + uint8_t hash[32]; + if (!msg->has_identity || cryptoIdentityFingerprint(&(msg->identity), hash) == 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Invalid identity")); + layoutHome(); + return; + } + + uint32_t address_n[5]; + address_n[0] = 0x80000000 | 17; + address_n[1] = 0x80000000 | hash[ 0] | (hash[ 1] << 8) | (hash[ 2] << 16) | (hash[ 3] << 24); + address_n[2] = 0x80000000 | hash[ 4] | (hash[ 5] << 8) | (hash[ 6] << 16) | (hash[ 7] << 24); + address_n[3] = 0x80000000 | hash[ 8] | (hash[ 9] << 8) | (hash[10] << 16) | (hash[11] << 24); + address_n[4] = 0x80000000 | hash[12] | (hash[13] << 8) | (hash[14] << 16) | (hash[15] << 24); + + const char *curve = SECP256K1_NAME; + if (msg->has_ecdsa_curve_name) { + curve = msg->ecdsa_curve_name; + } + + const HDNode *node = fsm_getDerivedNode(curve, address_n, 5, NULL); + if (!node) return; + + int result_size = 0; + if (hdnode_get_shared_key(node, msg->peer_public_key.bytes, resp->session_key.bytes, &result_size) == 0) { + resp->has_session_key = true; + resp->session_key.size = result_size; + msg_write(MessageType_MessageType_ECDHSessionKey, resp); + } else { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Error getting ECDH session key")); + } + layoutHome(); +} + +/* ECIES disabled +void fsm_msgEncryptMessage(EncryptMessage *msg) +{ + CHECK_INITIALIZED + + CHECK_PARAM(msg->has_pubkey, _("No public key provided")); + CHECK_PARAM(msg->has_message, _("No message provided")); + CHECK_PARAM(msg->pubkey.size == 33, _("Invalid public key provided")); + curve_point pubkey; + CHECK_PARAM(ecdsa_read_pubkey(&secp256k1, msg->pubkey.bytes, &pubkey) == 1, _("Invalid public key provided")); + + bool display_only = msg->has_display_only && msg->display_only; + bool signing = msg->address_n_count > 0; + RESP_INIT(EncryptedMessage); + const HDNode *node = 0; + uint8_t address_raw[MAX_ADDR_RAW_SIZE]; + if (signing) { + const CoinInfo *coin = fsm_getCoin(msg->has_coin_name, msg->coin_name); + if (!coin) return; + + CHECK_PIN + + node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + hdnode_get_address_raw(node, coin->address_type, address_raw); + } + layoutEncryptMessage(msg->message.bytes, msg->message.size, signing); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + layoutProgressSwipe(_("Encrypting"), 0); + if (cryptoMessageEncrypt(&pubkey, msg->message.bytes, msg->message.size, display_only, resp->nonce.bytes, &(resp->nonce.size), resp->message.bytes, &(resp->message.size), resp->hmac.bytes, &(resp->hmac.size), signing ? node->private_key : 0, signing ? address_raw : 0) != 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Error encrypting message")); + layoutHome(); + return; + } + resp->has_nonce = true; + resp->has_message = true; + resp->has_hmac = true; + msg_write(MessageType_MessageType_EncryptedMessage, resp); + layoutHome(); +} + +void fsm_msgDecryptMessage(DecryptMessage *msg) +{ + CHECK_INITIALIZED + + CHECK_PARAM(msg->has_nonce, _("No nonce provided")); + CHECK_PARAM(msg->has_message, _("No message provided")); + CHECK_PARAM(msg->has_hmac, _("No message hmac provided")); + + CHECK_PARAM(msg->nonce.size == 33, _("Invalid nonce key provided")); + curve_point nonce_pubkey; + CHECK_PARAM(ecdsa_read_pubkey(&secp256k1, msg->nonce.bytes, &nonce_pubkey) == 1, _("Invalid nonce provided")); + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + layoutProgressSwipe(_("Decrypting"), 0); + RESP_INIT(DecryptedMessage); + bool display_only = false; + bool signing = false; + uint8_t address_raw[MAX_ADDR_RAW_SIZE]; + if (cryptoMessageDecrypt(&nonce_pubkey, msg->message.bytes, msg->message.size, msg->hmac.bytes, msg->hmac.size, node->private_key, resp->message.bytes, &(resp->message.size), &display_only, &signing, address_raw) != 0) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + if (signing) { + base58_encode_check(address_raw, 21, resp->address, sizeof(resp->address)); + } + layoutDecryptMessage(resp->message.bytes, resp->message.size, signing ? resp->address : 0); + protectButton(ButtonRequestType_ButtonRequest_Other, true); + if (display_only) { + resp->has_address = false; + resp->has_message = false; + memset(resp->address, 0, sizeof(resp->address)); + memset(&(resp->message), 0, sizeof(resp->message)); + } else { + resp->has_address = signing; + resp->has_message = true; + } + msg_write(MessageType_MessageType_DecryptedMessage, resp); + layoutHome(); +} +*/ + +void fsm_msgRecoveryDevice(RecoveryDevice *msg) +{ + const bool dry_run = msg->has_dry_run ? msg->dry_run : false; + if (dry_run) { + CHECK_PIN + } else { + CHECK_NOT_INITIALIZED + } + + CHECK_PARAM(!msg->has_word_count || msg->word_count == 12 || msg->word_count == 18 || msg->word_count == 24, _("Invalid word count")); + + recovery_init( + msg->has_word_count ? msg->word_count : 12, + msg->has_passphrase_protection && msg->passphrase_protection, + msg->has_pin_protection && msg->pin_protection, + msg->has_language ? msg->language : 0, + msg->has_label ? msg->label : 0, + msg->has_enforce_wordlist && msg->enforce_wordlist, + msg->has_type ? msg->type : 0, + msg->has_u2f_counter ? msg->u2f_counter : 0, + dry_run + ); +} + +void fsm_msgWordAck(WordAck *msg) +{ + recovery_word(msg->word); +} + +void fsm_msgSetU2FCounter(SetU2FCounter *msg) +{ + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you want to set"), _("the U2F counter?"), NULL, NULL, NULL, NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + storage_setU2FCounter(msg->u2f_counter); + storage_update(); + fsm_sendSuccess(_("U2F counter set")); + layoutHome(); +} + +void fsm_msgNEMGetAddress(NEMGetAddress *msg) +{ + if (!msg->has_network) { + msg->network = NEM_NETWORK_MAINNET; + } + + const char *network; + CHECK_PARAM((network = nem_network_name(msg->network)), _("Invalid NEM network")); + + CHECK_INITIALIZED + CHECK_PIN + + RESP_INIT(NEMAddress); + + HDNode *node = fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + if (!hdnode_get_nem_address(node, msg->network, resp->address)) + return; + + if (msg->has_show_display && msg->show_display) { + char desc[16]; + strlcpy(desc, network, sizeof(desc)); + strlcat(desc, ":", sizeof(desc)); + + if (!fsm_layoutAddress(resp->address, desc, true, msg->address_n, msg->address_n_count)) { + return; + } + } + + msg_write(MessageType_MessageType_NEMAddress, resp); + layoutHome(); +} + +void fsm_msgNEMSignTx(NEMSignTx *msg) { + const char *reason; + +#define NEM_CHECK_PARAM(s) CHECK_PARAM( (reason = (s)) == NULL, reason) +#define NEM_CHECK_PARAM_WHEN(b, s) CHECK_PARAM(!(b) || (reason = (s)) == NULL, reason) + + CHECK_PARAM(msg->has_transaction, _("No common provided")); + + // Ensure exactly one transaction is provided + unsigned int provided = msg->has_transfer + + msg->has_provision_namespace + + msg->has_mosaic_creation + + msg->has_supply_change + + msg->has_aggregate_modification + + msg->has_importance_transfer; + CHECK_PARAM(provided != 0, _("No transaction provided")); + CHECK_PARAM(provided == 1, _("More than one transaction provided")); + + NEM_CHECK_PARAM(nem_validate_common(&msg->transaction, false)); + NEM_CHECK_PARAM_WHEN(msg->has_transfer, nem_validate_transfer(&msg->transfer, msg->transaction.network)); + NEM_CHECK_PARAM_WHEN(msg->has_provision_namespace, nem_validate_provision_namespace(&msg->provision_namespace, msg->transaction.network)); + NEM_CHECK_PARAM_WHEN(msg->has_mosaic_creation, nem_validate_mosaic_creation(&msg->mosaic_creation, msg->transaction.network)); + NEM_CHECK_PARAM_WHEN(msg->has_supply_change, nem_validate_supply_change(&msg->supply_change)); + NEM_CHECK_PARAM_WHEN(msg->has_aggregate_modification, nem_validate_aggregate_modification(&msg->aggregate_modification, !msg->has_multisig)); + NEM_CHECK_PARAM_WHEN(msg->has_importance_transfer, nem_validate_importance_transfer(&msg->importance_transfer)); + + bool cosigning = msg->has_cosigning && msg->cosigning; + if (msg->has_multisig) { + NEM_CHECK_PARAM(nem_validate_common(&msg->multisig, true)); + + CHECK_PARAM(msg->transaction.network == msg->multisig.network, _("Inner transaction network is different")); + } else { + CHECK_PARAM(!cosigning, _("No multisig transaction to cosign")); + } + + CHECK_INITIALIZED + CHECK_PIN + + const char *network = nem_network_name(msg->transaction.network); + + if (msg->has_multisig) { + char address[NEM_ADDRESS_SIZE + 1]; + nem_get_address(msg->multisig.signer.bytes, msg->multisig.network, address); + + if (!nem_askMultisig(address, network, cosigning, msg->transaction.fee)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user")); + layoutHome(); + return; + } + } + + RESP_INIT(NEMSignedTx); + + HDNode *node = fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->transaction.address_n, msg->transaction.address_n_count, NULL); + if (!node) return; + + hdnode_fill_public_key(node); + + const NEMTransactionCommon *common = msg->has_multisig ? &msg->multisig : &msg->transaction; + + char address[NEM_ADDRESS_SIZE + 1]; + hdnode_get_nem_address(node, common->network, address); + + if (msg->has_transfer) { + msg->transfer.mosaics_count = nem_canonicalizeMosaics(msg->transfer.mosaics, msg->transfer.mosaics_count); + } + + if (msg->has_transfer && !nem_askTransfer(common, &msg->transfer, network)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user")); + layoutHome(); + return; + } + + if (msg->has_provision_namespace && !nem_askProvisionNamespace(common, &msg->provision_namespace, network)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user")); + layoutHome(); + return; + } + + if (msg->has_mosaic_creation && !nem_askMosaicCreation(common, &msg->mosaic_creation, network, address)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user")); + layoutHome(); + return; + } + + if (msg->has_supply_change && !nem_askSupplyChange(common, &msg->supply_change, network)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user")); + layoutHome(); + return; + } + + if (msg->has_aggregate_modification && !nem_askAggregateModification(common, &msg->aggregate_modification, network, !msg->has_multisig)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user")); + layoutHome(); + return; + } + + if (msg->has_importance_transfer && !nem_askImportanceTransfer(common, &msg->importance_transfer, network)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, _("Signing cancelled by user")); + layoutHome(); + return; + } + + nem_transaction_ctx context; + nem_transaction_start(&context, &node->public_key[1], resp->data.bytes, sizeof(resp->data.bytes)); + + if (msg->has_multisig) { + uint8_t buffer[sizeof(resp->data.bytes)]; + + nem_transaction_ctx inner; + nem_transaction_start(&inner, msg->multisig.signer.bytes, buffer, sizeof(buffer)); + + if (msg->has_transfer && !nem_fsmTransfer(&inner, NULL, &msg->multisig, &msg->transfer)) { + layoutHome(); + return; + } + + if (msg->has_provision_namespace && !nem_fsmProvisionNamespace(&inner, &msg->multisig, &msg->provision_namespace)) { + layoutHome(); + return; + } + + if (msg->has_mosaic_creation && !nem_fsmMosaicCreation(&inner, &msg->multisig, &msg->mosaic_creation)) { + layoutHome(); + return; + } + + if (msg->has_supply_change && !nem_fsmSupplyChange(&inner, &msg->multisig, &msg->supply_change)) { + layoutHome(); + return; + } + + if (msg->has_aggregate_modification && !nem_fsmAggregateModification(&inner, &msg->multisig, &msg->aggregate_modification)) { + layoutHome(); + return; + } + + if (msg->has_importance_transfer && !nem_fsmImportanceTransfer(&inner, &msg->multisig, &msg->importance_transfer)) { + layoutHome(); + return; + } + + if (!nem_fsmMultisig(&context, &msg->transaction, &inner, cosigning)) { + layoutHome(); + return; + } + } else { + if (msg->has_transfer && !nem_fsmTransfer(&context, node, &msg->transaction, &msg->transfer)) { + layoutHome(); + return; + } + + if (msg->has_provision_namespace && !nem_fsmProvisionNamespace(&context, &msg->transaction, &msg->provision_namespace)) { + layoutHome(); + return; + } + + if (msg->has_mosaic_creation && !nem_fsmMosaicCreation(&context, &msg->transaction, &msg->mosaic_creation)) { + layoutHome(); + return; + } + + if (msg->has_supply_change && !nem_fsmSupplyChange(&context, &msg->transaction, &msg->supply_change)) { + layoutHome(); + return; + } + + if (msg->has_aggregate_modification && !nem_fsmAggregateModification(&context, &msg->transaction, &msg->aggregate_modification)) { + layoutHome(); + return; + } + + if (msg->has_importance_transfer && !nem_fsmImportanceTransfer(&context, &msg->transaction, &msg->importance_transfer)) { + layoutHome(); + return; + } + } + + resp->has_data = true; + resp->data.size = nem_transaction_end(&context, node->private_key, resp->signature.bytes); + + resp->has_signature = true; + resp->signature.size = sizeof(ed25519_signature); + + msg_write(MessageType_MessageType_NEMSignedTx, resp); + layoutHome(); +} + +void fsm_msgNEMDecryptMessage(NEMDecryptMessage *msg) +{ + RESP_INIT(NEMDecryptedMessage); + + CHECK_INITIALIZED + + CHECK_PARAM(nem_network_name(msg->network), _("Invalid NEM network")); + CHECK_PARAM(msg->has_payload, _("No payload provided")); + CHECK_PARAM(msg->payload.size >= NEM_ENCRYPTED_PAYLOAD_SIZE(0), _("Invalid encrypted payload")); + CHECK_PARAM(msg->has_public_key, _("No public key provided")); + CHECK_PARAM(msg->public_key.size == 32, _("Invalid public key")); + + char address[NEM_ADDRESS_SIZE + 1]; + nem_get_address(msg->public_key.bytes, msg->network, address); + + layoutNEMDialog(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + _("Decrypt message"), + _("Confirm address?"), + address); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + const uint8_t *salt = msg->payload.bytes; + uint8_t *iv = &msg->payload.bytes[NEM_SALT_SIZE]; + + const uint8_t *payload = &msg->payload.bytes[NEM_SALT_SIZE + AES_BLOCK_SIZE]; + size_t size = msg->payload.size - NEM_SALT_SIZE - AES_BLOCK_SIZE; + + // hdnode_nem_decrypt mutates the IV, so this will modify msg + bool ret = hdnode_nem_decrypt(node, + msg->public_key.bytes, + iv, + salt, + payload, + size, + resp->payload.bytes); + if (!ret) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to decrypt payload")); + layoutHome(); + return; + } + + resp->has_payload = true; + resp->payload.size = NEM_DECRYPTED_SIZE(resp->payload.bytes, size); + + layoutNEMTransferPayload(resp->payload.bytes, resp->payload.size, true); + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + msg_write(MessageType_MessageType_NEMDecryptedMessage, resp); + layoutHome(); +} + +void fsm_msgCosiCommit(CosiCommit *msg) +{ + RESP_INIT(CosiCommitment); + + CHECK_INITIALIZED + + CHECK_PARAM(msg->has_data, _("No data provided")); + + layoutCosiCommitSign(msg->address_n, msg->address_n_count, msg->data.bytes, msg->data.size, false); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(ED25519_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + uint8_t nonce[32]; + sha256_Raw(msg->data.bytes, msg->data.size, nonce); + rfc6979_state rng; + init_rfc6979(node->private_key, nonce, &rng); + generate_rfc6979(nonce, &rng); + + resp->has_commitment = true; + resp->has_pubkey = true; + resp->commitment.size = 32; + resp->pubkey.size = 32; + + ed25519_publickey(nonce, resp->commitment.bytes); + ed25519_publickey(node->private_key, resp->pubkey.bytes); + + msg_write(MessageType_MessageType_CosiCommitment, resp); + layoutHome(); +} + +void fsm_msgCosiSign(CosiSign *msg) +{ + RESP_INIT(CosiSignature); + + CHECK_INITIALIZED + + CHECK_PARAM(msg->has_data, _("No data provided")); + CHECK_PARAM(msg->has_global_commitment && msg->global_commitment.size == 32, _("Invalid global commitment")); + CHECK_PARAM(msg->has_global_pubkey && msg->global_pubkey.size == 32, _("Invalid global pubkey")); + + layoutCosiCommitSign(msg->address_n, msg->address_n_count, msg->data.bytes, msg->data.size, true); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + const HDNode *node = fsm_getDerivedNode(ED25519_NAME, msg->address_n, msg->address_n_count, NULL); + if (!node) return; + + uint8_t nonce[32]; + sha256_Raw(msg->data.bytes, msg->data.size, nonce); + rfc6979_state rng; + init_rfc6979(node->private_key, nonce, &rng); + generate_rfc6979(nonce, &rng); + + resp->has_signature = true; + resp->signature.size = 32; + + ed25519_cosi_sign(msg->data.bytes, msg->data.size, node->private_key, nonce, msg->global_commitment.bytes, msg->global_pubkey.bytes, resp->signature.bytes); + + msg_write(MessageType_MessageType_CosiSignature, resp); + layoutHome(); +} + +#if DEBUG_LINK + +void fsm_msgDebugLinkGetState(DebugLinkGetState *msg) +{ + (void)msg; + + // Do not use RESP_INIT because it clears msg_resp, but another message + // might be being handled + DebugLinkState resp; + memset(&resp, 0, sizeof(resp)); + + resp.has_layout = true; + resp.layout.size = OLED_BUFSIZE; + memcpy(resp.layout.bytes, oledGetBuffer(), OLED_BUFSIZE); + + if (storage_hasPin()) { + resp.has_pin = true; + strlcpy(resp.pin, storage_getPin(), sizeof(resp.pin)); + } + + resp.has_matrix = true; + strlcpy(resp.matrix, pinmatrix_get(), sizeof(resp.matrix)); + + resp.has_reset_entropy = true; + resp.reset_entropy.size = reset_get_int_entropy(resp.reset_entropy.bytes); + + resp.has_reset_word = true; + strlcpy(resp.reset_word, reset_get_word(), sizeof(resp.reset_word)); + + resp.has_recovery_fake_word = true; + strlcpy(resp.recovery_fake_word, recovery_get_fake_word(), sizeof(resp.recovery_fake_word)); + + resp.has_recovery_word_pos = true; + resp.recovery_word_pos = recovery_get_word_pos(); + + if (storage_hasMnemonic()) { + resp.has_mnemonic = true; + strlcpy(resp.mnemonic, storage_getMnemonic(), sizeof(resp.mnemonic)); + } + + if (storage_hasNode()) { + resp.has_node = true; + storage_dumpNode(&(resp.node)); + } + + resp.has_passphrase_protection = true; + resp.passphrase_protection = storage_hasPassphraseProtection(); + + msg_debug_write(MessageType_MessageType_DebugLinkState, &resp); +} + +void fsm_msgDebugLinkStop(DebugLinkStop *msg) +{ + (void)msg; +} + +void fsm_msgDebugLinkMemoryRead(DebugLinkMemoryRead *msg) +{ + RESP_INIT(DebugLinkMemory); + + uint32_t length = 1024; + if (msg->has_length && msg->length < length) + length = msg->length; + resp->has_memory = true; + memcpy(resp->memory.bytes, (void*) msg->address, length); + resp->memory.size = length; + msg_debug_write(MessageType_MessageType_DebugLinkMemory, resp); +} + +void fsm_msgDebugLinkMemoryWrite(DebugLinkMemoryWrite *msg) +{ + uint32_t length = msg->memory.size; + if (msg->flash) { + flash_clear_status_flags(); + flash_unlock(); + for (uint32_t i = 0; i < length; i += 4) { + uint32_t word; + memcpy(&word, msg->memory.bytes + i, 4); + flash_program_word(msg->address + i, word); + } + flash_lock(); + } else { + memcpy((void *) msg->address, msg->memory.bytes, length); + } +} + +void fsm_msgDebugLinkFlashErase(DebugLinkFlashErase *msg) +{ + flash_clear_status_flags(); + flash_unlock(); + flash_erase_sector(msg->sector, FLASH_CR_PROGRAM_X32); + flash_lock(); +} +#endif diff --git a/hardware-wallet/firmware/firmware/fsm.h b/hardware-wallet/firmware/firmware/fsm.h new file mode 100644 index 00000000..c7697bb1 --- /dev/null +++ b/hardware-wallet/firmware/firmware/fsm.h @@ -0,0 +1,96 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __FSM_H__ +#define __FSM_H__ + +#include "messages.pb.h" + +// message functions + +void fsm_sendSuccess(const char *text); + +#if DEBUG_LINK +void fsm_sendFailureDebug(FailureType code, const char *text, const char *source); + +#define fsm_sendFailure(code, text) fsm_sendFailureDebug((code), (text), __FILE__ ":" VERSTR(__LINE__) ":") +#else +void fsm_sendFailure(FailureType code, const char *text); +#endif + +void fsm_msgInitialize(Initialize *msg); +void fsm_msgGetFeatures(GetFeatures *msg); +void fsm_msgSkycoinCheckMessageSignature(SkycoinCheckMessageSignature* msg); +void fsm_msgSkycoinSignMessage(SkycoinSignMessage* msg); +void fsm_msgSkycoinAddress(SkycoinAddress* msg); +void fsm_msgPing(Ping *msg); +void fsm_msgChangePin(ChangePin *msg); +void fsm_msgWipeDevice(WipeDevice *msg); +void fsm_msgGetEntropy(GetEntropy *msg); +void fsm_msgGetPublicKey(GetPublicKey *msg); +void fsm_msgLoadDevice(LoadDevice *msg); +void fsm_msgResetDevice(ResetDevice *msg); +void fsm_msgBackupDevice(BackupDevice *msg); +void fsm_msgSignTx(SignTx *msg); +//void fsm_msgPinMatrixAck(PinMatrixAck *msg); +void fsm_msgCancel(Cancel *msg); +void fsm_msgTxAck(TxAck *msg); +void fsm_msgCipherKeyValue(CipherKeyValue *msg); +void fsm_msgClearSession(ClearSession *msg); +void fsm_msgApplySettings(ApplySettings *msg); +void fsm_msgApplyFlags(ApplyFlags *msg); +//void fsm_msgButtonAck(ButtonAck *msg); +void fsm_msgGetAddress(GetAddress *msg); +void fsm_msgEntropyAck(EntropyAck *msg); +void fsm_msgSignMessage(SignMessage *msg); +void fsm_msgVerifyMessage(VerifyMessage *msg); +void fsm_msgSignIdentity(SignIdentity *msg); +void fsm_msgGetECDHSessionKey(GetECDHSessionKey *msg); +/* ECIES disabled +void fsm_msgEncryptMessage(EncryptMessage *msg); +void fsm_msgDecryptMessage(DecryptMessage *msg); +*/ +//void fsm_msgPassphraseAck(PassphraseAck *msg); +void fsm_msgRecoveryDevice(RecoveryDevice *msg); +void fsm_msgWordAck(WordAck *msg); +void fsm_msgSetU2FCounter(SetU2FCounter *msg); +void fsm_msgEthereumGetAddress(EthereumGetAddress *msg); +void fsm_msgEthereumSignTx(EthereumSignTx *msg); +void fsm_msgEthereumTxAck(EthereumTxAck *msg); +void fsm_msgEthereumSignMessage(EthereumSignMessage *msg); +void fsm_msgEthereumVerifyMessage(EthereumVerifyMessage *msg); + +void fsm_msgNEMGetAddress(NEMGetAddress *msg); +void fsm_msgNEMSignTx(NEMSignTx *msg); +void fsm_msgNEMDecryptMessage(NEMDecryptMessage *msg); + +void fsm_msgCosiCommit(CosiCommit *msg); +void fsm_msgCosiSign(CosiSign *msg); + +// debug message functions +#if DEBUG_LINK +//void fsm_msgDebugLinkDecision(DebugLinkDecision *msg); +void fsm_msgDebugLinkGetState(DebugLinkGetState *msg); +void fsm_msgDebugLinkStop(DebugLinkStop *msg); +void fsm_msgDebugLinkMemoryWrite(DebugLinkMemoryWrite *msg); +void fsm_msgDebugLinkMemoryRead(DebugLinkMemoryRead *msg); +void fsm_msgDebugLinkFlashErase(DebugLinkFlashErase *msg); +#endif + +#endif diff --git a/hardware-wallet/firmware/firmware/gettext.h b/hardware-wallet/firmware/firmware/gettext.h new file mode 100644 index 00000000..bad59943 --- /dev/null +++ b/hardware-wallet/firmware/firmware/gettext.h @@ -0,0 +1,25 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __GETTEXT_H__ +#define __GETTEXT_H__ + +#define _(X) (X) + +#endif diff --git a/hardware-wallet/firmware/firmware/layout2.c b/hardware-wallet/firmware/firmware/layout2.c new file mode 100644 index 00000000..77a38a85 --- /dev/null +++ b/hardware-wallet/firmware/firmware/layout2.c @@ -0,0 +1,859 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +#include "layout2.h" +#include "storage.h" +#include "oled.h" +#include "bitmaps.h" +#include "string.h" +#include "util.h" +#include "qr_encode.h" +#include "timer.h" +#include "bignum.h" +#include "secp256k1.h" +#include "nem2.h" +#include "gettext.h" + +#define BITCOIN_DIVISIBILITY (8) + +static const char *slip44_extras(uint32_t coin_type) +{ + if ((coin_type & 0x80000000) == 0) { + return 0; + } + switch (coin_type & 0x7fffffff) { + case 40: return "EXP"; // Expanse + case 43: return "NEM"; // NEM + case 60: return "ETH"; // Ethereum Mainnet + case 61: return "ETC"; // Ethereum Classic Mainnet + case 108: return "UBQ"; // UBIQ + case 137: return "RSK"; // Rootstock Mainnet + case 37310: return "tRSK"; // Rootstock Testnet + } + return 0; +} + +#define BIP32_MAX_LAST_ELEMENT 1000000 + +static const char *address_n_str(const uint32_t *address_n, size_t address_n_count) +{ + if (address_n_count > 8) { + return _("Unknown long path"); + } + if (address_n_count == 0) { + return _("Path: m"); + } + + // known BIP44/49 path + static char path[100]; + if (address_n_count == 5 && + (address_n[0] == (0x80000000 + 44) || address_n[0] == (0x80000000 + 49) || address_n[0] == (0x80000000 + 84)) && + (address_n[1] & 0x80000000) && + (address_n[2] & 0x80000000) && + (address_n[3] <= 1) && + (address_n[4] <= BIP32_MAX_LAST_ELEMENT)) { + bool native_segwit = (address_n[0] == (0x80000000 + 84)); + bool p2sh_segwit = (address_n[0] == (0x80000000 + 49)); + bool legacy = false; + const CoinInfo *coin = coinByCoinType(address_n[1]); + const char *abbr = 0; + if (native_segwit) { + if (coin && coin->has_segwit && coin->bech32_prefix) { + abbr = coin->coin_shortcut + 1; + } + } else + if (p2sh_segwit) { + if (coin && coin->has_segwit && coin->has_address_type_p2sh) { + abbr = coin->coin_shortcut + 1; + } + } else { + if (coin) { + if (coin->has_segwit && coin->has_address_type_p2sh) { + legacy = true; + } + abbr = coin->coin_shortcut + 1; + } else { + abbr = slip44_extras(address_n[1]); + } + } + uint32_t accnum = (address_n[2] & 0x7fffffff) + 1; + if (abbr && accnum < 100) { + memset(path, 0, sizeof(path)); + strlcpy(path, abbr, sizeof(path)); + // TODO: how to name accounts? + // currently we have "legacy account", "account" and "segwit account" + // for BIP44/P2PKH, BIP49/P2SH-P2WPKH and BIP84/P2WPKH respectivelly + if (legacy) { + strlcat(path, " legacy", sizeof(path)); + } + if (native_segwit) { + strlcat(path, " segwit", sizeof(path)); + } + strlcat(path, " account #", sizeof(path)); + char acc[3]; + memset(acc, 0, sizeof(acc)); + if (accnum < 10) { + acc[0] = '0' + accnum; + } else { + acc[0] = '0' + (accnum / 10); + acc[1] = '0' + (accnum % 10); + } + strlcat(path, acc, sizeof(path)); + return path; + } + } + + // "Path: m" / i ' + static char address_str[7 + 8 * (1 + 9 + 1) + 1]; + char *c = address_str + sizeof(address_str) - 1; + + *c = 0; c--; + + for (int n = (int)address_n_count - 1; n >= 0; n--) { + uint32_t i = address_n[n]; + if (i & 0x80000000) { + *c = '\''; c--; + } + i = i & 0x7fffffff; + do { + *c = '0' + (i % 10); c--; + i /= 10; + } while (i > 0); + *c = '/'; c--; + } + *c = 'm'; c--; + *c = ' '; c--; + *c = ':'; c--; + *c = 'h'; c--; + *c = 't'; c--; + *c = 'a'; c--; + *c = 'P'; + + return c; +} + +// split longer string into 4 rows, rowlen chars each +static const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen) +{ + static char str[4][32 + 1]; + if (rowlen > 32) { + rowlen = 32; + } + memset(str, 0, sizeof(str)); + strlcpy(str[0], (char *)msg, rowlen + 1); + if (len > rowlen) { + strlcpy(str[1], (char *)msg + rowlen, rowlen + 1); + } + if (len > rowlen * 2) { + strlcpy(str[2], (char *)msg + rowlen * 2, rowlen + 1); + } + if (len > rowlen * 3) { + strlcpy(str[3], (char *)msg + rowlen * 3, rowlen + 1); + } + if (len > rowlen * 4) { + str[3][rowlen - 1] = '.'; + str[3][rowlen - 2] = '.'; + str[3][rowlen - 3] = '.'; + } + static const char *ret[4] = { str[0], str[1], str[2], str[3] }; + return ret; +} + +void *layoutLast = layoutHome; + +void layoutDialogSwipe(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6) +{ + layoutLast = layoutDialogSwipe; + layoutSwipe(); + layoutDialog(icon, btnNo, btnYes, desc, line1, line2, line3, line4, line5, line6); +} + +void layoutProgressSwipe(const char *desc, int permil) +{ + if (layoutLast == layoutProgressSwipe) { + oledClear(); + } else { + layoutLast = layoutProgressSwipe; + layoutSwipe(); + } + layoutProgress(desc, permil); +} + +void layoutScreensaver(void) +{ + layoutLast = layoutScreensaver; + oledClear(); + oledRefresh(); +} + +void layoutRawMessage(char* msg) +{ + oledClear(); + oledDrawStringCenter(OLED_HEIGHT/2, msg, FONT_STANDARD); + oledRefresh(); +} + +void layoutHome(void) +{ + if (layoutLast == layoutHome || layoutLast == layoutScreensaver) { + oledClear(); + } else { + layoutSwipe(); + } + layoutLast = layoutHome; + const char *label = storage_isInitialized() ? storage_getLabel() : _("Go to trezor.io/start"); + const uint8_t *homescreen = storage_getHomescreen(); + if (homescreen) { + BITMAP b; + b.width = 128; + b.height = 64; + b.data = homescreen; + oledDrawBitmap(0, 0, &b); + } else { + if (label && strlen(label) > 0) { + oledDrawBitmap(44, 4, &bmp_logo48); + oledDrawStringCenter(OLED_HEIGHT - 8, label, FONT_STANDARD); + } else { + oledDrawBitmap(40, 0, &bmp_logo64); + } + } + if (storage_needsBackup()) { + oledBox(0, 0, 127, 8, false); + oledDrawStringCenter(0, "NEEDS BACKUP!", FONT_STANDARD); + } + oledRefresh(); + + // Reset lock screen timeout + system_millis_lock_start = timer_ms(); +} + +void layoutConfirmOutput(const CoinInfo *coin, const TxOutputType *out) +{ + char str_out[32 + 3]; + bn_format_uint64(out->amount, NULL, coin->coin_shortcut, BITCOIN_DIVISIBILITY, 0, false, str_out, sizeof(str_out) - 3); + strlcat(str_out, " to", sizeof(str_out)); + const char *addr = out->address; + int addrlen = strlen(addr); + int numlines = addrlen <= 42 ? 2 : 3; + int linelen = (addrlen - 1) / numlines + 1; + if (linelen > 21) { + linelen = 21; + } + const char **str = split_message((const uint8_t *)addr, addrlen, linelen); + layoutLast = layoutDialogSwipe; + layoutSwipe(); + oledClear(); + oledDrawBitmap(0, 0, &bmp_icon_question); + oledDrawString(20, 0 * 9, _("Confirm sending"), FONT_STANDARD); + oledDrawString(20, 1 * 9, str_out, FONT_STANDARD); + int left = linelen > 18 ? 0 : 20; + oledDrawString(left, 2 * 9, str[0], FONT_FIXED); + oledDrawString(left, 3 * 9, str[1], FONT_FIXED); + oledDrawString(left, 4 * 9, str[2], FONT_FIXED); + oledDrawString(left, 5 * 9, str[3], FONT_FIXED); + if (!str[3][0]) { + if (out->address_n_count > 0) { + oledDrawString(0, 5*9, address_n_str(out->address_n, out->address_n_count), FONT_STANDARD); + } else { + oledHLine(OLED_HEIGHT - 13); + } + } + layoutButtonNo(_("Cancel")); + layoutButtonYes(_("Confirm")); + oledRefresh(); +} + +void layoutConfirmOpReturn(const uint8_t *data, uint32_t size) +{ + bool ascii_only = true; + for (uint32_t i = 0; i < size; i++) { + if (data[i] < ' ' || data[i] > '~') { + ascii_only = false; + break; + } + } + const char **str; + if (!ascii_only) { + char hex[65]; + memset(hex, 0, sizeof(hex)); + data2hex(data, (size > 32) ? 32 : size, hex); + str = split_message((const uint8_t *)hex, size * 2, 16); + } else { + str = split_message(data, size, 20); + } + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + NULL, + _("Confirm OP_RETURN:"), + str[0], + str[1], + str[2], + str[3], + NULL + ); +} + +void layoutConfirmTx(const CoinInfo *coin, uint64_t amount_out, uint64_t amount_fee) +{ + char str_out[32], str_fee[32]; + bn_format_uint64(amount_out, NULL, coin->coin_shortcut, BITCOIN_DIVISIBILITY, 0, false, str_out, sizeof(str_out)); + bn_format_uint64(amount_fee, NULL, coin->coin_shortcut, BITCOIN_DIVISIBILITY, 0, false, str_fee, sizeof(str_fee)); + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + NULL, + _("Really send"), + str_out, + _("from your wallet?"), + _("Fee included:"), + str_fee, + NULL + ); +} + +void layoutFeeOverThreshold(const CoinInfo *coin, uint64_t fee) +{ + char str_fee[32]; + bn_format_uint64(fee, NULL, coin->coin_shortcut, BITCOIN_DIVISIBILITY, 0, false, str_fee, sizeof(str_fee)); + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + NULL, + _("Fee"), + str_fee, + _("is unexpectedly high."), + NULL, + _("Send anyway?"), + NULL + ); +} + +void layoutSignMessage(const uint8_t *msg, uint32_t len) +{ + const char **str = split_message(msg, len, 16); + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), + _("Sign message?"), + str[0], str[1], str[2], str[3], NULL, NULL); +} + +void layoutVerifyAddress(const char *address) +{ + const char **str = split_message((const uint8_t *)address, strlen(address), 17); + layoutDialogSwipe(&bmp_icon_info, _("Cancel"), _("Confirm"), + _("Confirm address?"), + _("Message signed by:"), + str[0], str[1], str[2], NULL, NULL); +} + +void layoutVerifyMessage(const uint8_t *msg, uint32_t len) +{ + const char **str = split_message(msg, len, 16); + layoutDialogSwipe(&bmp_icon_info, _("Cancel"), _("Confirm"), + _("Verified message"), + str[0], str[1], str[2], str[3], NULL, NULL); +} + +void layoutCipherKeyValue(bool encrypt, const char *key) +{ + const char **str = split_message((const uint8_t *)key, strlen(key), 16); + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), + encrypt ? _("Encrypt value of this key?") : _("Decrypt value of this key?"), + str[0], str[1], str[2], str[3], NULL, NULL); +} + +void layoutEncryptMessage(const uint8_t *msg, uint32_t len, bool signing) +{ + const char **str = split_message(msg, len, 16); + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), + signing ? _("Encrypt+Sign message?") : _("Encrypt message?"), + str[0], str[1], str[2], str[3], NULL, NULL); +} + +void layoutDecryptMessage(const uint8_t *msg, uint32_t len, const char *address) +{ + const char **str = split_message(msg, len, 16); + layoutDialogSwipe(&bmp_icon_info, NULL, _("OK"), + address ? _("Decrypted signed message") : _("Decrypted message"), + str[0], str[1], str[2], str[3], NULL, NULL); +} + +void layoutResetWord(const char *word, int pass, int word_pos, bool last) +{ + layoutLast = layoutResetWord; + layoutSwipe(); + + const char *btnYes; + if (last) { + if (pass == 1) { + btnYes = _("Finish"); + } else { + btnYes = _("Again"); + } + } else { + btnYes = _("Next"); + } + + const char *action; + if (pass == 1) { + action = _("Please check the seed"); + } else { + action = _("Write down the seed"); + } + + char index_str[] = "##th word is:"; + if (word_pos < 10) { + index_str[0] = ' '; + } else { + index_str[0] = '0' + word_pos / 10; + } + index_str[1] = '0' + word_pos % 10; + if (word_pos == 1 || word_pos == 21) { + index_str[2] = 's'; index_str[3] = 't'; + } else + if (word_pos == 2 || word_pos == 22) { + index_str[2] = 'n'; index_str[3] = 'd'; + } else + if (word_pos == 3 || word_pos == 23) { + index_str[2] = 'r'; index_str[3] = 'd'; + } + + int left = 0; + oledClear(); + oledDrawBitmap(0, 0, &bmp_icon_info); + left = bmp_icon_info.width + 4; + + oledDrawString(left, 0 * 9, action, FONT_STANDARD); + oledDrawString(left, 2 * 9, word_pos < 10 ? index_str + 1 : index_str, FONT_STANDARD); + oledDrawString(left, 3 * 9, word, FONT_STANDARD | FONT_DOUBLE); + oledHLine(OLED_HEIGHT - 13); + layoutButtonYes(btnYes); + oledRefresh(); +} + +void layoutAddress(const char *address, const char *desc, bool qrcode, bool ignorecase, const uint32_t *address_n, size_t address_n_count) +{ + if (layoutLast != layoutAddress) { + layoutSwipe(); + } else { + oledClear(); + } + layoutLast = layoutAddress; + + uint32_t addrlen = strlen(address); + if (qrcode) { + static unsigned char bitdata[QR_MAX_BITDATA]; + char address_upcase[addrlen + 1]; + if (ignorecase) { + for (uint32_t i = 0; i < addrlen + 1; i++) { + address_upcase[i] = address[i] >= 'a' && address[i] <= 'z' ? + address[i] + 'A' - 'a' : address[i]; + } + } + int side = qr_encode(addrlen <= (ignorecase ? 60 : 40) ? QR_LEVEL_M : QR_LEVEL_L, 0, + ignorecase ? address_upcase : address, 0, bitdata); + + oledInvert(0, 0, 63, 63); + if (side > 0 && side <= 29) { + int offset = 32 - side; + for (int i = 0; i < side; i++) { + for (int j = 0; j< side; j++) { + int a = j * side + i; + if (bitdata[a / 8] & (1 << (7 - a % 8))) { + oledBox(offset + i * 2, offset + j * 2, + offset + 1 + i * 2, offset + 1 + j * 2, false); + } + } + } + } else if (side > 0 && side <= 60) { + int offset = 32 - (side / 2); + for (int i = 0; i < side; i++) { + for (int j = 0; j< side; j++) { + int a = j * side + i; + if (bitdata[a / 8] & (1 << (7 - a % 8))) { + oledClearPixel(offset + i, offset + j); + } + } + } + } + } else { + uint32_t rowlen = (addrlen - 1) / (addrlen <= 42 ? 2 : addrlen <= 63 ? 3 : 4) + 1; + const char **str = split_message((const uint8_t *)address, addrlen, rowlen); + if (desc) { + oledDrawString(0, 0 * 9, desc, FONT_STANDARD); + } + for (int i = 0; i < 4; i++) { + oledDrawString(0, (i + 1) * 9 + 4, str[i], FONT_FIXED); + } + oledDrawString(0, 42, address_n_str(address_n, address_n_count), FONT_STANDARD); + } + + if (!qrcode) { + layoutButtonNo(_("QR Code")); + } + + layoutButtonYes(_("Continue")); + oledRefresh(); +} + +void layoutPublicKey(const uint8_t *pubkey) +{ + char hex[32 * 2 + 1], desc[16]; + strlcpy(desc, "Public Key: 00", sizeof(desc)); + if (pubkey[0] == 1) { + /* ed25519 public key */ + // pass - leave 00 + } else { + data2hex(pubkey, 1, desc + 12); + } + data2hex(pubkey + 1, 32, hex); + const char **str = split_message((const uint8_t *)hex, 32 * 2, 16); + layoutDialogSwipe(&bmp_icon_question, NULL, _("Continue"), NULL, + desc, str[0], str[1], str[2], str[3], NULL); +} + +void layoutSignIdentity(const IdentityType *identity, const char *challenge) +{ + char row_proto[8 + 11 + 1]; + char row_hostport[64 + 6 + 1]; + char row_user[64 + 8 + 1]; + + bool is_gpg = (strcmp(identity->proto, "gpg") == 0); + + if (identity->has_proto && identity->proto[0]) { + if (strcmp(identity->proto, "https") == 0) { + strlcpy(row_proto, _("Web sign in to:"), sizeof(row_proto)); + } else if (is_gpg) { + strlcpy(row_proto, _("GPG sign for:"), sizeof(row_proto)); + } else { + strlcpy(row_proto, identity->proto, sizeof(row_proto)); + char *p = row_proto; + while (*p) { *p = toupper((int)*p); p++; } + strlcat(row_proto, _(" login to:"), sizeof(row_proto)); + } + } else { + strlcpy(row_proto, _("Login to:"), sizeof(row_proto)); + } + + if (identity->has_host && identity->host[0]) { + strlcpy(row_hostport, identity->host, sizeof(row_hostport)); + if (identity->has_port && identity->port[0]) { + strlcat(row_hostport, ":", sizeof(row_hostport)); + strlcat(row_hostport, identity->port, sizeof(row_hostport)); + } + } else { + row_hostport[0] = 0; + } + + if (identity->has_user && identity->user[0]) { + strlcpy(row_user, _("user: "), sizeof(row_user)); + strlcat(row_user, identity->user, sizeof(row_user)); + } else { + row_user[0] = 0; + } + + if (is_gpg) { + // Split "First Last " into 2 lines: + // "First Last" + // "first@last.com" + char *email_start = strchr(row_hostport, '<'); + if (email_start) { + strlcpy(row_user, email_start + 1, sizeof(row_user)); + *email_start = 0; + char *email_end = strchr(row_user, '>'); + if (email_end) { + *email_end = 0; + } + } + } + + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), + _("Do you want to sign in?"), + row_proto[0] ? row_proto : NULL, + row_hostport[0] ? row_hostport : NULL, + row_user[0] ? row_user : NULL, + challenge, + NULL, + NULL); +} + +void layoutDecryptIdentity(const IdentityType *identity) +{ + char row_proto[8 + 11 + 1]; + char row_hostport[64 + 6 + 1]; + char row_user[64 + 8 + 1]; + + if (identity->has_proto && identity->proto[0]) { + strlcpy(row_proto, identity->proto, sizeof(row_proto)); + char *p = row_proto; + while (*p) { *p = toupper((int)*p); p++; } + strlcat(row_proto, _(" decrypt for:"), sizeof(row_proto)); + } else { + strlcpy(row_proto, _("Decrypt for:"), sizeof(row_proto)); + } + + if (identity->has_host && identity->host[0]) { + strlcpy(row_hostport, identity->host, sizeof(row_hostport)); + if (identity->has_port && identity->port[0]) { + strlcat(row_hostport, ":", sizeof(row_hostport)); + strlcat(row_hostport, identity->port, sizeof(row_hostport)); + } + } else { + row_hostport[0] = 0; + } + + if (identity->has_user && identity->user[0]) { + strlcpy(row_user, _("user: "), sizeof(row_user)); + strlcat(row_user, identity->user, sizeof(row_user)); + } else { + row_user[0] = 0; + } + + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), + _("Do you want to decrypt?"), + row_proto[0] ? row_proto : NULL, + row_hostport[0] ? row_hostport : NULL, + row_user[0] ? row_user : NULL, + NULL, + NULL, + NULL); +} + +void layoutU2FDialog(const char *verb, const char *appname, const BITMAP *appicon) { + if (!appicon) { + appicon = &bmp_icon_question; + } + layoutDialog(appicon, NULL, verb, NULL, verb, _("U2F security key?"), NULL, appname, NULL, NULL); +} + +void layoutNEMDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *address) { + static char first_third[NEM_ADDRESS_SIZE / 3 + 1]; + strlcpy(first_third, address, sizeof(first_third)); + + static char second_third[NEM_ADDRESS_SIZE / 3 + 1]; + strlcpy(second_third, &address[NEM_ADDRESS_SIZE / 3], sizeof(second_third)); + + const char *third_third = &address[NEM_ADDRESS_SIZE * 2 / 3]; + + layoutDialogSwipe(icon, + btnNo, + btnYes, + desc, + line1, + first_third, + second_third, + third_third, + NULL, + NULL); +} + +void layoutNEMTransferXEM(const char *desc, uint64_t quantity, const bignum256 *multiplier, uint64_t fee) { + char str_out[32], str_fee[32]; + + nem_mosaicFormatAmount(NEM_MOSAIC_DEFINITION_XEM, quantity, multiplier, str_out, sizeof(str_out)); + nem_mosaicFormatAmount(NEM_MOSAIC_DEFINITION_XEM, fee, NULL, str_fee, sizeof(str_fee)); + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + _("Confirm transfer of"), + str_out, + _("and network fee of"), + str_fee, + NULL, + NULL); +} + +void layoutNEMNetworkFee(const char *desc, bool confirm, const char *fee1_desc, uint64_t fee1, const char *fee2_desc, uint64_t fee2) { + char str_fee1[32], str_fee2[32]; + + nem_mosaicFormatAmount(NEM_MOSAIC_DEFINITION_XEM, fee1, NULL, str_fee1, sizeof(str_fee1)); + + if (fee2_desc) { + nem_mosaicFormatAmount(NEM_MOSAIC_DEFINITION_XEM, fee2, NULL, str_fee2, sizeof(str_fee2)); + } + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + confirm ? _("Confirm") : _("Next"), + desc, + fee1_desc, + str_fee1, + fee2_desc, + fee2_desc ? str_fee2 : NULL, + NULL, + NULL); +} + +void layoutNEMTransferMosaic(const NEMMosaicDefinition *definition, uint64_t quantity, const bignum256 *multiplier, uint8_t network) { + char str_out[32], str_levy[32]; + + nem_mosaicFormatAmount(definition, quantity, multiplier, str_out, sizeof(str_out)); + + if (definition->has_levy) { + nem_mosaicFormatLevy(definition, quantity, multiplier, network, str_levy, sizeof(str_levy)); + } + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + definition->has_name ? definition->name : _("Mosaic"), + _("Confirm transfer of"), + str_out, + definition->has_levy ? _("and levy of") : NULL, + definition->has_levy ? str_levy : NULL, + NULL, + NULL); +} + +void layoutNEMTransferUnknownMosaic(const char *namespace, const char *mosaic, uint64_t quantity, const bignum256 *multiplier) { + char mosaic_name[32]; + nem_mosaicFormatName(namespace, mosaic, mosaic_name, sizeof(mosaic_name)); + + char str_out[32]; + nem_mosaicFormatAmount(NULL, quantity, multiplier, str_out, sizeof(str_out)); + + char *decimal = strchr(str_out, '.'); + if (decimal != NULL) { + *decimal = '\0'; + } + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("I take the risk"), + _("Unknown Mosaic"), + _("Confirm transfer of"), + str_out, + _("raw units of"), + mosaic_name, + NULL, + NULL); +} + +void layoutNEMTransferPayload(const uint8_t *payload, size_t length, bool encrypted) { + if (payload[0] == 0xFE) { + char encoded[(length - 1) * 2 + 1]; + data2hex(&payload[1], length - 1, encoded); + + const char **str = split_message((uint8_t *) encoded, sizeof(encoded) - 1, 16); + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Next"), + encrypted ? _("Encrypted hex data") : _("Unencrypted hex data"), + str[0], str[1], str[2], str[3], NULL, NULL); + } else { + const char **str = split_message(payload, length, 16); + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Next"), + encrypted ? _("Encrypted message") : _("Unencrypted message"), + str[0], str[1], str[2], str[3], NULL, NULL); + } +} + +void layoutNEMMosaicDescription(const char *description) { + const char **str = split_message((uint8_t *) description, strlen(description), 16); + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Next"), + _("Mosaic Description"), + str[0], str[1], str[2], str[3], NULL, NULL); +} + +void layoutNEMLevy(const NEMMosaicDefinition *definition, uint8_t network) { + const NEMMosaicDefinition *mosaic; + if (nem_mosaicMatches(definition, definition->levy_namespace, definition->levy_mosaic, network)) { + mosaic = definition; + } else { + mosaic = nem_mosaicByName(definition->levy_namespace, definition->levy_mosaic, network); + } + + char mosaic_name[32]; + if (mosaic == NULL) { + nem_mosaicFormatName(definition->levy_namespace, definition->levy_mosaic, mosaic_name, sizeof(mosaic_name)); + } + + char str_out[32]; + + switch (definition->levy) { + case NEMMosaicLevy_MosaicLevy_Percentile: + bn_format_uint64(definition->fee, NULL, NULL, 0, 0, false, str_out, sizeof(str_out)); + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + _("Percentile Levy"), + _("Raw levy value is"), + str_out, + _("in"), + mosaic ? (mosaic == definition ? _("the same mosaic") : mosaic->name) : mosaic_name, + NULL, + NULL); + break; + + case NEMMosaicLevy_MosaicLevy_Absolute: + default: + nem_mosaicFormatAmount(mosaic, definition->fee, NULL, str_out, sizeof(str_out)); + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + _("Absolute Levy"), + _("Levy is"), + str_out, + mosaic ? (mosaic == definition ? _("in the same mosaic") : NULL) : _("in raw units of"), + mosaic ? NULL : mosaic_name, + NULL, + NULL); + break; + } +} + +static inline bool is_slip18(const uint32_t *address_n, size_t address_n_count) +{ + return address_n_count == 2 && address_n[0] == (0x80000000 + 10018) && (address_n[1] & 0x80000000) && (address_n[1] & 0x7FFFFFFF) <= 9; +} + +void layoutCosiCommitSign(const uint32_t *address_n, size_t address_n_count, const uint8_t *data, uint32_t len, bool final_sign) +{ + char *desc = final_sign ? _("CoSi sign message?") : _("CoSi commit message?"); + char desc_buf[32]; + if (is_slip18(address_n, address_n_count)) { + if (final_sign) { + strlcpy(desc_buf, _("CoSi sign index #?"), sizeof(desc_buf)); + desc_buf[16] = '0' + (address_n[1] & 0x7FFFFFFF); + } else { + strlcpy(desc_buf, _("CoSi commit index #?"), sizeof(desc_buf)); + desc_buf[18] = '0' + (address_n[1] & 0x7FFFFFFF); + } + desc = desc_buf; + } + char str[4][17]; + if (len == 32) { + data2hex(data , 8, str[0]); + data2hex(data + 8, 8, str[1]); + data2hex(data + 16, 8, str[2]); + data2hex(data + 24, 8, str[3]); + } else { + strlcpy(str[0], "Data", sizeof(str[0])); + strlcpy(str[1], "of", sizeof(str[1])); + strlcpy(str[2], "unsupported", sizeof(str[2])); + strlcpy(str[3], "length", sizeof(str[3])); + } + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), desc, + str[0], str[1], str[2], str[3], NULL, NULL); +} diff --git a/hardware-wallet/firmware/firmware/layout2.h b/hardware-wallet/firmware/firmware/layout2.h new file mode 100644 index 00000000..048b96f5 --- /dev/null +++ b/hardware-wallet/firmware/firmware/layout2.h @@ -0,0 +1,72 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __LAYOUT2_H__ +#define __LAYOUT2_H__ + +#include "layout.h" +#include "types.pb.h" +#include "coins.h" +#include "bitmaps.h" +#include "bignum.h" +#include "trezor.h" + +extern void *layoutLast; + +#if DEBUG_LINK +#define layoutSwipe oledClear +#else +#define layoutSwipe oledSwipeLeft +#endif + +void layoutDialogSwipe(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6); +void layoutProgressSwipe(const char *desc, int permil); + +void layoutRawMessage(char* msg); +void layoutScreensaver(void); +void layoutHome(void); +void layoutConfirmOutput(const CoinInfo *coin, const TxOutputType *out); +void layoutConfirmOpReturn(const uint8_t *data, uint32_t size); +void layoutConfirmTx(const CoinInfo *coin, uint64_t amount_out, uint64_t amount_fee); +void layoutFeeOverThreshold(const CoinInfo *coin, uint64_t fee); +void layoutSignMessage(const uint8_t *msg, uint32_t len); +void layoutVerifyAddress(const char *address); +void layoutVerifyMessage(const uint8_t *msg, uint32_t len); +void layoutCipherKeyValue(bool encrypt, const char *key); +void layoutEncryptMessage(const uint8_t *msg, uint32_t len, bool signing); +void layoutDecryptMessage(const uint8_t *msg, uint32_t len, const char *address); +void layoutResetWord(const char *word, int pass, int word_pos, bool last); +void layoutAddress(const char *address, const char *desc, bool qrcode, bool ignorecase, const uint32_t *address_n, size_t address_n_count); +void layoutPublicKey(const uint8_t *pubkey); +void layoutSignIdentity(const IdentityType *identity, const char *challenge); +void layoutDecryptIdentity(const IdentityType *identity); +void layoutU2FDialog(const char *verb, const char *appname, const BITMAP *appicon); + +void layoutNEMDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *address); +void layoutNEMTransferXEM(const char *desc, uint64_t quantity, const bignum256 *multiplier, uint64_t fee); +void layoutNEMNetworkFee(const char *desc, bool confirm, const char *fee1_desc, uint64_t fee1, const char *fee2_desc, uint64_t fee2); +void layoutNEMTransferMosaic(const NEMMosaicDefinition *definition, uint64_t quantity, const bignum256 *multiplier, uint8_t network); +void layoutNEMTransferUnknownMosaic(const char *namespace, const char *mosaic, uint64_t quantity, const bignum256 *multiplier); +void layoutNEMTransferPayload(const uint8_t *payload, size_t length, bool encrypted); +void layoutNEMMosaicDescription(const char *description); +void layoutNEMLevy(const NEMMosaicDefinition *definition, uint8_t network); + +void layoutCosiCommitSign(const uint32_t *address_n, size_t address_n_count, const uint8_t *data, uint32_t len, bool final_sign); + +#endif diff --git a/hardware-wallet/firmware/firmware/messages.c b/hardware-wallet/firmware/firmware/messages.c new file mode 100644 index 00000000..65010d66 --- /dev/null +++ b/hardware-wallet/firmware/firmware/messages.c @@ -0,0 +1,373 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include "trezor.h" +#include "messages.h" +#include "debug.h" +#include "fsm.h" +#include "util.h" +#include "gettext.h" + +#include "pb_decode.h" +#include "pb_encode.h" +#include "messages.pb.h" + +struct MessagesMap_t { + char type; // n = normal, d = debug + char dir; // i = in, o = out + uint16_t msg_id; + const pb_field_t *fields; + void (*process_func)(void *ptr); +}; + +static const struct MessagesMap_t MessagesMap[] = { +#include "messages_map.h" + // end + {0, 0, 0, 0, 0} +}; + +const pb_field_t *MessageFields(char type, char dir, uint16_t msg_id) +{ + const struct MessagesMap_t *m = MessagesMap; + while (m->type) { +#if EMULATOR + (void) type; + if (dir == m->dir && msg_id == m->msg_id) { +#else + if (type == m->type && dir == m->dir && msg_id == m->msg_id) { +#endif + return m->fields; + } + m++; + } + return 0; +} + +void MessageProcessFunc(char type, char dir, uint16_t msg_id, void *ptr) +{ + const struct MessagesMap_t *m = MessagesMap; + while (m->type) { +#if EMULATOR + (void) type; + if (dir == m->dir && msg_id == m->msg_id) { +#else + if (type == m->type && dir == m->dir && msg_id == m->msg_id) { +#endif + m->process_func(ptr); + return; + } + m++; + } +} + +static uint32_t msg_out_start = 0; +static uint32_t msg_out_end = 0; +static uint32_t msg_out_cur = 0; +static uint8_t msg_out[MSG_OUT_SIZE]; + +#if DEBUG_LINK + +static uint32_t msg_debug_out_start = 0; +static uint32_t msg_debug_out_end = 0; +static uint32_t msg_debug_out_cur = 0; +static uint8_t msg_debug_out[MSG_DEBUG_OUT_SIZE]; + +#endif + +static inline void msg_out_append(uint8_t c) +{ + if (msg_out_cur == 0) { + msg_out[msg_out_end * 64] = '?'; + msg_out_cur = 1; + } + msg_out[msg_out_end * 64 + msg_out_cur] = c; + msg_out_cur++; + if (msg_out_cur == 64) { + msg_out_cur = 0; + msg_out_end = (msg_out_end + 1) % (MSG_OUT_SIZE / 64); + } +} + +#if DEBUG_LINK + +static inline void msg_debug_out_append(uint8_t c) +{ + if (msg_debug_out_cur == 0) { + msg_debug_out[msg_debug_out_end * 64] = '?'; + msg_debug_out_cur = 1; + } + msg_debug_out[msg_debug_out_end * 64 + msg_debug_out_cur] = c; + msg_debug_out_cur++; + if (msg_debug_out_cur == 64) { + msg_debug_out_cur = 0; + msg_debug_out_end = (msg_debug_out_end + 1) % (MSG_DEBUG_OUT_SIZE / 64); + } +} + +#endif + +static inline void msg_out_pad(void) +{ + if (msg_out_cur == 0) return; + while (msg_out_cur < 64) { + msg_out[msg_out_end * 64 + msg_out_cur] = 0; + msg_out_cur++; + } + msg_out_cur = 0; + msg_out_end = (msg_out_end + 1) % (MSG_OUT_SIZE / 64); +} + +#if DEBUG_LINK + +static inline void msg_debug_out_pad(void) +{ + if (msg_debug_out_cur == 0) return; + while (msg_debug_out_cur < 64) { + msg_debug_out[msg_debug_out_end * 64 + msg_debug_out_cur] = 0; + msg_debug_out_cur++; + } + msg_debug_out_cur = 0; + msg_debug_out_end = (msg_debug_out_end + 1) % (MSG_DEBUG_OUT_SIZE / 64); +} + +#endif + +static bool pb_callback_out(pb_ostream_t *stream, const uint8_t *buf, size_t count) +{ + (void)stream; + for (size_t i = 0; i < count; i++) { + msg_out_append(buf[i]); + } + return true; +} + +#if DEBUG_LINK + +static bool pb_debug_callback_out(pb_ostream_t *stream, const uint8_t *buf, size_t count) +{ + (void)stream; + for (size_t i = 0; i < count; i++) { + msg_debug_out_append(buf[i]); + } + return true; +} + +#endif + +bool msg_write_common(char type, uint16_t msg_id, const void *msg_ptr) +{ + const pb_field_t *fields = MessageFields(type, 'o', msg_id); + if (!fields) { // unknown message + return false; + } + + pb_ostream_t sizestream = {0, 0, SIZE_MAX, 0, 0}; + bool status = pb_encode(&sizestream, fields, msg_ptr); + + if (!status) { + return false; + } + + void (*append)(uint8_t); + bool (*pb_callback)(pb_ostream_t *, const uint8_t *, size_t); + + if (type == 'n') { + append = msg_out_append; + pb_callback = pb_callback_out; + } else +#if DEBUG_LINK + if (type == 'd') { + append = msg_debug_out_append; + pb_callback = pb_debug_callback_out; + } else +#endif + { + return false; + } + + uint32_t len = sizestream.bytes_written; + append('#'); + append('#'); + append((msg_id >> 8) & 0xFF); + append(msg_id & 0xFF); + append((len >> 24) & 0xFF); + append((len >> 16) & 0xFF); + append((len >> 8) & 0xFF); + append(len & 0xFF); + pb_ostream_t stream = {pb_callback, 0, SIZE_MAX, 0, 0}; + status = pb_encode(&stream, fields, msg_ptr); + if (type == 'n') { + msg_out_pad(); + } +#if DEBUG_LINK + else if (type == 'd') { + msg_debug_out_pad(); + } +#endif + return status; +} + +enum { + READSTATE_IDLE, + READSTATE_READING, +}; + +void msg_process(char type, uint16_t msg_id, const pb_field_t *fields, uint8_t *msg_raw, uint32_t msg_size) +{ + static CONFIDENTIAL uint8_t msg_data[MSG_IN_SIZE]; + memset(msg_data, 0, sizeof(msg_data)); + pb_istream_t stream = pb_istream_from_buffer(msg_raw, msg_size); + bool status = pb_decode(&stream, fields, msg_data); + if (status) { + MessageProcessFunc(type, 'i', msg_id, msg_data); + } else { + fsm_sendFailure(FailureType_Failure_DataError, stream.errmsg); + } +} + +void msg_read_common(char type, const uint8_t *buf, int len) +{ + static char read_state = READSTATE_IDLE; + static CONFIDENTIAL uint8_t msg_in[MSG_IN_SIZE]; + static uint16_t msg_id = 0xFFFF; + static uint32_t msg_size = 0; + static uint32_t msg_pos = 0; + static const pb_field_t *fields = 0; + + if (len != 64) return; + + if (read_state == READSTATE_IDLE) { + if (buf[0] != '?' || buf[1] != '#' || buf[2] != '#') { // invalid start - discard + return; + } + msg_id = (buf[3] << 8) + buf[4]; + msg_size = (buf[5] << 24)+ (buf[6] << 16) + (buf[7] << 8) + buf[8]; + + fields = MessageFields(type, 'i', msg_id); + if (!fields) { // unknown message + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Unknown message read_common")); + return; + } + if (msg_size > MSG_IN_SIZE) { // message is too big :( + fsm_sendFailure(FailureType_Failure_DataError, _("Message too big")); + return; + } + + read_state = READSTATE_READING; + + memcpy(msg_in, buf + 9, len - 9); + msg_pos = len - 9; + } else + if (read_state == READSTATE_READING) { + if (buf[0] != '?') { // invalid contents + read_state = READSTATE_IDLE; + return; + } + memcpy(msg_in + msg_pos, buf + 1, len - 1); + msg_pos += len - 1; + } + + if (msg_pos >= msg_size) { + msg_process(type, msg_id, fields, msg_in, msg_size); + msg_pos = 0; + read_state = READSTATE_IDLE; + } +} + +const uint8_t *msg_out_data(void) +{ + if (msg_out_start == msg_out_end) return 0; + uint8_t *data = msg_out + (msg_out_start * 64); + msg_out_start = (msg_out_start + 1) % (MSG_OUT_SIZE / 64); + debugLog(0, "", "msg_out_data"); + return data; +} + +#if DEBUG_LINK + +const uint8_t *msg_debug_out_data(void) +{ + if (msg_debug_out_start == msg_debug_out_end) return 0; + uint8_t *data = msg_debug_out + (msg_debug_out_start * 64); + msg_debug_out_start = (msg_debug_out_start + 1) % (MSG_DEBUG_OUT_SIZE / 64); + debugLog(0, "", "msg_debug_out_data"); + return data; +} + +#endif + +CONFIDENTIAL uint8_t msg_tiny[64]; +uint16_t msg_tiny_id = 0xFFFF; + +void msg_read_tiny(const uint8_t *buf, int len) +{ + if (len != 64) return; + if (buf[0] != '?' || buf[1] != '#' || buf[2] != '#') { + return; + } + uint16_t msg_id = (buf[3] << 8) + buf[4]; + uint32_t msg_size = (buf[5] << 24) + (buf[6] << 16) + (buf[7] << 8) + buf[8]; + if (msg_size > 64 || len - msg_size < 9) { + return; + } + + const pb_field_t *fields = 0; + // upstream nanopb is missing const qualifier, so we have to cast :-/ + pb_istream_t stream = pb_istream_from_buffer((uint8_t *)buf + 9, msg_size); + + switch (msg_id) { + case MessageType_MessageType_PinMatrixAck: + fields = PinMatrixAck_fields; + break; + case MessageType_MessageType_ButtonAck: + fields = ButtonAck_fields; + break; + case MessageType_MessageType_PassphraseAck: + fields = PassphraseAck_fields; + break; + case MessageType_MessageType_Cancel: + fields = Cancel_fields; + break; + case MessageType_MessageType_Initialize: + fields = Initialize_fields; + break; +#if DEBUG_LINK + case MessageType_MessageType_DebugLinkDecision: + fields = DebugLinkDecision_fields; + break; + case MessageType_MessageType_DebugLinkGetState: + fields = DebugLinkGetState_fields; + break; +#endif + } + if (fields) { + bool status = pb_decode(&stream, fields, msg_tiny); + if (status) { + msg_tiny_id = msg_id; + } else { + fsm_sendFailure(FailureType_Failure_DataError, stream.errmsg); + msg_tiny_id = 0xFFFF; + } + } else { + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Unknown message read_tiny")); + msg_tiny_id = 0xFFFF; + } +} diff --git a/hardware-wallet/firmware/firmware/messages.h b/hardware-wallet/firmware/firmware/messages.h new file mode 100644 index 00000000..e0a5c8b6 --- /dev/null +++ b/hardware-wallet/firmware/firmware/messages.h @@ -0,0 +1,53 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __MESSAGES_H__ +#define __MESSAGES_H__ + +#include +#include +#include "trezor.h" + +#define MSG_IN_SIZE (12*1024) + +#define MSG_OUT_SIZE (12*1024) + +#define msg_read(buf, len) msg_read_common('n', (buf), (len)) +#define msg_write(id, ptr) msg_write_common('n', (id), (ptr)) +const uint8_t *msg_out_data(void); + +#if DEBUG_LINK + +#define MSG_DEBUG_OUT_SIZE (4*1024) + +#define msg_debug_read(buf, len) msg_read_common('d', (buf), (len)) +#define msg_debug_write(id, ptr) msg_write_common('d', (id), (ptr)) +const uint8_t *msg_debug_out_data(void); + +#endif + +void msg_read_common(char type, const uint8_t *buf, int len); +bool msg_write_common(char type, uint16_t msg_id, const void *msg_ptr); + +void msg_read_tiny(const uint8_t *buf, int len); +void msg_debug_read_tiny(const uint8_t *buf, int len); +extern uint8_t msg_tiny[64]; +extern uint16_t msg_tiny_id; + +#endif diff --git a/hardware-wallet/firmware/firmware/nem2.c b/hardware-wallet/firmware/firmware/nem2.c new file mode 100644 index 00000000..ebe90731 --- /dev/null +++ b/hardware-wallet/firmware/firmware/nem2.c @@ -0,0 +1,812 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "nem2.h" + +#include "aes/aes.h" +#include "fsm.h" +#include "gettext.h" +#include "layout2.h" +#include "protect.h" +#include "rng.h" +#include "secp256k1.h" + +const char *nem_validate_common(NEMTransactionCommon *common, bool inner) { + if (!common->has_network) { + common->has_network = true; + common->network = NEM_NETWORK_MAINNET; + } + + if (nem_network_name(common->network) == NULL) { + return inner ? _("Invalid NEM network in inner transaction") : _("Invalid NEM network"); + } + + if (!common->has_timestamp) { + return inner ? _("No timestamp provided in inner transaction") : _("No timestamp provided"); + } + + if (!common->has_fee) { + return inner ? _("No fee provided in inner transaction") : _("No fee provided"); + } + + if (!common->has_deadline) { + return inner ? _("No deadline provided in inner transaction") : _("No deadline provided"); + } + + if (inner != common->has_signer) { + return inner ? _("No signer provided in inner transaction") : _("Signer not allowed in outer transaction"); + } + + if (common->has_signer && common->signer.size != sizeof(ed25519_public_key)) { + return _("Invalid signer public key in inner transaction"); + } + + return NULL; +} + +const char *nem_validate_transfer(const NEMTransfer *transfer, uint8_t network) { + if (!transfer->has_recipient) return _("No recipient provided"); + if (!transfer->has_amount) return _("No amount provided"); + + if (transfer->has_public_key && transfer->public_key.size != sizeof(ed25519_public_key)) { + return _("Invalid recipient public key"); + } + + if (!nem_validate_address(transfer->recipient, network)) return _("Invalid recipient address"); + + for (size_t i = 0; i < transfer->mosaics_count; i++) { + const NEMMosaic *mosaic = &transfer->mosaics[i]; + + if (!mosaic->has_namespace) return _("No mosaic namespace provided"); + if (!mosaic->has_mosaic) return _("No mosaic name provided"); + if (!mosaic->has_quantity) return _("No mosaic quantity provided"); + } + + return NULL; +} + +const char *nem_validate_provision_namespace(const NEMProvisionNamespace *provision_namespace, uint8_t network) { + if (!provision_namespace->has_namespace) return _("No namespace provided"); + if (!provision_namespace->has_sink) return _("No rental sink provided"); + if (!provision_namespace->has_fee) return _("No rental sink fee provided"); + + if (!nem_validate_address(provision_namespace->sink, network)) return _("Invalid rental sink address"); + + return NULL; +} + +const char *nem_validate_mosaic_creation(const NEMMosaicCreation *mosaic_creation, uint8_t network) { + if (!mosaic_creation->has_definition) return _("No mosaic definition provided"); + if (!mosaic_creation->has_sink) return _("No creation sink provided"); + if (!mosaic_creation->has_fee) return _("No creation sink fee provided"); + + if (!nem_validate_address(mosaic_creation->sink, network)) return _("Invalid creation sink address"); + + if (mosaic_creation->definition.has_name) return _("Name not allowed in mosaic creation transactions"); + if (mosaic_creation->definition.has_ticker) return _("Ticker not allowed in mosaic creation transactions"); + if (mosaic_creation->definition.networks_count) return _("Networks not allowed in mosaic creation transactions"); + + if (!mosaic_creation->definition.has_namespace) return _("No mosaic namespace provided"); + if (!mosaic_creation->definition.has_mosaic) return _("No mosaic name provided"); + + if (mosaic_creation->definition.has_levy) { + if (!mosaic_creation->definition.has_fee) return _("No levy address provided"); + if (!mosaic_creation->definition.has_levy_address) return _("No levy address provided"); + if (!mosaic_creation->definition.has_levy_namespace) return _("No levy namespace provided"); + if (!mosaic_creation->definition.has_levy_mosaic) return _("No levy mosaic name provided"); + + if (!mosaic_creation->definition.has_divisibility) return _("No divisibility provided"); + if (!mosaic_creation->definition.has_supply) return _("No supply provided"); + if (!mosaic_creation->definition.has_mutable_supply) return _("No supply mutability provided"); + if (!mosaic_creation->definition.has_transferable) return _("No mosaic transferability provided"); + if (!mosaic_creation->definition.has_description) return _("No description provided"); + + if (mosaic_creation->definition.divisibility > NEM_MAX_DIVISIBILITY) return _("Invalid divisibility provided"); + if (mosaic_creation->definition.supply > NEM_MAX_SUPPLY) return _("Invalid supply provided"); + + if (!nem_validate_address(mosaic_creation->definition.levy_address, network)) return _("Invalid levy address"); + } + + return NULL; +} + +const char *nem_validate_supply_change(const NEMMosaicSupplyChange *supply_change) { + if (!supply_change->has_namespace) return _("No namespace provided"); + if (!supply_change->has_mosaic) return _("No mosaic provided"); + if (!supply_change->has_type) return _("No type provided"); + if (!supply_change->has_delta) return _("No delta provided"); + + return NULL; +} + +const char *nem_validate_aggregate_modification(const NEMAggregateModification *aggregate_modification, bool creation) { + if (creation && aggregate_modification->modifications_count == 0) { + return _("No modifications provided"); + } + + for (size_t i = 0; i < aggregate_modification->modifications_count; i++) { + const NEMCosignatoryModification *modification = &aggregate_modification->modifications[i]; + + if (!modification->has_type) return _("No modification type provided"); + if (!modification->has_public_key) return _("No cosignatory public key provided"); + if (modification->public_key.size != 32) return _("Invalid cosignatory public key provided"); + + if (creation && modification->type == NEMModificationType_CosignatoryModification_Delete) { + return _("Cannot remove cosignatory when converting account"); + } + } + + return NULL; +} + +const char *nem_validate_importance_transfer(const NEMImportanceTransfer *importance_transfer) { + if (!importance_transfer->has_mode) return _("No mode provided"); + if (!importance_transfer->has_public_key) return _("No remote account provided"); + if (importance_transfer->public_key.size != 32) return _("Invalid remote account provided"); + + return NULL; +} + +bool nem_askTransfer(const NEMTransactionCommon *common, const NEMTransfer *transfer, const char *desc) { + if (transfer->mosaics_count) { + const NEMMosaic *xem = NULL; + bool unknownMosaic = false; + + const NEMMosaicDefinition *definitions[transfer->mosaics_count]; + + for (size_t i = 0; i < transfer->mosaics_count; i++) { + const NEMMosaic *mosaic = &transfer->mosaics[i]; + + definitions[i] = nem_mosaicByName(mosaic->namespace, mosaic->mosaic, common->network); + + if (definitions[i] == NEM_MOSAIC_DEFINITION_XEM) { + xem = mosaic; + } else if (definitions[i] == NULL) { + unknownMosaic = true; + } + } + + bignum256 multiplier; + bn_read_uint64(transfer->amount, &multiplier); + + if (unknownMosaic) { + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("I take the risk"), + _("Unknown Mosaics"), + _("Divisibility and levy"), + _("cannot be shown for"), + _("unknown mosaics!"), + NULL, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + + layoutNEMTransferXEM(desc, xem ? xem->quantity : 0, &multiplier, common->fee); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + for (size_t i = 0; i < transfer->mosaics_count; i++) { + const NEMMosaic *mosaic = &transfer->mosaics[i]; + + if (mosaic == xem) { + continue; + } + + if (definitions[i]) { + layoutNEMTransferMosaic(definitions[i], mosaic->quantity, &multiplier, common->network); + } else { + layoutNEMTransferUnknownMosaic(mosaic->namespace, mosaic->mosaic, mosaic->quantity, &multiplier); + } + + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + } else { + layoutNEMTransferXEM(desc, transfer->amount, NULL, common->fee); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + + if (transfer->has_payload) { + layoutNEMTransferPayload(transfer->payload.bytes, transfer->payload.size, transfer->has_public_key); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + + layoutNEMDialog(&bmp_icon_question, + _("Cancel"), + _("Confirm"), + desc, + _("Confirm transfer to"), + transfer->recipient); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + return false; + } + + return true; +} + +bool nem_fsmTransfer(nem_transaction_ctx *context, const HDNode *node, const NEMTransactionCommon *common, const NEMTransfer *transfer) { + static uint8_t encrypted[NEM_ENCRYPTED_PAYLOAD_SIZE(sizeof(transfer->payload.bytes))]; + + const uint8_t *payload = transfer->payload.bytes; + size_t size = transfer->payload.size; + + if (transfer->has_public_key) { + if (node == NULL) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Private key unavailable for encrypted message")); + return false; + } + + random_buffer(encrypted, NEM_SALT_SIZE + AES_BLOCK_SIZE); + + // hdnode_nem_encrypt mutates the IV + uint8_t iv[AES_BLOCK_SIZE]; + memcpy(iv, &encrypted[NEM_SALT_SIZE], AES_BLOCK_SIZE); + + const uint8_t *salt = encrypted; + uint8_t *buffer = &encrypted[NEM_SALT_SIZE + AES_BLOCK_SIZE]; + + bool ret = hdnode_nem_encrypt(node, + transfer->public_key.bytes, + iv, + salt, + payload, + size, + buffer); + + if (!ret) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to encrypt payload")); + return false; + } + + payload = encrypted; + size = NEM_ENCRYPTED_PAYLOAD_SIZE(size); + } + + bool ret = nem_transaction_create_transfer(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + transfer->recipient, + transfer->amount, + payload, + size, + transfer->has_public_key, + transfer->mosaics_count); + + if (!ret) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to create transfer transaction")); + return false; + } + + for (size_t i = 0; i < transfer->mosaics_count; i++) { + const NEMMosaic *mosaic = &transfer->mosaics[i]; + + ret = nem_transaction_write_mosaic(context, + mosaic->namespace, + mosaic->mosaic, + mosaic->quantity); + + if (!ret) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to attach mosaics")); + return false; + } + } + + return true; +} + +bool nem_askProvisionNamespace(const NEMTransactionCommon *common, const NEMProvisionNamespace *provision_namespace, const char *desc) { + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + _("Create namespace"), + provision_namespace->namespace, + provision_namespace->has_parent ? _("under namespace") : NULL, + provision_namespace->has_parent ? provision_namespace->parent : NULL, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + layoutNEMNetworkFee(desc, true, _("Confirm rental fee of"), provision_namespace->fee, _("and network fee of"), common->fee); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + return false; + } + + return true; +} + +bool nem_fsmProvisionNamespace(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMProvisionNamespace *provision_namespace) { + return nem_transaction_create_provision_namespace(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + provision_namespace->namespace, + provision_namespace->has_parent ? provision_namespace->parent : NULL, + provision_namespace->sink, + provision_namespace->fee); +} + +bool nem_askMosaicCreation(const NEMTransactionCommon *common, const NEMMosaicCreation *mosaic_creation, const char *desc, const char *address) { + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + _("Create mosaic"), + mosaic_creation->definition.mosaic, + _("under namespace"), + mosaic_creation->definition.namespace, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + layoutNEMMosaicDescription(mosaic_creation->definition.description); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + char str_out[32]; + + bn_format_uint64(mosaic_creation->definition.supply, + NULL, + NULL, + mosaic_creation->definition.divisibility, + mosaic_creation->definition.divisibility, + true, + str_out, + sizeof(str_out)); + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + _("Properties"), + mosaic_creation->definition.mutable_supply ? _("Mutable supply:") : _("Immutable supply:"), + str_out, + _("Mosaic will be"), + mosaic_creation->definition.transferable ? _("transferable") : _("non-transferable"), + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + if (mosaic_creation->definition.has_levy) { + layoutNEMLevy(&mosaic_creation->definition, common->network); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + if (strcmp(address, mosaic_creation->definition.levy_address) == 0) { + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + _("Levy Recipient"), + _("Levy will be paid to"), + _("yourself"), + NULL, + NULL, + NULL, + NULL); + } else { + layoutNEMDialog(&bmp_icon_question, + _("Cancel"), + _("Next"), + _("Levy Recipient"), + _("Levy will be paid to"), + mosaic_creation->definition.levy_address); + } + + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + + layoutNEMNetworkFee(desc, true, _("Confirm creation fee"), mosaic_creation->fee, _("and network fee of"), common->fee); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + return true; +} + +bool nem_fsmMosaicCreation(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMMosaicCreation *mosaic_creation) { + return nem_transaction_create_mosaic_creation(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + mosaic_creation->definition.namespace, + mosaic_creation->definition.mosaic, + mosaic_creation->definition.description, + mosaic_creation->definition.divisibility, + mosaic_creation->definition.supply, + mosaic_creation->definition.mutable_supply, + mosaic_creation->definition.transferable, + mosaic_creation->definition.levy, + mosaic_creation->definition.fee, + mosaic_creation->definition.levy_address, + mosaic_creation->definition.levy_namespace, + mosaic_creation->definition.levy_mosaic, + mosaic_creation->sink, + mosaic_creation->fee); +} + +bool nem_askSupplyChange(const NEMTransactionCommon *common, const NEMMosaicSupplyChange *supply_change, const char *desc) { + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + _("Modify supply for"), + supply_change->mosaic, + _("under namespace"), + supply_change->namespace, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + char str_out[32]; + bn_format_uint64(supply_change->delta, NULL, NULL, 0, 0, false, str_out, sizeof(str_out)); + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + supply_change->type == NEMSupplyChangeType_SupplyChange_Increase ? _("Increase supply by") : _("Decrease supply by"), + str_out, + _("whole units"), + NULL, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + layoutNEMNetworkFee(desc, true, _("Confirm network fee"), common->fee, NULL, 0); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + return false; + } + + return true; +} + +bool nem_fsmSupplyChange(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMMosaicSupplyChange *supply_change) { + return nem_transaction_create_mosaic_supply_change(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + supply_change->namespace, + supply_change->mosaic, + supply_change->type, + supply_change->delta); +} + +bool nem_askAggregateModification(const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification, const char *desc, bool creation) { + if (creation) { + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + _("Convert account to"), + _("multisig account?"), + NULL, + NULL, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + + char address[NEM_ADDRESS_SIZE + 1]; + + for (size_t i = 0; i < aggregate_modification->modifications_count; i++) { + const NEMCosignatoryModification *modification = &aggregate_modification->modifications[i]; + nem_get_address(modification->public_key.bytes, common->network, address); + + layoutNEMDialog(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + modification->type == NEMModificationType_CosignatoryModification_Add ? _("Add cosignatory") : _("Remove cosignatory"), + address); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + + int32_t relative_change = aggregate_modification->relative_change; + if (relative_change) { + char str_out[32]; + bn_format_uint64(relative_change < 0 ? -relative_change : relative_change, + NULL, + NULL, + 0, + 0, + false, + str_out, + sizeof(str_out)); + + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + creation ? _("Set minimum") : (relative_change < 0 ? _("Decrease minimum") : _("Increase minimum")), + creation ? _("cosignatories to") : _("cosignatories by"), + str_out, + NULL, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + } + + layoutNEMNetworkFee(desc, true, _("Confirm network fee"), common->fee, NULL, 0); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + return false; + } + + return true; +} + +bool nem_fsmAggregateModification(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification) { + bool ret = nem_transaction_create_aggregate_modification(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + aggregate_modification->modifications_count, + aggregate_modification->relative_change != 0); + if (!ret) return false; + + for (size_t i = 0; i < aggregate_modification->modifications_count; i++) { + const NEMCosignatoryModification *modification = &aggregate_modification->modifications[i]; + + ret = nem_transaction_write_cosignatory_modification(context, + modification->type, + modification->public_key.bytes); + if (!ret) return false; + } + + if (aggregate_modification->relative_change) { + ret = nem_transaction_write_minimum_cosignatories(context, aggregate_modification->relative_change); + if (!ret) return false; + } + + return true; +} + +bool nem_askImportanceTransfer(const NEMTransactionCommon *common, const NEMImportanceTransfer *importance_transfer, const char *desc) { + layoutDialogSwipe(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + importance_transfer->mode == NEMImportanceTransferMode_ImportanceTransfer_Activate ? _("Activate remote") : _("Deactivate remote"), + _("harvesting?"), + NULL, + NULL, + NULL, + NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + layoutNEMNetworkFee(desc, true, _("Confirm network fee"), common->fee, NULL, 0); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + return false; + } + + return true; +} + +bool nem_fsmImportanceTransfer(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMImportanceTransfer *importance_transfer) { + return nem_transaction_create_importance_transfer(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + importance_transfer->mode, + importance_transfer->public_key.bytes); +} + +bool nem_askMultisig(const char *address, const char *desc, bool cosigning, uint64_t fee) { + layoutNEMDialog(&bmp_icon_question, + _("Cancel"), + _("Next"), + desc, + cosigning ? _("Cosign transaction for") : _("Initiate transaction for"), + address); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + layoutNEMNetworkFee(desc, false, _("Confirm multisig fee"), fee, NULL, 0); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return false; + } + + return true; +} + +bool nem_fsmMultisig(nem_transaction_ctx *context, const NEMTransactionCommon *common, const nem_transaction_ctx *inner, bool cosigning) { + bool ret; + if (cosigning) { + ret = nem_transaction_create_multisig_signature(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + inner); + } else { + ret = nem_transaction_create_multisig(context, + common->network, + common->timestamp, + NULL, + common->fee, + common->deadline, + inner); + } + + if (!ret) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to create multisig transaction")); + return false; + } + + return true; +} + +const NEMMosaicDefinition *nem_mosaicByName(const char *namespace, const char *mosaic, uint8_t network) { + for (size_t i = 0; i < NEM_MOSAIC_DEFINITIONS_COUNT; i++) { + const NEMMosaicDefinition *definition = &NEM_MOSAIC_DEFINITIONS[i]; + + if (nem_mosaicMatches(definition, namespace, mosaic, network)) { + return definition; + } + } + + return NULL; +} + +static inline size_t format_amount(const NEMMosaicDefinition *definition, const bignum256 *amnt, const bignum256 *multiplier, int divisor, char *str_out, size_t size) { + bignum256 val; + memcpy(&val, amnt, sizeof(bignum256)); + + if (multiplier) { + bn_multiply(multiplier, &val, &secp256k1.prime); + divisor += NEM_MOSAIC_DEFINITION_XEM->divisibility; + } + + return bn_format(&val, + NULL, + definition && definition->has_ticker ? definition->ticker : NULL, + definition && definition->has_divisibility ? definition->divisibility : 0, + -divisor, + false, + str_out, + size); +} + +size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count) { + if (mosaics_count <= 1) { + return mosaics_count; + } + + size_t actual_count = 0; + + bool skip[mosaics_count]; + memset(skip, 0, sizeof(skip)); + + // Merge duplicates + for (size_t i = 0; i < mosaics_count; i++) { + if (skip[i]) continue; + + NEMMosaic *mosaic = &mosaics[actual_count]; + + if (actual_count++ != i) { + memcpy(mosaic, &mosaics[i], sizeof(NEMMosaic)); + } + + for (size_t j = i + 1; j < mosaics_count; j++) { + if (skip[j]) continue; + + const NEMMosaic *new_mosaic = &mosaics[j]; + + if (nem_mosaicCompare(mosaic, new_mosaic) == 0) { + skip[j] = true; + mosaic->quantity += new_mosaic->quantity; + } + } + } + + NEMMosaic temp; + + // Sort mosaics + for (size_t i = 0; i < actual_count - 1; i++) { + NEMMosaic *a = &mosaics[i]; + + for (size_t j = i + 1; j < actual_count; j++) { + NEMMosaic *b = &mosaics[j]; + + if (nem_mosaicCompare(a, b) > 0) { + memcpy(&temp, a, sizeof(NEMMosaic)); + memcpy(a, b, sizeof(NEMMosaic)); + memcpy(b, &temp, sizeof(NEMMosaic)); + } + } + } + + return actual_count; +} + +void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition, uint64_t quantity, const bignum256 *multiplier, char *str_out, size_t size) { + bignum256 amnt; + bn_read_uint64(quantity, &amnt); + + format_amount(definition, &amnt, multiplier, 0, str_out, size); +} + +bool nem_mosaicFormatLevy(const NEMMosaicDefinition *definition, uint64_t quantity, const bignum256 *multiplier, uint8_t network, char *str_out, size_t size) { + if (!definition->has_levy || !definition->has_fee) { + return false; + } + + bignum256 amnt, fee; + bn_read_uint64(quantity, &amnt); + bn_read_uint64(definition->fee, &fee); + + const NEMMosaicDefinition *mosaic = nem_mosaicByName(definition->levy_namespace, definition->levy_mosaic, network); + + switch (definition->levy) { + case NEMMosaicLevy_MosaicLevy_Absolute: + return format_amount(mosaic, &fee, NULL, 0, str_out, size); + + case NEMMosaicLevy_MosaicLevy_Percentile: + bn_multiply(&fee, &amnt, &secp256k1.prime); + return format_amount(mosaic, &amnt, multiplier, NEM_LEVY_PERCENTILE_DIVISOR, str_out, size); + + default: + return false; + } +} diff --git a/hardware-wallet/firmware/firmware/nem2.h b/hardware-wallet/firmware/firmware/nem2.h new file mode 100644 index 00000000..ed7c90fb --- /dev/null +++ b/hardware-wallet/firmware/firmware/nem2.h @@ -0,0 +1,111 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __NEM2_H__ +#define __NEM2_H__ + +#include "nem.h" +#include "nem_mosaics.h" + +#include "messages.pb.h" +#include "types.pb.h" + +#include + +const char *nem_validate_common(NEMTransactionCommon *common, bool inner); +const char *nem_validate_transfer(const NEMTransfer *transfer, uint8_t network); +const char *nem_validate_provision_namespace(const NEMProvisionNamespace *provision_namespace, uint8_t network); +const char *nem_validate_mosaic_creation(const NEMMosaicCreation *mosaic_creation, uint8_t network); +const char *nem_validate_supply_change(const NEMMosaicSupplyChange *supply_change); +const char *nem_validate_aggregate_modification(const NEMAggregateModification *aggregate_modification, bool creation); +const char *nem_validate_importance_transfer(const NEMImportanceTransfer *importance_transfer); + +bool nem_askTransfer(const NEMTransactionCommon *common, const NEMTransfer *transfer, const char *desc); +bool nem_fsmTransfer(nem_transaction_ctx *context, const HDNode *node, const NEMTransactionCommon *common, const NEMTransfer *transfer); + +bool nem_askProvisionNamespace(const NEMTransactionCommon *common, const NEMProvisionNamespace *provision_namespace, const char *desc); +bool nem_fsmProvisionNamespace(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMProvisionNamespace *provision_namespace); + +bool nem_askMosaicCreation(const NEMTransactionCommon *common, const NEMMosaicCreation *mosaic_creation, const char *desc, const char *address); +bool nem_fsmMosaicCreation(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMMosaicCreation *mosaic_creation); + +bool nem_askSupplyChange(const NEMTransactionCommon *common, const NEMMosaicSupplyChange *supply_change, const char *desc); +bool nem_fsmSupplyChange(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMMosaicSupplyChange *supply_change); + +bool nem_askAggregateModification(const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification, const char *desc, bool creation); +bool nem_fsmAggregateModification(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMAggregateModification *aggregate_modification); + +bool nem_askImportanceTransfer(const NEMTransactionCommon *common, const NEMImportanceTransfer *importance_transfer, const char *desc); +bool nem_fsmImportanceTransfer(nem_transaction_ctx *context, const NEMTransactionCommon *common, const NEMImportanceTransfer *importance_transfer); + +bool nem_askMultisig(const char *address, const char *desc, bool cosigning, uint64_t fee); +bool nem_fsmMultisig(nem_transaction_ctx *context, const NEMTransactionCommon *common, const nem_transaction_ctx *inner, bool cosigning); + +const NEMMosaicDefinition *nem_mosaicByName(const char *namespace, const char *mosaic, uint8_t network); + +size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count); +void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition, uint64_t quantity, const bignum256 *multiplier, char *str_out, size_t size); +bool nem_mosaicFormatLevy(const NEMMosaicDefinition *definition, uint64_t quantity, const bignum256 *multiplier, uint8_t network, char *str_out, size_t size); + +static inline void nem_mosaicFormatName(const char *namespace, const char *mosaic, char *str_out, size_t size) { + strlcpy(str_out, namespace, size); + strlcat(str_out, ".", size); + strlcat(str_out, mosaic, size); +} + +static inline bool nem_mosaicMatches(const NEMMosaicDefinition *definition, const char *namespace, const char *mosaic, uint8_t network) { + if (strcmp(namespace, definition->namespace) == 0 && strcmp(mosaic, definition->mosaic) == 0) { + if (definition->networks_count == 0) { + return true; + } + + for (size_t i = 0; i < definition->networks_count; i++) { + if (definition->networks[i] == network) { + return true; + } + } + } + + return false; +} + +static inline int nem_mosaicCompare(const NEMMosaic *a, const NEMMosaic *b) { + size_t namespace_length = strlen(a->namespace); + + // Ensure that strlen(a->namespace) <= strlen(b->namespace) + if (namespace_length > strlen(b->namespace)) { + return -nem_mosaicCompare(b, a); + } + + int r = strncmp(a->namespace, b->namespace, namespace_length); + + if (r == 0 && b->namespace[namespace_length] != '\0') { + // The next character would be the separator + r = (':' - b->namespace[namespace_length]); + } + + if (r == 0) { + // Finally compare the mosaic + r = strcmp(a->mosaic, b->mosaic); + } + + return r; +} + +#endif diff --git a/hardware-wallet/firmware/firmware/nem_mosaics.json b/hardware-wallet/firmware/firmware/nem_mosaics.json new file mode 100644 index 00000000..c547e93a --- /dev/null +++ b/hardware-wallet/firmware/firmware/nem_mosaics.json @@ -0,0 +1,57 @@ +[ + { + "name": "XEM", + "ticker": " XEM", + "namespace": "nem", + "mosaic": "xem", + "divisibility": 6 + }, + { + "name": "DIMCOIN", + "ticker": " DIM", + "namespace": "dim", + "mosaic": "coin", + "divisibility": 6, + "levy": "MosaicLevy_Percentile", + "fee": 10, + "levy_namespace": "dim", + "levy_mosaic": "coin", + "networks": [ 104 ] + }, + { + "name": "DIM TOKEN", + "ticker": " DIMTOK", + "namespace": "dim", + "mosaic": "token", + "divisibility": 6, + "networks": [ 104 ] + }, + { + "name": "Breeze Token", + "ticker": " BREEZE", + "namespace": "breeze", + "mosaic": "breeze-token", + "divisibility": 0, + "networks": [ 104 ] + }, + { + "name": "PacNEM Game Credits", + "ticker": " PAC:HRT", + "namespace": "pacnem", + "mosaic": "heart", + "divisibility": 0, + "networks": [ 104 ] + }, + { + "name": "PacNEM Score Tokens", + "ticker": " PAC:CHS", + "namespace": "pacnem", + "mosaic": "cheese", + "divisibility": 6, + "levy": "MosaicLevy_Percentile", + "fee": 100, + "levy_namespace": "nem", + "levy_mosaic": "xem", + "networks": [ 104 ] + } +] diff --git a/hardware-wallet/firmware/firmware/nem_mosaics.py b/hardware-wallet/firmware/firmware/nem_mosaics.py new file mode 100755 index 00000000..096d4539 --- /dev/null +++ b/hardware-wallet/firmware/firmware/nem_mosaics.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +import json, os, sys + +import collections, numbers + +from google.protobuf import json_format +from itertools import chain + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "protob")) +import types_pb2 as types + +try: + basestring +except NameError: + basestring = (str, bytes) + +HEADER_TEMPLATE = """ +// This file is automatically generated by nem_mosaics.py -- DO NOT EDIT! + +#ifndef __NEM_MOSAICS_H__ +#define __NEM_MOSAICS_H__ + +#include "types.pb.h" + +#define NEM_MOSAIC_DEFINITIONS_COUNT ({count}) + +extern const NEMMosaicDefinition NEM_MOSAIC_DEFINITIONS[NEM_MOSAIC_DEFINITIONS_COUNT]; +extern const NEMMosaicDefinition *NEM_MOSAIC_DEFINITION_XEM; + +#endif +""".lstrip() + +CODE_TEMPLATE = """ +// This file is automatically generated by nem_mosaics.py -- DO NOT EDIT! + +#include "nem_mosaics.h" + +const NEMMosaicDefinition NEM_MOSAIC_DEFINITIONS[NEM_MOSAIC_DEFINITIONS_COUNT] = {code}; + +const NEMMosaicDefinition *NEM_MOSAIC_DEFINITION_XEM = NEM_MOSAIC_DEFINITIONS; +""".lstrip() + +def format_primitive(value): + if isinstance(value, bool): + return ("false", "true")[value] + elif isinstance(value, numbers.Number): + return str(value) + elif isinstance(value, basestring): + return json.dumps(value) + elif isinstance(value, collections.Sequence): + return "{ " + ", ".join( + format_primitive(item) for item in value + ) + " }" + else: + raise TypeError + +def format_struct(struct): + return "{\n" + "\n".join( + "\t.{0} = {1},".format(member, value) for member, value in struct.items() + ) + "\n}" + + +def format_field(field, value): + if field.message_type is not None: + raise TypeError + elif field.enum_type: + return "{0}_{1}".format(field.enum_type.name, field.enum_type.values_by_number[value].name) + elif hasattr(value, "_values"): + return format_primitive(value._values) + else: + return format_primitive(value) + +def field_to_meta(field, value): + if field.label == field.LABEL_REPEATED: + return ("{}_count".format(field.name), format_primitive(len(value))) + else: + return ("has_{}".format(field.name), format_primitive(True)) + +def message_to_struct(_message, proto): + message = json_format.ParseDict(_message, proto()) + return collections.OrderedDict(chain.from_iterable( + ( + field_to_meta(field, value), + (field.name, format_field(field, value)), + ) for field, value in message.ListFields() + )) + +def format_message(message, proto): + return format_struct(message_to_struct(message, proto)) + +def format_messages(messages, proto): + return "{" + ",\n".join( + format_message(message, proto) for message in messages + ) + "}" + +if __name__ == "__main__": + os.chdir(os.path.abspath(os.path.dirname(__file__))) + + messages = json.load(open("nem_mosaics.json")) + + with open("nem_mosaics.h", "w+") as f: + f.write(HEADER_TEMPLATE.format(count=format_primitive(len(messages)))) + + with open("nem_mosaics.c", "w+") as f: + f.write(CODE_TEMPLATE.format(code=format_messages(messages, types.NEMMosaicDefinition))) diff --git a/hardware-wallet/firmware/firmware/pinmatrix.c b/hardware-wallet/firmware/firmware/pinmatrix.c new file mode 100644 index 00000000..c3a5aac9 --- /dev/null +++ b/hardware-wallet/firmware/firmware/pinmatrix.c @@ -0,0 +1,82 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include "pinmatrix.h" +#include "layout2.h" +#include "oled.h" +#include "rng.h" + +static char pinmatrix_perm[10] = "XXXXXXXXX"; + +void pinmatrix_draw(const char *text) +{ + const BITMAP *bmp_digits[10] = { + &bmp_digit0, &bmp_digit1, &bmp_digit2, &bmp_digit3, &bmp_digit4, + &bmp_digit5, &bmp_digit6, &bmp_digit7, &bmp_digit8, &bmp_digit9, + }; + layoutSwipe(); + const int w = bmp_digit0.width, h = bmp_digit0.height, pad = 2; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + // use (2 - j) instead of j to achieve 789456123 layout + int k = pinmatrix_perm[i + (2 - j) * 3] - '0'; + if (text) { + oledDrawStringCenter(0, text, FONT_STANDARD); + } + oledDrawBitmap((OLED_WIDTH - 3 * w - 2 * pad) / 2 + i * (w + pad), OLED_HEIGHT - 3 * h - 2 * pad + j * (h + pad), bmp_digits[k]); + } + } + oledRefresh(); +} + +void pinmatrix_start(const char *text) +{ + for (int i = 0; i < 9; i++) { + pinmatrix_perm[i] = '1' + i; + } + pinmatrix_perm[9] = 0; + random_permute(pinmatrix_perm, 9); + pinmatrix_draw(text); +} + +void pinmatrix_done(char *pin) +{ + int k, i = 0; + while (pin && pin[i]) { + k = pin[i] - '1'; + if (k >= 0 && k <= 8) { + pin[i] = pinmatrix_perm[k]; + } else { + pin[i] = 'X'; + } + i++; + } + memset(pinmatrix_perm, 'X', sizeof(pinmatrix_perm)); +} + +#if DEBUG_LINK + +const char *pinmatrix_get(void) +{ + return pinmatrix_perm; +} + +#endif diff --git a/hardware-wallet/firmware/firmware/pinmatrix.h b/hardware-wallet/firmware/firmware/pinmatrix.h new file mode 100644 index 00000000..a1c70bd9 --- /dev/null +++ b/hardware-wallet/firmware/firmware/pinmatrix.h @@ -0,0 +1,27 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __PINMATRIX_H__ +#define __PINMATRIX_H__ + +void pinmatrix_start(const char *text); +void pinmatrix_done(char *pin); +const char *pinmatrix_get(void); + +#endif diff --git a/hardware-wallet/firmware/firmware/protect.c b/hardware-wallet/firmware/firmware/protect.c new file mode 100644 index 00000000..ffbe4aa3 --- /dev/null +++ b/hardware-wallet/firmware/firmware/protect.c @@ -0,0 +1,276 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "protect.h" +#include "storage.h" +#include "messages.h" +#include "usb.h" +#include "oled.h" +#include "buttons.h" +#include "pinmatrix.h" +#include "fsm.h" +#include "layout2.h" +#include "util.h" +#include "debug.h" +#include "gettext.h" +#include "memzero.h" + +#define MAX_WRONG_PINS 15 + +bool protectAbortedByInitialize = false; + +bool protectButton(ButtonRequestType type, bool confirm_only) +{ + ButtonRequest resp; + bool result = false; + bool acked = false; +#if DEBUG_LINK + bool debug_decided = false; +#endif + + memset(&resp, 0, sizeof(ButtonRequest)); + resp.has_code = true; + resp.code = type; + usbTiny(1); + buttonUpdate(); // Clear button state + msg_write(MessageType_MessageType_ButtonRequest, &resp); + + for (;;) { + usbPoll(); + + // check for ButtonAck + if (msg_tiny_id == MessageType_MessageType_ButtonAck) { + msg_tiny_id = 0xFFFF; + acked = true; + } + + // button acked - check buttons + if (acked) { + usbSleep(5); + buttonUpdate(); + if (button.YesUp) { + result = true; + break; + } + if (!confirm_only && button.NoUp) { + result = false; + break; + } + } + + // check for Cancel / Initialize + if (msg_tiny_id == MessageType_MessageType_Cancel || msg_tiny_id == MessageType_MessageType_Initialize) { + if (msg_tiny_id == MessageType_MessageType_Initialize) { + protectAbortedByInitialize = true; + } + msg_tiny_id = 0xFFFF; + result = false; + break; + } + +#if DEBUG_LINK + // check DebugLink + if (msg_tiny_id == MessageType_MessageType_DebugLinkDecision) { + msg_tiny_id = 0xFFFF; + DebugLinkDecision *dld = (DebugLinkDecision *)msg_tiny; + result = dld->yes_no; + debug_decided = true; + } + + if (acked && debug_decided) { + break; + } + + if (msg_tiny_id == MessageType_MessageType_DebugLinkGetState) { + msg_tiny_id = 0xFFFF; + fsm_msgDebugLinkGetState((DebugLinkGetState *)msg_tiny); + } +#endif + } + + usbTiny(0); + + return result; +} + +const char *requestPin(PinMatrixRequestType type, const char *text) +{ + PinMatrixRequest resp; + memset(&resp, 0, sizeof(PinMatrixRequest)); + resp.has_type = true; + resp.type = type; + usbTiny(1); + msg_write(MessageType_MessageType_PinMatrixRequest, &resp); + pinmatrix_start(text); + for (;;) { + usbPoll(); + if (msg_tiny_id == MessageType_MessageType_PinMatrixAck) { + msg_tiny_id = 0xFFFF; + PinMatrixAck *pma = (PinMatrixAck *)msg_tiny; + pinmatrix_done(pma->pin); // convert via pinmatrix + usbTiny(0); + return pma->pin; + } + if (msg_tiny_id == MessageType_MessageType_Cancel || msg_tiny_id == MessageType_MessageType_Initialize) { + pinmatrix_done(0); + if (msg_tiny_id == MessageType_MessageType_Initialize) { + protectAbortedByInitialize = true; + } + msg_tiny_id = 0xFFFF; + usbTiny(0); + return 0; + } +#if DEBUG_LINK + if (msg_tiny_id == MessageType_MessageType_DebugLinkGetState) { + msg_tiny_id = 0xFFFF; + fsm_msgDebugLinkGetState((DebugLinkGetState *)msg_tiny); + } +#endif + } +} + +static void protectCheckMaxTry(uint32_t wait) { + if (wait < (1 << MAX_WRONG_PINS)) + return; + + storage_wipe(); + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Too many wrong PIN"), _("attempts. Storage has"), _("been wiped."), NULL, _("Please unplug"), _("the device.")); + for (;;) {} // loop forever +} + +bool protectPin(bool use_cached) +{ + if (!storage_hasPin() || (use_cached && session_isPinCached())) { + return true; + } + uint32_t *fails = storage_getPinFailsPtr(); + uint32_t wait = ~*fails; + protectCheckMaxTry(wait); + usbTiny(1); + while (wait > 0) { + // convert wait to secstr string + char secstrbuf[20]; + strlcpy(secstrbuf, _("________0 seconds"), sizeof(secstrbuf)); + char *secstr = secstrbuf + 9; + uint32_t secs = wait; + while (secs > 0 && secstr >= secstrbuf) { + secstr--; + *secstr = (secs % 10) + '0'; + secs /= 10; + } + if (wait == 1) { + secstrbuf[16] = 0; + } + layoutDialog(&bmp_icon_info, NULL, NULL, NULL, _("Wrong PIN entered"), NULL, _("Please wait"), secstr, _("to continue ..."), NULL); + // wait one second + usbSleep(1000); + if (msg_tiny_id == MessageType_MessageType_Initialize) { + protectAbortedByInitialize = true; + msg_tiny_id = 0xFFFF; + usbTiny(0); + fsm_sendFailure(FailureType_Failure_PinCancelled, NULL); + return false; + } + wait--; + } + usbTiny(0); + const char *pin; + pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, _("Please enter current PIN:")); + if (!pin) { + fsm_sendFailure(FailureType_Failure_PinCancelled, NULL); + return false; + } + if (!storage_increasePinFails(fails)) { + fsm_sendFailure(FailureType_Failure_PinInvalid, NULL); + return false; + } + if (storage_containsPin(pin)) { + session_cachePin(); + storage_resetPinFails(fails); + return true; + } else { + protectCheckMaxTry(~*fails); + fsm_sendFailure(FailureType_Failure_PinInvalid, NULL); + return false; + } +} + +bool protectChangePin(void) +{ + static CONFIDENTIAL char pin_compare[17]; + + const char *pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_NewFirst, _("Please enter new PIN:")); + + if (!pin) { + return false; + } + + strlcpy(pin_compare, pin, sizeof(pin_compare)); + + pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_NewSecond, _("Please re-enter new PIN:")); + + const bool result = pin && (strncmp(pin_compare, pin, sizeof(pin_compare)) == 0); + + if (result) { + storage_setPin(pin_compare); + storage_update(); + } + + memzero(pin_compare, sizeof(pin_compare)); + + return result; +} + +bool protectPassphrase(void) +{ + if (!storage_hasPassphraseProtection() || session_isPassphraseCached()) { + return true; + } + + PassphraseRequest resp; + memset(&resp, 0, sizeof(PassphraseRequest)); + usbTiny(1); + msg_write(MessageType_MessageType_PassphraseRequest, &resp); + + layoutDialogSwipe(&bmp_icon_info, NULL, NULL, NULL, _("Please enter your"), _("passphrase using"), _("the computer's"), _("keyboard."), NULL, NULL); + + bool result; + for (;;) { + usbPoll(); + // TODO: correctly process PassphraseAck with state field set (mismatch => Failure) + if (msg_tiny_id == MessageType_MessageType_PassphraseAck) { + msg_tiny_id = 0xFFFF; + PassphraseAck *ppa = (PassphraseAck *)msg_tiny; + session_cachePassphrase(ppa->has_passphrase ? ppa->passphrase : ""); + result = true; + break; + } + if (msg_tiny_id == MessageType_MessageType_Cancel || msg_tiny_id == MessageType_MessageType_Initialize) { + if (msg_tiny_id == MessageType_MessageType_Initialize) { + protectAbortedByInitialize = true; + } + msg_tiny_id = 0xFFFF; + result = false; + break; + } + } + usbTiny(0); + layoutHome(); + return result; +} diff --git a/hardware-wallet/firmware/firmware/protect.h b/hardware-wallet/firmware/firmware/protect.h new file mode 100644 index 00000000..efa6163c --- /dev/null +++ b/hardware-wallet/firmware/firmware/protect.h @@ -0,0 +1,33 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __PROTECT_H__ +#define __PROTECT_H__ + +#include +#include "types.pb.h" + +bool protectButton(ButtonRequestType type, bool confirm_only); +bool protectPin(bool use_cached); +bool protectChangePin(void); +bool protectPassphrase(void); + +extern bool protectAbortedByInitialize; + +#endif diff --git a/hardware-wallet/firmware/firmware/protob/.gitignore b/hardware-wallet/firmware/firmware/protob/.gitignore new file mode 100644 index 00000000..8ea827fb --- /dev/null +++ b/hardware-wallet/firmware/firmware/protob/.gitignore @@ -0,0 +1,7 @@ +*.pb +*_pb2.py +*.pb.c +*.pb.h +*.pyc +messages_map.h +__pycache__/ diff --git a/hardware-wallet/firmware/firmware/protob/Makefile b/hardware-wallet/firmware/firmware/protob/Makefile new file mode 100644 index 00000000..5a3327f9 --- /dev/null +++ b/hardware-wallet/firmware/firmware/protob/Makefile @@ -0,0 +1,18 @@ +all: messages.pb.c types.pb.c messages_map.h + +PYTHON ?= python + +%.pb.c: %.pb %.options + $(PYTHON) ../../vendor/nanopb/generator/nanopb_generator.py $< -L '#include "%s"' -T + +%.pb: %.proto + protoc -I/usr/include -I. $< -o $@ + +%_pb2.py: %.proto + protoc -I/usr/include -I. $< --python_out=. + +messages_map.h: messages_map.py messages_pb2.py types_pb2.py + $(PYTHON) $< > $@ + +clean: + rm -f *.pb *.o *.d *.pb.c *.pb.h *_pb2.py messages_map.h diff --git a/hardware-wallet/firmware/firmware/protob/messages.options b/hardware-wallet/firmware/firmware/protob/messages.options new file mode 100644 index 00000000..e607587a --- /dev/null +++ b/hardware-wallet/firmware/firmware/protob/messages.options @@ -0,0 +1,210 @@ +Initialize.state max_size:64 + +Features.vendor max_size:33 +Features.device_id max_size:25 +Features.language max_size:17 +Features.label max_size:33 +Features.coins max_count:16 +Features.revision max_size:20 +Features.bootloader_hash max_size:32 +Features.model max_size:17 +Features.fw_vendor max_size:256 +Features.fw_vendor_keys max_size:32 + +ApplySettings.language max_size:17 +ApplySettings.label max_size:33 +ApplySettings.homescreen max_size:1024 + +Ping.message max_size:256 + +SkycoinAddress.seed max_size:256 +SkycoinCheckMessageSignature.address max_size:36 +SkycoinCheckMessageSignature.message max_size:256 +SkycoinCheckMessageSignature.signature max_size:90 +SkycoinSignMessage.message max_size:256 +SkycoinSignMessage.secretKey max_size:45 + +Success.message max_size:256 + +Failure.message max_size:256 + +ButtonRequest.data max_size:256 + +PinMatrixAck.pin max_size:10 + +PassphraseAck.passphrase max_size:51 +PassphraseAck.state max_size:64 + +PassphraseStateRequest.state max_size:64 + +Entropy.entropy max_size:1024 + +GetPublicKey.address_n max_count:8 +GetPublicKey.ecdsa_curve_name max_size:32 +GetPublicKey.coin_name max_size:21 + +PublicKey.xpub max_size:113 + +GetAddress.address_n max_count:8 +GetAddress.coin_name max_size:21 + +Address.address max_size:76 + +EthereumGetAddress.address_n max_count:8 +EthereumAddress.address max_size:20 + +LoadDevice.mnemonic max_size:241 +LoadDevice.pin max_size:10 +LoadDevice.language max_size:17 +LoadDevice.label max_size:33 + +ResetDevice.language max_size:17 +ResetDevice.label max_size:33 + +EntropyAck.entropy max_size:128 + +RecoveryDevice.language max_size:17 +RecoveryDevice.label max_size:33 + +WordAck.word max_size:12 + +SignMessage.address_n max_count:8 +SignMessage.message max_size:1024 +SignMessage.coin_name max_size:21 + +VerifyMessage.address max_size:76 +VerifyMessage.signature max_size:65 +VerifyMessage.message max_size:1024 +VerifyMessage.coin_name max_size:21 + +MessageSignature.address max_size:76 +MessageSignature.signature max_size:65 + +EthereumSignMessage.address_n max_count:8 +EthereumSignMessage.message max_size:1024 + +EthereumVerifyMessage.address max_size:20 +EthereumVerifyMessage.signature max_size:65 +EthereumVerifyMessage.message max_size:1024 + +EthereumMessageSignature.address max_size:20 +EthereumMessageSignature.signature max_size:65 + +# deprecated +EncryptMessage skip_message:true +# EncryptMessage.pubkey max_size:33 +# EncryptMessage.message max_size:1024 +# EncryptMessage.address_n max_count:8 +# EncryptMessage.coin_name max_size:21 + +# deprecated +EncryptedMessage skip_message:true +# EncryptedMessage.nonce max_size:33 +# EncryptedMessage.message max_size:1120 +# EncryptedMessage.hmac max_size:8 + +# deprecated +DecryptMessage skip_message:true +# DecryptMessage.address_n max_count:8 +# DecryptMessage.nonce max_size:33 +# DecryptMessage.message max_size:1120 # 1 + 9 + 1024 + 21 + 65 +# DecryptMessage.hmac max_size:8 + +# deprecated +DecryptedMessage skip_message:true +# DecryptedMessage.address max_size:76 +# DecryptedMessage.message max_size:1024 + +CipherKeyValue.address_n max_count:8 +CipherKeyValue.key max_size:256 +CipherKeyValue.value max_size:1024 +CipherKeyValue.iv max_size:16 + +CipheredKeyValue.value max_size:1024 + +# deprecated +EstimateTxSize skip_message:true +# EstimateTxSize.coin_name max_size:21 + +# deprecated +TxSize skip_message:true + +SignTx.coin_name max_size:21 + +EthereumSignTx.address_n max_count:8 +EthereumSignTx.nonce max_size:32 +EthereumSignTx.gas_price max_size:32 +EthereumSignTx.gas_limit max_size:32 +EthereumSignTx.to max_size:20 +EthereumSignTx.value max_size:32 +EthereumSignTx.data_initial_chunk max_size:1024 + +EthereumTxRequest.signature_r max_size:32 +EthereumTxRequest.signature_s max_size:32 + +EthereumTxAck.data_chunk max_size:1024 + +SignIdentity.challenge_hidden max_size:256 +SignIdentity.challenge_visual max_size:256 +SignIdentity.ecdsa_curve_name max_size:32 + +SignedIdentity.address max_size:76 +SignedIdentity.public_key max_size:33 +SignedIdentity.signature max_size:65 + +GetECDHSessionKey.peer_public_key max_size:65 +GetECDHSessionKey.ecdsa_curve_name max_size:32 + +ECDHSessionKey.session_key max_size:65 + +NEMGetAddress.address_n max_count:8 + +NEMAddress.address max_size:41 + +NEMSignedTx.data max_size:2048 +NEMSignedTx.signature max_size:64 + +NEMDecryptMessage.address_n max_count:8 +NEMDecryptMessage.public_key max_size:32 +NEMDecryptMessage.payload max_size:1072 + +NEMDecryptedMessage.payload max_size:1024 + +CosiCommit.address_n max_count:8 +CosiCommit.data max_size:32 + +CosiCommitment.commitment max_size:32 +CosiCommitment.pubkey max_size:32 + +CosiSign.address_n max_count:8 +CosiSign.data max_size:32 +CosiSign.global_commitment max_size:32 +CosiSign.global_pubkey max_size:32 + +CosiSignature.signature max_size:32 + +# deprecated +SimpleSignTx skip_message:true + +# not used in firmware, just in bootloader + +FirmwareErase skip_message:true +FirmwareRequest skip_message:true +FirmwareUpload skip_message:true +SelfTest skip_message:true + +# used only in debug firmware + +DebugLinkState.layout max_size:1024 +DebugLinkState.pin max_size:10 +DebugLinkState.matrix max_size:10 +DebugLinkState.mnemonic max_size:241 +DebugLinkState.reset_word max_size:12 +DebugLinkState.reset_entropy max_size:128 +DebugLinkState.recovery_fake_word max_size:12 + +DebugLinkLog.bucket max_size:33 +DebugLinkLog.text max_size:256 + +DebugLinkMemory.memory max_size:1024 +DebugLinkMemoryWrite.memory max_size:1024 diff --git a/hardware-wallet/firmware/firmware/protob/messages.proto b/hardware-wallet/firmware/firmware/protob/messages.proto new file mode 120000 index 00000000..4f4140fb --- /dev/null +++ b/hardware-wallet/firmware/firmware/protob/messages.proto @@ -0,0 +1 @@ +../../vendor/trezor-common/protob/messages.proto \ No newline at end of file diff --git a/hardware-wallet/firmware/firmware/protob/messages_map.py b/hardware-wallet/firmware/firmware/protob/messages_map.py new file mode 100755 index 00000000..6499cfb6 --- /dev/null +++ b/hardware-wallet/firmware/firmware/protob/messages_map.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +from collections import defaultdict +from messages_pb2 import MessageType +from types_pb2 import wire_in, wire_out, wire_debug_in, wire_debug_out, wire_tiny, wire_bootloader + +# len("MessageType_MessageType_") - len("_fields") == 17 +TEMPLATE = "\t{{ {type} {dir} {msg_id:46} {fields:29} {process_func} }}," + +LABELS = { + wire_in: "in messages", + wire_out: "out messages", + wire_debug_in: "debug in messages", + wire_debug_out: "debug out messages", +} + +def handle_message(message, extension): + name = message.name + short_name = name.split("MessageType_", 1).pop() + assert(short_name != name) + + interface = "d" if extension in (wire_debug_in, wire_debug_out) else "n" + direction = "i" if extension in (wire_in, wire_debug_in) else "o" + + options = message.GetOptions() + bootloader = options.Extensions[wire_bootloader] + tiny = options.Extensions[wire_tiny] and direction == "i" + + if getattr(options, 'deprecated', None): + return '\t// Message %s is deprecated' % short_name + if bootloader: + return '\t// Message %s is used in bootloader mode only' % short_name + if tiny: + return '\t// Message %s is used in tiny mode' % short_name + + return TEMPLATE.format( + type="'%c'," % interface, + dir="'%c'," % direction, + msg_id="MessageType_%s," % name, + fields="%s_fields," % short_name, + process_func = "(void (*)(void *)) fsm_msg%s" % short_name if direction == "i" else "0" + ) + +print('\t// This file is automatically generated by messages_map.py -- DO NOT EDIT!') + +messages = defaultdict(list) + +for message in MessageType.DESCRIPTOR.values: + extensions = message.GetOptions().Extensions + + for extension in (wire_in, wire_out, wire_debug_in, wire_debug_out): + if extensions[extension]: + messages[extension].append(message) + +for extension in (wire_in, wire_out, wire_debug_in, wire_debug_out): + if extension == wire_debug_in: + print("\n#if DEBUG_LINK") + + print("\n\t// {label}\n".format(label=LABELS[extension])) + + for message in messages[extension]: + print(handle_message(message, extension)) + + if extension == wire_debug_out: + print("\n#endif") diff --git a/hardware-wallet/firmware/firmware/protob/types.options b/hardware-wallet/firmware/firmware/protob/types.options new file mode 100644 index 00000000..e087cb07 --- /dev/null +++ b/hardware-wallet/firmware/firmware/protob/types.options @@ -0,0 +1,74 @@ +HDNodeType.chain_code max_size:32 +HDNodeType.private_key max_size:32 +HDNodeType.public_key max_size:33 + +HDNodePathType.address_n max_count:8 + +CoinType.coin_name max_size:17 +CoinType.coin_shortcut max_size:9 +CoinType.signed_message_header max_size:32 + +TxInputType.address_n max_count:8 +TxInputType.prev_hash max_size:32 +TxInputType.script_sig max_size:1650 + +TxOutputType.address max_size:76 +TxOutputType.address_n max_count:8 +TxOutputType.op_return_data max_size:80 + +TxOutputBinType.script_pubkey max_size:520 + +TransactionType.inputs max_count:1 +TransactionType.bin_outputs max_count:1 +TransactionType.outputs max_count:1 +TransactionType.extra_data max_size:1024 + +TxRequestDetailsType.tx_hash max_size:32 + +TxRequestSerializedType.signature max_size:73 +TxRequestSerializedType.serialized_tx max_size:2048 + +MultisigRedeemScriptType.pubkeys max_count:15 +MultisigRedeemScriptType.signatures max_count:15 max_size:73 + +IdentityType.proto max_size:9 +IdentityType.user max_size:64 +IdentityType.host max_size:64 +IdentityType.port max_size:6 +IdentityType.path max_size:256 + +NEMTransactionCommon.address_n max_count:8 +NEMTransactionCommon.signer max_size:32 + +NEMTransfer.recipient max_size:41 +NEMTransfer.public_key max_size:32 +NEMTransfer.payload max_size:1024 +NEMTransfer.mosaics max_count:16 + +NEMMosaic.namespace max_size:145 +NEMMosaic.mosaic max_size:33 + +NEMProvisionNamespace.namespace max_size:65 +NEMProvisionNamespace.parent max_size:81 +NEMProvisionNamespace.sink max_size:41 + +NEMMosaicCreation.sink max_size:41 + +NEMMosaicDefinition.name max_size:32 +NEMMosaicDefinition.ticker max_size:16 +NEMMosaicDefinition.namespace max_size:145 +NEMMosaicDefinition.mosaic max_size:33 +NEMMosaicDefinition.levy_address max_size:41 +NEMMosaicDefinition.levy_namespace max_size:145 +NEMMosaicDefinition.levy_mosaic max_size:33 +NEMMosaicDefinition.description max_size:513 +NEMMosaicDefinition.networks max_count:8 + +NEMMosaicSupplyChange.namespace max_size:145 +NEMMosaicSupplyChange.mosaic max_size:33 + +NEMAggregateModification.modifications max_count:16 + +NEMCosignatoryModification.public_key max_size:32 + +NEMImportanceTransfer.public_key max_size:32 diff --git a/hardware-wallet/firmware/firmware/protob/types.proto b/hardware-wallet/firmware/firmware/protob/types.proto new file mode 120000 index 00000000..8eed39a0 --- /dev/null +++ b/hardware-wallet/firmware/firmware/protob/types.proto @@ -0,0 +1 @@ +../../vendor/trezor-common/protob/types.proto \ No newline at end of file diff --git a/hardware-wallet/firmware/firmware/recovery-table.h b/hardware-wallet/firmware/firmware/recovery-table.h new file mode 100644 index 00000000..0efb1145 --- /dev/null +++ b/hardware-wallet/firmware/firmware/recovery-table.h @@ -0,0 +1,112 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2016 Jochen Hoenicke + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* DO NOT EDIT: This file is automatically generated by + * cd ../gen/wordlist + * perl build-recoverytable.pl recovery_english.txt + */ + +static const uint16_t word_table1[82] = +{ + 8192, 8200, 8208, 8217, 8225, 8234, 8243, 8250, 8259, + 12361, 12367, 8280, 8285, 8292, 8297, 8302, 8311, 8318, + 8325, 12429, 12437, 8347, 8356, 8365, 8373, 8382, 8391, + 8400, 8409, 8412, 8417, 8426, 8432, 8439, 8447, 8455, + 8463, 8472, 8480, 8487, 8495, 4408, 4416, 8521, 8530, + 8539, 8548, 8557, 8564, 8573, 8582, 8589, 8597, 8601, + 8609, 8618, 8627, 8634, 4545, 8645, 12750, 12759, 8672, + 8681, 8690, 8695, 8703, 8712, 8721, 8730, 8738, 8746, + 8751, 8757, 8766, 8775, 8782, 4690, 4699, 8804, 8813, + 630, +}; + +static const uint16_t word_table2[631] = +{ + 12288, 12293, 12297, 12298, 12302, 12304, 12306, 12307, 12312, + 12313, 12316, 8225, 8226, 8229, 8233, 8234, 12334, 12337, + 12342, 12345, 8253, 12354, 12357, 12361, 12365, 8274, 12376, + 12378, 12380, 12381, 12385, 12386, 12390, 12394, 12396, 12400, + 8305, 12407, 12410, 8318, 8321, 8327, 12424, 12428, 12433, + 12439, 12443, 12448, 12451, 12456, 12459, 12463, 12465, 12468, + 12471, 12476, 12479, 12482, 12485, 12489, 12494, 12498, 12502, + 12507, 12509, 12515, 12521, 12522, 12527, 12530, 12532, 12535, + 12538, 12541, 12544, 12545, 12546, 12547, 12549, 16647, 16651, + 12559, 16658, 16662, 12569, 12574, 12579, 12582, 12583, 12584, + 12585, 12586, 12588, 16686, 16689, 12599, 12605, 12609, 12611, + 12612, 12615, 12616, 12617, 12618, 12620, 12621, 12626, 12629, + 12635, 12641, 12645, 12650, 12655, 16757, 16761, 12669, 12673, + 12679, 12684, 16782, 16786, 12695, 12699, 12703, 12707, 12713, + 12715, 12716, 12717, 12719, 12723, 12725, 8630, 12727, 12728, + 12730, 12732, 12733, 12734, 12735, 12736, 12737, 12738, 12740, + 12746, 12747, 12750, 12751, 12753, 12755, 12758, 12763, 12764, + 12770, 12772, 12775, 12779, 12782, 12786, 12788, 16886, 16891, + 12798, 12801, 12802, 12804, 12805, 12807, 12808, 12811, 12812, + 12813, 12814, 12815, 12820, 12822, 12827, 12830, 12832, 8741, + 8742, 12839, 12841, 8751, 8757, 12857, 12859, 12864, 12866, + 12870, 12874, 12876, 12879, 12884, 12887, 12891, 8799, 8802, + 8808, 8812, 8814, 12914, 12916, 12921, 12925, 12929, 12935, + 8841, 12939, 12942, 12943, 12945, 12947, 12950, 12953, 12955, + 12959, 12961, 12964, 12967, 12973, 12977, 12980, 12985, 12988, + 12993, 12998, 13001, 13005, 13008, 13012, 17112, 17116, 13023, + 13027, 13029, 13031, 13033, 13038, 8943, 13045, 13047, 13049, + 13051, 13056, 13058, 13060, 8966, 8972, 13069, 13070, 13071, + 13072, 13073, 13075, 13076, 13080, 13082, 13087, 13088, 13090, + 13093, 13096, 17194, 17197, 13105, 13107, 13110, 13113, 9018, + 9024, 13121, 13123, 13126, 13128, 13132, 13136, 13140, 13142, + 13145, 13147, 13149, 13151, 13154, 13156, 13160, 13164, 13167, + 13172, 13173, 13174, 13177, 13180, 13183, 9088, 9089, 9091, + 9094, 9095, 13194, 13195, 13196, 13198, 13202, 13206, 13210, + 13213, 13216, 13219, 13223, 13228, 9138, 9144, 9148, 9152, + 13253, 13254, 13255, 13256, 13259, 9164, 9165, 13265, 13266, + 13268, 13270, 13271, 13275, 9180, 13280, 13285, 13288, 13292, + 13295, 13300, 13304, 13309, 13314, 13318, 13322, 13326, 13330, + 13335, 13340, 13344, 9253, 9259, 13356, 13360, 13363, 13366, + 13372, 13373, 13379, 13382, 13387, 13389, 13393, 13394, 13396, + 13398, 13400, 13402, 13406, 13408, 13410, 13412, 13414, 13415, + 13419, 13421, 13424, 13427, 13432, 13436, 13440, 13444, 13448, + 13452, 13457, 9362, 13461, 13463, 13465, 13468, 13470, 13473, + 13475, 13477, 13480, 9387, 13485, 13489, 13491, 13492, 13496, + 9402, 9406, 13503, 13506, 9414, 9417, 9418, 9422, 9423, + 9424, 9427, 9428, 9433, 13534, 13540, 9447, 9448, 9449, + 9453, 9456, 9458, 13557, 13563, 13568, 13574, 13579, 13582, + 13586, 13591, 9500, 13600, 13604, 13609, 13614, 13619, 13624, + 13627, 13632, 13638, 13643, 13645, 17747, 17750, 17755, 17759, + 17764, 13672, 13674, 13677, 13679, 13681, 13685, 9592, 13689, + 13692, 13693, 13696, 13697, 13698, 13701, 13703, 13706, 13708, + 13711, 13713, 13715, 13718, 13721, 13723, 13728, 13729, 13732, + 13735, 13736, 13740, 13744, 13747, 13748, 13752, 13753, 13759, + 13762, 13763, 13765, 9670, 13767, 13773, 13778, 13783, 13788, + 13793, 13798, 13801, 13805, 13810, 13815, 13818, 13822, 13824, + 13828, 13831, 13835, 13839, 13843, 13847, 13853, 13856, 13862, + 13866, 13869, 17970, 17972, 13881, 13883, 13884, 13885, 13889, + 13895, 13899, 13904, 13906, 13911, 13915, 13919, 9827, 9832, + 13933, 13934, 13937, 13939, 13944, 13947, 13949, 13954, 13958, + 13963, 13964, 13969, 13970, 13975, 13978, 9883, 18078, 18084, + 13992, 13997, 14000, 14006, 14011, 14014, 14015, 14018, 14020, + 14024, 14026, 14029, 14032, 14038, 14040, 14044, 14046, 14050, + 9955, 14055, 14059, 14064, 14068, 14071, 14075, 14078, 14080, + 14085, 14088, 14091, 14093, 14095, 14099, 14101, 14104, 14108, + 14111, 14114, 14117, 14119, 14122, 14125, 14128, 18228, 18233, + 14142, 14145, 14151, 14153, 14159, 14160, 14165, 10072, 10078, + 10080, 14178, 14182, 14187, 14191, 10100, 10106, 10108, 10114, + 14211, 14217, 14223, 14228, 14234, 14239, 14245, 14250, 14253, + 14257, 14260, 14264, 14267, 14273, 14278, 14281, 14285, 14291, + 14293, 18394, 18399, 14305, 14310, 14315, 10224, 6134, 6140, + 2048, +}; diff --git a/hardware-wallet/firmware/firmware/recovery.c b/hardware-wallet/firmware/firmware/recovery.c new file mode 100644 index 00000000..b01e510c --- /dev/null +++ b/hardware-wallet/firmware/firmware/recovery.c @@ -0,0 +1,530 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * Copyright (C) 2016 Jochen Hoenicke + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include "recovery.h" +#include "fsm.h" +#include "storage.h" +#include "layout2.h" +#include "protect.h" +#include "types.pb.h" +#include "messages.h" +#include "rng.h" +#include "bip39.h" +#include "oled.h" +#include "usb.h" +#include "gettext.h" +#include "types.pb.h" +#include "recovery-table.h" +#include "memzero.h" + +/* number of words expected in the new seed */ +static uint32_t word_count; + +/* recovery mode: + * 0: not recovering + * 1: recover by scrambled plain text words + * 2: recover by matrix entry + */ +static int awaiting_word = 0; + +/* True if we should not write anything back to storage + * (can be used for testing seed for correctness). + */ +static bool dry_run; + +/* True if we should check that seed corresponds to bip39. + */ +static bool enforce_wordlist; + +/* For scrambled recovery Trezor may ask for faked words if + * seed is short. This contains the fake word. + */ +static char fake_word[12]; + +/* Word position in the seed that we are currently asking for. + * This is 0 if we ask for a fake word. Only for scrambled recovery. + */ +static uint32_t word_pos; + +/* Scrambled recovery: How many words has the user already entered. + * Matrix recovery: How many digits has the user already entered. + */ +static uint32_t word_index; + +/* Order in which we ask for the words. It holds that + * word_order[word_index] == word_pos. Only for scrambled recovery. + */ +static char word_order[24]; + +/* The recovered seed. This is filled during the recovery process. + */ +static char words[24][12]; + +/* The "pincode" of the current word. This is basically the "pin" + * that the user would have entered for the current word if the words + * were displayed in alphabetical order. Note that it is base 9, not + * base 10. Only for matrix recovery. + */ +static uint16_t word_pincode; + +/* The pinmatrix currently displayed on screen. + * Only for matrix recovery. + */ +static uint8_t word_matrix[9]; + +#define MASK_IDX(x) ((x) & 0xfff) +#define TABLE1(x) MASK_IDX(word_table1[x]) +#define TABLE2(x) MASK_IDX(word_table2[x]) + +/* Helper function to format a two digit number. + * Parameter dest is buffer containing the string. It should already + * start with "##th". The number is written in place. + * Parameter number gives the number that we should format. + */ +static void format_number(char *dest, int number) { + if (number < 10) { + dest[0] = ' '; + } else { + dest[0] = '0' + number / 10; + } + dest[1] = '0' + number % 10; + if (number == 1 || number == 21) { + dest[2] = 's'; dest[3] = 't'; + } else if (number == 2 || number == 22) { + dest[2] = 'n'; dest[3] = 'd'; + } else if (number == 3 || number == 23) { + dest[2] = 'r'; dest[3] = 'd'; + } +} + +/* Send a request for a new word/matrix code to the PC. + */ +static void recovery_request(void) { + WordRequest resp; + memset(&resp, 0, sizeof(WordRequest)); + resp.has_type = true; + resp.type = awaiting_word == 1 ? WordRequestType_WordRequestType_Plain + : (word_index % 4 == 3) ? WordRequestType_WordRequestType_Matrix6 + : WordRequestType_WordRequestType_Matrix9; + msg_write(MessageType_MessageType_WordRequest, &resp); +} + +/* Called when the last word was entered. + * Check mnemonic and send success/failure. + */ +static void recovery_done(void) { + char new_mnemonic[241] = {0}; // TODO: remove constant + + strlcpy(new_mnemonic, words[0], sizeof(new_mnemonic)); + for (uint32_t i = 1; i < word_count; i++) { + strlcat(new_mnemonic, " ", sizeof(new_mnemonic)); + strlcat(new_mnemonic, words[i], sizeof(new_mnemonic)); + } + if (!enforce_wordlist || mnemonic_check(new_mnemonic)) { + // New mnemonic is valid. + if (!dry_run) { + // Update mnemonic on storage. + storage_setMnemonic(new_mnemonic); + memzero(new_mnemonic, sizeof(new_mnemonic)); + if (!enforce_wordlist) { + // not enforcing => mark storage as imported + storage_setImported(true); + } + storage_update(); + fsm_sendSuccess(_("Device recovered")); + } else { + // Inform the user about new mnemonic correctness (as well as whether it is the same as the current one). + bool match = (storage_isInitialized() && storage_containsMnemonic(new_mnemonic)); + memzero(new_mnemonic, sizeof(new_mnemonic)); + if (match) { + layoutDialog(&bmp_icon_ok, NULL, _("Confirm"), NULL, + _("The seed is valid"), + _("and MATCHES"), + _("the one in the device."), NULL, NULL, NULL); + protectButton(ButtonRequestType_ButtonRequest_Other, true); + fsm_sendSuccess(_("The seed is valid and matches the one in the device")); + } else { + layoutDialog(&bmp_icon_error, NULL, _("Confirm"), NULL, + _("The seed is valid"), + _("but does NOT MATCH"), + _("the one in the device."), NULL, NULL, NULL); + protectButton(ButtonRequestType_ButtonRequest_Other, true); + fsm_sendFailure(FailureType_Failure_DataError, + _("The seed is valid but does not match the one in the device")); + } + } + } else { + // New mnemonic is invalid. + memzero(new_mnemonic, sizeof(new_mnemonic)); + if (!dry_run) { + session_clear(true); + } else { + layoutDialog(&bmp_icon_error, NULL, _("Confirm"), NULL, + _("The seed is"), _("INVALID!"), NULL, NULL, NULL, NULL); + protectButton(ButtonRequestType_ButtonRequest_Other, true); + } + fsm_sendFailure(FailureType_Failure_DataError, _("Invalid seed, are words in correct order?")); + } + awaiting_word = 0; + layoutHome(); +} + +/* Helper function for matrix recovery: + * Formats a string describing the word range from first to last where + * prefixlen gives the number of characters in first and last that are + * significant, i.e. the word before first or the word after last differ + * exactly at the prefixlen-th character. + * + * Invariants: + * memcmp("first - 1", first, prefixlen) != 0 + * memcmp(last, "last + 1", prefixlen) != 0 + * first[prefixlen-2] == last[prefixlen-2] except for range WI-Z. + */ +static void add_choice(char choice[12], int prefixlen, const char *first, const char *last) { + // assert prefixlen < 4 + char *dest = choice; + for (int i = 0; i < prefixlen; i++) { + *dest++ = toupper((int) first[i]); + } + if (first[0] != last[0]) { + /* special case WI-Z; also used for T-Z, etc. */ + *dest++ = '-'; + *dest++ = toupper((int) last[0]); + } else if (last[prefixlen-1] == first[prefixlen-1]) { + /* single prefix */ + } else if (prefixlen < 3) { + /* AB-AC, etc. */ + *dest++ = '-'; + for (int i = 0; i < prefixlen; i++) { + *dest++ = toupper((int) last[i]); + } + } else { + /* RE[A-M] etc. */ + /* remove last and replace with space */ + dest[-1] = ' '; + if (first[prefixlen - 1]) { + /* handle special case: CAN[-D] */ + *dest++ = toupper((int)first[prefixlen - 1]); + } + *dest++ = '-'; + *dest++ = toupper((int) last[prefixlen - 1]); + } + *dest++ = 0; +} + +/* Helper function for matrix recovery: + * Display the recovery matrix given in choices. If twoColumn is set + * use 2x3 layout, otherwise 3x3 layout. Also generates a random + * scrambling and stores it in word_matrix. + */ +static void display_choices(bool twoColumn, char choices[9][12], int num) +{ + const int nColumns = twoColumn ? 2 : 3; + const int displayedChoices = nColumns * 3; + for (int i = 0; i < displayedChoices; i++) { + word_matrix[i] = i; + } + /* scramble matrix */ + random_permute((char*)word_matrix, displayedChoices); + + if (word_index % 4 == 0) { + char desc[] = "##th word"; + int nr = (word_index / 4) + 1; + format_number(desc, nr); + layoutDialogSwipe(&bmp_icon_info, NULL, NULL, NULL, _("Please enter the"), (nr < 10 ? desc + 1 : desc), _("of your mnemonic"), NULL, NULL, NULL); + } else { + oledBox(0, 27, 127, 63, false); + } + + for (int row = 0; row < 3; row ++) { + int y = 55 - row * 11; + for (int col = 0; col < nColumns; col++) { + int x = twoColumn ? 64 * col + 32 : 42 * col + 22; + int choice = word_matrix[nColumns*row + col]; + const char *text = choice < num ? choices[choice] : "-"; + oledDrawString(x - oledStringWidth(text, FONT_STANDARD)/2, y, text, FONT_STANDARD); + if (twoColumn) { + oledInvert(x - 32 + 1, y - 1, x - 32 + 63 - 1, y + 8); + } else { + oledInvert(x - 22 + 1, y - 1, x - 22 + 41 - 1, y + 8); + } + } + } + oledRefresh(); + + /* avoid picking out of range numbers */ + for (int i = 0; i < displayedChoices; i++) { + if (word_matrix[i] > num) + word_matrix[i] = 0; + } + /* two column layout: middle column = right column */ + if (twoColumn) { + static const uint8_t twolayout[9] = { 0, 1, 1, 2, 3, 3, 4, 5, 5 }; + for (int i = 8; i >= 2; i--) { + word_matrix[i] = word_matrix[twolayout[i]]; + } + } +} + +/* Helper function for matrix recovery: + * Generates a new matrix and requests the next pin. + */ +static void next_matrix(void) { + const char * const *wl = mnemonic_wordlist(); + char word_choices[9][12]; + uint32_t idx, num; + bool last = (word_index % 4) == 3; + + switch (word_index % 4) { + case 3: + idx = TABLE1(word_pincode / 9) + word_pincode % 9; + const uint32_t first = word_table2[idx] & 0xfff; + num = (word_table2[idx + 1] & 0xfff) - first; + for (uint32_t i = 0; i < num; i++) { + strlcpy(word_choices[i], wl[first + i], sizeof(word_choices[i])); + } + break; + + case 2: + idx = TABLE1(word_pincode); + num = TABLE1(word_pincode + 1) - idx; + for (uint32_t i = 0; i < num; i++) { + add_choice(word_choices[i], (word_table2[idx + i] >> 12), + wl[TABLE2(idx + i)], + wl[TABLE2(idx + i + 1) - 1]); + } + break; + + case 1: + idx = word_pincode * 9; + num = 9; + for (uint32_t i = 0; i < num; i++) { + add_choice(word_choices[i], (word_table1[idx + i] >> 12), + wl[TABLE2(TABLE1(idx + i))], + wl[TABLE2(TABLE1(idx + i + 1)) - 1]); + } + break; + + case 0: + num = 9; + for (uint32_t i = 0; i < num; i++) { + add_choice(word_choices[i], 1, + wl[TABLE2(TABLE1(9*i))], + wl[TABLE2(TABLE1(9*(i+1)))-1]); + } + break; + } + display_choices(last, word_choices, num); + + recovery_request(); +} + +/* Function called when a digit was entered by user. + * digit: ascii code of the entered digit ('1'-'9') or + * '\x08' for backspace. + */ +static void recovery_digit(const char digit) { + if (digit == 8) { + /* backspace: undo */ + if ((word_index % 4) == 0) { + /* undo complete word */ + if (word_index > 0) + word_index -= 4; + } else { + word_index--; + word_pincode /= 9; + } + next_matrix(); + return; + } + + if (digit < '1' || digit > '9') { + recovery_request(); + return; + } + + int choice = word_matrix[digit - '1']; + if ((word_index % 4) == 3) { + /* received final word */ + int y = 54 - ((digit - '1')/3)*11; + int x = 64 * (((digit - '1') % 3) > 0); + oledInvert(x + 1, y, x + 62, y + 9); + oledRefresh(); + usbSleep(250); + + int idx = TABLE2(TABLE1(word_pincode / 9) + (word_pincode % 9)) + choice; + uint32_t widx = word_index / 4; + + word_pincode = 0; + strlcpy(words[widx], mnemonic_wordlist()[idx], sizeof(words[widx])); + if (widx + 1 == word_count) { + recovery_done(); + return; + } + /* next word */ + } else { + word_pincode = word_pincode * 9 + choice; + } + word_index++; + next_matrix(); +} + +/* Helper function for scrambled recovery: + * Ask the user for the next word. + */ +void next_word(void) { + word_pos = word_order[word_index]; + if (word_pos == 0) { + const char * const *wl = mnemonic_wordlist(); + strlcpy(fake_word, wl[random_uniform(2048)], sizeof(fake_word)); + layoutDialogSwipe(&bmp_icon_info, NULL, NULL, NULL, _("Please enter the word"), NULL, fake_word, NULL, _("on your computer"), NULL); + } else { + fake_word[0] = 0; + char desc[] = "##th word"; + format_number(desc, word_pos); + layoutDialogSwipe(&bmp_icon_info, NULL, NULL, NULL, _("Please enter the"), NULL, (word_pos < 10 ? desc + 1 : desc), NULL, _("of your mnemonic"), NULL); + } + recovery_request(); +} + +void recovery_init(uint32_t _word_count, bool passphrase_protection, bool pin_protection, const char *language, const char *label, bool _enforce_wordlist, uint32_t type, uint32_t u2f_counter, bool _dry_run) +{ + if (_word_count != 12 && _word_count != 18 && _word_count != 24) return; + + word_count = _word_count; + enforce_wordlist = _enforce_wordlist; + dry_run = _dry_run; + + if (!dry_run) { + if (pin_protection && !protectChangePin()) { + fsm_sendFailure(FailureType_Failure_PinMismatch, NULL); + layoutHome(); + return; + } + + storage_setPassphraseProtection(passphrase_protection); + storage_setLanguage(language); + storage_setLabel(label); + storage_setU2FCounter(u2f_counter); + storage_update(); + } + + if ((type & RecoveryDeviceType_RecoveryDeviceType_Matrix) != 0) { + awaiting_word = 2; + word_index = 0; + next_matrix(); + } else { + for (uint32_t i = 0; i < word_count; i++) { + word_order[i] = i + 1; + } + for (uint32_t i = word_count; i < 24; i++) { + word_order[i] = 0; + } + random_permute(word_order, 24); + awaiting_word = 1; + word_index = 0; + next_word(); + } +} + +static void recovery_scrambledword(const char *word) +{ + if (word_pos == 0) { // fake word + if (strcmp(word, fake_word) != 0) { + if (!dry_run) { + session_clear(true); + } + fsm_sendFailure(FailureType_Failure_ProcessError, _("Wrong word retyped")); + layoutHome(); + return; + } + } else { // real word + if (enforce_wordlist) { // check if word is valid + const char * const *wl = mnemonic_wordlist(); + bool found = false; + while (*wl) { + if (strcmp(word, *wl) == 0) { + found = true; + break; + } + wl++; + } + if (!found) { + if (!dry_run) { + session_clear(true); + } + fsm_sendFailure(FailureType_Failure_DataError, _("Word not found in a wordlist")); + layoutHome(); + return; + } + } + strlcpy(words[word_pos - 1], word, sizeof(words[word_pos - 1])); + } + + if (word_index + 1 == 24) { // last one + recovery_done(); + } else { + word_index++; + next_word(); + } +} + +/* Function called when a word was entered by user. Used + * for scrambled recovery. + */ +void recovery_word(const char *word) +{ + switch (awaiting_word) { + case 2: + recovery_digit(word[0]); + break; + case 1: + recovery_scrambledword(word); + break; + default: + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Not in Recovery mode")); + break; + } +} + +/* Abort recovery. + */ +void recovery_abort(void) +{ + if (awaiting_word) { + layoutHome(); + awaiting_word = 0; + } +} + +#if DEBUG_LINK + +const char *recovery_get_fake_word(void) +{ + return fake_word; +} + +uint32_t recovery_get_word_pos(void) +{ + return word_pos; +} + +#endif diff --git a/hardware-wallet/firmware/firmware/recovery.h b/hardware-wallet/firmware/firmware/recovery.h new file mode 100644 index 00000000..d0a63508 --- /dev/null +++ b/hardware-wallet/firmware/firmware/recovery.h @@ -0,0 +1,32 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __RECOVERY_H__ +#define __RECOVERY_H__ + +#include +#include + +void recovery_init(uint32_t _word_count, bool passphrase_protection, bool pin_protection, const char *language, const char *label, bool _enforce_wordlist, uint32_t type, uint32_t u2f_counter, bool _dry_run); +void recovery_word(const char *word); +void recovery_abort(void); +const char *recovery_get_fake_word(void); +uint32_t recovery_get_word_pos(void); + +#endif diff --git a/hardware-wallet/firmware/firmware/reset.c b/hardware-wallet/firmware/firmware/reset.c new file mode 100644 index 00000000..e44370ee --- /dev/null +++ b/hardware-wallet/firmware/firmware/reset.c @@ -0,0 +1,171 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "reset.h" +#include "storage.h" +#include "rng.h" +#include "sha2.h" +#include "messages.h" +#include "fsm.h" +#include "layout2.h" +#include "types.pb.h" +#include "protect.h" +#include "bip39.h" +#include "util.h" +#include "gettext.h" + +static uint32_t strength; +static uint8_t int_entropy[32]; +static bool awaiting_entropy = false; +static bool skip_backup = false; + +void reset_init(bool display_random, uint32_t _strength, bool passphrase_protection, bool pin_protection, const char *language, const char *label, uint32_t u2f_counter, bool _skip_backup) +{ + if (_strength != 128 && _strength != 192 && _strength != 256) return; + + strength = _strength; + skip_backup = _skip_backup; + + random_buffer(int_entropy, 32); + + char ent_str[4][17]; + data2hex(int_entropy , 8, ent_str[0]); + data2hex(int_entropy + 8, 8, ent_str[1]); + data2hex(int_entropy + 16, 8, ent_str[2]); + data2hex(int_entropy + 24, 8, ent_str[3]); + + if (display_random) { + layoutDialogSwipe(&bmp_icon_info, _("Cancel"), _("Continue"), NULL, _("Internal entropy:"), ent_str[0], ent_str[1], ent_str[2], ent_str[3], NULL); + if (!protectButton(ButtonRequestType_ButtonRequest_ResetDevice, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + } + + if (pin_protection && !protectChangePin()) { + fsm_sendFailure(FailureType_Failure_PinMismatch, NULL); + layoutHome(); + return; + } + + storage_setPassphraseProtection(passphrase_protection); + storage_setLanguage(language); + storage_setLabel(label); + storage_setU2FCounter(u2f_counter); + storage_update(); + + EntropyRequest resp; + memset(&resp, 0, sizeof(EntropyRequest)); + msg_write(MessageType_MessageType_EntropyRequest, &resp); + awaiting_entropy = true; +} + +void reset_entropy(const uint8_t *ext_entropy, uint32_t len) +{ + if (!awaiting_entropy) { + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Not in Reset mode")); + return; + } + SHA256_CTX ctx; + sha256_Init(&ctx); + sha256_Update(&ctx, int_entropy, 32); + sha256_Update(&ctx, ext_entropy, len); + sha256_Final(&ctx, int_entropy); + storage_setNeedsBackup(true); + storage_setMnemonic(mnemonic_from_data(int_entropy, strength / 8)); + memset(int_entropy, 0, 32); + awaiting_entropy = false; + + if (skip_backup) { + storage_update(); + fsm_sendSuccess(_("Device successfully initialized")); + layoutHome(); + } else { + reset_backup(false); + } + +} + +static char current_word[10]; + +// separated == true if called as a separate workflow via BackupMessage +void reset_backup(bool separated) +{ + if (!storage_needsBackup()) { + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Seed already backed up")); + return; + } + + storage_setNeedsBackup(false); + + if (separated) { + storage_update(); + } + + const char *mnemonic = storage_getMnemonic(); + + for (int pass = 0; pass < 2; pass++) { + int i = 0, word_pos = 1; + while (mnemonic[i] != 0) { + // copy current_word + int j = 0; + while (mnemonic[i] != ' ' && mnemonic[i] != 0 && j + 1 < (int)sizeof(current_word)) { + current_word[j] = mnemonic[i]; + i++; j++; + } + current_word[j] = 0; + if (mnemonic[i] != 0) { + i++; + } + layoutResetWord(current_word, pass, word_pos, mnemonic[i] == 0); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmWord, true)) { + if (!separated) { + storage_clear_update(); + session_clear(true); + } + layoutHome(); + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + return; + } + word_pos++; + } + } + + if (separated) { + fsm_sendSuccess(_("Seed successfully backed up")); + } else { + storage_update(); + fsm_sendSuccess(_("Device successfully initialized")); + } + layoutHome(); +} + +#if DEBUG_LINK + +uint32_t reset_get_int_entropy(uint8_t *entropy) { + memcpy(entropy, int_entropy, 32); + return 32; +} + +const char *reset_get_word(void) { + return current_word; +} + +#endif diff --git a/hardware-wallet/firmware/firmware/reset.h b/hardware-wallet/firmware/firmware/reset.h new file mode 100644 index 00000000..a4c54c5a --- /dev/null +++ b/hardware-wallet/firmware/firmware/reset.h @@ -0,0 +1,32 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __RESET_H__ +#define __RESET_H__ + +#include +#include + +void reset_init(bool display_random, uint32_t _strength, bool passphrase_protection, bool pin_protection, const char *language, const char *label, uint32_t u2f_counter, bool skip_backup); +void reset_entropy(const uint8_t *ext_entropy, uint32_t len); +void reset_backup(bool separated); +uint32_t reset_get_int_entropy(uint8_t *entropy); +const char *reset_get_word(void); + +#endif diff --git a/hardware-wallet/firmware/firmware/signing.c b/hardware-wallet/firmware/firmware/signing.c new file mode 100644 index 00000000..3c700340 --- /dev/null +++ b/hardware-wallet/firmware/firmware/signing.c @@ -0,0 +1,1161 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "signing.h" +#include "fsm.h" +#include "layout2.h" +#include "messages.h" +#include "transaction.h" +#include "ecdsa.h" +#include "protect.h" +#include "crypto.h" +#include "secp256k1.h" +#include "gettext.h" + +static uint32_t inputs_count; +static uint32_t outputs_count; +static const CoinInfo *coin; +static const HDNode *root; +static CONFIDENTIAL HDNode node; +static bool signing = false; +enum { + STAGE_REQUEST_1_INPUT, + STAGE_REQUEST_2_PREV_META, + STAGE_REQUEST_2_PREV_INPUT, + STAGE_REQUEST_2_PREV_OUTPUT, + STAGE_REQUEST_2_PREV_EXTRADATA, + STAGE_REQUEST_3_OUTPUT, + STAGE_REQUEST_4_INPUT, + STAGE_REQUEST_4_OUTPUT, + STAGE_REQUEST_SEGWIT_INPUT, + STAGE_REQUEST_5_OUTPUT, + STAGE_REQUEST_SEGWIT_WITNESS +} signing_stage; +static uint32_t idx1, idx2; +static uint32_t signatures; +static TxRequest resp; +static TxInputType input; +static TxOutputBinType bin_output; +static TxStruct to, tp, ti; +static Hasher hashers[3]; +static uint8_t CONFIDENTIAL privkey[32]; +static uint8_t pubkey[33], sig[64]; +static uint8_t hash_prevouts[32], hash_sequence[32],hash_outputs[32]; +static uint8_t hash_check[32]; +static uint64_t to_spend, authorized_amount, spending, change_spend; +static uint32_t version = 1; +static uint32_t lock_time = 0; +static uint32_t next_nonsegwit_input; +static uint32_t progress, progress_step, progress_meta_step; +static bool multisig_fp_set, multisig_fp_mismatch; +static uint8_t multisig_fp[32]; +static uint32_t in_address_n[8]; +static size_t in_address_n_count; +static uint32_t tx_weight; + +/* A marker for in_address_n_count to indicate a mismatch in bip32 paths in + input */ +#define BIP32_NOCHANGEALLOWED 1 +/* The number of bip32 levels used in a wallet (chain and address) */ +#define BIP32_WALLET_DEPTH 2 +/* The chain id used for change */ +#define BIP32_CHANGE_CHAIN 1 +/* The maximum allowed change address. This should be large enough for normal + use and still allow to quickly brute-force the correct bip32 path. */ +#define BIP32_MAX_LAST_ELEMENT 1000000 + +/* transaction header size: 4 byte version */ +#define TXSIZE_HEADER 4 +/* transaction footer size: 4 byte lock time */ +#define TXSIZE_FOOTER 4 +/* transaction segwit overhead 2 marker */ +#define TXSIZE_SEGWIT_OVERHEAD 2 + +enum { + SIGHASH_ALL = 1, + SIGHASH_FORKID = 0x40, +}; + + +/* progress_step/meta_step are fixed point numbers, giving the + * progress per input in permille with these many additional bits. + */ +#define PROGRESS_PRECISION 16 + +/* + +Workflow of streamed signing +The STAGE_ constants describe the signing_stage when request is sent. + +I - input +O - output + +Phase1 - check inputs, previous transactions, and outputs + - ask for confirmations + - check fee +========================================================= + +foreach I (idx1): + Request I STAGE_REQUEST_1_INPUT + Add I to segwit hash_prevouts, hash_sequence + Add I to TransactionChecksum (prevout and type) + If not segwit, Calculate amount of I: + Request prevhash I, META STAGE_REQUEST_2_PREV_META + foreach prevhash I (idx2): + Request prevhash I STAGE_REQUEST_2_PREV_INPUT + foreach prevhash O (idx2): + Request prevhash O STAGE_REQUEST_2_PREV_OUTPUT + Add amount of prevhash O (which is amount of I) + Request prevhash extra data (if applicable) STAGE_REQUEST_2_PREV_EXTRADATA + Calculate hash of streamed tx, compare to prevhash I +foreach O (idx1): + Request O STAGE_REQUEST_3_OUTPUT + Add O to TransactionChecksum + Display output + Ask for confirmation + +Check tx fee +Ask for confirmation + +Phase2: sign inputs, check that nothing changed +=============================================== + +foreach I (idx1): // input to sign + if (idx1 is segwit) + Request I STAGE_REQUEST_SEGWIT_INPUT + Return serialized input chunk + + else + foreach I (idx2): + Request I STAGE_REQUEST_4_INPUT + If idx1 == idx2 + Remember key for signing + Fill scriptsig + Add I to StreamTransactionSign + Add I to TransactionChecksum + foreach O (idx2): + Request O STAGE_REQUEST_4_OUTPUT + Add O to StreamTransactionSign + Add O to TransactionChecksum + + Compare TransactionChecksum with checksum computed in Phase 1 + If different: + Failure + Sign StreamTransactionSign + Return signed chunk + +foreach O (idx1): + Request O STAGE_REQUEST_5_OUTPUT + Rewrite change address + Return O + + +Phase3: sign segwit inputs, check that nothing changed +=============================================== + +foreach I (idx1): // input to sign + Request I STAGE_REQUEST_SEGWIT_WITNESS + Check amount + Sign segwit prevhash, sequence, amount, outputs + Return witness +*/ + +void send_req_1_input(void) +{ + signing_stage = STAGE_REQUEST_1_INPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXINPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx1; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_2_prev_meta(void) +{ + signing_stage = STAGE_REQUEST_2_PREV_META; + resp.has_request_type = true; + resp.request_type = RequestType_TXMETA; + resp.has_details = true; + resp.details.has_tx_hash = true; + resp.details.tx_hash.size = input.prev_hash.size; + memcpy(resp.details.tx_hash.bytes, input.prev_hash.bytes, input.prev_hash.size); + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_2_prev_input(void) +{ + signing_stage = STAGE_REQUEST_2_PREV_INPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXINPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx2; + resp.details.has_tx_hash = true; + resp.details.tx_hash.size = input.prev_hash.size; + memcpy(resp.details.tx_hash.bytes, input.prev_hash.bytes, resp.details.tx_hash.size); + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_2_prev_output(void) +{ + signing_stage = STAGE_REQUEST_2_PREV_OUTPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXOUTPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx2; + resp.details.has_tx_hash = true; + resp.details.tx_hash.size = input.prev_hash.size; + memcpy(resp.details.tx_hash.bytes, input.prev_hash.bytes, resp.details.tx_hash.size); + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_2_prev_extradata(uint32_t chunk_offset, uint32_t chunk_len) +{ + signing_stage = STAGE_REQUEST_2_PREV_EXTRADATA; + resp.has_request_type = true; + resp.request_type = RequestType_TXEXTRADATA; + resp.has_details = true; + resp.details.has_extra_data_offset = true; + resp.details.extra_data_offset = chunk_offset; + resp.details.has_extra_data_len = true; + resp.details.extra_data_len = chunk_len; + resp.details.has_tx_hash = true; + resp.details.tx_hash.size = input.prev_hash.size; + memcpy(resp.details.tx_hash.bytes, input.prev_hash.bytes, resp.details.tx_hash.size); + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_3_output(void) +{ + signing_stage = STAGE_REQUEST_3_OUTPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXOUTPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx1; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_4_input(void) +{ + signing_stage = STAGE_REQUEST_4_INPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXINPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx2; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_4_output(void) +{ + signing_stage = STAGE_REQUEST_4_OUTPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXOUTPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx2; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_segwit_input(void) +{ + signing_stage = STAGE_REQUEST_SEGWIT_INPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXINPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx1; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_segwit_witness(void) +{ + signing_stage = STAGE_REQUEST_SEGWIT_WITNESS; + resp.has_request_type = true; + resp.request_type = RequestType_TXINPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx1; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_5_output(void) +{ + signing_stage = STAGE_REQUEST_5_OUTPUT; + resp.has_request_type = true; + resp.request_type = RequestType_TXOUTPUT; + resp.has_details = true; + resp.details.has_request_index = true; + resp.details.request_index = idx1; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void send_req_finished(void) +{ + resp.has_request_type = true; + resp.request_type = RequestType_TXFINISHED; + msg_write(MessageType_MessageType_TxRequest, &resp); +} + +void phase1_request_next_input(void) +{ + if (idx1 < inputs_count - 1) { + idx1++; + send_req_1_input(); + } else { + // compute segwit hashPrevouts & hashSequence + hasher_Double(&hashers[0], hash_prevouts); + hasher_Double(&hashers[1], hash_sequence); + hasher_Final(&hashers[2], hash_check); + // init hashOutputs + hasher_Reset(&hashers[0]); + idx1 = 0; + send_req_3_output(); + } +} + +void phase2_request_next_input(void) +{ + if (idx1 == next_nonsegwit_input) { + idx2 = 0; + send_req_4_input(); + } else { + send_req_segwit_input(); + } +} + +void extract_input_bip32_path(const TxInputType *tinput) +{ + if (in_address_n_count == BIP32_NOCHANGEALLOWED) { + return; + } + size_t count = tinput->address_n_count; + if (count < BIP32_WALLET_DEPTH) { + // no change address allowed + in_address_n_count = BIP32_NOCHANGEALLOWED; + return; + } + if (in_address_n_count == 0) { + // initialize in_address_n on first input seen + in_address_n_count = count; + // store the bip32 path up to the account + memcpy(in_address_n, tinput->address_n, + (count - BIP32_WALLET_DEPTH) * sizeof(uint32_t)); + return; + } + // check that all addresses use a path of same length + if (in_address_n_count != count) { + in_address_n_count = BIP32_NOCHANGEALLOWED; + return; + } + // check that the bip32 path up to the account matches + if (memcmp(in_address_n, tinput->address_n, + (count - BIP32_WALLET_DEPTH) * sizeof(uint32_t)) != 0) { + // mismatch -> no change address allowed + in_address_n_count = BIP32_NOCHANGEALLOWED; + return; + } +} + +bool check_change_bip32_path(const TxOutputType *toutput) +{ + size_t count = toutput->address_n_count; + + // Check that the change path has the same bip32 path length, + // the same path up to the account, and that the wallet components + // (chain id and address) are as expected. + // Note: count >= BIP32_WALLET_DEPTH and count == in_address_n_count + // imply that in_address_n_count != BIP32_NOCHANGEALLOWED + return (count >= BIP32_WALLET_DEPTH + && count == in_address_n_count + && 0 == memcmp(in_address_n, toutput->address_n, + (count - BIP32_WALLET_DEPTH) * sizeof(uint32_t)) + && toutput->address_n[count - 2] <= BIP32_CHANGE_CHAIN + && toutput->address_n[count - 1] <= BIP32_MAX_LAST_ELEMENT); +} + +bool compile_input_script_sig(TxInputType *tinput) +{ + if (!multisig_fp_mismatch) { + // check that this is still multisig + uint8_t h[32]; + if (!tinput->has_multisig + || cryptoMultisigFingerprint(&(tinput->multisig), h) == 0 + || memcmp(multisig_fp, h, 32) != 0) { + // Transaction has changed during signing + return false; + } + } + if (in_address_n_count != BIP32_NOCHANGEALLOWED) { + // check that input address didn't change + size_t count = tinput->address_n_count; + if (count < 2 + || count != in_address_n_count + || 0 != memcmp(in_address_n, tinput->address_n, (count - 2) * sizeof(uint32_t))) { + return false; + } + } + memcpy(&node, root, sizeof(HDNode)); + if (hdnode_private_ckd_cached(&node, tinput->address_n, tinput->address_n_count, NULL) == 0) { + // Failed to derive private key + return false; + } + hdnode_fill_public_key(&node); + if (tinput->has_multisig) { + tinput->script_sig.size = compile_script_multisig(&(tinput->multisig), tinput->script_sig.bytes); + } else { // SPENDADDRESS + uint8_t hash[20]; + ecdsa_get_pubkeyhash(node.public_key, coin->curve->hasher_type, hash); + tinput->script_sig.size = compile_script_sig(coin->address_type, hash, tinput->script_sig.bytes); + } + return tinput->script_sig.size > 0; +} + +void signing_init(uint32_t _inputs_count, uint32_t _outputs_count, const CoinInfo *_coin, const HDNode *_root, uint32_t _version, uint32_t _lock_time) +{ + inputs_count = _inputs_count; + outputs_count = _outputs_count; + coin = _coin; + root = _root; + version = _version; + lock_time = _lock_time; + + tx_weight = 4 * (TXSIZE_HEADER + TXSIZE_FOOTER + + ser_length_size(inputs_count) + + ser_length_size(outputs_count)); + + signatures = 0; + idx1 = 0; + to_spend = 0; + spending = 0; + change_spend = 0; + authorized_amount = 0; + memset(&input, 0, sizeof(TxInputType)); + memset(&resp, 0, sizeof(TxRequest)); + + signing = true; + progress = 0; + // we step by 500/inputs_count per input in phase1 and phase2 + // this means 50 % per phase. + progress_step = (500 << PROGRESS_PRECISION) / inputs_count; + + in_address_n_count = 0; + multisig_fp_set = false; + multisig_fp_mismatch = false; + next_nonsegwit_input = 0xffffffff; + + tx_init(&to, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); + // segwit hashes for hashPrevouts and hashSequence + hasher_Init(&hashers[0], coin->curve->hasher_type); + hasher_Init(&hashers[1], coin->curve->hasher_type); + hasher_Init(&hashers[2], coin->curve->hasher_type); + + layoutProgressSwipe(_("Signing transaction"), 0); + + send_req_1_input(); +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +static bool signing_check_input(TxInputType *txinput) { + /* compute multisig fingerprint */ + /* (if all input share the same fingerprint, outputs having the same fingerprint will be considered as change outputs) */ + if (txinput->has_multisig && !multisig_fp_mismatch) { + uint8_t h[32]; + if (cryptoMultisigFingerprint(&txinput->multisig, h) == 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Error computing multisig fingerprint")); + signing_abort(); + return false; + } + if (multisig_fp_set) { + if (memcmp(multisig_fp, h, 32) != 0) { + multisig_fp_mismatch = true; + } + } else { + memcpy(multisig_fp, h, 32); + multisig_fp_set = true; + } + } else { // single signature + multisig_fp_mismatch = true; + } + // remember the input bip32 path + // change addresses must use the same bip32 path as all inputs + extract_input_bip32_path(txinput); + // compute segwit hashPrevouts & hashSequence + tx_prevout_hash(&hashers[0], txinput); + tx_sequence_hash(&hashers[1], txinput); + // hash prevout and script type to check it later (relevant for fee computation) + tx_prevout_hash(&hashers[2], txinput); + hasher_Update(&hashers[2], (const uint8_t *) &txinput->script_type, sizeof(&txinput->script_type)); + return true; +} + +// check if the hash of the prevtx matches +static bool signing_check_prevtx_hash(void) { + uint8_t hash[32]; + tx_hash_final(&tp, hash, true); + if (memcmp(hash, input.prev_hash.bytes, 32) != 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Encountered invalid prevhash")); + signing_abort(); + return false; + } + phase1_request_next_input(); + return true; +} + +static bool signing_check_output(TxOutputType *txoutput) { + // Phase1: Check outputs + // add it to hash_outputs + // ask user for permission + + // check for change address + bool is_change = false; + if (txoutput->address_n_count > 0) { + if (txoutput->has_address) { + fsm_sendFailure(FailureType_Failure_DataError, _("Address in change output")); + signing_abort(); + return false; + } + /* + * For multisig check that all inputs are multisig + */ + if (txoutput->has_multisig) { + uint8_t h[32]; + if (multisig_fp_set && !multisig_fp_mismatch + && cryptoMultisigFingerprint(&(txoutput->multisig), h) + && memcmp(multisig_fp, h, 32) == 0) { + is_change = check_change_bip32_path(txoutput); + } + } else { + is_change = check_change_bip32_path(txoutput); + } + /* + * only allow segwit change if amount is smaller than what segwit inputs paid. + * this was added during the times segwit was not yet fully activated + * to make sure the user is not tricked to use witness change output + * instead of regular one therefore creating ANYONECANSPEND output + */ + if ((txoutput->script_type == OutputScriptType_PAYTOWITNESS + || txoutput->script_type == OutputScriptType_PAYTOP2SHWITNESS) + && txoutput->amount > authorized_amount) { + is_change = false; + } + } + + if (is_change) { + if (change_spend == 0) { // not set + change_spend = txoutput->amount; + } else { + /* We only skip confirmation for the first change output */ + is_change = false; + } + } + + if (spending + txoutput->amount < spending) { + fsm_sendFailure(FailureType_Failure_DataError, _("Value overflow")); + signing_abort(); + return false; + } + spending += txoutput->amount; + int co = compile_output(coin, root, txoutput, &bin_output, !is_change); + if (!is_change) { + layoutProgress(_("Signing transaction"), progress); + } + if (co < 0) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + signing_abort(); + return false; + } else if (co == 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile output")); + signing_abort(); + return false; + } + // compute segwit hashOuts + tx_output_hash(&hashers[0], &bin_output); + return true; +} + +static bool signing_check_fee(void) { + // check fees + if (spending > to_spend) { + fsm_sendFailure(FailureType_Failure_NotEnoughFunds, _("Not enough funds")); + signing_abort(); + return false; + } + uint64_t fee = to_spend - spending; + if (fee > ((uint64_t) tx_weight * coin->maxfee_kb)/4000) { + layoutFeeOverThreshold(coin, fee); + if (!protectButton(ButtonRequestType_ButtonRequest_FeeOverThreshold, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + signing_abort(); + return false; + } + } + // last confirmation + layoutConfirmTx(coin, to_spend - change_spend, fee); + if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + signing_abort(); + return false; + } + return true; +} + +static uint32_t signing_hash_type(void) { + uint32_t hash_type = SIGHASH_ALL; + + if (coin->has_forkid) { + hash_type |= (coin->forkid << 8) | SIGHASH_FORKID; + } + + return hash_type; +} + +static void phase1_request_next_output(void) { + if (idx1 < outputs_count - 1) { + idx1++; + send_req_3_output(); + } else { + hasher_Double(&hashers[0], hash_outputs); + if (!signing_check_fee()) { + return; + } + // Everything was checked, now phase 2 begins and the transaction is signed. + progress_meta_step = progress_step / (inputs_count + outputs_count); + layoutProgress(_("Signing transaction"), progress); + idx1 = 0; + phase2_request_next_input(); + } +} + +static void signing_hash_bip143(const TxInputType *txinput, uint8_t *hash) { + uint32_t hash_type = signing_hash_type(); + hasher_Reset(&hashers[0]); + hasher_Update(&hashers[0], (const uint8_t *)&version, 4); + hasher_Update(&hashers[0], hash_prevouts, 32); + hasher_Update(&hashers[0], hash_sequence, 32); + tx_prevout_hash(&hashers[0], txinput); + tx_script_hash(&hashers[0], txinput->script_sig.size, txinput->script_sig.bytes); + hasher_Update(&hashers[0], (const uint8_t*) &txinput->amount, 8); + tx_sequence_hash(&hashers[0], txinput); + hasher_Update(&hashers[0], hash_outputs, 32); + hasher_Update(&hashers[0], (const uint8_t*) &lock_time, 4); + hasher_Update(&hashers[0], (const uint8_t*) &hash_type, 4); + hasher_Double(&hashers[0], hash); +} + +static bool signing_sign_hash(TxInputType *txinput, const uint8_t* private_key, const uint8_t *public_key, const uint8_t *hash) { + resp.serialized.has_signature_index = true; + resp.serialized.signature_index = idx1; + resp.serialized.has_signature = true; + resp.serialized.has_serialized_tx = true; + if (ecdsa_sign_digest(&secp256k1, private_key, hash, sig, NULL, NULL) != 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed")); + signing_abort(); + return false; + } + resp.serialized.signature.size = ecdsa_sig_to_der(sig, resp.serialized.signature.bytes); + + uint8_t sighash = signing_hash_type() & 0xff; + if (txinput->has_multisig) { + // fill in the signature + int pubkey_idx = cryptoMultisigPubkeyIndex(&(txinput->multisig), public_key); + if (pubkey_idx < 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Pubkey not found in multisig script")); + signing_abort(); + return false; + } + memcpy(txinput->multisig.signatures[pubkey_idx].bytes, resp.serialized.signature.bytes, resp.serialized.signature.size); + txinput->multisig.signatures[pubkey_idx].size = resp.serialized.signature.size; + txinput->script_sig.size = serialize_script_multisig(&(txinput->multisig), sighash, txinput->script_sig.bytes); + if (txinput->script_sig.size == 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to serialize multisig script")); + signing_abort(); + return false; + } + } else { // SPENDADDRESS + txinput->script_sig.size = serialize_script_sig(resp.serialized.signature.bytes, resp.serialized.signature.size, public_key, 33, sighash, txinput->script_sig.bytes); + } + return true; +} + +static bool signing_sign_input(void) { + uint8_t hash[32]; + hasher_Double(&hashers[0], hash); + if (memcmp(hash, hash_outputs, 32) != 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Transaction has changed during signing")); + signing_abort(); + return false; + } + + uint32_t hash_type = signing_hash_type(); + hasher_Update(&ti.hasher, (const uint8_t *)&hash_type, 4); + tx_hash_final(&ti, hash, false); + resp.has_serialized = true; + if (!signing_sign_hash(&input, privkey, pubkey, hash)) + return false; + resp.serialized.serialized_tx.size = tx_serialize_input(&to, &input, resp.serialized.serialized_tx.bytes); + return true; +} + +static bool signing_sign_segwit_input(TxInputType *txinput) { + // idx1: index to sign + uint8_t hash[32]; + + if (txinput->script_type == InputScriptType_SPENDWITNESS + || txinput->script_type == InputScriptType_SPENDP2SHWITNESS) { + if (!compile_input_script_sig(txinput)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input")); + signing_abort(); + return false; + } + if (txinput->amount > authorized_amount) { + fsm_sendFailure(FailureType_Failure_DataError, _("Transaction has changed during signing")); + signing_abort(); + return false; + } + authorized_amount -= txinput->amount; + + signing_hash_bip143(txinput, hash); + + resp.has_serialized = true; + if (!signing_sign_hash(txinput, node.private_key, node.public_key, hash)) + return false; + + uint8_t sighash = signing_hash_type() & 0xff; + if (txinput->has_multisig) { + uint32_t r = 1; // skip number of items (filled in later) + resp.serialized.serialized_tx.bytes[r] = 0; r++; + int nwitnesses = 2; + for (uint32_t i = 0; i < txinput->multisig.signatures_count; i++) { + if (txinput->multisig.signatures[i].size == 0) { + continue; + } + nwitnesses++; + txinput->multisig.signatures[i].bytes[txinput->multisig.signatures[i].size] = sighash; + r += tx_serialize_script(txinput->multisig.signatures[i].size + 1, txinput->multisig.signatures[i].bytes, resp.serialized.serialized_tx.bytes + r); + } + uint32_t script_len = compile_script_multisig(&txinput->multisig, 0); + r += ser_length(script_len, resp.serialized.serialized_tx.bytes + r); + r += compile_script_multisig(&txinput->multisig, resp.serialized.serialized_tx.bytes + r); + resp.serialized.serialized_tx.bytes[0] = nwitnesses; + resp.serialized.serialized_tx.size = r; + } else { // single signature + uint32_t r = 0; + r += ser_length(2, resp.serialized.serialized_tx.bytes + r); + resp.serialized.signature.bytes[resp.serialized.signature.size] = sighash; + r += tx_serialize_script(resp.serialized.signature.size + 1, resp.serialized.signature.bytes, resp.serialized.serialized_tx.bytes + r); + r += tx_serialize_script(33, node.public_key, resp.serialized.serialized_tx.bytes + r); + resp.serialized.serialized_tx.size = r; + } + } else { + // empty witness + resp.has_serialized = true; + resp.serialized.has_signature_index = false; + resp.serialized.has_signature = false; + resp.serialized.has_serialized_tx = true; + resp.serialized.serialized_tx.bytes[0] = 0; + resp.serialized.serialized_tx.size = 1; + } + // if last witness add tx footer + if (idx1 == inputs_count - 1) { + uint32_t r = resp.serialized.serialized_tx.size; + r += tx_serialize_footer(&to, resp.serialized.serialized_tx.bytes + r); + resp.serialized.serialized_tx.size = r; + } + return true; +} + +#define ENABLE_SEGWIT_NONSEGWIT_MIXING 1 + +void signing_txack(TransactionType *tx) +{ + if (!signing) { + fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Not in Signing mode")); + layoutHome(); + return; + } + + static int update_ctr = 0; + if (update_ctr++ == 20) { + layoutProgress(_("Signing transaction"), progress); + update_ctr = 0; + } + + memset(&resp, 0, sizeof(TxRequest)); + + switch (signing_stage) { + case STAGE_REQUEST_1_INPUT: + signing_check_input(&tx->inputs[0]); + tx_weight += tx_input_weight(&tx->inputs[0]); + if (tx->inputs[0].script_type == InputScriptType_SPENDMULTISIG + || tx->inputs[0].script_type == InputScriptType_SPENDADDRESS) { + memcpy(&input, tx->inputs, sizeof(TxInputType)); +#if !ENABLE_SEGWIT_NONSEGWIT_MIXING + // don't mix segwit and non-segwit inputs + if (idx1 > 0 && to.is_segwit == true) { + fsm_sendFailure(FailureType_Failure_DataError, _("Mixing segwit and non-segwit inputs is not allowed")); + signing_abort(); + return; + } +#endif + + if (coin->force_bip143) { + if (!tx->inputs[0].has_amount) { + fsm_sendFailure(FailureType_Failure_DataError, _("BIP 143 input without amount")); + signing_abort(); + return; + } + if (to_spend + tx->inputs[0].amount < to_spend) { + fsm_sendFailure(FailureType_Failure_DataError, _("Value overflow")); + signing_abort(); + return; + } + to_spend += tx->inputs[0].amount; + authorized_amount += tx->inputs[0].amount; + phase1_request_next_input(); + } else { + // remember the first non-segwit input -- this is the first input + // we need to sign during phase2 + if (next_nonsegwit_input == 0xffffffff) + next_nonsegwit_input = idx1; + send_req_2_prev_meta(); + } + } else if (tx->inputs[0].script_type == InputScriptType_SPENDWITNESS + || tx->inputs[0].script_type == InputScriptType_SPENDP2SHWITNESS) { + if (!coin->has_segwit) { + fsm_sendFailure(FailureType_Failure_DataError, _("Segwit not enabled on this coin")); + signing_abort(); + return; + } + if (!tx->inputs[0].has_amount) { + fsm_sendFailure(FailureType_Failure_DataError, _("Segwit input without amount")); + signing_abort(); + return; + } + if (to_spend + tx->inputs[0].amount < to_spend) { + fsm_sendFailure(FailureType_Failure_DataError, _("Value overflow")); + signing_abort(); + return; + } + if (!to.is_segwit) { + tx_weight += TXSIZE_SEGWIT_OVERHEAD + to.inputs_len; + } +#if !ENABLE_SEGWIT_NONSEGWIT_MIXING + // don't mix segwit and non-segwit inputs + if (idx1 == 0) { + to.is_segwit = true; + } else if (to.is_segwit == false) { + fsm_sendFailure(FailureType_Failure_DataError, _("Mixing segwit and non-segwit inputs is not allowed")); + signing_abort(); + return; + } +#else + to.is_segwit = true; +#endif + to_spend += tx->inputs[0].amount; + authorized_amount += tx->inputs[0].amount; + phase1_request_next_input(); + } else { + fsm_sendFailure(FailureType_Failure_DataError, _("Wrong input script type")); + signing_abort(); + return; + } + return; + case STAGE_REQUEST_2_PREV_META: + tx_init(&tp, tx->inputs_cnt, tx->outputs_cnt, tx->version, tx->lock_time, tx->extra_data_len, coin->curve->hasher_type); + progress_meta_step = progress_step / (tp.inputs_len + tp.outputs_len); + idx2 = 0; + if (tp.inputs_len > 0) { + send_req_2_prev_input(); + } else { + tx_serialize_header_hash(&tp); + send_req_2_prev_output(); + } + return; + case STAGE_REQUEST_2_PREV_INPUT: + progress = (idx1 * progress_step + idx2 * progress_meta_step) >> PROGRESS_PRECISION; + if (!tx_serialize_input_hash(&tp, tx->inputs)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to serialize input")); + signing_abort(); + return; + } + if (idx2 < tp.inputs_len - 1) { + idx2++; + send_req_2_prev_input(); + } else { + idx2 = 0; + send_req_2_prev_output(); + } + return; + case STAGE_REQUEST_2_PREV_OUTPUT: + progress = (idx1 * progress_step + (tp.inputs_len + idx2) * progress_meta_step) >> PROGRESS_PRECISION; + if (!tx_serialize_output_hash(&tp, tx->bin_outputs)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to serialize output")); + signing_abort(); + return; + } + if (idx2 == input.prev_index) { + if (to_spend + tx->bin_outputs[0].amount < to_spend) { + fsm_sendFailure(FailureType_Failure_DataError, _("Value overflow")); + signing_abort(); + return; + } + to_spend += tx->bin_outputs[0].amount; + } + if (idx2 < tp.outputs_len - 1) { + /* Check prevtx of next input */ + idx2++; + send_req_2_prev_output(); + } else if (tp.extra_data_len > 0) { // has extra data + send_req_2_prev_extradata(0, MIN(1024, tp.extra_data_len)); + return; + } else { + /* prevtx is done */ + signing_check_prevtx_hash(); + } + return; + case STAGE_REQUEST_2_PREV_EXTRADATA: + if (!tx_serialize_extra_data_hash(&tp, tx->extra_data.bytes, tx->extra_data.size)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to serialize extra data")); + signing_abort(); + return; + } + if (tp.extra_data_received < tp.extra_data_len) { // still some data remanining + send_req_2_prev_extradata(tp.extra_data_received, MIN(1024, tp.extra_data_len - tp.extra_data_received)); + } else { + signing_check_prevtx_hash(); + } + return; + case STAGE_REQUEST_3_OUTPUT: + if (!signing_check_output(&tx->outputs[0])) { + return; + } + tx_weight += tx_output_weight(coin, &tx->outputs[0]); + phase1_request_next_output(); + return; + case STAGE_REQUEST_4_INPUT: + progress = 500 + ((signatures * progress_step + idx2 * progress_meta_step) >> PROGRESS_PRECISION); + if (idx2 == 0) { + tx_init(&ti, inputs_count, outputs_count, version, lock_time, 0, coin->curve->hasher_type); + hasher_Reset(&hashers[0]); + } + // check prevouts and script type + tx_prevout_hash(&hashers[0], tx->inputs); + hasher_Update(&hashers[0], (const uint8_t *) &tx->inputs[0].script_type, sizeof(&tx->inputs[0].script_type)); + if (idx2 == idx1) { + if (!compile_input_script_sig(&tx->inputs[0])) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input")); + signing_abort(); + return; + } + memcpy(&input, &tx->inputs[0], sizeof(input)); + memcpy(privkey, node.private_key, 32); + memcpy(pubkey, node.public_key, 33); + } else { + if (next_nonsegwit_input == idx1 && idx2 > idx1 + && (tx->inputs[0].script_type == InputScriptType_SPENDADDRESS + || tx->inputs[0].script_type == InputScriptType_SPENDMULTISIG)) { + next_nonsegwit_input = idx2; + } + tx->inputs[0].script_sig.size = 0; + } + if (!tx_serialize_input_hash(&ti, tx->inputs)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to serialize input")); + signing_abort(); + return; + } + if (idx2 < inputs_count - 1) { + idx2++; + send_req_4_input(); + } else { + uint8_t hash[32]; + hasher_Final(&hashers[0], hash); + if (memcmp(hash, hash_check, 32) != 0) { + fsm_sendFailure(FailureType_Failure_DataError, _("Transaction has changed during signing")); + signing_abort(); + return; + } + hasher_Reset(&hashers[0]); + idx2 = 0; + send_req_4_output(); + } + return; + case STAGE_REQUEST_4_OUTPUT: + progress = 500 + ((signatures * progress_step + (inputs_count + idx2) * progress_meta_step) >> PROGRESS_PRECISION); + if (compile_output(coin, root, tx->outputs, &bin_output, false) <= 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile output")); + signing_abort(); + return; + } + // check hashOutputs + tx_output_hash(&hashers[0], &bin_output); + if (!tx_serialize_output_hash(&ti, &bin_output)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to serialize output")); + signing_abort(); + return; + } + if (idx2 < outputs_count - 1) { + idx2++; + send_req_4_output(); + } else { + if (!signing_sign_input()) { + return; + } + // since this took a longer time, update progress + signatures++; + progress = 500 + ((signatures * progress_step) >> PROGRESS_PRECISION); + layoutProgress(_("Signing transaction"), progress); + update_ctr = 0; + if (idx1 < inputs_count - 1) { + idx1++; + phase2_request_next_input(); + } else { + idx1 = 0; + send_req_5_output(); + } + } + return; + + case STAGE_REQUEST_SEGWIT_INPUT: + resp.has_serialized = true; + resp.serialized.has_signature_index = false; + resp.serialized.has_signature = false; + resp.serialized.has_serialized_tx = true; + if (tx->inputs[0].script_type == InputScriptType_SPENDMULTISIG + || tx->inputs[0].script_type == InputScriptType_SPENDADDRESS) { + if (!coin->force_bip143) { + fsm_sendFailure(FailureType_Failure_DataError, _("Transaction has changed during signing")); + signing_abort(); + return; + } + if (!compile_input_script_sig(&tx->inputs[0])) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input")); + signing_abort(); + return; + } + if (tx->inputs[0].amount > authorized_amount) { + fsm_sendFailure(FailureType_Failure_DataError, _("Transaction has changed during signing")); + signing_abort(); + return; + } + authorized_amount -= tx->inputs[0].amount; + + uint8_t hash[32]; + signing_hash_bip143(&tx->inputs[0], hash); + if (!signing_sign_hash(&tx->inputs[0], node.private_key, node.public_key, hash)) + return; + // since this took a longer time, update progress + signatures++; + progress = 500 + ((signatures * progress_step) >> PROGRESS_PRECISION); + layoutProgress(_("Signing transaction"), progress); + update_ctr = 0; + } else if (tx->inputs[0].script_type == InputScriptType_SPENDP2SHWITNESS + && !tx->inputs[0].has_multisig) { + if (!compile_input_script_sig(&tx->inputs[0])) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input")); + signing_abort(); + return; + } + // fixup normal p2pkh script into witness 0 p2wpkh script for p2sh + // we convert 76 A9 14 88 AC to 16 00 14 + // P2SH input pushes witness 0 script + tx->inputs[0].script_sig.size = 0x17; // drops last 2 bytes. + tx->inputs[0].script_sig.bytes[0] = 0x16; // push 22 bytes; replaces OP_DUP + tx->inputs[0].script_sig.bytes[1] = 0x00; // witness 0 script ; replaces OP_HASH160 + // digest is already in right place. + } else if (tx->inputs[0].script_type == InputScriptType_SPENDP2SHWITNESS) { + // Prepare P2SH witness script. + tx->inputs[0].script_sig.size = 0x23; // 35 bytes long: + tx->inputs[0].script_sig.bytes[0] = 0x22; // push 34 bytes (full witness script) + tx->inputs[0].script_sig.bytes[1] = 0x00; // witness 0 script + tx->inputs[0].script_sig.bytes[2] = 0x20; // push 32 bytes (digest) + // compute digest of multisig script + if (!compile_script_multisig_hash(&tx->inputs[0].multisig, coin->curve->hasher_type, tx->inputs[0].script_sig.bytes + 3)) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input")); + signing_abort(); + return; + } + } else { + // direct witness scripts require zero scriptSig + tx->inputs[0].script_sig.size = 0; + } + resp.serialized.serialized_tx.size = tx_serialize_input(&to, &tx->inputs[0], resp.serialized.serialized_tx.bytes); + if (idx1 < inputs_count - 1) { + idx1++; + phase2_request_next_input(); + } else { + idx1 = 0; + send_req_5_output(); + } + return; + + case STAGE_REQUEST_5_OUTPUT: + if (compile_output(coin, root, tx->outputs, &bin_output,false) <= 0) { + fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile output")); + signing_abort(); + return; + } + resp.has_serialized = true; + resp.serialized.has_serialized_tx = true; + resp.serialized.serialized_tx.size = tx_serialize_output(&to, &bin_output, resp.serialized.serialized_tx.bytes); + if (idx1 < outputs_count - 1) { + idx1++; + send_req_5_output(); + } else if (to.is_segwit) { + idx1 = 0; + send_req_segwit_witness(); + } else { + send_req_finished(); + signing_abort(); + } + return; + + case STAGE_REQUEST_SEGWIT_WITNESS: + if (!signing_sign_segwit_input(&tx->inputs[0])) { + return; + } + signatures++; + progress = 500 + ((signatures * progress_step) >> PROGRESS_PRECISION); + layoutProgress(_("Signing transaction"), progress); + update_ctr = 0; + if (idx1 < inputs_count - 1) { + idx1++; + send_req_segwit_witness(); + } else { + send_req_finished(); + signing_abort(); + } + return; + } + + fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing error")); + signing_abort(); +} + +void signing_abort(void) +{ + if (signing) { + layoutHome(); + signing = false; + } +} diff --git a/hardware-wallet/firmware/firmware/signing.h b/hardware-wallet/firmware/firmware/signing.h new file mode 100644 index 00000000..e4ee8c55 --- /dev/null +++ b/hardware-wallet/firmware/firmware/signing.h @@ -0,0 +1,34 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __SIGNING_H__ +#define __SIGNING_H__ + +#include +#include +#include "bip32.h" +#include "coins.h" +#include "hasher.h" +#include "types.pb.h" + +void signing_init(uint32_t _inputs_count, uint32_t _outputs_count, const CoinInfo *_coin, const HDNode *_root, uint32_t _version, uint32_t _lock_time); +void signing_abort(void); +void signing_txack(TransactionType *tx); + +#endif diff --git a/hardware-wallet/firmware/firmware/storage.c b/hardware-wallet/firmware/firmware/storage.c new file mode 100644 index 00000000..27a16296 --- /dev/null +++ b/hardware-wallet/firmware/firmware/storage.c @@ -0,0 +1,902 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#include + +#include "messages.pb.h" + +#include "trezor.h" +#include "sha2.h" +#include "aes/aes.h" +#include "pbkdf2.h" +#include "hmac.h" +#include "bip32.h" +#include "bip39.h" +#include "curves.h" +#include "util.h" +#include "memory.h" +#include "rng.h" +#include "storage.h" +#include "debug.h" +#include "protect.h" +#include "layout2.h" +#include "usb.h" +#include "gettext.h" +#include "u2f.h" +#include "memzero.h" + +/* magic constant to check validity of storage block */ +static const uint32_t storage_magic = 0x726f7473; // 'stor' as uint32_t + +static uint32_t storage_uuid[12 / sizeof(uint32_t)]; +#ifndef __clang__ +// TODO: Fix this for Clang +_Static_assert(((uint32_t)storage_uuid & 3) == 0, "uuid unaligned"); +_Static_assert((sizeof(storage_uuid) & 3) == 0, "uuid unaligned"); +#endif + +Storage CONFIDENTIAL storageUpdate; +#ifndef __clang__ +// TODO: Fix this for Clang +_Static_assert(((uint32_t)&storageUpdate & 3) == 0, "storage unaligned"); +_Static_assert((sizeof(storageUpdate) & 3) == 0, "storage unaligned"); +#endif + +#define STORAGE_ROM ((const Storage *)(FLASH_STORAGE_START + sizeof(storage_magic) + sizeof(storage_uuid))) + +#if EMULATOR +// TODO: Fix this for emulator +#define storageRom STORAGE_ROM +#else +const Storage *storageRom = STORAGE_ROM; +#endif + +char storage_uuid_str[25]; + +/* + storage layout: + + offset | type/length | description +--------+--------------+------------------------------- + 0x0000 | 4 bytes | magic = 'stor' + 0x0004 | 12 bytes | uuid + 0x0010 | ? bytes | Storage structure +--------+--------------+------------------------------- + 0x4000 | 4 kbytes | area for pin failures + 0x5000 | 256 bytes | area for u2f counter updates + 0x5100 | 11.75 kbytes | reserved + +The area for pin failures looks like this: +0 ... 0 pinfail 0xffffffff .. 0xffffffff +The pinfail is a binary number of the form 1...10...0, +the number of zeros is the number of pin failures. +This layout is used because we can only clear bits without +erasing the flash. + +The area for u2f counter updates is just a sequence of zero-bits +followed by a sequence of one-bits. The bits in a byte are numbered +from LSB to MSB. The number of zero bits is the offset that should +be added to the storage u2f_counter to get the real counter value. + + */ + +#define FLASH_STORAGE_PINAREA (FLASH_META_START + 0x4000) +#define FLASH_STORAGE_PINAREA_LEN (0x1000) +#define FLASH_STORAGE_U2FAREA (FLASH_STORAGE_PINAREA + FLASH_STORAGE_PINAREA_LEN) +#define FLASH_STORAGE_U2FAREA_LEN (0x100) +#define FLASH_STORAGE_REALLEN (sizeof(storage_magic) + sizeof(storage_uuid) + sizeof(Storage)) + +#if !EMULATOR +// TODO: Fix this for emulator +_Static_assert(FLASH_STORAGE_START + FLASH_STORAGE_REALLEN <= FLASH_STORAGE_PINAREA, "Storage struct is too large for TREZOR flash"); +#endif + +/* Current u2f offset, i.e. u2f counter is + * storage.u2f_counter + storage_u2f_offset. + * This corresponds to the number of cleared bits in the U2FAREA. + */ +static uint32_t storage_u2f_offset; + +static bool sessionSeedCached, sessionSeedUsesPassphrase; + +static uint8_t CONFIDENTIAL sessionSeed[64]; + +static bool sessionPinCached; + +static bool sessionPassphraseCached; +static char CONFIDENTIAL sessionPassphrase[51]; + +#define STORAGE_VERSION 9 + +void storage_show_error(void) +{ + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Storage failure"), _("detected."), NULL, _("Please unplug"), _("the device."), NULL); + shutdown(); +} + +void storage_check_flash_errors(void) +{ +#if !EMULATOR + // flash operation failed + if (FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) { + storage_show_error(); + } +#endif +} + +bool storage_from_flash(void) +{ + storage_clear_update(); + if (memcmp((void *)FLASH_STORAGE_START, &storage_magic, sizeof(storage_magic)) != 0) { + // wrong magic + return false; + } + + const uint32_t version = storageRom->version; + // version 1: since 1.0.0 + // version 2: since 1.2.1 + // version 3: since 1.3.1 + // version 4: since 1.3.2 + // version 5: since 1.3.3 + // version 6: since 1.3.6 + // version 7: since 1.5.1 + // version 8: since 1.5.2 + // version 9: since 1.6.1 + if (version > STORAGE_VERSION) { + // downgrade -> clear storage + return false; + } + + // load uuid + memcpy(storage_uuid, (void *)(FLASH_STORAGE_START + sizeof(storage_magic)), sizeof(storage_uuid)); + data2hex(storage_uuid, sizeof(storage_uuid), storage_uuid_str); + +#define OLD_STORAGE_SIZE(last_member) (((offsetof(Storage, last_member) + pb_membersize(Storage, last_member)) + 3) & ~3) + + // copy storage + size_t old_storage_size = 0; + + if (version == 0) { + } else if (version <= 2) { + old_storage_size = OLD_STORAGE_SIZE(imported); + } else if (version <= 5) { + // added homescreen + old_storage_size = OLD_STORAGE_SIZE(homescreen); + } else if (version <= 7) { + // added u2fcounter + old_storage_size = OLD_STORAGE_SIZE(u2f_counter); + } else if (version <= 8) { + // added flags and needsBackup + old_storage_size = OLD_STORAGE_SIZE(flags); + } else if (version <= 9) { + // added u2froot + old_storage_size = OLD_STORAGE_SIZE(u2froot); + } + + // erase newly added fields + if (old_storage_size != sizeof(Storage)) { + flash_clear_status_flags(); + flash_unlock(); + for (uint32_t offset = old_storage_size; offset < sizeof(Storage); offset += sizeof(uint32_t)) { + flash_program_word(FLASH_STORAGE_START + sizeof(storage_magic) + sizeof(storage_uuid) + offset, 0); + } + flash_lock(); + storage_check_flash_errors(); + } + + if (version <= 5) { + // convert PIN failure counter from version 5 format + uint32_t pinctr = storageRom->has_pin_failed_attempts ? storageRom->pin_failed_attempts : 0; + if (pinctr > 31) { + pinctr = 31; + } + flash_clear_status_flags(); + flash_unlock(); + // erase extra storage sector + flash_erase_sector(FLASH_META_SECTOR_LAST, FLASH_CR_PROGRAM_X32); + flash_program_word(FLASH_STORAGE_PINAREA, 0xffffffff << pinctr); + // erase storageRom.has_pin_failed_attempts and storageRom.pin_failed_attempts +#if !EMULATOR +// TODO: Fix this for emulator + _Static_assert(((uint32_t)&STORAGE_ROM->pin_failed_attempts & 3) == 0, "storage.pin_failed_attempts unaligned"); +#endif + flash_program_byte((uint32_t)&storageRom->has_pin_failed_attempts, 0); + flash_program_word((uint32_t)&storageRom->pin_failed_attempts, 0); + flash_lock(); + storage_check_flash_errors(); + } + uint32_t *u2fptr = (uint32_t*) FLASH_STORAGE_U2FAREA; + while (*u2fptr == 0) { + u2fptr++; + } + storage_u2f_offset = 32 * (u2fptr - (uint32_t*) FLASH_STORAGE_U2FAREA); + uint32_t u2fword = *u2fptr; + while ((u2fword & 1) == 0) { + storage_u2f_offset++; + u2fword >>= 1; + } + // force recomputing u2f root for storage version < 9. + // this is done by re-setting the mnemonic, which triggers the computation + if (version < 9) { + storageUpdate.has_mnemonic = storageRom->has_mnemonic; + strlcpy(storageUpdate.mnemonic, storageRom->mnemonic, sizeof(storageUpdate.mnemonic)); + } + // update storage version on flash + if (version != STORAGE_VERSION) { + storage_update(); + } + return true; +} + +void storage_init(void) +{ + if (!storage_from_flash()) { + storage_wipe(); + } +} + +void storage_generate_uuid(void) +{ + // set random uuid + random_buffer((uint8_t *)storage_uuid, sizeof(storage_uuid)); + data2hex(storage_uuid, sizeof(storage_uuid), storage_uuid_str); +} + +void session_clear(bool clear_pin) +{ + sessionSeedCached = false; + memzero(&sessionSeed, sizeof(sessionSeed)); + sessionPassphraseCached = false; + memzero(&sessionPassphrase, sizeof(sessionPassphrase)); + if (clear_pin) { + sessionPinCached = false; + } +} + +static uint32_t storage_flash_words(uint32_t addr, const uint32_t *src, int nwords) { + for (int i = 0; i < nwords; i++) { + flash_program_word(addr, *src++); + addr += sizeof(uint32_t); + } + return addr; +} + +static void get_u2froot_callback(uint32_t iter, uint32_t total) +{ + layoutProgress(_("Updating"), 1000 * iter / total); +} + +static void storage_compute_u2froot(const char* mnemonic, StorageHDNode *u2froot) { + static CONFIDENTIAL HDNode node; + char oldTiny = usbTiny(1); + mnemonic_to_seed(mnemonic, "", sessionSeed, get_u2froot_callback); // BIP-0039 + usbTiny(oldTiny); + hdnode_from_seed(sessionSeed, 64, NIST256P1_NAME, &node); + hdnode_private_ckd(&node, U2F_KEY_PATH); + u2froot->depth = node.depth; + u2froot->child_num = U2F_KEY_PATH; + u2froot->chain_code.size = sizeof(node.chain_code); + memcpy(u2froot->chain_code.bytes, node.chain_code, sizeof(node.chain_code)); + u2froot->has_private_key = true; + u2froot->private_key.size = sizeof(node.private_key); + memcpy(u2froot->private_key.bytes, node.private_key, sizeof(node.private_key)); + memzero(&node, sizeof(node)); + session_clear(false); // invalidate seed cache +} + +// if storage is filled in - update fields that has has_field set to true +// if storage is NULL - do not backup original content - essentialy a wipe +static void storage_commit_locked(bool update) +{ + if (update) { + if (storageUpdate.has_passphrase_protection) { + sessionSeedCached = false; + sessionPassphraseCached = false; + } + if (storageUpdate.has_pin) { + sessionPinCached = false; + } + + storageUpdate.version = STORAGE_VERSION; + if (!storageUpdate.has_node && !storageUpdate.has_mnemonic) { + storageUpdate.has_node = storageRom->has_node; + memcpy(&storageUpdate.node, &storageRom->node, sizeof(StorageHDNode)); + storageUpdate.has_mnemonic = storageRom->has_mnemonic; + strlcpy(storageUpdate.mnemonic, storageRom->mnemonic, sizeof(storageUpdate.mnemonic)); + storageUpdate.has_u2froot = storageRom->has_u2froot; + memcpy(&storageUpdate.u2froot, &storageRom->u2froot, sizeof(StorageHDNode)); + } else if (storageUpdate.has_mnemonic) { + storageUpdate.has_u2froot = true; + storage_compute_u2froot(storageUpdate.mnemonic, &storageUpdate.u2froot); + } + if (!storageUpdate.has_passphrase_protection) { + storageUpdate.has_passphrase_protection = storageRom->has_passphrase_protection; + storageUpdate.passphrase_protection = storageRom->passphrase_protection; + } + if (!storageUpdate.has_pin) { + storageUpdate.has_pin = storageRom->has_pin; + strlcpy(storageUpdate.pin, storageRom->pin, sizeof(storageUpdate.pin)); + } else if (!storageUpdate.pin[0]) { + storageUpdate.has_pin = false; + } + if (!storageUpdate.has_language) { + storageUpdate.has_language = storageRom->has_language; + strlcpy(storageUpdate.language, storageRom->language, sizeof(storageUpdate.language)); + } + if (!storageUpdate.has_label) { + storageUpdate.has_label = storageRom->has_label; + strlcpy(storageUpdate.label, storageRom->label, sizeof(storageUpdate.label)); + } else if (!storageUpdate.label[0]) { + storageUpdate.has_label = false; + } + if (!storageUpdate.has_imported) { + storageUpdate.has_imported = storageRom->has_imported; + storageUpdate.imported = storageRom->imported; + } + if (!storageUpdate.has_homescreen) { + storageUpdate.has_homescreen = storageRom->has_homescreen; + memcpy(&storageUpdate.homescreen, &storageRom->homescreen, sizeof(storageUpdate.homescreen)); + } else if (storageUpdate.homescreen.size == 0) { + storageUpdate.has_homescreen = false; + } + if (!storageUpdate.has_u2f_counter) { + storageUpdate.has_u2f_counter = storageRom->has_u2f_counter; + storageUpdate.u2f_counter = storageRom->u2f_counter; + } + if (!storageUpdate.has_needs_backup) { + storageUpdate.has_needs_backup = storageRom->has_needs_backup; + storageUpdate.needs_backup = storageRom->needs_backup; + } + if (!storageUpdate.has_flags) { + storageUpdate.has_flags = storageRom->has_flags; + storageUpdate.flags = storageRom->flags; + } + } + + // backup meta + uint32_t meta_backup[FLASH_META_DESC_LEN / sizeof(uint32_t)]; + memcpy(meta_backup, (uint8_t*)FLASH_META_START, FLASH_META_DESC_LEN); + + // erase storage + flash_erase_sector(FLASH_META_SECTOR_FIRST, FLASH_CR_PROGRAM_X32); + + // copy meta back + uint32_t flash = FLASH_META_START; + flash = storage_flash_words(flash, meta_backup, FLASH_META_DESC_LEN / sizeof(uint32_t)); + + // copy storage + flash = storage_flash_words(flash, &storage_magic, sizeof(storage_magic) / sizeof(uint32_t)); + flash = storage_flash_words(flash, storage_uuid, sizeof(storage_uuid) / sizeof(uint32_t)); + + if (update) { + flash = storage_flash_words(flash, (const uint32_t *)&storageUpdate, sizeof(storageUpdate) / sizeof(uint32_t)); + } + storage_clear_update(); + + // fill remainder with zero for future extensions + while (flash < FLASH_STORAGE_PINAREA) { + flash_program_word(flash, 0); + flash += sizeof(uint32_t); + } +} + +void storage_clear_update(void) +{ + memzero(&storageUpdate, sizeof(storageUpdate)); +} + +void storage_update(void) +{ + flash_clear_status_flags(); + flash_unlock(); + storage_commit_locked(true); + flash_lock(); + storage_check_flash_errors(); +} + +static void storage_setNode(const HDNodeType *node) { + storageUpdate.node.depth = node->depth; + storageUpdate.node.fingerprint = node->fingerprint; + storageUpdate.node.child_num = node->child_num; + + storageUpdate.node.chain_code.size = 32; + memcpy(storageUpdate.node.chain_code.bytes, node->chain_code.bytes, 32); + + if (node->has_private_key) { + storageUpdate.node.has_private_key = true; + storageUpdate.node.private_key.size = 32; + memcpy(storageUpdate.node.private_key.bytes, node->private_key.bytes, 32); + } +} + +#if DEBUG_LINK +void storage_dumpNode(HDNodeType *node) { + node->depth = storageRom->node.depth; + node->fingerprint = storageRom->node.fingerprint; + node->child_num = storageRom->node.child_num; + + node->chain_code.size = 32; + memcpy(node->chain_code.bytes, storageRom->node.chain_code.bytes, 32); + + if (storageRom->node.has_private_key) { + node->has_private_key = true; + node->private_key.size = 32; + memcpy(node->private_key.bytes, storageRom->node.private_key.bytes, 32); + } +} +#endif + +void storage_loadDevice(LoadDevice *msg) +{ + session_clear(true); + + storageUpdate.has_imported = true; + storageUpdate.imported = true; + + storage_setPin(msg->has_pin ? msg->pin : ""); + storage_setPassphraseProtection(msg->has_passphrase_protection && msg->passphrase_protection); + + if (msg->has_node) { + storageUpdate.has_node = true; + storageUpdate.has_mnemonic = false; + storage_setNode(&(msg->node)); + sessionSeedCached = false; + memset(&sessionSeed, 0, sizeof(sessionSeed)); + } else if (msg->has_mnemonic) { + storageUpdate.has_mnemonic = true; + storageUpdate.has_node = false; + strlcpy(storageUpdate.mnemonic, msg->mnemonic, sizeof(storageUpdate.mnemonic)); + sessionSeedCached = false; + memset(&sessionSeed, 0, sizeof(sessionSeed)); + } + + if (msg->has_language) { + storageUpdate.has_language = true; + strlcpy(storageUpdate.language, msg->language, sizeof(storageUpdate.language)); + } + + storage_setLabel(msg->has_label ? msg->label : ""); + + if (msg->has_u2f_counter) { + storageUpdate.has_u2f_counter = true; + storageUpdate.u2f_counter = msg->u2f_counter - storage_u2f_offset; + } + + storage_update(); +} + +void storage_setLabel(const char *label) +{ + storageUpdate.has_label = true; + if (!label) return; + strlcpy(storageUpdate.label, label, sizeof(storageUpdate.label)); +} + +void storage_setLanguage(const char *lang) +{ + if (!lang) return; + // sanity check + if (strcmp(lang, "english") == 0) { + storageUpdate.has_language = true; + strlcpy(storageUpdate.language, lang, sizeof(storageUpdate.language)); + } +} + +void storage_setPassphraseProtection(bool passphrase_protection) +{ + sessionSeedCached = false; + sessionPassphraseCached = false; + + storageUpdate.has_passphrase_protection = true; + storageUpdate.passphrase_protection = passphrase_protection; +} + +bool storage_hasPassphraseProtection(void) +{ + return storageRom->has_passphrase_protection && storageRom->passphrase_protection; +} + +void storage_setHomescreen(const uint8_t *data, uint32_t size) +{ + storageUpdate.has_homescreen = true; + if (data && size == 1024) { + memcpy(storageUpdate.homescreen.bytes, data, size); + storageUpdate.homescreen.size = size; + } else { + memset(storageUpdate.homescreen.bytes, 0, sizeof(storageUpdate.homescreen.bytes)); + storageUpdate.homescreen.size = 0; + } +} + +static void get_root_node_callback(uint32_t iter, uint32_t total) +{ + usbSleep(1); + layoutProgress(_("Waking up"), 1000 * iter / total); +} + +const uint8_t *storage_getSeed(bool usePassphrase) +{ + // root node is properly cached + if (usePassphrase == sessionSeedUsesPassphrase + && sessionSeedCached) { + return sessionSeed; + } + + // if storage has mnemonic, convert it to node and use it + if (storageRom->has_mnemonic) { + if (usePassphrase && !protectPassphrase()) { + return NULL; + } + // if storage was not imported (i.e. it was properly generated or recovered) + if (!storageRom->has_imported || !storageRom->imported) { + // test whether mnemonic is a valid BIP-0039 mnemonic + if (!mnemonic_check(storageRom->mnemonic)) { + // and if not then halt the device + storage_show_error(); + } + } + char oldTiny = usbTiny(1); + mnemonic_to_seed(storageRom->mnemonic, usePassphrase ? sessionPassphrase : "", sessionSeed, get_root_node_callback); // BIP-0039 + usbTiny(oldTiny); + sessionSeedCached = true; + sessionSeedUsesPassphrase = usePassphrase; + return sessionSeed; + } + + return NULL; +} + +static bool storage_loadNode(const StorageHDNode *node, const char *curve, HDNode *out) { + return hdnode_from_xprv(node->depth, node->child_num, node->chain_code.bytes, node->private_key.bytes, curve, out); +} + +bool storage_getU2FRoot(HDNode *node) +{ + return storageRom->has_u2froot && storage_loadNode(&storageRom->u2froot, NIST256P1_NAME, node); +} + +bool storage_getRootNode(HDNode *node, const char *curve, bool usePassphrase) +{ + // if storage has node, decrypt and use it + if (storageRom->has_node && strcmp(curve, SECP256K1_NAME) == 0) { + if (!protectPassphrase()) { + return false; + } + if (!storage_loadNode(&storageRom->node, curve, node)) { + return false; + } + if (storageRom->has_passphrase_protection && storageRom->passphrase_protection && sessionPassphraseCached && strlen(sessionPassphrase) > 0) { + // decrypt hd node + uint8_t secret[64]; + PBKDF2_HMAC_SHA512_CTX pctx; + pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)sessionPassphrase, strlen(sessionPassphrase), (const uint8_t *)"TREZORHD", 8); + get_root_node_callback(0, BIP39_PBKDF2_ROUNDS); + for (int i = 0; i < 8; i++) { + pbkdf2_hmac_sha512_Update(&pctx, BIP39_PBKDF2_ROUNDS / 8); + get_root_node_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 8, BIP39_PBKDF2_ROUNDS); + } + pbkdf2_hmac_sha512_Final(&pctx, secret); + aes_decrypt_ctx ctx; + aes_decrypt_key256(secret, &ctx); + aes_cbc_decrypt(node->chain_code, node->chain_code, 32, secret + 32, &ctx); + aes_cbc_decrypt(node->private_key, node->private_key, 32, secret + 32, &ctx); + } + return true; + } + + const uint8_t *seed = storage_getSeed(usePassphrase); + if (seed == NULL) { + return false; + } + + return hdnode_from_seed(seed, 64, curve, node); +} + +const char *storage_getLabel(void) +{ + return storageRom->has_label ? storageRom->label : 0; +} + +const char *storage_getLanguage(void) +{ + return storageRom->has_language ? storageRom->language : 0; +} + +const uint8_t *storage_getHomescreen(void) +{ + return (storageRom->has_homescreen && storageRom->homescreen.size == 1024) ? storageRom->homescreen.bytes : 0; +} + +void storage_setMnemonic(const char *mnemonic) +{ + storageUpdate.has_mnemonic = true; + strlcpy(storageUpdate.mnemonic, mnemonic, sizeof(storageUpdate.mnemonic)); +} + +bool storage_hasNode(void) +{ + return storageRom->has_node; +} + +bool storage_hasMnemonic(void) +{ + return storageRom->has_mnemonic; +} + +const char *storage_getMnemonic(void) +{ + return storageUpdate.has_mnemonic ? storageUpdate.mnemonic + : storageRom->has_mnemonic ? storageRom->mnemonic : 0; +} + +/* Check whether mnemonic matches storage. The mnemonic must be + * a null-terminated string. + */ +bool storage_containsMnemonic(const char *mnemonic) { + /* The execution time of the following code only depends on the + * (public) input. This avoids timing attacks. + */ + char diff = 0; + uint32_t i = 0; + for (; mnemonic[i]; i++) { + diff |= (storageRom->mnemonic[i] - mnemonic[i]); + } + diff |= storageRom->mnemonic[i]; + return diff == 0; +} + +/* Check whether pin matches storage. The pin must be + * a null-terminated string with at most 9 characters. + */ +bool storage_containsPin(const char *pin) +{ + /* The execution time of the following code only depends on the + * (public) input. This avoids timing attacks. + */ + char diff = 0; + uint32_t i = 0; + while (pin[i]) { + diff |= storageRom->pin[i] - pin[i]; + i++; + } + diff |= storageRom->pin[i]; + return diff == 0; +} + +bool storage_hasPin(void) +{ + return storageRom->has_pin && storageRom->pin[0] != 0; +} + +void storage_setPin(const char *pin) +{ + storageUpdate.has_pin = true; + strlcpy(storageUpdate.pin, pin, sizeof(storageUpdate.pin)); + sessionPinCached = false; +} + +const char *storage_getPin(void) +{ + return storageRom->has_pin ? storageRom->pin : 0; +} + +void session_cachePassphrase(const char *passphrase) +{ + strlcpy(sessionPassphrase, passphrase, sizeof(sessionPassphrase)); + sessionPassphraseCached = true; +} + +bool session_isPassphraseCached(void) +{ + return sessionPassphraseCached; +} + +bool session_getState(const uint8_t *salt, uint8_t *state, const char *passphrase) +{ + if (!passphrase && !sessionPassphraseCached) { + return false; + } else { + passphrase = sessionPassphrase; + } + if (!salt) { + // if salt is not provided fill the first half of the state with random data + random_buffer(state, 32); + } else { + // if salt is provided fill the first half of the state with salt + memcpy(state, salt, 32); + } + // state[0:32] = salt + // state[32:64] = HMAC(passphrase, salt || device_id) + HMAC_SHA256_CTX ctx; + hmac_sha256_Init(&ctx, (const uint8_t *)passphrase, strlen(passphrase)); + hmac_sha256_Update(&ctx, state, 32); + hmac_sha256_Update(&ctx, (const uint8_t *)storage_uuid, sizeof(storage_uuid)); + hmac_sha256_Final(&ctx, state + 32); + + memzero(&ctx, sizeof(ctx)); + + return true; +} + +void session_cachePin(void) +{ + sessionPinCached = true; +} + +bool session_isPinCached(void) +{ + return sessionPinCached; +} + +void storage_clearPinArea(void) +{ + flash_clear_status_flags(); + flash_unlock(); + flash_erase_sector(FLASH_META_SECTOR_LAST, FLASH_CR_PROGRAM_X32); + flash_lock(); + storage_check_flash_errors(); + storage_u2f_offset = 0; +} + +// called when u2f area or pin area overflows +static void storage_area_recycle(uint32_t new_pinfails) +{ + // first clear storage marker. In case of a failure below it is better + // to clear the storage than to allow restarting with zero PIN failures + flash_program_word(FLASH_STORAGE_START, 0); + if (*(uint32_t *)FLASH_STORAGE_START != 0) { + storage_show_error(); + } + + // erase storage sector + flash_erase_sector(FLASH_META_SECTOR_LAST, FLASH_CR_PROGRAM_X32); + flash_program_word(FLASH_STORAGE_PINAREA, new_pinfails); + if (*(uint32_t *)FLASH_STORAGE_PINAREA != new_pinfails) { + storage_show_error(); + } + + if (storage_u2f_offset > 0) { + storageUpdate.has_u2f_counter = true; + storageUpdate.u2f_counter += storage_u2f_offset; + storage_u2f_offset = 0; + storage_commit_locked(true); + } +} + +void storage_resetPinFails(uint32_t *pinfailsptr) +{ + flash_clear_status_flags(); + flash_unlock(); + if ((uint32_t) (pinfailsptr + 1) + >= FLASH_STORAGE_PINAREA + FLASH_STORAGE_PINAREA_LEN) { + // recycle extra storage sector + storage_area_recycle(0xffffffff); + } else { + flash_program_word((uint32_t) pinfailsptr, 0); + } + flash_lock(); + storage_check_flash_errors(); +} + +bool storage_increasePinFails(uint32_t *pinfailsptr) +{ + uint32_t newctr = *pinfailsptr << 1; + // counter already at maximum, we do not increase it any more + // return success so that a good pin is accepted + if (!newctr) + return true; + + flash_clear_status_flags(); + flash_unlock(); + flash_program_word((uint32_t) pinfailsptr, newctr); + flash_lock(); + storage_check_flash_errors(); + + return *pinfailsptr == newctr; +} + +uint32_t *storage_getPinFailsPtr(void) +{ + uint32_t *pinfailsptr = (uint32_t *) FLASH_STORAGE_PINAREA; + while (*pinfailsptr == 0) + pinfailsptr++; + return pinfailsptr; +} + +bool storage_isInitialized(void) +{ + return storageRom->has_node || storageRom->has_mnemonic; +} + +bool storage_isImported(void) +{ + return storageRom->has_imported && storageRom->imported; +} + +void storage_setImported(bool imported) +{ + storageUpdate.has_imported = true; + storageUpdate.imported = imported; +} + +bool storage_needsBackup(void) +{ + return storageUpdate.has_needs_backup ? storageUpdate.needs_backup + : storageRom->has_needs_backup && storageRom->needs_backup; +} + +void storage_setNeedsBackup(bool needs_backup) +{ + storageUpdate.has_needs_backup = true; + storageUpdate.needs_backup = needs_backup; +} + +void storage_applyFlags(uint32_t flags) +{ + if ((storageRom->flags | flags) == storageRom->flags) { + return; // no new flags + } + storageUpdate.has_flags = true; + storageUpdate.flags |= flags; +} + +uint32_t storage_getFlags(void) +{ + return storageRom->has_flags ? storageRom->flags : 0; +} + +uint32_t storage_nextU2FCounter(void) +{ + uint32_t *ptr = ((uint32_t *) FLASH_STORAGE_U2FAREA) + (storage_u2f_offset / 32); + uint32_t newval = 0xfffffffe << (storage_u2f_offset & 31); + + flash_clear_status_flags(); + flash_unlock(); + flash_program_word((uint32_t) ptr, newval); + storage_u2f_offset++; + if (storage_u2f_offset >= 8 * FLASH_STORAGE_U2FAREA_LEN) { + storage_area_recycle(*storage_getPinFailsPtr()); + } + flash_lock(); + storage_check_flash_errors(); + return storageRom->u2f_counter + storage_u2f_offset; +} + +void storage_setU2FCounter(uint32_t u2fcounter) +{ + storageUpdate.has_u2f_counter = true; + storageUpdate.u2f_counter = u2fcounter - storage_u2f_offset; +} + +void storage_wipe(void) +{ + session_clear(true); + storage_generate_uuid(); + + flash_clear_status_flags(); + flash_unlock(); + storage_commit_locked(false); + flash_lock(); + storage_check_flash_errors(); + + storage_clearPinArea(); +} diff --git a/hardware-wallet/firmware/firmware/storage.h b/hardware-wallet/firmware/firmware/storage.h new file mode 100644 index 00000000..431e830c --- /dev/null +++ b/hardware-wallet/firmware/firmware/storage.h @@ -0,0 +1,147 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __STORAGE_H__ +#define __STORAGE_H__ + +#include "types.pb.h" +#include "messages.pb.h" +#include "bip32.h" + +#define STORAGE_FIELD(TYPE, NAME) \ + bool has_##NAME; \ + TYPE NAME; + +#define STORAGE_STRING(NAME, SIZE) \ + bool has_##NAME; \ + char NAME[SIZE]; + +#define STORAGE_BYTES(NAME, SIZE) \ + bool has_##NAME; \ + struct { \ + size_t size; \ + uint8_t bytes[SIZE]; \ + } NAME; + +#define STORAGE_BOOL(NAME) STORAGE_FIELD(bool, NAME) +#define STORAGE_NODE(NAME) STORAGE_FIELD(StorageHDNode, NAME) +#define STORAGE_UINT32(NAME) STORAGE_FIELD(uint32_t, NAME) + +typedef struct { + uint32_t depth; + uint32_t fingerprint; + uint32_t child_num; + struct { + size_t size; + uint8_t bytes[32]; + } chain_code; + + STORAGE_BYTES(private_key, 32); + STORAGE_BYTES(public_key, 33); +} StorageHDNode; + +typedef struct _Storage { + uint32_t version; + + STORAGE_NODE (node) + STORAGE_STRING (mnemonic, 241) + STORAGE_BOOL (passphrase_protection) + STORAGE_UINT32 (pin_failed_attempts) + STORAGE_STRING (pin, 10) + STORAGE_STRING (language, 17) + STORAGE_STRING (label, 33) + STORAGE_BOOL (imported) + STORAGE_BYTES (homescreen, 1024) + STORAGE_UINT32 (u2f_counter) + STORAGE_BOOL (needs_backup) + STORAGE_UINT32 (flags) + STORAGE_NODE (u2froot) +} Storage; + +extern Storage storageUpdate; + +void storage_init(void); +void storage_generate_uuid(void); +void storage_clear_update(void); +void storage_update(void); +void session_clear(bool clear_pin); + +void storage_loadDevice(LoadDevice *msg); + +const uint8_t *storage_getSeed(bool usePassphrase); + +bool storage_getU2FRoot(HDNode *node); +bool storage_getRootNode(HDNode *node, const char *curve, bool usePassphrase); + +const char *storage_getLabel(void); +void storage_setLabel(const char *label); + +const char *storage_getLanguage(void); +void storage_setLanguage(const char *lang); + +void storage_setPassphraseProtection(bool passphrase_protection); +bool storage_hasPassphraseProtection(void); + +const uint8_t *storage_getHomescreen(void); +void storage_setHomescreen(const uint8_t *data, uint32_t size); + +void session_cachePassphrase(const char *passphrase); +bool session_isPassphraseCached(void); +bool session_getState(const uint8_t *salt, uint8_t *state, const char *passphrase); + +void storage_setMnemonic(const char *mnemonic); +bool storage_containsMnemonic(const char *mnemonic); +bool storage_hasMnemonic(void); +const char *storage_getMnemonic(void); + +bool storage_hasNode(void); +#if DEBUG_LINK +void storage_dumpNode(HDNodeType *node); +#endif + +bool storage_containsPin(const char *pin); +bool storage_hasPin(void); +const char *storage_getPin(void); +void storage_setPin(const char *pin); +void session_cachePin(void); +bool session_isPinCached(void); +void storage_clearPinArea(void); +void storage_resetPinFails(uint32_t *pinfailptr); +bool storage_increasePinFails(uint32_t *pinfailptr); +uint32_t *storage_getPinFailsPtr(void); + +uint32_t storage_nextU2FCounter(void); +void storage_setU2FCounter(uint32_t u2fcounter); + +bool storage_isInitialized(void); + +bool storage_isImported(void); +void storage_setImported(bool imported); + +bool storage_needsBackup(void); +void storage_setNeedsBackup(bool needs_backup); + +void storage_applyFlags(uint32_t flags); +uint32_t storage_getFlags(void); + +void storage_wipe(void); + +extern char storage_uuid_str[25]; + +#endif diff --git a/hardware-wallet/firmware/firmware/transaction.c b/hardware-wallet/firmware/firmware/transaction.c new file mode 100644 index 00000000..8cbe21c5 --- /dev/null +++ b/hardware-wallet/firmware/firmware/transaction.c @@ -0,0 +1,664 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include "transaction.h" +#include "ecdsa.h" +#include "coins.h" +#include "util.h" +#include "debug.h" +#include "protect.h" +#include "layout2.h" +#include "crypto.h" +#include "ripemd160.h" +#include "base58.h" +#include "address.h" +#include "messages.pb.h" +#include "types.pb.h" +#include "segwit_addr.h" + +#define SEGWIT_VERSION_0 0 + +/* transaction input size (without script): 32 prevhash, 4 idx, 4 sequence */ +#define TXSIZE_INPUT 40 +/* transaction output size (without script): 8 amount */ +#define TXSIZE_OUTPUT 8 +/* size of a pubkey */ +#define TXSIZE_PUBKEY 33 +/* size of a DER signature (3 type bytes, 3 len bytes, 33 R, 32 S, 1 sighash */ +#define TXSIZE_SIGNATURE 72 +/* size of a multiscript without pubkey (1 M, 1 N, 1 checksig) */ +#define TXSIZE_MULTISIGSCRIPT 3 +/* size of a p2wpkh script (1 version, 1 push, 20 hash) */ +#define TXSIZE_WITNESSPKHASH 22 +/* size of a p2wsh script (1 version, 1 push, 32 hash) */ +#define TXSIZE_WITNESSSCRIPT 34 +/* size of a p2pkh script (dup, hash, push, 20 pubkeyhash, equal, checksig) */ +#define TXSIZE_P2PKHASH 25 +/* size of a p2sh script (hash, push, 20 scripthash, equal) */ +#define TXSIZE_P2SCRIPT 23 + +static const uint8_t segwit_header[2] = {0,1}; + +static inline uint32_t op_push_size(uint32_t i) { + if (i < 0x4C) { + return 1; + } + if (i < 0x100) { + return 2; + } + if (i < 0x10000) { + return 3; + } + return 5; +} + +uint32_t op_push(uint32_t i, uint8_t *out) { + if (i < 0x4C) { + out[0] = i & 0xFF; + return 1; + } + if (i < 0x100) { + out[0] = 0x4C; + out[1] = i & 0xFF; + return 2; + } + if (i < 0x10000) { + out[0] = 0x4D; + out[1] = i & 0xFF; + out[2] = (i >> 8) & 0xFF; + return 3; + } + out[0] = 0x4E; + out[1] = i & 0xFF; + out[2] = (i >> 8) & 0xFF; + out[3] = (i >> 16) & 0xFF; + out[4] = (i >> 24) & 0xFF; + return 5; +} + +bool compute_address(const CoinInfo *coin, + InputScriptType script_type, + const HDNode *node, + bool has_multisig, const MultisigRedeemScriptType *multisig, + char address[MAX_ADDR_SIZE]) { + + uint8_t raw[MAX_ADDR_RAW_SIZE]; + uint8_t digest[32]; + size_t prelen; + + if (has_multisig) { + if (cryptoMultisigPubkeyIndex(multisig, node->public_key) < 0) { + return 0; + } + if (compile_script_multisig_hash(multisig, coin->curve->hasher_type, digest) == 0) { + return 0; + } + if (script_type == InputScriptType_SPENDWITNESS) { + // segwit p2wsh: script hash is single sha256 + if (!coin->has_segwit || !coin->bech32_prefix) { + return 0; + } + if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_0, digest, 32)) { + return 0; + } + } else if (script_type == InputScriptType_SPENDP2SHWITNESS) { + // segwit p2wsh encapsuled in p2sh address + if (!coin->has_segwit) { + return 0; + } + if (!coin->has_address_type_p2sh) { + return 0; + } + raw[0] = 0; // push version + raw[1] = 32; // push 32 bytes + memcpy(raw+2, digest, 32); // push hash + hasher_Raw(coin->curve->hasher_type, raw, 34, digest); + prelen = address_prefix_bytes_len(coin->address_type_p2sh); + address_write_prefix_bytes(coin->address_type_p2sh, raw); + ripemd160(digest, 32, raw + prelen); + if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) { + return 0; + } + } else { + // non-segwit p2sh multisig + prelen = address_prefix_bytes_len(coin->address_type_p2sh); + address_write_prefix_bytes(coin->address_type_p2sh, raw); + ripemd160(digest, 32, raw + prelen); + if (!base58_encode_check(raw, prelen + 20, coin->curve->hasher_type, address, MAX_ADDR_SIZE)) { + return 0; + } + } + } else if (script_type == InputScriptType_SPENDWITNESS) { + // segwit p2wpkh: pubkey hash is ripemd160 of sha256 + if (!coin->has_segwit || !coin->bech32_prefix) { + return 0; + } + ecdsa_get_pubkeyhash(node->public_key, coin->curve->hasher_type, digest); + if (!segwit_addr_encode(address, coin->bech32_prefix, SEGWIT_VERSION_0, digest, 20)) { + return 0; + } + } else if (script_type == InputScriptType_SPENDP2SHWITNESS) { + // segwit p2wpkh embedded in p2sh + if (!coin->has_segwit) { + return 0; + } + if (!coin->has_address_type_p2sh) { + return 0; + } + ecdsa_get_address_segwit_p2sh(node->public_key, coin->address_type_p2sh, coin->curve->hasher_type, address, MAX_ADDR_SIZE); + } else { + ecdsa_get_address(node->public_key, coin->address_type, coin->curve->hasher_type, address, MAX_ADDR_SIZE); + } + return 1; +} + +int compile_output(const CoinInfo *coin, const HDNode *root, TxOutputType *in, TxOutputBinType *out, bool needs_confirm) +{ + memset(out, 0, sizeof(TxOutputBinType)); + out->amount = in->amount; + uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; + size_t addr_raw_len; + + if (in->script_type == OutputScriptType_PAYTOOPRETURN) { + // only 0 satoshi allowed for OP_RETURN + if (in->amount != 0) { + return 0; // failed to compile output + } + if (needs_confirm) { + layoutConfirmOpReturn(in->op_return_data.bytes, in->op_return_data.size); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return -1; // user aborted + } + } + uint32_t r = 0; + out->script_pubkey.bytes[0] = 0x6A; r++; // OP_RETURN + r += op_push(in->op_return_data.size, out->script_pubkey.bytes + r); + memcpy(out->script_pubkey.bytes + r, in->op_return_data.bytes, in->op_return_data.size); r += in->op_return_data.size; + out->script_pubkey.size = r; + return r; + } + + if (in->address_n_count > 0) { + static CONFIDENTIAL HDNode node; + InputScriptType input_script_type; + + switch (in->script_type) { + case OutputScriptType_PAYTOADDRESS: + input_script_type = InputScriptType_SPENDADDRESS; + break; + case OutputScriptType_PAYTOMULTISIG: + input_script_type = InputScriptType_SPENDMULTISIG; + break; + case OutputScriptType_PAYTOWITNESS: + input_script_type = InputScriptType_SPENDWITNESS; + break; + case OutputScriptType_PAYTOP2SHWITNESS: + input_script_type = InputScriptType_SPENDP2SHWITNESS; + break; + default: + return 0; // failed to compile output + } + memcpy(&node, root, sizeof(HDNode)); + if (hdnode_private_ckd_cached(&node, in->address_n, in->address_n_count, NULL) == 0) { + return 0; // failed to compile output + } + hdnode_fill_public_key(&node); + if (!compute_address(coin, input_script_type, &node, + in->has_multisig, &in->multisig, + in->address)) { + return 0; // failed to compile output + } + } else if (!in->has_address) { + return 0; // failed to compile output + } + + addr_raw_len = base58_decode_check(in->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + size_t prefix_len; + if (coin->has_address_type // p2pkh + && addr_raw_len == 20 + (prefix_len = address_prefix_bytes_len(coin->address_type)) + && address_check_prefix(addr_raw, coin->address_type)) { + out->script_pubkey.bytes[0] = 0x76; // OP_DUP + out->script_pubkey.bytes[1] = 0xA9; // OP_HASH_160 + out->script_pubkey.bytes[2] = 0x14; // pushing 20 bytes + memcpy(out->script_pubkey.bytes + 3, addr_raw + prefix_len, 20); + out->script_pubkey.bytes[23] = 0x88; // OP_EQUALVERIFY + out->script_pubkey.bytes[24] = 0xAC; // OP_CHECKSIG + out->script_pubkey.size = 25; + } else if (coin->has_address_type_p2sh // p2sh + && addr_raw_len == 20 + (prefix_len = address_prefix_bytes_len(coin->address_type_p2sh)) + && address_check_prefix(addr_raw, coin->address_type_p2sh)) { + out->script_pubkey.bytes[0] = 0xA9; // OP_HASH_160 + out->script_pubkey.bytes[1] = 0x14; // pushing 20 bytes + memcpy(out->script_pubkey.bytes + 2, addr_raw + prefix_len, 20); + out->script_pubkey.bytes[22] = 0x87; // OP_EQUAL + out->script_pubkey.size = 23; + } else if (coin->bech32_prefix) { + int witver; + if (!segwit_addr_decode(&witver, addr_raw, &addr_raw_len, coin->bech32_prefix, in->address)) { + return 0; + } + // segwit: + // push 1 byte version id (opcode OP_0 = 0, OP_i = 80+i) + // push addr_raw (segwit_addr_decode makes sure addr_raw_len is at most 40) + out->script_pubkey.bytes[0] = witver == 0 ? 0 : 80 + witver; + out->script_pubkey.bytes[1] = addr_raw_len; + memcpy(out->script_pubkey.bytes + 2, addr_raw, addr_raw_len); + out->script_pubkey.size = addr_raw_len + 2; + } else { + return 0; + } + + if (needs_confirm) { + layoutConfirmOutput(coin, in); + if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmOutput, false)) { + return -1; // user aborted + } + } + + return out->script_pubkey.size; +} + +uint32_t compile_script_sig(uint32_t address_type, const uint8_t *pubkeyhash, uint8_t *out) +{ + if (coinByAddressType(address_type)) { // valid coin type + out[0] = 0x76; // OP_DUP + out[1] = 0xA9; // OP_HASH_160 + out[2] = 0x14; // pushing 20 bytes + memcpy(out + 3, pubkeyhash, 20); + out[23] = 0x88; // OP_EQUALVERIFY + out[24] = 0xAC; // OP_CHECKSIG + return 25; + } else { + return 0; // unsupported + } +} + +// if out == NULL just compute the length +uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t *out) +{ + if (!multisig->has_m) return 0; + const uint32_t m = multisig->m; + const uint32_t n = multisig->pubkeys_count; + if (m < 1 || m > 15) return 0; + if (n < 1 || n > 15) return 0; + uint32_t r = 0; + if (out) { + out[r] = 0x50 + m; r++; + for (uint32_t i = 0; i < n; i++) { + out[r] = 33; r++; // OP_PUSH 33 + const uint8_t *pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])); + if (!pubkey) return 0; + memcpy(out + r, pubkey, 33); r += 33; + } + out[r] = 0x50 + n; r++; + out[r] = 0xAE; r++; // OP_CHECKMULTISIG + } else { + r = 1 + 34 * n + 2; + } + return r; +} + +uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, HasherType hasher_type, uint8_t *hash) +{ + if (!multisig->has_m) return 0; + const uint32_t m = multisig->m; + const uint32_t n = multisig->pubkeys_count; + if (m < 1 || m > 15) return 0; + if (n < 1 || n > 15) return 0; + + Hasher hasher; + hasher_Init(&hasher, hasher_type); + + uint8_t d[2]; + d[0] = 0x50 + m; hasher_Update(&hasher, d, 1); + for (uint32_t i = 0; i < n; i++) { + d[0] = 33; hasher_Update(&hasher, d, 1); // OP_PUSH 33 + const uint8_t *pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])); + if (!pubkey) return 0; + hasher_Update(&hasher, pubkey, 33); + } + d[0] = 0x50 + n; + d[1] = 0xAE; + hasher_Update(&hasher, d, 2); + + hasher_Final(&hasher, hash); + + return 1; +} + +uint32_t serialize_script_sig(const uint8_t *signature, uint32_t signature_len, const uint8_t *pubkey, uint32_t pubkey_len, uint8_t sighash, uint8_t *out) +{ + uint32_t r = 0; + r += op_push(signature_len + 1, out + r); + memcpy(out + r, signature, signature_len); r += signature_len; + out[r] = sighash; r++; + r += op_push(pubkey_len, out + r); + memcpy(out + r, pubkey, pubkey_len); r += pubkey_len; + return r; +} + +uint32_t serialize_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t sighash, uint8_t *out) +{ + uint32_t r = 0; + out[r] = 0x00; r++; + for (uint32_t i = 0; i < multisig->signatures_count; i++) { + if (multisig->signatures[i].size == 0) { + continue; + } + r += op_push(multisig->signatures[i].size + 1, out + r); + memcpy(out + r, multisig->signatures[i].bytes, multisig->signatures[i].size); r += multisig->signatures[i].size; + out[r] = sighash; r++; + } + uint32_t script_len = compile_script_multisig(multisig, 0); + if (script_len == 0) { + return 0; + } + r += op_push(script_len, out + r); + r += compile_script_multisig(multisig, out + r); + return r; +} + +// tx methods + +uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input) +{ + for (int i = 0; i < 32; i++) { + hasher_Update(hasher, &(input->prev_hash.bytes[31 - i]), 1); + } + hasher_Update(hasher, (const uint8_t *)&input->prev_index, 4); + return 36; +} + +uint32_t tx_script_hash(Hasher *hasher, uint32_t size, const uint8_t *data) +{ + int r = ser_length_hash(hasher, size); + hasher_Update(hasher, data, size); + return r + size; +} + +uint32_t tx_sequence_hash(Hasher *hasher, const TxInputType *input) +{ + hasher_Update(hasher, (const uint8_t *)&input->sequence, 4); + return 4; +} + +uint32_t tx_output_hash(Hasher *hasher, const TxOutputBinType *output) +{ + uint32_t r = 0; + hasher_Update(hasher, (const uint8_t *)&output->amount, 8); r += 8; + r += tx_script_hash(hasher, output->script_pubkey.size, output->script_pubkey.bytes); + return r; +} + +uint32_t tx_serialize_script(uint32_t size, const uint8_t *data, uint8_t *out) +{ + int r = ser_length(size, out); + memcpy(out + r, data, size); + return r + size; +} + +uint32_t tx_serialize_header(TxStruct *tx, uint8_t *out) +{ + int r = 4; + memcpy(out, &(tx->version), 4); + if (tx->is_segwit) { + memcpy(out + r, segwit_header, 2); + r += 2; + } + return r + ser_length(tx->inputs_len, out + r); +} + +uint32_t tx_serialize_header_hash(TxStruct *tx) +{ + int r = 4; + hasher_Update(&(tx->hasher), (const uint8_t *)&(tx->version), 4); + if (tx->is_segwit) { + hasher_Update(&(tx->hasher), segwit_header, 2); + r += 2; + } + return r + ser_length_hash(&(tx->hasher), tx->inputs_len); +} + +uint32_t tx_serialize_input(TxStruct *tx, const TxInputType *input, uint8_t *out) +{ + if (tx->have_inputs >= tx->inputs_len) { + // already got all inputs + return 0; + } + uint32_t r = 0; + if (tx->have_inputs == 0) { + r += tx_serialize_header(tx, out + r); + } + for (int i = 0; i < 32; i++) { + *(out + r + i) = input->prev_hash.bytes[31 - i]; + } + r += 32; + memcpy(out + r, &input->prev_index, 4); r += 4; + r += tx_serialize_script(input->script_sig.size, input->script_sig.bytes, out + r); + memcpy(out + r, &input->sequence, 4); r += 4; + + tx->have_inputs++; + tx->size += r; + + return r; +} + +uint32_t tx_serialize_input_hash(TxStruct *tx, const TxInputType *input) +{ + if (tx->have_inputs >= tx->inputs_len) { + // already got all inputs + return 0; + } + uint32_t r = 0; + if (tx->have_inputs == 0) { + r += tx_serialize_header_hash(tx); + } + r += tx_prevout_hash(&(tx->hasher), input); + r += tx_script_hash(&(tx->hasher), input->script_sig.size, input->script_sig.bytes); + r += tx_sequence_hash(&(tx->hasher), input); + + tx->have_inputs++; + tx->size += r; + + return r; +} + +uint32_t tx_serialize_middle(TxStruct *tx, uint8_t *out) +{ + return ser_length(tx->outputs_len, out); +} + +uint32_t tx_serialize_middle_hash(TxStruct *tx) +{ + return ser_length_hash(&(tx->hasher), tx->outputs_len); +} + +uint32_t tx_serialize_footer(TxStruct *tx, uint8_t *out) +{ + memcpy(out, &(tx->lock_time), 4); + return 4; +} + +uint32_t tx_serialize_footer_hash(TxStruct *tx) +{ + hasher_Update(&(tx->hasher), (const uint8_t *)&(tx->lock_time), 4); + return 4; +} + +uint32_t tx_serialize_output(TxStruct *tx, const TxOutputBinType *output, uint8_t *out) +{ + if (tx->have_inputs < tx->inputs_len) { + // not all inputs provided + return 0; + } + if (tx->have_outputs >= tx->outputs_len) { + // already got all outputs + return 0; + } + uint32_t r = 0; + if (tx->have_outputs == 0) { + r += tx_serialize_middle(tx, out + r); + } + memcpy(out + r, &output->amount, 8); r += 8; + r += tx_serialize_script(output->script_pubkey.size, output->script_pubkey.bytes, out + r); + tx->have_outputs++; + if (tx->have_outputs == tx->outputs_len + && !tx->is_segwit) { + r += tx_serialize_footer(tx, out + r); + } + tx->size += r; + return r; +} + +uint32_t tx_serialize_output_hash(TxStruct *tx, const TxOutputBinType *output) +{ + if (tx->have_inputs < tx->inputs_len) { + // not all inputs provided + return 0; + } + if (tx->have_outputs >= tx->outputs_len) { + // already got all outputs + return 0; + } + uint32_t r = 0; + if (tx->have_outputs == 0) { + r += tx_serialize_middle_hash(tx); + } + r += tx_output_hash(&(tx->hasher), output); + tx->have_outputs++; + if (tx->have_outputs == tx->outputs_len + && !tx->is_segwit) { + r += tx_serialize_footer_hash(tx); + } + tx->size += r; + return r; +} + +uint32_t tx_serialize_extra_data_hash(TxStruct *tx, const uint8_t *data, uint32_t datalen) +{ + if (tx->have_inputs < tx->inputs_len) { + // not all inputs provided + return 0; + } + if (tx->have_outputs < tx->outputs_len) { + // not all inputs provided + return 0; + } + if (tx->extra_data_received + datalen > tx->extra_data_len) { + // we are receiving too much data + return 0; + } + hasher_Update(&(tx->hasher), data, datalen); + tx->extra_data_received += datalen; + tx->size += datalen; + return datalen; +} + +void tx_init(TxStruct *tx, uint32_t inputs_len, uint32_t outputs_len, uint32_t version, uint32_t lock_time, uint32_t extra_data_len, HasherType hasher_type) +{ + tx->inputs_len = inputs_len; + tx->outputs_len = outputs_len; + tx->version = version; + tx->lock_time = lock_time; + tx->have_inputs = 0; + tx->have_outputs = 0; + tx->extra_data_len = extra_data_len; + tx->extra_data_received = 0; + tx->size = 0; + tx->is_segwit = false; + hasher_Init(&(tx->hasher), hasher_type); +} + +void tx_hash_final(TxStruct *t, uint8_t *hash, bool reverse) +{ + hasher_Double(&(t->hasher), hash); + if (!reverse) return; + for (uint8_t i = 0; i < 16; i++) { + uint8_t k = hash[31 - i]; + hash[31 - i] = hash[i]; + hash[i] = k; + } +} + +uint32_t tx_input_weight(const TxInputType *txinput) { + uint32_t input_script_size; + if (txinput->has_multisig) { + uint32_t multisig_script_size = TXSIZE_MULTISIGSCRIPT + + txinput->multisig.pubkeys_count * (1 + TXSIZE_PUBKEY); + input_script_size = 1 // the OP_FALSE bug in multisig + + txinput->multisig.m * (1 + TXSIZE_SIGNATURE) + + op_push_size(multisig_script_size) + multisig_script_size; + } else { + input_script_size = (1 + TXSIZE_SIGNATURE + 1 + TXSIZE_PUBKEY); + } + uint32_t weight = 4 * TXSIZE_INPUT; + if (txinput->script_type == InputScriptType_SPENDADDRESS + || txinput->script_type == InputScriptType_SPENDMULTISIG) { + input_script_size += ser_length_size(input_script_size); + weight += 4 * input_script_size; + } else if (txinput->script_type == InputScriptType_SPENDWITNESS + || txinput->script_type == InputScriptType_SPENDP2SHWITNESS) { + if (txinput->script_type == InputScriptType_SPENDP2SHWITNESS) { + weight += 4 * (2 + (txinput->has_multisig + ? TXSIZE_WITNESSSCRIPT : TXSIZE_WITNESSPKHASH)); + } else { + weight += 4; // empty input script + } + weight += input_script_size; // discounted witness + } + return weight; +} + +uint32_t tx_output_weight(const CoinInfo *coin, const TxOutputType *txoutput) { + uint32_t output_script_size = 0; + if (txoutput->script_type == OutputScriptType_PAYTOOPRETURN) { + output_script_size = 1 + op_push_size(txoutput->op_return_data.size) + + txoutput->op_return_data.size; + } else if (txoutput->address_n_count > 0) { + if (txoutput->script_type == OutputScriptType_PAYTOWITNESS) { + output_script_size = txoutput->has_multisig + ? TXSIZE_WITNESSSCRIPT : TXSIZE_WITNESSPKHASH; + } else if (txoutput->script_type == OutputScriptType_PAYTOP2SHWITNESS) { + output_script_size = TXSIZE_P2SCRIPT; + } else { + output_script_size = txoutput->has_multisig + ? TXSIZE_P2SCRIPT : TXSIZE_P2PKHASH; + } + } else { + uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; + int witver; + size_t addr_raw_len; + if (coin->bech32_prefix + && segwit_addr_decode(&witver, addr_raw, &addr_raw_len, coin->bech32_prefix, txoutput->address)) { + output_script_size = 2 + addr_raw_len; + } else { + addr_raw_len = base58_decode_check(txoutput->address, coin->curve->hasher_type, addr_raw, MAX_ADDR_RAW_SIZE); + if (coin->has_address_type + && address_check_prefix(addr_raw, coin->address_type)) { + output_script_size = TXSIZE_P2PKHASH; + } else if (coin->has_address_type_p2sh + && address_check_prefix(addr_raw, coin->address_type_p2sh)) { + output_script_size = TXSIZE_P2SCRIPT; + } + } + } + output_script_size += ser_length_size(output_script_size); + return 4 * (TXSIZE_OUTPUT + output_script_size); +} diff --git a/hardware-wallet/firmware/firmware/transaction.h b/hardware-wallet/firmware/firmware/transaction.h new file mode 100644 index 00000000..a65f5897 --- /dev/null +++ b/hardware-wallet/firmware/firmware/transaction.h @@ -0,0 +1,78 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __TRANSACTION_H__ +#define __TRANSACTION_H__ + +#include +#include +#include "sha2.h" +#include "bip32.h" +#include "coins.h" +#include "hasher.h" +#include "types.pb.h" + +typedef struct { + uint32_t inputs_len; + uint32_t outputs_len; + + uint32_t version; + uint32_t lock_time; + bool is_segwit; + + uint32_t have_inputs; + uint32_t have_outputs; + + uint32_t extra_data_len; + uint32_t extra_data_received; + + uint32_t size; + + Hasher hasher; +} TxStruct; + +bool compute_address(const CoinInfo *coin, InputScriptType script_type, const HDNode *node, bool has_multisig, const MultisigRedeemScriptType *multisig, char address[MAX_ADDR_SIZE]); +uint32_t compile_script_sig(uint32_t address_type, const uint8_t *pubkeyhash, uint8_t *out); +uint32_t compile_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t *out); +uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig, HasherType hasher_type, uint8_t *hash); +uint32_t serialize_script_sig(const uint8_t *signature, uint32_t signature_len, const uint8_t *pubkey, uint32_t pubkey_len, uint8_t sighash, uint8_t *out); +uint32_t serialize_script_multisig(const MultisigRedeemScriptType *multisig, uint8_t sighash, uint8_t *out); +int compile_output(const CoinInfo *coin, const HDNode *root, TxOutputType *in, TxOutputBinType *out, bool needs_confirm); + +uint32_t tx_prevout_hash(Hasher *hasher, const TxInputType *input); +uint32_t tx_script_hash(Hasher *hasher, uint32_t size, const uint8_t *data); +uint32_t tx_sequence_hash(Hasher *hasher, const TxInputType *input); +uint32_t tx_output_hash(Hasher *hasher, const TxOutputBinType *output); +uint32_t tx_serialize_script(uint32_t size, const uint8_t *data, uint8_t *out); + +uint32_t tx_serialize_footer(TxStruct *tx, uint8_t *out); +uint32_t tx_serialize_input(TxStruct *tx, const TxInputType *input, uint8_t *out); +uint32_t tx_serialize_output(TxStruct *tx, const TxOutputBinType *output, uint8_t *out); + +void tx_init(TxStruct *tx, uint32_t inputs_len, uint32_t outputs_len, uint32_t version, uint32_t lock_time, uint32_t extra_data_len, HasherType hasher_type); +uint32_t tx_serialize_header_hash(TxStruct *tx); +uint32_t tx_serialize_input_hash(TxStruct *tx, const TxInputType *input); +uint32_t tx_serialize_output_hash(TxStruct *tx, const TxOutputBinType *output); +uint32_t tx_serialize_extra_data_hash(TxStruct *tx, const uint8_t *data, uint32_t datalen); +void tx_hash_final(TxStruct *t, uint8_t *hash, bool reverse); + +uint32_t tx_input_weight(const TxInputType *txinput); +uint32_t tx_output_weight(const CoinInfo *coin, const TxOutputType *txoutput); + +#endif diff --git a/hardware-wallet/firmware/firmware/trezor.c b/hardware-wallet/firmware/firmware/trezor.c new file mode 100644 index 00000000..8c5d55a9 --- /dev/null +++ b/hardware-wallet/firmware/firmware/trezor.c @@ -0,0 +1,129 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "trezor.h" +#include "oled.h" +#include "bitmaps.h" +#include "util.h" +#include "usb.h" +#include "setup.h" +#include "storage.h" +#include "layout.h" +#include "layout2.h" +#include "rng.h" +#include "timer.h" +#include "buttons.h" +#include "gettext.h" +#include "fastflash.h" + +/* Screen timeout */ +uint32_t system_millis_lock_start; + +void check_lock_screen(void) +{ + buttonUpdate(); + + // wake from screensaver on any button + if (layoutLast == layoutScreensaver && (button.NoUp || button.YesUp)) { + layoutHome(); + return; + } + + // button held for long enough (2 seconds) + if (layoutLast == layoutHome && button.NoDown >= 285000 * 2) { + + layoutDialog(&bmp_icon_question, _("Cancel"), _("Lock Device"), NULL, _("Do you really want to"), _("lock your TREZOR?"), NULL, NULL, NULL, NULL); + + // wait until NoButton is released + usbTiny(1); + do { + usbSleep(5); + buttonUpdate(); + } while (!button.NoUp); + + // wait for confirmation/cancellation of the dialog + do { + usbSleep(5); + buttonUpdate(); + } while (!button.YesUp && !button.NoUp); + usbTiny(0); + + if (button.YesUp) { + // lock the screen + session_clear(true); + layoutScreensaver(); + } else { + // resume homescreen + layoutHome(); + } + } + + // if homescreen is shown for longer than 10 minutes, lock too + if (layoutLast == layoutHome) { + if ((timer_ms() - system_millis_lock_start) >= 600000) { + // lock the screen + session_clear(true); + layoutScreensaver(); + } + } +} + +int main(void) +{ +#ifndef APPVER + setup(); + __stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks + oledInit(); +#else + setupApp(); + __stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks +#endif + +#if FASTFLASH + uint16_t state = gpio_port_read(BTN_PORT); + if ((state & BTN_PIN_NO) == 0) { + run_bootloader(); + } +#endif + + timer_init(); + +#ifdef APPVER + // enable MPU (Memory Protection Unit) + mpu_config(); +#endif + +#if DEBUG_LINK + oledSetDebugLink(1); + storage_wipe(); +#endif + + oledDrawBitmap(40, 0, &bmp_logo64); + oledRefresh(); + + storage_init(); + layoutHome(); + usbInit(); + for (;;) { + usbPoll(); + check_lock_screen(); + } + + return 0; +} diff --git a/hardware-wallet/firmware/firmware/trezor.h b/hardware-wallet/firmware/firmware/trezor.h new file mode 100644 index 00000000..d40a10e2 --- /dev/null +++ b/hardware-wallet/firmware/firmware/trezor.h @@ -0,0 +1,43 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __TREZOR_H__ +#define __TREZOR_H__ + +#include + +#define VERSION_MAJOR 1 +#define VERSION_MINOR 6 +#define VERSION_PATCH 1 + +#define STR(X) #X +#define VERSTR(X) STR(X) + +#ifndef DEBUG_LINK +#define DEBUG_LINK 0 +#endif + +#ifndef DEBUG_LOG +#define DEBUG_LOG 0 +#endif + +/* Screen timeout */ +extern uint32_t system_millis_lock_start; + +#endif diff --git a/hardware-wallet/firmware/firmware/u2f.c b/hardware-wallet/firmware/firmware/u2f.c new file mode 100644 index 00000000..33a5f1c1 --- /dev/null +++ b/hardware-wallet/firmware/firmware/u2f.c @@ -0,0 +1,763 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2015 Mark Bryars + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#include "debug.h" +#include "storage.h" +#include "bip32.h" +#include "layout2.h" +#include "usb.h" +#include "buttons.h" +#include "trezor.h" +#include "curves.h" +#include "nist256p1.h" +#include "rng.h" +#include "hmac.h" +#include "util.h" +#include "gettext.h" + +#include "u2f/u2f.h" +#include "u2f/u2f_hid.h" +#include "u2f/u2f_keys.h" +#include "u2f_knownapps.h" +#include "u2f.h" + +// About 1/2 Second according to values used in protect.c +#define U2F_TIMEOUT (800000/2) +#define U2F_OUT_PKT_BUFFER_LEN 128 + +// Initialise without a cid +static uint32_t cid = 0; + +// Circular Output buffer +static uint32_t u2f_out_start = 0; +static uint32_t u2f_out_end = 0; +static uint8_t u2f_out_packets[U2F_OUT_PKT_BUFFER_LEN][HID_RPT_SIZE]; + +#define U2F_PUBKEY_LEN 65 +#define KEY_PATH_LEN 32 +#define KEY_HANDLE_LEN (KEY_PATH_LEN + SHA256_DIGEST_LENGTH) + +// Derivation path is m/U2F'/r'/r'/r'/r'/r'/r'/r'/r' +#define KEY_PATH_ENTRIES (KEY_PATH_LEN / sizeof(uint32_t)) + +// Defined as UsbSignHandler.BOGUS_APP_ID_HASH +// in https://github.com/google/u2f-ref-code/blob/master/u2f-chrome-extension/usbsignhandler.js#L118 +#define BOGUS_APPID "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + +// Auth/Register request state machine +typedef enum { + INIT = 0, + AUTH = 10, + AUTH_PASS = 11, + REG = 20, + REG_PASS = 21 +} U2F_STATE; + +static U2F_STATE last_req_state = INIT; + +typedef struct { + uint8_t reserved; + uint8_t appId[U2F_APPID_SIZE]; + uint8_t chal[U2F_CHAL_SIZE]; + uint8_t keyHandle[KEY_HANDLE_LEN]; + uint8_t pubKey[U2F_PUBKEY_LEN]; +} U2F_REGISTER_SIG_STR; + +typedef struct { + uint8_t appId[U2F_APPID_SIZE]; + uint8_t flags; + uint8_t ctr[4]; + uint8_t chal[U2F_CHAL_SIZE]; +} U2F_AUTHENTICATE_SIG_STR; + +static uint32_t dialog_timeout = 0; + +uint32_t next_cid(void) +{ + // extremely unlikely but hey + do { + cid = random32(); + } while (cid == 0 || cid == CID_BROADCAST); + return cid; +} + +typedef struct { + uint8_t buf[57+127*59]; + uint8_t *buf_ptr; + uint32_t len; + uint8_t seq; + uint8_t cmd; +} U2F_ReadBuffer; + +U2F_ReadBuffer *reader; + +void u2fhid_read(char tiny, const U2FHID_FRAME *f) +{ + // Always handle init packets directly + if (f->init.cmd == U2FHID_INIT) { + u2fhid_init(f); + if (tiny && reader && f->cid == cid) { + // abort current channel + reader->cmd = 0; + reader->len = 0; + reader->seq = 255; + } + return; + } + + if (tiny) { + // read continue packet + if (reader == 0 || cid != f->cid) { + send_u2fhid_error(f->cid, ERR_CHANNEL_BUSY); + return; + } + + if ((f->type & TYPE_INIT) && reader->seq == 255) { + u2fhid_init_cmd(f); + return; + } + + if (reader->seq != f->cont.seq) { + send_u2fhid_error(f->cid, ERR_INVALID_SEQ); + reader->cmd = 0; + reader->len = 0; + reader->seq = 255; + return; + } + + // check out of bounds + if ((reader->buf_ptr - reader->buf) >= (signed) reader->len + || (reader->buf_ptr + sizeof(f->cont.data) - reader->buf) > (signed) sizeof(reader->buf)) + return; + reader->seq++; + memcpy(reader->buf_ptr, f->cont.data, sizeof(f->cont.data)); + reader->buf_ptr += sizeof(f->cont.data); + return; + } + + u2fhid_read_start(f); +} + +void u2fhid_init_cmd(const U2FHID_FRAME *f) { + reader->seq = 0; + reader->buf_ptr = reader->buf; + reader->len = MSG_LEN(*f); + reader->cmd = f->type; + memcpy(reader->buf_ptr, f->init.data, sizeof(f->init.data)); + reader->buf_ptr += sizeof(f->init.data); + cid = f->cid; +} + +void u2fhid_read_start(const U2FHID_FRAME *f) { + U2F_ReadBuffer readbuffer; + if (!(f->type & TYPE_INIT)) { + return; + } + + // Broadcast is reserved for init + if (f->cid == CID_BROADCAST || f->cid == 0) { + send_u2fhid_error(f->cid, ERR_INVALID_CID); + return; + } + + if ((unsigned)MSG_LEN(*f) > sizeof(reader->buf)) { + send_u2fhid_error(f->cid, ERR_INVALID_LEN); + return; + } + + reader = &readbuffer; + u2fhid_init_cmd(f); + + usbTiny(1); + for(;;) { + // Do we need to wait for more data + while ((reader->buf_ptr - reader->buf) < (signed)reader->len) { + uint8_t lastseq = reader->seq; + uint8_t lastcmd = reader->cmd; + int counter = U2F_TIMEOUT; + while (reader->seq == lastseq && reader->cmd == lastcmd) { + if (counter-- == 0) { + // timeout + send_u2fhid_error(cid, ERR_MSG_TIMEOUT); + cid = 0; + reader = 0; + usbTiny(0); + layoutHome(); + return; + } + usbPoll(); + } + } + + // We have all the data + switch (reader->cmd) { + case 0: + // message was aborted by init + break; + case U2FHID_PING: + u2fhid_ping(reader->buf, reader->len); + break; + case U2FHID_MSG: + u2fhid_msg((APDU *)reader->buf, reader->len); + break; + case U2FHID_WINK: + u2fhid_wink(reader->buf, reader->len); + break; + default: + send_u2fhid_error(cid, ERR_INVALID_CMD); + break; + } + + // wait for next commmand/ button press + reader->cmd = 0; + reader->seq = 255; + while (dialog_timeout > 0 && reader->cmd == 0) { + dialog_timeout--; + usbPoll(); // may trigger new request + buttonUpdate(); + if (button.YesUp && + (last_req_state == AUTH || last_req_state == REG)) { + last_req_state++; + // standard requires to remember button press for 10 seconds. + dialog_timeout = 10 * U2F_TIMEOUT; + } + } + + if (reader->cmd == 0) { + last_req_state = INIT; + cid = 0; + reader = 0; + usbTiny(0); + layoutHome(); + return; + } + } +} + +void u2fhid_ping(const uint8_t *buf, uint32_t len) +{ + debugLog(0, "", "u2fhid_ping"); + send_u2fhid_msg(U2FHID_PING, buf, len); +} + +void u2fhid_wink(const uint8_t *buf, uint32_t len) +{ + debugLog(0, "", "u2fhid_wink"); + (void)buf; + + if (len > 0) + return send_u2fhid_error(cid, ERR_INVALID_LEN); + + if (dialog_timeout > 0) + dialog_timeout = U2F_TIMEOUT; + + U2FHID_FRAME f; + memset(&f, 0, sizeof(f)); + f.cid = cid; + f.init.cmd = U2FHID_WINK; + f.init.bcntl = 0; + queue_u2f_pkt(&f); +} + +void u2fhid_init(const U2FHID_FRAME *in) +{ + const U2FHID_INIT_REQ *init_req = (const U2FHID_INIT_REQ *)&in->init.data; + U2FHID_FRAME f; + U2FHID_INIT_RESP resp; + + debugLog(0, "", "u2fhid_init"); + + if (in->cid == 0) { + send_u2fhid_error(in->cid, ERR_INVALID_CID); + return; + } + + memset(&f, 0, sizeof(f)); + f.cid = in->cid; + f.init.cmd = U2FHID_INIT; + f.init.bcnth = 0; + f.init.bcntl = U2FHID_INIT_RESP_SIZE; + + memcpy(resp.nonce, init_req->nonce, sizeof(init_req->nonce)); + resp.cid = in->cid == CID_BROADCAST ? next_cid() : in->cid; + resp.versionInterface = U2FHID_IF_VERSION; + resp.versionMajor = VERSION_MAJOR; + resp.versionMinor = VERSION_MINOR; + resp.versionBuild = VERSION_PATCH; + resp.capFlags = CAPFLAG_WINK; + memcpy(&f.init.data, &resp, sizeof(resp)); + + queue_u2f_pkt(&f); +} + +void queue_u2f_pkt(const U2FHID_FRAME *u2f_pkt) +{ + // debugLog(0, "", "u2f_write_pkt"); + uint32_t next = (u2f_out_end + 1) % U2F_OUT_PKT_BUFFER_LEN; + if (u2f_out_start == next) { + debugLog(0, "", "u2f_write_pkt full"); + return; // Buffer full :( + } + memcpy(u2f_out_packets[u2f_out_end], u2f_pkt, HID_RPT_SIZE); + u2f_out_end = next; +} + +uint8_t *u2f_out_data(void) +{ + if (u2f_out_start == u2f_out_end) + return NULL; // No data + // debugLog(0, "", "u2f_out_data"); + uint32_t t = u2f_out_start; + u2f_out_start = (u2f_out_start + 1) % U2F_OUT_PKT_BUFFER_LEN; + return u2f_out_packets[t]; +} + +void u2fhid_msg(const APDU *a, uint32_t len) +{ + if ((APDU_LEN(*a) + sizeof(APDU)) > len) { + debugLog(0, "", "BAD APDU LENGTH"); + debugInt(APDU_LEN(*a)); + debugInt(len); + return; + } + + if (a->cla != 0) { + send_u2f_error(U2F_SW_CLA_NOT_SUPPORTED); + return; + } + + switch (a->ins) { + case U2F_REGISTER: + u2f_register(a); + break; + case U2F_AUTHENTICATE: + u2f_authenticate(a); + break; + case U2F_VERSION: + u2f_version(a); + break; + default: + debugLog(0, "", "u2f unknown cmd"); + send_u2f_error(U2F_SW_INS_NOT_SUPPORTED); + } +} + +void send_u2fhid_msg(const uint8_t cmd, const uint8_t *data, const uint32_t len) +{ + U2FHID_FRAME f; + uint8_t *p = (uint8_t *)data; + uint32_t l = len; + uint32_t psz; + uint8_t seq = 0; + + // debugLog(0, "", "send_u2fhid_msg"); + + memset(&f, 0, sizeof(f)); + f.cid = cid; + f.init.cmd = cmd; + f.init.bcnth = len >> 8; + f.init.bcntl = len & 0xff; + + // Init packet + psz = MIN(sizeof(f.init.data), l); + memcpy(f.init.data, p, psz); + queue_u2f_pkt(&f); + l -= psz; + p += psz; + + // Cont packet(s) + for (; l > 0; l -= psz, p += psz) { + // debugLog(0, "", "send_u2fhid_msg con"); + memset(&f.cont.data, 0, sizeof(f.cont.data)); + f.cont.seq = seq++; + psz = MIN(sizeof(f.cont.data), l); + memcpy(f.cont.data, p, psz); + queue_u2f_pkt(&f); + } + + if (data + len != p) { + debugLog(0, "", "send_u2fhid_msg is bad"); + debugInt(data + len - p); + } +} + +void send_u2fhid_error(uint32_t fcid, uint8_t err) +{ + U2FHID_FRAME f; + + memset(&f, 0, sizeof(f)); + f.cid = fcid; + f.init.cmd = U2FHID_ERROR; + f.init.bcntl = 1; + f.init.data[0] = err; + queue_u2f_pkt(&f); +} + +void u2f_version(const APDU *a) +{ + if (APDU_LEN(*a) != 0) { + debugLog(0, "", "u2f version - badlen"); + send_u2f_error(U2F_SW_WRONG_LENGTH); + return; + } + + // INCLUDES SW_NO_ERROR + static const uint8_t version_response[] = {'U', '2', 'F', '_', + 'V', '2', 0x90, 0x00}; + debugLog(0, "", "u2f version"); + send_u2f_msg(version_response, sizeof(version_response)); +} + +static void getReadableAppId(const uint8_t appid[U2F_APPID_SIZE], const char **appname, const BITMAP **appicon) { + static char buf[8+2+8+1]; + + for (unsigned int i = 0; i < sizeof(u2f_well_known)/sizeof(U2FWellKnown); i++) { + if (memcmp(appid, u2f_well_known[i].appid, U2F_APPID_SIZE) == 0) { + *appname = u2f_well_known[i].appname; + *appicon = u2f_well_known[i].appicon; + return; + } + } + + data2hex(appid, 4, &buf[0]); + buf[8] = buf[9] = '.'; + data2hex(appid + (U2F_APPID_SIZE - 4), 4, &buf[10]); + *appname = buf; + *appicon = NULL; +} + +static const HDNode *getDerivedNode(uint32_t *address_n, size_t address_n_count) +{ + static CONFIDENTIAL HDNode node; + if (!storage_getU2FRoot(&node)) { + layoutHome(); + debugLog(0, "", "ERR: Device not init"); + return 0; + } + if (!address_n || address_n_count == 0) { + return &node; + } + for (size_t i = 0; i < address_n_count; i++) { + if (hdnode_private_ckd(&node, address_n[i]) == 0) { + layoutHome(); + debugLog(0, "", "ERR: Derive private failed"); + return 0; + } + } + return &node; +} + +static const HDNode *generateKeyHandle(const uint8_t app_id[], uint8_t key_handle[]) +{ + uint8_t keybase[U2F_APPID_SIZE + KEY_PATH_LEN]; + + // Derivation path is m/U2F'/r'/r'/r'/r'/r'/r'/r'/r' + uint32_t key_path[KEY_PATH_ENTRIES]; + for (uint32_t i = 0; i < KEY_PATH_ENTRIES; i++) { + // high bit for hardened keys + key_path[i]= 0x80000000 | random32(); + } + + // First half of keyhandle is key_path + memcpy(key_handle, key_path, KEY_PATH_LEN); + + // prepare keypair from /random data + const HDNode *node = getDerivedNode(key_path, KEY_PATH_ENTRIES); + if (!node) + return NULL; + + // For second half of keyhandle + // Signature of app_id and random data + memcpy(&keybase[0], app_id, U2F_APPID_SIZE); + memcpy(&keybase[U2F_APPID_SIZE], key_handle, KEY_PATH_LEN); + hmac_sha256(node->private_key, sizeof(node->private_key), + keybase, sizeof(keybase), &key_handle[KEY_PATH_LEN]); + + // Done! + return node; +} + + +static const HDNode *validateKeyHandle(const uint8_t app_id[], const uint8_t key_handle[]) +{ + uint32_t key_path[KEY_PATH_ENTRIES]; + memcpy(key_path, key_handle, KEY_PATH_LEN); + for (unsigned int i = 0; i < KEY_PATH_ENTRIES; i++) { + // check high bit for hardened keys + if (! (key_path[i] & 0x80000000)) { + return NULL; + } + } + + const HDNode *node = getDerivedNode(key_path, KEY_PATH_ENTRIES); + if (!node) + return NULL; + + uint8_t keybase[U2F_APPID_SIZE + KEY_PATH_LEN]; + memcpy(&keybase[0], app_id, U2F_APPID_SIZE); + memcpy(&keybase[U2F_APPID_SIZE], key_handle, KEY_PATH_LEN); + + + uint8_t hmac[SHA256_DIGEST_LENGTH]; + hmac_sha256(node->private_key, sizeof(node->private_key), + keybase, sizeof(keybase), hmac); + + if (memcmp(&key_handle[KEY_PATH_LEN], hmac, SHA256_DIGEST_LENGTH) != 0) + return NULL; + + // Done! + return node; +} + + +void u2f_register(const APDU *a) +{ + static U2F_REGISTER_REQ last_req; + const U2F_REGISTER_REQ *req = (U2F_REGISTER_REQ *)a->data; + + if (!storage_isInitialized()) { + send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED); + return; + } + + // Validate basic request parameters + debugLog(0, "", "u2f register"); + if (APDU_LEN(*a) != sizeof(U2F_REGISTER_REQ)) { + debugLog(0, "", "u2f register - badlen"); + send_u2f_error(U2F_SW_WRONG_LENGTH); + return; + } + + // If this request is different from last request, reset state machine + if (memcmp(&last_req, req, sizeof(last_req)) != 0) { + memcpy(&last_req, req, sizeof(last_req)); + last_req_state = INIT; + } + + // First Time request, return not present and display request dialog + if (last_req_state == INIT) { + // error: testof-user-presence is required + buttonUpdate(); // Clear button state + if (0 == memcmp(req->appId, BOGUS_APPID, U2F_APPID_SIZE)) { + layoutDialog(&bmp_icon_warning, NULL, _("OK"), NULL, _("Another U2F device"), _("was used to register"), _("in this application."), NULL, NULL, NULL); + } else { + const char *appname; + const BITMAP *appicon; + getReadableAppId(req->appId, &appname, &appicon); + layoutU2FDialog(_("Register"), appname, appicon); + } + last_req_state = REG; + } + + // Still awaiting Keypress + if (last_req_state == REG) { + // error: testof-user-presence is required + send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED); + dialog_timeout = U2F_TIMEOUT; + return; + } + + // Buttons said yes + if (last_req_state == REG_PASS) { + uint8_t data[sizeof(U2F_REGISTER_RESP) + 2]; + U2F_REGISTER_RESP *resp = (U2F_REGISTER_RESP *)&data; + memset(data, 0, sizeof(data)); + + resp->registerId = U2F_REGISTER_ID; + resp->keyHandleLen = KEY_HANDLE_LEN; + // Generate keypair for this appId + const HDNode *node = + generateKeyHandle(req->appId, (uint8_t*)&resp->keyHandleCertSig); + + if (!node) { + debugLog(0, "", "getDerivedNode Fail"); + send_u2f_error(U2F_SW_WRONG_DATA); // error:bad key handle + return; + } + + ecdsa_get_public_key65(node->curve->params, node->private_key, + (uint8_t *)&resp->pubKey); + + memcpy(resp->keyHandleCertSig + resp->keyHandleLen, + U2F_ATT_CERT, sizeof(U2F_ATT_CERT)); + + uint8_t sig[64]; + U2F_REGISTER_SIG_STR sig_base; + sig_base.reserved = 0; + memcpy(sig_base.appId, req->appId, U2F_APPID_SIZE); + memcpy(sig_base.chal, req->chal, U2F_CHAL_SIZE); + memcpy(sig_base.keyHandle, &resp->keyHandleCertSig, KEY_HANDLE_LEN); + memcpy(sig_base.pubKey, &resp->pubKey, U2F_PUBKEY_LEN); + if (ecdsa_sign(&nist256p1, HASHER_SHA2, U2F_ATT_PRIV_KEY, (uint8_t *)&sig_base, sizeof(sig_base), sig, NULL, NULL) != 0) { + send_u2f_error(U2F_SW_WRONG_DATA); + return; + } + + // Where to write the signature in the response + uint8_t *resp_sig = resp->keyHandleCertSig + + resp->keyHandleLen + sizeof(U2F_ATT_CERT); + // Convert to der for the response + const uint8_t sig_len = ecdsa_sig_to_der(sig, resp_sig); + + // Append success bytes + memcpy(resp->keyHandleCertSig + resp->keyHandleLen + + sizeof(U2F_ATT_CERT) + sig_len, + "\x90\x00", 2); + + int l = 1 /* registerId */ + U2F_PUBKEY_LEN + + 1 /* keyhandleLen */ + resp->keyHandleLen + + sizeof(U2F_ATT_CERT) + sig_len + 2; + + last_req_state = INIT; + dialog_timeout = 0; + send_u2f_msg(data, l); + return; + } + + // Didnt expect to get here + dialog_timeout = 0; +} + +void u2f_authenticate(const APDU *a) +{ + const U2F_AUTHENTICATE_REQ *req = (U2F_AUTHENTICATE_REQ *)a->data; + static U2F_AUTHENTICATE_REQ last_req; + + if (!storage_isInitialized()) { + send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED); + return; + } + + if (APDU_LEN(*a) < 64) { /// FIXME: decent value + debugLog(0, "", "u2f authenticate - badlen"); + send_u2f_error(U2F_SW_WRONG_LENGTH); + return; + } + + if (req->keyHandleLen != KEY_HANDLE_LEN) { + debugLog(0, "", "u2f auth - bad keyhandle len"); + send_u2f_error(U2F_SW_WRONG_DATA); // error:bad key handle + return; + } + + const HDNode *node = + validateKeyHandle(req->appId, req->keyHandle); + + if (!node) { + debugLog(0, "", "u2f auth - bad keyhandle len"); + send_u2f_error(U2F_SW_WRONG_DATA); // error:bad key handle + return; + } + + if (a->p1 == U2F_AUTH_CHECK_ONLY) { + debugLog(0, "", "u2f authenticate check"); + // This is a success for a good keyhandle + // A failed check would have happened earlier + // error: testof-user-presence is required + send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED); + return; + } + + if (a->p1 != U2F_AUTH_ENFORCE) { + debugLog(0, "", "u2f authenticate unknown"); + // error:bad key handle + send_u2f_error(U2F_SW_WRONG_DATA); + return; + } + + debugLog(0, "", "u2f authenticate enforce"); + + if (memcmp(&last_req, req, sizeof(last_req)) != 0) { + memcpy(&last_req, req, sizeof(last_req)); + last_req_state = INIT; + } + + if (last_req_state == INIT) { + // error: testof-user-presence is required + buttonUpdate(); // Clear button state + const char *appname; + const BITMAP *appicon; + getReadableAppId(req->appId, &appname, &appicon); + layoutU2FDialog(_("Authenticate"), appname, appicon); + last_req_state = AUTH; + } + + // Awaiting Keypress + if (last_req_state == AUTH) { + // error: testof-user-presence is required + send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED); + dialog_timeout = U2F_TIMEOUT; + return; + } + + // Buttons said yes + if (last_req_state == AUTH_PASS) { + uint8_t buf[sizeof(U2F_AUTHENTICATE_RESP) + 2]; + U2F_AUTHENTICATE_RESP *resp = + (U2F_AUTHENTICATE_RESP *)&buf; + + const uint32_t ctr = storage_nextU2FCounter(); + resp->flags = U2F_AUTH_FLAG_TUP; + resp->ctr[0] = ctr >> 24 & 0xff; + resp->ctr[1] = ctr >> 16 & 0xff; + resp->ctr[2] = ctr >> 8 & 0xff; + resp->ctr[3] = ctr & 0xff; + + // Build and sign response + U2F_AUTHENTICATE_SIG_STR sig_base; + uint8_t sig[64]; + memcpy(sig_base.appId, req->appId, U2F_APPID_SIZE); + sig_base.flags = resp->flags; + memcpy(sig_base.ctr, resp->ctr, 4); + memcpy(sig_base.chal, req->chal, U2F_CHAL_SIZE); + if (ecdsa_sign(&nist256p1, HASHER_SHA2, node->private_key, (uint8_t *)&sig_base, sizeof(sig_base), sig, NULL, NULL) != 0) { + send_u2f_error(U2F_SW_WRONG_DATA); + return; + } + + // Copy DER encoded signature into response + const uint8_t sig_len = ecdsa_sig_to_der(sig, resp->sig); + + // Append OK + memcpy(buf + sizeof(U2F_AUTHENTICATE_RESP) - + U2F_MAX_EC_SIG_SIZE + sig_len, + "\x90\x00", 2); + last_req_state = INIT; + dialog_timeout = 0; + send_u2f_msg(buf, sizeof(U2F_AUTHENTICATE_RESP) - + U2F_MAX_EC_SIG_SIZE + sig_len + + 2); + } +} + +void send_u2f_error(const uint16_t err) +{ + uint8_t data[2]; + data[0] = err >> 8 & 0xFF; + data[1] = err & 0xFF; + send_u2f_msg(data, 2); +} + +void send_u2f_msg(const uint8_t *data, const uint32_t len) +{ + send_u2fhid_msg(U2FHID_MSG, data, len); +} diff --git a/hardware-wallet/firmware/firmware/u2f.h b/hardware-wallet/firmware/firmware/u2f.h new file mode 100644 index 00000000..9eb0cca6 --- /dev/null +++ b/hardware-wallet/firmware/firmware/u2f.h @@ -0,0 +1,62 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2015 Mark Bryars + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __U2F_H__ +#define __U2F_H__ + +#include +#include +#include "u2f/u2f_hid.h" +#include "trezor.h" + +#define U2F_KEY_PATH 0x80553246 + +typedef struct { + uint8_t cla, ins, p1, p2; + uint8_t lc1, lc2, lc3; + uint8_t data[]; +} APDU; + +#define APDU_LEN(A) (uint32_t)(((A).lc1 << 16) + ((A).lc2 << 8) + ((A).lc3)) + +void u2fhid_read(char tiny, const U2FHID_FRAME *buf); +void u2fhid_init_cmd(const U2FHID_FRAME *f); +void u2fhid_read_start(const U2FHID_FRAME *f); +bool u2fhid_write(uint8_t *buf); +void u2fhid_init(const U2FHID_FRAME *in); +void u2fhid_ping(const uint8_t *buf, uint32_t len); +void u2fhid_wink(const uint8_t *buf, uint32_t len); +void u2fhid_sync(const uint8_t *buf, uint32_t len); +void u2fhid_lock(const uint8_t *buf, uint32_t len); +void u2fhid_msg(const APDU *a, uint32_t len); +void queue_u2f_pkt(const U2FHID_FRAME *u2f_pkt); + +uint8_t *u2f_out_data(void); +void u2f_register(const APDU *a); +void u2f_version(const APDU *a); +void u2f_authenticate(const APDU *a); + +void send_u2f_msg(const uint8_t *data, uint32_t len); +void send_u2f_error(uint16_t err); + +void send_u2fhid_msg(const uint8_t cmd, const uint8_t *data, + const uint32_t len); +void send_u2fhid_error(uint32_t fcid, uint8_t err); + +#endif diff --git a/hardware-wallet/firmware/firmware/u2f/genkeys.sh b/hardware-wallet/firmware/firmware/u2f/genkeys.sh new file mode 100755 index 00000000..33371d5b --- /dev/null +++ b/hardware-wallet/firmware/firmware/u2f/genkeys.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -e + +cat > u2f_keys.h < + +const uint8_t U2F_ATT_PRIV_KEY[] = { +EOF + +if [ \! -e trezordevkey.pem ]; then + openssl ecparam -genkey -out trezordevkey.pem -name prime256v1 +fi +openssl ec -in trezordevkey.pem -text | + perl -e '$key = "\t"; while (<>) { + if (/priv:/) { $priv = 1 } + elsif (/pub:/) { $priv = 0 } + elsif ($priv) { + while ($_ =~ s/.*?([0-9a-f]{2})//) { + $key .= "0x$1,"; + if ($num++ % 8 == 7) { $key .= "\n\t"; } + else {$key .= " ";} + } + } + } + $key =~ s/,\s*$/\n/s; + print $key;' >> u2f_keys.h +cat >> u2f_keys.h <> u2f_keys.h + +cat >> u2f_keys.h <. +*/ + +// Common U2F raw message format header. +// 2014-08-14 J Ehrensvard, Yubico, Inc. + +#ifndef __U2F_H_INCLUDED__ +#define __U2F_H_INCLUDED__ + +#ifdef _MSC_VER // Windows +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long int uint64_t; +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +// General constants + +#define U2F_EC_KEY_SIZE 32 // EC key size in bytes +#define U2F_EC_POINT_SIZE ((U2F_EC_KEY_SIZE * 2) + 1) // Size of EC point +#define U2F_MAX_KH_SIZE 128 // Max size of key handle +#define U2F_MAX_ATT_CERT_SIZE 1024 // Max size of attestation certificate +#define U2F_MAX_EC_SIG_SIZE 72 // Max size of DER coded EC signature +#define U2F_CTR_SIZE 4 // Size of counter field +#define U2F_APPID_SIZE 32 // Size of application id +#define U2F_CHAL_SIZE 32 // Size of challenge + +#define ENC_SIZE(x) ((x + 7) & 0xfff8) + +// EC (uncompressed) point + +#define U2F_POINT_UNCOMPRESSED 0x04 // Uncompressed point format + + typedef struct + { + uint8_t pointFormat; // Point type + uint8_t x[U2F_EC_KEY_SIZE]; // X-value + uint8_t y[U2F_EC_KEY_SIZE]; // Y-value + } U2F_EC_POINT; + +// U2F native commands + +#define U2F_REGISTER 0x01 // Registration command +#define U2F_AUTHENTICATE 0x02 // Authenticate/sign command +#define U2F_VERSION 0x03 // Read version string command + +#define U2F_VENDOR_FIRST 0x40 // First vendor defined command +#define U2F_VENDOR_LAST 0x7f // Last vendor defined command + +// U2F_CMD_REGISTER command defines + +#define U2F_REGISTER_ID 0x05 // Version 2 registration identifier +#define U2F_REGISTER_HASH_ID 0x00 // Version 2 hash identintifier + + typedef struct + { + uint8_t chal[U2F_CHAL_SIZE]; // Challenge + uint8_t appId[U2F_APPID_SIZE]; // Application id + } U2F_REGISTER_REQ; + + typedef struct + { + uint8_t registerId; // Registration identifier (U2F_REGISTER_ID_V2) + U2F_EC_POINT pubKey; // Generated public key + uint8_t keyHandleLen; // Length of key handle + uint8_t keyHandleCertSig[U2F_MAX_KH_SIZE + // Key handle + U2F_MAX_ATT_CERT_SIZE + // Attestation certificate + U2F_MAX_EC_SIG_SIZE]; // Registration signature + } U2F_REGISTER_RESP; + +// U2F_CMD_AUTHENTICATE command defines + +// Authentication control byte + +#define U2F_AUTH_ENFORCE 0x03 // Enforce user presence and sign +#define U2F_AUTH_CHECK_ONLY 0x07 // Check only +#define U2F_AUTH_FLAG_TUP 0x01 // Test of user presence set + + typedef struct + { + uint8_t chal[U2F_CHAL_SIZE]; // Challenge + uint8_t appId[U2F_APPID_SIZE]; // Application id + uint8_t keyHandleLen; // Length of key handle + uint8_t keyHandle[U2F_MAX_KH_SIZE]; // Key handle + } U2F_AUTHENTICATE_REQ; + + typedef struct + { + uint8_t flags; // U2F_AUTH_FLAG_ values + uint8_t ctr[U2F_CTR_SIZE]; // Counter field (big-endian) + uint8_t sig[U2F_MAX_EC_SIG_SIZE]; // Signature + } U2F_AUTHENTICATE_RESP; + +// Common raw message format (ISO7816-4:2005 mapping) + + typedef struct + { + uint8_t cla; // Class - reserved + uint8_t ins; // U2F instruction + uint8_t p1; // U2F parameter 1 + uint8_t p2; // U2F parameter 2 + uint8_t lc1; // Length field, set to zero + uint8_t lc2; // Length field, MSB + uint8_t lc3; // Length field, LSB + uint8_t data[1]; // Data field + } U2F_MSG; + +// Command status responses + +#define U2F_SW_NO_ERROR 0x9000 // SW_NO_ERROR +#define U2F_SW_WRONG_LENGTH 0x6700 // SW_WRONG_LENGTH +#define U2F_SW_DATA_INVALID 0x6984 // SW_WRONG_DATA +#define U2F_SW_CONDITIONS_NOT_SATISFIED 0x6985 // SW_CONDITIONS_NOT_SATISFIED +#define U2F_SW_WRONG_DATA 0x6a80 // SW_WRONG_DATA +#define U2F_SW_INS_NOT_SUPPORTED 0x6d00 // SW_INS_NOT_SUPPORTED +#define U2F_SW_CLA_NOT_SUPPORTED 0x6e00 // SW_CLA_NOT_SUPPORTED + +#ifdef __cplusplus +} +#endif + +#endif // __U2F_H_INCLUDED__ diff --git a/hardware-wallet/firmware/firmware/u2f/u2f_hid.h b/hardware-wallet/firmware/firmware/u2f/u2f_hid.h new file mode 100644 index 00000000..326a3fc2 --- /dev/null +++ b/hardware-wallet/firmware/firmware/u2f/u2f_hid.h @@ -0,0 +1,142 @@ +/* + Copyright (C) 2013-2015 Yubico AB + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, 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 Lesser + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +// Common U2F HID transport header. +// 2014-08-21 J Ehrensvard, Yubico, Inc. + +#ifndef __U2FHID_H_INCLUDED__ +#define __U2FHID_H_INCLUDED__ + +#ifdef _MSC_VER // Windows +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long int uint64_t; +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +// Size of HID reports + +#define HID_RPT_SIZE 64 // Default size of raw HID report + +// Frame layout - command- and continuation frames + +#define CID_BROADCAST 0xffffffff // Broadcast channel id + +#define TYPE_MASK 0x80 // Frame type mask +#define TYPE_INIT 0x80 // Initial frame identifier +#define TYPE_CONT 0x00 // Continuation frame identifier + + typedef struct + { + uint32_t cid; // Channel identifier + union + { + uint8_t type; // Frame type - b7 defines type + struct + { + uint8_t cmd; // Command - b7 set + uint8_t bcnth; // Message byte count - high part + uint8_t bcntl; // Message byte count - low part + uint8_t data[HID_RPT_SIZE - 7]; // Data payload + } init; + struct + { + uint8_t seq; // Sequence number - b7 cleared + uint8_t data[HID_RPT_SIZE - 5]; // Data payload + } cont; + }; + } U2FHID_FRAME; + +#define FRAME_TYPE(f) ((f).type & TYPE_MASK) +#define FRAME_CMD(f) ((f).init.cmd & ~TYPE_MASK) +#define MSG_LEN(f) (((f).init.bcnth << 8) + (f).init.bcntl) +#define FRAME_SEQ(f) ((f).cont.seq & ~TYPE_MASK) + +// HID usage- and usage-page definitions + +#define FIDO_USAGE_PAGE 0xf1d0 // FIDO alliance HID usage page +#define FIDO_USAGE_U2FHID 0x01 // U2FHID usage for top-level collection +#define FIDO_USAGE_DATA_IN 0x20 // Raw IN data report +#define FIDO_USAGE_DATA_OUT 0x21 // Raw OUT data report + +// General constants + +#define U2FHID_IF_VERSION 2 // Current interface implementation version +#define U2FHID_FRAME_TIMEOUT 500 // Default frame timeout in ms +#define U2FHID_TRANS_TIMEOUT 3000 // Default message timeout in ms + +// U2FHID native commands + +#define U2FHID_PING (TYPE_INIT | 0x01) // Echo data through local processor only +#define U2FHID_MSG (TYPE_INIT | 0x03) // Send U2F message frame +#define U2FHID_LOCK (TYPE_INIT | 0x04) // Send lock channel command +#define U2FHID_INIT (TYPE_INIT | 0x06) // Channel initialization +#define U2FHID_WINK (TYPE_INIT | 0x08) // Send device identification wink +#define U2FHID_ERROR (TYPE_INIT | 0x3f) // Error response + +#define U2FHID_VENDOR_FIRST (TYPE_INIT | 0x40) // First vendor defined command +#define U2FHID_VENDOR_LAST (TYPE_INIT | 0x7f) // Last vendor defined command + +// U2FHID_INIT command defines + +#define INIT_NONCE_SIZE 8 // Size of channel initialization challenge +#define CAPFLAG_WINK 0x01 // Device supports WINK command +#define CAPFLAG_LOCK 0x02 // Device supports LOCK command + + typedef struct + { + uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce + } U2FHID_INIT_REQ; + + typedef struct + { + uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce + uint32_t cid; // Channel identifier + uint8_t versionInterface; // Interface version + uint8_t versionMajor; // Major version number + uint8_t versionMinor; // Minor version number + uint8_t versionBuild; // Build version number + uint8_t capFlags; // Capabilities flags + } U2FHID_INIT_RESP; + +#define U2FHID_INIT_RESP_SIZE 17 + +// Low-level error codes. Return as negatives. + +#define ERR_NONE 0x00 // No error +#define ERR_INVALID_CMD 0x01 // Invalid command +#define ERR_INVALID_PAR 0x02 // Invalid parameter +#define ERR_INVALID_LEN 0x03 // Invalid message length +#define ERR_INVALID_SEQ 0x04 // Invalid message sequencing +#define ERR_MSG_TIMEOUT 0x05 // Message has timed out +#define ERR_CHANNEL_BUSY 0x06 // Channel busy +#define ERR_LOCK_REQUIRED 0x0a // Command requires channel lock +#define ERR_INVALID_CID 0x0b // Command not allowed on this cid +#define ERR_OTHER 0x7f // Other unspecified error + +#ifdef __cplusplus +} +#endif + +#endif // __U2FHID_H_INCLUDED__ diff --git a/hardware-wallet/firmware/firmware/u2f/u2f_keys.h b/hardware-wallet/firmware/firmware/u2f/u2f_keys.h new file mode 100644 index 00000000..680a730e --- /dev/null +++ b/hardware-wallet/firmware/firmware/u2f/u2f_keys.h @@ -0,0 +1,40 @@ +#ifndef __U2F_KEYS_H_INCLUDED__ +#define __U2F_KEYS_H_INCLUDED__ + +#include + +const uint8_t U2F_ATT_PRIV_KEY[] = { + 0x71, 0x26, 0xac, 0x2b, 0xf6, 0x44, 0xdc, 0x61, + 0x86, 0xad, 0x83, 0xef, 0x1f, 0xcd, 0xf1, 0x2a, + 0x57, 0xb5, 0xcf, 0xa2, 0x00, 0x0b, 0x8a, 0xd0, + 0x27, 0xe9, 0x56, 0xe8, 0x54, 0xc5, 0x0a, 0x8b +}; + +const uint8_t U2F_ATT_CERT[] = { + 0x30, 0x82, 0x01, 0x18, 0x30, 0x81, 0xc0, 0x02, 0x09, 0x00, 0xb1, 0xd9, + 0x8f, 0x42, 0x64, 0x72, 0xd3, 0x2c, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x54, 0x72, 0x65, 0x7a, 0x6f, + 0x72, 0x20, 0x55, 0x32, 0x46, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, + 0x34, 0x32, 0x39, 0x31, 0x33, 0x33, 0x31, 0x35, 0x33, 0x5a, 0x17, 0x0d, + 0x32, 0x36, 0x30, 0x34, 0x32, 0x37, 0x31, 0x33, 0x33, 0x31, 0x35, 0x33, + 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x0a, 0x54, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x20, 0x55, 0x32, 0x46, + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0xd9, 0x18, 0xbd, 0xfa, 0x8a, 0x54, 0xac, 0x92, 0xe9, + 0x0d, 0xa9, 0x1f, 0xca, 0x7a, 0xa2, 0x64, 0x54, 0xc0, 0xd1, 0x73, 0x36, + 0x31, 0x4d, 0xde, 0x83, 0xa5, 0x4b, 0x86, 0xb5, 0xdf, 0x4e, 0xf0, 0x52, + 0x65, 0x9a, 0x1d, 0x6f, 0xfc, 0xb7, 0x46, 0x7f, 0x1a, 0xcd, 0xdb, 0x8a, + 0x33, 0x08, 0x0b, 0x5e, 0xed, 0x91, 0x89, 0x13, 0xf4, 0x43, 0xa5, 0x26, + 0x1b, 0xc7, 0x7b, 0x68, 0x60, 0x6f, 0xc1, 0x30, 0x0a, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, + 0x02, 0x20, 0x24, 0x1e, 0x81, 0xff, 0xd2, 0xe5, 0xe6, 0x15, 0x36, 0x94, + 0xc3, 0x55, 0x2e, 0x8f, 0xeb, 0xd7, 0x1e, 0x89, 0x35, 0x92, 0x1c, 0xb4, + 0x83, 0x41, 0x43, 0x71, 0x1c, 0x76, 0xea, 0xee, 0xf3, 0x95, 0x02, 0x20, + 0x5f, 0x80, 0xeb, 0x10, 0xf2, 0x5c, 0xcc, 0x39, 0x8b, 0x3c, 0xa8, 0xa9, + 0xad, 0xa4, 0x02, 0x7f, 0x93, 0x13, 0x20, 0x77, 0xb7, 0xab, 0xce, 0x77, + 0x46, 0x5a, 0x27, 0xf5, 0x3d, 0x33, 0xa1, 0x1d, +}; + +#endif // __U2F_KEYS_H_INCLUDED__ diff --git a/hardware-wallet/firmware/firmware/u2f_knownapps.h b/hardware-wallet/firmware/firmware/u2f_knownapps.h new file mode 100644 index 00000000..a6a25ea8 --- /dev/null +++ b/hardware-wallet/firmware/firmware/u2f_knownapps.h @@ -0,0 +1,136 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2016 Jochen Hoenicke + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __U2F_KNOWNAPPS_H_INCLUDED__ +#define __U2F_KNOWNAPPS_H_INCLUDED__ + +#include +#include "u2f/u2f.h" +#include "bitmaps.h" + +typedef struct { + const uint8_t appid[U2F_APPID_SIZE]; + const char *appname; + const BITMAP *appicon; +} U2FWellKnown; + +static const U2FWellKnown u2f_well_known[] = { + { + // https://www.gstatic.com/securitykey/origins.json + { 0xa5, 0x46, 0x72, 0xb2, 0x22, 0xc4, 0xcf, 0x95, + 0xe1, 0x51, 0xed, 0x8d, 0x4d, 0x3c, 0x76, 0x7a, + 0x6c, 0xc3, 0x49, 0x43, 0x59, 0x43, 0x79, 0x4e, + 0x88, 0x4f, 0x3d, 0x02, 0x3a, 0x82, 0x29, 0xfd }, + "Google", + &bmp_u2f_google + }, + { + // https://github.com/u2f/trusted_facets + { 0x70, 0x61, 0x7d, 0xfe, 0xd0, 0x65, 0x86, 0x3a, + 0xf4, 0x7c, 0x15, 0x55, 0x6c, 0x91, 0x79, 0x88, + 0x80, 0x82, 0x8c, 0xc4, 0x07, 0xfd, 0xf7, 0x0a, + 0xe8, 0x50, 0x11, 0x56, 0x94, 0x65, 0xa0, 0x75 }, + "GitHub", + &bmp_u2f_github + }, + { + // https://www.dropbox.com/u2f-app-id.json + { 0xc5, 0x0f, 0x8a, 0x7b, 0x70, 0x8e, 0x92, 0xf8, + 0x2e, 0x7a, 0x50, 0xe2, 0xbd, 0xc5, 0x5d, 0x8f, + 0xd9, 0x1a, 0x22, 0xfe, 0x6b, 0x29, 0xc0, 0xcd, + 0xf7, 0x80, 0x55, 0x30, 0x84, 0x2a, 0xf5, 0x81 }, + "Dropbox", + &bmp_u2f_dropbox + }, + { + // https://slushpool.com/static/security/u2f.json + { 0x08, 0xb2, 0xa3, 0xd4, 0x19, 0x39, 0xaa, 0x31, + 0x66, 0x84, 0x93, 0xcb, 0x36, 0xcd, 0xcc, 0x4f, + 0x16, 0xc4, 0xd9, 0xb4, 0xc8, 0x23, 0x8b, 0x73, + 0xc2, 0xf6, 0x72, 0xc0, 0x33, 0x00, 0x71, 0x97 }, + "Slush Pool", + &bmp_u2f_slushpool + }, + { + // https://bitbucket.org + { 0x12, 0x74, 0x3b, 0x92, 0x12, 0x97, 0xb7, 0x7f, + 0x11, 0x35, 0xe4, 0x1f, 0xde, 0xdd, 0x4a, 0x84, + 0x6a, 0xfe, 0x82, 0xe1, 0xf3, 0x69, 0x32, 0xa9, + 0x91, 0x2f, 0x3b, 0x0d, 0x8d, 0xfb, 0x7d, 0x0e }, + "Bitbucket", + &bmp_u2f_bitbucket + }, + { + // https://gitlab.com + { 0xe7, 0xbe, 0x96, 0xa5, 0x1b, 0xd0, 0x19, 0x2a, + 0x72, 0x84, 0x0d, 0x2e, 0x59, 0x09, 0xf7, 0x2b, + 0xa8, 0x2a, 0x2f, 0xe9, 0x3f, 0xaa, 0x62, 0x4f, + 0x03, 0x39, 0x6b, 0x30, 0xe4, 0x94, 0xc8, 0x04 }, + "GitLab", + &bmp_u2f_gitlab + }, + { + // https://www.fastmail.com + { 0x69, 0x66, 0xab, 0xe3, 0x67, 0x4e, 0xa2, 0xf5, + 0x30, 0x79, 0xeb, 0x71, 0x01, 0x97, 0x84, 0x8c, + 0x9b, 0xe6, 0xf3, 0x63, 0x99, 0x2f, 0xd0, 0x29, + 0xe9, 0x89, 0x84, 0x47, 0xcb, 0x9f, 0x00, 0x84 }, + "FastMail", + &bmp_u2f_fastmail + }, + { + // https://account.gandi.net/api/u2f/trusted_facets.json + { 0xa4, 0xe2, 0x2d, 0xca, 0xfe, 0xa7, 0xe9, 0x0e, + 0x12, 0x89, 0x50, 0x11, 0x39, 0x89, 0xfc, 0x45, + 0x97, 0x8d, 0xc9, 0xfb, 0x87, 0x76, 0x75, 0x60, + 0x51, 0x6c, 0x1c, 0x69, 0xdf, 0xdf, 0xd1, 0x96 }, + "Gandi", + &bmp_u2f_gandi, + }, + { + // https://www.bitfinex.com + { 0x30, 0x2f, 0xd5, 0xb4, 0x49, 0x2a, 0x07, 0xb9, + 0xfe, 0xbb, 0x30, 0xe7, 0x32, 0x69, 0xec, 0xa5, + 0x01, 0x20, 0x5c, 0xcf, 0xe0, 0xc2, 0x0b, 0xf7, + 0xb4, 0x72, 0xfa, 0x2d, 0x31, 0xe2, 0x1e, 0x63 }, + "Bitfinex", + &bmp_u2f_bitfinex + }, + { + // https://demo.yubico.com + { 0x55, 0x67, 0x3b, 0x51, 0x38, 0xcc, 0x90, 0xd3, + 0xb7, 0xf3, 0x2b, 0xfd, 0xad, 0x6a, 0x38, 0xa8, + 0xed, 0xd7, 0xb3, 0x55, 0xb7, 0x7a, 0xb9, 0x79, + 0x21, 0x96, 0xf1, 0x06, 0xd1, 0x6c, 0xa3, 0x12 }, + "Yubico U2F Demo", + &bmp_u2f_yubico + }, + { + // https://u2f.bin.coffee + { + 0x1b, 0x3c, 0x16, 0xdd, 0x2f, 0x7c, 0x46, 0xe2, + 0xb4, 0xc2, 0x89, 0xdc, 0x16, 0x74, 0x6b, 0xcc, + 0x60, 0xdf, 0xcf, 0x0f, 0xb8, 0x18, 0xe1, 0x32, + 0x15, 0x52, 0x6e, 0x14, 0x08, 0xe7, 0xf4, 0x68 }, + "u2f.bin.coffee", + NULL + } +}; + +#endif // U2F_KNOWNAPPS_INCLUDED diff --git a/hardware-wallet/firmware/firmware/udp.c b/hardware-wallet/firmware/firmware/udp.c new file mode 100644 index 00000000..04959aed --- /dev/null +++ b/hardware-wallet/firmware/firmware/udp.c @@ -0,0 +1,70 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2017 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include "usb.h" + +#include "messages.h" +#include "timer.h" + +static volatile char tiny = 0; + +void usbInit(void) { + emulatorSocketInit(); +} + +void usbPoll(void) { + emulatorPoll(); + + static uint8_t buffer[64]; + if (emulatorSocketRead(buffer, sizeof(buffer)) > 0) { + if (!tiny) { + msg_read(buffer, sizeof(buffer)); + } else { + msg_read_tiny(buffer, sizeof(buffer)); + } + } + + const uint8_t *data = msg_out_data(); + +#if DEBUG_LINK + if (data == NULL) { + data = msg_debug_out_data(); + } +#endif + + if (data != NULL) { + emulatorSocketWrite(data, 64); + } +} + +char usbTiny(char set) { + char old = tiny; + tiny = set; + return old; +} + +void usbSleep(uint32_t millis) { + uint32_t start = timer_ms(); + + while ((timer_ms() - start) < millis) { + usbPoll(); + } +} diff --git a/hardware-wallet/firmware/firmware/usb.c b/hardware-wallet/firmware/firmware/usb.c new file mode 100644 index 00000000..7a59b6fa --- /dev/null +++ b/hardware-wallet/firmware/firmware/usb.c @@ -0,0 +1,454 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#include "trezor.h" +#include "usb.h" +#include "debug.h" +#include "messages.h" +#include "u2f.h" +#include "storage.h" +#include "util.h" +#include "timer.h" + +#define USB_INTERFACE_INDEX_MAIN 0 +#if DEBUG_LINK +#define USB_INTERFACE_INDEX_DEBUG 1 +#define USB_INTERFACE_INDEX_U2F 2 +#else +#define USB_INTERFACE_INDEX_U2F 1 +#endif + +#define ENDPOINT_ADDRESS_IN (0x81) +#define ENDPOINT_ADDRESS_OUT (0x01) +#define ENDPOINT_ADDRESS_DEBUG_IN (0x82) +#define ENDPOINT_ADDRESS_DEBUG_OUT (0x02) +#define ENDPOINT_ADDRESS_U2F_IN (0x83) +#define ENDPOINT_ADDRESS_U2F_OUT (0x03) + +#define USB_STRINGS \ + X(MANUFACTURER, "SatoshiLabs") \ + X(PRODUCT, "TREZOR") \ + X(SERIAL_NUMBER, storage_uuid_str) \ + X(INTERFACE_MAIN, "TREZOR Interface") \ + X(INTERFACE_DEBUG, "TREZOR Debug Link Interface") \ + X(INTERFACE_U2F, "U2F Interface") + +#define X(name, value) USB_STRING_##name, +enum { + USB_STRING_LANGID_CODES, // LANGID code array + USB_STRINGS +}; +#undef X + +#define X(name, value) value, +static const char *usb_strings[] = { + USB_STRINGS +}; +#undef X + +static const struct usb_device_descriptor dev_descr = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x534c, + .idProduct = 0x0001, + .bcdDevice = 0x0100, + .iManufacturer = USB_STRING_MANUFACTURER, + .iProduct = USB_STRING_PRODUCT, + .iSerialNumber = USB_STRING_SERIAL_NUMBER, + .bNumConfigurations = 1, +}; + +static const uint8_t hid_report_descriptor[] = { + 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined) + 0x09, 0x01, // USAGE (1) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x20, // USAGE (Input Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x21, // USAGE (Output Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION +}; + +#if DEBUG_LINK +static const uint8_t hid_report_descriptor_debug[] = { + 0x06, 0x01, 0xff, // USAGE_PAGE (Vendor Defined) + 0x09, 0x01, // USAGE (1) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x20, // USAGE (Input Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x21, // USAGE (Output Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION +}; +#endif + +static const uint8_t hid_report_descriptor_u2f[] = { + 0x06, 0xd0, 0xf1, // USAGE_PAGE (FIDO Alliance) + 0x09, 0x01, // USAGE (U2F HID Authenticator Device) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x20, // USAGE (Input Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x21, // USAGE (Output Report Data) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x40, // REPORT_COUNT (64) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0xc0 // END_COLLECTION +}; + +static const struct { + struct usb_hid_descriptor hid_descriptor; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report; +} __attribute__((packed)) hid_function = { + .hid_descriptor = { + .bLength = sizeof(hid_function), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0111, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor), + } +}; + +static const struct { + struct usb_hid_descriptor hid_descriptor_u2f; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report_u2f; +} __attribute__((packed)) hid_function_u2f = { + .hid_descriptor_u2f = { + .bLength = sizeof(hid_function_u2f), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0111, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report_u2f = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor_u2f), + } +}; + + +static const struct usb_endpoint_descriptor hid_endpoints[2] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_IN, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_OUT, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}}; + +static const struct usb_interface_descriptor hid_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = USB_INTERFACE_INDEX_MAIN, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = USB_STRING_INTERFACE_MAIN, + .endpoint = hid_endpoints, + .extra = &hid_function, + .extralen = sizeof(hid_function), +}}; + +static const struct usb_endpoint_descriptor hid_endpoints_u2f[2] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_U2F_IN, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 2, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_U2F_OUT, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 2, +}}; + +static const struct usb_interface_descriptor hid_iface_u2f[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = USB_INTERFACE_INDEX_U2F, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = USB_STRING_INTERFACE_U2F, + .endpoint = hid_endpoints_u2f, + .extra = &hid_function_u2f, + .extralen = sizeof(hid_function_u2f), +}}; + +#if DEBUG_LINK +static const struct usb_endpoint_descriptor hid_endpoints_debug[2] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_DEBUG_IN, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = ENDPOINT_ADDRESS_DEBUG_OUT, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 64, + .bInterval = 1, +}}; + +static const struct usb_interface_descriptor hid_iface_debug[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = USB_INTERFACE_INDEX_DEBUG, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = USB_STRING_INTERFACE_DEBUG, + .endpoint = hid_endpoints_debug, + .extra = &hid_function, + .extralen = sizeof(hid_function), +}}; +#endif + +static const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = hid_iface, +#if DEBUG_LINK +}, { + .num_altsetting = 1, + .altsetting = hid_iface_debug, +#endif +}, { + .num_altsetting = 1, + .altsetting = hid_iface_u2f, +}}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, +#if DEBUG_LINK + .bNumInterfaces = 3, +#else + .bNumInterfaces = 2, +#endif + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + .interface = ifaces, +}; + +static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) +{ + (void)complete; + (void)dev; + + if ((req->bmRequestType != 0x81) || + (req->bRequest != USB_REQ_GET_DESCRIPTOR) || + (req->wValue != 0x2200)) + return 0; + + if (req->wIndex == USB_INTERFACE_INDEX_U2F) { + debugLog(0, "", "hid_control_request u2f"); + *buf = (uint8_t *)hid_report_descriptor_u2f; + *len = sizeof(hid_report_descriptor_u2f); + return 1; + } + +#if DEBUG_LINK + if (req->wIndex == USB_INTERFACE_INDEX_DEBUG) { + debugLog(0, "", "hid_control_request debug"); + *buf = (uint8_t *)hid_report_descriptor_debug; + *len = sizeof(hid_report_descriptor_debug); + return 1; + } +#endif + + debugLog(0, "", "hid_control_request main"); + *buf = (uint8_t *)hid_report_descriptor; + *len = sizeof(hid_report_descriptor); + return 1; +} + +static volatile char tiny = 0; + +static void hid_rx_callback(usbd_device *dev, uint8_t ep) +{ + (void)ep; + static CONFIDENTIAL uint8_t buf[64] __attribute__ ((aligned(4))); + if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_OUT, buf, 64) != 64) return; + debugLog(0, "", "hid_rx_callback"); + if (!tiny) { + msg_read(buf, 64); + } else { + msg_read_tiny(buf, 64); + } +} + +static void hid_u2f_rx_callback(usbd_device *dev, uint8_t ep) +{ + (void)ep; + static CONFIDENTIAL uint8_t buf[64] __attribute__ ((aligned(4))); + + debugLog(0, "", "hid_u2f_rx_callback"); + if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_U2F_OUT, buf, 64) != 64) return; + u2fhid_read(tiny, (const U2FHID_FRAME *) (void*) buf); +} + +#if DEBUG_LINK +static void hid_debug_rx_callback(usbd_device *dev, uint8_t ep) +{ + (void)ep; + static CONFIDENTIAL uint8_t buf[64] __attribute__ ((aligned(4))); + if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_DEBUG_OUT, buf, 64) != 64) return; + debugLog(0, "", "hid_debug_rx_callback"); + if (!tiny) { + msg_debug_read(buf, 64); + } else { + msg_read_tiny(buf, 64); + } +} +#endif + +static void hid_set_config(usbd_device *dev, uint16_t wValue) +{ + (void)wValue; + + usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_U2F_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_U2F_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_u2f_rx_callback); +#if DEBUG_LINK + usbd_ep_setup(dev, ENDPOINT_ADDRESS_DEBUG_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_DEBUG_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_debug_rx_callback); +#endif + + usbd_register_control_callback( + dev, + USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + hid_control_request); +} + +static usbd_device *usbd_dev; +static uint8_t usbd_control_buffer[128]; + +void usbInit(void) +{ + usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, sizeof(usb_strings) / sizeof(*usb_strings), usbd_control_buffer, sizeof(usbd_control_buffer)); + usbd_register_set_config_callback(usbd_dev, hid_set_config); +} + +void usbPoll(void) +{ + static const uint8_t *data; + // poll read buffer + usbd_poll(usbd_dev); + // write pending data + data = msg_out_data(); + if (data) { + while ( usbd_ep_write_packet(usbd_dev, ENDPOINT_ADDRESS_IN, data, 64) != 64 ) {} + } + data = u2f_out_data(); + if (data) { + while ( usbd_ep_write_packet(usbd_dev, ENDPOINT_ADDRESS_U2F_IN, data, 64) != 64 ) {} + } +#if DEBUG_LINK + // write pending debug data + data = msg_debug_out_data(); + if (data) { + while ( usbd_ep_write_packet(usbd_dev, ENDPOINT_ADDRESS_DEBUG_IN, data, 64) != 64 ) {} + } +#endif +} + +void usbReconnect(void) +{ + usbd_disconnect(usbd_dev, 1); + delay(1000); + usbd_disconnect(usbd_dev, 0); +} + +char usbTiny(char set) +{ + char old = tiny; + tiny = set; + return old; +} + +void usbSleep(uint32_t millis) +{ + uint32_t start = timer_ms(); + + while ((timer_ms() - start) < millis) { + usbd_poll(usbd_dev); + } +} diff --git a/hardware-wallet/firmware/firmware/usb.h b/hardware-wallet/firmware/firmware/usb.h new file mode 100644 index 00000000..46426777 --- /dev/null +++ b/hardware-wallet/firmware/firmware/usb.h @@ -0,0 +1,29 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __USB_H__ +#define __USB_H__ + +void usbInit(void); +void usbPoll(void); +void usbReconnect(void); +char usbTiny(char set); +void usbSleep(uint32_t millis); + +#endif diff --git a/hardware-wallet/firmware/gen/Makefile b/hardware-wallet/firmware/gen/Makefile new file mode 100644 index 00000000..c518d918 --- /dev/null +++ b/hardware-wallet/firmware/gen/Makefile @@ -0,0 +1,9 @@ +CC=gcc + +all: strwidth + +strwidth: strwidth.c fonts.c + $(CC) strwidth.c fonts.c -o strwidth -lreadline + +clean: + rm -f strwidth diff --git a/hardware-wallet/firmware/gen/bitmaps.c b/hardware-wallet/firmware/gen/bitmaps.c new file mode 100644 index 00000000..b86073fd --- /dev/null +++ b/hardware-wallet/firmware/gen/bitmaps.c @@ -0,0 +1,69 @@ +#include "bitmaps.h" + +const uint8_t bmp_digit0_data[] = { 0xff, 0xff, 0xf8, 0x1f, 0xf0, 0x0f, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xf0, 0x0f, 0xf8, 0x1f, 0xff, 0xff, }; +const uint8_t bmp_digit1_data[] = { 0xff, 0xff, 0xfc, 0x3f, 0xf8, 0x3f, 0xf0, 0x3f, 0xf0, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xff, 0xff, }; +const uint8_t bmp_digit2_data[] = { 0xff, 0xff, 0xe0, 0x1f, 0xe0, 0x0f, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xf8, 0x0f, 0xf0, 0x1f, 0xe1, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe0, 0x07, 0xe0, 0x07, 0xff, 0xff, }; +const uint8_t bmp_digit3_data[] = { 0xff, 0xff, 0xe0, 0x1f, 0xe0, 0x0f, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xf8, 0x0f, 0xf8, 0x0f, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xe0, 0x0f, 0xe0, 0x1f, 0xff, 0xff, }; +const uint8_t bmp_digit4_data[] = { 0xff, 0xff, 0xff, 0x0f, 0xfe, 0x0f, 0xfc, 0x0f, 0xf8, 0x0f, 0xf1, 0x0f, 0xe3, 0x0f, 0xc7, 0x0f, 0xcf, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0xff, }; +const uint8_t bmp_digit5_data[] = { 0xff, 0xff, 0xe0, 0x1f, 0xe0, 0x1f, 0xe7, 0xff, 0xe7, 0xff, 0xe0, 0x1f, 0xe0, 0x0f, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xff, 0x87, 0xe0, 0x0f, 0xe0, 0x1f, 0xff, 0xff, }; +const uint8_t bmp_digit6_data[] = { 0xff, 0xff, 0xf8, 0x1f, 0xf0, 0x1f, 0xe1, 0xff, 0xe1, 0xff, 0xe0, 0x1f, 0xe0, 0x0f, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xf0, 0x0f, 0xf8, 0x1f, 0xff, 0xff, }; +const uint8_t bmp_digit7_data[] = { 0xff, 0xff, 0xe0, 0x07, 0xe0, 0x07, 0xff, 0x87, 0xff, 0x87, 0xff, 0x0f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfc, 0x3f, 0xf8, 0x7f, 0xf8, 0x7f, 0xf8, 0x7f, 0xf8, 0x7f, 0xf8, 0x7f, 0xf8, 0x7f, 0xff, 0xff, }; +const uint8_t bmp_digit8_data[] = { 0xff, 0xff, 0xf8, 0x1f, 0xf0, 0x0f, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xf0, 0x0f, 0xf0, 0x0f, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xf0, 0x0f, 0xf8, 0x1f, 0xff, 0xff, }; +const uint8_t bmp_digit9_data[] = { 0xff, 0xff, 0xf8, 0x1f, 0xf0, 0x0f, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xf0, 0x07, 0xf8, 0x07, 0xff, 0x87, 0xff, 0x87, 0xf8, 0x0f, 0xf8, 0x1f, 0xff, 0xff, }; +const uint8_t bmp_gears0_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x3e, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x1f, 0xe0, 0x00, 0x00, 0x1f, 0xf0, 0x1f, 0xe0, 0x00, 0x00, 0x1f, 0xf0, 0x1f, 0xe0, 0x00, 0x00, 0x1f, 0xf0, 0x1f, 0xc0, 0x00, 0x00, 0x01, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0xc0, 0x18, 0x00, 0x00, 0x7f, 0xfd, 0xe0, 0x3c, 0x00, 0x00, 0x7f, 0xfd, 0xe0, 0x7c, 0x00, 0x00, 0xff, 0xfd, 0xff, 0xf8, 0x00, 0x00, 0xf8, 0x7e, 0xff, 0xf8, 0x00, 0x00, 0xf0, 0x1e, 0xff, 0xf0, 0x00, 0x00, 0x60, 0x0d, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x3f, 0xc0, 0x00, 0x00, 0x3f, 0xe0, 0x3f, 0xc0, 0x00, 0x00, 0x3f, 0xe0, 0x3f, 0xc0, 0x00, 0x00, 0x07, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_gears1_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xcf, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x01, 0xf0, 0x1f, 0xe0, 0x00, 0x00, 0x01, 0xf0, 0x1f, 0xe0, 0x00, 0x00, 0x01, 0xf8, 0x3f, 0xe1, 0xc0, 0x00, 0x00, 0xff, 0xfc, 0xc1, 0xc0, 0x00, 0x00, 0xff, 0xfb, 0x03, 0xc0, 0x00, 0x01, 0xff, 0xf7, 0xc3, 0xc0, 0x00, 0x03, 0xff, 0xf7, 0xff, 0xc0, 0x00, 0x03, 0xc7, 0xf7, 0xff, 0xe0, 0x00, 0x01, 0x81, 0xf3, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0x80, 0x00, 0x00, 0xe1, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xf0, 0x7f, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x3f, 0x80, 0x00, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_gears2_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc1, 0x80, 0x00, 0x00, 0x07, 0x3f, 0xf7, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x3e, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x3f, 0x0e, 0x00, 0x00, 0x07, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x06, 0x1f, 0xe1, 0x9f, 0x83, 0x00, 0x00, 0x0f, 0xce, 0x7f, 0xef, 0x80, 0x00, 0x07, 0x9f, 0xff, 0xff, 0x80, 0x00, 0x07, 0x9f, 0xff, 0xff, 0x00, 0x00, 0x03, 0x8f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x7e, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0c, 0x3f, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_gears3_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x81, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xe1, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0xe0, 0x00, 0x00, 0x01, 0xf0, 0x1f, 0xc0, 0x00, 0x00, 0x01, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x3e, 0x70, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x78, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x7c, 0x0e, 0x00, 0x00, 0x1f, 0xff, 0x7f, 0x9f, 0x00, 0x00, 0x1f, 0x87, 0x7f, 0xff, 0x00, 0x00, 0x1e, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x1e, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x0c, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3f, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x3f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x7f, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x07, 0x8f, 0xe0, 0x00, 0x00, 0x00, 0x03, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_icon_error_data[] = { 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7b, 0xde, 0xf1, 0x8f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfc, 0x3f, 0xf8, 0x1f, 0xf1, 0x8f, 0x7b, 0xde, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, }; +const uint8_t bmp_icon_info_data[] = { 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3e, 0x7c, 0x7e, 0x7e, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0x7e, 0x7e, 0x3e, 0x7c, 0x1f, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, }; +const uint8_t bmp_icon_ok_data[] = { 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xbf, 0xf9, 0x3f, 0xf8, 0x7f, 0xfc, 0xff, 0x7e, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, }; +const uint8_t bmp_icon_question_data[] = { 0x07, 0xe0, 0x0f, 0xf0, 0x1e, 0x78, 0x3c, 0x3c, 0x79, 0x9e, 0xf3, 0xcf, 0xff, 0xcf, 0xff, 0x9f, 0xff, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f, 0x7f, 0xfe, 0x3e, 0x7c, 0x1e, 0x78, 0x0f, 0xf0, 0x07, 0xe0, }; +const uint8_t bmp_icon_warning_data[] = { 0x01, 0x80, 0x01, 0x80, 0x03, 0xc0, 0x03, 0xc0, 0x07, 0xe0, 0x07, 0xe0, 0x0e, 0x70, 0x0e, 0x70, 0x1e, 0x78, 0x1e, 0x78, 0x3e, 0x7c, 0x3f, 0xfc, 0x7e, 0x7e, 0x7e, 0x7e, 0xff, 0xff, 0xff, 0xff, }; +const uint8_t bmp_logo48_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0x81, 0xfc, 0x00, 0x00, 0x3e, 0x00, 0x7c, 0x00, 0x00, 0x7c, 0x00, 0x3e, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x00, 0x00, 0xf8, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xc0, 0x00, 0x03, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x01, 0xf0, 0x0f, 0xe0, 0x00, 0x07, 0xf0, 0x0f, 0xfc, 0x00, 0x3f, 0xf0, 0x0f, 0xff, 0x81, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_logo48_empty_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, 0x81, 0x80, 0x00, 0x00, 0x06, 0x00, 0x60, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x10, 0x7e, 0x08, 0x00, 0x00, 0x21, 0x81, 0x84, 0x00, 0x00, 0x22, 0x00, 0x44, 0x00, 0x00, 0x44, 0x00, 0x22, 0x00, 0x00, 0x48, 0x00, 0x12, 0x00, 0x00, 0x88, 0x00, 0x11, 0x00, 0x00, 0x90, 0x00, 0x09, 0x00, 0x00, 0x90, 0x00, 0x09, 0x00, 0x00, 0x90, 0x00, 0x09, 0x00, 0x00, 0x90, 0x00, 0x09, 0x00, 0x00, 0x90, 0x00, 0x09, 0x00, 0x00, 0x90, 0x00, 0x09, 0x00, 0x03, 0x9f, 0xff, 0xf9, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x3f, 0xff, 0xfc, 0x10, 0x08, 0x40, 0x00, 0x02, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x80, 0x00, 0x01, 0x10, 0x08, 0x60, 0x00, 0x06, 0x10, 0x08, 0x1c, 0x00, 0x38, 0x10, 0x08, 0x03, 0x81, 0xc0, 0x10, 0x07, 0x00, 0x7e, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x07, 0x00, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x03, 0x81, 0xc0, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_logo64_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xf0, 0x1f, 0xf8, 0x00, 0x00, 0x3f, 0xc0, 0x07, 0xf8, 0x00, 0x00, 0x7f, 0x80, 0x03, 0xfc, 0x00, 0x00, 0x7f, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0x80, 0x03, 0xff, 0xf0, 0x1f, 0xc0, 0x00, 0x00, 0x07, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x1f, 0xe0, 0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xfc, 0x00, 0x00, 0x7f, 0xf0, 0x1f, 0xff, 0x00, 0x01, 0xff, 0xf0, 0x1f, 0xff, 0xf0, 0x1f, 0xff, 0xf0, 0x1f, 0xff, 0xfc, 0x7f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_logo64_empty_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x0f, 0xe0, 0x10, 0x00, 0x00, 0x20, 0x30, 0x18, 0x08, 0x00, 0x00, 0x20, 0x40, 0x04, 0x08, 0x00, 0x00, 0x40, 0x80, 0x02, 0x04, 0x00, 0x00, 0x41, 0x00, 0x01, 0x04, 0x00, 0x00, 0x42, 0x00, 0x00, 0x84, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x84, 0x00, 0x00, 0x42, 0x00, 0x00, 0x84, 0x00, 0x00, 0x42, 0x00, 0x00, 0x84, 0x00, 0x00, 0x42, 0x00, 0x00, 0x84, 0x00, 0x00, 0x42, 0x00, 0x00, 0x84, 0x00, 0x00, 0x42, 0x00, 0x00, 0x84, 0x00, 0x00, 0x42, 0x00, 0x00, 0x84, 0x00, 0x00, 0x42, 0x00, 0x00, 0x87, 0xff, 0xff, 0xc2, 0x00, 0x03, 0x80, 0x00, 0x00, 0x03, 0x80, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x7f, 0xfc, 0x00, 0x10, 0x10, 0x3f, 0x80, 0x03, 0xf8, 0x10, 0x10, 0x40, 0x00, 0x00, 0x04, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x80, 0x00, 0x00, 0x02, 0x10, 0x10, 0x60, 0x00, 0x00, 0x0c, 0x10, 0x10, 0x1c, 0x00, 0x00, 0x70, 0x10, 0x10, 0x03, 0x00, 0x01, 0x80, 0x10, 0x10, 0x00, 0xf0, 0x1e, 0x00, 0x10, 0x10, 0x00, 0x0c, 0x60, 0x00, 0x10, 0x0e, 0x00, 0x03, 0x80, 0x00, 0xe0, 0x01, 0xc0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x01, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_bitbucket_data[] = { 0x00, 0x3f, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xf0, 0x3f, 0x00, 0x01, 0xf8, 0x3c, 0x00, 0x00, 0x78, 0x3f, 0x00, 0x01, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xe3, 0x8f, 0xf0, 0x1f, 0xe7, 0xcf, 0xf0, 0x1f, 0xe7, 0xcf, 0xf0, 0x1f, 0xe7, 0xcf, 0xf0, 0x0f, 0xe3, 0x8f, 0xe0, 0x0f, 0xf0, 0x1f, 0xe0, 0x0f, 0xf8, 0x3f, 0xe0, 0x07, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x00, 0x04, 0x3f, 0xf8, 0x40, 0x07, 0x00, 0x01, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0xe0, 0x00, }; +const uint8_t bmp_u2f_bitfinex_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xa0, 0x00, 0x0f, 0xff, 0x20, 0x00, 0x3f, 0xff, 0x60, 0x00, 0x7f, 0xfe, 0xe0, 0x00, 0xff, 0xfc, 0xe0, 0x01, 0xff, 0xf1, 0xe0, 0x01, 0xff, 0xe3, 0xe0, 0x03, 0xff, 0xc7, 0xe0, 0x03, 0xff, 0x8f, 0xc0, 0x07, 0xfe, 0x0f, 0xc0, 0x07, 0xfc, 0x1f, 0xc0, 0x07, 0xf0, 0x7f, 0x80, 0x07, 0x80, 0xff, 0x80, 0x00, 0x01, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_dropbox_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x07, 0xf8, 0x1f, 0xe0, 0x0f, 0xfc, 0x3f, 0xf8, 0x3f, 0xfe, 0x7f, 0xfc, 0x7f, 0xfe, 0x7f, 0xff, 0x7f, 0xfc, 0x1f, 0xfe, 0x3f, 0xf0, 0x0f, 0xfc, 0x1f, 0xe0, 0x03, 0xf8, 0x07, 0x80, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x60, 0x07, 0x80, 0x01, 0xf0, 0x1f, 0xe0, 0x03, 0xf8, 0x3f, 0xf0, 0x0f, 0xfc, 0x7f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x1f, 0xfe, 0x7f, 0xfc, 0x0f, 0xfc, 0x3f, 0xf0, 0x03, 0xf9, 0x9f, 0xc0, 0x00, 0xe3, 0xc7, 0x80, 0x00, 0x47, 0xe2, 0x00, 0x03, 0x1f, 0xf8, 0x40, 0x03, 0xff, 0xfd, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_fastmail_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xf8, 0x4f, 0xff, 0xff, 0xf2, 0x67, 0xff, 0xff, 0xe6, 0x73, 0xff, 0xff, 0xce, 0x79, 0xff, 0xff, 0x9e, 0x7c, 0xff, 0xff, 0x3e, 0x7e, 0x7f, 0xfe, 0x7e, 0x7f, 0x3f, 0xfc, 0xfe, 0x7f, 0x9f, 0xf9, 0xfe, 0x7f, 0xcf, 0xf3, 0xfe, 0x7f, 0xe7, 0xe7, 0xfe, 0x7f, 0xf3, 0xcf, 0xfe, 0x7f, 0xf8, 0x1f, 0xfe, 0x7f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_gandi_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0x1c, 0x70, 0x00, 0x00, 0x1c, 0x70, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x01, 0x8f, 0xe1, 0x00, 0x03, 0xc7, 0xc3, 0x80, 0x03, 0xe0, 0x07, 0x80, 0x01, 0xf0, 0x1f, 0x80, 0x01, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf8, 0x30, 0x00, 0x00, 0xf0, 0xfc, 0x00, 0x00, 0xf1, 0xfe, 0x00, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xf1, 0xcf, 0x00, 0x00, 0xf0, 0x8f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x78, 0x1f, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_github_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x78, 0x1f, 0x80, 0x01, 0xf8, 0x1f, 0xe0, 0x03, 0xf8, 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 0x20, 0x04, 0x1f, 0xf0, 0x70, 0x0e, 0x0f, 0x70, 0xf0, 0x0f, 0x0e, 0x70, 0xf8, 0x1f, 0x0e, 0x70, 0x70, 0x0e, 0x0e, 0x30, 0x70, 0x0e, 0x0c, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 0x70, 0x07, 0x80, 0x01, 0xe0, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_gitlab_data[] = { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x70, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0x01, 0xf8, 0x1f, 0x80, 0x01, 0xf8, 0x1f, 0x80, 0x01, 0xf8, 0x3f, 0xc0, 0x03, 0xfc, 0x3f, 0xc0, 0x03, 0xfc, 0x3f, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_google_data[] = { 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xc0, 0x07, 0xf0, 0x0f, 0xe0, 0x0f, 0xc0, 0x03, 0xf0, 0x1f, 0x00, 0x01, 0xf8, 0x3e, 0x00, 0x00, 0xfc, 0x3c, 0x00, 0x01, 0xfc, 0x7c, 0x0f, 0xf3, 0xfe, 0x78, 0x1f, 0xff, 0xfe, 0x78, 0x3f, 0xff, 0xfe, 0xf0, 0x3f, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xf0, 0x7f, 0x00, 0x1f, 0xf0, 0x7f, 0x00, 0x1f, 0xf0, 0x7f, 0x00, 0x1f, 0xf0, 0x7f, 0x00, 0x1f, 0xf0, 0x7f, 0xfe, 0x1f, 0xf0, 0x3f, 0xfe, 0x1f, 0x78, 0x3f, 0xfc, 0x1e, 0x78, 0x1f, 0xf8, 0x3e, 0x7c, 0x07, 0xf0, 0x3e, 0x3c, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0xc0, 0x03, 0xf0, 0x07, 0xf0, 0x0f, 0xe0, 0x03, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x0f, 0xf0, 0x00, }; +const uint8_t bmp_u2f_slushpool_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x01, 0xee, 0x00, 0x01, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xf8, 0x00, 0xfe, 0x0f, 0xf8, 0x00, 0xfe, 0x03, 0xf8, 0x00, 0xfc, 0x03, 0xf8, 0x00, 0xfc, 0x03, 0xf8, 0x01, 0xfc, 0x03, 0xf8, 0x01, 0xfc, 0x03, 0xf0, 0x01, 0xfc, 0x07, 0xf0, 0x01, 0xfc, 0x1f, 0xf0, 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t bmp_u2f_yubico_data[] = { 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x01, 0xff, 0xff, 0x80, 0x03, 0xfc, 0x3f, 0xc0, 0x07, 0xe0, 0x07, 0xe0, 0x0f, 0x80, 0x01, 0xf0, 0x1f, 0x00, 0x00, 0x78, 0x3e, 0x00, 0x00, 0x3c, 0x3c, 0x7c, 0x1f, 0x3c, 0x78, 0x7c, 0x1f, 0x1e, 0x78, 0x7c, 0x3e, 0x0e, 0xf0, 0x3e, 0x3e, 0x0f, 0xf0, 0x3e, 0x3c, 0x0f, 0xf0, 0x1f, 0x7c, 0x0f, 0xe0, 0x1f, 0x7c, 0x07, 0xe0, 0x1f, 0x78, 0x07, 0xe0, 0x0f, 0xf8, 0x07, 0xe0, 0x0f, 0xf0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x07, 0xf0, 0x0f, 0xf0, 0x07, 0xe0, 0x0f, 0x78, 0x03, 0xe0, 0x0e, 0x78, 0x07, 0xc0, 0x1e, 0x3c, 0x07, 0xc0, 0x3e, 0x3c, 0x0f, 0xc0, 0x3c, 0x1e, 0x0f, 0x80, 0x78, 0x0f, 0x8f, 0x81, 0xf0, 0x07, 0xc0, 0x03, 0xe0, 0x03, 0xfc, 0x3f, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x1f, 0xf8, 0x00, }; + +const BITMAP bmp_digit0 = {16, 16, bmp_digit0_data}; +const BITMAP bmp_digit1 = {16, 16, bmp_digit1_data}; +const BITMAP bmp_digit2 = {16, 16, bmp_digit2_data}; +const BITMAP bmp_digit3 = {16, 16, bmp_digit3_data}; +const BITMAP bmp_digit4 = {16, 16, bmp_digit4_data}; +const BITMAP bmp_digit5 = {16, 16, bmp_digit5_data}; +const BITMAP bmp_digit6 = {16, 16, bmp_digit6_data}; +const BITMAP bmp_digit7 = {16, 16, bmp_digit7_data}; +const BITMAP bmp_digit8 = {16, 16, bmp_digit8_data}; +const BITMAP bmp_digit9 = {16, 16, bmp_digit9_data}; +const BITMAP bmp_gears0 = {48, 48, bmp_gears0_data}; +const BITMAP bmp_gears1 = {48, 48, bmp_gears1_data}; +const BITMAP bmp_gears2 = {48, 48, bmp_gears2_data}; +const BITMAP bmp_gears3 = {48, 48, bmp_gears3_data}; +const BITMAP bmp_icon_error = {16, 16, bmp_icon_error_data}; +const BITMAP bmp_icon_info = {16, 16, bmp_icon_info_data}; +const BITMAP bmp_icon_ok = {16, 16, bmp_icon_ok_data}; +const BITMAP bmp_icon_question = {16, 16, bmp_icon_question_data}; +const BITMAP bmp_icon_warning = {16, 16, bmp_icon_warning_data}; +const BITMAP bmp_logo48 = {40, 48, bmp_logo48_data}; +const BITMAP bmp_logo48_empty = {40, 48, bmp_logo48_empty_data}; +const BITMAP bmp_logo64 = {48, 64, bmp_logo64_data}; +const BITMAP bmp_logo64_empty = {48, 64, bmp_logo64_empty_data}; +const BITMAP bmp_u2f_bitbucket = {32, 32, bmp_u2f_bitbucket_data}; +const BITMAP bmp_u2f_bitfinex = {32, 32, bmp_u2f_bitfinex_data}; +const BITMAP bmp_u2f_dropbox = {32, 32, bmp_u2f_dropbox_data}; +const BITMAP bmp_u2f_fastmail = {32, 32, bmp_u2f_fastmail_data}; +const BITMAP bmp_u2f_gandi = {32, 32, bmp_u2f_gandi_data}; +const BITMAP bmp_u2f_github = {32, 32, bmp_u2f_github_data}; +const BITMAP bmp_u2f_gitlab = {32, 32, bmp_u2f_gitlab_data}; +const BITMAP bmp_u2f_google = {32, 32, bmp_u2f_google_data}; +const BITMAP bmp_u2f_slushpool = {32, 32, bmp_u2f_slushpool_data}; +const BITMAP bmp_u2f_yubico = {32, 32, bmp_u2f_yubico_data}; diff --git a/hardware-wallet/firmware/gen/bitmaps.h b/hardware-wallet/firmware/gen/bitmaps.h new file mode 100644 index 00000000..29f7b5b0 --- /dev/null +++ b/hardware-wallet/firmware/gen/bitmaps.h @@ -0,0 +1,45 @@ +#ifndef __BITMAPS_H__ +#define __BITMAPS_H__ + +#include + +typedef struct { + uint8_t width, height; + const uint8_t *data; +} BITMAP; + +extern const BITMAP bmp_digit0; +extern const BITMAP bmp_digit1; +extern const BITMAP bmp_digit2; +extern const BITMAP bmp_digit3; +extern const BITMAP bmp_digit4; +extern const BITMAP bmp_digit5; +extern const BITMAP bmp_digit6; +extern const BITMAP bmp_digit7; +extern const BITMAP bmp_digit8; +extern const BITMAP bmp_digit9; +extern const BITMAP bmp_gears0; +extern const BITMAP bmp_gears1; +extern const BITMAP bmp_gears2; +extern const BITMAP bmp_gears3; +extern const BITMAP bmp_icon_error; +extern const BITMAP bmp_icon_info; +extern const BITMAP bmp_icon_ok; +extern const BITMAP bmp_icon_question; +extern const BITMAP bmp_icon_warning; +extern const BITMAP bmp_logo48; +extern const BITMAP bmp_logo48_empty; +extern const BITMAP bmp_logo64; +extern const BITMAP bmp_logo64_empty; +extern const BITMAP bmp_u2f_bitbucket; +extern const BITMAP bmp_u2f_bitfinex; +extern const BITMAP bmp_u2f_dropbox; +extern const BITMAP bmp_u2f_fastmail; +extern const BITMAP bmp_u2f_gandi; +extern const BITMAP bmp_u2f_github; +extern const BITMAP bmp_u2f_gitlab; +extern const BITMAP bmp_u2f_google; +extern const BITMAP bmp_u2f_slushpool; +extern const BITMAP bmp_u2f_yubico; + +#endif diff --git a/hardware-wallet/firmware/gen/bitmaps/digit0.png b/hardware-wallet/firmware/gen/bitmaps/digit0.png new file mode 100644 index 0000000000000000000000000000000000000000..9dfc0a41cb6d476032f20def389587ae9511821b GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|4xTQKAsXl323hhk7;p$(`d>eD z-7)RL*8ygZ5e$=ZnuYTi8aX@X>^D9cG~r3}UYF=c()SD&WN(=*+&*`z%C^t@%mt;z UKWA*c4m69w)78&qol`;+0Nsr!6951J literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit1.png b/hardware-wallet/firmware/gen/bitmaps/digit1.png new file mode 100644 index 0000000000000000000000000000000000000000..8645ae6f1ede04cc5e23d8e80c843e81f325883f GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|=AJH&AsXkC|NQ@N&#c+N8r(5) zqTsn>CVia!S!)_PRjx+lDEJ=!|NlQ{8)K?jPnLuMZ_g67e1_cB{L=q9d%ppVVDNPH Kb6Mw<&;$UlZ6jj< literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit2.png b/hardware-wallet/firmware/gen/bitmaps/digit2.png new file mode 100644 index 0000000000000000000000000000000000000000..81f206e79a393468481c80bf96b4cd0904b5292d GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|9-c0aAsXkC|NQ@N&#c+NdM+s? z<;W_gvo2~)Zi^(3bR73Q;q~y;3<(dGE!Ph;-S3{kc+_Q5)|`(G>MzQ}JYD@<);T3K0RS1ZE+hZ| literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit3.png b/hardware-wallet/firmware/gen/bitmaps/digit3.png new file mode 100644 index 0000000000000000000000000000000000000000..eef5494406771d1d84f07eb38789bef29a9192d9 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|E}kxqAsXkC|NQ@N&#c+NdM+s? z<;W_gvo2~)Zi^(3bR73Q;q~y;3<(dGE!Ph;-S3{k=(>sbu=bRKrK*#hIdwxMJbmvm Yoc$mt{wRxoCeS9&b?%k={uS)bS#UOGu=eD+s=1vHz%)78&qol`;+0Ce{)O#lD@ literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit5.png b/hardware-wallet/firmware/gen/bitmaps/digit5.png new file mode 100644 index 0000000000000000000000000000000000000000..aafcd3c54549d02e8494ca4bdd4e80fcc25404cb GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|?w&4=AsXkC|NQ@N&#c+NdM+s? z<;W_gvo30ELX6yXpA8s~nkD>dNwHrbd9dU7#S>l+PkDShTyVj`LU*AnYohdpLvtry bdBV$}q9rZ0_f^9oppguou6{1-oD!M literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit6.png b/hardware-wallet/firmware/gen/bitmaps/digit6.png new file mode 100644 index 0000000000000000000000000000000000000000..0b0c59eac082a76c225dcf8c35df264cf0d9ce55 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|KAtX)AsXlJ203yu7;wzG_<#SK zb&5}4?8@s*YgMQ;n|g^^z(uVs-MamhS@p5Vux%>}tF2EY?rlhsjWK;KT_=$6>zK%L g1Iuj3oX53{yH_hpl&vti3N)9&)78&qol`;+091c1g8%>k literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit7.png b/hardware-wallet/firmware/gen/bitmaps/digit7.png new file mode 100644 index 0000000000000000000000000000000000000000..e4eea9e0a41ae441f3bbb289aabbee9512cb3aa5 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Zk{fVAsXkC|NQ@N&#c+NdM+s? z<;Y^bJUwCN&IZ=YJb%h2Z4)*Go0?Ba~}32iLGANv-TY49rY_AF7$ ZXK36lA!~C#rU_^wgQu&X%Q~loCIFfKCei=^ literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit8.png b/hardware-wallet/firmware/gen/bitmaps/digit8.png new file mode 100644 index 0000000000000000000000000000000000000000..de021652a1a37f7860abb4e01013d6e3f892505f GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|E}kxqAsXkC|NQ@N&#c+N+I#-Q zi4L`t23H>B2@qV|KFcuut`LixwGM$ltkf9(Qt>r2TLYOc|`>4%~DWac~Y98 Xtx8>ZrR?u!pm_|Qu6{1-oD!M<;p-^n literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/digit9.png b/hardware-wallet/firmware/gen/bitmaps/digit9.png new file mode 100644 index 0000000000000000000000000000000000000000..2a7458aae68d597f726d214f9c837d94ea18e9bd GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|-kvUwAsXlJ23hhk7;p$({$D?H zU0c}N?3;TOx)d^nbvhY6+$8qCvzuI}JE7;u#wTV+_?b_vo4E5~tGmD7_NK?Ozv6{% f#yN@|{<7Dcxld7A?VYhE&{zgfS3j3^P6l$`hU_9=$O?}J6FrV3A^?c$tEa)z0ARC~ zWEDRTNsJRXt3Z9(t~p@_n{^khw*6ZG6+bM<(PH_V{lAYNexS2ZY`I$)EyebpS*5xU z*~gD9<6^ta`Pi_fs5ksNiom`%W;{qX8UuU)C*qkf)q+{d00000NkvXXu0mjf!2^Ao literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/gears1.png b/hardware-wallet/firmware/gen/bitmaps/gears1.png new file mode 100644 index 0000000000000000000000000000000000000000..9fa6a8102a06ed63ff8369bb6a157c819da78e32 GIT binary patch literal 326 zcmV-M0lEH(P)g(z@U>8!I4?+PV`GC08GkONeAbD?5YokUmDy7WJx;PS z;oLP9OsV(rQ@Q{$wv883;&m!rvRl}+l7;2=5}`4h#s@s=iYdY?+&+cT(P4Tt+G4jC zC&3Ezv}XQJFH=m8MS;o}p@s3-*UqZLx{lczgCbojaG0ybJ(W#WhtlmW|Fv_{sSk|x z>2gF4_D{p2JEj?j05HGF?7rf9+p|fVTynoUw36rcVOUV4a;YG>mW_B z`Y639gy31lEz1D;h(Yas2@$GTfDIZJtw9sxC6+5L6kduAddR?+(XAuw@wC1Aq>aD9 Y3+@u1Hl08`n*aa+07*qoM6N<$f~#kdUH||9 literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/gears2.png b/hardware-wallet/firmware/gen/bitmaps/gears2.png new file mode 100644 index 0000000000000000000000000000000000000000..56c199862071f6b90092964214e5d0a17677afe7 GIT binary patch literal 293 zcmV+=0owkFP)brhvQck!c||kw%Zh!^6Wi(3uxw{1yPFfP%E(LbeMa>jZ}n@BMQB3Tr!x3?d;k*Ga)o>MajBCn$ILl#~I1N!JWes~@)(@>4F zFkG*huZ>#m(58EpK<~V=mp<+P4iMd|@H>=4OjaH)^i}Oq%`zjh_8J|Al!?5`qr1ff rQHySBlMhgur~cWS+WJqe$5wFyoXdeqtB%bx00000NkvXXu0mjf15ki0 literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/gears3.png b/hardware-wallet/firmware/gen/bitmaps/gears3.png new file mode 100644 index 0000000000000000000000000000000000000000..9aa384062fe95c8549a9254a74ae602f724de024 GIT binary patch literal 330 zcmV-Q0k!^#P)v@LnS<0e*bow)g8;Y**h`>7p7M3Nggwm#n~U2C8mO zH=Y$kxloW@26Q8~HS=ur`o|y47>VfqiB$ zRpqE-Xd$95>--#y524UV*Pw4c)W8P-(o(X9z6ONf%ldpO`$$+6*X**H2DojyY6$YY z9De*KyFIob%7 literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/generate.py b/hardware-wallet/firmware/gen/bitmaps/generate.py new file mode 100755 index 00000000..21d72a6d --- /dev/null +++ b/hardware-wallet/firmware/gen/bitmaps/generate.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +from __future__ import print_function +import glob +import os +from PIL import Image + +hdrs = [] +data = [] +imgs = [] + +def encode_pixels(img): + r = '' + img = [ (x[0] + x[1] + x[2] > 384 and '1' or '0') for x in img] + for i in range(len(img) // 8): + c = ''.join(img[i * 8 : i * 8 + 8]) + r += '0x%02x, ' % int(c, 2) + return r + +cnt = 0 +for fn in sorted(glob.glob('*.png')): + print('Processing:', fn) + im = Image.open(fn) + name = os.path.splitext(fn)[0] + w, h = im.size + if w % 8 != 0: + raise Exception('Width must be divisable by 8! (%s is %dx%d)' % (fn, w, h)) + img = list(im.getdata()) + hdrs.append('extern const BITMAP bmp_%s;\n' % name) + imgs.append('const BITMAP bmp_%s = {%d, %d, bmp_%s_data};\n' % (name, w, h, name)) + data.append('const uint8_t bmp_%s_data[] = { %s};\n' % (name, encode_pixels(img))) + cnt += 1 + +with open('../bitmaps.c', 'wt') as f: + f.write('#include "bitmaps.h"\n\n') + for i in range(cnt): + f.write(data[i]) + f.write('\n') + for i in range(cnt): + f.write(imgs[i]) + f.close() + +with open('../bitmaps.h', 'wt') as f: + f.write('''#ifndef __BITMAPS_H__ +#define __BITMAPS_H__ + +#include + +typedef struct { + uint8_t width, height; + const uint8_t *data; +} BITMAP; + +''') + + for i in range(cnt): + f.write(hdrs[i]) + + f.write('\n#endif\n') + f.close() diff --git a/hardware-wallet/firmware/gen/bitmaps/icon_error.png b/hardware-wallet/firmware/gen/bitmaps/icon_error.png new file mode 100644 index 0000000000000000000000000000000000000000..f23a1e79459682b18fdb9be90153f566bc6931d2 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|@t!V@AsXlBPVyEyV8G$@dC&j3 zFPB};ykIC_&L&}aXomNsy$r#(H*aoJy>0Sl!~aA6@!(@vm<`3btR|!FfMzk9>ZzlfW(y%TqwB7(8A5T-G@yGywok C=sQ#Z literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/icon_info.png b/hardware-wallet/firmware/gen/bitmaps/icon_info.png new file mode 100644 index 0000000000000000000000000000000000000000..2044c7622f608eda67691abc280b20fff1fb5a76 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|fu1goAsXk823hhkC~$24^Z&fX zj2Q*W-8l}YBXu&*tWjcUnY~z-T{Wuk!6N@#yg`xCy$x!=q+EqpKNe|u&R5TQvFM`V liB+og-$JB>Kbk(>%UJeJQ7PL0;Vhux44$rjF6*2UngHOLF8}}l literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/icon_ok.png b/hardware-wallet/firmware/gen/bitmaps/icon_ok.png new file mode 100644 index 0000000000000000000000000000000000000000..36fcee2a2e86775be4a2b82be2aebf4e854bc848 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`d7dtgAr_~nPWBdKaAaYgeCPkU zv{bPz@%n+cxD^?kE7CMs7!+nE-8vNN7rkTEMb^5juegq@?K%+XVtiVu?1RQ5Q9bDi ze~#C_t+Q=BJlAj5HIvRYSx3&6c{IIieXaZB_^X~xJK25nX7_nYpDx?U-&k)Uwf$$# QLZHnIp00i_>zopr0PST!LjV8( literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/icon_question.png b/hardware-wallet/firmware/gen/bitmaps/icon_question.png new file mode 100644 index 0000000000000000000000000000000000000000..b3ef441620f429ce82d8e33acf69222c0811a2c2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|37#&FAsXkGPO|1ZV8G%0TI2hE zBUz&-hr7E&wn@yENU^PUJ<{lLYu>!MrcU1yQc}1!wC^~R^T%COUHg)@_xh_o`u*ih zDe98+E*DY-J2dD-QQIt$OR?f57Vd~rw0tphE`zeX%Qv6Zp^V+L0Q$1X;1jfY&- kYaT5*&g^(Sc-AxqEnh8`9p^4z1{%)b>FVdQ&MBb@08-^M?*IS* literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/logo48.png b/hardware-wallet/firmware/gen/bitmaps/logo48.png new file mode 100644 index 0000000000000000000000000000000000000000..86ec6867677e5b00585df4da64093b472c4f89bf GIT binary patch literal 283 zcmV+$0p$LPP)Q1H?PlUe!tHD;F^ufOeY*8mZeQ~uLa2}oXK>`wxfCMBU0SQRJ`xn;d za+!56^b}?dRqTaDtHqXK1*8QWD%@|?#-oico9L%umwj$=405tyUHxqVM`7-H2bcju hv$_@R^NOwLM1>c@}U7>w#GPBTYP8 zj5>~h!hovkUJ=h&2(ae>i9r-{7_ep78-obs7C9i6lf6F@7S#g-ZGtJ zKtX_!?a2VHccmEbD%P@iBOn2n)q}m$=E-FdrPKTu&&qwC6joP&`5BTO+p=^aVsA)M9}AJFWN%#=kg-sO^;*QV97ZN& z-ir~#k%t`1msv#5ScQm9_!;8v7<9cfJsyJ*SkL8rI^fLq1EHR-VeHkGSO5S307*qo IM6N<$g0sPd%>V!Z literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/logo64.png b/hardware-wallet/firmware/gen/bitmaps/logo64.png new file mode 100644 index 0000000000000000000000000000000000000000..d07a745fbbab8e2ba847b369c4e376ff3aa74b26 GIT binary patch literal 317 zcmV-D0mA-?P)j^YhI|l+g#T?^(IQ;DasW~lUksK%RcG|>jHUh4v3uO$6w~W z$Kcx3q!vgZfdmprAb|uD=#R3F<3JvGvYyF9+I%at%#;tAuVYLsA~kEC?sAz|eCB#J zW-;&i0y`IyIwCMF4@qGWJ}aH6^oB2iowCFa2~09Nih8$&FImP7&co#c?QCp=x*-a> P00000NkvXXu0mjf^WK6C literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/logo64_empty.png b/hardware-wallet/firmware/gen/bitmaps/logo64_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..ec8ba1da415ff5d10e317c8d5d5d39da3eeecd7e GIT binary patch literal 444 zcmV;t0YmVXj(2TM7zMx378YprU=dM2m5AS`^ zEAubI0;FW6tBYrvSL|1y9<5L5DcWTf9l**e30r@p0@R~BY^W%TXUdJGa`Or`W5_u) z4uo2qREN#C44A8hQpb6y0Tj;G6@|p_uuU4~rCzK7F*D{52nA%Vb{3|kR!4n2A^76phDX)jA^OG@g) mYanbY%qJhAl2mCE>>odGabf*O0ohLg0000QL70(Y)*K0-AbW|YuPgflHYs5t%iyPC-9Vv@o-U3d9>?E?dGZ}l;1D_Vf4`4^ zZq(^@$ChZOCnO}eWGpk>{FZ^C&)FzLde;`ND7$zs@SJOL;vKO}gS!2b5|gef&9}CSSluku iwlOE5y8DrnCBw)0nZ}crbj1K2&*16m=d#Wzp$Pyje{vuI literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/u2f_bitfinex.png b/hardware-wallet/firmware/gen/bitmaps/u2f_bitfinex.png new file mode 100644 index 0000000000000000000000000000000000000000..48a1048456d5dea18014964b630db2f0e6a4cd9b GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7a$D;Kb?2i11Zh|kH}&M z25w;xW@MN(M*=9wUgGKN%Kng>kz0=MA8QXinf?Q%OpAXxT-~~C=FWKytT(DySG{7JA3E=y!{P#k3LfJJ^$GrUD+OH-`Z9IgQr=m#>eEy;wxGS?8M?AF8q-~@{TL31 z<;XVZDZAZkk^8VIHXyQemcv)I5@843pD*+}ejN^L5fqY4=JGw*!}F@`g2cZ5lga^t Z@{3KwY*#I_ivhZt!PC{xWt~$(6977sWiS8$ literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/u2f_dropbox.png b/hardware-wallet/firmware/gen/bitmaps/u2f_dropbox.png new file mode 100644 index 0000000000000000000000000000000000000000..9d78cadb004addcb8344a54cd62690849256c0cb GIT binary patch literal 263 zcmV+i0r>ujP)*Bi47H{Zla*jJXXUhY zYcWW{RwfmHc!A-Oego-^_%8hk?*_|yOZ N002ovPDHLkV1l8qa>4)r literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/u2f_fastmail.png b/hardware-wallet/firmware/gen/bitmaps/u2f_fastmail.png new file mode 100644 index 0000000000000000000000000000000000000000..20d05d163046417c8516776966dd1c7fd378501d GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJm7Xq+ArXh)PInY)P~dPq`0-!( zHqo;g84g^!1y{FJuAlUumvMpP11*6)K?*SoF1cp!s}>aeZSG)h^Kd(Z?cR14!;Z*f z{slovE%s&)JvsT#`5ol!l&rC8vsMlJkjnRFLPhg_wu|DNoH0{c#5gr$WR6O4^2S_c z72?#5iFMQFc0Nobmr@l`|iP1`cJp8K)x*E!)pu0PHPKHFHZi9cH($>qWw ZGvi;Fn|RBFsX#|Fc)I$ztaD0e0swITP%8ic literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/u2f_gandi.png b/hardware-wallet/firmware/gen/bitmaps/u2f_gandi.png new file mode 100644 index 0000000000000000000000000000000000000000..12abe0ff114a8075d60d926035e4f71b01137394 GIT binary patch literal 250 zcmVl}sKSjKh{yvs6Z-vK^GUCCruz_mSPGJnA68?>)Wgxs5+|TS>}@oPLy-~rXzC^* z(*d4Q5u8QKrfCx0AaDk8*{}1CAO=iPdJwO3(Q=LpD^#|ix=P)hV{vK>!Cy;AzF6RiKIsgCw07*qoM6N<$g8VOK A&j0`b literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/u2f_github.png b/hardware-wallet/firmware/gen/bitmaps/u2f_github.png new file mode 100644 index 0000000000000000000000000000000000000000..9f9be253e30c34e220ea3cac2145152b0189a3f7 GIT binary patch literal 236 zcmVo5iB zVHX|v@n&##lix2uQx+Oi6Fuc1qx{`OzJt8-je~Zd6Z)`{3Iz_vCY>b16WJl0gM-LS zU`2leD-9CL996ouil7PSdzpLq*buDeM=4xCVsx m4V^P)lnh~P}IH05!RFv&zDRA?A|5Q)ueRRzisWGR74`S(Y# z!g@vUB-acQ%h~TC7$%^}<-uU}SFXSjd7<10Ryns6^mhSEh5lR30cNg6(EbUtNwmVz zFJuP4D3CF9?uvwUy&mh|2>%E@0;RuOGDMYdLURs0< flZlRTA&9gS9LG;4emS$N00000NkvXXu0mjfu5n@$ literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/u2f_google.png b/hardware-wallet/firmware/gen/bitmaps/u2f_google.png new file mode 100644 index 0000000000000000000000000000000000000000..864f4e18667bf0153e49dc59bf1a8a74141cc1dd GIT binary patch literal 240 zcmV+jBA_UP z8z^byR*3WzXoUmk=$ylI)vebB6!&?fF?3)o-6!@+L3{e`YG+&_w%ixRA9df%M#;b- zZn-@y?2s|1P>Rbt9UMtAY=VT>is-kjq45^o5a0000RmFP;X;f6Ka+7>t=K<}%hC+Am>L`_^2;*j|5iR4LG* N44$rjF6*2UngASlQk?(* literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/bitmaps/u2f_yubico.png b/hardware-wallet/firmware/gen/bitmaps/u2f_yubico.png new file mode 100644 index 0000000000000000000000000000000000000000..c4bc1f0a280ddee04f59b57898c707ecede0425d GIT binary patch literal 253 zcmVCz?)ilsvs_|?z(PRu*NGgGS^ z#zRDh20DqTSAVT=q+?d~9>yw+(x@gU_FBuG=SyQX?J+iHYJH4NckruYrU|iDU=000000NkvXXu0mjf D(wu7= literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/font.inc b/hardware-wallet/firmware/gen/font.inc new file mode 100644 index 00000000..e1408959 --- /dev/null +++ b/hardware-wallet/firmware/gen/font.inc @@ -0,0 +1,128 @@ + /* 0x00 _ */ (uint8_t *)"\x01\x00", + /* 0x01 _ */ (uint8_t *)"\x01\x00", + /* 0x02 _ */ (uint8_t *)"\x01\x00", + /* 0x03 _ */ (uint8_t *)"\x01\x00", + /* 0x04 _ */ (uint8_t *)"\x01\x00", + /* 0x05 _ */ (uint8_t *)"\x01\x00", + /* 0x06 _ */ (uint8_t *)"\x07\x18\x1c\x0e\x18\x30\x40\x80", + /* 0x07 _ */ (uint8_t *)"\x01\x00", + /* 0x08 _ */ (uint8_t *)"\x01\x00", + /* 0x09 _ */ (uint8_t *)"\x01\x00", + /* 0x0a _ */ (uint8_t *)"\x01\x00", + /* 0x0b _ */ (uint8_t *)"\x01\x00", + /* 0x0c _ */ (uint8_t *)"\x01\x00", + /* 0x0d _ */ (uint8_t *)"\x01\x00", + /* 0x0e _ */ (uint8_t *)"\x01\x00", + /* 0x0f _ */ (uint8_t *)"\x01\x00", + /* 0x10 _ */ (uint8_t *)"\x01\x00", + /* 0x11 _ */ (uint8_t *)"\x01\x00", + /* 0x12 _ */ (uint8_t *)"\x01\x00", + /* 0x13 _ */ (uint8_t *)"\x01\x00", + /* 0x14 _ */ (uint8_t *)"\x01\x00", + /* 0x15 _ */ (uint8_t *)"\x07\x44\xee\x7c\x38\x7c\xee\x44", + /* 0x16 _ */ (uint8_t *)"\x01\x00", + /* 0x17 _ */ (uint8_t *)"\x01\x00", + /* 0x18 _ */ (uint8_t *)"\x01\x00", + /* 0x19 _ */ (uint8_t *)"\x01\x00", + /* 0x1a _ */ (uint8_t *)"\x01\x00", + /* 0x1b _ */ (uint8_t *)"\x01\x00", + /* 0x1c _ */ (uint8_t *)"\x01\x00", + /* 0x1d _ */ (uint8_t *)"\x01\x00", + /* 0x1e _ */ (uint8_t *)"\x01\x00", + /* 0x1f _ */ (uint8_t *)"\x01\x00", + /* 0x20 */ (uint8_t *)"\x01\x00", + /* 0x21 ! */ (uint8_t *)"\x02\xfa\xfa", + /* 0x22 " */ (uint8_t *)"\x03\xc0\x00\xc0", + /* 0x23 # */ (uint8_t *)"\x05\x6c\xfe\x6c\xfe\x6c", + /* 0x24 $ */ (uint8_t *)"\x05\x32\xff\x5a\xff\x4c", + /* 0x25 % */ (uint8_t *)"\x06\xc0\xc6\x1c\x70\xc6\x06", + /* 0x26 & */ (uint8_t *)"\x06\x5c\xfe\xb2\xfe\x4c\x1e", + /* 0x27 ' */ (uint8_t *)"\x01\xc0", + /* 0x28 ( */ (uint8_t *)"\x03\x38\x7c\x82", + /* 0x29 ) */ (uint8_t *)"\x03\x82\x7c\x38", + /* 0x2a * */ (uint8_t *)"\x05\x6c\x38\xfe\x38\x6c", + /* 0x2b + */ (uint8_t *)"\x05\x10\x10\x7c\x10\x10", + /* 0x2c , */ (uint8_t *)"\x02\x03\x06", + /* 0x2d - */ (uint8_t *)"\x04\x10\x10\x10\x10", + /* 0x2e . */ (uint8_t *)"\x02\x06\x06", + /* 0x2f / */ (uint8_t *)"\x03\x0e\x38\xe0", + /* 0x30 0 */ (uint8_t *)"\x05\x7c\xfe\x82\xfe\x7c", + /* 0x31 1 */ (uint8_t *)"\x03\x40\xfe\xfe", + /* 0x32 2 */ (uint8_t *)"\x05\x8e\x9e\x92\xf2\x62", + /* 0x33 3 */ (uint8_t *)"\x05\x82\x92\x92\xfe\x6c", + /* 0x34 4 */ (uint8_t *)"\x05\x18\x28\x48\xfe\xfe", + /* 0x35 5 */ (uint8_t *)"\x05\xe2\xa2\xa2\xbe\x1c", + /* 0x36 6 */ (uint8_t *)"\x05\x7c\xfe\xa2\xbe\x1c", + /* 0x37 7 */ (uint8_t *)"\x05\x80\x8e\xbe\xf0\xc0", + /* 0x38 8 */ (uint8_t *)"\x05\x6c\xfe\x92\xfe\x6c", + /* 0x39 9 */ (uint8_t *)"\x05\x70\xfa\x8a\xfe\x7c", + /* 0x3a : */ (uint8_t *)"\x02\x36\x36", + /* 0x3b ; */ (uint8_t *)"\x02\x33\x36", + /* 0x3c < */ (uint8_t *)"\x04\x10\x38\x6c\xc6", + /* 0x3d = */ (uint8_t *)"\x04\x28\x28\x28\x28", + /* 0x3e > */ (uint8_t *)"\x04\xc6\x6c\x38\x10", + /* 0x3f ? */ (uint8_t *)"\x05\x80\x9a\xba\xe0\x40", + /* 0x40 @ */ (uint8_t *)"\x06\x7c\xfe\xaa\xba\xfa\x78", + /* 0x41 A */ (uint8_t *)"\x05\x7e\xfe\x88\xfe\x7e", + /* 0x42 B */ (uint8_t *)"\x05\xfe\xfe\xa2\xfe\x5c", + /* 0x43 C */ (uint8_t *)"\x05\x7c\xfe\x82\x82\x82", + /* 0x44 D */ (uint8_t *)"\x05\xfe\xfe\x82\xfe\x7c", + /* 0x45 E */ (uint8_t *)"\x05\xfe\xfe\xa2\xa2\x82", + /* 0x46 F */ (uint8_t *)"\x05\xfe\xfe\xa0\xa0\x80", + /* 0x47 G */ (uint8_t *)"\x05\x7c\xfe\x82\x9e\x1e", + /* 0x48 H */ (uint8_t *)"\x05\xfe\xfe\x20\xfe\xfe", + /* 0x49 I */ (uint8_t *)"\x02\xfe\xfe", + /* 0x4a J */ (uint8_t *)"\x04\x02\x02\xfe\xfc", + /* 0x4b K */ (uint8_t *)"\x06\xfe\xfe\x38\x6c\xc6\x82", + /* 0x4c L */ (uint8_t *)"\x04\xfe\xfe\x02\x02", + /* 0x4d M */ (uint8_t *)"\x07\xfe\x7e\x30\x18\x30\x7e\xfe", + /* 0x4e N */ (uint8_t *)"\x06\xfe\x7e\x30\x18\xfc\xfe", + /* 0x4f O */ (uint8_t *)"\x06\x7c\xfe\x82\x82\xfe\x7c", + /* 0x50 P */ (uint8_t *)"\x05\xfe\xfe\x88\xf8\x70", + /* 0x51 Q */ (uint8_t *)"\x06\x7c\xfe\x82\x86\xff\x7d", + /* 0x52 R */ (uint8_t *)"\x05\xfe\xfe\x88\xfe\x72", + /* 0x53 S */ (uint8_t *)"\x04\x62\xf2\x9e\x8c", + /* 0x54 T */ (uint8_t *)"\x06\x80\x80\xfe\xfe\x80\x80", + /* 0x55 U */ (uint8_t *)"\x05\xfc\xfe\x02\xfe\xfc", + /* 0x56 V */ (uint8_t *)"\x06\xe0\xf8\x1e\x1e\xf8\xe0", + /* 0x57 W */ (uint8_t *)"\x07\xf0\xfe\x1e\x3c\x1e\xfe\xf0", + /* 0x58 X */ (uint8_t *)"\x06\xc6\xee\x38\x38\xee\xc6", + /* 0x59 Y */ (uint8_t *)"\x06\xc0\xe0\x3e\x3e\xe0\xc0", + /* 0x5a Z */ (uint8_t *)"\x05\x8e\x9e\xba\xf2\xe2", + /* 0x5b [ */ (uint8_t *)"\x03\xfe\xfe\x82", + /* 0x5c \ */ (uint8_t *)"\x03\xe0\x38\x0e", + /* 0x5d ] */ (uint8_t *)"\x03\x82\xfe\xfe", + /* 0x5e ^ */ (uint8_t *)"\x03\x60\xc0\x60", + /* 0x5f _ */ (uint8_t *)"\x06\x02\x02\x02\x02\x02\x02", + /* 0x60 ` */ (uint8_t *)"\x02\x80\x40", + /* 0x61 a */ (uint8_t *)"\x05\x04\x2e\x2a\x3e\x1e", + /* 0x62 b */ (uint8_t *)"\x05\xfe\xfe\x22\x3e\x1c", + /* 0x63 c */ (uint8_t *)"\x05\x1c\x3e\x22\x36\x14", + /* 0x64 d */ (uint8_t *)"\x05\x1c\x3e\x22\xfe\xfe", + /* 0x65 e */ (uint8_t *)"\x05\x1c\x3e\x2a\x3a\x1a", + /* 0x66 f */ (uint8_t *)"\x03\x7e\xfe\xa0", + /* 0x67 g */ (uint8_t *)"\x05\x18\x3d\x25\x3f\x3e", + /* 0x68 h */ (uint8_t *)"\x05\xfe\xfe\x20\x3e\x1e", + /* 0x69 i */ (uint8_t *)"\x02\xbe\xbe", + /* 0x6a j */ (uint8_t *)"\x03\x01\xbf\xbe", + /* 0x6b k */ (uint8_t *)"\x05\xfe\xfe\x1c\x36\x22", + /* 0x6c l */ (uint8_t *)"\x02\xfe\xfe", + /* 0x6d m */ (uint8_t *)"\x08\x3e\x3e\x20\x3e\x3e\x20\x3e\x1e", + /* 0x6e n */ (uint8_t *)"\x05\x3e\x3e\x20\x3e\x1e", + /* 0x6f o */ (uint8_t *)"\x05\x1c\x3e\x22\x3e\x1c", + /* 0x70 p */ (uint8_t *)"\x05\x3f\x3f\x24\x3c\x18", + /* 0x71 q */ (uint8_t *)"\x05\x18\x3c\x24\x3f\x3f", + /* 0x72 r */ (uint8_t *)"\x04\x3e\x3e\x10\x30", + /* 0x73 s */ (uint8_t *)"\x04\x1a\x3a\x2e\x2c", + /* 0x74 t */ (uint8_t *)"\x03\xfc\xfe\x22", + /* 0x75 u */ (uint8_t *)"\x05\x3c\x3e\x02\x3e\x3e", + /* 0x76 v */ (uint8_t *)"\x05\x30\x3c\x0e\x3c\x30", + /* 0x77 w */ (uint8_t *)"\x07\x38\x3e\x06\x1c\x06\x3e\x38", + /* 0x78 x */ (uint8_t *)"\x05\x36\x3e\x08\x3e\x36", + /* 0x79 y */ (uint8_t *)"\x05\x38\x3d\x05\x3f\x3e", + /* 0x7a z */ (uint8_t *)"\x05\x26\x2e\x3a\x32\x22", + /* 0x7b { */ (uint8_t *)"\x04\x10\x7c\xee\x82", + /* 0x7c | */ (uint8_t *)"\x02\xff\xff", + /* 0x7d } */ (uint8_t *)"\x04\x82\xee\x7c\x10", + /* 0x7e ~ */ (uint8_t *)"\x04\x08\x10\x08\x10", + /* 0x7f _ */ (uint8_t *)"\x01\x00", diff --git a/hardware-wallet/firmware/gen/fontfixed.inc b/hardware-wallet/firmware/gen/fontfixed.inc new file mode 100644 index 00000000..823d4b0a --- /dev/null +++ b/hardware-wallet/firmware/gen/fontfixed.inc @@ -0,0 +1,128 @@ + /* 0x00 _ */ (uint8_t *)"\x01\x00", + /* 0x01 _ */ (uint8_t *)"\x01\x00", + /* 0x02 _ */ (uint8_t *)"\x01\x00", + /* 0x03 _ */ (uint8_t *)"\x01\x00", + /* 0x04 _ */ (uint8_t *)"\x01\x00", + /* 0x05 _ */ (uint8_t *)"\x01\x00", + /* 0x06 _ */ (uint8_t *)"\x07\x18\x1c\x0e\x18\x30\x40\x80", + /* 0x07 _ */ (uint8_t *)"\x01\x00", + /* 0x08 _ */ (uint8_t *)"\x01\x00", + /* 0x09 _ */ (uint8_t *)"\x01\x00", + /* 0x0a _ */ (uint8_t *)"\x01\x00", + /* 0x0b _ */ (uint8_t *)"\x01\x00", + /* 0x0c _ */ (uint8_t *)"\x01\x00", + /* 0x0d _ */ (uint8_t *)"\x01\x00", + /* 0x0e _ */ (uint8_t *)"\x01\x00", + /* 0x0f _ */ (uint8_t *)"\x01\x00", + /* 0x10 _ */ (uint8_t *)"\x01\x00", + /* 0x11 _ */ (uint8_t *)"\x01\x00", + /* 0x12 _ */ (uint8_t *)"\x01\x00", + /* 0x13 _ */ (uint8_t *)"\x01\x00", + /* 0x14 _ */ (uint8_t *)"\x01\x00", + /* 0x15 _ */ (uint8_t *)"\x07\x44\xee\x7c\x38\x7c\xee\x44", + /* 0x16 _ */ (uint8_t *)"\x01\x00", + /* 0x17 _ */ (uint8_t *)"\x01\x00", + /* 0x18 _ */ (uint8_t *)"\x01\x00", + /* 0x19 _ */ (uint8_t *)"\x01\x00", + /* 0x1a _ */ (uint8_t *)"\x01\x00", + /* 0x1b _ */ (uint8_t *)"\x01\x00", + /* 0x1c _ */ (uint8_t *)"\x01\x00", + /* 0x1d _ */ (uint8_t *)"\x01\x00", + /* 0x1e _ */ (uint8_t *)"\x01\x00", + /* 0x1f _ */ (uint8_t *)"\x01\x00", + /* 0x20 */ (uint8_t *)"\x01\x00", + /* 0x21 ! */ (uint8_t *)"\x03\x60\xfa\x60", + /* 0x22 " */ (uint8_t *)"\x05\x00\xe0\x00\xe0\x00", + /* 0x23 # */ (uint8_t *)"\x05\x6c\xfe\x6c\xfe\x6c", + /* 0x24 $ */ (uint8_t *)"\x05\x32\xff\x5a\xff\x4c", + /* 0x25 % */ (uint8_t *)"\x05\xc2\xcc\x10\x66\x86", + /* 0x26 & */ (uint8_t *)"\x05\x5c\xa2\xb2\x4c\x1a", + /* 0x27 ' */ (uint8_t *)"\x05\x00\x00\xe0\x00\x00", + /* 0x28 ( */ (uint8_t *)"\x03\x38\x44\x82", + /* 0x29 ) */ (uint8_t *)"\x03\x82\x44\x38", + /* 0x2a * */ (uint8_t *)"\x05\x44\x28\xfe\x28\x44", + /* 0x2b + */ (uint8_t *)"\x05\x10\x10\x7c\x10\x10", + /* 0x2c , */ (uint8_t *)"\x03\x01\x06\x00", + /* 0x2d - */ (uint8_t *)"\x04\x10\x10\x10\x10", + /* 0x2e . */ (uint8_t *)"\x03\x00\x02\x00", + /* 0x2f / */ (uint8_t *)"\x03\x06\x38\xc0", + /* 0x30 0 */ (uint8_t *)"\x05\x7c\x82\x92\x82\x7c", + /* 0x31 1 */ (uint8_t *)"\x05\x22\x42\xfe\x02\x02", + /* 0x32 2 */ (uint8_t *)"\x05\x42\x86\x8a\x92\x62", + /* 0x33 3 */ (uint8_t *)"\x05\x44\x82\x92\x92\x6c", + /* 0x34 4 */ (uint8_t *)"\x05\x18\x28\x48\x88\xfe", + /* 0x35 5 */ (uint8_t *)"\x05\xf4\x92\x92\x92\x8c", + /* 0x36 6 */ (uint8_t *)"\x05\x7c\x92\x92\x92\x4c", + /* 0x37 7 */ (uint8_t *)"\x05\x80\x80\x8e\xb0\xc0", + /* 0x38 8 */ (uint8_t *)"\x05\x6c\x92\x92\x92\x6c", + /* 0x39 9 */ (uint8_t *)"\x05\x64\x92\x92\x92\x7c", + /* 0x3a : */ (uint8_t *)"\x03\x00\x24\x00", + /* 0x3b ; */ (uint8_t *)"\x03\x01\x26\x00", + /* 0x3c < */ (uint8_t *)"\x04\x10\x28\x44\x82", + /* 0x3d = */ (uint8_t *)"\x04\x28\x28\x28\x28", + /* 0x3e > */ (uint8_t *)"\x04\x82\x44\x28\x10", + /* 0x3f ? */ (uint8_t *)"\x05\x40\x80\x9a\xa0\x40", + /* 0x40 @ */ (uint8_t *)"\x05\x7c\x82\x9a\xaa\x72", + /* 0x41 A */ (uint8_t *)"\x05\x7e\x90\x90\x90\x7e", + /* 0x42 B */ (uint8_t *)"\x05\xfe\x92\x92\x92\x6c", + /* 0x43 C */ (uint8_t *)"\x05\x7c\x82\x82\x82\x44", + /* 0x44 D */ (uint8_t *)"\x05\xfe\x82\x82\x82\x7c", + /* 0x45 E */ (uint8_t *)"\x05\xfe\x92\x92\x92\x82", + /* 0x46 F */ (uint8_t *)"\x05\xfe\x90\x90\x90\x80", + /* 0x47 G */ (uint8_t *)"\x05\x7c\x82\x82\x92\x5c", + /* 0x48 H */ (uint8_t *)"\x05\xfe\x10\x10\x10\xfe", + /* 0x49 I */ (uint8_t *)"\x05\x82\x82\xfe\x82\x82", + /* 0x4a J */ (uint8_t *)"\x05\x04\x02\x02\x82\xfc", + /* 0x4b K */ (uint8_t *)"\x05\xfe\x10\x28\x44\x82", + /* 0x4c L */ (uint8_t *)"\x05\xfe\x02\x02\x02\x02", + /* 0x4d M */ (uint8_t *)"\x05\xfe\x40\x30\x40\xfe", + /* 0x4e N */ (uint8_t *)"\x05\xfe\x40\x38\x04\xfe", + /* 0x4f O */ (uint8_t *)"\x05\x7c\x82\x82\x82\x7c", + /* 0x50 P */ (uint8_t *)"\x05\xfe\x90\x90\x90\x60", + /* 0x51 Q */ (uint8_t *)"\x05\x7c\x82\x8a\x84\x7a", + /* 0x52 R */ (uint8_t *)"\x05\xfe\x90\x98\x94\x62", + /* 0x53 S */ (uint8_t *)"\x05\x64\x92\x92\x92\x4c", + /* 0x54 T */ (uint8_t *)"\x05\x80\x80\xfe\x80\x80", + /* 0x55 U */ (uint8_t *)"\x05\xfc\x02\x02\x02\xfc", + /* 0x56 V */ (uint8_t *)"\x05\xe0\x18\x06\x18\xe0", + /* 0x57 W */ (uint8_t *)"\x05\xfc\x02\x1c\x02\xfc", + /* 0x58 X */ (uint8_t *)"\x05\xc6\x28\x10\x28\xc6", + /* 0x59 Y */ (uint8_t *)"\x05\xc0\x20\x1e\x20\xc0", + /* 0x5a Z */ (uint8_t *)"\x05\x86\x8a\x92\xa2\xc2", + /* 0x5b [ */ (uint8_t *)"\x03\xfe\x82\x82", + /* 0x5c \ */ (uint8_t *)"\x03\xe0\x38\x0e", + /* 0x5d ] */ (uint8_t *)"\x03\x82\x82\xfe", + /* 0x5e ^ */ (uint8_t *)"\x03\x60\xc0\x60", + /* 0x5f _ */ (uint8_t *)"\x05\x02\x02\x02\x02\x02", + /* 0x60 ` */ (uint8_t *)"\x05\x00\x80\x40\x20\x00", + /* 0x61 a */ (uint8_t *)"\x05\x04\x2a\x2a\x2a\x1e", + /* 0x62 b */ (uint8_t *)"\x05\xfe\x22\x22\x22\x1c", + /* 0x63 c */ (uint8_t *)"\x05\x1c\x22\x22\x22\x14", + /* 0x64 d */ (uint8_t *)"\x05\x1c\x22\x22\x22\xfe", + /* 0x65 e */ (uint8_t *)"\x05\x1c\x2a\x2a\x2a\x1a", + /* 0x66 f */ (uint8_t *)"\x05\x10\x7e\x90\x80\x40", + /* 0x67 g */ (uint8_t *)"\x05\x18\x25\x25\x25\x3e", + /* 0x68 h */ (uint8_t *)"\x05\xfe\x10\x20\x20\x1e", + /* 0x69 i */ (uint8_t *)"\x05\x00\x22\xbe\x02\x00", + /* 0x6a j */ (uint8_t *)"\x05\x02\x01\x21\xbe\x00", + /* 0x6b k */ (uint8_t *)"\x05\xfe\x08\x14\x22\x00", + /* 0x6c l */ (uint8_t *)"\x05\x80\x80\xfc\x02\x02", + /* 0x6d m */ (uint8_t *)"\x05\x3e\x20\x1e\x20\x1e", + /* 0x6e n */ (uint8_t *)"\x05\x3e\x10\x20\x20\x1e", + /* 0x6f o */ (uint8_t *)"\x05\x1c\x22\x22\x22\x1c", + /* 0x70 p */ (uint8_t *)"\x05\x3f\x24\x24\x24\x18", + /* 0x71 q */ (uint8_t *)"\x05\x18\x24\x24\x24\x3f", + /* 0x72 r */ (uint8_t *)"\x05\x3e\x10\x20\x20\x10", + /* 0x73 s */ (uint8_t *)"\x05\x12\x2a\x2a\x2a\x24", + /* 0x74 t */ (uint8_t *)"\x05\x20\x20\xfc\x22\x22", + /* 0x75 u */ (uint8_t *)"\x05\x3c\x02\x02\x02\x3e", + /* 0x76 v */ (uint8_t *)"\x05\x30\x0c\x02\x0c\x30", + /* 0x77 w */ (uint8_t *)"\x05\x3c\x02\x0c\x02\x3c", + /* 0x78 x */ (uint8_t *)"\x05\x22\x36\x08\x36\x22", + /* 0x79 y */ (uint8_t *)"\x05\x38\x05\x05\x05\x3e", + /* 0x7a z */ (uint8_t *)"\x05\x22\x26\x2a\x32\x22", + /* 0x7b { */ (uint8_t *)"\x04\x10\x7c\xee\x82", + /* 0x7c | */ (uint8_t *)"\x03\x00\xfe\x00", + /* 0x7d } */ (uint8_t *)"\x04\x82\xee\x7c\x10", + /* 0x7e ~ */ (uint8_t *)"\x05\x18\x20\x10\x08\x30", + /* 0x7f _ */ (uint8_t *)"\x01\x00", diff --git a/hardware-wallet/firmware/gen/fonts.c b/hardware-wallet/firmware/gen/fonts.c new file mode 100644 index 00000000..68deb549 --- /dev/null +++ b/hardware-wallet/firmware/gen/fonts.c @@ -0,0 +1,18 @@ +#include "fonts.h" + +const uint8_t * const font_data[2][128] = { + { +#include"font.inc" + }, + { +#include"fontfixed.inc" + }, +}; + +int fontCharWidth(int font, char c) { + return font_data[font][c & 0x7f][0]; +} + +const uint8_t *fontCharData(int font, char c) { + return font_data[font][c & 0x7f] + 1; +} diff --git a/hardware-wallet/firmware/gen/fonts.h b/hardware-wallet/firmware/gen/fonts.h new file mode 100644 index 00000000..dbbbef13 --- /dev/null +++ b/hardware-wallet/firmware/gen/fonts.h @@ -0,0 +1,16 @@ +#ifndef __FONTS_H__ +#define __FONTS_H__ + +#include + +#define FONT_HEIGHT 8 +#define FONT_STANDARD 0 +#define FONT_FIXED 1 +#define FONT_DOUBLE 0x80 + +extern const uint8_t * const font_data[2][128]; + +int fontCharWidth(int font, char c); +const uint8_t *fontCharData(int font, char c); + +#endif diff --git a/hardware-wallet/firmware/gen/fonts/font.png b/hardware-wallet/firmware/gen/fonts/font.png new file mode 100644 index 0000000000000000000000000000000000000000..a3d26a98eb7fa4eb7a3937783f9dad53dca2e414 GIT binary patch literal 1795 zcmV+e2mJVnP)005u}0ssI21g-FT000KcNkl7v#pQcC&rznAUv zFRb%)f25Rh&J%bf!La*4f>TNI8J~A$za#T{*Du;?MtVB4JH>sB`Cm)Nr%8Gb-?a|!f22RUOIql#Wc;n0&!e7M^t+WN>4fBy zg0~*bCv*f;te{9Dk}EBA=!X?IpNDi>_j_u;GdL(a)N@XZS9eNvC#6q!>q?dG8TtCv z?(VY1R(eJ@w#Y*N6>=gP#3R%PKaYerfX+N)J*H7cT2nS_p3 zRFh&wDMxIt(PBl~td-?nth82sT{1YYQk`nCgfAa0@9azOx^1i0Zu0iql-IIHYYnC) zSzTQ@$5YbdM1!Dm6x{KiKN^+-MdunEq35{LnTW8UXTYz@RDv_lG05{l_x+bKqy}cx zyqQ<)S@kX)4LU8J>7jNIF@HMbUea`ZaztYF_3F4KL%&(EbRaIj>v7&*P+Ze;)Lc7VfA z7apW=8EFt4w;F1z`@?K;tuQ2X#1&LASSJf%-4ny*u{NIzy4gBk6P%5!pznm|2`u_v z+H^}ckMPBx4AiUJr&4?oB`MolGIw#)6sx*g-Q>8Xy}nyc9%&)c&q{4*x%0QyWHnwj zTQ#GI?$cGHy2{QVRmj?_$hpP%nMaf?lq~QpCCgguIXMr3X{$cC)@rM2&;xz$)?{_h zTDtGt<|p*}m6=80$iyl%E z>#kGreH-j2`siin}_?KLz_LdinO0(Zu1SRmbbYI9K3LJ&K|ZBciV@On%0B|pSXYaeINCp zt=Y@2l1z=Sa0szezd99aRC#CpyTV%4mEw2S8renHV4vQk(>}{N-J?IWHasB_l_WvU z!15(5|LMX}k3CT3aA$tUwVjSEK+}@`_q)qJf_-wtHPwc)&)esUdJaAsRq1fM5W@0D=Jog9T8s@L+Ing3)~*ZN-BL(Ex%01Oo^L5DXv~EP#@Q z2ZMVPjPCPjD;`XU1`rG&7(g(9U;x2j0hBB}7~Gp+be~6C@nAwUfM5W@0D=Jo0|*8S zpk(2};NAqI`#jo;2NR+J1Oo^L5DXv~KrmPUB?}J*_a+$K=h0R?m=Fyh7(g(9U;x1Y zg24hPS$HtGH^JyWkGA5$glGW40D=Jo0|*8X3>HAi!h^xR2}bvMv=t8~L<0y05DXv~ lKrnz{umDOH9t`e`{{UEXYrTBBiSGaa002ovPDHLkV1gm$baem# literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/fonts/fontfixed.png b/hardware-wallet/firmware/gen/fonts/fontfixed.png new file mode 100644 index 0000000000000000000000000000000000000000..50c77f7a4b2fd9dbfee3d64127396cd9040cf7ee GIT binary patch literal 1794 zcmV+d2mSboP)005u}0ssI21g-FT00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-*n2NNwYXxt2%000J|NklhgpiDF*sE)5YF88pb|Zm0!imeWgc!0|!bhz~#2At% z7%;ucUTXG+VMj)9IFjrA&l`Yk1Yw(^?*d37IeM}}kk4Eq{GQ;tJYw-1d zz#0sWu@EH-4+dQmtW=alYx+G7YYcH!vf{PkXgR#$YCQ;HIcqYYUn>L?#xv>DmD)FGk{o%y=f=H%T_B@%{&pSJN`I{%#~r%yU^ztZ?@{uq zJg)Z4MdhN79DZ`wvf^oio5rGI=fz2FxRtiBu{YV~R-@@Cd&1OiSaOKoyFzXorCEaw z!xLH+Kesrs8u^2ng;+ki@-KmqtjYJ3tSdu_G5C5`S>vPE8^gb;Q|vifM-@@BP_n>a zn17*iTR&1^XIq(4VOD5c?0H*;kAdW*%bdfE*t4gta?GCaemDrJ3(;G6&jfH`%=0Oy zyneP)X1ca5_Po9)mvv;c|Lo7+ zG()cq{--c|ZL19awE-_|J(n*!;>Jv$e5Im~)C6WNG$e)V}psYh#aw{eSB<+NTi4wNjE zEHJc^rPPe>Z7Zu$PMu2YLoNB;BanCYErIl2w&d+}O658k%)3jck&YW_9VZ zEuWFU{k%cRYMPn6Rl)T9=bGg+IZ-y3ugt~iqs;sab5@ygnw6|%AZNtJo9u@BR$;zFw z=bT*Sxz7T}1uYUKYiuh@7D^WAdf#x~#l4|qc~qf?tr~qT{r$A~RfODjEipC}^Um$m zC{5*5Q8W4!ipOot*RtLXVe4m0M5pI(&FdryCj^z}2h9f?pTB{#Q;n)flN#s=axIuF z``N5!c0Kv=cKoNlgDLFlMGR9;0BJJ z?7p&2&C0+c7ZW9|?JB4I0sIyh%xP7It&qnVPHoRyU6ic*t)6p>cb|Dg$wJ8jJ!9Tf zlKP+|*BR-{zHm(8rKg$PlIk=Xd2zdI%Y)zC zMGIMnr*uYXElVi!y{`W*S@_ko;t#56-cZZsAyvsdv7|WWq;)RN%0^nW{H&{D+u(SL z*7}Cr6`7A1g*%Gwa>W9LSyxqA^}*+CA*Sc-!&Q~eQi8*!#e3X$KQKYYvSrwl|9<7X ze;sk7Lwv#d5GSV`AwM+E{$S_Q{ICss){7M$`dd8r(HZXKve{a8TSpyX4Xp^#_o_nY z)jd`yJ4(er=Sf0M*6F8ls-AQwKNn06vyFCV<(`AA`ntcC|D!6H`Kj%9r%5PTC|RIy zf=j<$h_!1g9!!V^5DXv~Krnz{0Kwn@lq@_L^i43j&(Kypm=Fyh7(g(9U;x1Yg24eO zS$Ht$n_zUGp{;l@AsRq1fM5W@0D=Jog9A{q@L`LEi+U`wVTxg9*_9f&l~r2nG-g zAQ&8gl7$C@z6nP68QO{m6QThG0|*8X3?LXlFgO4u3l9c;6O8UNv=t8~L<0y05DXv~ kKrnz{Z~#gc9t?WMf0?p;kSOe3RsaA107*qoM6N<$g0q8cYybcN literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/gen/fonts/generate.py b/hardware-wallet/firmware/gen/fonts/generate.py new file mode 100755 index 00000000..d9ade676 --- /dev/null +++ b/hardware-wallet/firmware/gen/fonts/generate.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +from __future__ import print_function +from PIL import Image + +class Img(object): + + def __init__(self, fn): + im = Image.open(fn) + self.w, self.h = im.size + self.data = list(im.getdata()) + + def pixel(self, r, c): + p = self.data[ r + c * self.w ] + if p == (255, 255, 255): + return '0' + if p == (0, 0, 0): + return '1' + if p == (255, 0, 255): + return None + raise Exception('Unknown color', p) + + +def convert(imgfile, outfile): + img = Img(imgfile) + cur = '' + with open(outfile, 'w') as f: + for i in range(128): + x = (i % 16) * 10 + y = (i // 16) * 10 + cur = '' + while img.pixel(x, y) != None: + val = ''.join(img.pixel(x, y + j) for j in range(8)) + x += 1 + cur += '\\x%02x' % int(val, 2) + cur = '\\x%02x' % (len(cur) // 4) + cur + ch = chr(i) if i >= 32 and i <= 126 else '_' + f.write('\t/* 0x%02x %c */ (uint8_t *)"%s",\n' % (i, ch , cur)) + +convert('fonts/fontfixed.png', 'fontfixed.inc') +convert('fonts/font.png', 'font.inc') diff --git a/hardware-wallet/firmware/gen/handlers/handlers.py b/hardware-wallet/firmware/gen/handlers/handlers.py new file mode 100755 index 00000000..5e796106 --- /dev/null +++ b/hardware-wallet/firmware/gen/handlers/handlers.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +from __future__ import print_function + +handlers = [ + 'hard_fault_handler', + 'mem_manage_handler', + 'bus_fault_handler', + 'usage_fault_handler', + 'nvic_wwdg_isr', + 'pvd_isr', + 'tamp_stamp_isr', + 'rtc_wkup_isr', + 'flash_isr', + 'rcc_isr', + 'exti0_isr', + 'exti1_isr', + 'exti2_isr', + 'exti3_isr', + 'exti4_isr', + 'dma1_stream0_isr', + 'dma1_stream1_isr', + 'dma1_stream2_isr', + 'dma1_stream3_isr', + 'dma1_stream4_isr', + 'dma1_stream5_isr', + 'dma1_stream6_isr', + 'adc_isr', + 'can1_tx_isr', + 'can1_rx0_isr', + 'can1_rx1_isr', + 'can1_sce_isr', + 'exti9_5_isr', + 'tim1_brk_tim9_isr', + 'tim1_up_tim10_isr', + 'tim1_trg_com_tim11_isr', + 'tim1_cc_isr', + 'tim2_isr', + 'tim3_isr', + 'tim4_isr', + 'i2c1_ev_isr', + 'i2c1_er_isr', + 'i2c2_ev_isr', + 'i2c2_er_isr', + 'spi1_isr', + 'spi2_isr', + 'usart1_isr', + 'usart2_isr', + 'usart3_isr', + 'exti15_10_isr', + 'rtc_alarm_isr', + 'usb_fs_wkup_isr', + 'tim8_brk_tim12_isr', + 'tim8_up_tim13_isr', + 'tim8_trg_com_tim14_isr', + 'tim8_cc_isr', + 'dma1_stream7_isr', + 'fsmc_isr', + 'sdio_isr', + 'tim5_isr', + 'spi3_isr', + 'uart4_isr', + 'uart5_isr', + 'tim6_dac_isr', + 'tim7_isr', + 'dma2_stream0_isr', + 'dma2_stream1_isr', + 'dma2_stream2_isr', + 'dma2_stream3_isr', + 'dma2_stream4_isr', + 'eth_isr', + 'eth_wkup_isr', + 'can2_tx_isr', + 'can2_rx0_isr', + 'can2_rx1_isr', + 'can2_sce_isr', + 'otg_fs_isr', + 'dma2_stream5_isr', + 'dma2_stream6_isr', + 'dma2_stream7_isr', + 'usart6_isr', + 'i2c3_ev_isr', + 'i2c3_er_isr', + 'otg_hs_ep1_out_isr', + 'otg_hs_ep1_in_isr', + 'otg_hs_wkup_isr', + 'otg_hs_isr', + 'dcmi_isr', + 'cryp_isr', + 'hash_rng_isr', +] + +with open('handlers.c', 'wt') as f: + f.write('#include "layout.h"\n') + f.write('#include "oled.h"\n\n') + for i in handlers: + f.write('void __attribute__((noreturn)) %s(void)\n' % i) + f.write('{\n') + f.write('\tlayoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Encountered", NULL, "%s", NULL, "Please restart", "the device.");\n' % i.upper()) + f.write('\tfor (;;) {} // loop forever\n') + f.write('}\n\n') diff --git a/hardware-wallet/firmware/gen/strwidth.c b/hardware-wallet/firmware/gen/strwidth.c new file mode 100644 index 00000000..8ba3f1c3 --- /dev/null +++ b/hardware-wallet/firmware/gen/strwidth.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +#include "fonts.h" + +static inline char convert(char c) { + if (c < 0x80) { + return c; + } else if (c >= 0xC0) { + return '_'; + } else { + return '\0'; + } +} + +int main(int argc, char **argv) { + char *line; + int font = FONT_STANDARD; + while ((line = readline(NULL)) != NULL) { + size_t length = strlen(line); + if (length) { + add_history(line); + } + + size_t width = 0; + for (size_t i = 0; i < length; i++) { + width += fontCharWidth(font, convert(line[i])) + 1; + } + + printf("%zu\n", width); + free(line); + } +} diff --git a/hardware-wallet/firmware/gen/wordlist/build-recovery-table.pl b/hardware-wallet/firmware/gen/wordlist/build-recovery-table.pl new file mode 100644 index 00000000..60d12eb8 --- /dev/null +++ b/hardware-wallet/firmware/gen/wordlist/build-recovery-table.pl @@ -0,0 +1,110 @@ +#!/usr/bin/perl +print <<'EOF'; +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2016 Jochen Hoenicke + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +EOF + +my @arr1; +my @arr2; +my $x = 0; +my $l = "00"; +my @words; +while (<>) { + $_ =~ /([1-9]{2})[1-9] ([1-6]):(.*)/; + my $n = $1; + my $c = $2; + my @nw = split(",", $3); + die if $c != @nw; + die if $c > 6; + push @words, @nw; + if ($n ne $l) { + $len = @arr2; + die if $len - $arr1[-1] > 9; + push @arr1, $len; + } + push @arr2, $x; + $x += $c; + $l = $n; +} +$len = @arr2; +push @arr1, $len; +push @arr2, $x; + +sub computerange($$$) { + my ($i1, $i2, $entries) = @_; + $prev = $i1 == 0 ? "_" : $words[$i1 - 1]; + $first = $words[$i1]; + $last = $words[$i2-1]; + $next = $i2 == @words ? "_" : $words[$i2]; + my $j; + for ($j = 0; $j < 5; $j++) { + last if substr($first, 0, $j+1) ne substr($last, 0, $j+1); + last if substr($prev, 0, $j) ne substr($first, 0, $j) + && substr($next, 0, $j) ne substr($last, 0, $j); + } + $prefix = substr($first, 0, $j); + $range = ""; + $rng = 0; + if (substr($prev, 0, $j) eq substr($first, 0, $j) + || substr($last, 0, $j) eq substr($next, 0, $j)) { + $range = "[".substr($first, $j, 1) . "-". substr($last, $j, 1)."]"; + $rng++; + if ($j <= 1) { + $range = substr($first,0, $j+1)."-".substr($last,0,$j+1); + $prefix= ""; + } + } + if (substr($prev, 0, $j+1) eq substr($first, 0, $j+1) + || substr($last, 0, $j+1) eq substr($next, 0, $j+1)) { + $j = 0; $rng = 2; + } + #printf STDERR " # %1d: %9s - %9s = \U$prefix$range\E\n", $entries, $first, $last; + return $j + $rng; +} + +print << 'EOF'; +/* DO NOT EDIT: This file is automatically generated by + * cd ../gen/wordlist + * perl build-recoverytable.pl recovery_english.txt + */ + +EOF + +$len = @arr1; +print "static const uint16_t word_table1[$len] =\n"; +print "{"; +for ($i = 0; $i< @arr1; $i++) { + print "\n " if ($i % 9 == 0); + $prefixlen = computerange($arr2[$arr1[$i]], $arr2[$arr1[$i+1]], $arr1[$i+1]-$arr1[$i]); + $prefixlen = 0 if ($i == @arr1 - 1); + printf(" %5d,", $arr1[$i] + 4096 * $prefixlen); +} +print "\n};\n\n"; + +$len = @arr2; +print "static const uint16_t word_table2[$len] =\n"; +print "{"; +for ($i = 0; $i< @arr2; $i++) { + print "\n " if ($i % 9 == 0); + $prefixlen = computerange($arr2[$i], $arr2[$i+1], $arr2[$i+1]-$arr2[$i]); + $prefixlen = 0 if ($i == @arr2 - 1); + printf(" %5d,", $arr2[$i] + 4096 * $prefixlen); +} +print "\n};\n"; diff --git a/hardware-wallet/firmware/gen/wordlist/recovery_english.txt b/hardware-wallet/firmware/gen/wordlist/recovery_english.txt new file mode 100644 index 00000000..ab85f326 --- /dev/null +++ b/hardware-wallet/firmware/gen/wordlist/recovery_english.txt @@ -0,0 +1,630 @@ +111 5:abandon,ability,able,about,above +112 4:absent,absorb,abstract,absurd +113 1:abuse +114 4:access,accident,account,accuse +115 2:achieve,acid +116 2:acoustic,acquire +117 1:across +118 5:act,action,actor,actress,actual +121 1:adapt +122 3:add,addict,address +123 5:adjust,admit,adult,advance,advice +124 1:aerobic +125 3:affair,afford,afraid +126 4:again,age,agent,agree +127 1:ahead +128 4:aim,air,airport,aisle +131 3:alarm,album,alcohol +132 5:alert,alien,all,alley,allow +133 3:almost,alone,alpha +134 4:already,also,alter,always +135 5:amateur,amazing,among,amount,amused +136 3:analyst,anchor,ancient +137 4:anger,angle,angry,animal +138 4:ankle,announce,annual,another +139 5:answer,antenna,antique,anxiety,any +141 6:apart,apology,appear,apple,approve,april +142 2:arch,arctic +143 2:area,arena +144 1:argue +145 4:arm,armed,armor,army +146 1:around +147 4:arrange,arrest,arrive,arrow +148 4:art,artefact,artist,artwork +151 2:ask,aspect +152 4:assault,asset,assist,assume +153 1:asthma +154 6:athlete,atom,attack,attend,attitude,attract +155 3:auction,audit,august +156 4:aunt,author,auto,autumn +157 3:average,avocado,avoid +158 6:awake,aware,away,awesome,awful,awkward +159 1:axis +161 4:baby,bachelor,bacon,badge +162 5:bag,balance,balcony,ball,bamboo +163 6:banana,banner,bar,barely,bargain,barrel +164 4:base,basic,basket,battle +165 5:beach,bean,beauty,because,become +166 3:beef,before,begin +167 5:behave,behind,believe,below,belt +168 3:bench,benefit,best +169 4:betray,better,between,beyond +171 2:bicycle,bid +172 3:bike,bind,biology +173 3:bird,birth,bitter +174 5:black,blade,blame,blanket,blast +175 3:bleak,bless,blind +176 3:blood,blossom,blouse +177 3:blue,blur,blush +181 4:board,boat,body,boil +182 5:bomb,bone,bonus,book,boost +183 4:border,boring,borrow,boss +184 4:bottom,bounce,box,boy +185 5:bracket,brain,brand,brass,brave +186 2:bread,breeze +187 6:brick,bridge,brief,bright,bring,brisk +188 6:broccoli,broken,bronze,broom,brother,brown +189 1:brush +191 5:bubble,buddy,budget,buffalo,build +192 3:bulb,bulk,bullet +193 2:bundle,bunker +194 3:burden,burger,burst +195 3:bus,business,busy +196 3:butter,buyer,buzz +211 3:cabbage,cabin,cable +212 1:cactus +213 1:cage +214 1:cake +215 2:call,calm +216 2:camera,camp +221 4:can,canal,cancel,candy +222 4:cannon,canoe,canvas,canyon +223 3:capable,capital,captain +224 4:car,carbon,card,cargo +225 3:carpet,carry,cart +226 5:case,cash,casino,castle,casual +227 5:cat,catalog,catch,category,cattle +228 3:caught,cause,caution +229 1:cave +231 1:ceiling +232 1:celery +233 1:cement +234 2:census,century +235 2:cereal,certain +241 3:chair,chalk,champion +243 6:change,chaos,chapter,charge,chase,chat +245 6:cheap,check,cheese,chef,cherry,chest +246 4:chicken,chief,child,chimney +247 2:choice,choose +248 1:chronic +249 3:chuckle,chunk,churn +251 1:cigar +252 1:cinnamon +253 1:circle +254 2:citizen,city +255 1:civil +261 5:claim,clap,clarify,claw,clay +262 3:clean,clerk,clever +263 6:click,client,cliff,climb,clinic,clip +264 6:clock,clog,close,cloth,cloud,clown +265 4:club,clump,cluster,clutch +271 5:coach,coast,coconut,code,coffee +272 5:coil,coin,collect,color,column +273 6:combine,come,comfort,comic,common,company +274 4:concert,conduct,confirm,congress +275 4:connect,consider,control,convince +276 4:cook,cool,copper,copy +277 6:coral,core,corn,correct,cost,cotton +278 5:couch,country,couple,course,cousin +279 2:cover,coyote +281 4:crack,cradle,craft,cram +283 5:crane,crash,crater,crawl,crazy +285 4:cream,credit,creek,crew +286 4:cricket,crime,crisp,critic +287 4:crop,cross,crouch,crowd +288 6:crucial,cruel,cruise,crumble,crunch,crush +289 2:cry,crystal +291 1:cube +292 1:culture +293 2:cup,cupboard +294 4:curious,current,curtain,curve +295 2:cushion,custom +296 1:cute +299 1:cycle +311 1:dad +312 2:damage,damp +313 2:dance,danger +314 1:daring +315 1:dash +316 1:daughter +317 1:dawn +318 1:day +321 1:deal +322 2:debate,debris +323 6:decade,december,decide,decline,decorate,decrease +324 1:deer +325 3:defense,define,defy +326 1:degree +327 2:delay,deliver +328 2:demand,demise +331 3:denial,dentist,deny +332 5:depart,depend,deposit,depth,deputy +333 1:derive +334 6:describe,desert,design,desk,despair,destroy +335 2:detail,detect +336 3:develop,device,devote +341 4:diagram,dial,diamond,diary +342 3:dice,diesel,diet +343 4:differ,digital,dignity,dilemma +344 2:dinner,dinosaur +345 2:direct,dirt +346 5:disagree,discover,disease,dish,dismiss +347 3:disorder,display,distance +348 3:divert,divide,divorce +349 1:dizzy +351 2:doctor,document +352 1:dog +353 2:doll,dolphin +354 1:domain +355 3:donate,donkey,donor +356 1:door +357 1:dose +358 1:double +359 1:dove +361 5:draft,dragon,drama,drastic,draw +362 2:dream,dress +363 5:drift,drill,drink,drip,drive +364 3:drop,drum,dry +365 2:duck,dumb +366 5:dune,during,dust,dutch,duty +368 1:dwarf +369 1:dynamic +371 2:eager,eagle +372 6:early,earn,earth,easily,east,easy +373 6:echo,ecology,economy,edge,edit,educate +374 4:effort,egg,eight,either +375 2:elbow,elder +376 5:electric,elegant,element,elephant,elevator +377 2:elite,else +378 4:embark,embody,embrace,emerge +379 4:emotion,employ,empower,empty +381 2:enable,enact +382 3:end,endless,endorse +383 5:enemy,energy,enforce,engage,engine +384 3:enhance,enjoy,enlist +385 4:enough,enrich,enroll,ensure +386 4:enter,entire,entry,envelope +387 3:episode,equal,equip +388 6:era,erase,erode,erosion,error,erupt +389 4:escape,essay,essence,estate +391 2:eternal,ethics +392 4:evidence,evil,evoke,evolve +393 2:exact,example +394 5:excess,exchange,excite,exclude,excuse +395 4:execute,exercise,exhaust,exhibit +396 4:exile,exist,exit,exotic +397 6:expand,expect,expire,explain,expose,express +398 2:extend,extra +399 2:eye,eyebrow +411 3:fabric,face,faculty +412 1:fade +413 2:faint,faith +414 2:fall,false +415 3:fame,family,famous +416 3:fan,fancy,fantasy +417 2:farm,fashion +418 4:fat,fatal,father,fatigue +419 2:fault,favorite +421 3:feature,february,federal +422 3:fee,feed,feel +423 6:female,fence,festival,fetch,fever,few +431 4:fiber,fiction,field,figure +432 3:file,film,filter +433 5:final,find,fine,finger,finish +434 3:fire,firm,first +435 5:fiscal,fish,fit,fitness,fix +441 5:flag,flame,flash,flat,flavor +442 3:flee,flight,flip +443 4:float,flock,floor,flower +444 3:fluid,flush,fly +445 4:foam,focus,fog,foil +446 4:fold,follow,food,foot +447 4:force,forest,forget,fork +448 3:fortune,forum,forward +449 4:fossil,foster,found,fox +451 2:fragile,frame +452 2:frequent,fresh +453 2:friend,fringe +454 5:frog,front,frost,frown,frozen +455 1:fruit +458 6:fuel,fun,funny,furnace,fury,future +461 2:gadget,gain +462 2:galaxy,gallery +463 2:game,gap +464 5:garage,garbage,garden,garlic,garment +465 2:gas,gasp +466 2:gate,gather +467 2:gauge,gaze +471 6:general,genius,genre,gentle,genuine,gesture +472 1:ghost +473 1:giant +474 1:gift +475 1:giggle +476 1:ginger +477 2:giraffe,girl +478 1:give +481 4:glad,glance,glare,glass +482 2:glide,glimpse +483 5:globe,gloom,glory,glove,glow +484 1:glue +486 2:goat,goddess +487 3:gold,good,goose +488 3:gorilla,gospel,gossip +489 2:govern,gown +491 3:grab,grace,grain +492 4:grant,grape,grass,gravity +493 2:great,green +494 3:grid,grief,grit +495 3:grocery,group,grow +496 1:grunt +497 6:guard,guess,guide,guilt,guitar,gun +498 1:gym +511 2:habit,hair +512 3:half,hammer,hamster +513 2:hand,happy +514 4:harbor,hard,harsh,harvest +515 4:hat,have,hawk,hazard +516 4:head,health,heart,heavy +517 2:hedgehog,height +518 3:hello,helmet,help +519 2:hen,hero +521 2:hidden,high +522 2:hill,hint +523 3:hip,hire,history +524 2:hobby,hockey +525 4:hold,hole,holiday,hollow +526 4:home,honey,hood,hope +527 3:horn,horror,horse +528 5:hospital,host,hotel,hour,hover +531 1:hub +532 1:huge +533 3:human,humble,humor +534 3:hundred,hungry,hunt +535 3:hurdle,hurry,hurt +536 1:husband +539 1:hybrid +541 2:ice,icon +542 3:idea,identify,idle +543 1:ignore +544 3:ill,illegal,illness +545 1:image +546 1:imitate +547 2:immense,immune +548 4:impact,impose,improve,impulse +551 4:inch,include,income,increase +552 4:index,indicate,indoor,industry +553 3:infant,inflict,inform +554 3:inhale,inherit,initial +555 3:inject,injury,inmate +556 4:inner,innocent,input,inquiry +557 5:insane,insect,inside,inspire,install +558 6:intact,interest,into,invest,invite,involve +559 6:iron,island,isolate,issue,item,ivory +561 4:jacket,jaguar,jar,jazz +562 4:jealous,jeans,jelly,jewel +563 5:job,join,joke,journey,joy +564 1:judge +565 1:juice +566 1:jump +567 3:jungle,junior,junk +568 1:just +571 1:kangaroo +572 4:keen,keep,ketchup,key +573 1:kick +574 2:kid,kidney +575 2:kind,kingdom +576 1:kiss +577 4:kit,kitchen,kite,kitten +578 1:kiwi +579 4:knee,knife,knock,know +581 5:lab,label,labor,ladder,lady +582 3:lake,lamp,language +583 4:laptop,large,later,latin +584 3:laugh,laundry,lava +585 5:law,lawn,lawsuit,layer,lazy +586 4:leader,leaf,learn,leave +587 5:lecture,left,leg,legal,legend +588 5:leisure,lemon,lend,length,lens +589 4:leopard,lesson,letter,level +591 4:liar,liberty,library,license +592 4:life,lift,light,like +593 4:limb,limit,link,lion +594 5:liquid,list,little,live,lizard +595 5:load,loan,lobster,local,lock +596 4:logic,lonely,long,loop +597 5:lottery,loud,lounge,love,loyal +598 6:lucky,luggage,lumber,lunar,lunch,luxury +599 1:lyrics +611 4:machine,mad,magic,magnet +612 3:maid,mail,main +613 3:major,make,mammal +614 6:man,manage,mandate,mango,mansion,manual +615 1:maple +616 6:marble,march,margin,marine,market,marriage +617 3:mask,mass,master +618 5:match,material,math,matrix,matter +619 2:maximum,maze +621 4:meadow,mean,measure,meat +622 1:mechanic +623 2:medal,media +624 2:melody,melt +625 2:member,memory +626 2:mention,menu +627 4:mercy,merge,merit,merry +628 2:mesh,message +629 2:metal,method +631 2:middle,midnight +632 2:milk,million +633 1:mimic +634 4:mind,minimum,minor,minute +635 2:miracle,mirror +636 3:misery,miss,mistake +637 3:mix,mixed,mixture +641 5:mobile,model,modify,mom,moment +642 4:monitor,monkey,monster,month +643 4:moon,moral,more,morning +644 4:mosquito,mother,motion,motor +645 4:mountain,mouse,move,movie +646 4:much,muffin,mule,multiply +647 5:muscle,museum,mushroom,music,must +648 1:mutual +649 3:myself,mystery,myth +651 2:naive,name +652 2:napkin,narrow +653 3:nasty,nation,nature +654 2:near,neck +655 3:need,negative,neglect +656 2:neither,nephew +657 2:nerve,nest +658 3:net,network,neutral +659 3:never,news,next +661 2:nice,night +662 4:noble,noise,nominee,noodle +663 2:normal,north +664 1:nose +665 4:notable,note,nothing,notice +666 2:novel,now +669 4:nuclear,number,nurse,nut +671 1:oak +672 3:obey,object,oblige +673 4:obscure,observe,obtain,obvious +675 3:occur,ocean,october +676 1:odor +677 4:off,offer,office,often +678 1:oil +679 1:okay +681 3:old,olive,olympic +682 1:omit +683 5:once,one,onion,online,only +684 5:open,opera,opinion,oppose,option +691 6:orange,orbit,orchard,order,ordinary,organ +692 3:orient,original,orphan +693 1:ostrich +694 1:other +695 4:outdoor,outer,output,outside +696 3:oval,oven,over +697 2:own,owner +698 3:oxygen,oyster,ozone +711 6:pact,paddle,page,pair,palace,palm +712 5:panda,panel,panic,panther,paper +713 6:parade,parent,park,parrot,party,pass +714 5:patch,path,patient,patrol,pattern +715 3:pause,pave,payment +716 4:peace,peanut,pear,peasant +717 5:pelican,pen,penalty,pencil,people +718 5:pepper,perfect,permit,person,pet +719 4:phone,photo,phrase,physical +721 4:piano,picnic,picture,piece +722 5:pig,pigeon,pill,pilot,pink +723 5:pioneer,pipe,pistol,pitch,pizza +724 5:place,planet,plastic,plate,play +725 5:please,pledge,pluck,plug,plunge +726 3:poem,poet,point +727 5:polar,pole,police,pond,pony +728 6:pool,popular,portion,position,possible,post +729 5:potato,pottery,poverty,powder,power +731 2:practice,praise +732 6:predict,prefer,prepare,present,pretty,prevent +733 3:price,pride,primary +735 5:print,priority,prison,private,prize +736 4:problem,process,produce,profit +737 5:program,project,promote,proof,property +739 4:prosper,protect,proud,provide +741 2:public,pudding +742 3:pull,pulp,pulse +743 2:pumpkin,punch +744 2:pupil,puppy +745 4:purchase,purity,purpose,purse +746 3:push,put,puzzle +749 1:pyramid +751 3:quality,quantum,quarter +752 1:question +753 3:quick,quit,quiz +754 1:quote +761 1:rabbit +762 3:raccoon,race,rack +763 2:radar,radio +764 3:rail,rain,raise +765 2:rally,ramp +766 3:ranch,random,range +767 2:rapid,rare +768 2:rate,rather +769 3:raven,raw,razor +771 3:ready,real,reason +772 2:rebel,rebuild +773 5:recall,receive,recipe,record,recycle +774 1:reduce +775 3:reflect,reform,refuse +776 3:region,regret,regular +777 1:reject +778 4:relax,release,relief,rely +779 4:remain,remember,remind,remove +781 3:render,renew,rent +782 1:reopen +783 4:repair,repeat,replace,report +784 1:require +785 6:rescue,resemble,resist,resource,response,result +786 3:retire,retreat,return +787 1:reunion +788 2:reveal,review +789 1:reward +791 1:rhythm +792 6:rib,ribbon,rice,rich,ride,ridge +793 5:rifle,right,rigid,ring,riot +794 5:ripple,risk,ritual,rival,river +795 5:road,roast,robot,robust,rocket +796 5:romance,roof,rookie,room,rose +797 5:rotate,rough,round,route,royal +798 3:rubber,rude,rug +799 4:rule,run,runway,rural +811 5:sad,saddle,sadness,safe,sail +812 5:salad,salmon,salon,salt,salute +813 3:same,sample,sand +814 4:satisfy,satoshi,sauce,sausage +815 2:save,say +816 4:scale,scan,scare,scatter +817 3:scene,scheme,school +818 4:science,scissors,scorpion,scout +819 4:scrap,screen,script,scrub +821 4:sea,search,season,seat +822 4:second,secret,section,security +823 6:seed,seek,segment,select,sell,seminar +824 3:senior,sense,sentence +825 6:series,service,session,settle,setup,seven +831 4:shadow,shaft,shallow,share +832 3:shed,shell,sheriff +833 5:shield,shift,shine,ship,shiver +834 2:shock,shoe +836 5:shoot,shop,short,shoulder,shove +837 2:shrimp,shrug +838 1:shuffle +839 1:shy +841 4:sibling,sick,side,siege +842 6:sight,sign,silent,silk,silly,silver +843 4:similar,simple,since,sing +844 5:siren,sister,situate,six,size +845 2:skate,sketch +846 5:ski,skill,skin,skirt,skull +847 4:slab,slam,sleep,slender +848 4:slice,slide,slight,slim +849 4:slogan,slot,slow,slush +851 5:small,smart,smile,smoke,smooth +852 5:snack,snake,snap,sniff,snow +853 1:soap +854 3:soccer,social,sock +855 2:soda,soft +856 5:solar,soldier,solid,solution,solve +857 3:someone,song,soon +858 2:sorry,sort +859 5:soul,sound,soup,source,south +861 4:space,spare,spatial,spawn +862 5:speak,special,speed,spell,spend +863 1:sphere +864 5:spice,spider,spike,spin,spirit +865 1:split +866 5:spoil,sponsor,spoon,sport,spot +867 3:spray,spread,spring +868 1:spy +869 3:square,squeeze,squirrel +871 6:stable,stadium,staff,stage,stairs,stamp +872 4:stand,start,state,stay +873 5:steak,steel,stem,step,stereo +874 3:stick,still,sting +875 6:stock,stomach,stone,stool,story,stove +876 5:strategy,street,strike,strong,struggle +877 3:student,stuff,stumble +878 1:style +881 3:subject,submit,subway +882 2:success,such +883 4:sudden,suffer,sugar,suggest +884 2:suit,summer +885 3:sun,sunny,sunset +886 3:super,supply,supreme +887 6:sure,surface,surge,surprise,surround,survey +888 2:suspect,sustain +891 4:swallow,swamp,swap,swarm +892 2:swear,sweet +893 4:swift,swim,swing,switch +894 1:sword +898 4:symbol,symptom,syrup,system +911 4:table,tackle,tag,tail, +912 5:talent,talk,tank,tape,target +913 4:task,taste,tattoo,taxi +914 3:teach,team,tell +915 4:ten,tenant,tennis,tent +916 3:term,test,text +921 2:thank,that +922 5:theme,then,theory,there,they +923 3:thing,this,thought +924 3:three,thrive,throw +925 2:thumb,thunder +926 2:ticket,tide +927 4:tiger,tilt,timber,time +928 2:tiny,tip +929 3:tired,tissue,title +931 4:toast,tobacco,today,toddler +932 3:toe,together,toilet +933 3:token,tomato,tomorrow +934 3:tone,tongue,tonight +935 2:tool,tooth +936 3:top,topic,topple +937 3:torch,tornado,tortoise +938 3:toss,total,tourist +939 4:toward,tower,town,toy +941 5:track,trade,traffic,tragic,train +942 5:transfer,trap,trash,travel,tray +943 3:treat,tree,trend +944 6:trial,tribe,trick,trigger,trim,trip +945 2:trophy,trouble +946 6:truck,true,truly,trumpet,trust,truth +947 1:try +951 5:tube,tuition,tumble,tuna,tunnel +952 3:turkey,turn,turtle +953 6:twelve,twenty,twice,twin,twist,two +954 2:type,typical +961 2:ugly,umbrella +962 4:unable,unaware,uncle,uncover +963 5:under,undo,unfair,unfold,unhappy +964 4:uniform,unique,unit,universe +965 5:unknown,unlock,until,unusual,unveil +966 6:update,upgrade,uphold,upon,upper,upset +967 2:urban,urge +968 6:usage,use,used,useful,useless,usual +969 1:utility +971 6:vacant,vacuum,vague,valid,valley,valve +972 6:van,vanish,vapor,various,vast,vault +973 5:vehicle,velvet,vendor,venture,venue +974 6:verb,verify,version,very,vessel,veteran +975 5:viable,vibrant,vicious,victory,video +976 6:view,village,vintage,violin,virtual,virus +977 5:visa,visit,visual,vital,vivid +978 3:vocal,voice,void +979 4:volcano,volume,vote,voyage +981 3:wage,wagon,wait +982 4:walk,wall,walnut,want +983 3:warfare,warm,warrior +984 6:wash,wasp,waste,water,wave,way +985 5:wealth,weapon,wear,weasel,weather +986 3:web,wedding,weekend +987 4:weird,welcome,west,wet +988 6:whale,what,wheat,wheel,when,where +989 2:whip,whisper +991 5:wide,width,wife,wild,will +992 5:win,window,wine,wing,wink +993 2:winner,winter +994 5:wire,wisdom,wise,wish,witness +995 5:wolf,woman,wonder,wood,wool +996 5:word,work,world,worry,worth +997 6:wrap,wreck,wrestle,wrist,write,wrong +998 6:yard,year,yellow,you,young,youth +999 4:zebra,zero,zone,zoo diff --git a/hardware-wallet/firmware/gitian/gitian.yml b/hardware-wallet/firmware/gitian/gitian.yml new file mode 100644 index 00000000..2f24b977 --- /dev/null +++ b/hardware-wallet/firmware/gitian/gitian.yml @@ -0,0 +1,19 @@ +--- +name: "trezor-mcu" +enable_cache: true +suites: +- "trusty" +architectures: +- "amd64" +packages: +- "build-essential" +- "gcc-arm-none-eabi" +reference_datetime: "2015-06-01 00:00:00" +remotes: +- "url": "https://github.com/trezor/trezor-mcu.git" + "dir": "trezor-mcu" +files: [] +script: | + make -C vendor/libopencm3 + make + make -C firmware diff --git a/hardware-wallet/firmware/layout.c b/hardware-wallet/firmware/layout.c new file mode 100644 index 00000000..cb8302b9 --- /dev/null +++ b/hardware-wallet/firmware/layout.c @@ -0,0 +1,116 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include "layout.h" +#include "oled.h" + +void layoutButtonNo(const char *btnNo) +{ + oledDrawString(1, OLED_HEIGHT - 8, "\x15", FONT_STANDARD); + oledDrawString(fontCharWidth(FONT_STANDARD, '\x15') + 3, OLED_HEIGHT - 8, btnNo, FONT_STANDARD); + oledInvert(0, OLED_HEIGHT - 9, fontCharWidth(FONT_STANDARD, '\x15') + oledStringWidth(btnNo, FONT_STANDARD) + 2, OLED_HEIGHT - 1); +} + +void layoutButtonYes(const char *btnYes) +{ + oledDrawString(OLED_WIDTH - fontCharWidth(FONT_STANDARD, '\x06') - 1, OLED_HEIGHT - 8, "\x06", FONT_STANDARD); + oledDrawStringRight(OLED_WIDTH - fontCharWidth(FONT_STANDARD, '\x06') - 3, OLED_HEIGHT - 8, btnYes, FONT_STANDARD); + oledInvert(OLED_WIDTH - oledStringWidth(btnYes, FONT_STANDARD) - fontCharWidth(FONT_STANDARD, '\x06') - 4, OLED_HEIGHT - 9, OLED_WIDTH - 1, OLED_HEIGHT - 1); +} + +void layoutDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6) +{ + int left = 0; + oledClear(); + if (icon) { + oledDrawBitmap(0, 0, icon); + left = icon->width + 4; + } + if (line1) oledDrawString(left, 0 * 9, line1, FONT_STANDARD); + if (line2) oledDrawString(left, 1 * 9, line2, FONT_STANDARD); + if (line3) oledDrawString(left, 2 * 9, line3, FONT_STANDARD); + if (line4) oledDrawString(left, 3 * 9, line4, FONT_STANDARD); + if (desc) { + oledDrawStringCenter(OLED_HEIGHT - 2 * 9 - 1, desc, FONT_STANDARD); + if (btnYes || btnNo) { + oledHLine(OLED_HEIGHT - 21); + } + } else { + if (line5) oledDrawString(left, 4 * 9, line5, FONT_STANDARD); + if (line6) oledDrawString(left, 5 * 9, line6, FONT_STANDARD); + if (btnYes || btnNo) { + oledHLine(OLED_HEIGHT - 13); + } + } + if (btnNo) { + layoutButtonNo(btnNo); + } + if (btnYes) { + layoutButtonYes(btnYes); + } + oledRefresh(); +} + +void layoutProgressUpdate(bool refresh) +{ + static uint8_t step = 0; + switch (step) { + case 0: + oledDrawBitmap(40, 0, &bmp_gears0); + break; + case 1: + oledDrawBitmap(40, 0, &bmp_gears1); + break; + case 2: + oledDrawBitmap(40, 0, &bmp_gears2); + break; + case 3: + oledDrawBitmap(40, 0, &bmp_gears3); + break; + } + step = (step + 1) % 4; + if (refresh) { + oledRefresh(); + } +} + +void layoutProgress(const char *desc, int permil) +{ + oledClear(); + layoutProgressUpdate(false); + // progressbar + oledFrame(0, OLED_HEIGHT - 8, OLED_WIDTH - 1, OLED_HEIGHT - 1); + oledBox(1, OLED_HEIGHT - 7, OLED_WIDTH - 2, OLED_HEIGHT - 2, 0); + permil = permil * (OLED_WIDTH - 4) / 1000; + if (permil < 0) { + permil = 0; + } + if (permil > OLED_WIDTH - 4) { + permil = OLED_WIDTH - 4; + } + oledBox(2, OLED_HEIGHT - 6, 1 + permil, OLED_HEIGHT - 3, 1); + // text + oledBox(0, OLED_HEIGHT - 16, OLED_WIDTH - 1, OLED_HEIGHT - 16 + 7, 0); + if (desc) { + oledDrawStringCenter(OLED_HEIGHT - 16, desc, FONT_STANDARD); + } + oledRefresh(); +} diff --git a/hardware-wallet/firmware/layout.h b/hardware-wallet/firmware/layout.h new file mode 100644 index 00000000..eea04327 --- /dev/null +++ b/hardware-wallet/firmware/layout.h @@ -0,0 +1,33 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __LAYOUT_H__ +#define __LAYOUT_H__ + +#include +#include +#include "bitmaps.h" + +void layoutButtonNo(const char *btnNo); +void layoutButtonYes(const char *btnYes); +void layoutDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6); +void layoutProgressUpdate(bool refresh); +void layoutProgress(const char *desc, int permil); + +#endif diff --git a/hardware-wallet/firmware/make-firmware.sh b/hardware-wallet/firmware/make-firmware.sh new file mode 100755 index 00000000..e4c320e0 --- /dev/null +++ b/hardware-wallet/firmware/make-firmware.sh @@ -0,0 +1,19 @@ +make -C vendor/libopencm3/ +make -C vendor/nanopb/generator/proto/ +make -C firmware/protob/ +# make -C vendor/skycoin-crypto/ +export MEMORY_PROTECT=0 +make +make -C bootloader/ align +make -C firmware/ sign + +#sudo cp 99-dev-kit.rules /etc/udev/rules.d/ + +cp bootloader/bootloader.bin bootloader/combine/bl.bin +cp firmware/trezor.bin bootloader/combine/fw.bin +pushd bootloader/combine/ && ./prepare.py +popd; + +#st-flash erase + +alias st-trezor='pushd bootloader/combine/; st-flash write combined.bin 0x08000000; popd;' diff --git a/hardware-wallet/firmware/memory.c b/hardware-wallet/firmware/memory.c new file mode 100644 index 00000000..da078419 --- /dev/null +++ b/hardware-wallet/firmware/memory.c @@ -0,0 +1,57 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include "memory.h" +#include "sha2.h" + +#define FLASH_OPTION_BYTES_1 (*(const uint64_t *)0x1FFFC000) +#define FLASH_OPTION_BYTES_2 (*(const uint64_t *)0x1FFFC008) + +void memory_protect(void) +{ +#if MEMORY_PROTECT + // Reference STM32F205 Flash programming manual revision 5 http://www.st.com/resource/en/programming_manual/cd00233952.pdf + // Section 2.6 Option bytes + // set RDP level 2 WRP for sectors 0 and 1 flash option control register matches + if (((FLASH_OPTION_BYTES_1 & 0xFFEC) == 0xCCEC) && ((FLASH_OPTION_BYTES_2 & 0xFFF) == 0xFFC) && (FLASH_OPTCR == 0x0FFCCCED)) { + return; // already set up correctly - bail out + } + flash_unlock_option_bytes(); + // Section 2.8.6 Flash option control register (FLASH_OPTCR) + // Bits 31:28 Reserved, must be kept cleared. + // Bits 27:16 nWRP: Not write protect: write protect bootloader code in flash main memory sectors 0 and 1 (Section 2.3; table 2) + // Bits 15:8 RDP: Read protect: level 2 chip read protection active + // Bits 7:5 USER: User option bytes: no reset on standby, no reset on stop, software watchdog + // Bit 4 Reserved, must be kept cleared. + // Bits 3:2 BOR_LEV: BOR reset Level: BOR off + // Bit 1 OPTSTRT: Option start: ignored by flash_program_option_bytes + // Bit 0 OPTLOCK: Option lock: ignored by flash_program_option_bytes + flash_program_option_bytes(0x0FFCCCEC); + flash_lock_option_bytes(); +#endif +} + +int memory_bootloader_hash(uint8_t *hash) +{ + sha256_Raw((const uint8_t *)FLASH_BOOT_START, FLASH_BOOT_LEN, hash); + sha256_Raw(hash, 32, hash); + return 32; +} diff --git a/hardware-wallet/firmware/memory.h b/hardware-wallet/firmware/memory.h new file mode 100644 index 00000000..f6c4a870 --- /dev/null +++ b/hardware-wallet/firmware/memory.h @@ -0,0 +1,108 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + +/* + + flash memory layout: + + name | range | size | function +-----------+-------------------------+---------+------------------ + Sector 0 | 0x08000000 - 0x08003FFF | 16 KiB | bootloader code + Sector 1 | 0x08004000 - 0x08007FFF | 16 KiB | bootloader code +-----------+-------------------------+---------+------------------ + Sector 2 | 0x08008000 - 0x0800BFFF | 16 KiB | metadata area + Sector 3 | 0x0800C000 - 0x0800FFFF | 16 KiB | metadata area +-----------+-------------------------+---------+------------------ + Sector 4 | 0x08010000 - 0x0801FFFF | 64 KiB | application code + Sector 5 | 0x08020000 - 0x0803FFFF | 128 KiB | application code + Sector 6 | 0x08040000 - 0x0805FFFF | 128 KiB | application code + Sector 7 | 0x08060000 - 0x0807FFFF | 128 KiB | application code +===========+=========================+============================ + Sector 8 | 0x08080000 - 0x0809FFFF | 128 KiB | N/A + Sector 9 | 0x080A0000 - 0x080BFFFF | 128 KiB | N/A + Sector 10 | 0x080C0000 - 0x080DFFFF | 128 KiB | N/A + Sector 11 | 0x080E0000 - 0x080FFFFF | 128 KiB | N/A + + metadata area: + + offset | type/length | description +--------+-------------+------------------------------- + 0x0000 | 4 bytes | magic = 'TRZR' + 0x0004 | uint32 | length of the code (codelen) + 0x0008 | uint8 | signature index #1 + 0x0009 | uint8 | signature index #2 + 0x000A | uint8 | signature index #3 + 0x000B | uint8 | flags + 0x000C | 52 bytes | reserved + 0x0040 | 64 bytes | signature #1 + 0x0080 | 64 bytes | signature #2 + 0x00C0 | 64 bytes | signature #3 + 0x0100 | 32K-256 B | persistent storage + + flags & 0x01 -> restore storage after flashing (if signatures are ok) + + */ + +#if EMULATOR +#define FLASH_ORIGIN ((uint32_t) emulator_flash_base) +#else +#define FLASH_ORIGIN (0x08000000) +#endif + +#define FLASH_TOTAL_SIZE (512 * 1024) + +#define FLASH_BOOT_START (FLASH_ORIGIN) +#define FLASH_BOOT_LEN (0x8000) + +#define FLASH_META_START (FLASH_BOOT_START + FLASH_BOOT_LEN) +#define FLASH_META_LEN (0x8000) + +#define FLASH_APP_START (FLASH_META_START + FLASH_META_LEN) + +#define FLASH_META_MAGIC (FLASH_META_START) +#define FLASH_META_CODELEN (FLASH_META_START + 0x0004) +#define FLASH_META_SIGINDEX1 (FLASH_META_START + 0x0008) +#define FLASH_META_SIGINDEX2 (FLASH_META_START + 0x0009) +#define FLASH_META_SIGINDEX3 (FLASH_META_START + 0x000A) +#define FLASH_META_FLAGS (FLASH_META_START + 0x000B) +#define FLASH_META_SIG1 (FLASH_META_START + 0x0040) +#define FLASH_META_SIG2 (FLASH_META_START + 0x0080) +#define FLASH_META_SIG3 (FLASH_META_START + 0x00C0) + +#define FLASH_META_DESC_LEN (0x100) + +#define FLASH_STORAGE_START (FLASH_META_START + FLASH_META_DESC_LEN) +#define FLASH_STORAGE_LEN (FLASH_APP_START - FLASH_STORAGE_START) + +#define FLASH_BOOT_SECTOR_FIRST 0 +#define FLASH_BOOT_SECTOR_LAST 1 + +#define FLASH_META_SECTOR_FIRST 2 +#define FLASH_META_SECTOR_LAST 3 + +#define FLASH_CODE_SECTOR_FIRST 4 +#define FLASH_CODE_SECTOR_LAST 7 + +void memory_protect(void); +int memory_bootloader_hash(uint8_t *hash); + +#endif diff --git a/hardware-wallet/firmware/memory.ld b/hardware-wallet/firmware/memory.ld new file mode 100644 index 00000000..b147a909 --- /dev/null +++ b/hardware-wallet/firmware/memory.ld @@ -0,0 +1,22 @@ +/* STM32F205RE - 512K Flash, 128K RAM */ + +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +SECTIONS +{ + .confidential (NOLOAD) : { + *(confidential) + ASSERT ((SIZEOF(.confidential) <= 33K), "Error: Confidential section too big!"); + } >ram +} + +INCLUDE libopencm3_stm32f2.ld + +_ram_start = ORIGIN(ram); +_ram_end = ORIGIN(ram) + LENGTH(ram); + +_data_size = SIZEOF(.data); diff --git a/hardware-wallet/firmware/memory_app_0.0.0.ld b/hardware-wallet/firmware/memory_app_0.0.0.ld new file mode 100644 index 00000000..ce3f3f7c --- /dev/null +++ b/hardware-wallet/firmware/memory_app_0.0.0.ld @@ -0,0 +1,9 @@ +/* STM32F205RE - 512K Flash, 128K RAM */ +/* program starts at 0x08010000 */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08004000, LENGTH = 512K - 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +INCLUDE libopencm3_stm32f2.ld diff --git a/hardware-wallet/firmware/memory_app_1.0.0.ld b/hardware-wallet/firmware/memory_app_1.0.0.ld new file mode 100644 index 00000000..291bfd31 --- /dev/null +++ b/hardware-wallet/firmware/memory_app_1.0.0.ld @@ -0,0 +1,22 @@ +/* STM32F205RE - 512K Flash, 128K RAM */ +/* program starts at 0x08010000 */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08010000, LENGTH = 512K - 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +SECTIONS +{ + .confidential (NOLOAD) : { + *(confidential) + ASSERT ((SIZEOF(.confidential) <= 33K), "Error: Confidential section too big!"); + } >ram +} + +INCLUDE libopencm3_stm32f2.ld + +_ram_start = ORIGIN(ram); +_ram_end = ORIGIN(ram) + LENGTH(ram); + +_data_size = SIZEOF(.data); diff --git a/hardware-wallet/firmware/memory_app_fastflash.ld b/hardware-wallet/firmware/memory_app_fastflash.ld new file mode 100644 index 00000000..fc17e75f --- /dev/null +++ b/hardware-wallet/firmware/memory_app_fastflash.ld @@ -0,0 +1,22 @@ +/* STM32F205RE - 512K Flash, 128K RAM */ +MEMORY +{ + rom (rx) : ORIGIN = 0x20000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000 + LENGTH(rom), + LENGTH = 128K - LENGTH(rom) +} + +SECTIONS +{ + .confidential (NOLOAD) : { + *(confidential) + ASSERT ((SIZEOF(.confidential) <= 33K), "Error: Confidential section too big!"); + } >ram +} + +INCLUDE libopencm3_stm32f2.ld + +_ram_start = ORIGIN(ram); +_ram_end = ORIGIN(ram) + LENGTH(ram); + +_data_size = SIZEOF(.data); diff --git a/hardware-wallet/firmware/oled.c b/hardware-wallet/firmware/oled.c new file mode 100644 index 00000000..54a15b64 --- /dev/null +++ b/hardware-wallet/firmware/oled.c @@ -0,0 +1,422 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#include + +#include "oled.h" +#include "util.h" + +#define OLED_SETCONTRAST 0x81 +#define OLED_DISPLAYALLON_RESUME 0xA4 +#define OLED_DISPLAYALLON 0xA5 +#define OLED_NORMALDISPLAY 0xA6 +#define OLED_INVERTDISPLAY 0xA7 +#define OLED_DISPLAYOFF 0xAE +#define OLED_DISPLAYON 0xAF +#define OLED_SETDISPLAYOFFSET 0xD3 +#define OLED_SETCOMPINS 0xDA +#define OLED_SETVCOMDETECT 0xDB +#define OLED_SETDISPLAYCLOCKDIV 0xD5 +#define OLED_SETPRECHARGE 0xD9 +#define OLED_SETMULTIPLEX 0xA8 +#define OLED_SETLOWCOLUMN 0x00 +#define OLED_SETHIGHCOLUMN 0x10 +#define OLED_SETSTARTLINE 0x40 +#define OLED_MEMORYMODE 0x20 +#define OLED_COMSCANINC 0xC0 +#define OLED_COMSCANDEC 0xC8 +#define OLED_SEGREMAP 0xA0 +#define OLED_CHARGEPUMP 0x8D + +#define SPI_BASE SPI1 +#define OLED_DC_PORT GPIOB +#define OLED_DC_PIN GPIO0 // PB0 | Data/Command +#define OLED_CS_PORT GPIOA +#define OLED_CS_PIN GPIO4 // PA4 | SPI Select +#define OLED_RST_PORT GPIOB +#define OLED_RST_PIN GPIO1 // PB1 | Reset display + +/* TREZOR has a display of size OLED_WIDTH x OLED_HEIGHT (128x64). + * The contents of this display are buffered in _oledbuffer. This is + * an array of OLED_WIDTH * OLED_HEIGHT/8 bytes. At byte y*OLED_WIDTH + x + * it stores the column of pixels from (x,8y) to (x,8y+7); the LSB stores + * the top most pixel. The pixel (0,0) is the top left corner of the + * display. + */ + +static uint8_t _oledbuffer[OLED_BUFSIZE]; +static bool is_debug_link = 0; + +/* + * macros to convert coordinate to bit position + */ +#define OLED_OFFSET(x, y) (OLED_BUFSIZE - 1 - (x) - ((y)/8)*OLED_WIDTH) +#define OLED_MASK(x, y) (1 << (7 - (y) % 8)) + +/* + * Draws a white pixel at x, y + */ +void oledDrawPixel(int x, int y) +{ + if ((x < 0) || (y < 0) || (x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) { + return; + } + _oledbuffer[OLED_OFFSET(x, y)] |= OLED_MASK(x, y); +} + +/* + * Clears pixel at x, y + */ +void oledClearPixel(int x, int y) +{ + if ((x < 0) || (y < 0) || (x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) { + return; + } + _oledbuffer[OLED_OFFSET(x, y)] &= ~OLED_MASK(x, y); +} + +/* + * Inverts pixel at x, y + */ +void oledInvertPixel(int x, int y) +{ + if ((x < 0) || (y < 0) || (x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) { + return; + } + _oledbuffer[OLED_OFFSET(x, y)] ^= OLED_MASK(x, y); +} + +#if !EMULATOR +/* + * Send a block of data via the SPI bus. + */ +static inline void SPISend(uint32_t base, const uint8_t *data, int len) +{ + delay(1); + for (int i = 0; i < len; i++) { + spi_send(base, data[i]); + } + while (!(SPI_SR(base) & SPI_SR_TXE)); + while ((SPI_SR(base) & SPI_SR_BSY)); +} + +/* + * Initialize the display. + */ +void oledInit() +{ + static const uint8_t s[25] = { + OLED_DISPLAYOFF, + OLED_SETDISPLAYCLOCKDIV, + 0x80, + OLED_SETMULTIPLEX, + 0x3F, // 128x64 + OLED_SETDISPLAYOFFSET, + 0x00, + OLED_SETSTARTLINE | 0x00, + OLED_CHARGEPUMP, + 0x14, + OLED_MEMORYMODE, + 0x00, + OLED_SEGREMAP | 0x01, + OLED_COMSCANDEC, + OLED_SETCOMPINS, + 0x12, // 128x64 + OLED_SETCONTRAST, + 0xCF, + OLED_SETPRECHARGE, + 0xF1, + OLED_SETVCOMDETECT, + 0x40, + OLED_DISPLAYALLON_RESUME, + OLED_NORMALDISPLAY, + OLED_DISPLAYON + }; + + gpio_clear(OLED_DC_PORT, OLED_DC_PIN); // set to CMD + gpio_set(OLED_CS_PORT, OLED_CS_PIN); // SPI deselect + + // Reset the LCD + gpio_set(OLED_RST_PORT, OLED_RST_PIN); + delay(40); + gpio_clear(OLED_RST_PORT, OLED_RST_PIN); + delay(400); + gpio_set(OLED_RST_PORT, OLED_RST_PIN); + + // init + gpio_clear(OLED_CS_PORT, OLED_CS_PIN); // SPI select + SPISend(SPI_BASE, s, 25); + gpio_set(OLED_CS_PORT, OLED_CS_PIN); // SPI deselect + + oledClear(); + oledRefresh(); +} +#endif + +/* + * Clears the display buffer (sets all pixels to black) + */ +void oledClear() +{ + memset(_oledbuffer, 0, sizeof(_oledbuffer)); +} + +void oledInvertDebugLink() +{ + if (is_debug_link) { + oledInvertPixel(OLED_WIDTH - 5, 0); oledInvertPixel(OLED_WIDTH - 4, 0); oledInvertPixel(OLED_WIDTH - 3, 0); oledInvertPixel(OLED_WIDTH - 2, 0); oledInvertPixel(OLED_WIDTH - 1, 0); + oledInvertPixel(OLED_WIDTH - 4, 1); oledInvertPixel(OLED_WIDTH - 3, 1); oledInvertPixel(OLED_WIDTH - 2, 1); oledInvertPixel(OLED_WIDTH - 1, 1); + oledInvertPixel(OLED_WIDTH - 3, 2); oledInvertPixel(OLED_WIDTH - 2, 2); oledInvertPixel(OLED_WIDTH - 1, 2); + oledInvertPixel(OLED_WIDTH - 2, 3); oledInvertPixel(OLED_WIDTH - 1, 3); + oledInvertPixel(OLED_WIDTH - 1, 4); + } +} + +/* + * Refresh the display. This copies the buffer to the display to show the + * contents. This must be called after every operation to the buffer to + * make the change visible. All other operations only change the buffer + * not the content of the display. + */ +#if !EMULATOR +void oledRefresh() +{ + static const uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00, OLED_SETHIGHCOLUMN | 0x00, OLED_SETSTARTLINE | 0x00}; + + // draw triangle in upper right corner + oledInvertDebugLink(); + + gpio_clear(OLED_CS_PORT, OLED_CS_PIN); // SPI select + SPISend(SPI_BASE, s, 3); + gpio_set(OLED_CS_PORT, OLED_CS_PIN); // SPI deselect + + gpio_set(OLED_DC_PORT, OLED_DC_PIN); // set to DATA + gpio_clear(OLED_CS_PORT, OLED_CS_PIN); // SPI select + SPISend(SPI_BASE, _oledbuffer, sizeof(_oledbuffer)); + gpio_set(OLED_CS_PORT, OLED_CS_PIN); // SPI deselect + gpio_clear(OLED_DC_PORT, OLED_DC_PIN); // set to CMD + + // return it back + oledInvertDebugLink(); +} +#endif + +const uint8_t *oledGetBuffer() +{ + return _oledbuffer; +} + +void oledSetDebugLink(bool set) +{ + is_debug_link = set; + oledRefresh(); +} + +void oledSetBuffer(uint8_t *buf) +{ + memcpy(_oledbuffer, buf, sizeof(_oledbuffer)); +} + +void oledDrawChar(int x, int y, char c, int font) +{ + if (x >= OLED_WIDTH || y >= OLED_HEIGHT || y <= -FONT_HEIGHT) { + return; + } + + int zoom = (font & FONT_DOUBLE ? 2 : 1); + int char_width = fontCharWidth(font & 0x7f, c); + const uint8_t *char_data = fontCharData(font & 0x7f, c); + + if (x <= -char_width * zoom) { + return; + } + + for (int xo = 0; xo < char_width; xo++) { + for (int yo = 0; yo < FONT_HEIGHT; yo++) { + if (char_data[xo] & (1 << (FONT_HEIGHT - 1 - yo))) { + if (zoom <= 1) { + oledDrawPixel(x + xo, y + yo); + } else { + oledBox(x + xo * zoom, y + yo * zoom, x + (xo + 1) * zoom - 1, y + (yo + 1) * zoom - 1, true); + } + } + } + } +} + +char oledConvertChar(const char c) { + uint8_t a = c; + if (a < 0x80) return c; + // UTF-8 handling: https://en.wikipedia.org/wiki/UTF-8#Description + // bytes 11xxxxxx are first byte of UTF-8 characters + // bytes 10xxxxxx are successive UTF-8 characters + if (a >= 0xC0) return '_'; + return 0; +} + +int oledStringWidth(const char *text, int font) { + if (!text) return 0; + int size = (font & FONT_DOUBLE ? 2 : 1); + int l = 0; + for (; *text; text++) { + char c = oledConvertChar(*text); + if (c) { + l += size * (fontCharWidth(font & 0x7f, c) + 1); + } + } + return l; +} + +void oledDrawString(int x, int y, const char* text, int font) +{ + if (!text) return; + int l = 0; + int size = (font & FONT_DOUBLE ? 2 : 1); + for (; *text; text++) { + char c = oledConvertChar(*text); + if (c) { + oledDrawChar(x + l, y, c, font); + l += size * (fontCharWidth(font & 0x7f, c) + 1); + } + } +} + +void oledDrawStringCenter(int y, const char* text, int font) +{ + int x = ( OLED_WIDTH - oledStringWidth(text, font) ) / 2; + oledDrawString(x, y, text, font); +} + +void oledDrawStringRight(int x, int y, const char* text, int font) +{ + x -= oledStringWidth(text, font); + oledDrawString(x, y, text, font); +} + +void oledDrawBitmap(int x, int y, const BITMAP *bmp) +{ + for (int i = 0; i < bmp->width; i++) { + for (int j = 0; j < bmp->height; j++) { + if (bmp->data[(i / 8) + j * bmp->width / 8] & (1 << (7 - i % 8))) { + oledDrawPixel(x + i, y + j); + } else { + oledClearPixel(x + i, y + j); + } + } + } +} + +/* + * Inverts box between (x1,y1) and (x2,y2) inclusive. + */ +void oledInvert(int x1, int y1, int x2, int y2) +{ + x1 = MAX(x1, 0); + y1 = MAX(y1, 0); + x2 = MIN(x2, OLED_WIDTH - 1); + y2 = MIN(y2, OLED_HEIGHT - 1); + for (int x = x1; x <= x2; x++) { + for (int y = y1; y <= y2; y++) { + oledInvertPixel(x,y); + } + } +} + +/* + * Draw a filled rectangle. + */ +void oledBox(int x1, int y1, int x2, int y2, bool set) +{ + x1 = MAX(x1, 0); + y1 = MAX(y1, 0); + x2 = MIN(x2, OLED_WIDTH - 1); + y2 = MIN(y2, OLED_HEIGHT - 1); + for (int x = x1; x <= x2; x++) { + for (int y = y1; y <= y2; y++) { + set ? oledDrawPixel(x, y) : oledClearPixel(x, y); + } + } +} + +void oledHLine(int y) { + if (y < 0 || y >= OLED_HEIGHT) { + return; + } + for (int x = 0; x < OLED_WIDTH; x++) { + oledDrawPixel(x, y); + } +} + +/* + * Draw a rectangle frame. + */ +void oledFrame(int x1, int y1, int x2, int y2) +{ + for (int x = x1; x <= x2; x++) { + oledDrawPixel(x, y1); + oledDrawPixel(x, y2); + } + for (int y = y1 + 1; y < y2; y++) { + oledDrawPixel(x1, y); + oledDrawPixel(x2, y); + } +} + +/* + * Animates the display, swiping the current contents out to the left. + * This clears the display. + */ +void oledSwipeLeft(void) +{ + for (int i = 0; i < OLED_WIDTH; i++) { + for (int j = 0; j < OLED_HEIGHT / 8; j++) { + for (int k = OLED_WIDTH-1; k > 0; k--) { + _oledbuffer[j * OLED_WIDTH + k] = _oledbuffer[j * OLED_WIDTH + k - 1]; + } + _oledbuffer[j * OLED_WIDTH] = 0; + } + oledRefresh(); + } +} + +/* + * Animates the display, swiping the current contents out to the right. + * This clears the display. + */ +void oledSwipeRight(void) +{ + for (int i = 0; i < OLED_WIDTH / 4; i++) { + for (int j = 0; j < OLED_HEIGHT / 8; j++) { + for (int k = 0; k < OLED_WIDTH / 4 - 1; k++) { + _oledbuffer[k * 4 + 0 + j * OLED_WIDTH] = _oledbuffer[k * 4 + 4 + j * OLED_WIDTH]; + _oledbuffer[k * 4 + 1 + j * OLED_WIDTH] = _oledbuffer[k * 4 + 5 + j * OLED_WIDTH]; + _oledbuffer[k * 4 + 2 + j * OLED_WIDTH] = _oledbuffer[k * 4 + 6 + j * OLED_WIDTH]; + _oledbuffer[k * 4 + 3 + j * OLED_WIDTH] = _oledbuffer[k * 4 + 7 + j * OLED_WIDTH]; + } + _oledbuffer[j * OLED_WIDTH + OLED_WIDTH - 1] = 0; + _oledbuffer[j * OLED_WIDTH + OLED_WIDTH - 2] = 0; + _oledbuffer[j * OLED_WIDTH + OLED_WIDTH - 3] = 0; + _oledbuffer[j * OLED_WIDTH + OLED_WIDTH - 4] = 0; + } + oledRefresh(); + } +} diff --git a/hardware-wallet/firmware/oled.h b/hardware-wallet/firmware/oled.h new file mode 100644 index 00000000..fcd7cc7d --- /dev/null +++ b/hardware-wallet/firmware/oled.h @@ -0,0 +1,59 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __OLED_H__ +#define __OLED_H__ + +#include +#include + +#include "bitmaps.h" +#include "fonts.h" + +#define OLED_WIDTH 128 +#define OLED_HEIGHT 64 +#define OLED_BUFSIZE (OLED_WIDTH * OLED_HEIGHT / 8) + +void oledInit(void); +void oledClear(void); +void oledRefresh(void); + +void oledSetDebugLink(bool set); +void oledInvertDebugLink(void); + +void oledSetBuffer(uint8_t *buf); +const uint8_t *oledGetBuffer(void); +void oledDrawPixel(int x, int y); +void oledClearPixel(int x, int y); +void oledInvertPixel(int x, int y); +void oledDrawChar(int x, int y, char c, int zoom); +int oledStringWidth(const char *text, int font); + +void oledDrawString(int x, int y, const char* text, int font); +void oledDrawStringCenter(int y, const char* text, int font); +void oledDrawStringRight(int x, int y, const char* text, int font); +void oledDrawBitmap(int x, int y, const BITMAP *bmp); +void oledInvert(int x1, int y1, int x2, int y2); +void oledBox(int x1, int y1, int x2, int y2, bool set); +void oledHLine(int y); +void oledFrame(int x1, int y1, int x2, int y2); +void oledSwipeLeft(void); +void oledSwipeRight(void); + +#endif diff --git a/hardware-wallet/firmware/rng.c b/hardware-wallet/firmware/rng.c new file mode 100644 index 00000000..6576d8bb --- /dev/null +++ b/hardware-wallet/firmware/rng.c @@ -0,0 +1,38 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +#include "rng.h" + +#if !EMULATOR +uint32_t random32(void) +{ + static uint32_t last = 0, new = 0; + while (new == last) { + if ((RNG_SR & (RNG_SR_SECS | RNG_SR_CECS | RNG_SR_DRDY)) == RNG_SR_DRDY) { + new = RNG_DR; + } + } + last = new; + return new; +} +#endif diff --git a/hardware-wallet/firmware/rng.h b/hardware-wallet/firmware/rng.h new file mode 100644 index 00000000..c28ef22f --- /dev/null +++ b/hardware-wallet/firmware/rng.h @@ -0,0 +1,25 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __RNG_H__ +#define __RNG_H__ + +#include "rand.h" + +#endif diff --git a/hardware-wallet/firmware/script/bootstrap b/hardware-wallet/firmware/script/bootstrap new file mode 100755 index 00000000..4f687bf0 --- /dev/null +++ b/hardware-wallet/firmware/script/bootstrap @@ -0,0 +1,10 @@ +#!/bin/bash + +# script/bootstrap: Resolve all dependencies that the application requires to +# run. + +set -e + +cd "$(dirname "$0")/.." + +git submodule update --init diff --git a/hardware-wallet/firmware/script/cibuild b/hardware-wallet/firmware/script/cibuild new file mode 100755 index 00000000..02396966 --- /dev/null +++ b/hardware-wallet/firmware/script/cibuild @@ -0,0 +1,25 @@ +#!/bin/bash + +# script/cibuild: Setup environment for CI to run tests. This is primarily +# designed to run on the continuous integration server. + +set -e + +cd "$(dirname "$0")/.." + +if [ "$EMULATOR" = 1 ]; then + make -C emulator +else + make -C vendor/libopencm3 lib/stm32/f2 +fi + +make + +if [ "$FASTFLASH" = 1 ]; then + make -C fastflash +fi + +make -C vendor/nanopb/generator/proto +make -C firmware/protob + +make -C firmware diff --git a/hardware-wallet/firmware/script/setup b/hardware-wallet/firmware/script/setup new file mode 100755 index 00000000..704168ec --- /dev/null +++ b/hardware-wallet/firmware/script/setup @@ -0,0 +1,13 @@ +#!/bin/bash + +# script/setup: Set up application for the first time after cloning, or set it +# back to the initial first unused state. + +set -e + +cd "$(dirname "$0")/.." + +script/bootstrap + +git clean -fdX +git submodule foreach git clean -fdX diff --git a/hardware-wallet/firmware/script/test b/hardware-wallet/firmware/script/test new file mode 100755 index 00000000..69e098d9 --- /dev/null +++ b/hardware-wallet/firmware/script/test @@ -0,0 +1,15 @@ +#!/bin/bash + +# script/test: Run test suite for application. + +set -e + +cd "$(dirname "$0")/.." + +if [ "$EMULATOR" = 1 ]; then + trap "kill %1" EXIT + + firmware/trezor.elf & +fi + +TREZOR_TRANSPORT_V1=1 "${PYTHON:-python}" -m pytest --pyarg trezorlib.tests.device_tests "$@" diff --git a/hardware-wallet/firmware/serialno.c b/hardware-wallet/firmware/serialno.c new file mode 100644 index 00000000..c621f954 --- /dev/null +++ b/hardware-wallet/firmware/serialno.c @@ -0,0 +1,36 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#include + +#include "serialno.h" +#include "util.h" +#include "sha2.h" + +void fill_serialno_fixed(char *s) +{ + uint32_t uuid[8]; + desig_get_unique_id(uuid); + sha256_Raw((const uint8_t *)uuid, 12, (uint8_t *)uuid); + sha256_Raw((const uint8_t *)uuid, 32, (uint8_t *)uuid); + data2hex(uuid, 12, s); +} diff --git a/hardware-wallet/firmware/serialno.h b/hardware-wallet/firmware/serialno.h new file mode 100644 index 00000000..4e157f9c --- /dev/null +++ b/hardware-wallet/firmware/serialno.h @@ -0,0 +1,26 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __SERIALNO_H__ +#define __SERIALNO_H__ + +// buffer has to be (at least) 25 chars long +void fill_serialno_fixed(char *s); + +#endif diff --git a/hardware-wallet/firmware/setup.c b/hardware-wallet/firmware/setup.c new file mode 100644 index 00000000..0cd7f43d --- /dev/null +++ b/hardware-wallet/firmware/setup.c @@ -0,0 +1,199 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rng.h" +#include "layout.h" +#include "util.h" + +uint32_t __stack_chk_guard; + +static inline void __attribute__((noreturn)) fault_handler(const char *line1) { + layoutDialog(&bmp_icon_error, NULL, NULL, NULL, line1, "detected.", NULL, "Please unplug", "the device.", NULL); + for (;;) {} // loop forever +} + +void __attribute__((noreturn)) __stack_chk_fail(void) { + fault_handler("Stack smashing"); +} + +void nmi_handler(void) +{ + // Clock Security System triggered NMI + if ((RCC_CIR & RCC_CIR_CSSF) != 0) { + fault_handler("Clock instability"); + } +} + +void hard_fault_handler(void) { + fault_handler("Hard fault"); +} + +void mem_manage_handler(void) { + fault_handler("Memory fault"); +} + +void setup(void) +{ + // set SCB_CCR STKALIGN bit to make sure 8-byte stack alignment on exception entry is in effect. + // This is not strictly necessary for the current TREZOR system. + // This is here to comply with guidance from section 3.3.3 "Binary compatibility with other Cortex processors" + // of the ARM Cortex-M3 Processor Technical Reference Manual. + // According to section 4.4.2 and 4.4.7 of the "STM32F10xxx/20xxx/21xxx/L1xxxx Cortex-M3 programming manual", + // STM32F2 series MCUs are r2p0 and always have this bit set on reset already. + SCB_CCR |= SCB_CCR_STKALIGN; + + // setup clock + struct rcc_clock_scale clock = rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_120MHZ]; + rcc_clock_setup_hse_3v3(&clock); + + // enable GPIO clock - A (oled), B(oled), C (buttons) + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_GPIOB); + rcc_periph_clock_enable(RCC_GPIOC); + + // enable SPI clock + rcc_periph_clock_enable(RCC_SPI1); + + // enable RNG + rcc_periph_clock_enable(RCC_RNG); + RNG_CR |= RNG_CR_RNGEN; + // to be extra careful and heed the STM32F205xx Reference manual, Section 20.3.1 + // we don't use the first random number generated after setting the RNGEN bit in setup + random32(); + + // enable CSS (Clock Security System) + RCC_CR |= RCC_CR_CSSON; + + // set GPIO for buttons + gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO2 | GPIO5); + + // set GPIO for OLED display + gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO4); + gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO0 | GPIO1); + + // enable SPI 1 for OLED display + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO5 | GPIO7); + gpio_set_af(GPIOA, GPIO_AF5, GPIO5 | GPIO7); + +// spi_disable_crc(SPI1); + spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); + spi_enable_ss_output(SPI1); +// spi_enable_software_slave_management(SPI1); +// spi_set_nss_high(SPI1); +// spi_clear_mode_fault(SPI1); + spi_enable(SPI1); + + // enable OTG_FS + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO10); + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO11 | GPIO12); + gpio_set_af(GPIOA, GPIO_AF10, GPIO10 | GPIO11 | GPIO12); + + // enable OTG FS clock + rcc_periph_clock_enable(RCC_OTGFS); + // clear USB OTG_FS peripheral dedicated RAM + memset_reg((void *) 0x50020000, (void *) 0x50020500, 0); +} + +void setupApp(void) +{ + // for completeness, disable RNG peripheral interrupts for old bootloaders that had + // enabled them in RNG control register (the RNG interrupt was never enabled in the NVIC) + RNG_CR &= ~RNG_CR_IE; + // the static variables in random32 are separate between the bootloader and firmware. + // therefore, they need to be initialized here so that we can be sure to avoid dupes. + // this is to try to comply with STM32F205xx Reference manual - Section 20.3.1: + // "Each subsequent generated random number has to be compared with the previously generated + // number. The test fails if any two compared numbers are equal (continuous random number generator test)." + random32(); + + // enable CSS (Clock Security System) + RCC_CR |= RCC_CR_CSSON; + + // hotfix for old bootloader + gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO9); + spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); + + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO10); + gpio_set_af(GPIOA, GPIO_AF10, GPIO10); +} + +#define MPU_RASR_SIZE_32KB (0x0EUL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_64KB (0x0FUL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_128KB (0x10UL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_256KB (0x11UL << MPU_RASR_SIZE_LSB) +#define MPU_RASR_SIZE_512MB (0x1CUL << MPU_RASR_SIZE_LSB) + +// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html +#define MPU_RASR_ATTR_FLASH (MPU_RASR_ATTR_C) +#define MPU_RASR_ATTR_SRAM (MPU_RASR_ATTR_C | MPU_RASR_ATTR_S) +#define MPU_RASR_ATTR_PERIPH (MPU_RASR_ATTR_B | MPU_RASR_ATTR_S) + +#define FLASH_BASE (0x08000000U) +#define SRAM_BASE (0x20000000U) + +// Never use in bootloader! Disables access to PPB (including MPU, NVIC, SCB) +void mpu_config(void) +{ + // Disable MPU + MPU_CTRL = 0; + + // Bootloader (0x08000000 - 0x08007FFF, 32 KiB, read-only, execute never) + MPU_RBAR = FLASH_BASE | MPU_RBAR_VALID | (0 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_32KB | MPU_RASR_ATTR_AP_PRO_URO | MPU_RASR_ATTR_XN; + + // Metadata (0x08008000 - 0x0800FFFF, 32 KiB, read-write, execute never) + MPU_RBAR = FLASH_BASE | 0x8000 | MPU_RBAR_VALID | (1 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_32KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN; + + // Firmware (0x08010000 - 0x0807FFFF, 64 + 3 * 128 KiB = 64 + 128 + 256 KiB = 448 KiB, read-only) + MPU_RBAR = FLASH_BASE | 0x10000 | MPU_RBAR_VALID | (2 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_64KB | MPU_RASR_ATTR_AP_PRO_URO; + MPU_RBAR = FLASH_BASE | 0x20000 | MPU_RBAR_VALID | (3 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRO_URO; + MPU_RBAR = FLASH_BASE | 0x40000 | MPU_RBAR_VALID | (4 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_256KB | MPU_RASR_ATTR_AP_PRO_URO; + + // SRAM (0x20000000 - 0x2001FFFF, read-write, execute never) + MPU_RBAR = SRAM_BASE | MPU_RBAR_VALID | (5 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_SRAM | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN; + + // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) + MPU_RBAR = PERIPH_BASE | MPU_RBAR_VALID | (6 << MPU_RBAR_REGION_LSB); + MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_PERIPH | MPU_RASR_SIZE_512MB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN; + + // Enable MPU + MPU_CTRL = MPU_CTRL_ENABLE; + + // Enable memory fault handler + SCB_SHCSR |= SCB_SHCSR_MEMFAULTENA; + + __asm__ volatile("dsb"); + __asm__ volatile("isb"); + + // Switch to unprivileged software execution to prevent access to MPU + set_mode_unprivileged(); +} diff --git a/hardware-wallet/firmware/setup.h b/hardware-wallet/firmware/setup.h new file mode 100644 index 00000000..34b88aae --- /dev/null +++ b/hardware-wallet/firmware/setup.h @@ -0,0 +1,32 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __SETUP_H__ +#define __SETUP_H__ + +#include + +extern uint32_t __stack_chk_guard; + +void setup(void); +void setupApp(void); + +void mpu_config(void); + +#endif diff --git a/hardware-wallet/firmware/startup.s b/hardware-wallet/firmware/startup.s new file mode 100644 index 00000000..f2f29c07 --- /dev/null +++ b/hardware-wallet/firmware/startup.s @@ -0,0 +1,63 @@ + .syntax unified + + .text + + .global memset_reg + .type memset_reg, STT_FUNC +memset_reg: + // call with the following (note that the arguments are not validated prior to use): + // r0 - address of first word to write (inclusive) + // r1 - address of first word following the address in r0 to NOT write (exclusive) + // r2 - word value to be written + // both addresses in r0 and r1 needs to be divisible by 4! + .L_loop_begin: + str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed + cmp r0, r1 + bne .L_loop_begin + bx lr + + .global reset_handler + .type reset_handler, STT_FUNC +reset_handler: + ldr r0, =_ram_start // r0 - point to beginning of SRAM + ldr r1, =_ram_end // r1 - point to byte after the end of SRAM + ldr r2, =0 // r2 - the byte-sized value to be written + bl memset_reg + + // copy .data section from flash to SRAM + ldr r0, =_data // dst addr + ldr r1, =_data_loadaddr // src addr + ldr r2, =_data_size // length in bytes + bl memcpy + + // enter the application code + bl main + + // loop forever if the application code returns + b . + + .global shutdown + .type shutdown, STT_FUNC +shutdown: + cpsid f + ldr r0, =0 + mov r1, r0 + mov r2, r0 + mov r3, r0 + mov r4, r0 + mov r5, r0 + mov r6, r0 + mov r7, r0 + mov r8, r0 + mov r9, r0 + mov r10, r0 + mov r11, r0 + mov r12, r0 + ldr lr, =0xffffffff + ldr r0, =_ram_start + ldr r1, =_ram_end + // set to value in r2 + bl memset_reg + b . // loop forever + + .end diff --git a/hardware-wallet/firmware/timer.c b/hardware-wallet/firmware/timer.c new file mode 100644 index 00000000..d58855fe --- /dev/null +++ b/hardware-wallet/firmware/timer.c @@ -0,0 +1,62 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2016 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + + +#include "timer.h" + +#include +#include +#include + +/* 1 tick = 1 ms */ +volatile uint32_t system_millis; + +/* + * Initialise the Cortex-M3 SysTick timer + */ +void timer_init(void) { + system_millis = 0; + + /* + * MCU clock (120 MHz) as source + * + * (120 MHz / 8) = 15 clock pulses + * + */ + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); + STK_CVR = 0; + + /* + * 1 tick = 1 ms @ 120 MHz + * + * (15 clock pulses * 1000 ms) = 15000 clock pulses + * + * Send an interrupt every (N - 1) clock pulses + */ + systick_set_reload(14999); + + /* SysTick as interrupt */ + systick_interrupt_enable(); + + systick_counter_enable(); +} + +void sys_tick_handler(void) { + system_millis++; +} diff --git a/hardware-wallet/firmware/timer.h b/hardware-wallet/firmware/timer.h new file mode 100644 index 00000000..ac76d07e --- /dev/null +++ b/hardware-wallet/firmware/timer.h @@ -0,0 +1,38 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2016 Saleem Rashid + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include + +void timer_init(void); + +#if EMULATOR +uint32_t timer_ms(void); +#else +static inline uint32_t timer_ms(void) { + /* 1 tick = 1 ms */ + extern volatile uint32_t system_millis; + + return system_millis; +} +#endif + +#endif diff --git a/hardware-wallet/firmware/usb21_standard.c b/hardware-wallet/firmware/usb21_standard.c new file mode 100644 index 00000000..7ed1986c --- /dev/null +++ b/hardware-wallet/firmware/usb21_standard.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, Devan Lai + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include "util.h" +#include "usb21_standard.h" + +static uint16_t build_bos_descriptor(const struct usb_bos_descriptor *bos, + uint8_t *buf, uint16_t len) +{ + uint8_t *tmpbuf = buf; + uint16_t count, total = 0, totallen = 0; + uint16_t i; + + memcpy(buf, bos, count = MIN(len, bos->bLength)); + buf += count; + len -= count; + total += count; + totallen += bos->bLength; + + /* For each device capability */ + for (i = 0; i < bos->bNumDeviceCaps; i++) { + /* Copy device capability descriptor. */ + const struct usb_device_capability_descriptor *cap = + bos->capabilities[i]; + + memcpy(buf, cap, count = MIN(len, cap->bLength)); + buf += count; + len -= count; + total += count; + totallen += cap->bLength; + } + + /* Fill in wTotalLength. */ + *(uint16_t *)(tmpbuf + 2) = totallen; + + return total; +} + +static const struct usb_bos_descriptor* usb21_bos; + +static int usb21_standard_get_descriptor(usbd_device* usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len, + usbd_control_complete_callback* complete) { + (void)complete; + (void)usbd_dev; + + if (req->bRequest == USB_REQ_GET_DESCRIPTOR) { + int descr_type = req->wValue >> 8; + if (descr_type == USB_DT_BOS) { + if (!usb21_bos) { + return USBD_REQ_NOTSUPP; + } + *len = MIN(*len, build_bos_descriptor(usb21_bos, *buf, *len)); + return USBD_REQ_HANDLED; + } + } + + return USBD_REQ_NEXT_CALLBACK; +} + +static void usb21_set_config(usbd_device* usbd_dev, uint16_t wValue) { + (void)wValue; + + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE, + USB_REQ_TYPE_DIRECTION | USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + &usb21_standard_get_descriptor); +} + +void usb21_setup(usbd_device* usbd_dev, const struct usb_bos_descriptor* binary_object_store) { + usb21_bos = binary_object_store; + + /* Register the control request handler _before_ the config is set */ + usb21_set_config(usbd_dev, 0x0000); + usbd_register_set_config_callback(usbd_dev, usb21_set_config); +} diff --git a/hardware-wallet/firmware/usb21_standard.h b/hardware-wallet/firmware/usb21_standard.h new file mode 100644 index 00000000..e7578a53 --- /dev/null +++ b/hardware-wallet/firmware/usb21_standard.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, Devan Lai + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef USB21_STANDARD_H_INCLUDED +#define USB21_STANDARD_H_INCLUDED + +#include + +/* USB 3.1 Descriptor Types - Table 9-6 */ +#define USB_DT_BOS 15 +#define USB_DT_DEVICE_CAPABILITY 16 +#define USB_DT_SUPERSPEED_USB_ENDPOINT_COMPANION 48 +#define USB_DT_SUPERSPEEDPLUS_ISOCHRONOUS_ENDPOINT_COMPANION 49 + +struct usb_device_capability_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; +} __attribute__((packed)); + +struct usb_bos_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; + /* Descriptor ends here. The following are used internally: */ + const struct usb_device_capability_descriptor **capabilities; +} __attribute__((packed)); + +#define USB_DT_BOS_SIZE 5 + +/* USB Device Capability Types - USB 3.1 Table 9-14 */ +#define USB_DC_WIRELESS_USB 1 +#define USB_DC_USB_2_0_EXTENSION 2 +#define USB_DC_SUPERSPEED_USB 3 +#define USB_DC_CONTAINER_ID 4 +#define USB_DC_PLATFORM 5 +#define USB_DC_POWER_DELIVERY_CAPABILITY 6 +#define USB_DC_BATTERY_INFO_CAPABILITY 7 +#define USB_DC_PD_CONSUMER_PORT_CAPABILITY 8 +#define USB_DC_PD_PROVIDER_PORT_CAPABILITY 9 +#define USB_DC_SUPERSPEED_PLUS 10 +#define USB_DC_PRECISION_TIME_MEASUREMENT 11 +#define USB_DC_WIRELESS_USB_EXT 12 + +extern void usb21_setup(usbd_device* usbd_dev, const struct usb_bos_descriptor* binary_object_store); + +#endif diff --git a/hardware-wallet/firmware/util.c b/hardware-wallet/firmware/util.c new file mode 100644 index 00000000..768410c3 --- /dev/null +++ b/hardware-wallet/firmware/util.c @@ -0,0 +1,68 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "util.h" + +inline void delay(uint32_t wait) +{ + while (--wait > 0) __asm__("nop"); +} + +static const char *hexdigits = "0123456789ABCDEF"; + +void uint32hex(uint32_t num, char *str) +{ + for (uint32_t i = 0; i < 8; i++) { + str[i] = hexdigits[(num >> (28 - i * 4)) & 0xF]; + } +} + +// converts data to hexa +void data2hex(const void *data, uint32_t len, char *str) +{ + const uint8_t *cdata = (uint8_t *)data; + for (uint32_t i = 0; i < len; i++) { + str[i * 2 ] = hexdigits[(cdata[i] >> 4) & 0xF]; + str[i * 2 + 1] = hexdigits[cdata[i] & 0xF]; + } + str[len * 2] = 0; +} + +uint32_t readprotobufint(uint8_t **ptr) +{ + uint32_t result = (**ptr & 0x7F); + if (**ptr & 0x80) { + (*ptr)++; + result += (**ptr & 0x7F) * 128; + if (**ptr & 0x80) { + (*ptr)++; + result += (**ptr & 0x7F) * 128 * 128; + if (**ptr & 0x80) { + (*ptr)++; + result += (**ptr & 0x7F) * 128 * 128 * 128; + if (**ptr & 0x80) { + (*ptr)++; + result += (**ptr & 0x7F) * 128 * 128 * 128 * 128; + } + } + } + } + (*ptr)++; + return result; +} diff --git a/hardware-wallet/firmware/util.h b/hardware-wallet/firmware/util.h new file mode 100644 index 00000000..7fa54f17 --- /dev/null +++ b/hardware-wallet/firmware/util.h @@ -0,0 +1,75 @@ +/* + * This file is part of the TREZOR project, https://trezor.io/ + * + * Copyright (C) 2014 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __UTIL_H_ +#define __UTIL_H_ + +#include + +#if !EMULATOR +#include +#include +#endif + +// Statement expressions make these macros side-effect safe +#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; }) +#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; }) + +void delay(uint32_t wait); + +// converts uint32 to hexa (8 digits) +void uint32hex(uint32_t num, char *str); + +// converts data to hexa +void data2hex(const void *data, uint32_t len, char *str); + +// read protobuf integer and advance pointer +uint32_t readprotobufint(uint8_t **ptr); + +#if !EMULATOR +// defined in memory.ld +extern uint8_t _ram_start[], _ram_end[]; + +// defined in startup.s +extern void memset_reg(void *start, void *stop, uint32_t val); +extern void __attribute__((noreturn)) shutdown(void); + +static inline void __attribute__((noreturn)) load_vector_table(const vector_table_t *vector_table) +{ + // Relocate vector table + SCB_VTOR = (uint32_t)vector_table; + + // Set stack pointer + __asm__ volatile("msr msp, %0" :: "r" (vector_table->initial_sp_value)); + + // Jump to address + vector_table->reset(); + + // Prevent compiler from generating stack protector code (which causes CPU fault because the stack is moved) + for (;;); +} + +static inline void set_mode_unprivileged(void) +{ + // http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html + __asm__ volatile("msr control, %0" :: "r" (0x1)); +} +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/.gitignore b/hardware-wallet/firmware/vendor/libopencm3/.gitignore new file mode 100644 index 00000000..da0940de --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/.gitignore @@ -0,0 +1,44 @@ +*.d +*.o +*.bin +*.hex +*.list +*.srec +*.a +*.elf +lib/*.ld +*.stylecheck +*.swp +\#* +.\#* +*~ +*.map +*.log +*.pyc +html/ +latex/ +*.pdf +*.tag +.DS_Store +# These are generated +include/libopencm3/**/nvic.h +include/libopencm3/**/**/nvic.h +lib/**/vector_nvic.c +lib/**/**/vector_nvic.c +include/libopencmsis/efm32/ +include/libopencmsis/lm3s/ +include/libopencmsis/lpc13xx/ +include/libopencmsis/lpc17xx/ +include/libopencmsis/lpc43xx/ +include/libopencmsis/sam/ +include/libopencmsis/stm32/ +include/libopencmsis/vf6xx/ + +# Editor/IDE config files +nbproject/ +.idea/ +.project +locm3.sublime-workspace + +# cscope databases +cscope.out diff --git a/hardware-wallet/firmware/vendor/libopencm3/COPYING.GPL3 b/hardware-wallet/firmware/vendor/libopencm3/COPYING.GPL3 new file mode 100644 index 00000000..44325404 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/COPYING.GPL3 @@ -0,0 +1,676 @@ + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff --git a/hardware-wallet/firmware/vendor/libopencm3/COPYING.LGPL3 b/hardware-wallet/firmware/vendor/libopencm3/COPYING.LGPL3 new file mode 100644 index 00000000..65c5ca88 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/COPYING.LGPL3 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/hardware-wallet/firmware/vendor/libopencm3/HACKING b/hardware-wallet/firmware/vendor/libopencm3/HACKING new file mode 100644 index 00000000..af89ec4c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/HACKING @@ -0,0 +1,85 @@ +------------------------------------------------------------------------------ +HACKING +------------------------------------------------------------------------------ + +Coding style +------------ + +The whole library is programmed using the Linux kernel coding style, see +http://lxr.linux.no/linux/Documentation/CodingStyle for details. + +Please use the same style for any code contributions, thanks! + +Amendments to the Linux kernel coding style +------------------------------------------- + +1) We use the stdint types. The linux kernel accepts the abbreviated types (u8, + s8, u16 and so on) for legacy reasons. We should in general not introduce + things like types ourselves as long as they are not necessary to make our + job possible of refining the hardware and make it easier to be used. stdint + is a standard and it is not in the scope of our project to introduce a new + type standard. + +2) Based on the same logic as in (1) we do not use __packed and __aligned + definitions, it is not our job to add compiler extensions. If we need to + deal with compiler incompatibility we will do that the same way we are + dealing with the deprecated attribute by introducing a normal macro that is + not in the compiler reserved keyword space. + +3) We accept to write an empty body busy waiting while loop like this: + while (1); + there is no need to put the colon on the next line as per linux kernel + style. + +4) We always add brackets around bodies of if, while and for statements, even + if the body contains only one expression. It is dangerous to not have them + as it easily happens that one adds a second expression and is hunting for + hours why the code is not working just because of a missing bracket pair. + +Development guidelines +---------------------- + + - Every new file added must have the usual license header, see the + existing files for examples. + + - In general, please try to keep the register and bit naming as close + as possible to the official vendor datasheets. Among other reasons, this + makes it easier for users to find what they're looking for in the + datasheets, programming manuals, and application notes. + + - All register definitions should follow the following naming conventions: + + - The #define names should be all-caps, parts are separated by + an underscore. + + - The name should be of the form SUBSYSTEM_REGISTER_BIT, e.g. + ADC_CR2_DMA, where ADC is the subsystem name, CR2 is the register NAME, + and DMA is the name of the bit in the register that is defined. + + - All subsystem-specific function names should be prefixed with the + subsystem name. For example, gpio_set_mode() or rcc_osc_on(). + + - Please consistently use the stdint types. + + - Variables that are used to store register values read from registers or + to be stored in a register should be named reg8, reg16, reg32 etc. + + - For examples on using libopencm3 see the libopencm3-examples repository. + + - Doxygen is used to generate API docs, please follow that style for function + and definition commentary where possible. + +Tips and tricks +--------------- + +SublimeText users: + + - The project contains a sublime project description file with some basic + settings provided to make hacking on libopencm3 easier. + + - Recommended SublimeText plugins when hacking on libopencm3: + + - TrailingSpaces: Show and trim trailing line spaces. + + - SublimeLinter: Run checkpatch.pl in the background while you write your + code and indicate possible coding style issues on the fly. diff --git a/hardware-wallet/firmware/vendor/libopencm3/HACKING_COMMON_DOC b/hardware-wallet/firmware/vendor/libopencm3/HACKING_COMMON_DOC new file mode 100644 index 00000000..b0fa4b3d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/HACKING_COMMON_DOC @@ -0,0 +1,76 @@ +Files for each peripheral (examples given for STM32 GPIO) +--------------------------------------------------------- + +In include/libopencm3/stm32. +A "dispatch" header to point to the subfamily header (gpio.h) + +In include/libopencm3/stm32/f* +A file with defines that are specific to the subfamily, and an include of +needed common header files (gpio.h). + +In include/libopencm3/stm32/common +A file with defines common to all subfamilies. Includes the cm3 common header +(gpio_common_all.h). + +In include/libopencm3/stm32/common +May be one other file with defines common to a subgroup of devices. +This includes the file common to all (gpio_common_f24.h). + +In lib/stm32/f* +A file with functions specific to the subfamily. Includes the "dispatch" header +and any common headers needed (gpio.c). + +In lib/stm32/common +Has functions common to all subfamilies. Includes the "dispatch" header +(gpio_common_all.c). + +In lib/stm32/common +May be one other file with functions common to a group of subfamilies. Includes +the "dispatch" header and the file common to all (gpio_common_f24.h). + +Makefiles in lib/stm32/f? have the common object files added and the +common directory added to VPATH. + +NOTE: The common source files MUST have the "dispatch" header so that +compilation will use the specific defines for the subfamily being compiled. +These can differ between subfamilies. + +NOTE: The common source files must have a line of the form + +#ifdef LIBOPENCM3_xxx_H + +where xxx is the associated peripheral name. This prevents the common files +from being included accidentally into a user's application. This however +causes doxygen to skip processing of the remainder of the file. Thus a + +@cond ... @endcond + +directive must be placed around the statement to prevent doxygen from +processing it. This works only for doxygen 1.8.4 or later. At the present +time most distros have an earlier buggy version. + +Documentation +------------- + +In include/libopencm3/stm32/f* +A file doc-stm32f*.h contains a definition of the particular family grouping. +This grouping will appear in the main index of the resulting document with all +documentation under it. + +All header files for a peripheral (common or otherwise) will subgroup under a +name which is the same in all families (such as gpio_defines). The peripheral +header file in include/libopencm3/stm32/f* will then include this group as a +subgroup under the specific family group. Doxygen is run separately for each +family so there is no danger of accidentally including the wrong stuff. + +Similarly for the source files for a peripheral which will subgroup under a +same name (such as gpio_files). The peripheral source file in lib/stm32/f* +will include this as a subgroup under the specific family group. + +DOXYFILE for a particular family will list the family specific and common files +(headers and source) that are to be included. The result (in the long run) will +be that all peripherals will appear under the same family grouping in the +documentation, even if they are identical over a number of families. That is +probably most useful to end users who only need to see the documentation for +one family. + diff --git a/hardware-wallet/firmware/vendor/libopencm3/Makefile b/hardware-wallet/firmware/vendor/libopencm3/Makefile new file mode 100644 index 00000000..ea51f6d9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/Makefile @@ -0,0 +1,111 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf + +STYLECHECK := scripts/checkpatch.pl +STYLECHECKFLAGS := --no-tree -f --terse --mailback + +space:= +space+= +SRCLIBDIR:= $(subst $(space),\$(space),$(realpath lib)) + +TARGETS := stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/f7 +TARGETS += stm32/l0 stm32/l1 stm32/l4 +TARGETS += lpc13xx lpc17xx lpc43xx/m4 lpc43xx/m0 +TARGETS += lm3s lm4f +TARGETS += efm32/tg efm32/g efm32/lg efm32/gg +TARGETS += sam/3a sam/3n sam/3s sam/3u sam/3x +TARGETS += sam/d +TARGETS += vf6xx + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +# Do not print "Entering directory ...". +MAKEFLAGS += --no-print-directory +endif + +IRQ_DEFN_FILES := $(shell find . -name 'irq.json') +STYLECHECKFILES := $(shell find . -name '*.[ch]') + +all: build + +build: lib + +%.genhdr: + @printf " GENHDR $*\n"; + @./scripts/irq2nvic_h ./$*; + +%.cleanhdr: + @printf " CLNHDR $*\n"; + @./scripts/irq2nvic_h --remove ./$* + +LIB_DIRS:=$(wildcard $(addprefix lib/,$(TARGETS))) +$(LIB_DIRS): $(IRQ_DEFN_FILES:=.genhdr) + @printf " BUILD $@\n"; + $(Q)$(MAKE) --directory=$@ SRCLIBDIR="$(SRCLIBDIR)" + +lib: $(LIB_DIRS) + $(Q)true + +html doc: + $(Q)$(MAKE) -C doc html + +clean: $(IRQ_DEFN_FILES:=.cleanhdr) $(LIB_DIRS:=.clean) $(EXAMPLE_DIRS:=.clean) doc.clean styleclean + +%.clean: + $(Q)if [ -d $* ]; then \ + printf " CLEAN $*\n"; \ + $(MAKE) -C $* clean SRCLIBDIR="$(SRCLIBDIR)" || exit $?; \ + fi; + + +stylecheck: $(STYLECHECKFILES:=.stylecheck) +styleclean: $(STYLECHECKFILES:=.styleclean) + +# the cat is due to multithreaded nature - we like to have consistent chunks of text on the output +%.stylecheck: % + $(Q)if ! grep -q "* It was generated by the irq2nvic_h script." $* ; then \ + $(STYLECHECK) $(STYLECHECKFLAGS) $* > $*.stylecheck; \ + if [ -s $*.stylecheck ]; then \ + cat $*.stylecheck; \ + else \ + rm -f $*.stylecheck; \ + fi; \ + fi; + +%.styleclean: + $(Q)rm -f $*.stylecheck; + + +LDTESTS :=$(wildcard ld/tests/*.data) + +genlinktests: $(LDTESTS:.data=.ldtest) + +%.ldtest: + @if ./scripts/genlinktest.sh $* >/dev/null; then\ + printf " TEST OK : $*\n"; \ + else \ + printf " TEST FAIL : $*\n"; \ + fi; + + +.PHONY: build lib $(LIB_DIRS) doc clean generatedheaders cleanheaders stylecheck genlinktests diff --git a/hardware-wallet/firmware/vendor/libopencm3/README.md b/hardware-wallet/firmware/vendor/libopencm3/README.md new file mode 100644 index 00000000..5b364035 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/README.md @@ -0,0 +1,187 @@ +README +====== + +[![Gitter channel](https://badges.gitter.im/libopencm3/discuss.svg)](https://gitter.im/libopencm3/discuss) + +The libopencm3 project aims to create an open-source firmware library for +various ARM Cortex-M microcontrollers. + +Currently (at least partly) supported microcontrollers: + + - ST STM32F0xx/F1xx/F2xx/F30x/F37x/F4xx/F7xx/L0xx/L1xx/L4xx series + - Atmel SAM3A/3N/3S/3U/3X series, as well as SAMDxx and friends + - NXP LPC1311/13/17/42/43 + - Stellaris LM3S series (discontinued, without replacement) + - TI (Tiva) LM4F series (continuing as TM4F, pin and peripheral compatible) + - EFM32 Gecko series (only core support) + - Freescale Vybrid VF6xx + +The library is written completely from scratch based on the vendor datasheets, +programming manuals, and application notes. The code is meant to be used +with a GCC toolchain for ARM (arm-elf or arm-none-eabi), flashing of the +code to a microcontroller can be done using the OpenOCD ARM JTAG software. + + +Status and API +-------------- + +The libopencm3 project is currently work in progress. Not all subsystems +of the microcontrollers are supported, yet. + +**IMPORTANT**: The API of the library is _NOT_ yet considered stable! Please do + not rely on it, yet! Changes to function names, macro names etc. + can happen at any time without prior notice! + +_TIP_: Include this repository as a GIT submodule in your project. To make sure + your users get the right version of the library to compile your project. + For how that can be done refer to the libopencm3-examples repository. + +Prerequisites +------------- + +Building requires python. (Some code is generated) +If your user application uses the (optional) dynamic linker script generator, +you will (presently) need GNU awk. Please see https://github.com/libopencm3/libopencm3/issues/732 + +**For Ubuntu/Fedora:** + + - An arm-none-eabi/arm-elf toolchain. + +**For Windows:** + + Download and install: + + - msys - http://sourceforge.net/projects/mingw/files/MSYS/Base/msys-core/msys-1.0.11/MSYS-1.0.11.exe + - Python - http://www.python.org/ftp/python/2.7/python-2.7.msi (any 2.7 release) + - arm-none-eabi/arm-elf toolchain (for example this one https://launchpad.net/gcc-arm-embedded) + +Run msys shell and set the path without standard Windows paths, so Windows programs such as 'find' won't interfere: + + export PATH="/c//Python27:/c/ARMToolchain/bin:/usr/local/bin:/usr/bin:/bin" + +After that you can navigate to the folder where you've extracted libopencm3 and build it. + +Toolchain +--------- + +The most heavily tested toolchain is "gcc-arm-embedded" +https://launchpad.net/gcc-arm-embedded + +Other toolchains _should_ work, but have not been nearly as well tested. +Toolchains targeting linux, such as "gcc-arm-linux-gnu" or the like are +_not_ appropriate. + +_NOTE_ We recommend, that you use g-a-c version 2.8 2014q3 or newer +to build all platforms covered by libopencm3 successfully. + +Building +-------- + + $ make + +If your have an arm-elf toolchain (uncommon) you may want to override the +toolchain prefix (arm-none-eabi is the default) + + $ PREFIX=arm-elf make + +For a more verbose build you can use + + $ make V=1 + +Fine-tuning the build +--------------------- + +The build may be fine-tuned with a limited number of parameters, by specifying +them as environment variables, for example: + + $ VARIABLE=value make + +* `FP_FLAGS` - Control the floating-point ABI + + If the Cortex-M core supports a hard float ABI, it will be compiled with + best floating-point support by default. In cases where this is not desired, the + behavior can be specified by setting `FP_FLAGS`. + + Currently, M4F cores default to `-mfloat-abi=hard -mfpu=fpv4-sp-d16`, + M7 cores defaults to double precision `-mfloat-abi=hard -mfpu=fpv5-d16` if available, + and single precision `-mfloat-abi=hard -mfpu=fpv5-sp-d16` otherwise. + Other architectures use no FP flags, in otherwords, traditional softfp. + + You may find which FP_FLAGS you can use in particular architecture in readme.txt + shipped with gcc-arm-embedded package. + + Examples: + + $ FP_FLAGS="-mfloat-abi=soft" make # No hardfloat + $ FP_FLAGS="-mfloat-abi=hard -mfpu=magic" make # New FPU we don't know of + +* `CFLAGS` - Add to or supersede compiler flags + + If the library needs to be compiled with additional flags, they can be + passed to the build system via the environment variable `CFLAGS`. The + contents of `CFLAGS` will be placed after all flags defined by the build + system, giving the user a way to override any default if necessary. + + Examples: + + $ CFLAGS="-fshort-wchar" make # compile lib with 2 byte wide wchar_t + +Example projects +---------------- + +The libopencm3 community has written and is maintaining a huge collection of +examples, displaying the capabilities and uses of the library. You can find all +of them in the libopencm3-examples repository: + +https://github.com/libopencm3/libopencm3-examples + +Installation +------------ + +Simply pass -I and -L flags to your own project. See the libopencm3-examples +repository for an example of using this library as a git submodule, the most +popular method of use. + +It is strongly advised that you do not attempt to install this library to any +path inside your toolchain itself. While this means you don't have to include +any `-I` or `-L` flags in your projects, it is _very_ easy to confuse a multilib +linker from picking the right versions of libraries. Common symptoms are +hardfaults caused by branches into arm code. You can use `arm-none-eabi-objdump` +to check for this in your final elf. You have been warned. + +Coding style and development guidelines +--------------------------------------- + +See HACKING. + + +License +------- + +The libopencm3 code is released under the terms of the GNU Lesser General +Public License (LGPL), version 3 or later. + +See COPYING.GPL3 and COPYING.LGPL3 for details. + +Community +--------- + + * Our [![Gitter channel](https://badges.gitter.im/libopencm3/discuss.svg)](https://gitter.im/libopencm3/discuss) + * Our IRC channel on the freenode IRC network is called #libopencm3 + +Mailing lists +------------- + + * Developer mailing list (for patches and discussions): + https://lists.sourceforge.net/lists/listinfo/libopencm3-devel + + * Commits mailing list (receives one mail per `git push`): + https://lists.sourceforge.net/lists/listinfo/libopencm3-commits + + +Website +------- + + * http://libopencm3.org + * http://sourceforge.net/projects/libopencm3/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile new file mode 100644 index 00000000..f9c0a5a0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile @@ -0,0 +1,21 @@ +# Doxygen include file to generate top level entry document + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ./Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +INPUT = ../include/libopencm3/docmain.dox + +LAYOUT_FILE = DoxygenLayout.xml + +GENERATE_LATEX = NO + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile_common b/hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile_common new file mode 100644 index 00000000..a36a2c10 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/Doxyfile_common @@ -0,0 +1,1809 @@ +# Doxyfile 1.8.2 + +# 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 sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = libopencm3 + +# 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 = "A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers." + +# With the PROJECT_LOGO tag one can specify an logo or 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) +# 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, Esperanto, 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, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +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. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +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 if your file system +# 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 = YES + +# 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 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 = 8 + +# 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 = + +# 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. + +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 + +# 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, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. 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 +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) 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. + +MARKDOWN_SUPPORT = YES + +# 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 by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. + +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); v.s. +# func(std::string) {}). This also makes 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 + +# For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen 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. + +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. + +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 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). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data 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 (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# 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 + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE 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 appear 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. + +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 and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# 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 namespaces 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 = YES + +# 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. + +FORCE_LOCAL_INCLUDES = 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 = YES + +# 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_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 default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to 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 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 + +# 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. + +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. + +GENERATE_TODOLIST = NO + +# 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= NO + +# 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 macro 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 macros 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 = 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 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 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 , 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 = + +# 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. + +LAYOUT_FILE = DoxygenLayout.xml + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://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. + +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 +# 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 + +# The 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 (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 = doxygen.log + +#--------------------------------------------------------------------------- +# 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 = + +# 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++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +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 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. + +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 = */*.d + +# 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 = + +# 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 or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +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 + +# 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 option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# 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 = YES + +# 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, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES +# 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 +# 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 documentation. + +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 = 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. + +ALPHABETICAL_INDEX = YES + +# 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. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +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 = + +# 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. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is 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 therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +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. + +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 http://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. +# The allowed range is 0 to 359. + +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. + +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. + +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 NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = 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. + +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. + +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, 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 http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +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 + +# When GENERATE_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. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# 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_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 CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# 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 = 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. + +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. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +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 +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +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. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, 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. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, 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. + +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. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW 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. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) 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. + +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. + +TREEVIEW_WIDTH = 250 + +# When 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. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# 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. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT 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 before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered 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. + +USE_MATHJAX = NO + +# 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 http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# 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. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# 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. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +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, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# 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 = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# 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 = YES + +# 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 = YES + +# 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 + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# 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 style sheet 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 +# pointed to by INCLUDE_PATH will be searched when 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 = __attribute__(x)= BEGIN_DECLS END_DECLS + +# 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 that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these 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. For each +# tag file the location of the external documentation should be added. 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. 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 also works with HAVE_DOT disabled, but 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 = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# 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 +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# 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 = YES + +# 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 = YES + +# 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 the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# 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 = YES + +# 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 = YES + +# 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 = YES + +# 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 = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH 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 = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# 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 MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The 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 disabled by default, because dot on Windows does not +# seem to support this out of the box. 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 = YES + +# 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 + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/DoxygenLayout.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/DoxygenLayout.xml new file mode 100644 index 00000000..98075380 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/DoxygenLayout.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/HACKING b/hardware-wallet/firmware/vendor/libopencm3/doc/HACKING new file mode 100644 index 00000000..d67684bb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/HACKING @@ -0,0 +1,114 @@ +libopencm3 Documentation +12 October 2012 (C) K Sarkies +----------------------------- + +Each family and subfamily of devices has a separate directory and configuration +files. Doxygen is run independently on each of these and the result is +integrated under a single HTML page. LaTeX and pdf files are produced +separately. Due to relative referencing used in the files, the directory +structure is important and should be maintained. + +Each of the subdirectories has a configuration file, a layout file and +subdirectories for the documentation. Doxygen is intended to be run inside +these subdirectories. The Makefile will handle this in the appropriate +order. + +Markup +------ + +Each family has been given a group name that will allow subgrouping of API +functions and defines in the documentation. + +The header and source files for each peripheral in each family must have a +heading section in which an @defgroup defines the group name for the particular +peripheral. This group name will be the same across all families as each one +is documented separately. Thus for a peripheral xxx the header will have a +group name xxx_defines and the source file will have xxx_file. This will allow +the group to appear separately. An @ingroup must be provided to place the group +as a subgroup of the appropriate family grouping. Note that @file is not used. + +The heading section must include the version number and date and authors names +plus a license reference. Any documentation specific to the family can be +included here. If there are common files included then their documentation will +appear in a separate section. + +Common header and source files that are included into a number of families must +have an @addgroup to include its documentation into the appropriate peripheral +group. These headings may include authors and any specific descriptions but the +date and version number must be omitted as it will be included from the family +files. There must not be any reference to family groupings as these common files +will be incorporated into multiple family groups. + +The common files should not be included in an application explicitly. Also the +doxygen preprocessor must be enabled to ensure that all macros and defines are +included. This means that common header files need to have a section at the top +of the file of the type (eg for gpio_common_f24.h): + +/** @cond */ +#ifdef LIBOPENCM3_GPIO_H +/** @endcond */ + +and at the end of the file: + +/** @cond */ +#else +#warning "gpio_common_f24.h should not be included explicitly, only via gpio.h" +#endif +/** @endcond */ + +This will stop the compiler preprocessor from including the common header file +unless the device family header file has also been included. The doxygen +conditional clauses are needed to stop the doxygen preprocessor seeing this +statement and so excluding processing of the common file contents. + +/** @cond */ +#if defined(LIBOPENCM3_GPIO_H) || defined(LIBOPENCM3_GPIO_COMMON_F24_H) +/** @endcond */ + +Each helper function must have a header with an @brief, and where appropriate +additional description, @parameter and @return elements. These latter must +describe the allowable parameter ranges preferably with reference to a suitable +define in the corresponding header file. + +The Doxyfile for a family must include input files from the header and source +subdirectories, as well as all needed common files. The common files can be +added separately or as an entire directory with exclusions of inappropriate +files. + +Doxyfiles +--------- + +Doxyfile_common holds global settings. + +OUTPUT_DIRECTORY blank so that the output is placed in the current directory. +RECURSIVE = NO +EXTERNAL_GROUPS = NO + +Each Doxyfile_include for a processor family has: + +@INCLUDE = ../Doxyfile_common +INPUT = specific directories needed, including /include/libopencm3/cm3 + in top directory to set the top level page and GNU license. +LAYOUT_FILE = DoxygenLayout_$processor.xml +WARN_LOGFILE = doxygen_$processor.log +TAGFILES = ../cm3/cm3.tag=../../cm3/html +GENERATE_TAGFILE = $processor.tag +PREDEFINED = list of macro definitions + +For the top level Doxyfile + +INPUT = ../include/libopencm3/docmain.dox to add in the main page text +LAYOUT_FILE = DoxygenLayout.xml +WARN_LOGFILE = doxygen.log +TAGFILES = cm3/cm3.tag=../cm3/html plus all families to be included. + +Generation of PDF +----------------- + +The needs for pdf documents differ from HTML so separate Doxyfile_latex +files are provided. + +@INCLUDE = ../Doxyfile_common +GENERATE_LATEX = YES +GENERATE_HTML = NO + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/Makefile b/hardware-wallet/firmware/vendor/libopencm3/doc/Makefile new file mode 100644 index 00000000..a4b93fb1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/Makefile @@ -0,0 +1,39 @@ +# Makefile to build libopencm3 documentation + +# 14 September 2012 +# (C) Ken Sarkies + +ARCHS := stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 +ARCHS += stm32l0 stm32l1 stm32l4 +ARCHS += efm32g efm32gg efm32lg efm32tg +ARCHS += lm3s lm4f +ARCHS += lpc13xx lpc17xx lpc43xx +ARCHS += sam3a sam3n sam3s sam3u sam3x +ARCHS += vf6xx + +PDFS := $(ARCHS:=.pdf) + +doc: html latex + +html: cm3 usb $(ARCHS) + doxygen + +latex: $(PDFS) + +cm3: + cd cm3/; doxygen + +usb: + cd usb/; doxygen + +$(ARCHS): + cd $@/; doxygen + +%.pdf: + cd $*/; doxygen Doxyfile_latex; cd latex/; $(MAKE); cp refman.pdf ../../$(*).pdf + +clean: + @rm -rf html/ */html/ */latex/ *.pdf */*.tag + +.PHONY: doc html cm3 usb $(ARCHS) latex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/README b/hardware-wallet/firmware/vendor/libopencm3/doc/README new file mode 100644 index 00000000..a7ac627e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/README @@ -0,0 +1,34 @@ +libopencm3 Documentation +14 September 2012 (C) K Sarkies +------------------------------- + +To generate all documentation run 'make doc' in the doc directory, or +for html documentation only run 'make html' (much faster). This runs doxygen +for each of the processor families then integrates the whole. + +Alternatively run 'make doc' in the top directory to make html documentation. +LaTeX and pdf documentation is currently very large in size. + +This requires doxygen v 1.8.2 or later. + +HTML, LaTeX, and pdf output can be produced. + +Generation of HTML +------------------ + +To view HTML, point a browser to libopencm3/doc/html/index.html. + +Generation of PDF +----------------- + +The pdf is generated via LaTeX. The pdf files are placed in the +doc directory. Each file contains all documentation for the core and common +features. The resulting files are huge. + + +Requirements +------------ +On Fedora 19, the following packages (at least!) are needed to build the pdf +output + + texlive texlive-sectsty texlive-tocloft texlive-xtab texlive-multirow diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/cm3/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/cm3/Doxyfile new file mode 100644 index 00000000..7cf6496c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/cm3/Doxyfile @@ -0,0 +1,24 @@ +# HTML Documentation for CM3 Core features. + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_cm3.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/cm3/ + +LAYOUT_FILE = DoxygenLayout_cm3.xml + +GENERATE_TAGFILE = cm3.tag + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/cm3/DoxygenLayout_cm3.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/cm3/DoxygenLayout_cm3.xml new file mode 100644 index 00000000..8173b18e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/cm3/DoxygenLayout_cm3.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile new file mode 100644 index 00000000..a3a65c76 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile @@ -0,0 +1,30 @@ +# HTML Documentation for efm32 code level + +# 11 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32g.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32g \ + ../../lib/efm32/efm32g + +EXCLUDE = + +LAYOUT_FILE = DoxygenLayout_efm32g.xml + +GENERATE_TAGFILE = efm32g.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile_latex new file mode 100644 index 00000000..47373f0e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for efm32 code level + +# 12 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32g_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32g \ + ../../lib/efm32/efm32g + +EXCLUDE = ../../include/libopencm3/efm32/doc-efm32g.h + +LAYOUT_FILE = DoxygenLayout_efm32g.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_efm32g.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/DoxygenLayout_efm32g.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/DoxygenLayout_efm32g.xml new file mode 100644 index 00000000..8c1fae61 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/DoxygenLayout_efm32g.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/header_efm32g.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/header_efm32g.tex new file mode 100644 index 00000000..43a3ea6a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32g/header_efm32g.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ EFM32 Gecko ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile new file mode 100644 index 00000000..1b939004 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile @@ -0,0 +1,30 @@ +# HTML Documentation for efm32 code level + +# 11 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32gg.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32gg \ + ../../lib/efm32/efm32gg + +EXCLUDE = + +LAYOUT_FILE = DoxygenLayout_efm32gg.xml + +GENERATE_TAGFILE = efm32gg.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile_latex new file mode 100644 index 00000000..2f1f8fd0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for efm32 code level + +# 12 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32gg_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32gg \ + ../../lib/efm32/efm32gg + +EXCLUDE = ../../include/libopencm3/efm32/doc-efm32gg.h + +LAYOUT_FILE = DoxygenLayout_efm32gg.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_efm32gg.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/DoxygenLayout_efm32gg.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/DoxygenLayout_efm32gg.xml new file mode 100644 index 00000000..2b3bcf2c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/DoxygenLayout_efm32gg.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/header_efm32gg.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/header_efm32gg.tex new file mode 100644 index 00000000..55288fbd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32gg/header_efm32gg.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ EFM32 Giant Gecko ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile new file mode 100644 index 00000000..2139da58 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile @@ -0,0 +1,30 @@ +# HTML Documentation for efm32 code level + +# 11 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32lg.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32lg \ + ../../lib/efm32/efm32lg + +EXCLUDE = + +LAYOUT_FILE = DoxygenLayout_efm32lg.xml + +GENERATE_TAGFILE = efm32lg.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile_latex new file mode 100644 index 00000000..0b8ed0df --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for efm32 code level + +# 12 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32lg_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32lg \ + ../../lib/efm32/efm32lg + +EXCLUDE = ../../include/libopencm3/efm32/doc-efm32lg.h + +LAYOUT_FILE = DoxygenLayout_efm32lg.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_efm32lg.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/DoxygenLayout_efm32lg.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/DoxygenLayout_efm32lg.xml new file mode 100644 index 00000000..7517a3b8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/DoxygenLayout_efm32lg.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/header_efm32lg.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/header_efm32lg.tex new file mode 100644 index 00000000..900752cf --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32lg/header_efm32lg.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ EFM32 Leopard Gecko ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile new file mode 100644 index 00000000..1610f21f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile @@ -0,0 +1,30 @@ +# HTML Documentation for efm32 code level + +# 11 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32tg.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32tg \ + ../../lib/efm32/efm32tg + +EXCLUDE = + +LAYOUT_FILE = DoxygenLayout_efm32tg.xml + +GENERATE_TAGFILE = efm32tg.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile_latex new file mode 100644 index 00000000..adca3de9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for efm32 code level + +# 12 November 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_efm32tg_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/efm32/efm32tg \ + ../../lib/efm32/efm32tg + +EXCLUDE = ../../include/libopencm3/efm32/doc-efm32tg.h + +LAYOUT_FILE = DoxygenLayout_efm32tg.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_efm32tg.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/DoxygenLayout_efm32tg.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/DoxygenLayout_efm32tg.xml new file mode 100644 index 00000000..ac1cba91 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/DoxygenLayout_efm32tg.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/header_efm32tg.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/header_efm32tg.tex new file mode 100644 index 00000000..625e7fa9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/efm32tg/header_efm32tg.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ EFM32 Tiny Gecko ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile new file mode 100644 index 00000000..d7feff22 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile @@ -0,0 +1,28 @@ +# HTML Documentation for LM3S code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lm3s.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lm3s \ + ../../lib/lm3s + +LAYOUT_FILE = DoxygenLayout_lm3s.xml + +GENERATE_TAGFILE = lm3s.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile_latex new file mode 100644 index 00000000..1cff5655 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for LM3S code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lm3s_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lm3s \ + ../../lib/lm3s + +EXCLUDE = ../../include/libopencm3/lm3s/doc-lm3s.h + +LAYOUT_FILE = DoxygenLayout_lm3s.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_lm3s.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/DoxygenLayout_lm3s.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/DoxygenLayout_lm3s.xml new file mode 100644 index 00000000..178c9078 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/DoxygenLayout_lm3s.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/header_lm3s.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/header_lm3s.tex new file mode 100644 index 00000000..089dce39 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm3s/header_lm3s.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ TI LM3S ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile new file mode 100644 index 00000000..284ac7ab --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile @@ -0,0 +1,28 @@ +# HTML Documentation for LM3S code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lm4f.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lm4f \ + ../../lib/lm4f + +LAYOUT_FILE = DoxygenLayout_lm4f.xml + +GENERATE_TAGFILE = lm4f.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile_latex new file mode 100644 index 00000000..da3c0dd5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/Doxyfile_latex @@ -0,0 +1,33 @@ +# LaTeX Documentation for LM3S code level + +# 14 September 2012 +# Copyright (C) Ken Sarkies +# Copyright (C) 2012 Alexandru Gagniuc + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lm4f_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lm4f \ + ../../lib/lm4f + +EXCLUDE = ../../include/libopencm3/lm4f/doc-lm4f.h + +LAYOUT_FILE = DoxygenLayout_lm4f.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_lm4f.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/DoxygenLayout_lm4f.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/DoxygenLayout_lm4f.xml new file mode 100644 index 00000000..5e3fb0ad --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/DoxygenLayout_lm4f.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/header_lm4f.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/header_lm4f.tex new file mode 100644 index 00000000..68f02bad --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lm4f/header_lm4f.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ TI LM4f ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile new file mode 100644 index 00000000..d8284fc5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile @@ -0,0 +1,28 @@ +# HTML Documentation for LPC13xx code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lpc13xx.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lpc13xx \ + ../../lib/lpc13xx + +LAYOUT_FILE = DoxygenLayout_lpc13xx.xml + +GENERATE_TAGFILE = lpc13xx.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile_latex new file mode 100644 index 00000000..140e9085 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for LPC13xx code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lpc13xx_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lpc13xx/ \ + ../../lib/lpc13xx + +EXCLUDE = ../../include/libopencm3/lpc13xx/doc-lpc13xx.h + +LAYOUT_FILE = DoxygenLayout_lpc13xx.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_lpc13xx.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/DoxygenLayout_lpc13xx.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/DoxygenLayout_lpc13xx.xml new file mode 100644 index 00000000..a21c8a8a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/DoxygenLayout_lpc13xx.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/header_lpc13xx.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/header_lpc13xx.tex new file mode 100644 index 00000000..2f50154e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc13xx/header_lpc13xx.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ NXP LPC13xx ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile new file mode 100644 index 00000000..0dba6631 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile @@ -0,0 +1,28 @@ +# HTML Documentation for LPC17xx code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lpc17xx.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lpc17xx \ + ../../lib/lpc17xx + +LAYOUT_FILE = DoxygenLayout_lpc17xx.xml + +GENERATE_TAGFILE = lpc17xx.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile_latex new file mode 100644 index 00000000..8d3202cc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for LPC17xx code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lpc17xx_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lpc17xx/ \ + ../../lib/lpc17xx + +EXCLUDE = ../../include/libopencm3/lpc17xx/doc-lpc17xx.h + +LAYOUT_FILE = DoxygenLayout_lpc17xx.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_lpc17xx.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/DoxygenLayout_lpc17xx.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/DoxygenLayout_lpc17xx.xml new file mode 100644 index 00000000..e82a7def --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/DoxygenLayout_lpc17xx.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/header_lpc17xx.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/header_lpc17xx.tex new file mode 100644 index 00000000..3f8539da --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc17xx/header_lpc17xx.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ NXP LPC17xx ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile new file mode 100644 index 00000000..fc6a3114 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile @@ -0,0 +1,28 @@ +# HTML Documentation for LPC43xx code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lpc43xx.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lpc43xx \ + ../../lib/lpc43xx + +LAYOUT_FILE = DoxygenLayout_lpc43xx.xml + +GENERATE_TAGFILE = lpc43xx.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile_latex new file mode 100644 index 00000000..567ddc26 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/Doxyfile_latex @@ -0,0 +1,32 @@ +# LaTeX Documentation for LPC43xx code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_lpc43xx_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/lpc43xx/ \ + ../../lib/lpc43xx + +EXCLUDE = ../../include/libopencm3/lpc43xx/doc-lpc43xx.h + +LAYOUT_FILE = DoxygenLayout_lpc43xx.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_lpc43xx.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/DoxygenLayout_lpc43xx.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/DoxygenLayout_lpc43xx.xml new file mode 100644 index 00000000..9c30b500 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/DoxygenLayout_lpc43xx.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/header_lpc43xx.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/header_lpc43xx.tex new file mode 100644 index 00000000..829e2e7b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/lpc43xx/header_lpc43xx.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ NXP LPC43xx ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile new file mode 100644 index 00000000..4ec920c4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile @@ -0,0 +1,37 @@ +# HTML Documentation for SAM3A code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3a.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3a \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3a \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3n3s.h + +LAYOUT_FILE = DoxygenLayout_sam3a.xml + +GENERATE_TAGFILE = sam3a.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile_latex new file mode 100644 index 00000000..c20eb73c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/Doxyfile_latex @@ -0,0 +1,39 @@ +# LaTeX Documentation for SAM3A code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3a_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3a \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3a \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3n3s.h + +LAYOUT_FILE = DoxygenLayout_sam3a.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_sam3a.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/DoxygenLayout_sam3a.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/DoxygenLayout_sam3a.xml new file mode 100644 index 00000000..46af0ce5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/DoxygenLayout_sam3a.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/header_sam3a.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/header_sam3a.tex new file mode 100644 index 00000000..89c48881 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3a/header_sam3a.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ Atmel SAM3A ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile new file mode 100644 index 00000000..c268821c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile @@ -0,0 +1,37 @@ +# HTML Documentation for SAM3N code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3n.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3n \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3n \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3a3u3x.h + +LAYOUT_FILE = DoxygenLayout_sam3n.xml + +GENERATE_TAGFILE = sam3n.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile_latex new file mode 100644 index 00000000..9583bc56 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/Doxyfile_latex @@ -0,0 +1,39 @@ +# LaTeX Documentation for SAM3N code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3n_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3n \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3n \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3a3u3x.h + +LAYOUT_FILE = DoxygenLayout_sam3n.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_sam3n.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/DoxygenLayout_sam3n.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/DoxygenLayout_sam3n.xml new file mode 100644 index 00000000..4a5152c1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/DoxygenLayout_sam3n.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/header_sam3a.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/header_sam3a.tex new file mode 100644 index 00000000..987ced71 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3n/header_sam3a.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ Atmel SAM3N ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile new file mode 100644 index 00000000..2c6a2ebb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile @@ -0,0 +1,37 @@ +# HTML Documentation for SAM3S code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3s.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3s \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3a \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3a3u3x.h + +LAYOUT_FILE = DoxygenLayout_sam3s.xml + +GENERATE_TAGFILE = sam3s.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile_latex new file mode 100644 index 00000000..648f7a8f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/Doxyfile_latex @@ -0,0 +1,39 @@ +# LaTeX Documentation for SAM3S code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3s_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3s \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3s \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3a3u3x.h + +LAYOUT_FILE = DoxygenLayout_sam3s.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_sam3s.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/DoxygenLayout_sam3s.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/DoxygenLayout_sam3s.xml new file mode 100644 index 00000000..71305c80 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/DoxygenLayout_sam3s.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/header_sam3a.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/header_sam3a.tex new file mode 100644 index 00000000..61e24c13 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3s/header_sam3a.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ Atmel SAM3S ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile new file mode 100644 index 00000000..72fddf45 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile @@ -0,0 +1,37 @@ +# HTML Documentation for SAM3U code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3u.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3u \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3u \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3n3s.h + +LAYOUT_FILE = DoxygenLayout_sam3u.xml + +GENERATE_TAGFILE = sam3u.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile_latex new file mode 100644 index 00000000..d732d6eb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/Doxyfile_latex @@ -0,0 +1,39 @@ +# LaTeX Documentation for SAM3U code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3u_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3u \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3u \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3n3s.h + +LAYOUT_FILE = DoxygenLayout_sam3u.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_sam3u.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/DoxygenLayout_sam3u.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/DoxygenLayout_sam3u.xml new file mode 100644 index 00000000..85023287 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/DoxygenLayout_sam3u.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/header_sam3a.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/header_sam3a.tex new file mode 100644 index 00000000..79668b1b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3u/header_sam3a.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ Atmel SAM3U ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile new file mode 100644 index 00000000..ce5e62a7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile @@ -0,0 +1,37 @@ +# HTML Documentation for SAM3X code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3x.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3x \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3x \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3n3s.h + +LAYOUT_FILE = DoxygenLayout_sam3x.xml + +GENERATE_TAGFILE = sam3x.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile_latex new file mode 100644 index 00000000..11e0105b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/Doxyfile_latex @@ -0,0 +1,39 @@ +# LaTeX Documentation for SAM3X code level + +# 14 September 2012 +# (C) Ken Sarkies +# 09 February 2014 +# (C) Felix Held + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_sam3x_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/sam/3x \ + ../../include/libopencm3/sam/common + +INPUT += ../../lib/sam/3x \ + ../../lib/sam/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_3n3s.h + +LAYOUT_FILE = DoxygenLayout_sam3x.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_sam3x.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/DoxygenLayout_sam3x.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/DoxygenLayout_sam3x.xml new file mode 100644 index 00000000..da863df9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/DoxygenLayout_sam3x.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/header_sam3a.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/header_sam3a.tex new file mode 100644 index 00000000..b3c7e4ec --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/sam3x/header_sam3a.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ Atmel SAM3X ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile new file mode 100644 index 00000000..725499db --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile @@ -0,0 +1,38 @@ +# HTML Documentation for STM32F1 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f0.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f0 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f0 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f0/usb.h \ + ../../include/libopencm3/stm32/f0/usb_desc.h + +EXCLUDE_PATTERNS = *_common_*f24.h *_common_*f24.c \ + *_common_*f234.h *_common_*f234.c \ + *_common_*f124.h *_common_*f124.c + +LAYOUT_FILE = DoxygenLayout_stm32f0.xml + +GENERATE_TAGFILE = stm32f0.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile_latex new file mode 100644 index 00000000..f62818d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/Doxyfile_latex @@ -0,0 +1,40 @@ +# LaTeX Documentation for STM32F1 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f0_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f0 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f0 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f0/doc-stm32f0.h \ + ../../include/libopencm3/stm32/f0/usb.h \ + ../../include/libopencm3/stm32/f0/usb_desc.h \ + ../../include/libopencm3/stm32/f0/nvic_f0.h + +EXCLUDE_PATTERNS = *_common_f24.h *_common_f24.c + +LAYOUT_FILE = DoxygenLayout_stm32f0.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32f0.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/DoxygenLayout_stm32f0.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/DoxygenLayout_stm32f0.xml new file mode 100644 index 00000000..0bdde1f0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/DoxygenLayout_stm32f0.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/header_stm32f0.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/header_stm32f0.tex new file mode 100644 index 00000000..6de861d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/header_stm32f0.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32F0 ARM Cortex M0 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f0/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile new file mode 100644 index 00000000..556b6230 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile @@ -0,0 +1,46 @@ +# HTML Documentation for STM32F1 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f1.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f1 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f1 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f1/usb.h \ + ../../include/libopencm3/stm32/f1/usb_desc.h \ + ../../include/libopencm3/stm32/common/crs_common_all.h + +EXCLUDE += ../../lib/stm32/common/crs_common_all.c \ + ../../lib/stm32/common/rtc_common_l1f024.c \ + ../../lib/stm32/common/ + +EXCLUDE_PATTERNS = *_common_*f24.h *_common_*f24.c \ + *_common_*f234.h *_common_*f234.c \ + *_common_*f0234.h *_common_*f0234.c \ + *_common_*f024.h *_common_*f024.c \ + *_common_*f03.h *_common_*f03.c \ + *_common_l01.h _common_l01.c + +LAYOUT_FILE = DoxygenLayout_stm32f1.xml + +GENERATE_TAGFILE = stm32f1.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile_latex new file mode 100644 index 00000000..97c32e77 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/Doxyfile_latex @@ -0,0 +1,40 @@ +# LaTeX Documentation for STM32F1 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f1_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f1 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f1 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f1/doc-stm32f1.h \ + ../../include/libopencm3/stm32/f1/usb.h \ + ../../include/libopencm3/stm32/f1/usb_desc.h \ + ../../include/libopencm3/stm32/f1/nvic_f1.h + +EXCLUDE_PATTERNS = *_common_f24.h *_common_f24.c + +LAYOUT_FILE = DoxygenLayout_stm32f1.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32f1.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/DoxygenLayout_stm32f1.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/DoxygenLayout_stm32f1.xml new file mode 100644 index 00000000..20e26e5e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/DoxygenLayout_stm32f1.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/header_stm32f1.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/header_stm32f1.tex new file mode 100644 index 00000000..19fb8db1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/header_stm32f1.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32F1 ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f1/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile new file mode 100644 index 00000000..b522998f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile @@ -0,0 +1,39 @@ +# HTML Documentation for STM32F2 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f2.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f2 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f2 \ + ../../lib/stm32/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_f13.h *_common_f13.c \ + *_common_*f013.h *_common_*f013.c \ + *_common_*f01.h *_common_*f01.c \ + *_common_*f03.h *_common_*f03.c \ + *crs_common_all.[ch] + +LAYOUT_FILE = DoxygenLayout_stm32f2.xml + +GENERATE_TAGFILE = stm32f2.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile_latex new file mode 100644 index 00000000..dad68489 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/Doxyfile_latex @@ -0,0 +1,37 @@ +# LaTeX Documentation for STM32F2 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f2_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f2 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f2 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f2/doc-stm32f2.h + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32f2.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32f2.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/DoxygenLayout_stm32f2.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/DoxygenLayout_stm32f2.xml new file mode 100644 index 00000000..1b23e833 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/DoxygenLayout_stm32f2.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/header_stm32f2.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/header_stm32f2.tex new file mode 100644 index 00000000..d65c4f0a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/header_stm32f2.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32F2 ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f2/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile new file mode 100644 index 00000000..f751db82 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile @@ -0,0 +1,36 @@ +# HTML Documentation for STM32F3 code level + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f3.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f3 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f3 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f3/usb.h \ + ../../include/libopencm3/stm32/f3/usb_desc.h + +EXCLUDE_PATTERNS = *_common_*f*24.h *_common_*f*24.c \ + *_common_*f01.h *_common_*f01.c \ + *_common_bcd.h *_common_bcd.c \ + *crs_common_all.[ch] +EXCLUDE_PATTERNS += *adc_common_v1* *adc_common_v2_single* +EXCLUDE_PATTERNS += *pwr_common_l01.* + +LAYOUT_FILE = DoxygenLayout_stm32f3.xml + +GENERATE_TAGFILE = stm32f3.tag + +ENABLE_PREPROCESSING = YES diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile_latex new file mode 100644 index 00000000..a9dc0f6e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/Doxyfile_latex @@ -0,0 +1,40 @@ +# LaTeX Documentation for STM32F3 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f3_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f3 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f3 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f3/doc-stm32f3.h \ + ../../include/libopencm3/stm32/f3/usb.h \ + ../../include/libopencm3/stm32/f3/usb_desc.h \ + ../../include/libopencm3/stm32/f3/nvic_f3.h + +EXCLUDE_PATTERNS = *_common_f24.h *_common_f24.c + +LAYOUT_FILE = DoxygenLayout_stm32f1.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32f3.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/DoxygenLayout_stm32f3.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/DoxygenLayout_stm32f3.xml new file mode 100644 index 00000000..814011b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/DoxygenLayout_stm32f3.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/header_stm32f3.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/header_stm32f3.tex new file mode 100644 index 00000000..0755c0a9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/header_stm32f3.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32F3 ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f3/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile new file mode 100644 index 00000000..5c1dcd61 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile @@ -0,0 +1,39 @@ +# HTML Documentation for STM32F4 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f4.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f4 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f4 \ + ../../lib/stm32/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_f*3.h *_common_f*3.c \ + *_common_*f013.h *_common_*f013.c \ + *_common_*f01.h *_common_*f01.c \ \ + *_common_*f03.h *_common_*f03.c \ + *crs_common_all.[ch] + +LAYOUT_FILE = DoxygenLayout_stm32f4.xml + +GENERATE_TAGFILE = stm32f4.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile_latex new file mode 100644 index 00000000..e93248c5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/Doxyfile_latex @@ -0,0 +1,37 @@ +# LaTeX Documentation for STM32F4 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f4_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f4 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f4 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f4/doc-stm32f4.h + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32f4.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32f4.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/DoxygenLayout_stm32f4.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/DoxygenLayout_stm32f4.xml new file mode 100644 index 00000000..3fcef60c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/DoxygenLayout_stm32f4.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/header_stm32f4.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/header_stm32f4.tex new file mode 100644 index 00000000..97cc35ff --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/header_stm32f4.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32F4 ARM Cortex M4 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f4/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile new file mode 100644 index 00000000..3c2bd708 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile @@ -0,0 +1,39 @@ +# HTML Documentation for STM32F7 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f7.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f7 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f7 \ + ../../lib/stm32/common + +EXCLUDE = + +EXCLUDE_PATTERNS = *_common_f*3.h *_common_f*3.c \ + *_common_*f013.h *_common_*f013.c \ + *_common_*f01.h *_common_*f01.c \ \ + *_common_*f03.h *_common_*f03.c +EXCLUDE_PATTERNS += pwr_common_v1.* pwr_common_v2.* + +LAYOUT_FILE = DoxygenLayout_stm32f7.xml + +GENERATE_TAGFILE = stm32f7.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile_latex new file mode 100644 index 00000000..28517110 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/Doxyfile_latex @@ -0,0 +1,37 @@ +# LaTeX Documentation for STM32F7 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32f7_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/f7 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/f4 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/f4/doc-stm32f7.h + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32f7.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32f7.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/DoxygenLayout_stm32f7.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/DoxygenLayout_stm32f7.xml new file mode 100644 index 00000000..a44fbaf0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/DoxygenLayout_stm32f7.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/header_stm32f7.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/header_stm32f7.tex new file mode 100644 index 00000000..03ff59c2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/header_stm32f7.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32F7 ARM Cortex M7 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32f7/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile new file mode 100644 index 00000000..496336ff --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile @@ -0,0 +1,43 @@ +# HTML Documentation for STM32L0 code level + +# 15 December 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32l0.log + +INPUT = ../../include/libopencm3/license.dox +INPUT +=../../include/libopencm3/stm32/l0 +INPUT +=../../include/libopencm3/stm32/common + +INPUT +=../../lib/stm32/l0 +INPUT +=../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/common/gpio_common_f24.h +EXCLUDE +=../../include/libopencm3/stm32/common/timer_common_f24.h \ +EXCLUDE +=../../include/libopencm3/stm32/common/crypto_common_f24.h \ +EXCLUDE +=../../include/libopencm3/stm32/common/hash_common_f24.h + +EXCLUDE =../../lib/stm32/common/gpio_common_f24.c +EXCLUDE =../../lib/stm32/common/timer_common_f24.c +EXCLUDE =../../lib/stm32/common/crypto_common_f24.c +EXCLUDE =../../lib/stm32/common/hash_common_f24.c + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32l0.xml + +GENERATE_TAGFILE = stm32l0.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile_latex new file mode 100644 index 00000000..2886e4e8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/Doxyfile_latex @@ -0,0 +1,38 @@ +# LaTeX Documentation for STM32L0 code level + +# 15 September 2014 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32l0_latex.log + +INPUT = ../../include/libopencm3/docmain.dox +INPUT += ../../include/libopencm3/license.dox \ +INPUT += ../../include/libopencm3/stm32/l0 \ +INPUT += ../../include/libopencm3/stm32/common +INPUT += ../../lib/stm32/l0 +INPUT += ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/l0/doc-stm32l0.h +EXCLUDE += ../../include/libopencm3/stm32/common/gpio_common_f24.h +EXCLUDE += ../../lib/stm32/common/gpio_common_f24.c + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32l0.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32l0.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/DoxygenLayout_stm32l0.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/DoxygenLayout_stm32l0.xml new file mode 100644 index 00000000..a50ef37f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/DoxygenLayout_stm32l0.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/header_stm32l0.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/header_stm32l0.tex new file mode 100644 index 00000000..2c5e7c27 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/header_stm32l0.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32L0 ARM Cortex M0 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l0/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile new file mode 100644 index 00000000..98835ab8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile @@ -0,0 +1,48 @@ +# HTML Documentation for STM32L1 code level + +# 15 December 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32l1.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/l1 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/l1 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/common/gpio_common_f24.h \ + ../../include/libopencm3/stm32/common/gpio_common_f234.h \ + ../../include/libopencm3/stm32/common/timer_common_f24.h \ + ../../include/libopencm3/stm32/common/crypto_common_f24.h \ + ../../include/libopencm3/stm32/common/hash_common_f24.h \ + ../../include/libopencm3/stm32/common/crs_common_all.h + +EXCLUDE += ../../lib/stm32/common/gpio_common_f24.c \ + ../../lib/stm32/common/timer_common_f24.c \ + ../../lib/stm32/common/crypto_common_f24.c \ + ../../lib/stm32/common/hash_common_f24.c \ + ../../lib/stm32/common/crs_common_all.c + +EXCLUDE_PATTERNS = *common/flash_common_f*.* +EXCLUDE_PATTERNS += *common/adc_common_v2* +EXCLUDE_PATTERNS += *common/spi_common_f03.* + +LAYOUT_FILE = DoxygenLayout_stm32l1.xml + +GENERATE_TAGFILE = stm32l1.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile_latex new file mode 100644 index 00000000..51d217fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/Doxyfile_latex @@ -0,0 +1,40 @@ +# LaTeX Documentation for STM32L1 code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32l1_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/stm32/l1 \ + ../../include/libopencm3/stm32/common + +INPUT += ../../lib/stm32/l1 \ + ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/l1/doc-stm32l1.h \ + ../../include/libopencm3/stm32/common/gpio_common_f24.h + +EXCLUDE += ../../lib/stm32/common/gpio_common_f24.c + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32l1.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32l1.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/DoxygenLayout_stm32l1.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/DoxygenLayout_stm32l1.xml new file mode 100644 index 00000000..b2d19af9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/DoxygenLayout_stm32l1.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/header_stm32l1.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/header_stm32l1.tex new file mode 100644 index 00000000..edf6907e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/header_stm32l1.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32L1 ARM Cortex M3 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l1/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile new file mode 100644 index 00000000..6af32498 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile @@ -0,0 +1,46 @@ +# HTML Documentation for STM32L4 code level + +# 15 December 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32l4.log + +INPUT = ../../include/libopencm3/license.dox +INPUT +=../../include/libopencm3/stm32/l4 +#INPUT +=../../include/libopencm3/stm32/common +INPUT +=../../include/libopencm3/stm32/common/rcc_common_all.h +INPUT +=../../include/libopencm3/stm32/common/gpio_common_all.h +INPUT +=../../include/libopencm3/stm32/common/gpio_common_f234.h +INPUT +=../../include/libopencm3/stm32/common/gpio_common_f24.h + +INPUT +=../../lib/stm32/l4 +#INPUT +=../../lib/stm32/common +INPUT +=../../lib/stm32/common/rcc_common_all.c +INPUT +=../../lib/stm32/common/gpio_common_all.c +INPUT +=../../lib/stm32/common/gpio_common_f0234.c + +# No headers to exclude until we include some! +EXCLUDE = + +# No libs to exclude until we include some! +EXCLUDE = + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32l4.xml + +GENERATE_TAGFILE = stm32l4.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile_latex new file mode 100644 index 00000000..c03cb756 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/Doxyfile_latex @@ -0,0 +1,38 @@ +# LaTeX Documentation for STM32L4 code level + +# 15 September 2014 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_stm32l4_latex.log + +INPUT = ../../include/libopencm3/docmain.dox +INPUT += ../../include/libopencm3/license.dox \ +INPUT += ../../include/libopencm3/stm32/l4 \ +INPUT += ../../include/libopencm3/stm32/common +INPUT += ../../lib/stm32/l4 +INPUT += ../../lib/stm32/common + +EXCLUDE = ../../include/libopencm3/stm32/l4/doc-stm32l4.h +EXCLUDE += ../../include/libopencm3/stm32/common/gpio_common_f24.h +EXCLUDE += ../../lib/stm32/common/gpio_common_f24.c + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_stm32l4.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_stm32l4.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/DoxygenLayout_stm32l4.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/DoxygenLayout_stm32l4.xml new file mode 100644 index 00000000..2049aff0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/DoxygenLayout_stm32l4.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/header_stm32l4.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/header_stm32l4.tex new file mode 100644 index 00000000..4ff6359a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/header_stm32l4.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ STM STM32L4 ARM Cortex M4 Series}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu Sep 13 2012 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/index.html new file mode 100644 index 00000000..7715877a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/stm32l4/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile new file mode 100644 index 00000000..fcd2745d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile @@ -0,0 +1,31 @@ +# HTML Documentation for USB code level + +# 10 March 2013 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_usb.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/usb + +INPUT += ../../lib/usb + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_usb.xml + +GENERATE_TAGFILE = usb.tag + +ENABLE_PREPROCESSING = NO + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile_latex new file mode 100644 index 00000000..00392aaa --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/Doxyfile_latex @@ -0,0 +1,40 @@ +# LaTeX Documentation for USB code level + +# 10 March 2013 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_usb_latex.log + +WARN_LOGFILE = doxygen_usb.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/usb + +INPUT += ../../lib/usb + +EXCLUDE_PATTERNS = + +LAYOUT_FILE = DoxygenLayout_usb.xml + +TAGFILES = + +GENERATE_TAGFILE = usb.tag + +ENABLE_PREPROCESSING = NO + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_usb.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/usb/DoxygenLayout_usb.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/DoxygenLayout_usb.xml new file mode 100644 index 00000000..c140cbdb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/DoxygenLayout_usb.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/usb/header_usb.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/header_usb.tex new file mode 100644 index 00000000..5b902527 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/usb/header_usb.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ Cortex M3 Generic USB}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu 10 March 2013 23:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile new file mode 100644 index 00000000..93dfb661 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile @@ -0,0 +1,31 @@ +# HTML Documentation for VF6XX code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_vf6xx.log + +INPUT = ../../include/libopencm3/license.dox \ + ../../include/libopencm3/vf6xx + +INPUT += ../../lib/vf6xx + +EXCLUDE = + +LAYOUT_FILE = DoxygenLayout_vf6xx.xml + +GENERATE_TAGFILE = vf6xx.tag + +ENABLE_PREPROCESSING = YES + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile_latex b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile_latex new file mode 100644 index 00000000..34bf79b9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/Doxyfile_latex @@ -0,0 +1,35 @@ +# LaTeX Documentation for VF6XX code level + +# 14 September 2012 +# (C) Ken Sarkies + +#--------------------------------------------------------------------------- +# Common Include File +#--------------------------------------------------------------------------- + +@INCLUDE = ../Doxyfile_common + +#--------------------------------------------------------------------------- +# Local settings +#--------------------------------------------------------------------------- + +WARN_LOGFILE = doxygen_vf6xx_latex.log + +INPUT = ../../include/libopencm3/docmain.dox \ + ../../include/libopencm3/license.dox \ + ../../include/libopencm3/vf6xx + +INPUT += ../../lib/vf6xx + +EXCLUDE_PATTERNS = + +EXCLUDE = ../../include/libopencm3/vf6xx/doc-vf6xx.h + +LAYOUT_FILE = DoxygenLayout_vf6xx.xml + +GENERATE_HTML = NO + +GENERATE_LATEX = YES + +LATEX_HEADER = header_vf6xx.tex + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/DoxygenLayout_vf6xx.xml b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/DoxygenLayout_vf6xx.xml new file mode 100644 index 00000000..9b427673 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/DoxygenLayout_vf6xx.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/header_vf6xx.tex b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/header_vf6xx.tex new file mode 100644 index 00000000..7493f832 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/header_vf6xx.tex @@ -0,0 +1,61 @@ +\documentclass{book} +\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry} +\usepackage{makeidx} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{listings} +\usepackage{color} +\usepackage{ifthen} +\usepackage[table]{xcolor} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{ifpdf} +\ifpdf +\usepackage[pdftex, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\else +\usepackage[ps2pdf, + pagebackref=true, + colorlinks=true, + linkcolor=blue, + unicode + ]{hyperref} +\usepackage{pspicture} +\fi +\usepackage[utf8]{inputenc} +\usepackage{mathptmx} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{sectsty} +\usepackage{amssymb} +\usepackage[titles]{tocloft} +\usepackage{doxygen} +\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left } +\makeindex +\setcounter{tocdepth}{3} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\familydefault}{\sfdefault} +\hfuzz=15pt +\setlength{\emergencystretch}{15pt} +\hbadness=750 +\tolerance=750 +\begin{document} +\hypersetup{pageanchor=false,citecolor=blue} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Huge libopencm3: API Reference\\ Freescale Vybrid VF6xx Series ARM Cortex-M4}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.2}\\ +\vspace*{0.5cm} +{\small Thu July 14 2014 14:26:45}\\ +\end{center} +\end{titlepage} +\pagenumbering{arabic} +\hypersetup{pageanchor=true,citecolor=blue} diff --git a/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/index.html b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/index.html new file mode 100644 index 00000000..048aa174 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/doc/vf6xx/index.html @@ -0,0 +1,8 @@ + + + + + + Documentation index

+ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/assert.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/assert.h new file mode 100644 index 00000000..f1aabc3c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/assert.h @@ -0,0 +1,137 @@ +/** @defgroup debugging Debugging + +@brief Macros and functions to aid in debugging + +@version 1.0.0 + +@date 25 September 2012 + +Two preprocessor defines control the behavior of assertion check macros in +this module. They allow the choice between generated code size and ease of +debugging. + +If NDEBUG is defined, all assertion checks are disabled and macros do not +generate any code. + +If CM3_ASSERT_VERBOSE is defined, information regarding the position of +assertion checks will be stored in the binary, allowing for more +informative error messages, but also significantly increased code size. As +default assertion checks do not use this information it is only useful if +the application linked with libopencm3 defines its own +cm3_assert_failed_verbose() implementation. + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Tomaz Solc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_CM3_ASSERT_H +#define LIBOPENCM3_CM3_ASSERT_H + +#include + +#define CM3_LIKELY(expr) (__builtin_expect(!!(expr), 1)) + +#ifdef NDEBUG +# define cm3_assert(expr) (void)0 +# define cm3_assert_not_reached() do { } while (1) +#else +# ifdef CM3_ASSERT_VERBOSE +# define cm3_assert(expr) do { \ + if (CM3_LIKELY(expr)) { \ + (void)0; \ + } else { \ + cm3_assert_failed_verbose( \ + __FILE__, __LINE__, \ + __func__, #expr); \ + } \ + } while (0) +# define cm3_assert_not_reached() \ + cm3_assert_failed_verbose( \ + __FILE__, __LINE__, \ + __func__, 0) +# else +/** @brief Check if assertion is true. + * + * If NDEBUG macro is defined, this macro generates no code. Otherwise + * cm3_assert_failed() or cm3_assert_failed_verbose() is called if assertion + * is false. + * + * The purpose of this macro is to aid in debugging libopencm3 and + * applications using it. It can be used for example to check if function + * arguments are within expected ranges and stop execution in case an + * unexpected state is reached. + * + * @param expr expression to check */ +# define cm3_assert(expr) do { \ + if (CM3_LIKELY(expr)) { \ + (void)0; \ + } else { \ + cm3_assert_failed(); \ + } \ + } while (0) +/** @brief Check if unreachable code is reached. + * + * If NDEBUG macro is defined, this macro generates code for an infinite loop. + * Otherwise cm3_assert_failed() or cm3_assert_failed_verbose() is called if + * the macro is ever reached. + * + * The purpose of this macro is to aid in debugging libopencm3 and + * applications using it. It can be used for example to stop execution if an + * unreachable portion of code is reached. */ +# define cm3_assert_not_reached() cm3_assert_failed() +# endif +#endif + +BEGIN_DECLS + +/** @brief Called on a failed assertion. + * + * Halts execution in an infinite loop. This function never returns. + * + * Defined as a weak symbol, so applications can define their own + * implementation. Usually, a custom implementation of this function should + * report an error in some way (print a message to a debug console, display, + * LED, ...) and halt execution or reboot the device. */ +void cm3_assert_failed(void) __attribute__((__noreturn__)); + +/** @brief Called on a failed assertion with verbose messages enabled. + * + * Halts execution in an infinite loop. This function never returns. + * + * Defined as a weak symbol, so applications can define their own + * implementation. Usually, a custom implementation of this function should + * report an error in some way (print a message to a debug console, display, + * LED, ...) and halt execution or reboot the device. + * + * @param file File name where the failed assertion occurred + * @param line Line number where the failed assertion occurred + * @param func Name of the function where the failed assertion occurred + * @param assert_expr Expression that evaluated to false (can be NULL) */ +void cm3_assert_failed_verbose(const char *file, int line, const char *func, + const char *assert_expr) __attribute__((__noreturn__)); + +END_DECLS + +#endif + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/common.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/common.h new file mode 100644 index 00000000..a7a8df8d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/common.h @@ -0,0 +1,96 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_COMMON_H +#define LIBOPENCM3_CM3_COMMON_H + +#include +#include + +/* This must be placed around external function declaration for C++ + * support. */ +#ifdef __cplusplus +# define BEGIN_DECLS extern "C" { +# define END_DECLS } +#else +# define BEGIN_DECLS +# define END_DECLS +#endif + +/* Full-featured deprecation attribute with fallback for older compilers. */ + +#ifdef __GNUC__ +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4) +# define LIBOPENCM3_DEPRECATED(x) __attribute__((deprecated(x))) +# else +# define LIBOPENCM3_DEPRECATED(x) __attribute__((deprecated)) +# endif +#else +# define LIBOPENCM3_DEPRECATED(x) +#endif + + +/* Generic memory-mapped I/O accessor functions */ +#define MMIO8(addr) (*(volatile uint8_t *)(addr)) +#define MMIO16(addr) (*(volatile uint16_t *)(addr)) +#define MMIO32(addr) (*(volatile uint32_t *)(addr)) +#define MMIO64(addr) (*(volatile uint64_t *)(addr)) + +/* Generic bit-band I/O accessor functions */ +#define BBIO_SRAM(addr, bit) \ + MMIO32((((uint32_t)addr) & 0x0FFFFF) * 32 + 0x22000000 + (bit) * 4) + +#define BBIO_PERIPH(addr, bit) \ + MMIO32((((uint32_t)addr) & 0x0FFFFF) * 32 + 0x42000000 + (bit) * 4) + +/* Generic bit definition */ +#define BIT0 (1<<0) +#define BIT1 (1<<1) +#define BIT2 (1<<2) +#define BIT3 (1<<3) +#define BIT4 (1<<4) +#define BIT5 (1<<5) +#define BIT6 (1<<6) +#define BIT7 (1<<7) +#define BIT8 (1<<8) +#define BIT9 (1<<9) +#define BIT10 (1<<10) +#define BIT11 (1<<11) +#define BIT12 (1<<12) +#define BIT13 (1<<13) +#define BIT14 (1<<14) +#define BIT15 (1<<15) +#define BIT16 (1<<16) +#define BIT17 (1<<17) +#define BIT18 (1<<18) +#define BIT19 (1<<19) +#define BIT20 (1<<20) +#define BIT21 (1<<21) +#define BIT22 (1<<22) +#define BIT23 (1<<23) +#define BIT24 (1<<24) +#define BIT25 (1<<25) +#define BIT26 (1<<26) +#define BIT27 (1<<27) +#define BIT28 (1<<28) +#define BIT29 (1<<29) +#define BIT30 (1<<30) +#define BIT31 (1<<31) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/cortex.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/cortex.h new file mode 100644 index 00000000..cca18b38 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/cortex.h @@ -0,0 +1,281 @@ +/** @defgroup CM3_cortex_defines Cortex Core Defines + * + * @brief libopencm3 Defined Constants and Types for the Cortex Core + * + * @ingroup CM3_defines + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Ben Gamari + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CORTEX_H +#define LIBOPENCM3_CORTEX_H + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Enable interrupts + * + * Disable the interrupt mask and enable interrupts globally + */ +static inline void cm_enable_interrupts(void) +{ + __asm__ volatile ("CPSIE I\n"); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Disable interrupts + * + * Mask all interrupts globally + */ +static inline void cm_disable_interrupts(void) +{ + __asm__ volatile ("CPSID I\n"); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Enable faults + * + * Disable the HardFault mask and enable fault interrupt globally + */ +static inline void cm_enable_faults(void) +{ + __asm__ volatile ("CPSIE F\n"); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Disable faults + * + * Mask the HardFault interrupt globally + */ +static inline void cm_disable_faults(void) +{ + __asm__ volatile ("CPSID F\n"); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Check if interrupts are masked + * + * Checks, if interrupts are masked (disabled). + * + * @returns true, if interrupts are disabled. + */ +__attribute__((always_inline)) +static inline bool cm_is_masked_interrupts(void) +{ + register uint32_t result; + __asm__ volatile ("MRS %0, PRIMASK" : "=r" (result)); + return result; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Check if Fault interrupt is masked + * + * Checks, if HardFault interrupt is masked (disabled). + * + * @returns bool true, if HardFault interrupt is disabled. + */ +__attribute__((always_inline)) +static inline bool cm_is_masked_faults(void) +{ + register uint32_t result; + __asm__ volatile ("MRS %0, FAULTMASK" : "=r" (result)); + return result; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Mask interrupts + * + * This function switches the mask of the interrupts. If mask is true, the + * interrupts will be disabled. The result of this function can be used for + * restoring previous state of the mask. + * + * @param[in] mask uint32_t New state of the interrupt mask + * @returns uint32_t old state of the interrupt mask + */ +__attribute__((always_inline)) +static inline uint32_t cm_mask_interrupts(uint32_t mask) +{ + register uint32_t old; + __asm__ __volatile__("MRS %0, PRIMASK" : "=r" (old)); + __asm__ __volatile__("" : : : "memory"); + __asm__ __volatile__("MSR PRIMASK, %0" : : "r" (mask)); + return old; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Mask HardFault interrupt + * + * This function switches the mask of the HardFault interrupt. If mask is true, + * the HardFault interrupt will be disabled. The result of this function can be + * used for restoring previous state of the mask. + * + * @param[in] mask uint32_t New state of the HardFault interrupt mask + * @returns uint32_t old state of the HardFault interrupt mask + */ +__attribute__((always_inline)) +static inline uint32_t cm_mask_faults(uint32_t mask) +{ + register uint32_t old; + __asm__ __volatile__ ("MRS %0, FAULTMASK" : "=r" (old)); + __asm__ __volatile__ ("" : : : "memory"); + __asm__ __volatile__ ("MSR FAULTMASK, %0" : : "r" (mask)); + return old; +} + +/**@}*/ + +/*===========================================================================*/ +/** @defgroup CM3_cortex_atomic_defines Cortex Core Atomic support Defines + * + * @brief Atomic operation support + * + * @ingroup CM3_cortex_defines + */ +/**@{*/ + +#if !defined(__DOXYGEN__) +/* Do not populate this definition outside */ +static inline uint32_t __cm_atomic_set(uint32_t *val) +{ + return cm_mask_interrupts(*val); +} + +#define __CM_SAVER(state) \ + __val = (state), \ + __save __attribute__((__cleanup__(__cm_atomic_set))) = \ + __cm_atomic_set(&__val) + +#endif /* !defined(__DOXYGEN) */ + + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Atomic Declare block + * + * This macro disables interrupts for the next command or block of code. The + * interrupt mask is automatically restored after exit of the boundary of the + * code block. Therefore restore of interrupt is done automatically after call + * of return or goto control sentence jumping outside of the block. + * + * @warning The usage of sentences break or continue is prohibited in the block + * due to implementation of this macro! + * + * @note It is safe to use this block inside normal code and in interrupt + * routine. + * + * @example 1: Basic usage of atomic block + * + * @code + * uint64_t value; // This value is used somewhere in interrupt + * + * ... + * + * CM_ATOMIC_BLOCK() { // interrupts are masked in this block + * value = value * 1024 + 651; // access value as atomic + * } // interrupts is restored automatically + * @endcode + * + * @example 2: Use of return inside block: + * + * @code + * uint64_t value; // This value is used somewhere in interrupt + * + * ... + * + * uint64_t allocval(void) + * { + * CM_ATOMIC_BLOCK() { // interrupts are masked in this block + * value = value * 1024 + 651; // do long atomic operation + * return value; // interrupts is restored automatically + * } + * } + * @endcode + */ +#if defined(__DOXYGEN__) +#define CM_ATOMIC_BLOCK() +#else /* defined(__DOXYGEN__) */ +#define CM_ATOMIC_BLOCK() \ + for (uint32_t __CM_SAVER(true), __my = true; __my; __my = false) +#endif /* defined(__DOXYGEN__) */ + +/*---------------------------------------------------------------------------*/ +/** @brief Cortex M Atomic Declare context + * + * This macro disables interrupts in the current block of code from the place + * where it is defined to the end of the block. The interrupt mask is + * automatically restored after exit of the boundary of the code block. + * Therefore restore of interrupt is done automatically after call of return, + * continue, break, or goto control sentence jumping outside of the block. + * + * @note This function is intended for use in for- cycles to enable the use of + * break and contine sentences inside the block, and for securing the atomic + * reader-like functions. + * + * @note It is safe to use this block inside normal code and in interrupt + * routine. + * + * @example 1: Basic usage of atomic context + * + * @code + * uint64_t value; // This value is used somewhere in interrupt + * + * ... + * + * for (int i=0;i < 100; i++) { + * CM_ATOMIC_CONTEXT(); // interrupts are masked in this block + * value += 100; // access value as atomic + * if ((value % 16) == 0) { + * break; // restore interrupts and break cycle + * } + * } // interrupts is restored automatically + * @endcode + * + * @example 2: Usage of atomic context inside atomic reader fcn. + * + * @code + * uint64_t value; // This value is used somewhere in interrupt + * + * ... + * + * uint64_t getnextval(void) + * { + * CM_ATOMIC_CONTEXT(); // interrupts are masked in this block + * value = value + 3; // do long atomic operation + * return value; // interrupts is restored automatically + * } + * @endcode + */ +#if defined(__DOXYGEN__) +#define CM_ATOMIC_CONTEXT() +#else /* defined(__DOXYGEN__) */ +#define CM_ATOMIC_CONTEXT() uint32_t __CM_SAVER(true) +#endif /* defined(__DOXYGEN__) */ + +/**@}*/ + + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/doc-cm3.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/doc-cm3.h new file mode 100644 index 00000000..0f76370f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/doc-cm3.h @@ -0,0 +1,22 @@ +/** @mainpage libopencm3 Core CM3 + +@version 1.0.0 + +@date 14 September 2012 + +API documentation for Cortex M3 core features. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup CM3_defines CM3 Defines + +@brief Defined Constants and Types for Cortex M3 core features + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/dwt.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/dwt.h new file mode 100644 index 00000000..184b509e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/dwt.h @@ -0,0 +1,152 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_DWT_H +#define LIBOPENCM3_CM3_DWT_H + +#include +#include + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define DWT_CTRL MMIO32(DWT_BASE + 0x00) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +#define DWT_CYCCNT MMIO32(DWT_BASE + 0x04) +#define DWT_CPICNT MMIO32(DWT_BASE + 0x08) +#define DWT_EXCCNT MMIO32(DWT_BASE + 0x0C) +#define DWT_SLEEPCNT MMIO32(DWT_BASE + 0x10) +#define DWT_LSUCNT MMIO32(DWT_BASE + 0x14) +#define DWT_FOLDCNT MMIO32(DWT_BASE + 0x18) + +#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */ + +#define DWT_PCSR MMIO32(DWT_BASE + 0x1C) +#define DWT_COMP(n) MMIO32(DWT_BASE + 0x20 + (n) * 16) +#define DWT_MASK(n) MMIO32(DWT_BASE + 0x24 + (n) * 16) +#define DWT_FUNCTION(n) MMIO32(DWT_BASE + 0x28 + (n) * 16) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- DWT_CTRL values ---------------------------------------------------- */ + +#define DWT_CTRL_NUMCOMP_SHIFT 28 +#define DWT_CTRL_NUMCOMP (0x0F << DWT_CTRL_NUMCOMP_SHIFT) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +#define DWT_CTRL_NOTRCPKT (1 << 27) +#define DWT_CTRL_NOEXTTRIG (1 << 26) +#define DWT_CTRL_NOCYCCNT (1 << 25) +#define DWT_CTRL_NOPRFCCNT (1 << 24) + +#define DWT_CTRL_CYCEVTENA (1 << 22) +#define DWT_CTRL_FOLDEVTENA (1 << 21) +#define DWT_CTRL_LSUEVTENA (1 << 20) +#define DWT_CTRL_SLEEPEVTENA (1 << 19) +#define DWT_CTRL_EXCEVTENA (1 << 18) +#define DWT_CTRL_CPIEVTENA (1 << 17) +#define DWT_CTRL_EXCTRCENA (1 << 16) +#define DWT_CTRL_PCSAMPLENA (1 << 12) + +#define DWT_CTRL_SYNCTAP_SHIFT 10 +#define DWT_CTRL_SYNCTAP (3 << DWT_CTRL_SYNCTAP_SHIFT) +#define DWT_CTRL_SYNCTAP_DISABLED (0 << DWT_CTRL_SYNCTAP_SHIFT) +#define DWT_CTRL_SYNCTAP_BIT24 (1 << DWT_CTRL_SYNCTAP_SHIFT) +#define DWT_CTRL_SYNCTAP_BIT26 (2 << DWT_CTRL_SYNCTAP_SHIFT) +#define DWT_CTRL_SYNCTAP_BIT28 (3 << DWT_CTRL_SYNCTAP_SHIFT) + +#define DWT_CTRL_CYCTAP (1 << 9) + +#define DWT_CTRL_POSTCNT_SHIFT 5 +#define DWT_CTRL_POSTCNT (0x0F << DWT_CTRL_POSTCNT_SHIFT) + +#define DWT_CTRL_POSTPRESET_SHIFT 1 +#define DWT_CTRL_POSTPRESET (0x0F << DWT_CTRL_POSTPRESET_SHIFT) + +#define DWT_CTRL_CYCCNTENA (1 << 0) + +#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */ + +/* --- DWT_MASK(x) values -------------------------------------------------- */ + +#define DWT_MASKx_MASK 0x0F + +/* --- DWT_FUNCTION(x) values ---------------------------------------------- */ + +#define DWT_FUNCTIONx_MATCHED (1 << 24) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +#define DWT_FUNCTIONx_DATAVADDR1_SHIFT 16 +#define DWT_FUNCTIONx_DATAVADDR1 (15 << DWT_FUNCTIONx_DATAVADDR1_SHIFT) + +#define DWT_FUNCTIONx_DATAVADDR0_SHIFT 12 +#define DWT_FUNCTIONx_DATAVADDR0 (15 << DWT_FUNCTIONx_DATAVADDR0_SHIFT) + +#define DWT_FUNCTIONx_DATAVSIZE_SHIFT 10 +#define DWT_FUNCTIONx_DATAVSIZE (3 << DWT_FUNCTIONx_DATAVSIZE_SHIFT) +#define DWT_FUNCTIONx_DATAVSIZE_BYTE (0 << DWT_FUNCTIONx_DATAVSIZE_SHIFT) +#define DWT_FUNCTIONx_DATAVSIZE_HALF (1 << DWT_FUNCTIONx_DATAVSIZE_SHIFT) +#define DWT_FUNCTIONx_DATAVSIZE_WORD (2 << DWT_FUNCTIONx_DATAVSIZE_SHIFT) + +#define DWT_FUNCTIONx_LNK1ENA (1 << 9) +#define DWT_FUNCTIONx_DATAVMATCH (1 << 8) +#define DWT_FUNCTIONx_CYCMATCH (1 << 7) +#define DWT_FUNCTIONx_EMITRANGE (1 << 5) + +#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */ + +#define DWT_FUNCTIONx_FUNCTION 15 +#define DWT_FUNCTIONx_FUNCTION_DISABLED 0 + +/* Those defined only on ARMv6 */ +#if defined(__ARM_ARCH_6M__) + +#define DWT_FUNCTIONx_FUNCTION_PCWATCH 4 +#define DWT_FUNCTIONx_FUNCTION_DWATCH_R 5 +#define DWT_FUNCTIONx_FUNCTION_DWATCH_W 6 +#define DWT_FUNCTIONx_FUNCTION_DWATCH_RW 7 + +#endif /* defined(__ARM_ARCH_6M__)*/ + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +bool dwt_enable_cycle_counter(void); +uint32_t dwt_read_cycle_counter(void); + +END_DECLS + +#endif /* LIBOPENCM3_CM3_DWT_H */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/fpb.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/fpb.h new file mode 100644 index 00000000..805ddbb9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/fpb.h @@ -0,0 +1,87 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_FPB_H +#define LIBOPENCM3_CM3_FPB_H + +/* Cortex-M3 Flash Patch and Breakpoint (FPB) unit */ + +/* Those defined only on ARMv7 and above */ +#if !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) +#error "Flash Patch and Breakpoint not available in CM0" +#endif + +/* Note: We always use "FPB" as abbreviation, docs sometimes use only "FP". */ + +/* --- FPB registers ------------------------------------------------------- */ + +/* Flash Patch Control (FPB_CTRL) */ +#define FPB_CTRL MMIO32(FPB_BASE + 0) + +/* Flash Patch Remap (FPB_REMAP) */ +#define FPB_REMAP MMIO32(FPB_BASE + 4) + +/* Flash Patch Comparator (FPB_COMPx) */ +#define FPB_COMP (&MMIO32(FPB_BASE + 8)) + +/* CoreSight Lock Status Register for this peripheral */ +#define FPB_LSR MMIO32(FPB_BASE + 0xFB4) +/* CoreSight Lock Access Register for this peripheral */ +#define FPB_LAR MMIO32(FPB_BASE + 0xFB0) + + +/* TODO: PID, CID */ + +/* --- FPB_CTRL values ----------------------------------------------------- */ + +/* Bits [31:15]: Reserved, read as zero, writes ignored */ + +#define FPB_CTRL_NUM_CODE2_MASK (0x7 << 12) + +#define FPB_CTRL_NUM_LIT_MASK (0xf << 8) + +#define FPB_CTRL_NUM_CODE1_MASK (0xf << 4) + +/* Bits [3:2]: Reserved */ + +#define FPB_CTRL_KEY (1 << 1) + +#define FPB_CTRL_ENABLE (1 << 0) + +/* --- FPB_REMAP values ---------------------------------------------------- */ + +/* TODO */ + +/* --- FPB_COMPx values ---------------------------------------------------- */ + +#define FPB_COMP_REPLACE_REMAP (0x0 << 30) +#define FPB_COMP_REPLACE_BREAK_LOWER (0x1 << 30) +#define FPB_COMP_REPLACE_BREAK_UPPER (0x2 << 30) +#define FPB_COMP_REPLACE_BREAK_BOTH (0x3 << 30) +#define FPB_COMP_REPLACE_MASK (0x3 << 30) + +/* Bit 29: Reserved */ + +/* TODO */ + +/* Bit 1: Reserved */ + +#define FPB_COMP_ENABLE (1 << 0) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/itm.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/itm.h new file mode 100644 index 00000000..d549fc2f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/itm.h @@ -0,0 +1,88 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_ITM_H +#define LIBOPENCM3_CM3_ITM_H + +/* Cortex-M3 Instrumentation Trace Macrocell (ITM) */ + +/* Those defined only on ARMv7 and above */ +#if !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) +#error "Instrumentation Trace Macrocell not available in CM0" +#endif + +/* --- ITM registers ------------------------------------------------------- */ + +/* Stimulus Port x (ITM_STIM(x)) */ +#define ITM_STIM8(n) (MMIO8(ITM_BASE + ((n)*4))) +#define ITM_STIM16(n) (MMIO16(ITM_BASE + ((n)*4))) +#define ITM_STIM32(n) (MMIO32(ITM_BASE + ((n)*4))) + +/* Trace Enable ports (ITM_TER[x]) */ +#define ITM_TER (&MMIO32(ITM_BASE + 0xE00)) + +/* Trace Privilege (ITM_TPR) */ +#define ITM_TPR MMIO32(ITM_BASE + 0xE40) + +/* Trace Control (ITM_TCR) */ +#define ITM_TCR MMIO32(ITM_BASE + 0xE80) + +/* CoreSight Lock Status Register for this peripheral */ +#define ITM_LSR MMIO32(ITM_BASE + 0xFB4) +/* CoreSight Lock Access Register for this peripheral */ +#define ITM_LAR MMIO32(ITM_BASE + 0xFB0) + +/* TODO: PID, CID */ + +/* --- ITM_STIM values ----------------------------------------------------- */ + +/* Bits 31:0 - Write to port FIFO for forwarding as software event packet */ +/* Bits 31:1 - RAZ */ +#define ITM_STIM_FIFOREADY (1 << 0) + +/* --- ITM_TER values ------------------------------------------------------ */ + +/* Bits 31:0 - Stimulus port #N is enabled with STIMENA[N] is set */ + +/* --- ITM_TPR values ------------------------------------------------------ */ +/* + * Bits 31:0 - Bit [N] of PRIVMASK controls stimulus ports 8N to 8N+7 + * 0: User access allowed to stimulus ports + * 1: Privileged access only to stimulus ports + */ + +/* --- ITM_TCR values ------------------------------------------------------ */ + +/* Bits 31:24 - Reserved */ +#define ITM_TCR_BUSY (1 << 23) +#define ITM_TCR_TRACE_BUS_ID_MASK (0x3f << 16) +/* Bits 15:10 - Reserved */ +#define ITM_TCR_TSPRESCALE_NONE (0 << 8) +#define ITM_TCR_TSPRESCALE_DIV4 (1 << 8) +#define ITM_TCR_TSPRESCALE_DIV16 (2 << 8) +#define ITM_TCR_TSPRESCALE_DIV64 (3 << 8) +#define ITM_TCR_TSPRESCALE_MASK (3 << 8) +/* Bits 7:5 - Reserved */ +#define ITM_TCR_SWOENA (1 << 4) +#define ITM_TCR_TXENA (1 << 3) +#define ITM_TCR_SYNCENA (1 << 2) +#define ITM_TCR_TSENA (1 << 1) +#define ITM_TCR_ITMENA (1 << 0) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/memorymap.h new file mode 100644 index 00000000..55cec86a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/memorymap.h @@ -0,0 +1,85 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_MEMORYMAP_H +#define LIBOPENCM3_CM3_MEMORYMAP_H + +/* --- ARM Cortex-M0, M3 and M4 specific definitions ----------------------- */ + +/* Private peripheral bus - Internal */ +#define PPBI_BASE (0xE0000000U) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* ITM: Instrumentation Trace Macrocell */ +#define ITM_BASE (PPBI_BASE + 0x0000) + +/* DWT: Data Watchpoint and Trace unit */ +#define DWT_BASE (PPBI_BASE + 0x1000) + +/* FPB: Flash Patch and Breakpoint unit */ +#define FPB_BASE (PPBI_BASE + 0x2000) +#endif + +/* PPBI_BASE + 0x3000 (0xE000 3000 - 0xE000 DFFF): Reserved */ + +#define SCS_BASE (PPBI_BASE + 0xE000) + +/* PPBI_BASE + 0xF000 (0xE000 F000 - 0xE003 FFFF): Reserved */ + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +#define TPIU_BASE (PPBI_BASE + 0x40000) +#endif + +/* --- SCS: System Control Space --- */ + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* ITR: Interrupt Type Register */ +#define ITR_BASE (SCS_BASE + 0x0000) +#endif + +/* SYS_TICK: System Timer */ +#define SYS_TICK_BASE (SCS_BASE + 0x0010) + +/* NVIC: Nested Vector Interrupt Controller */ +#define NVIC_BASE (SCS_BASE + 0x0100) + +/* SCB: System Control Block */ +#define SCB_BASE (SCS_BASE + 0x0D00) + +/* MPU: Memory protection unit */ +#define MPU_BASE (SCS_BASE + 0x0D90) + +/* Those defined only on CM0*/ +#if defined(__ARM_ARCH_6M__) +/* DEBUG: Debug control and configuration */ +#define DEBUG_BASE (SCS_BASE + 0x0DF0) +#endif + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* STE: Software Trigger Interrupt Register */ +#define STIR_BASE (SCS_BASE + 0x0F00) +/* ID: ID space */ +#define ID_BASE (SCS_BASE + 0x0FD0) +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/mpu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/mpu.h new file mode 100644 index 00000000..3d6960af --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/mpu.h @@ -0,0 +1,143 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @defgroup CM3_mpu_defines MPU Defines + * + * @brief libopencm3 Cortex Memory Protection Unit + * + * @ingroup CM3_defines + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + * + * The MPU is available as an option in both ARMv6-M and ARMv7-M, but it has + * more features in v7, particularly in the available attributes. + * + * For more information see the ARM Architecture reference manuals. + */ +/**@{*/ + +#ifndef LIBOPENCM3_MPU_H +#define LIBOPENCM3_MPU_H + +#include +#include + +/* --- SCB: Registers ------------------------------------------------------ */ +/** @defgroup CM3_mpu_registers MPU Registers + * @ingroup CM3_mpu_defines + * + *@{*/ +/** MPU_TYPE is alays available, even if the MPU is not implemented */ +#define MPU_TYPE MMIO32(MPU_BASE + 0x00) +#define MPU_CTRL MMIO32(MPU_BASE + 0x04) +#define MPU_RNR MMIO32(MPU_BASE + 0x08) +#define MPU_RBAR MMIO32(MPU_BASE + 0x0C) +#define MPU_RASR MMIO32(MPU_BASE + 0x10) +/**@}*/ + +/* --- MPU values ---------------------------------------------------------- */ + +/** @defgroup CM3_mpu_type MPU TYPE register fields + * @ingroup CM3_mpu_defines + * The MPU_TYPE register is always available, even if the MPU is not implemented. + * In that case, the DREGION field will read as 0. + *@{*/ +/** v6m/v7m only support a unified MPU (IREGION always 0) */ +#define MPU_TYPE_IREGION_LSB 16 +#define MPU_TYPE_IREGION (0xFF << MPU_TYPE_IREGION_LSB) +/** DREGION is non zero if the MPU is available */ +#define MPU_TYPE_DREGION_LSB 8 +#define MPU_TYPE_DREGION (0xFF << MPU_TYPE_DREGION_LSB) +/** v6m/v7m only support a unifed MPU (Separate always 0) */ +#define MPU_TYPE_SEPARATE (1<<0) +/**@}*/ + +/** @defgroup CM3_mpu_ctrl MPU CTRL register fields + * @ingroup CM3_mpu_defines + * Defines for the Control Register. + *@{*/ +#define MPU_CTRL_PRIVDEFENA (1<<2) +#define MPU_CTRL_HFNMIENA (1<<1) +#define MPU_CTRL_ENABLE (1<<0) +/**@}*/ + +/** @defgroup CM3_mpu_rnr MPU RNR register fields + * @ingroup CM3_mpu_defines + * Defines for the Region Number Register. + *@{*/ +#define MPU_RNR_REGION_LSB 0 +#define MPU_RNR_REGION (0xFF << MPU_RNR_REGION_LSB) +/**@}*/ + +/** @defgroup CM3_mpu_rbar MPU RBAR register fields + * @ingroup CM3_mpu_defines + * Defines for the Region Base Address Register. + *@{*/ +/** minimum size supported is by writing all ones to ADDR, then reading back */ +#define MPU_RBAR_ADDR 0xFFFFFFE0 +#define MPU_RBAR_VALID (1<<4) +#define MPU_RBAR_REGION_LSB 0 +#define MPU_RBAR_REGION (0xF << MPU_RBAR_REGION_LSB) +/**@}*/ + +/** @defgroup CM3_mpu_rasr MPU RASR register fields + * @ingroup CM3_mpu_defines + * Defines for the Region Attribute and Size Register. + *@{*/ +#define MPU_RASR_ATTRS_LSB 16 +#define MPU_RASR_ATTRS (0xFFFF << MPU_RASR_ATTRS_LSB) +#define MPU_RASR_SRD_LSB 8 +#define MPU_RASR_SRD (0xFF << MPU_RASR_SRD_LSB) +#define MPU_RASR_SIZE_LSB 1 +#define MPU_RASR_SIZE (0x1F << MPU_RASR_SIZE_LSB) +#define MPU_RASR_ENABLE (1 << 0) + +/** @defgroup mpu_rasr_attributes MPU RASR Attributes + * @ingroup CM3_mpu_rasr + * Not all attributes are available on v6m. + * + *@{*/ +#define MPU_RASR_ATTR_XN (1 << 28) +#define MPU_RASR_ATTR_AP (7 << 24) +#define MPU_RASR_ATTR_AP_PNO_UNO (0 << 24) +#define MPU_RASR_ATTR_AP_PRW_UNO (1 << 24) +#define MPU_RASR_ATTR_AP_PRW_URO (2 << 24) +#define MPU_RASR_ATTR_AP_PRW_URW (3 << 24) +#define MPU_RASR_ATTR_AP_PRO_UNO (5 << 24) +#define MPU_RASR_ATTR_AP_PRO_URO (6 << 24) +#define MPU_RASR_ATTR_TEX (7 << 19) +#define MPU_RASR_ATTR_S (1 << 18) +#define MPU_RASR_ATTR_C (1 << 17) +#define MPU_RASR_ATTR_B (1 << 16) +#define MPU_RASR_ATTR_SCB (7 << 16) +/**@}*/ +/**@}*/ + +/* --- MPU functions ------------------------------------------------------- */ + +BEGIN_DECLS + + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scb.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scb.h new file mode 100644 index 00000000..416ff963 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scb.h @@ -0,0 +1,450 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SCB_H +#define LIBOPENCM3_SCB_H + +#include +#include + +/* --- SCB: Registers ------------------------------------------------------ */ + +/* CPUID: CPUID base register */ +#define SCB_CPUID MMIO32(SCB_BASE + 0x00) + +/* ICSR: Interrupt Control State Register */ +#define SCB_ICSR MMIO32(SCB_BASE + 0x04) + +/* VTOR: Vector Table Offset Register */ +#define SCB_VTOR MMIO32(SCB_BASE + 0x08) + +/* AIRCR: Application Interrupt and Reset Control Register */ +#define SCB_AIRCR MMIO32(SCB_BASE + 0x0C) + +/* SCR: System Control Register */ +#define SCB_SCR MMIO32(SCB_BASE + 0x10) + +/* CCR: Configuration Control Register */ +#define SCB_CCR MMIO32(SCB_BASE + 0x14) + +/* SHP: System Handler Priority Registers */ +/* Note: 12 8bit registers */ +#define SCB_SHPR(shpr_id) MMIO8(SCB_BASE + 0x18 + (shpr_id)) +#define SCB_SHPR1 MMIO32(SCB_BASE + 0x18) +#define SCB_SHPR2 MMIO32(SCB_BASE + 0x1C) +#define SCB_SHPR3 MMIO32(SCB_BASE + 0x20) + +/* SHCSR: System Handler Control and State Register */ +#define SCB_SHCSR MMIO32(SCB_BASE + 0x24) + +/* DFSR: Debug Fault Status Register */ +#define SCB_DFSR MMIO32(SCB_BASE + 0x30) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* CFSR: Configurable Fault Status Registers */ +#define SCB_CFSR MMIO32(SCB_BASE + 0x28) + +/* HFSR: Hard Fault Status Register */ +#define SCB_HFSR MMIO32(SCB_BASE + 0x2C) + +/* MMFAR: Memory Manage Fault Address Register */ +#define SCB_MMFAR MMIO32(SCB_BASE + 0x34) + +/* BFAR: Bus Fault Address Register */ +#define SCB_BFAR MMIO32(SCB_BASE + 0x38) + +/* AFSR: Auxiliary Fault Status Register */ +#define SCB_AFSR MMIO32(SCB_BASE + 0x3C) + +/* ID_PFR0: Processor Feature Register 0 */ +#define SCB_ID_PFR0 MMIO32(SCB_BASE + 0x40) + +/* ID_PFR1: Processor Feature Register 1 */ +#define SCB_ID_PFR1 MMIO32(SCB_BASE + 0x44) + +/* ID_DFR0: Debug Features Register 0 */ +#define SCB_ID_DFR0 MMIO32(SCB_BASE + 0x48) + +/* ID_AFR0: Auxiliary Features Register 0 */ +#define SCB_ID_AFR0 MMIO32(SCB_BASE + 0x4C) + +/* ID_MMFR0: Memory Model Feature Register 0 */ +#define SCB_ID_MMFR0 MMIO32(SCB_BASE + 0x50) + +/* ID_MMFR1: Memory Model Feature Register 1 */ +#define SCB_ID_MMFR1 MMIO32(SCB_BASE + 0x54) + +/* ID_MMFR2: Memory Model Feature Register 2 */ +#define SCB_ID_MMFR2 MMIO32(SCB_BASE + 0x58) + +/* ID_MMFR3: Memory Model Feature Register 3 */ +#define SCB_ID_MMFR3 MMIO32(SCB_BASE + 0x5C) + +/* ID_ISAR0: Instruction Set Attributes Register 0 */ +#define SCB_ID_ISAR0 MMIO32(SCB_BASE + 0x60) + +/* ID_ISAR1: Instruction Set Attributes Register 1 */ +#define SCB_ID_ISAR1 MMIO32(SCB_BASE + 0x64) + +/* ID_ISAR2: Instruction Set Attributes Register 2 */ +#define SCB_ID_ISAR2 MMIO32(SCB_BASE + 0x68) + +/* ID_ISAR3: Instruction Set Attributes Register 3 */ +#define SCB_ID_ISAR3 MMIO32(SCB_BASE + 0x6C) + +/* ID_ISAR4: Instruction Set Attributes Register 4 */ +#define SCB_ID_ISAR4 MMIO32(SCB_BASE + 0x70) + +/* CPACR: Coprocessor Access Control Register */ +#define SCB_CPACR MMIO32(SCB_BASE + 0x88) + +/* FPCCR: Floating-Point Context Control Register */ +#define SCB_FPCCR MMIO32(SCB_BASE + 0x234) + +/* FPCAR: Floating-Point Context Address Register */ +#define SCB_FPCAR MMIO32(SCB_BASE + 0x238) + +/* FPDSCR: Floating-Point Default Status Control Register */ +#define SCB_FPDSCR MMIO32(SCB_BASE + 0x23C) + +/* MVFR0: Media and Floating-Point Feature Register 0 */ +#define SCB_MVFR0 MMIO32(SCB_BASE + 0x240) + +/* MVFR1: Media and Floating-Point Feature Register 1 */ +#define SCB_MVFR1 MMIO32(SCB_BASE + 0x244) +#endif + +/* --- SCB values ---------------------------------------------------------- */ + +/* --- SCB_CPUID values ---------------------------------------------------- */ + +/* Implementer[31:24]: Implementer code */ +#define SCB_CPUID_IMPLEMENTER_LSB 24 +#define SCB_CPUID_IMPLEMENTER (0xFF << SCB_CPUID_IMPLEMENTER_LSB) +/* Variant[23:20]: Variant number */ +#define SCB_CPUID_VARIANT_LSB 20 +#define SCB_CPUID_VARIANT (0xF << SCB_CPUID_VARIANT_LSB) +/* Constant[19:16]: Reads as 0xF (ARMv7-M) M3, M4 */ +/* Constant[19:16]: Reads as 0xC (ARMv6-M) M0, M0+ */ +#define SCB_CPUID_CONSTANT_LSB 16 +#define SCB_CPUID_CONSTANT (0xF << SCB_CPUID_CONSTANT_LSB) +#define SCB_CPUID_CONSTANT_ARMV6 (0xC << SCB_CPUID_CONSTANT_LSB) +#define SCB_CPUID_CONSTANT_ARMV7 (0xF << SCB_CPUID_CONSTANT_LSB) + +/* PartNo[15:4]: Part number of the processor */ +#define SCB_CPUID_PARTNO_LSB 4 +#define SCB_CPUID_PARTNO (0xFFF << SCB_CPUID_PARTNO_LSB) +/* Revision[3:0]: Revision number */ +#define SCB_CPUID_REVISION_LSB 0 +#define SCB_CPUID_REVISION (0xF << SCB_CPUID_REVISION_LSB) + +/* --- SCB_ICSR values ----------------------------------------------------- */ + +/* NMIPENDSET: NMI set-pending bit */ +#define SCB_ICSR_NMIPENDSET (1 << 31) +/* Bits [30:29]: reserved - must be kept cleared */ +/* PENDSVSET: PendSV set-pending bit */ +#define SCB_ICSR_PENDSVSET (1 << 28) +/* PENDSVCLR: PendSV clear-pending bit */ +#define SCB_ICSR_PENDSVCLR (1 << 27) +/* PENDSTSET: SysTick exception set-pending bit */ +#define SCB_ICSR_PENDSTSET (1 << 26) +/* PENDSTCLR: SysTick exception clear-pending bit */ +#define SCB_ICSR_PENDSTCLR (1 << 25) +/* Bit 24: reserved - must be kept cleared */ +/* Bit 23: reserved for debug - reads as 0 when not in debug mode */ +#define SCB_ICSR_ISRPREEMPT (1 << 23) +/* ISRPENDING: Interrupt pending flag, excluding NMI and Faults */ +#define SCB_ICSR_ISRPENDING (1 << 22) +/* VECTPENDING[21:12] Pending vector */ +#define SCB_ICSR_VECTPENDING_LSB 12 +#define SCB_ICSR_VECTPENDING (0x1FF << SCB_ICSR_VECTPENDING_LSB) +/* RETOBASE: Return to base level */ +#define SCB_ICSR_RETOBASE (1 << 11) +/* Bits [10:9]: reserved - must be kept cleared */ +/* VECTACTIVE[8:0] Active vector */ +#define SCB_ICSR_VECTACTIVE_LSB 0 +#define SCB_ICSR_VECTACTIVE (0x1FF << SCB_ICSR_VECTACTIVE_LSB) + + +/* --- SCB_VTOR values ----------------------------------------------------- */ + +/* IMPLEMENTATION DEFINED */ + +#if defined(__ARM_ARCH_6M__) + +#define SCB_VTOR_TBLOFF_LSB 7 +#define SCB_VTOR_TBLOFF (0x1FFFFFF << SCB_VTOR_TBLOFF_LSB) + +#elif defined(CM1) +/* VTOR not defined there */ + +#elif defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +/* Bits [31:30]: reserved - must be kept cleared */ +/* TBLOFF[29:9]: Vector table base offset field */ +/* inconsistent datasheet - LSB could be 11 */ +/* BUG: TBLOFF is in the ARMv6 Architecture reference manual defined from b7 */ +#define SCB_VTOR_TBLOFF_LSB 9 +#define SCB_VTOR_TBLOFF (0x7FFFFF << SCB_VTOR_TBLOFF_LSB) + +#endif + +/* --- SCB_AIRCR values ---------------------------------------------------- */ + +/* VECTKEYSTAT[31:16]/ VECTKEY[31:16] Register key */ +#define SCB_AIRCR_VECTKEYSTAT_LSB 16 +#define SCB_AIRCR_VECTKEYSTAT (0xFFFF << SCB_AIRCR_VECTKEYSTAT_LSB) +#define SCB_AIRCR_VECTKEY (0x05FA << SCB_AIRCR_VECTKEYSTAT_LSB) + +/* ENDIANNESS Data endianness bit */ +#define SCB_AIRCR_ENDIANESS (1 << 15) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* Bits [14:11]: reserved - must be kept cleared */ +/* PRIGROUP[10:8]: Interrupt priority grouping field */ +#define SCB_AIRCR_PRIGROUP_GROUP16_NOSUB (0x3 << 8) +#define SCB_AIRCR_PRIGROUP_GROUP8_SUB2 (0x4 << 8) +#define SCB_AIRCR_PRIGROUP_GROUP4_SUB4 (0x5 << 8) +#define SCB_AIRCR_PRIGROUP_GROUP2_SUB8 (0x6 << 8) +#define SCB_AIRCR_PRIGROUP_NOGROUP_SUB16 (0x7 << 8) +#define SCB_AIRCR_PRIGROUP_MASK (0x7 << 8) +#define SCB_AIRCR_PRIGROUP_SHIFT 8 +/* Bits [7:3]: reserved - must be kept cleared */ +#endif + +/* SYSRESETREQ System reset request */ +#define SCB_AIRCR_SYSRESETREQ (1 << 2) +/* VECTCLRACTIVE */ +#define SCB_AIRCR_VECTCLRACTIVE (1 << 1) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* VECTRESET */ +#define SCB_AIRCR_VECTRESET (1 << 0) +#endif + +/* --- SCB_SCR values ------------------------------------------------------ */ + +/* Bits [31:5]: reserved - must be kept cleared */ +/* SEVONPEND Send Event on Pending bit */ +#define SCB_SCR_SEVONPEND (1 << 4) +/* Bit 3: reserved - must be kept cleared */ +/* SLEEPDEEP */ +#define SCB_SCR_SLEEPDEEP (1 << 2) +/* SLEEPONEXIT */ +#define SCB_SCR_SLEEPONEXIT (1 << 1) +/* Bit 0: reserved - must be kept cleared */ + +/* --- SCB_CCR values ------------------------------------------------------ */ + +/* Bits [31:10]: reserved - must be kept cleared */ +/* STKALIGN */ +#define SCB_CCR_STKALIGN (1 << 9) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* BFHFNMIGN */ +#define SCB_CCR_BFHFNMIGN (1 << 8) +/* Bits [7:5]: reserved - must be kept cleared */ +/* DIV_0_TRP */ +#define SCB_CCR_DIV_0_TRP (1 << 4) +#endif + +/* UNALIGN_TRP */ +#define SCB_CCR_UNALIGN_TRP (1 << 3) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* Bit 2: reserved - must be kept cleared */ +/* USERSETMPEND */ +#define SCB_CCR_USERSETMPEND (1 << 1) +/* NONBASETHRDENA */ +#define SCB_CCR_NONBASETHRDENA (1 << 0) +#endif + +/* These numbers are designed to be used with the SCB_SHPR() macro */ +/* SCB_SHPR1 */ +#define SCB_SHPR_PRI_4_MEMMANAGE 0 +#define SCB_SHPR_PRI_5_BUSFAULT 1 +#define SCB_SHPR_PRI_6_USAGEFAULT 2 +#define SCB_SHPR_PRI_7_RESERVED 3 +/* SCB_SHPR2 */ +#define SCB_SHPR_PRI_8_RESERVED 4 +#define SCB_SHPR_PRI_9_RESERVED 5 +#define SCB_SHPR_PRI_10_RESERVED 6 +#define SCB_SHPR_PRI_11_SVCALL 7 +/* SCB_SHPR3 */ +#define SCB_SHPR_PRI_12_RESERVED 8 +#define SCB_SHPR_PRI_13_RESERVED 9 +#define SCB_SHPR_PRI_14_PENDSV 10 +#define SCB_SHPR_PRI_15_SYSTICK 11 + +/* --- SCB_SHCSR values ---------------------------------------------------- */ + +/* Bits [31:19]: reserved - must be kept cleared */ + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* USGFAULTENA: Usage fault enable */ +#define SCB_SHCSR_USGFAULTENA (1 << 18) +/* BUSFAULTENA: Bus fault enable */ +#define SCB_SHCSR_BUSFAULTENA (1 << 17) +/* MEMFAULTENA: Memory management fault enable */ +#define SCB_SHCSR_MEMFAULTENA (1 << 16) +#endif + +/* SVCALLPENDED: SVC call pending */ +#define SCB_SHCSR_SVCALLPENDED (1 << 15) + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/* BUSFAULTPENDED: Bus fault exception pending */ +#define SCB_SHCSR_BUSFAULTPENDED (1 << 14) +/* MEMFAULTPENDED: Memory management fault exception pending */ +#define SCB_SHCSR_MEMFAULTPENDED (1 << 13) +/* USGFAULTPENDED: Usage fault exception pending */ +#define SCB_SHCSR_USGFAULTPENDED (1 << 12) +/* SYSTICKACT: SysTick exception active */ +#define SCB_SHCSR_SYSTICKACT (1 << 11) +/* PENDSVACT: PendSV exception active */ +#define SCB_SHCSR_PENDSVACT (1 << 10) +/* Bit 9: reserved - must be kept cleared */ +/* MONITORACT: Debug monitor active */ +#define SCB_SHCSR_MONITORACT (1 << 8) +/* SVCALLACT: SVC call active */ +#define SCB_SHCSR_SVCALLACT (1 << 7) +/* Bits [6:4]: reserved - must be kept cleared */ +/* USGFAULTACT: Usage fault exception active */ +#define SCB_SHCSR_USGFAULTACT (1 << 3) +/* Bit 2: reserved - must be kept cleared */ +/* BUSFAULTACT: Bus fault exception active */ +#define SCB_SHCSR_BUSFAULTACT (1 << 1) +/* MEMFAULTACT: Memory management fault exception active */ +#define SCB_SHCSR_MEMFAULTACT (1 << 0) + +/* --- SCB_CFSR values ----------------------------------------------------- */ + +/* Bits [31:26]: reserved - must be kept cleared */ +/* DIVBYZERO: Divide by zero usage fault */ +#define SCB_CFSR_DIVBYZERO (1 << 25) +/* UNALIGNED: Unaligned access usage fault */ +#define SCB_CFSR_UNALIGNED (1 << 24) +/* Bits [23:20]: reserved - must be kept cleared */ +/* NOCP: No coprocessor usage fault */ +#define SCB_CFSR_NOCP (1 << 19) +/* INVPC: Invalid PC load usage fault */ +#define SCB_CFSR_INVPC (1 << 18) +/* INVSTATE: Invalid state usage fault */ +#define SCB_CFSR_INVSTATE (1 << 17) +/* UNDEFINSTR: Undefined instruction usage fault */ +#define SCB_CFSR_UNDEFINSTR (1 << 16) +/* BFARVALID: Bus Fault Address Register (BFAR) valid flag */ +#define SCB_CFSR_BFARVALID (1 << 15) +/* Bits [14:13]: reserved - must be kept cleared */ +/* STKERR: Bus fault on stacking for exception entry */ +#define SCB_CFSR_STKERR (1 << 12) +/* UNSTKERR: Bus fault on unstacking for a return from exception */ +#define SCB_CFSR_UNSTKERR (1 << 11) +/* IMPRECISERR: Imprecise data bus error */ +#define SCB_CFSR_IMPRECISERR (1 << 10) +/* PRECISERR: Precise data bus error */ +#define SCB_CFSR_PRECISERR (1 << 9) +/* IBUSERR: Instruction bus error */ +#define SCB_CFSR_IBUSERR (1 << 8) +/* MMARVALID: Memory Management Fault Address Register (MMAR) valid flag */ +#define SCB_CFSR_MMARVALID (1 << 7) +/* Bits [6:5]: reserved - must be kept cleared */ +/* MSTKERR: Memory manager fault on stacking for exception entry */ +#define SCB_CFSR_MSTKERR (1 << 4) +/* MUNSTKERR: Memory manager fault on unstacking for a return from exception */ +#define SCB_CFSR_MUNSTKERR (1 << 3) +/* Bit 2: reserved - must be kept cleared */ +/* DACCVIOL: Data access violation flag */ +#define SCB_CFSR_DACCVIOL (1 << 1) +/* IACCVIOL: Instruction access violation flag */ +#define SCB_CFSR_IACCVIOL (1 << 0) + +/* --- SCB_HFSR values ----------------------------------------------------- */ + +/* DEBUG_VT: reserved for debug use */ +#define SCB_HFSR_DEBUG_VT (1 << 31) +/* FORCED: Forced hard fault */ +#define SCB_HFSR_FORCED (1 << 30) +/* Bits [29:2]: reserved - must be kept cleared */ +/* VECTTBL: Vector table hard fault */ +#define SCB_HFSR_VECTTBL (1 << 1) +/* Bit 0: reserved - must be kept cleared */ + +/* --- SCB_MMFAR values ---------------------------------------------------- */ + +/* MMFAR [31:0]: Memory management fault address */ + +/* --- SCB_BFAR values ----------------------------------------------------- */ + +/* BFAR [31:0]: Bus fault address */ + +/* --- SCB_CPACR values ---------------------------------------------------- */ + +/* CPACR CPn: Access privileges values */ +#define SCB_CPACR_NONE 0 /* Access denied */ +#define SCB_CPACR_PRIV 1 /* Privileged access only */ +#define SCB_CPACR_FULL 3 /* Full access */ + +/* CPACR [20:21]: Access privileges for coprocessor 10 */ +#define SCB_CPACR_CP10 (1 << 20) +/* CPACR [22:23]: Access privileges for coprocessor 11 */ +#define SCB_CPACR_CP11 (1 << 22) +#endif + +/* --- SCB functions ------------------------------------------------------- */ + +BEGIN_DECLS + +struct scb_exception_stack_frame { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t xpsr; +} __attribute__((packed)); + +#define SCB_GET_EXCEPTION_STACK_FRAME(f) \ + do { \ + asm volatile ("mov %[frameptr], sp" \ + : [frameptr]"=r" (f)); \ + } while (0) + +void scb_reset_system(void) __attribute__((noreturn, naked)); + +/* Those defined only on ARMv7 and above */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +void scb_reset_core(void) __attribute__((noreturn, naked)); +void scb_set_priority_grouping(uint32_t prigroup); +#endif + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scs.h new file mode 100644 index 00000000..b4801549 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/scs.h @@ -0,0 +1,350 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * Copyright (C) 2012 Benjamin Vernoux + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_SCS_H +#define LIBOPENCM3_CM3_SCS_H + +/* + * All the definition hereafter are generic for CortexMx ARMv7-M + * See ARM document "ARMv7-M Architecture Reference Manual" for more details. + * See also ARM document "ARM Compiler toolchain Developing Software for ARM + * Processors" for details on System Timer/SysTick. + */ + +/* + * The System Control Space (SCS) is a memory-mapped 4KB address space that + * provides 32-bit registers for configuration, status reporting and control. + * The SCS registers divide into the following groups: + * - system control and identification + * - the CPUID processor identification space + * - system configuration and status + * - fault reporting + * - a system timer, SysTick + * - a Nested Vectored Interrupt Controller (NVIC) + * - a Protected Memory System Architecture (PMSA) + * - system debug. + */ + +/* System Handler Priority 8 bits Registers, SHPR1/2/3 */ +/* Note: 12 8bit Registers */ +#define SCS_SHPR(ipr_id) MMIO8(SCS_BASE + 0xD18 + (ipr_id)) + +/* + * Debug Halting Control and Status Register (DHCSR). + * + * Purpose Controls halting debug. + * Usage constraints: The effect of modifying the C_STEP or C_MASKINTS bit when + * the system is running with halting debug enabled is UNPREDICTABLE. + * Halting debug is enabled when C_DEBUGEN is set to 1. The system is running + * when S_HALT is set to 0. + * - When C_DEBUGEN is set to 0, the processor ignores the values of all other + * bits in this register. + * - For more information about the use of DHCSR see Debug stepping on page + * C1-824. + * Configurations Always implemented. + */ +/* SCS_DHCSR register */ +#define SCS_DHCSR MMIO32(SCS_BASE + 0xDF0) +/* + * Debug Core Register Selector Register (DCRSR). + * + * Purpose With the DCRDR, the DCRSR provides debug access to the ARM core + * registers, special-purpose registers, and Floating-point extension + * registers. A write to DCRSR specifies the register to transfer, whether the + * transfer is a read or a write, and starts the transfer. + * Usage constraints: Only accessible in Debug state. + * Configurations Always implemented. + * + */ +/* SCS_DCRS register */ +#define SCS_DCRSR MMIO32(SCS_BASE + 0xDF4) +/* + * Debug Core Register Data Register (DCRDR) + * + * Purpose With the DCRSR, see Debug Core Register Selector Register, the DCRDR + * provides debug access to the ARM core registers, special-purpose registers, + * and Floating-point extension registers. The DCRDR is the data register for + * these accesses. + * - Used on its own, the DCRDR provides a message passing resource between an + * external debugger and a debug agent running on the processor. + * Note: + * The architecture does not define any handshaking mechanism for this use of + * DCRDR. + * Usage constraints: See Use of DCRSR and DCRDR for constraints that apply to + * particular transfers using the DCRSR and DCRDR. + * Configurations Always implemented. + * + */ +/* SCS_DCRDR register */ +#define SCS_DCRDR MMIO32(SCS_BASE + 0xDF8) +/* + * Debug Exception and Monitor Control Register (DEMCR). + * + * Purpose Manages vector catch behavior and DebugMonitor handling when + * debugging. + * Usage constraints: + * - Bits [23:16] provide DebugMonitor exception control. + * - Bits [15:0] provide Debug state, halting debug, control. + * Configurations Always implemented. + * + */ +/* SCS_DEMCR register */ +#define SCS_DEMCR MMIO32(SCS_BASE + 0xDFC) + +/* Debug Halting Control and Status Register (DHCSR) */ +#define SCS_DHCSR_DBGKEY 0xA05F0000 +#define SCS_DHCSR_C_DEBUGEN 0x00000001 +#define SCS_DHCSR_C_HALT 0x00000002 +#define SCS_DHCSR_C_STEP 0x00000004 +#define SCS_DHCSR_C_MASKINTS 0x00000008 +#define SCS_DHCSR_C_SNAPSTALL 0x00000020 +#define SCS_DHCSR_S_REGRDY 0x00010000 +#define SCS_DHCSR_S_HALT 0x00020000 +#define SCS_DHCSR_S_SLEEP 0x00040000 +#define SCS_DHCSR_S_LOCKUP 0x00080000 +#define SCS_DHCSR_S_RETIRE_ST 0x01000000 +#define SCS_DHCSR_S_RESET_ST 0x02000000 + +/* Debug Core Register Selector Register (DCRSR) */ +#define SCS_DCRSR_REGSEL_MASK 0x0000001F +#define SCS_DCRSR_REGSEL_XPSR 0x00000010 +#define SCS_DCRSR_REGSEL_MSP 0x00000011 +#define SCS_DCRSR_REGSEL_PSP 0x00000012 + +/* Debug Exception and Monitor Control Register (DEMCR) */ +/* Bits 31:25 - Reserved */ +#define SCS_DEMCR_TRCENA (1 << 24) +/* Bits 23:20 - Reserved */ +#define SCS_DEMCR_MON_REQ (1 << 19) +#define SCS_DEMCR_MON_STEP (1 << 18) +#define SCS_DEMCR_VC_MON_PEND (1 << 17) +#define SCS_DEMCR_VC_MON_EN (1 << 16) +/* Bits 15:11 - Reserved */ +#define SCS_DEMCR_VC_HARDERR (1 << 10) +#define SCS_DEMCR_VC_INTERR (1 << 9) +#define SCS_DEMCR_VC_BUSERR (1 << 8) +#define SCS_DEMCR_VC_STATERR (1 << 7) +#define SCS_DEMCR_VC_CHKERR (1 << 6) +#define SCS_DEMCR_VC_NOCPERR (1 << 5) +#define SCS_DEMCR_VC_MMERR (1 << 4) +/* Bits 3:1 - Reserved */ +#define SCS_DEMCR_VC_CORERESET (1 << 0) + +/* + * System Control Space (SCS) => System timer register support in the SCS. + * To configure SysTick, load the interval required between SysTick events to + * the SysTick Reload Value register. The timer interrupt, or COUNTFLAG bit in + * the SysTick Control and Status register, is activated on the transition from + * 1 to 0, therefore it activates every n+1 clock ticks. If you require a + * period of 100, write 99 to the SysTick Reload Value register. The SysTick + * Reload Value register supports values between 0x1 and 0x00FFFFFF. + * + * If you want to use SysTick to generate an event at a timed interval, for + * example 1ms, you can use the SysTick Calibration Value Register to scale + * your value for the Reload register. The SysTick Calibration Value Register + * is a read-only register that contains the number of pulses for a period of + * 10ms, in the TENMS field, bits[23:0]. + * + * This register also has a SKEW bit. Bit[30] == 1 indicates that the + * calibration for 10ms in the TENMS section is not exactly 10ms due to clock + * frequency. Bit[31] == 1 indicates that the reference clock is not provided. + */ +/* + * SysTick Control and Status Register (CSR). + * Purpose Controls the system timer and provides status data. + * Usage constraints: There are no usage constraints. + * Configurations Always implemented. +*/ +#define SCS_SYST_CSR MMIO32(SCS_BASE + 0x10) + +/* SysTick Reload Value Register (CVR). + * Purpose Reads or clears the current counter value. + * Usage constraints: + * - Any write to the register clears the register to zero. + * - The counter does not provide read-modify-write protection. + * - Unsupported bits are read as zero + * Configurations Always implemented. + */ +#define CM_SCS_SYST_RVR MMIO32(SCS_BASE + 0x14) + +/* SysTick Current Value Register (RVR). + * Purpose Holds the reload value of the SYST_CVR. + * Usage constraints There are no usage constraints. + * Configurations Always implemented. + */ +#define CM_SCS_SYST_CVR MMIO32(SCS_BASE + 0x18) + +/* + * SysTick Calibration value Register(Read Only) (CALIB) + * Purpose Reads the calibration value and parameters for SysTick. + * Usage constraints: There are no usage constraints. + * Configurations Always implemented. + */ +#define CM_SCS_SYST_CALIB MMIO32(SCS_BASE + 0x1C) + +/* --- SCS_SYST_CSR values ----------------------------------------------- */ +/* Counter is operating. */ +#define SCS_SYST_CSR_ENABLE (BIT0) +/* Count to 0 changes the SysTick exception status to pending. */ +#define SCS_SYST_CSR_TICKINT (BIT1) +/* SysTick uses the processor clock. */ +#define SCS_SYST_CSR_CLKSOURCE (BIT2) +/* + * Indicates whether the counter has counted to 0 since the last read of this + * register: + * 0 = Timer has not counted to 0 + * 1 = Timer has counted to 0. + */ +#define SCS_SYST_CSR_COUNTFLAG (BIT16) + +/* --- CM_SCS_SYST_RVR values ---------------------------------------------- */ +/* Bit 0 to 23 => RELOAD The value to load into the SYST_CVR when the counter + * reaches 0. + */ +/* Bit 24 to 31 are Reserved */ + +/* --- CM_SCS_SYST_CVR values ---------------------------------------------- */ +/* Bit0 to 31 => Reads or clears the current counter value. */ + +/* --- CM_SCS_SYST_CALIB values -------------------------------------------- */ +/* + * Bit0 to 23 => TENMS Optionally, holds a reload value to be used for 10ms + * (100Hz) timing, subject to system clock skew errors. If this field is zero, + * the calibration value is not known. + */ +#define SCS_SYST_SYST_CALIB_TENMS_MASK (BIT24-1) + +/* + * Bit30 => SKEW Indicates whether the 10ms calibration value is exact: + * 0 = 10ms calibration value is exact. + * 1 = 10ms calibration value is inexact, because of the clock frequency + */ +#define SCS_SYST_SYST_CALIB_VALUE_INEXACT (BIT30) +/* + * Bit31 => NOREF Indicates whether the IMPLEMENTATION DEFINED reference clock + * is implemented: + * 0 = The reference clock is implemented. + * 1 = The reference clock is not implemented. + * When this bit is 1, the CLKSOURCE bit of the SYST_CSR register is forced to + * 1 and cannot be cleared to 0. + */ +#define SCS_SYST_SYST_CALIB_REF_NOT_IMPLEMENTED (BIT31) + +/* + * System Control Space (SCS) => Data Watchpoint and Trace (DWT). + * See "ARMv7-M Architecture Reference Manual" + * (https://github.com/libopencm3/libopencm3-archive/blob/master/arm/ + * ARMv7-M_ARM.pdf) + * The DWT is an optional debug unit that provides watchpoints, data tracing, + * and system profiling for the processor. + */ +/* + * DWT Control register + * Purpose Provides configuration and status information for the DWT block, and + * used to control features of the block + * Usage constraints: There are no usage constraints. + * Configurations Always implemented. + */ +#define SCS_DWT_CTRL MMIO32(DWT_BASE + 0x00) +/* + * DWT_CYCCNT register + * Cycle Count Register (Shows or sets the value of the processor cycle + * counter, CYCCNT) + * When enabled, CYCCNT increments on each processor clock cycle. On overflow, + * CYCCNT wraps to zero. + * + * Purpose Shows or sets the value of the processor cycle counter, CYCCNT. + * Usage constraints: The DWT unit suspends CYCCNT counting when the processor + * is in Debug state. + * Configurations Implemented: only when DWT_CTRL.NOCYCCNT is RAZ, see Control + * register, DWT_CTRL. + * When DWT_CTRL.NOCYCCNT is RAO no cycle counter is implemented and this + * register is UNK/SBZP. +*/ +#define SCS_DWT_CYCCNT MMIO32(DWT_BASE + 0x04) + +/* DWT_CPICNT register + * Purpose Counts additional cycles required to execute multi-cycle + * instructions and instruction fetch stalls. + * Usage constraints: The counter initializes to 0 when software enables its + * counter overflow event by + * setting the DWT_CTRL.CPIEVTENA bit to 1. + * Configurations Implemented: only when DWT_CTRL.NOPRFCNT is RAZ, see Control + * register, DWT_CTRL. + * If DWT_CTRL.NOPRFCNT is RAO, indicating that the implementation does not + * include the profiling counters, this register is UNK/SBZP. + */ +#define SCS_DWT_CPICNT MMIO32(DWT_BASE + 0x08) + +/* DWT_EXCCNT register */ +#define SCS_DWT_EXCCNT MMIO32(DWT_BASE + 0x0C) + +/* DWT_EXCCNT register */ +#define SCS_DWT_SLEEPCNT MMIO32(DWT_BASE + 0x10) + +/* DWT_EXCCNT register */ +#define SCS_DWT_LSUCNT MMIO32(DWT_BASE + 0x14) + +/* DWT_EXCCNT register */ +#define SCS_DWT_FOLDCNT MMIO32(DWT_BASE + 0x18) + +/* DWT_PCSR register */ +#define SCS_DWT_PCSR MMIO32(DWT_BASE + 0x18) + +/* CoreSight Lock Status Register for this peripheral */ +#define SCS_DWT_LSR MMIO32(SCS_DWT_BASE + 0xFB4) +/* CoreSight Lock Access Register for this peripheral */ +#define SCS_DWT_LAR MMIO32(SCS_DWT_BASE + 0xFB0) + +/* --- SCS_DWT_CTRL values ------------------------------------------------- */ +/* + * Enables CYCCNT: + * 0 = Disabled, 1 = Enabled + * This bit is UNK/SBZP if the NOCYCCNT bit is RAO. + */ +#define SCS_DWT_CTRL_CYCCNTENA (BIT0) + +/* CoreSight Lock Status Register lock status bit */ +#define SCS_LSR_SLK (1<<1) +/* CoreSight Lock Status Register lock availability bit */ +#define SCS_LSR_SLI (1<<0) +/* CoreSight Lock Access key, common for all */ +#define SCS_LAR_KEY 0xC5ACCE55 + +/* TODO bit definition values for other DWT_XXX register */ + +/* Macro to be called at startup to enable SCS & Cycle Counter */ +#define SCS_DWT_CYCLE_COUNTER_ENABLED() ((SCS_DEMCR |= SCS_DEMCR_TRCENA)\ + (SCS_DWT_CTRL |= SCS_DWT_CTRL_CYCCNTENA)) + +#define SCS_SYSTICK_DISABLED() (SCS_SYST_CSR = 0) + +/* Macro to be called at startup to Enable CortexMx SysTick (but IRQ not + * enabled) + */ +#define SCS_SYSTICK_ENABLED() (SCS_SYST_CSR = (SCS_SYST_CSR_ENABLE | \ + SCS_SYST_CSR_CLKSOURCE)) + +/* Macro to be called at startup to Enable CortexMx SysTick and IRQ */ +#define SCS_SYSTICK_AND_IRQ_ENABLED() (SCS_SYST_CSR = (SCS_SYST_CSR_ENABLE | \ + SCS_SYST_CSR_CLKSOURCE | \ + SCS_SYST_CSR_TICKINT)) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/sync.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/sync.h new file mode 100644 index 00000000..6937ac63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/sync.h @@ -0,0 +1,59 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_SYNC_H +#define LIBOPENCM3_CM3_SYNC_H + +#include "common.h" + +BEGIN_DECLS + +void __dmb(void); + +/* Implements synchronisation primitives as discussed in the ARM document + * DHT0008A (ID081709) "ARM Synchronization Primitives" and the ARM v7-M + * Architecture Reference Manual. +*/ + +/* --- Exclusive load and store instructions ------------------------------- */ + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +uint32_t __ldrex(volatile uint32_t *addr); +uint32_t __strex(uint32_t val, volatile uint32_t *addr); + +/* --- Convenience functions ----------------------------------------------- */ + +/* Here we implement some simple synchronisation primitives. */ + +typedef uint32_t mutex_t; + +#define MUTEX_UNLOCKED 0 +#define MUTEX_LOCKED 1 + +void mutex_lock(mutex_t *m); +uint32_t mutex_trylock(mutex_t *m); +void mutex_unlock(mutex_t *m); + +#endif + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/systick.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/systick.h new file mode 100644 index 00000000..a355b0f8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/systick.h @@ -0,0 +1,134 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Benjamin Vernoux + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/** @defgroup CM3_systick_defines SysTick Defines + * + * @brief libopencm3 Defined Constants and Types for the Cortex SysTick + * + * @ingroup CM3_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 Thomas Otto + * + * @date 19 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/** + * @note this file has been not following the register naming scheme, the + * correct names defined, and the old ones stay there for compatibility with + * old software (will be deprecated in the future) + */ + +/**@{*/ + +#ifndef LIBOPENCM3_SYSTICK_H +#define LIBOPENCM3_SYSTICK_H + +#include +#include + +/* --- SYSTICK registers --------------------------------------------------- */ + +/* Control and status register (STK_CTRL) */ +#define STK_CSR MMIO32(SYS_TICK_BASE + 0x00) + +/* reload value register (STK_LOAD) */ +#define STK_RVR MMIO32(SYS_TICK_BASE + 0x04) + +/* current value register (STK_VAL) */ +#define STK_CVR MMIO32(SYS_TICK_BASE + 0x08) + +/* calibration value register (STK_CALIB) */ +#define STK_CALIB MMIO32(SYS_TICK_BASE + 0x0C) + +/* --- STK_CSR values ------------------------------------------------------ */ +/* Bits [31:17] Reserved, must be kept cleared. */ +/* COUNTFLAG: */ +#define STK_CSR_COUNTFLAG (1 << 16) + +/* Bits [15:3] Reserved, must be kept cleared. */ +/* CLKSOURCE: Clock source selection */ +#define STK_CSR_CLKSOURCE_LSB 2 +#define STK_CSR_CLKSOURCE (1 << STK_CSR_CLKSOURCE_LSB) + +/** @defgroup systick_clksource Clock source selection +@ingroup CM3_systick_defines + +@{*/ +#if defined(__ARM_ARCH_6M__) +#define STK_CSR_CLKSOURCE_EXT (0 << STK_CSR_CLKSOURCE_LSB) +#define STK_CSR_CLKSOURCE_AHB (1 << STK_CSR_CLKSOURCE_LSB) +#else +#define STK_CSR_CLKSOURCE_AHB_DIV8 (0 << STK_CSR_CLKSOURCE_LSB) +#define STK_CSR_CLKSOURCE_AHB (1 << STK_CSR_CLKSOURCE_LSB) +#endif +/**@}*/ + +/* TICKINT: SysTick exception request enable */ +#define STK_CSR_TICKINT (1 << 1) +/* ENABLE: Counter enable */ +#define STK_CSR_ENABLE (1 << 0) + +/* --- STK_RVR values ------------------------------------------------------ */ +/* Bits [31:24] Reserved, must be kept cleared. */ +/* RELOAD[23:0]: RELOAD value */ +#define STK_RVR_RELOAD 0x00FFFFFF + + +/* --- STK_CVR values ------------------------------------------------------ */ +/* Bits [31:24] Reserved, must be kept cleared. */ +/* CURRENT[23:0]: Current counter value */ +#define STK_CVR_CURRENT 0x00FFFFFF + + +/* --- STK_CALIB values ---------------------------------------------------- */ +/* NOREF: NOREF flag */ +#define STK_CALIB_NOREF (1 << 31) +/* SKEW: SKEW flag */ +#define STK_CALIB_SKEW (1 << 30) +/* Bits [29:24] Reserved, must be kept cleared. */ +/* TENMS[23:0]: Calibration value */ +#define STK_CALIB_TENMS 0x00FFFFFF + +/* --- Function Prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void systick_set_reload(uint32_t value); +bool systick_set_frequency(uint32_t freq, uint32_t ahb); +uint32_t systick_get_reload(void); +uint32_t systick_get_value(void); +void systick_set_clocksource(uint8_t clocksource); +void systick_interrupt_enable(void); +void systick_interrupt_disable(void); +void systick_counter_enable(void); +void systick_counter_disable(void); +uint8_t systick_get_countflag(void); +void systick_clear(void); + +uint32_t systick_get_calib(void); + +END_DECLS + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/tpiu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/tpiu.h new file mode 100644 index 00000000..ff215116 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/tpiu.h @@ -0,0 +1,97 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_TPIU_H +#define LIBOPENCM3_CM3_TPIU_H + +/* Cortex-M3 Trace Port Interface Unit (TPIU) */ + +/* Those defined only on ARMv7 and above */ +#if !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) +#error "Trace Port Interface Unit not available in CM0" +#endif + +/* --- TPIU registers ------------------------------------------------------ */ + +/* Supported Synchronous Port Size (TPIU_SSPSR) */ +#define TPIU_SSPSR MMIO32(TPIU_BASE + 0x000) + +/* Current Synchronous Port Size (TPIU_CSPSR) */ +#define TPIU_CSPSR MMIO32(TPIU_BASE + 0x004) + +/* Asynchronous Clock Prescaler (TPIU_ACPR) */ +#define TPIU_ACPR MMIO32(TPIU_BASE + 0x010) + +/* Selected Pin Protocol (TPIU_SPPR) */ +#define TPIU_SPPR MMIO32(TPIU_BASE + 0x0F0) + +/* Formatter and Flush Status Register (TPIU_FFSR) */ +#define TPIU_FFSR MMIO32(TPIU_BASE + 0x300) + +/* Formatter and Flush Control Register (TPIU_FFCR) */ +#define TPIU_FFCR MMIO32(TPIU_BASE + 0x304) + +/* (TPIU_DEVID) */ +#define TPIU_DEVID MMIO32(TPIU_BASE + 0xFC8) + +/* CoreSight Lock Status Register for this peripheral */ +#define TPIU_LSR MMIO32(TPIU_BASE + 0xFB4) +/* CoreSight Lock Access Register for this peripheral */ +#define TPIU_LAR MMIO32(TPIU_BASE + 0xFB0) + +/* TODO: PID, CID */ + +/* --- TPIU_ACPR values ---------------------------------------------------- */ + +/* Bits 31:16 - Reserved */ +/* Bits 15:0 - SWO output clock = Asynchronous_Reference_Clock/(value +1) */ + +/* --- TPIU_SPPR values ---------------------------------------------------- */ + +/* Bits 31:2 - Reserved */ +#define TPIU_SPPR_SYNC (0x0) +#define TPIU_SPPR_ASYNC_MANCHESTER (0x1) +#define TPIU_SPPR_ASYNC_NRZ (0x2) + +/* --- TPIU_FFSR values ---------------------------------------------------- */ + +/* Bits 31:4 - Reserved */ +#define TPIU_FFSR_FTNONSTOP (1 << 3) +#define TPIU_FFSR_TCPRESENT (1 << 2) +#define TPIU_FFSR_FTSTOPPED (1 << 1) +#define TPIU_FFSR_FLINPROG (1 << 0) + +/* --- TPIU_FFCR values ---------------------------------------------------- */ + +/* Bits 31:9 - Reserved */ +#define TPIU_FFCR_TRIGIN (1 << 8) +/* Bits 7:2 - Reserved */ +#define TPIU_FFCR_ENFCONT (1 << 1) +/* Bit 0 - Reserved */ + +/* --- TPIU_DEVID values ---------------------------------------------------- */ +/* Bits 31:16 - Reserved */ +/* Bits 15:12 - Implementation defined */ +#define TPUI_DEVID_NRZ_SUPPORTED (1 << 11) +#define TPUI_DEVID_MANCHESTER_SUPPORTED (1 << 10) +/* Bit 9 - RAZ, indicated that trace data and clock are supported */ +#define TPUI_DEVID_FIFO_SIZE_MASK (7 << 6) +/* Bits 5:0 - Implementation defined */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/vector.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/vector.h new file mode 100644 index 00000000..17ebb152 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/cm3/vector.h @@ -0,0 +1,64 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @file + * + * Definitions for handling vector tables. + * + * This implements d0002_efm32_cortex-m3_reference_manual.pdf's figure 2.2 + * (from the EFM32 documentation at + * http://www.energymicro.com/downloads/datasheets), and was seen analogously + * in other ARM implementations' libopencm3 files. + * + * The structure of the vector table is implemented independently of the system + * vector table starting at memory position 0x0, as it can be relocated to + * other memory locations too. + * + * The exact size of a vector interrupt table depends on the number of + * interrupts IRQ_COUNT, which is defined per family. + */ + +#ifndef LIBOPENCM3_VECTOR_H +#define LIBOPENCM3_VECTOR_H + +#include +#include + +/** Type of an interrupt function. Only used to avoid hard-to-read function + * pointers in the efm32_vector_table_t struct. */ +typedef void (*vector_table_entry_t)(void); + +typedef struct { + unsigned int *initial_sp_value; /**< Initial stack pointer value. */ + vector_table_entry_t reset; + vector_table_entry_t nmi; + vector_table_entry_t hard_fault; + vector_table_entry_t memory_manage_fault; /* not in CM0 */ + vector_table_entry_t bus_fault; /* not in CM0 */ + vector_table_entry_t usage_fault; /* not in CM0 */ + vector_table_entry_t reserved_x001c[4]; + vector_table_entry_t sv_call; + vector_table_entry_t debug_monitor; /* not in CM0 */ + vector_table_entry_t reserved_x0034; + vector_table_entry_t pend_sv; + vector_table_entry_t systick; + vector_table_entry_t irq[NVIC_IRQ_COUNT]; +} vector_table_t; + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/docmain.dox b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/docmain.dox new file mode 100644 index 00000000..799ebbbc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/docmain.dox @@ -0,0 +1,21 @@ +/** @mainpage libopencm3 Developer Documentation + +@version 1.0.0 + +@date 7 September 2012 + + * The libopencm3 project (previously known as libopenstm32) aims to create + * a free/libre/open-source (LGPL v3, or later) firmware library for various + * ARM Cortex-M microcontrollers, including ST STM32, Atmel SAM, NXP LPC, + * TI Stellaris/Tiva/MSP432, Silabs (Energy Micro) and others. + * + * @par "" + * + * See the libopencm3 wiki for + * more information. + +LGPL License Terms @ref lgpl_license +*/ + + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/acmp.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/acmp.h new file mode 100644 index 00000000..cf5694dd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/acmp.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/adc.h new file mode 100644 index 00000000..7b99f23b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/adc.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/burtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/burtc.h new file mode 100644 index 00000000..1158d7f8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/burtc.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/cmu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/cmu.h new file mode 100644 index 00000000..d89e28c6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/cmu.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dac.h new file mode 100644 index 00000000..00011862 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dac.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dma.h new file mode 100644 index 00000000..cc06a229 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/dma.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/emu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/emu.h new file mode 100644 index 00000000..0fc19bef --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/emu.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/doc-efm32g.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/doc-efm32g.h new file mode 100644 index 00000000..747cb514 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/doc-efm32g.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 EFM32 Gecko + +@version 1.0.0 + +@date 11 November 2012 + +API documentation for Energy Micro EFM32 Gecko Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32G EFM32 Gecko +Libraries for Energy Micro EFM32 Gecko series. + +@version 1.0.0 + +@date 11 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32G_defines EFM32 Gecko Defines + +@brief Defined Constants and Types for the Energy Micro EFM32 Gecko series + +@version 1.0.0 + +@date 11 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/irq.json new file mode 100644 index 00000000..59cc38b4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/g/irq.json @@ -0,0 +1,38 @@ +{ + "_source": "The names and sequence are taken from d0001_efm32g_reference_manual.pdf table 4.1.", + "irqs": [ + "dma", + "gpio_even", + "timer0", + "usart0_rx", + "usart0_tx", + "acmp01", + "adc0", + "dac0", + "i2c0", + "gpio_odd", + "timer1", + "timer2", + "usart1_rx", + "usart1_tx", + "usart2_rx", + "usart2_tx", + "uart0_rx", + "uart0_tx", + "leuart0", + "leuart1", + "letimer0", + "pcnt0", + "pcnt1", + "pcnt2", + "rtc", + "cmu", + "vcmp", + "lcd", + "msc", + "aes" + ], + "partname_humanreadable": "EFM32 Gecko series", + "partname_doxygen": "EFM32G", + "includeguard": "LIBOPENCM3_EFM32G_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/doc-efm32gg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/doc-efm32gg.h new file mode 100644 index 00000000..aacb17bc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/doc-efm32gg.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 EFM32 Giant Gecko + +@version 1.0.0 + +@date 11 November 2012 + +API documentation for Energy Micro EFM32 Giant Gecko Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32GG EFM32 Giant Gecko +Libraries for Energy Micro EFM32 Giant Gecko series. + +@version 1.0.0 + +@date 11 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32GG_defines EFM32 Giant Gecko Defines + +@brief Defined Constants and Types for the Energy Micro EFM32 Giant Gecko series + +@version 1.0.0 + +@date 11 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/irq.json new file mode 100644 index 00000000..43e7e8ca --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gg/irq.json @@ -0,0 +1,46 @@ +{ + "_source": "The names and sequence are taken from d0053_efm32gg_refreence_manual.pdf table 4.1.", + "irqs": [ + "dma", + "gpio_even", + "timer0", + "usart0_rx", + "usart0_tx", + "usb", + "acmp01", + "adc0", + "dac0", + "i2c0", + "i2c1", + "gpio_odd", + "timer1", + "timer2", + "timer3", + "usart1_rx", + "usart1_tx", + "lesense", + "usart2_rx", + "usart2_tx", + "uart0_rx", + "uart0_tx", + "uart1_rx", + "uart1_tx", + "leuart0", + "leuart1", + "letimer0", + "pcnt0", + "pcnt1", + "pcnt2", + "rtc", + "burtc", + "cmu", + "vcmp", + "lcd", + "msc", + "aes", + "ebi" + ], + "partname_humanreadable": "EFM32 Giant Gecko series", + "partname_doxygen": "EFM32GG", + "includeguard": "LIBOPENCM3_EFM32GG_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gpio.h new file mode 100644 index 00000000..0d91fbb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/gpio.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/i2c.h new file mode 100644 index 00000000..0acf48a7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/i2c.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/letimer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/letimer.h new file mode 100644 index 00000000..92b6ad7a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/letimer.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/acmp.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/acmp.h new file mode 100644 index 00000000..1a57cb02 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/acmp.h @@ -0,0 +1,185 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_ACMP_H +#define LIBOPENCM3_EFM32_ACMP_H + +#include +#include + +#define ACMP_CTRL(base) ((base) + 0x000) +#define ACMP_INPUTSEL(base) ((base) + 0x004) +#define ACMP_STATUS(base) ((base) + 0x008) +#define ACMP_IEN(base) ((base) + 0x00C) +#define ACMP_IF(base) ((base) + 0x010) +#define ACMP_IFS(base) ((base) + 0x014) +#define ACMP_IFC(base) ((base) + 0x018) +#define ACMP_ROUTE(base) ((base) + 0x01C) + +/* ACMP_CTRL */ +#define ACMP_CTRL_FULLBIAS (1 << 31) +#define ACMP_CTRL_HALFBIAS (1 << 30) + +#define ACMP_CTRL_BIASPROG_SHIFT (24) +#define ACMP_CTRL_BIASPROG_MASK (0xF << ACMP_CTRL_BIASPROG_SHIFT) +#define ACMP_CTRL_BIASPROG(v) \ + (((v) << ACMP_CTRL_BIASPROG_SHIFT) & ACMP_CTRL_BIASPROG_MASK) + +#define ACMP_CTRL_IFALL (1 << 17) +#define ACMP_CTRL_IRISE (1 << 16) + +#define ACMP_CTRL_WARMTIME_SHIFT (8) +#define ACMP_CTRL_WARMTIME_MASK (0x7 << ACMP_CTRL_WARMTIME_SHIFT) +#define ACMP_CTRL_WARMTIME(v) \ + (((v) << ACMP_CTRL_WARMTIME_SHIFT) & ACMP_CTRL_WARMTIME_MASK) +#define ACMP_CTRL_WARMTIME_4CYCLES ACMP_CTRL_WARMTIME(0) +#define ACMP_CTRL_WARMTIME_8CYCLES ACMP_CTRL_WARMTIME(1) +#define ACMP_CTRL_WARMTIME_16CYCLES ACMP_CTRL_WARMTIME(2) +#define ACMP_CTRL_WARMTIME_32CYCLES ACMP_CTRL_WARMTIME(3) +#define ACMP_CTRL_WARMTIME_64CYCLES ACMP_CTRL_WARMTIME(4) +#define ACMP_CTRL_WARMTIME_128CYCLES ACMP_CTRL_WARMTIME(5) +#define ACMP_CTRL_WARMTIME_256CYCLES ACMP_CTRL_WARMTIME(6) +#define ACMP_CTRL_WARMTIME_512CYCLES ACMP_CTRL_WARMTIME(7) + +#define ACMP_CTRL_HYSTSEL_SHIFT (8) +#define ACMP_CTRL_HYSTSEL_MASK (0x7 << ACMP_CTRL_HYSTSEL_SHIFT) +#define ACMP_CTRL_HYSTSEL(v) \ + (((v) << ACMP_CTRL_HYSTSEL_SHIFT) & ACMP_CTRL_HYSTSEL_MASK) +#define ACMP_CTRL_HYSTSEL_HYSTx(x) ACMP_CTRL_HYSTSEL_HYST(x) +#define ACMP_CTRL_HYSTSEL_HYST0 ACMP_CTRL_HYSTSEL_HYSTx(0) +#define ACMP_CTRL_HYSTSEL_HYST1 ACMP_CTRL_HYSTSEL_HYSTx(1) +#define ACMP_CTRL_HYSTSEL_HYST2 ACMP_CTRL_HYSTSEL_HYSTx(2) +#define ACMP_CTRL_HYSTSEL_HYST3 ACMP_CTRL_HYSTSEL_HYSTx(3) +#define ACMP_CTRL_HYSTSEL_HYST4 ACMP_CTRL_HYSTSEL_HYSTx(4) +#define ACMP_CTRL_HYSTSEL_HYST5 ACMP_CTRL_HYSTSEL_HYSTx(5) +#define ACMP_CTRL_HYSTSEL_HYST6 ACMP_CTRL_HYSTSEL_HYSTx(6) +#define ACMP_CTRL_HYSTSEL_HYST7 ACMP_CTRL_HYSTSEL_HYSTx(7) + +#define ACMP_CTRL_GPIOINV (1 << 3) +#define ACMP_CTRL_INACTVAL (1 << 2) +#define ACMP_CTRL_MUXEN (1 << 1) +#define ACMP_CTRL_EN (1 << 0) + +/* ACMP_INPUTSEL */ +#define ACMP_INPUTSEL_CSRESSEL_SHIFT (28) +#define ACMP_INPUTSEL_CSRESSEL_MASK (0x3 << ACMP_INPUTSEL_CSRESSEL_SHIFT) +#define ACMP_INPUTSEL_CSRESSEL(v) \ + (((v) << ACMP_INPUTSEL_CSRESSEL_SHIFT) & ACMP_INPUTSEL_CSRESSEL_MASK) +#define ACMP_INPUTSEL_CSRESSEL_RESx(x) ACMP_INPUTSEL_CSRESSEL_RES(x) +#define ACMP_INPUTSEL_CSRESSEL_RES0 ACMP_INPUTSEL_CSRESSEL_RESx(0) +#define ACMP_INPUTSEL_CSRESSEL_RES1 ACMP_INPUTSEL_CSRESSEL_RESx(1) +#define ACMP_INPUTSEL_CSRESSEL_RES2 ACMP_INPUTSEL_CSRESSEL_RESx(2) +#define ACMP_INPUTSEL_CSRESSEL_RES3 ACMP_INPUTSEL_CSRESSEL_RESx(3) + +#define ACMP_INPUTSEL_CSRESEN (1 << 24) +#define ACMP_INPUTSEL_LPREF (1 << 16) + +#define ACMP_INPUTSEL_VDDLEVEL_SHIFT (8) +#define ACMP_INPUTSEL_VDDLEVEL_MASK (0x3F << ACMP_INPUTSEL_VDDLEVEL_SHIFT) +#define ACMP_INPUTSEL_VDDLEVEL(v) \ + (((v) << ACMP_INPUTSEL_VDDLEVEL_SHIFT) & ACMP_INPUTSEL_VDDLEVEL_MASK) + +#define ACMP_INPUTSEL_NEGSEL_SHIFT (8) +#define ACMP_INPUTSEL_NEGSEL_MASK (0x3F << ACMP_INPUTSEL_NEGSEL_SHIFT) +#define ACMP_INPUTSEL_NEGSEL(v) \ + (((v) << ACMP_INPUTSEL_NEGSEL_SHIFT) & ACMP_INPUTSEL_NEGSEL_MASK) +#define ACMP_INPUTSEL_NEGSEL_CHx(x) ACMP_INPUTSEL_NEGSEL(x) +#define ACMP_INPUTSEL_NEGSEL_CH0 ACMP_INPUTSEL_NEGSEL_CHx(0) +#define ACMP_INPUTSEL_NEGSEL_CH1 ACMP_INPUTSEL_NEGSEL_CHx(1) +#define ACMP_INPUTSEL_NEGSEL_CH2 ACMP_INPUTSEL_NEGSEL_CHx(2) +#define ACMP_INPUTSEL_NEGSEL_CH3 ACMP_INPUTSEL_NEGSEL_CHx(3) +#define ACMP_INPUTSEL_NEGSEL_CH4 ACMP_INPUTSEL_NEGSEL_CHx(4) +#define ACMP_INPUTSEL_NEGSEL_CH5 ACMP_INPUTSEL_NEGSEL_CHx(5) +#define ACMP_INPUTSEL_NEGSEL_CH6 ACMP_INPUTSEL_NEGSEL_CHx(6) +#define ACMP_INPUTSEL_NEGSEL_CH7 ACMP_INPUTSEL_NEGSEL_CHx(7) +#define ACMP_INPUTSEL_NEGSEL_1V25 ACMP_INPUTSEL_NEGSEL(8) +#define ACMP_INPUTSEL_NEGSEL_2V5 ACMP_INPUTSEL_NEGSEL(9) +#define ACMP_INPUTSEL_NEGSEL_VDD ACMP_INPUTSEL_NEGSEL(10) +#define ACMP_INPUTSEL_NEGSEL_CAPSENSE ACMP_INPUTSEL_NEGSEL(11) +#define ACMP_INPUTSEL_NEGSEL_DAC0CH0 ACMP_INPUTSEL_NEGSEL(12) +#define ACMP_INPUTSEL_NEGSEL_DAC0CH1 ACMP_INPUTSEL_NEGSEL(13) + +#define ACMP_INPUTSEL_POSSEL_SHIFT (0) +#define ACMP_INPUTSEL_POSSEL_MASK (0x7 << ACMP_INPUTSEL_POSSEL_SHIFT) +#define ACMP_INPUTSEL_POSSEL(v) \ + (((v) << ACMP_INPUTSEL_LPOSSELL_SHIFT) & ACMP_INPUTSEL_LPOSSELL_MASK) +#define ACMP_INPUTSEL_POSSEL_CHx(x) ACMP_INPUTSEL_POSSEL(x) +#define ACMP_INPUTSEL_POSSEL_CH0 ACMP_INPUTSEL_POSSEL_CHx(0) +#define ACMP_INPUTSEL_POSSEL_CH1 ACMP_INPUTSEL_POSSEL_CHx(1) +#define ACMP_INPUTSEL_POSSEL_CH2 ACMP_INPUTSEL_POSSEL_CHx(2) +#define ACMP_INPUTSEL_POSSEL_CH3 ACMP_INPUTSEL_POSSEL_CHx(3) +#define ACMP_INPUTSEL_POSSEL_CH4 ACMP_INPUTSEL_POSSEL_CHx(4) +#define ACMP_INPUTSEL_POSSEL_CH5 ACMP_INPUTSEL_POSSEL_CHx(5) +#define ACMP_INPUTSEL_POSSEL_CH6 ACMP_INPUTSEL_POSSEL_CHx(6) +#define ACMP_INPUTSEL_POSSEL_CH7 ACMP_INPUTSEL_POSSEL_CHx(7) + +/* ACMP_STATUS */ +#define ACMP_STATUS_ACMPOUT (1 << 1) +#define ACMP_STATUS_ACMPACT (1 << 0) + +/* ACMP_IEN */ +#define ACMP_IEN_WARMUP (1 << 1) +#define ACMP_IEN_EDGE (1 << 0) + +/* ACMP_IF */ +#define ACMP_IF_WARMUP (1 << 1) +#define ACMP_IF_EDGE (1 << 0) + +/* ACMP_IFS */ +#define ACMP_IFS_WARMUP (1 << 1) +#define ACMP_IFS_EDGE (1 << 0) + +/* ACMP_IFC */ +#define ACMP_IFC_WARMUP (1 << 1) +#define ACMP_IFC_EDGE (1 << 0) + +/* ACMP_ROUTE */ +#define ACMP_ROUTE_LOCATION_SHIFT (8) +#define ACMP_ROUTE_LOCATION_MASK (0x7 << ACMP_ROUTE_LOCATION_SHIFT) +#define ACMP_ROUTE_LOCATION(v) \ + (((v) << ACMP_ROUTE_LOCATION_SHIFT) & ACMP_ROUTE_LOCATION_MASK) +#define ACMP_ROUTE_LOCATION_LOCx(x) ACMP_ROUTE_LOCATION(x) +#define ACMP_ROUTE_LOCATION_LOC0 ACMP_ROUTE_LOCATIONx(0) +#define ACMP_ROUTE_LOCATION_LOC1 ACMP_ROUTE_LOCATIONx(1) +#define ACMP_ROUTE_LOCATION_LOC2 ACMP_ROUTE_LOCATIONx(2) + +#define ACMP_ROUTE_ACMPPEN (1 << 0) + +#define ACMP0 ACMP0_BASE +#define ACMP0_CTRL ACMP_CTRL(ACMP0) +#define ACMP0_INPUTSEL ACMP_INPUTSEL(ACMP0) +#define ACMP0_STATUS ACMP_STATUS(ACMP0) +#define ACMP0_IEN ACMP_IEN(ACMP0) +#define ACMP0_IF ACMP_IF(ACMP0) +#define ACMP0_IFS ACMP_IFS(ACMP0) +#define ACMP0_IFC ACMP_IFC(ACMP0) +#define ACMP0_ROUTE ACMP_ROUTE(ACMP0) + +#define ACMP1 ACMP1_BASE +#define ACMP1_CTRL ACMP_CTRL(ACMP1) +#define ACMP1_INPUTSEL ACMP_INPUTSEL(ACMP1) +#define ACMP1_STATUS ACMP_STATUS(ACMP1) +#define ACMP1_IEN ACMP_IEN(ACMP1) +#define ACMP1_IF ACMP_IF(ACMP1) +#define ACMP1_IFS ACMP_IFS(ACMP1) +#define ACMP1_IFC ACMP_IFC(ACMP1) +#define ACMP1_ROUTE ACMP_ROUTE(ACMP1) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/adc.h new file mode 100644 index 00000000..f0a0fe02 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/adc.h @@ -0,0 +1,457 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_ADC_H +#define LIBOPENCM3_EFM32_ADC_H + +#include +#include + +#define ADC_CTRL(base) MMIO32((base) + 0x000) +#define ADC_CMD(base) MMIO32((base) + 0x004) +#define ADC_STATUS(base) MMIO32((base) + 0x008) +#define ADC_SINGLECTRL(base) MMIO32((base) + 0x00C) +#define ADC_SCANCTRL(base) MMIO32((base) + 0x010) +#define ADC_IEN(base) MMIO32((base) + 0x014) +#define ADC_IF(base) MMIO32((base) + 0x018) +#define ADC_IFS(base) MMIO32((base) + 0x01C) +#define ADC_IFC(base) MMIO32((base) + 0x020) +#define ADC_SINGLEDATA(base) MMIO32((base) + 0x024) +#define ADC_SCANDATA(base) MMIO32((base) + 0x028) +#define ADC_SINGLEDATAP(base) MMIO32((base) + 0x02C) +#define ADC_SCANDATAP(base) MMIO32((base) + 0x030) +#define ADC_CAL(base) MMIO32((base) + 0x034) +#define ADC_BIASPROG(base) MMIO32((base) + 0x03C) + +/* ADC_CTRL */ +#define ADC_CTRL_OVERSEL_SHIFT (24) +#define ADC_CTRL_OVERSEL_MASK (0xF << ADC_CTRL_OVERSEL_SHIFT) +#define ADC_CTRL_OVERSEL(v) \ + (((v) << ADC_CTRL_OVERSEL_SHIFT) & ADC_CTRL_OVERSEL_MASK) +#define ADC_CTRL_OVERSEL_X2 ADC_CTRL_OVERSEL(0) +#define ADC_CTRL_OVERSEL_X4 ADC_CTRL_OVERSEL(1) +#define ADC_CTRL_OVERSEL_X8 ADC_CTRL_OVERSEL(2) +#define ADC_CTRL_OVERSEL_X16 ADC_CTRL_OVERSEL(3) +#define ADC_CTRL_OVERSEL_X32 ADC_CTRL_OVERSEL(4) +#define ADC_CTRL_OVERSEL_X64 ADC_CTRL_OVERSEL(5) +#define ADC_CTRL_OVERSEL_X128 ADC_CTRL_OVERSEL(6) +#define ADC_CTRL_OVERSEL_X256 ADC_CTRL_OVERSEL(7) +#define ADC_CTRL_OVERSEL_X512 ADC_CTRL_OVERSEL(8) +#define ADC_CTRL_OVERSEL_X1024 ADC_CTRL_OVERSEL(9) +#define ADC_CTRL_OVERSEL_X2048 ADC_CTRL_OVERSEL(10) +#define ADC_CTRL_OVERSEL_X4096 ADC_CTRL_OVERSEL(11) + +#define ADC_CTRL_TIMEBASE_SHIFT (16) +#define ADC_CTRL_TIMEBASE_MASK (0x3F << ADC_CTRL_TIMEBASE_SHIFT) +#define ADC_CTRL_TIMEBASE(v) \ + (((v) << ADC_CTRL_TIMEBASE_SHIFT) & ADC_CTRL_TIMEBASE_MASK) + +#define ADC_CTRL_PRESC_SHIFT (8) +#define ADC_CTRL_PRESC_MASK (0x3F << ADC_CTRL_PRESC_SHIFT) +#define ADC_CTRL_PRESC(v) \ + (((v) << ADC_CTRL_PRESC_SHIFT) & ADC_CTRL_PRESC_MASK) + +#define ADC_CTRL_LPFMODE_SHIFT (4) +#define ADC_CTRL_LPFMODE_MASK (0x3 << ADC_CTRL_LPFMODE_SHIFT) +#define ADC_CTRL_LPFMODE(v) \ + (((v) << ADC_CTRL_LPFMODEC_SHIFT) & ADC_CTRL_LPFMODEC_MASK) +#define ADC_CTRL_LPFMODE_BYPASS ADC_CTRL_LPFMODE(0) +#define ADC_CTRL_LPFMODE_DECAP ADC_CTRL_LPFMODE(1) +#define ADC_CTRL_LPFMODE_RCFILT ADC_CTRL_LPFMODE(2) + +#define ADC_CTRL_TAILGATE (1 << 3) + +#define ADC_CTRL_WARMUPMODE_SHIFT (0) +#define ADC_CTRL_WARMUPMODE_MASK (0x3 << ADC_CTRL_WARMUPMODE_SHIFT) +#define ADC_CTRL_WARMUPMODE(v) \ + (((v) << ADC_CTRL_WARMUPMODE_SHIFT) & ADC_CTRL_WARMUPMODE_MASK) +#define ADC_CTRL_WARMUPMODE_NORMAL ADC_CTRL_WARMUPMODE(0) +#define ADC_CTRL_WARMUPMODE_FASTBG ADC_CTRL_WARMUPMODE(1) +#define ADC_CTRL_WARMUPMODE_KEEPSCANREFWARM ADC_CTRL_WARMUPMODE(2) +#define ADC_CTRL_WARMUPMODE_KEEPADCWARM ADC_CTRL_WARMUPMODE(3) + +/* ADC_CMD */ +#define ADC_CMD_SCANSTOP (1 << 3) +#define ADC_CMD_SCANSTART (1 << 2) +#define ADC_CMD_SINGLESTOP (1 << 1) +#define ADC_CMD_SINGLESTART (1 << 0) + +/* ADC_STATUS */ +#define ADC_STATUS_SCANDATASRC_SHIFT (0) +#define ADC_STATUS_SCANDATASRC_MASK (0x7 << ADC_STATUS_SCANDATASRC_SHIFT) +#define ADC_STATUS_SCANDATASRC(v) \ + (((v) << ADC_STATUS_SCANDATASRC_SHIFT) & ADC_STATUS_SCANDATASRC_MASK) + +#define ADC_STATUS_SCANDV (1 << 17) +#define ADC_STATUS_SINGLEDV (1 << 16) +#define ADC_STATUS_WARM (1 << 12) +#define ADC_STATUS_SCANREFWARM (1 << 9) +#define ADC_STATUS_SINGLEREFWARM (1 << 8) +#define ADC_STATUS_SCANACT (1 << 1) +#define ADC_STATUS_SINGLEACT (1 << 0) + +/* ADC_SINGLECTRL */ +#define ADC_SINGLECTRL_PRSSEL_SHIFT (28) +#define ADC_SINGLECTRL_PRSSEL_MASK (0xF << ADC_SINGLECTRL_PRSSEL_SHIFT) +#define ADC_SINGLECTRL_PRSSEL(v) \ + (((v) << ADC_SINGLECTRL_PRSSEL_SHIFT) & ADC_SINGLECTRL_PRSSEL_MASK) +#define ADC_SINGLECTRL_PRSSEL_PRSCHx(x) ADC_SINGLECTRL_PRSSEL(x) +#define ADC_SINGLECTRL_PRSSEL_PRSCH0 ADC_SINGLECTRL_PRSSEL_PRSCHx(0) +#define ADC_SINGLECTRL_PRSSEL_PRSCH1 ADC_SINGLECTRL_PRSSEL_PRSCHx(1) +#define ADC_SINGLECTRL_PRSSEL_PRSCH2 ADC_SINGLECTRL_PRSSEL_PRSCHx(2) +#define ADC_SINGLECTRL_PRSSEL_PRSCH3 ADC_SINGLECTRL_PRSSEL_PRSCHx(3) +#define ADC_SINGLECTRL_PRSSEL_PRSCH4 ADC_SINGLECTRL_PRSSEL_PRSCHx(4) +#define ADC_SINGLECTRL_PRSSEL_PRSCH5 ADC_SINGLECTRL_PRSSEL_PRSCHx(5) +#define ADC_SINGLECTRL_PRSSEL_PRSCH6 ADC_SINGLECTRL_PRSSEL_PRSCHx(6) +#define ADC_SINGLECTRL_PRSSEL_PRSCH7 ADC_SINGLECTRL_PRSSEL_PRSCHx(7) +#define ADC_SINGLECTRL_PRSSEL_PRSCH8 ADC_SINGLECTRL_PRSSEL_PRSCHx(8) +#define ADC_SINGLECTRL_PRSSEL_PRSCH9 ADC_SINGLECTRL_PRSSEL_PRSCHx(9) +#define ADC_SINGLECTRL_PRSSEL_PRSCH10 ADC_SINGLECTRL_PRSSEL_PRSCHx(10) +#define ADC_SINGLECTRL_PRSSEL_PRSCH11 ADC_SINGLECTRL_PRSSEL_PRSCHx(11) + +#define ADC_SINGLECTRL_PRSEN (1 << 24) + +#define ADC_SINGLECTRL_AT_SHIFT (20) +#define ADC_SINGLECTRL_AT_MASK (0xF << ADC_SINGLECTRL_AT_SHIFT) +#define ADC_SINGLECTRL_AT(v) \ + (((v) << ADC_SINGLECTRL_AT_SHIFT) & ADC_SINGLECTRL_AT_MASK) +#define ADC_SINGLECTRL_AT_1CYCLE ADC_SINGLECTRL_AT(0x0) +#define ADC_SINGLECTRL_AT_2CYCLES ADC_SINGLECTRL_AT(0x1) +#define ADC_SINGLECTRL_AT_4CYCLES ADC_SINGLECTRL_AT(0x2) +#define ADC_SINGLECTRL_AT_8CYCLES ADC_SINGLECTRL_AT(0x3) +#define ADC_SINGLECTRL_AT_16CYCLES ADC_SINGLECTRL_AT(0x4) +#define ADC_SINGLECTRL_AT_32CYCLES ADC_SINGLECTRL_AT(0x5) +#define ADC_SINGLECTRL_AT_64CYCLES ADC_SINGLECTRL_AT(0x6) +#define ADC_SINGLECTRL_AT_128CYCLES ADC_SINGLECTRL_AT(0x7) +#define ADC_SINGLECTRL_AT_256CYCLES ADC_SINGLECTRL_AT(0x8) + +#define ADC_SINGLECTRL_REF_SHIFT (16) +#define ADC_SINGLECTRL_REF_MASK (0xF << ADC_SINGLECTRL_REF_SHIFT) +#define ADC_SINGLECTRL_REF(v) \ + (((v) << ADC_SINGLECTRL_REF_SHIFT) & ADC_SINGLECTRL_REF_MASK) +#define ADC_SINGLECTRL_REF_1V25 ADC_SINGLECTRL_REF(0) +#define ADC_SINGLECTRL_REF_2V5 ADC_SINGLECTRL_REF(1) +#define ADC_SINGLECTRL_REF_VDD ADC_SINGLECTRL_REF(2) +#define ADC_SINGLECTRL_REF_5VDIFF ADC_SINGLECTRL_REF(3) +#define ADC_SINGLECTRL_REF_EXTSINGLE ADC_SINGLECTRL_REF(4) +#define ADC_SINGLECTRL_REF_2XEXTDIFF ADC_SINGLECTRL_REF(5) +#define ADC_SINGLECTRL_REF_2XVDD ADC_SINGLECTRL_REF(6) + +#define ADC_SINGLECTRL_INPUTSEL_SHIFT (8) +#define ADC_SINGLECTRL_INPUTSEL_MASK (0xF << ADC_SINGLECTRL_INPUTSEL_SHIFT) +#define ADC_SINGLECTRL_INPUTSEL(v) \ + (((v) << ADC_SINGLECTRL_INPUTSEL_SHIFT) & ADC_SINGLECTRL_INPUTSEL_MASK) +/* DIFF=0 */ +#define ADC_SINGLECTRL_INPUTSEL_CHx(x) ADC_SINGLECTRL_INPUTSEL(x) +#define ADC_SINGLECTRL_INPUTSEL_CH0 ADC_SINGLECTRL_INPUTSEL_CHx(0) +#define ADC_SINGLECTRL_INPUTSEL_CH1 ADC_SINGLECTRL_INPUTSEL_CHx(1) +#define ADC_SINGLECTRL_INPUTSEL_CH2 ADC_SINGLECTRL_INPUTSEL_CHx(2) +#define ADC_SINGLECTRL_INPUTSEL_CH3 ADC_SINGLECTRL_INPUTSEL_CHx(3) +#define ADC_SINGLECTRL_INPUTSEL_CH4 ADC_SINGLECTRL_INPUTSEL_CHx(4) +#define ADC_SINGLECTRL_INPUTSEL_CH5 ADC_SINGLECTRL_INPUTSEL_CHx(5) +#define ADC_SINGLECTRL_INPUTSEL_CH6 ADC_SINGLECTRL_INPUTSEL_CHx(6) +#define ADC_SINGLECTRL_INPUTSEL_CH7 ADC_SINGLECTRL_INPUTSEL_CHx(7) +#define ADC_SINGLECTRL_INPUTSEL_TEMP ADC_SINGLECTRL_INPUTSEL(8) +#define ADC_SINGLECTRL_INPUTSEL_VDDDIV3 ADC_SINGLECTRL_INPUTSEL(9) +#define ADC_SINGLECTRL_INPUTSEL_VDD ADC_SINGLECTRL_INPUTSEL(10) +#define ADC_SINGLECTRL_INPUTSEL_VSS ADC_SINGLECTRL_INPUTSEL(11) +#define ADC_SINGLECTRL_INPUTSEL_VREFDIV2 ADC_SINGLECTRL_INPUTSEL(12) +#define ADC_SINGLECTRL_INPUTSEL_DAC0OUT0 ADC_SINGLECTRL_INPUTSEL(13) +#define ADC_SINGLECTRL_INPUTSEL_DAC0OUT1 ADC_SINGLECTRL_INPUTSEL(14) +/* DIFF=1 */ +#define ADC_SINGLECTRL_INPUTSEL_CH0CH1 ADC_SINGLECTRL_INPUTSEL(0) +#define ADC_SINGLECTRL_INPUTSEL_CH2CH3 ADC_SINGLECTRL_INPUTSEL(1) +#define ADC_SINGLECTRL_INPUTSEL_CH4CH5 ADC_SINGLECTRL_INPUTSEL(2) +#define ADC_SINGLECTRL_INPUTSEL_CH6CH7 ADC_SINGLECTRL_INPUTSEL(3) +#define ADC_SINGLECTRL_INPUTSEL_DIFF0 ADC_SINGLECTRL_INPUTSEL(4) + +#define ADC_SINGLECTRL_RES_SHIFT (4) +#define ADC_SINGLECTRL_RES_MASK (0x3 << ADC_SINGLECTRL_RES_SHIFT) +#define ADC_SINGLECTRL_RES(v) \ + (((v) << ADC_SINGLECTRL_RES_SHIFT) & ADC_SINGLECTRL_RES_MASK) +#define ADC_SINGLECTRL_RES_12BIT ADC_SINGLECTRL_RES(0) +#define ADC_SINGLECTRL_RES_8BIT ADC_SINGLECTRL_RES(1) +#define ADC_SINGLECTRL_RES_6BIT ADC_SINGLECTRL_RES(2) +#define ADC_SINGLECTRL_RES_OVS ADC_SINGLECTRL_RES(3) + +#define ADC_SINGLECTRL_ADJ (1 << 2) +#define ADC_SINGLECTRL_DIFF (1 << 1) +#define ADC_SINGLECTRL_REP (1 << 0) + +/* ADC_SCANCTRL */ +#define ADC_SCANCTRL_PRSSEL_SHIFT (28) +#define ADC_SCANCTRL_PRSSEL_MASK (0xF << ADC_SCANCTRL_PRSSEL_SHIFT) +#define ADC_SCANCTRL_PRSSEL(v) \ + (((v) << ADC_SCANCTRL_PRSSEL_SHIFT) & ADC_SCANCTRL_PRSSEL_MASK) +#define ADC_SCANCTRL_PRSSEL_PRSCHx(x) ADC_SCANCTRL_PRSSEL(x) +#define ADC_SCANCTRL_PRSSEL_PRSCH0 ADC_SCANCTRL_PRSSEL_PRSCHx(0) +#define ADC_SCANCTRL_PRSSEL_PRSCH1 ADC_SCANCTRL_PRSSEL_PRSCHx(1) +#define ADC_SCANCTRL_PRSSEL_PRSCH2 ADC_SCANCTRL_PRSSEL_PRSCHx(2) +#define ADC_SCANCTRL_PRSSEL_PRSCH3 ADC_SCANCTRL_PRSSEL_PRSCHx(3) +#define ADC_SCANCTRL_PRSSEL_PRSCH4 ADC_SCANCTRL_PRSSEL_PRSCHx(4) +#define ADC_SCANCTRL_PRSSEL_PRSCH5 ADC_SCANCTRL_PRSSEL_PRSCHx(5) +#define ADC_SCANCTRL_PRSSEL_PRSCH6 ADC_SCANCTRL_PRSSEL_PRSCHx(6) +#define ADC_SCANCTRL_PRSSEL_PRSCH7 ADC_SCANCTRL_PRSSEL_PRSCHx(7) +#define ADC_SCANCTRL_PRSSEL_PRSCH8 ADC_SCANCTRL_PRSSEL_PRSCHx(8) +#define ADC_SCANCTRL_PRSSEL_PRSCH9 ADC_SCANCTRL_PRSSEL_PRSCHx(9) +#define ADC_SCANCTRL_PRSSEL_PRSCH10 ADC_SCANCTRL_PRSSEL_PRSCHx(10) +#define ADC_SCANCTRL_PRSSEL_PRSCH11 ADC_SCANCTRL_PRSSEL_PRSCHx(11) + +#define ADC_SCANCTRL_PRSEN (1 << 24) + +#define ADC_SCANCTRL_AT_SHIFT (20) +#define ADC_SCANCTRL_AT_MASK (0xF << ADC_SCANCTRL_AT_SHIFT) +#define ADC_SCANCTRL_AT(v) \ + (((v) << ADC_SCANCTRL_AT_SHIFT) & ADC_SCANCTRL_AT_MASK) +#define ADC_SCANCTRL_AT_1CYCLE ADC_SCANCTRL_AT(0) +#define ADC_SCANCTRL_AT_2CYCLES ADC_SCANCTRL_AT(1) +#define ADC_SCANCTRL_AT_4CYCLES ADC_SCANCTRL_AT(2) +#define ADC_SCANCTRL_AT_8CYCLES ADC_SCANCTRL_AT(3) +#define ADC_SCANCTRL_AT_16CYCLES ADC_SCANCTRL_AT(4) +#define ADC_SCANCTRL_AT_32CYCLES ADC_SCANCTRL_AT(5) +#define ADC_SCANCTRL_AT_64CYCLES ADC_SCANCTRL_AT(6) +#define ADC_SCANCTRL_AT_128CYCLES ADC_SCANCTRL_AT(7) +#define ADC_SCANCTRL_AT_256CYCLES ADC_SCANCTRL_AT(8) + +#define ADC_SCANCTRL_REF_SHIFT (16) +#define ADC_SCANCTRL_REF_MASK (0xF << ADC_SCANCTRL_REF_SHIFT) +#define ADC_SCANCTRL_REF(v) \ + (((v) << ADC_SCANCTRL_REF_SHIFT) & ADC_SCANCTRL_REF_MASK) +#define ADC_SCANCTRL_REF_1V25 ADC_SCANCTRL_REF(0) +#define ADC_SCANCTRL_REF_2V5 ADC_SCANCTRL_REF(1) +#define ADC_SCANCTRL_REF_VDD ADC_SCANCTRL_REF(2) +#define ADC_SCANCTRL_REF_5VDIFF ADC_SCANCTRL_REF(3) +#define ADC_SCANCTRL_REF_EXTSCAN ADC_SCANCTRL_REF(4) +#define ADC_SCANCTRL_REF_2XEXTDIFF ADC_SCANCTRL_REF(5) +#define ADC_SCANCTRL_REF_2XVDD ADC_SCANCTRL_REF(6) + + +#define ADC_SCANCTRL_INPUTSEL_SHIFT (8) +#define ADC_SCANCTRL_INPUTSEL_MASK (0xFF << ADC_SCANCTRL_INPUTSEL_SHIFT) +#define ADC_SCANCTRL_INPUTSEL(v) \ + (((v) << ADC_SCANCTRL_INPUTSEL_SHIFT) & ADC_SCANCTRL_INPUTSEL_MASK) +/* DIFF=0 */ +#define ADC_SCANCTRL_INPUTSEL_CHx(x) ADC_SCANCTRL_INPUTSEL(1 << (x)) +#define ADC_SCANCTRL_INPUTSEL_CH0 ADC_SCANCTRL_INPUTSEL_CHx(0) +#define ADC_SCANCTRL_INPUTSEL_CH1 ADC_SCANCTRL_INPUTSEL_CHx(1) +#define ADC_SCANCTRL_INPUTSEL_CH2 ADC_SCANCTRL_INPUTSEL_CHx(2) +#define ADC_SCANCTRL_INPUTSEL_CH3 ADC_SCANCTRL_INPUTSEL_CHx(3) +#define ADC_SCANCTRL_INPUTSEL_CH4 ADC_SCANCTRL_INPUTSEL_CHx(4) +#define ADC_SCANCTRL_INPUTSEL_CH5 ADC_SCANCTRL_INPUTSEL_CHx(5) +#define ADC_SCANCTRL_INPUTSEL_CH6 ADC_SCANCTRL_INPUTSEL_CHx(6) +#define ADC_SCANCTRL_INPUTSEL_CH7 ADC_SCANCTRL_INPUTSEL_CHx(7) +/* DIFF=1 */ +#define ADC_SCANCTRL_INPUTSEL_CH0CH1 ADC_SCANCTRL_INPUTSEL(1 << 0) +#define ADC_SCANCTRL_INPUTSEL_CH2CH3 ADC_SCANCTRL_INPUTSEL(1 << 1) +#define ADC_SCANCTRL_INPUTSEL_CH4CH5 ADC_SCANCTRL_INPUTSEL(1 << 2) +#define ADC_SCANCTRL_INPUTSEL_CH6CH7 ADC_SCANCTRL_INPUTSEL(1 << 3) + +#define ADC_SCANCTRL_RES_SHIFT (4) +#define ADC_SCANCTRL_RES_MASK (0x3 << ADC_SCANCTRL_RES_SHIFT) +#define ADC_SCANCTRL_RES(v) \ + (((v) << ADC_SCANCTRL_RES_SHIFT) & ADC_SCANCTRL_RES_MASK) +#define ADC_SCANCTRL_RES_12BIT ADC_SCANCTRL_RES(0) +#define ADC_SCANCTRL_RES_8BIT ADC_SCANCTRL_RES(1) +#define ADC_SCANCTRL_RES_6BIT ADC_SCANCTRL_RES(2) +#define ADC_SCANCTRL_RES_OVS ADC_SCANCTRL_RES(3) + +#define ADC_SCANCTRL_ADJ (1 << 2) +#define ADC_SCANCTRL_DIFF (1 << 1) +#define ADC_SCANCTRL_REP (1 << 0) + +/* ADC_IEN */ +#define ADC_IEN_SCANOF (1 << 9) +#define ADC_IEN_SINGLEOF (1 << 8) +#define ADC_IEN_SCAN (1 << 1) +#define ADC_IEN_SINGLE (1 << 0) + +/* ADC_IF */ +#define ADC_IF_SCANOF (1 << 9) +#define ADC_IF_SINGLEOF (1 << 8) +#define ADC_IF_SCAN (1 << 1) +#define ADC_IF_SINGLE (1 << 0) + +/* ADC_IFS */ +#define ADC_IFS_SCANOF (1 << 9) +#define ADC_IFS_SINGLEOF (1 << 8) +#define ADC_IFS_SCAN (1 << 1) +#define ADC_IFS_SINGLE (1 << 0) + +/* ADC_IFC */ +#define ADC_IFC_SCANOF (1 << 9) +#define ADC_IFC_SINGLEOF (1 << 8) +#define ADC_IFC_SCAN (1 << 1) +#define ADC_IFC_SINGLE (1 << 0) + +/* ADC_CAL */ +#define ADC_CAL_SCANGAIN_SHIFT (24) +#define ADC_CAL_SCANGAIN_MASK (0x7F) + +#define ADC_CAL_SCANOFF_SHIFT (16) +#define ADC_CAL_SCANOFF_MASK (0x7F) + +#define ADC_CAL_SINGLEGAIN_SHIFT (8) +#define ADC_CAL_SINGLEGAIN_MASK (0x7F) + +#define ADC_CAL_SINGLEOFF_SHIFT (0) +#define ADC_CAL_SINGLEOFF_MASK (0x7F) + +/* ADC_BIASPROG */ +#define ADC_BIASPROG_COMPBIAS_SHIFT (8) +#define ADC_BIASPROG_COMPBIAS_MASK (0xF) + +#define ADC_BIASPROG_HALFBIAS (1 << 6) + +#define ADC_BIASPROG_BIASPROG_SHIFT (0) +#define ADC_BIASPROG_BIASPROG_MASK (0xF) + +/* ADC0 */ +#define ADC0 ADC0_BASE +#define ADC0_CTRL ADC_CTRL(ADC0) +#define ADC0_CMD ADC_CMD(ADC0) +#define ADC0_STATUS ADC_STATUS(ADC0) +#define ADC0_SINGLECTRL ADC_SINGLECTRL(ADC0) +#define ADC0_SCANCTRL ADC_SCANCTRL(ADC0) +#define ADC0_IEN ADC_IEN(ADC0) +#define ADC0_IF ADC_IF(ADC0) +#define ADC0_IFS ADC_IFS(ADC0) +#define ADC0_IFC ADC_IFC(ADC0) +#define ADC0_SINGLEDATA ADC_SINGLEDATA(ADC0) +#define ADC0_SCANDATA ADC_SCANDATA(ADC0) +#define ADC0_SINGLEDATAP ADC_SINGLEDATAP(ADC0) +#define ADC0_SCANDATAP ADC_SCANDATAP(ADC0) +#define ADC0_CAL ADC_CAL(ADC0) +#define ADC0_BIASPROG ADC_BIASPROG(ADC0) + +/** @defgroup adc_ch ADC Channel Number +@ingroup adc_defines + +@{*/ +#define ADC_CH0 0 +#define ADC_CH1 1 +#define ADC_CH2 2 +#define ADC_CH3 3 +#define ADC_CH4 4 +#define ADC_CH5 5 +#define ADC_CH6 6 +#define ADC_CH7 7 +#define ADC_CH_TEMP 8 +#define ADC_CH_VDDDIV3 9 +#define ADC_CH_VDD 10 +#define ADC_CH_VSS 11 +#define ADC_CH_VREFDIV2 12 +#define ADC_CH_DAC0OUT0 13 +#define ADC_CH_DAC0OUT1 14 + +#define ADC_CH_CH0CH1 0 +#define ADC_CH_CH2CH3 1 +#define ADC_CH_CH4CH5 2 +#define ADC_CH_CH6CH7 3 +#define ADC_CH_DIFF0 4 +/**@}*/ + +BEGIN_DECLS + +void adc_set_oversampling(uint32_t adc, uint32_t oversamp); +void adc_set_warm_up(uint32_t adc, uint8_t clocks); +void adc_set_clock_prescaler(uint32_t adc, uint8_t factor); +void adc_set_lowpass_filter(uint32_t adc, uint32_t lpfmode); + +void adc_enable_tailgating(uint32_t adc); +void adc_disable_tailgating(uint32_t adc); + +void adc_set_warm_up_mode(uint32_t adc, uint32_t warmupmode); + +void adc_single_start(uint32_t adc); +void adc_single_stop(uint32_t adc); + +void adc_scan_start(uint32_t adc); +void adc_scan_stop(uint32_t adc); + +/* TODO: ADC_STATUS */ + +void adc_set_single_prs_trigger(uint32_t adc, uint8_t prssel); +void adc_enable_single_prs_trigger(uint32_t adc); +void adc_disable_single_prs_trigger(uint32_t adc); +void adc_set_single_acquisition_cycle(uint32_t adc, uint32_t at); +void adc_set_single_reference(uint32_t adc, uint32_t ref); +void adc_set_single_channel(uint32_t adc, uint8_t ch); +void adc_set_single_resolution(uint32_t adc, uint32_t res); +void adc_set_single_left_aligned(uint32_t adc); +void adc_set_single_right_aligned(uint32_t adc); +void adc_set_single_single_ended(uint32_t adc); +void adc_set_single_differential(uint32_t adc); +void adc_enable_single_repeat_conv(uint32_t adc); +void adc_disable_single_repeat_conv(uint32_t adc); + +void adc_set_scan_prs_trigger(uint32_t adc, uint8_t prssel); +void adc_enable_scan_prs_trigger(uint32_t adc); +void adc_disable_scan_prs_trigger(uint32_t adc); +void adc_set_scan_acquisition_cycle(uint32_t adc, uint32_t at); +void adc_set_scan_reference(uint32_t adc, uint32_t ref); +void adc_set_scan_channel(uint32_t adc, uint8_t length, + uint8_t channel[]); +void adc_set_scan_resolution(uint32_t adc, uint32_t res); +void adc_set_scan_left_aligned(uint32_t adc); +void adc_set_scan_right_aligned(uint32_t adc); +void adc_set_scan_single_ended(uint32_t adc); +void adc_set_scan_differential(uint32_t adc); +void adc_enable_scan_repeat_conv(uint32_t adc); +void adc_disable_scan_repeat_conv(uint32_t adc); + +void adc_enable_single_result_overflow_interrupt(uint32_t adc); +void adc_disable_single_result_overflow_interrupt(uint32_t adc); +void adc_enable_single_conversion_complete_interrupt(uint32_t adc); +void adc_disable_single_conversion_complete_interrupt(uint32_t adc); +void adc_enable_scan_result_overflow_interrupt(uint32_t adc); +void adc_disable_scan_result_overflow_interrupt(uint32_t adc); +void adc_enable_scan_conversion_complete_interrupt(uint32_t adc); +void adc_disable_scan_conversion_complete_interrupt(uint32_t adc); + +bool adc_get_single_result_overflow_flag(uint32_t adc); +bool adc_get_single_conversion_complete_flag(uint32_t adc); +bool adc_get_scan_result_overflow_flag(uint32_t adc); +bool adc_get_scan_conversion_complete_flag(uint32_t adc); + +void adc_set_single_result_overflow_flag(uint32_t adc); +void adc_set_single_conversion_complete_flag(uint32_t adc); +void adc_set_scan_result_overflow_flag(uint32_t adc); +void adc_set_scan_conversion_complete_flag(uint32_t adc); + +void adc_clear_single_result_overflow_flag(uint32_t adc); +void adc_clear_single_conversion_complete_flag(uint32_t adc); +void adc_clear_scan_result_overflow_flag(uint32_t adc); +void adc_clear_scan_conversion_complete_flag(uint32_t adc); + +uint32_t adc_single_data(uint32_t adc); +uint32_t adc_scan_data(uint32_t adc); + +uint32_t adc_single_data_peak(uint32_t adc); +uint32_t adc_scan_data_peak(uint32_t adc); + +void adc_set_calibration_scan_gain(uint32_t adc, uint8_t scan_gain); +void adc_set_calibration_scan_offset(uint32_t adc, uint8_t scan_offset); + +void adc_set_calibration_single_gain(uint32_t adc, uint8_t single_gain); +void adc_set_calibration_single_offset(uint32_t adc, uint8_t single_offset); + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/burtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/burtc.h new file mode 100644 index 00000000..d3ff15bc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/burtc.h @@ -0,0 +1,170 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_BURTC_H +#define LIBOPENCM3_EFM32_BURTC_H + +#include +#include + +#define BURTC_CTRL MMIO32(BURTC_BASE + 0x000) +#define BURTC_LPMODE MMIO32(BURTC_BASE + 0x004) +#define BURTC_CNT MMIO32(BURTC_BASE + 0x008) +#define BURTC_COMP0 MMIO32(BURTC_BASE + 0x00C) +#define BURTC_TIMESTAMP MMIO32(BURTC_BASE + 0x010) +#define BURTC_LFXOFDET MMIO32(BURTC_BASE + 0x014) +#define BURTC_STATUS MMIO32(BURTC_BASE + 0x018) +#define BURTC_CMD MMIO32(BURTC_BASE + 0x01C) +#define BURTC_POWERDOWN MMIO32(BURTC_BASE + 0x020) +#define BURTC_LOCK MMIO32(BURTC_BASE + 0x024) +#define BURTC_IF MMIO32(BURTC_BASE + 0x028) +#define BURTC_IFS MMIO32(BURTC_BASE + 0x02C) +#define BURTC_IFC MMIO32(BURTC_BASE + 0x030) +#define BURTC_IEN MMIO32(BURTC_BASE + 0x034) +#define BURTC_FREEZE MMIO32(BURTC_BASE + 0x038) +#define BURTC_SYNCBUSY MMIO32(BURTC_BASE + 0x03C) + +#define RETx_REG(x) MMIO32(BURTC_BASE + 0x100 + (4 * (x))) +/* [for ease] */ +#define BURTC_RETx(x) RETx_REG(x) + +/* BURTC_CTRL */ +#define BURTC_CTRL_BUMODETSEN (1 << 14) + +#define BURTC_CTRL_CLKSEL_SHIFT (8) +#define BURTC_CTRL_CLKSEL_MASK (0x3 << BURTC_CTRL_CLKSEL_SHIFT) +#define BURTC_CTRL_CLKSEL(v) \ + (((v) << BURTC_CTRL_CLKSEL_SHIFT) & BURTC_CTRL_CLKSEL_MASK) +#define BURTC_CTRL_CLKSEL_NONE BURTC_CTRL_CLKSEL(0) +#define BURTC_CTRL_CLKSEL_LFRCO BURTC_CTRL_CLKSEL(1) +#define BURTC_CTRL_CLKSEL_LFXO BURTC_CTRL_CLKSEL(2) +#define BURTC_CTRL_CLKSEL_ULFRCO BURTC_CTRL_CLKSEL(3) + +#define BURTC_CTRL_PRESC_SHIFT (12) +#define BURTC_CTRL_PRESC_MASK (0x7 << BURTC_CTRL_PRESC_SHIFT) +#define BURTC_CTRL_PRESC(v) \ + (((v) << BURTC_CTRL_PRESC_SHIFT) & BURTC_CTRL_PRESC_MASK) +#define BURTC_CTRL_PRESC_DIV1 BURTC_CTRL_PRESC(0) +#define BURTC_CTRL_PRESC_DIV2 BURTC_CTRL_PRESC(1) +#define BURTC_CTRL_PRESC_DIV4 BURTC_CTRL_PRESC(2) +#define BURTC_CTRL_PRESC_DIV8 BURTC_CTRL_PRESC(3) +#define BURTC_CTRL_PRESC_DIV16 BURTC_CTRL_PRESC(4) +#define BURTC_CTRL_PRESC_DIV32 BURTC_CTRL_PRESC(5) +#define BURTC_CTRL_PRESC_DIV64 BURTC_CTRL_PRESC(6) +#define BURTC_CTRL_PRESC_DIV128 BURTC_CTRL_PRESC(7) +#define BURTC_CTRL_PRESC_NODIV BURTC_CTRL_PRESC_DIV1 + +#define BURTC_CTRL_LPCOMPC_SHIFT (5) +#define BURTC_CTRL_LPCOMPC_MASK (0x7 << BURTC_CTRL_LPCOMPC_SHIFT) +#define BURTC_CTRL_LPCOMPC(v) \ + (((v) << BURTC_CTRL_LPCOMPC_SHIFT) & BURTC_CTRL_LPCOMPC_MASK) +#define BURTC_CTRL_LPCOMPC_IGNxLSB BURTC_CTRL_LPCOMPC(x) +#define BURTC_CTRL_LPCOMPC_IGN0LSB BURTC_CTRL_LPCOMPC_IGNxLSB(0) +#define BURTC_CTRL_LPCOMPC_IGN1LSB BURTC_CTRL_LPCOMPC_IGNxLSB(1) +#define BURTC_CTRL_LPCOMPC_IGN2LSB BURTC_CTRL_LPCOMPC_IGNxLSB(2) +#define BURTC_CTRL_LPCOMPC_IGN3LSB BURTC_CTRL_LPCOMPC_IGNxLSB(3) +#define BURTC_CTRL_LPCOMPC_IGN4LSB BURTC_CTRL_LPCOMPC_IGNxLSB(4) +#define BURTC_CTRL_LPCOMPC_IGN5LSB BURTC_CTRL_LPCOMPC_IGNxLSB(5) +#define BURTC_CTRL_LPCOMPC_IGN6LSB BURTC_CTRL_LPCOMPC_IGNxLSB(6) +#define BURTC_CTRL_LPCOMPC_IGN7LSB BURTC_CTRL_LPCOMPC_IGNxLSB(7) + +#define BURTC_CTRL_COMP0TOP (1 << 4) +#define BURTC_CTRL_RSTEN (1 << 3) +#define BURTC_CTRL_DEBUGRUN (1 << 2) + +#define BURTC_CTRL_MODE_SHIFT (0) +#define BURTC_CTRL_MODE_MASK (0x3 << BURTC_CTRL_MODE_SHIFT) +#define BURTC_CTRL_MODE(v) \ + (((v) << BURTC_CTRL_MODE_SHIFT) & BURTC_CTRL_MODE_MASK) +#define BURTC_CTRL_MODE_DISABLE BURTC_CTRL_MODE(0) +#define BURTC_CTRL_MODE_EM2EN BURTC_CTRL_MODE(1) +#define BURTC_CTRL_MODE_EM3EN BURTC_CTRL_MODE(2) +#define BURTC_CTRL_MODE_EM4EN BURTC_CTRL_MODE(3) + +/* BURTC_LPMODE */ +#define BURTC_LPMODE_LPMODE_SHIFT (0) +#define BURTC_LPMODE_LPMODE_MASK (0x3 << BURTC_LPMODE_LPMODE_SHIFT) +#define BURTC_LPMODE_LPMODE(v) \ + (((v) << BURTC_LPMODE_LPMODE_SHIFT) & BURTC_LPMODE_LPMODE_MASK) +#define BURTC_LPMODE_LPMODE_DISABLE BURTC_LPMODE_LPMODE(0) +#define BURTC_LPMODE_LPMODE_ENABLE BURTC_LPMODE_LPMODE(1) +#define BURTC_LPMODE_LPMODE_BUEN BURTC_LPMODE_LPMODE(2) + +/* BURTC_LFXOFDET */ +#define BURTC_LFXOFDET_TOP_SHIFT (4) +#define BURTC_LFXOFDET_TOP_MASK (0xF << BURTC_LFXOFDET_TOP_SHIFT) +#define BURTC_LFXOFDET_TOP(v) \ + (((v) << BURTC_LFXOFDET_TOP_SHIFT) & BURTC_LFXOFDET_TOP_MASK) + +#define BURTC_LFXOFDET_OSC_SHIFT (0) +#define BURTC_LFXOFDET_OSC_MASK (0x3 << BURTC_LFXOFDET_OSC_SHIFT) +#define BURTC_LFXOFDET_OSC(v) \ + (((v) << BURTC_LFXOFDET_OSC_SHIFT) & BURTC_LFXOFDET_OSC_MASK) +#define BURTC_LFXOFDET_OSC_DISABLE BURTC_LFXOFDET_OSC(0) +#define BURTC_LFXOFDET_OSC_LFRCO BURTC_LFXOFDET_OSC(1) +#define BURTC_LFXOFDET_OSC_ULFRCO BURTC_LFXOFDET_OSC(2) + +/* BURTC_STATUS */ +#define BURTC_STATUS_RAMWERR (1 << 2) +#define BURTC_STATUS_BUMODETS (1 << 1) +#define BURTC_STATUS_LPMODEACT (1 << 0) + +/* BURTC_CMD */ +#define BURTC_CMD_CLRSTATUS (1 << 0) + +/* BURTC_POWERDOWN */ +#define BURTC_POWERDOWN_RAM (1 << 0) + +/* BURTC_LOCK */ +#define BURTC_LOCK_LOCKKEY_SHIFT (0) +#define BURTC_LOCK_LOCKKEY_MASK (0xFFFF << BURTC_LOCK_LOCKKEY_SHIFT) +#define BURTC_LOCK_LOCKKEY_UNLOCKED (0x0000 << BURTC_LOCK_LOCKKEY_SHIFT) +#define BURTC_LOCK_LOCKKEY_LOCKED (0x0001 << BURTC_LOCK_LOCKKEY_SHIFT) +#define BURTC_LOCK_LOCKKEY_LOCK (0x0000 << BURTC_LOCK_LOCKKEY_SHIFT) +#define BURTC_LOCK_LOCKKEY_UNLOCK (0xAEE8 << BURTC_LOCK_LOCKKEY_SHIFT) + +/* BURTC_IF */ +#define BURTC_IF_LFXOFAIL (1 << 2) +#define BURTC_IF_COMP0 (1 << 1) +#define BURTC_IF_OF (1 << 0) + +/* BURTC_IFS */ +#define BURTC_IFS_LFXOFAIL (1 << 2) +#define BURTC_IFS_COMP0 (1 << 1) +#define BURTC_IFS_OF (1 << 0) + +/* BURTC_IFC */ +#define BURTC_IFC_LFXOFAIL (1 << 2) +#define BURTC_IFC_COMP0 (1 << 1) +#define BURTC_IFC_OF (1 << 0) + +/* BURTC_IEN */ +#define BURTC_IEN_LFXOFAIL (1 << 2) +#define BURTC_IEN_COMP0 (1 << 1) +#define BURTC_IEN_OF (1 << 0) + +/* BURTC_FREEZE */ +#define BURTC_FREEZE_REGFREEZE (1 << 0) + +/* BURTC_SYNCBUSY */ +#define BURTC_SYNCBUSY_COMP0 (1 << 1) +#define BURTC_SYNCBUSY_LPMODE (1 << 0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/cmu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/cmu.h new file mode 100644 index 00000000..168955b7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/cmu.h @@ -0,0 +1,705 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_CMU_H +#define LIBOPENCM3_EFM32_CMU_H + +#include +#include + +#define CMU_CTRL MMIO32(CMU_BASE + 0x000) +#define CMU_HFCORECLKDIV MMIO32(CMU_BASE + 0x004) +#define CMU_HFPERCLKDIV MMIO32(CMU_BASE + 0x008) +#define CMU_HFRCOCTRL MMIO32(CMU_BASE + 0x00C) +#define CMU_LFRCOCTRL MMIO32(CMU_BASE + 0x010) +#define CMU_AUXHFRCOCTRL MMIO32(CMU_BASE + 0x014) +#define CMU_CALCTRL MMIO32(CMU_BASE + 0x018) +#define CMU_CALCNT MMIO32(CMU_BASE + 0x01C) +#define CMU_OSCENCMD MMIO32(CMU_BASE + 0x020) +#define CMU_CMD MMIO32(CMU_BASE + 0x024) +#define CMU_LFCLKSEL MMIO32(CMU_BASE + 0x028) +#define CMU_STATUS MMIO32(CMU_BASE + 0x02C) +#define CMU_IF MMIO32(CMU_BASE + 0x030) +#define CMU_IFS MMIO32(CMU_BASE + 0x034) +#define CMU_IFC MMIO32(CMU_BASE + 0x038) +#define CMU_IEN MMIO32(CMU_BASE + 0x03C) +#define CMU_HFCORECLKEN0 MMIO32(CMU_BASE + 0x040) +#define CMU_HFPERCLKEN0 MMIO32(CMU_BASE + 0x044) +#define CMU_SYNCBUSY MMIO32(CMU_BASE + 0x050) +#define CMU_FREEZE MMIO32(CMU_BASE + 0x054) +#define CMU_LFACLKEN0 MMIO32(CMU_BASE + 0x058) +#define CMU_LFBCLKEN0 MMIO32(CMU_BASE + 0x060) +#define CMU_LFAPRESC0 MMIO32(CMU_BASE + 0x068) +#define CMU_LFBPRESC0 MMIO32(CMU_BASE + 0x070) +#define CMU_PCNTCTRL MMIO32(CMU_BASE + 0x078) +#define CMU_LCDCTRL MMIO32(CMU_BASE + 0x07C) +#define CMU_ROUTE MMIO32(CMU_BASE + 0x080) +#define CMU_LOCK MMIO32(CMU_BASE + 0x084) + +/* CMU_CTRL */ +#define CMU_CTRL_HFLE (1 << 30) +#define CMU_CTRL_DBGCLK (1 << 28) + + +#define CMU_CTRL_CLKOUTSEL1_SHIFT (23) +#define CMU_CTRL_CLKOUTSEL1_MASK (0x7 << CMU_CTRL_CLKOUTSEL1_SHIFT) +#define CMU_CTRL_CLKOUTSEL1(v) \ + (((v) << CMU_CTRL_CLKOUTSEL1_SHIFT) & CMU_CTRL_CLKOUTSEL1_MASK) +#define CMU_CTRL_CLKOUTSEL1_LFRCO CMU_CTRL_CLKOUTSEL1(0) +#define CMU_CTRL_CLKOUTSEL1_LFXO CMU_CTRL_CLKOUTSEL1(1) +#define CMU_CTRL_CLKOUTSEL1_HFCLK CMU_CTRL_CLKOUTSEL1(2) +#define CMU_CTRL_CLKOUTSEL1_LFXOQ CMU_CTRL_CLKOUTSEL1(3) +#define CMU_CTRL_CLKOUTSEL1_HFXOQ CMU_CTRL_CLKOUTSEL1(4) +#define CMU_CTRL_CLKOUTSEL1_LFRCOQ CMU_CTRL_CLKOUTSEL1(5) +#define CMU_CTRL_CLKOUTSEL1_HFRCOQ CMU_CTRL_CLKOUTSEL1(6) +#define CMU_CTRL_CLKOUTSEL1_AUXHFRCOQ CMU_CTRL_CLKOUTSEL1(7) + +#define CMU_CTRL_CLKOUTSEL0_SHIFT (23) +#define CMU_CTRL_CLKOUTSEL0_MASK (0x7 << CMU_CTRL_CLKOUTSEL0_SHIFT) +#define CMU_CTRL_CLKOUTSEL0(v) \ + (((v) << CMU_CTRL_CLKOUTSEL0_SHIFT) & CMU_CTRL_CLKOUTSEL0_MASK) +#define CMU_CTRL_CLKOUTSEL0_HFRCO CMU_CTRL_CLKOUTSEL0(0) +#define CMU_CTRL_CLKOUTSEL0_HFXO CMU_CTRL_CLKOUTSEL0(1) +#define CMU_CTRL_CLKOUTSEL0_HFCLK2 CMU_CTRL_CLKOUTSEL0(2) +#define CMU_CTRL_CLKOUTSEL0_HFCLK4 CMU_CTRL_CLKOUTSEL0(3) +#define CMU_CTRL_CLKOUTSEL0_HFCLK8 CMU_CTRL_CLKOUTSEL0(4) +#define CMU_CTRL_CLKOUTSEL0_HFCLK16 CMU_CTRL_CLKOUTSEL0(5) +#define CMU_CTRL_CLKOUTSEL0_ULFRCO CMU_CTRL_CLKOUTSEL0(6) +#define CMU_CTRL_CLKOUTSEL0_AUXHFRCO CMU_CTRL_CLKOUTSEL0(7) + +#define CMU_CTRL_LFXOTIMEOUT_SHIFT (18) +#define CMU_CTRL_LFXOTIMEOUT_MASK (0x3 << CMU_CTRL_LFXOTIMEOUT_SHIFT) +#define CMU_CTRL_LFXOTIMEOUT(v) \ + (((v) << CMU_CTRL_LFXOTIMEOUT_SHIFT) & CMU_CTRL_LFXOTIMEOUT_MASK) +#define CMU_CTRL_LFXOTIMEOUT_8CYCLES CMU_CTRL_LFXOTIMEOUT(0) +#define CMU_CTRL_LFXOTIMEOUT_1KCYCLES CMU_CTRL_LFXOTIMEOUT(1) +#define CMU_CTRL_LFXOTIMEOUT_16KCYCLES CMU_CTRL_LFXOTIMEOUT(2) +#define CMU_CTRL_LFXOTIMEOUT_32KCYCLES CMU_CTRL_LFXOTIMEOUT(3) + +#define CMU_CTRL_LFXOBUFCUR (1 << 17) + +#define CMU_CTRL_HFCLKDIV_SHIFT (14) +#define CMU_CTRL_HFCLKDIV_MASK (0x7 << CMU_CTRL_HFCLKDIV_SHIFT) +#define CMU_CTRL_HFCLKDIV(v) \ + (((v) << CMU_CTRL_HFCLKDIV_SHIFT) & CMU_CTRL_HFCLKDIV_MASK) +#define CMU_CTRL_HFCLKDIV_NODIV CMU_CTRL_HFCLKDIV(0) +#define CMU_CTRL_HFCLKDIV_DIV2 CMU_CTRL_HFCLKDIV(1) +#define CMU_CTRL_HFCLKDIV_DIV3 CMU_CTRL_HFCLKDIV(2) +#define CMU_CTRL_HFCLKDIV_DIV4 CMU_CTRL_HFCLKDIV(3) +#define CMU_CTRL_HFCLKDIV_DIV5 CMU_CTRL_HFCLKDIV(4) +#define CMU_CTRL_HFCLKDIV_DIV6 CMU_CTRL_HFCLKDIV(5) +#define CMU_CTRL_HFCLKDIV_DIV7 CMU_CTRL_HFCLKDIV(6) +#define CMU_CTRL_HFCLKDIV_DIV8 CMU_CTRL_HFCLKDIV(7) + +#define CMU_CTRL_LFXOBOOST (1 << 13) + +#define CMU_CTRL_LFXOMODE_SHIFT (11) +#define CMU_CTRL_LFXOMODE_MASK (0x3 << CMU_CTRL_LFXOMODE_SHIFT) +#define CMU_CTRL_LFXOMODE(v) \ + (((v) << CMU_CTRL_LFXOMODE_SHIFT) & CMU_CTRL_LFXOMODE_MASK) +#define CMU_CTRL_LFXOMODE_XTAL CMU_CTRL_LFXOMODE(0) +#define CMU_CTRL_LFXOMODE_BUFEXTCLK CMU_CTRL_LFXOMODE(1) +#define CMU_CTRL_LFXOMODE_DIGEXTCLK CMU_CTRL_LFXOMODE(2) + +#define CMU_CTRL_HFXOTIMEOUT_SHIFT (9) +#define CMU_CTRL_HFXOTIMEOUT_MASK (0x3 << CMU_CTRL_HFXOTIMEOUT_SHIFT) +#define CMU_CTRL_HFXOTIMEOUT(v) \ + (((v) << CMU_CTRL_HFXOTIMEOUT_SHIFT) & CMU_CTRL_HFXOTIMEOUT_MASK) +#define CMU_CTRL_HFXOTIMEOUT_8CYCLES CMU_CTRL_HFXOTIMEOUT(0) +#define CMU_CTRL_HFXOTIMEOUT_256CYCLES CMU_CTRL_HFXOTIMEOUT(1) +#define CMU_CTRL_HFXOTIMEOUT_1KCYCLES CMU_CTRL_HFXOTIMEOUT(2) +#define CMU_CTRL_HFXOTIMEOUT_16KCYCLES CMU_CTRL_HFXOTIMEOUT(3) + +#define CMU_CTRL_HFXOGLITCHDETEN (1 << 7) + +#define CMU_CTRL_HFXOBUFCUR_SHIFT (5) +#define CMU_CTRL_HFXOBUFCUR_MASK (0x3 << CMU_CTRL_HFXOBUFCUR_SHIFT) +#define CMU_CTRL_HFXOBUFCUR(v) \ + (((v) << CMU_CTRL_HFXOBUFCUR_SHIFT) & CMU_CTRL_HFXOBUFCUR_MASK) +#define CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ CMU_CTRL_HFXOBUFCUR(1) +#define CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ CMU_CTRL_HFXOBUFCUR(3) + +#define CMU_CTRL_HFXOBOOST_SHIFT (2) +#define CMU_CTRL_HFXOBOOST_MASK (0x3 << CMU_CTRL_HFXOBOOST_SHIFT) +#define CMU_CTRL_HFXOBOOST(v) \ + (((v) << CMU_CTRL_HFXOBOOST_SHIFT) & CMU_CTRL_HFXOBOOST_MASK) +#define CMU_CTRL_HFXOBOOST_50PCENT CMU_CTRL_HFXOBOOST(0) +#define CMU_CTRL_HFXOBOOST_70PCENT CMU_CTRL_HFXOBOOST(1) +#define CMU_CTRL_HFXOBOOST_80PCENT CMU_CTRL_HFXOBOOST(2) +#define CMU_CTRL_HFXOBOOST_100PCENT CMU_CTRL_HFXOBOOST(3) + +#define CMU_CTRL_HFXOMODE_SHIFT (0) +#define CMU_CTRL_HFXOMODE_MASK (0x3 << CMU_CTRL_HFXOMODE_SHIFT) +#define CMU_CTRL_HFXOMODE(v) \ + (((v) << CMU_CTRL_HFXOMODE_SHIFT) & CMU_CTRL_HFXOMODE_MASK) +#define CMU_CTRL_HFXOMODE_XTAL CMU_CTRL_HFXOMODE(0) +#define CMU_CTRL_HFXOMODE_BUFEXTCLK CMU_CTRL_HFXOMODE(1) +#define CMU_CTRL_HFXOMODE_DIGEXTCLK CMU_CTRL_HFXOMODE(2) + +/* CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKLEDIV (1 << 8) + +#define CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT (0) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_MASK \ + (0xF << CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT) +#define CMU_HFCORECLKDIV_HFCORECLKDIV(v) \ + (((v) << CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT) & \ + CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK \ + CMU_HFCORECLKDIV_HFCORECLKDIV(0) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK2 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(1) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK4 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(2) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK8 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(3) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK16 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(4) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK32 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(5) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK64 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(6) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK128 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(7) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK256 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(8) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK512 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(9) + +#define CMU_HFCORECLKDIV_HFCORECLKDIV_NODIV \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV2 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK2 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV4 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK4 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV8 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK8 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV16 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK16 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV32 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK32 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV64 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK64 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV128 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK128 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV256 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK256 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV512 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK512 + +/* CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKEN (1 << 8) + +#define CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT (0) +#define CMU_HFPERCLKDIV_HFPERCLKDIV_MASK \ + (0xF << CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT) +#define CMU_HFPERCLKDIV_HFPERCLKDIV(v) \ + (((v) << CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT) & \ + CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK CMU_HFPERCLKDIV_HFPERCLKDIV(0) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK2 CMU_HFPERCLKDIV_HFPERCLKDIV(1) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK4 CMU_HFPERCLKDIV_HFPERCLKDIV(2) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK8 CMU_HFPERCLKDIV_HFPERCLKDIV(3) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK16 CMU_HFPERCLKDIV_HFPERCLKDIV(4) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK32 CMU_HFPERCLKDIV_HFPERCLKDIV(5) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK64 CMU_HFPERCLKDIV_HFPERCLKDIV(6) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK128 CMU_HFPERCLKDIV_HFPERCLKDIV(7) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK256 CMU_HFPERCLKDIV_HFPERCLKDIV(8) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK512 CMU_HFPERCLKDIV_HFPERCLKDIV(9) + +/* CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK* to CMU_HFPERCLKDIV_HFPERCLKHFCLK_DIV* */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_NODIV \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV2 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK2 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV4 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK4 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV8 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK8 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV16 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK16 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV32 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK32 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV64 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK64 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV128 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK128 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV256 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK256 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV512 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK512 + +/* CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_SUDELAY_SHIFT (12) +#define CMU_HFRCOCTRL_SUDELAY_MASK (0x1F << CMU_HFRCOCTRL_SUDELAY_SHIFT) +#define CMU_HFRCOCTRL_SUDELAY(v) \ + ((((v) << CMU_HFRCOCTRL_SUDELAY_SHIFT) & CMU_HFRCOCTRL_SUDELAY_MASK)) + +#define CMU_HFRCOCTRL_BAND_SHIFT (8) +#define CMU_HFRCOCTRL_BAND_MASK (0x7 << CMU_HFRCOCTRL_BAND_SHIFT) +#define CMU_HFRCOCTRL_BAND(v) \ + (((v) << CMU_HFRCOCTRL_BAND_SHIFT) & CMU_HFRCOCTRL_BAND_MASK) +#define CMU_HFRCOCTRL_BAND_1MHZ CMU_HFRCOCTRL_BAND(0) +#define CMU_HFRCOCTRL_BAND_7MHZ CMU_HFRCOCTRL_BAND(1) +#define CMU_HFRCOCTRL_BAND_11MHZ CMU_HFRCOCTRL_BAND(2) +#define CMU_HFRCOCTRL_BAND_14MHZ CMU_HFRCOCTRL_BAND(3) +#define CMU_HFRCOCTRL_BAND_21MHZ CMU_HFRCOCTRL_BAND(4) +#define CMU_HFRCOCTRL_BAND_28MHZ CMU_HFRCOCTRL_BAND(5) + +#define CMU_HFRCOCTRL_TUNING_SHIFT (0) +#define CMU_HFRCOCTRL_TUNING_MASK (0xFF << CMU_HFRCOCTRL_TUNING_SHIFT) +#define CMU_HFRCOCTRL_TUNING(v) \ + (((v) << CMU_HFRCOCTRL_TUNING_SHIFT) & CMU_HFRCOCTRL_TUNING_MASK) + +/* CMU_LFRCOCTRL */ +#define CMU_LFRCOCTRL_TUNING_SHIFT (0) +#define CMU_LFRCOCTRL_TUNING_MASK (0xFF << CMU_LFRCOCTRL_TUNING_SHIFT) +#define CMU_LFRCOCTRL_TUNING(v) \ + (((v) << CMU_LFRCOCTRL_TUNING_SHIFT) & CMU_LFRCOCTRL_TUNING_MASK) + +/* CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_SHIFT (8) +#define CMU_AUXHFRCOCTRL_BAND_MASK (0x7 << CMU_AUXHFRCOCTRL_BAND_SHIFT) +#define CMU_AUXHFRCOCTRL_BAND(v) \ + (((v) << CMU_AUXHFRCOCTRL_BAND_SHIFT) & CMU_AUXHFRCOCTRL_BAND_MASK) +#define CMU_AUXHFRCOCTRL_BAND_1MHZ CMU_AUXHFRCOCTRL_BAND(0) +#define CMU_AUXHFRCOCTRL_BAND_7MHZ CMU_AUXHFRCOCTRL_BAND(1) +#define CMU_AUXHFRCOCTRL_BAND_11MHZ CMU_AUXHFRCOCTRL_BAND(2) +#define CMU_AUXHFRCOCTRL_BAND_14MHZ CMU_AUXHFRCOCTRL_BAND(3) +#define CMU_AUXHFRCOCTRL_BAND_28MHZ CMU_AUXHFRCOCTRL_BAND(4) +#define CMU_AUXHFRCOCTRL_BAND_21MHZ CMU_AUXHFRCOCTRL_BAND(5) + +#define CMU_AUXHFRCOCTRL_TUNING_SHIFT (0) +#define CMU_AUXHFRCOCTRL_TUNING_MASK (0xFF << CMU_AUXHFRCOCTRL_TUNING_SHIFT) +#define CMU_AUXHFRCOCTRL_TUNING(v) \ + (((v) << CMU_AUXHFRCOCTRL_TUNING_SHIFT) & CMU_AUXHFRCOCTRL_TUNING_MASK) + +/* CMU_CALCTRL */ +#define CMU_CALCTRL_CONT (1 << 6) + +#define CMU_CALCTRL_DOWNSEL_SHIFT (3) +#define CMU_CALCTRL_DOWNSEL_MASK (0x7 << CMU_CALCTRL_DOWNSEL_SHIFT) +#define CMU_CALCTRL_DOWNSEL(v) \ + (((v) << CMU_CALCTRL_DOWNSEL_SHIFT) & CMU_CALCTRL_DOWNSEL_MASK) +#define CMU_CALCTRL_DOWNSEL_HFCLK CMU_CALCTRL_DOWNSEL(0) +#define CMU_CALCTRL_DOWNSEL_HFXO CMU_CALCTRL_DOWNSEL(1) +#define CMU_CALCTRL_DOWNSEL_LFXO CMU_CALCTRL_DOWNSEL(2) +#define CMU_CALCTRL_DOWNSEL_HFRCO CMU_CALCTRL_DOWNSEL(3) +#define CMU_CALCTRL_DOWNSEL_LFRCO CMU_CALCTRL_DOWNSEL(4) +#define CMU_CALCTRL_DOWNSEL_AUXHFRCO CMU_CALCTRL_DOWNSEL(5) + +#define CMU_CALCTRL_UPSEL_SHIFT (3) +#define CMU_CALCTRL_UPSEL_MASK (0x7 << CMU_CALCTRL_UPSEL_SHIFT) +#define CMU_CALCTRL_UPSEL(v) \ + (((v) << CMU_CALCTRL_UPSEL_SHIFT) & CMU_CALCTRL_UPSEL_MASK) +#define CMU_CALCTRL_UPSEL_HFXO CMU_CALCTRL_UPSEL(0) +#define CMU_CALCTRL_UPSEL_LFXO CMU_CALCTRL_UPSEL(1) +#define CMU_CALCTRL_UPSEL_HFRCO CMU_CALCTRL_UPSEL(2) +#define CMU_CALCTRL_UPSEL_LFRCO CMU_CALCTRL_UPSEL(3) +#define CMU_CALCTRL_UPSEL_AUXHFRCO CMU_CALCTRL_UPSEL(4) + +/* CMU_CALCNT */ +#define CMU_CALCNT_CALCNT_SHIFT (0) +#define CMU_CALCNT_CALCNT_MASK (0xFFFFF << CMU_CALCNT_CALCNT_SHIFT) +#define CMU_CALCNT_CALCNT(v) \ + (((v) << CMU_CALCNT_CALCNT_SHIFT) & CMU_CALCNT_CALCNT_MASK) + +/* CMU_OSCENCMD */ +#define CMU_OSCENCMD_LFXODIS (1 << 9) +#define CMU_OSCENCMD_LFXOEN (1 << 8) +#define CMU_OSCENCMD_LFRCODIS (1 << 7) +#define CMU_OSCENCMD_LFRCOEN (1 << 6) +#define CMU_OSCENCMD_AUXHFRCODIS (1 << 5) +#define CMU_OSCENCMD_AUXHFRCOEN (1 << 4) +#define CMU_OSCENCMD_HFXODIS (1 << 3) +#define CMU_OSCENCMD_HFXOEN (1 << 2) +#define CMU_OSCENCMD_HFRCODIS (1 << 1) +#define CMU_OSCENCMD_HFRCOEN (1 << 0) + +/* CMU_CMD */ +#define CMU_CMD_USBCCLKSEL_SHIFT (5) +#define CMU_CMD_USBCCLKSEL_MASK (0x3 << CMU_CMD_USBCCLKSEL_SHIFT) +#define CMU_CMD_USBCCLKSEL(v) \ + (((v) << CMU_CMD_USBCCLKSEL_SHIFT) & CMU_CMD_USBCCLKSEL_MASK) +#define CMU_CMD_USBCCLKSEL_HFCLKNODIV CMU_CMD_USBCCLKSEL(1) +#define CMU_CMD_USBCCLKSEL_LFXO CMU_CMD_USBCCLKSEL(2) +#define CMU_CMD_USBCCLKSEL_LFRCO CMU_CMD_USBCCLKSEL(3) + +#define CMU_CMD_CALSTOP (1 << 4) +#define CMU_CMD_CALSTART (1 << 3) + +#define CMU_CMD_HFCLKSEL_SHIFT (0) +#define CMU_CMD_HFCLKSEL_MASK (0x7 << CMU_CMD_HFCLKSEL_SHIFT) +#define CMU_CMD_HFCLKSEL(v) \ + (((v) << CMU_CMD_HFCLKSEL_SHIFT) & CMU_CMD_HFCLKSEL_MASK) +#define CMU_CMD_HFCLKSEL_HFRCO CMU_CMD_HFCLKSEL(1) +#define CMU_CMD_HFCLKSEL_HFXO CMU_CMD_HFCLKSEL(2) +#define CMU_CMD_HFCLKSEL_LFRCO CMU_CMD_HFCLKSEL(3) +#define CMU_CMD_HFCLKSEL_LFXO CMU_CMD_HFCLKSEL(4) + +/* CMU_LFCLKSEL */ +#define CMU_LFCLKSEL_LFBE (1 << 20) +#define CMU_LFCLKSEL_LFAE (1 << 16) + +#define CMU_LFCLKSEL_LFB_SHIFT (2) +#define CMU_LFCLKSEL_LFB_MASK (0x3 << CMU_LFCLKSEL_LFB_MASK) +#define CMU_LFCLKSEL_LFB(v) \ + (((v) << CMU_LFCLKSEL_LFB_MASK) & CMU_LFCLKSEL_LFB_MASK) + +#define CMU_LFCLKSEL_LFA_SHIFT (0) +#define CMU_LFCLKSEL_LFA_MASK (0x3 << CMU_LFCLKSEL_LFA_MASK) +#define CMU_LFCLKSEL_LFA(v) \ + (((v) << CMU_LFCLKSEL_LFA_MASK) & CMU_LFCLKSEL_LFA_MASK) + +/* CMU_STATUS */ +#define CMU_STATUS_USBCLFRCOSEL (1 << 17) +#define CMU_STATUS_USBCLFXOSEL (1 << 16) +#define CMU_STATUS_USBCHFCLKSEL (1 << 15) +#define CMU_STATUS_CALBSY (1 << 14) +#define CMU_STATUS_LFXOSEL (1 << 13) +#define CMU_STATUS_LFRCOSEL (1 << 12) +#define CMU_STATUS_HFXOSEL (1 << 11) +#define CMU_STATUS_HFRCOSEL (1 << 10) +#define CMU_STATUS_LFXORDY (1 << 9) +#define CMU_STATUS_LFXOENS (1 << 8) +#define CMU_STATUS_LFRCORDY (1 << 7) +#define CMU_STATUS_LFRCOENS (1 << 6) +#define CMU_STATUS_AUXHFRCORDY (1 << 5) +#define CMU_STATUS_AUXHFRCOENS (1 << 4) +#define CMU_STATUS_HFXORDY (1 << 3) +#define CMU_STATUS_HFXOENS (1 << 2) +#define CMU_STATUS_HFRCORDY (1 << 1) +#define CMU_STATUS_HFRCOENS (1 << 0) + +/* CMU_IF */ +#define CMU_IF_USBCHFCLKSEL (1 << 7) +#define CMU_IF_CALOF (1 << 6) +#define CMU_IF_CALRDY (1 << 5) +#define CMU_IF_AUXHFRCORDY (1 << 4) +#define CMU_IF_LFXORDY (1 << 3) +#define CMU_IF_LFRCORDY (1 << 2) +#define CMU_IF_HFXORDY (1 << 1) +#define CMU_IF_HFRCORDY (1 << 0) + +/* CMU_IFS */ +#define CMU_IFS_USBCHFCLKSEL (1 << 7) +#define CMU_IFS_CALOF (1 << 6) +#define CMU_IFS_CALRDY (1 << 5) +#define CMU_IFS_AUXHFRCORDY (1 << 4) +#define CMU_IFS_LFXORDY (1 << 3) +#define CMU_IFS_LFRCORDY (1 << 2) +#define CMU_IFS_HFXORDY (1 << 1) +#define CMU_IFS_HFRCORDY (1 << 0) + +/* CMU_IFC */ +#define CMU_IFC_USBCHFCLKSEL (1 << 7) +#define CMU_IFC_CALOF (1 << 6) +#define CMU_IFC_CALRDY (1 << 5) +#define CMU_IFC_AUXHFRCORDY (1 << 4) +#define CMU_IFC_LFXORDY (1 << 3) +#define CMU_IFC_LFRCORDY (1 << 2) +#define CMU_IFC_HFXORDY (1 << 1) +#define CMU_IFC_HFRCORDY (1 << 0) + +/* CMU_IEN */ +#define CMU_IEN_USBCHFCLKSEL (1 << 7) +#define CMU_IEN_CALOF (1 << 6) +#define CMU_IEN_CALRDY (1 << 5) +#define CMU_IEN_AUXHFRCORDY (1 << 4) +#define CMU_IEN_LFXORDY (1 << 3) +#define CMU_IEN_LFRCORDY (1 << 2) +#define CMU_IEN_HFXORDY (1 << 1) +#define CMU_IEN_HFRCORDY (1 << 0) + +/* CMU_HFCORECLKEN0 */ +#define CMU_HFCORECLKEN0_EBI (1 << 5) +#define CMU_HFCORECLKEN0_LE (1 << 4) +#define CMU_HFCORECLKEN0_USB (1 << 3) +#define CMU_HFCORECLKEN0_USBC (1 << 2) +#define CMU_HFCORECLKEN0_AES (1 << 1) +#define CMU_HFCORECLKEN0_DMA (1 << 0) + +/* CMU_HFPERCLKEN0 */ +#define CMU_HFPERCLKEN0_DAC0 (1 << 17) +#define CMU_HFPERCLKEN0_ADC0 (1 << 16) +#define CMU_HFPERCLKEN0_PRS (1 << 15) +#define CMU_HFPERCLKEN0_VCMP (1 << 14) +#define CMU_HFPERCLKEN0_GPIO (1 << 13) +#define CMU_HFPERCLKEN0_I2C1 (1 << 12) +#define CMU_HFPERCLKEN0_I2C0 (1 << 11) +#define CMU_HFPERCLKEN0_ACMP1 (1 << 10) +#define CMU_HFPERCLKEN0_ACMP0 (1 << 9) +#define CMU_HFPERCLKEN0_TIMER3 (1 << 8) +#define CMU_HFPERCLKEN0_TIMER2 (1 << 7) +#define CMU_HFPERCLKEN0_TIMER1 (1 << 6) +#define CMU_HFPERCLKEN0_TIMER0 (1 << 5) +#define CMU_HFPERCLKEN0_UART1 (1 << 4) +#define CMU_HFPERCLKEN0_UART0 (1 << 3) +#define CMU_HFPERCLKEN0_USART2 (1 << 2) +#define CMU_HFPERCLKEN0_USART1 (1 << 1) +#define CMU_HFPERCLKEN0_USART0 (1 << 0) + +/* CMU_SYNCBUSY */ +#define CMU_SYNCBUSY_LFBPRESC0 (1 << 6) +#define CMU_SYNCBUSY_LFBCLKEN0 (1 << 4) +#define CMU_SYNCBUSY_LFAPRESC0 (1 << 2) +#define CMU_SYNCBUSY_LFACLKEN0 (1 << 0) + +/* CMU_FREEZE */ +#define CMU_FREEZE_REGFREEZE (1 << 0) + +/* CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_LCD (1 << 3) +#define CMU_LFACLKEN0_LETIMER0 (1 << 2) +#define CMU_LFACLKEN0_RTC (1 << 1) +#define CMU_LFACLKEN0_LESENSE (1 << 0) + +/* CMU_LFBCLKEN0 */ +#define CMU_LFBCLKEN0_LEUART1 (1 << 1) +#define CMU_LFBCLKEN0_LEUART0 (1 << 0) + +/* CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_LCD_SHIFT (12) +#define CMU_LFAPRESC0_LCD_MASK (0x3 << CMU_LFAPRESC0_LCD_SHIFT) +#define CMU_LFAPRESC0_LCD(v) \ + (((v) << CMU_LFAPRESC0_LCD_SHIFT) & CMU_LFAPRESC0_LCD_MASK) +#define CMU_LFAPRESC0_LCD_DIV16 CMU_LFAPRESC0_LCD(0) +#define CMU_LFAPRESC0_LCD_DIV32 CMU_LFAPRESC0_LCD(1) +#define CMU_LFAPRESC0_LCD_DIV64 CMU_LFAPRESC0_LCD(2) +#define CMU_LFAPRESC0_LCD_DIV128 CMU_LFAPRESC0_LCD(3) + +#define CMU_LFAPRESC0_LETIMER0_SHIFT (8) +#define CMU_LFAPRESC0_LETIMER0_MASK (0xF << CMU_LFAPRESC0_LETIMER0_SHIFT) +#define CMU_LFAPRESC0_LETIMER0(v) \ + (((v) << CMU_LFAPRESC0_LETIMER0_SHIFT) & CMU_LFAPRESC0_LETIMER0_MASK) +#define CMU_LFAPRESC0_LETIMER0_DIV1 CMU_LFAPRESC0_LETIMER0(0) +#define CMU_LFAPRESC0_LETIMER0_DIV2 CMU_LFAPRESC0_LETIMER0(1) +#define CMU_LFAPRESC0_LETIMER0_DIV4 CMU_LFAPRESC0_LETIMER0(2) +#define CMU_LFAPRESC0_LETIMER0_DIV8 CMU_LFAPRESC0_LETIMER0(3) +#define CMU_LFAPRESC0_LETIMER0_DIV16 CMU_LFAPRESC0_LETIMER0(4) +#define CMU_LFAPRESC0_LETIMER0_DIV32 CMU_LFAPRESC0_LETIMER0(5) +#define CMU_LFAPRESC0_LETIMER0_DIV64 CMU_LFAPRESC0_LETIMER0(6) +#define CMU_LFAPRESC0_LETIMER0_DIV128 CMU_LFAPRESC0_LETIMER0(7) +#define CMU_LFAPRESC0_LETIMER0_DIV256 CMU_LFAPRESC0_LETIMER0(8) +#define CMU_LFAPRESC0_LETIMER0_DIV512 CMU_LFAPRESC0_LETIMER0(9) +#define CMU_LFAPRESC0_LETIMER0_DIV1024 CMU_LFAPRESC0_LETIMER0(10) +#define CMU_LFAPRESC0_LETIMER0_DIV2048 CMU_LFAPRESC0_LETIMER0(11) +#define CMU_LFAPRESC0_LETIMER0_DIV4096 CMU_LFAPRESC0_LETIMER0(12) +#define CMU_LFAPRESC0_LETIMER0_DIV8192 CMU_LFAPRESC0_LETIMER0(13) +#define CMU_LFAPRESC0_LETIMER0_DIV16384 CMU_LFAPRESC0_LETIMER0(14) +#define CMU_LFAPRESC0_LETIMER0_DIV32768 CMU_LFAPRESC0_LETIMER0(15) +#define CMU_LFAPRESC0_LETIMER0_NODIV CMU_LFAPRESC0_LETIMER0_DIV1 + +#define CMU_LFAPRESC0_RTC_SHIFT (4) +#define CMU_LFAPRESC0_RTC_MASK (0xF << CMU_LFAPRESC0_RTC_SHIFT) +#define CMU_LFAPRESC0_RTC(v) \ + (((v) << CMU_LFAPRESC0_RTC_SHIFT) & CMU_LFAPRESC0_RTC_MASK) +#define CMU_LFAPRESC0_RTC_DIV1 CMU_LFAPRESC0_RTC(0) +#define CMU_LFAPRESC0_RTC_DIV2 CMU_LFAPRESC0_RTC(1) +#define CMU_LFAPRESC0_RTC_DIV4 CMU_LFAPRESC0_RTC(2) +#define CMU_LFAPRESC0_RTC_DIV8 CMU_LFAPRESC0_RTC(3) +#define CMU_LFAPRESC0_RTC_DIV16 CMU_LFAPRESC0_RTC(4) +#define CMU_LFAPRESC0_RTC_DIV32 CMU_LFAPRESC0_RTC(5) +#define CMU_LFAPRESC0_RTC_DIV64 CMU_LFAPRESC0_RTC(6) +#define CMU_LFAPRESC0_RTC_DIV128 CMU_LFAPRESC0_RTC(7) +#define CMU_LFAPRESC0_RTC_DIV256 CMU_LFAPRESC0_RTC(8) +#define CMU_LFAPRESC0_RTC_DIV512 CMU_LFAPRESC0_RTC(9) +#define CMU_LFAPRESC0_RTC_DIV1024 CMU_LFAPRESC0_RTC(10) +#define CMU_LFAPRESC0_RTC_DIV2048 CMU_LFAPRESC0_RTC(11) +#define CMU_LFAPRESC0_RTC_DIV4096 CMU_LFAPRESC0_RTC(12) +#define CMU_LFAPRESC0_RTC_DIV8192 CMU_LFAPRESC0_RTC(13) +#define CMU_LFAPRESC0_RTC_DIV16384 CMU_LFAPRESC0_RTC(14) +#define CMU_LFAPRESC0_RTC_DIV32768 CMU_LFAPRESC0_RTC(15) +#define CMU_LFAPRESC0_RTC_NODIV CMU_LFAPRESC0_RTC_DIV1 + +#define CMU_LFAPRESC0_LESENSE_SHIFT (12) +#define CMU_LFAPRESC0_LESENSE_MASK (0x3 << CMU_LFAPRESC0_LESENSE_SHIFT) +#define CMU_LFAPRESC0_LESENSE(v) \ + (((v) << CMU_LFAPRESC0_LESENSE_SHIFT) & CMU_LFAPRESC0_LESENSE_MASK) +#define CMU_LFAPRESC0_LESENSE_DIV1 CMU_LFAPRESC0_LESENSE(0) +#define CMU_LFAPRESC0_LESENSE_DIV2 CMU_LFAPRESC0_LESENSE(1) +#define CMU_LFAPRESC0_LESENSE_DIV4 CMU_LFAPRESC0_LESENSE(2) +#define CMU_LFAPRESC0_LESENSE_DIV8 CMU_LFAPRESC0_LESENSE(3) +#define CMU_LFAPRESC0_LESENSE_NODIV CMU_LFAPRESC0_LESENSE_DIV1 + +/* CMU_LFBPRESC0 */ +#define CMU_LFBPRESC0_LEUART1_SHIFT (4) +#define CMU_LFBPRESC0_LEUART1_MASK (0x3 << CMU_LFBPRESC0_LEUART1_SHIFT) +#define CMU_LFBPRESC0_LEUART1(v) \ + (((v) << CMU_LFBPRESC0_LEUART1_SHIFT) & CMU_LFBPRESC0_LEUART1_MASK) +#define CMU_LFBPRESC0_LEUART1_DIV1 CMU_LFBPRESC0_LEUART1(0) +#define CMU_LFBPRESC0_LEUART1_DIV2 CMU_LFBPRESC0_LEUART1(1) +#define CMU_LFBPRESC0_LEUART1_DIV4 CMU_LFBPRESC0_LEUART1(2) +#define CMU_LFBPRESC0_LEUART1_DIV8 CMU_LFBPRESC0_LEUART1(3) +#define CMU_LFBPRESC0_LEUART1_NODIV CMU_LFBPRESC0_LEUART1_DIV1 + +#define CMU_LFBPRESC0_LEUART0_SHIFT (0) +#define CMU_LFBPRESC0_LEUART0_MASK (0x3 << CMU_LFBPRESC0_LEUART0_SHIFT) +#define CMU_LFBPRESC0_LEUART0(v) \ + (((v) << CMU_LFBPRESC0_LEUART0_SHIFT) & CMU_LFBPRESC0_LEUART0_MASK) +#define CMU_LFBPRESC0_LEUART0_DIV1 CMU_LFBPRESC0_LEUART0(0) +#define CMU_LFBPRESC0_LEUART0_DIV2 CMU_LFBPRESC0_LEUART0(1) +#define CMU_LFBPRESC0_LEUART0_DIV4 CMU_LFBPRESC0_LEUART0(2) +#define CMU_LFBPRESC0_LEUART0_DIV8 CMU_LFBPRESC0_LEUART0(3) +#define CMU_LFBPRESC0_LEUART0_NODIV CMU_LFBPRESC0_LEUART0_DIV1 + +/* CMU_PCNTCTRL */ +#define CMU_PCNTCTRL_PCNT2CLKSE (1 << 5) +#define CMU_PCNTCTRL_PCNT2CLKEN (1 << 4) +#define CMU_PCNTCTRL_PCNT1CLKSEL (1 << 3) +#define CMU_PCNTCTRL_PCNT1CLKEN (1 << 2) +#define CMU_PCNTCTRL_PCNT0CLKSEL (1 << 1) +#define CMU_PCNTCTRL_PCNT0CLKEN (1 << 0) + +/* CMU_LCDCTRL */ +#define CMU_LCDCTRL_VBFDIV_SHIFT (4) +#define CMU_LCDCTRL_VBFDIV_MASK (0xF << CMU_LCDCTRL_VBFDIV_SHIFT) +#define CMU_LCDCTRL_VBFDIV(v) \ + (((v) << CMU_LCDCTRL_VBFDIV_SHIFT) & CMU_LCDCTRL_VBFDIV_MASK) +#define CMU_LCDCTRL_VBFDIV_DIV1 CMU_LCDCTRL_VBFDIV(0) +#define CMU_LCDCTRL_VBFDIV_DIV2 CMU_LCDCTRL_VBFDIV(1) +#define CMU_LCDCTRL_VBFDIV_DIV4 CMU_LCDCTRL_VBFDIV(2) +#define CMU_LCDCTRL_VBFDIV_DIV8 CMU_LCDCTRL_VBFDIV(3) +#define CMU_LCDCTRL_VBFDIV_DIV16 CMU_LCDCTRL_VBFDIV(4) +#define CMU_LCDCTRL_VBFDIV_DIV32 CMU_LCDCTRL_VBFDIV(5) +#define CMU_LCDCTRL_VBFDIV_DIV64 CMU_LCDCTRL_VBFDIV(6) +#define CMU_LCDCTRL_VBFDIV_DIV128 CMU_LCDCTRL_VBFDIV(7) +#define CMU_LCDCTRL_VBFDIV_NODIV CMU_LCDCTRL_VBFDIV_DIV1 + +#define CMU_LCDCTRL_VBOOSTEN (1 << 3) + +#define CMU_LCDCTRL_FDIV_SHIFT (0) +#define CMU_LCDCTRL_FDIV_MASK (0x3 << CMU_LCDCTRL_FDIV_SHIFT) +#define CMU_LCDCTRL_FDIV(v) \ + (((v) & CMU_LCDCTRL_FDIV_MASK) << CMU_LCDCTRL_FDIV_SHIFT) + +/* CMU_ROUTE */ +#define CMU_ROUTE_LOCATION_SHIFT (2) +#define CMU_ROUTE_LOCATION_MASK (0x7 << CMU_ROUTE_LOCATION_SHIFT) +#define CMU_ROUTE_LOCATION_LOCx(i) \ + (((i) << CMU_ROUTE_LOCATION_SHIFT) & CMU_ROUTE_LOCATION_MASK) +#define CMU_ROUTE_LOCATION_LOC0 CMU_ROUTE_LOCATION_LOCx(0) +#define CMU_ROUTE_LOCATION_LOC1 CMU_ROUTE_LOCATION_LOCx(1) +#define CMU_ROUTE_LOCATION_LOC2 CMU_ROUTE_LOCATION_LOCx(2) + +#define CMU_ROUTE_CLKOUT1PEN (1 << 1) +#define CMU_ROUTE_CLKOUT0PEN (1 << 0) + +/* CMU_LOCK */ +#define CMU_LOCK_LOCKKEY_SHIFT (0) +#define CMU_LOCK_LOCKKEY_MASK (0xFFFF << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_UNLOCKED (0x0000 << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_LOCKED (0x0001 << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_LOCK (0x0000 << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_UNLOCK (0x580E << CMU_LOCK_LOCKKEY_SHIFT) + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum cmu_periph_clken { + /* CMU_PCNTCTRL */ + CMU_PCNT2 = _REG_BIT(0x078, 4), + CMU_PCNT1 = _REG_BIT(0x078, 2), + CMU_PCNT0 = _REG_BIT(0x078, 0), + + /* CMU_LFBCLKEN0 */ + CMU_LEUART1 = _REG_BIT(0x060, 1), + CMU_LEUART0 = _REG_BIT(0x060, 0), + + /* CMU_LFACLKEN0 */ + CMU_LCD = _REG_BIT(0x058, 3), + CMU_LETIMER0 = _REG_BIT(0x058, 2), + CMU_RTC = _REG_BIT(0x058, 1), + CMU_LESENSE = _REG_BIT(0x058, 0), + + /* CMU_HFPERCLKEN0 */ + CMU_DAC0 = _REG_BIT(0x044, 17), + CMU_ADC0 = _REG_BIT(0x044, 16), + CMU_PRS = _REG_BIT(0x044, 15), + CMU_VCMP = _REG_BIT(0x044, 14), + CMU_GPIO = _REG_BIT(0x044, 13), + CMU_I2C1 = _REG_BIT(0x044, 12), + CMU_I2C0 = _REG_BIT(0x044, 11), + CMU_ACMP1 = _REG_BIT(0x044, 10), + CMU_ACMP0 = _REG_BIT(0x044, 9), + CMU_TIMER3 = _REG_BIT(0x044, 8), + CMU_TIMER2 = _REG_BIT(0x044, 7), + CMU_TIMER1 = _REG_BIT(0x044, 6), + CMU_TIMER0 = _REG_BIT(0x044, 5), + CMU_UART1 = _REG_BIT(0x044, 4), + CMU_UART0 = _REG_BIT(0x044, 3), + CMU_USART2 = _REG_BIT(0x044, 2), + CMU_USART1 = _REG_BIT(0x044, 1), + CMU_USART0 = _REG_BIT(0x044, 0), + + /* CMU_HFCORECLKEN0 */ + CMU_EBI = _REG_BIT(0x040, 5), + CMU_LE = _REG_BIT(0x040, 4), + CMU_USB = _REG_BIT(0x040, 3), + CMU_USBC = _REG_BIT(0x040, 2), + CMU_AES = _REG_BIT(0x040, 1), + CMU_DMA = _REG_BIT(0x040, 0) +}; + +enum cmu_osc { + HFRCO, /**< Internal, 1 - 28Mhz */ + LFRCO, /**< Internal, 32.768kHz */ + ULFRCO, /**< Internal, 1Khz */ + HFXO, /**< External, 4-48Mhz */ + LFXO, /**< External, 32.768kHz */ + AUXHFRCO, /**< Internal, 1-28Mhz */ +}; + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void cmu_enable_lock(void); +void cmu_disable_lock(void); +bool cmu_get_lock_flag(void); + +void cmu_periph_clock_enable(enum cmu_periph_clken periph); +void cmu_periph_clock_disable(enum cmu_periph_clken periph); + +/* TODO: CMU_CTRL, CMU_HFCORECLKDIV, CMU_HFPERCLKDIV, CMU_HFRCOCTRL, + * CMU_LFRCOCTRL, CMU_AUXHFRCOCTRL, CMU_CALCTRL, CMU_CALCNT */ + +void cmu_osc_on(enum cmu_osc osc); +void cmu_osc_off(enum cmu_osc osc); + +/* TODO: CMU_CMD, CMU_LFCLKSEL */ + +/* TODO: portions of CMU_STATUS */ +bool cmu_osc_ready_flag(enum cmu_osc osc); +void cmu_wait_for_osc_ready(enum cmu_osc osc); +void cmu_set_hfclk_source(enum cmu_osc osc); +void cmu_set_usbclk_source(enum cmu_osc osc); +enum cmu_osc cmu_get_hfclk_source(void); + +/* TODO: CMU_IF, CMU_IFS, CMU_IFC, CMU_IEN */ + +/* TODO: CMU_SYNCBUSY, CMU_FREEZE, CMU_LFACLKEN0 */ + +/* TODO: CMU_LFAPRESC0, CMU_LFBPRESC0, CMU_PCNTCTRL, CMU_LCDCTRL, CMU_ROUTE */ + +void cmu_clock_setup_in_hfxo_out_48mhz(void); + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dac.h new file mode 100644 index 00000000..1c7b37f3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dac.h @@ -0,0 +1,512 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_DAC_H +#define LIBOPENCM3_EFM32_DAC_H + +#include +#include +#include + +#define DAC_CTRL(base) MMIO32((base) + 0x00) +#define DAC_STATUS(base) MMIO32((base) + 0x04) +#define DAC_CHx_CTRL(base, x) MMIO32((base) + 0x08 + (0x04 * (x))) +#define DAC_CH0CTRL(base) DAC_CHx_CTRL(base, 0) +#define DAC_CH1CTRL(base) DAC_CHx_CTRL(base, 1) +#define DAC_IEN(base) MMIO32((base) + 0x010) +#define DAC_IF(base) MMIO32((base) + 0x014) +#define DAC_IFS(base) MMIO32((base) + 0x018) +#define DAC_IFC(base) MMIO32((base) + 0x01C) +#define DAC_CH0DATA(base) MMIO32((base) + 0x020) +#define DAC_CH1DATA(base) MMIO32((base) + 0x024) +#define DAC_COMBDATA(base) MMIO32((base) + 0x028) +#define DAC_CAL(base) MMIO32((base) + 0x02C) +#define DAC_BIASPROG(base) MMIO32((base) + 0x030) +#define DAC_OPACTRL(base) MMIO32((base) + 0x054) +#define DAC_OPAOFFSET(base) MMIO32((base) + 0x058) +#define DAC_OPA0MUX(base) MMIO32((base) + 0x05C) +#define DAC_OPA1MUX(base) MMIO32((base) + 0x060) +#define DAC_OPA2MUX(base) MMIO32((base) + 0x064) + +/* DAC_CTRL */ +#define DAC_CTRL_REFRSEL_SHIFT (20) +#define DAC_CTRL_REFRSEL_MASK (0x3 << DAC_CTRL_REFRSEL_SHIFT) +#define DAC_CTRL_REFRSEL(v) \ + (((v) << DAC_CTRL_REFRSEL_SHIFT) & DAC_CTRL_REFRSEL_MASK) +#define DAC_CTRL_REFRSEL_8CYCLES DAC_CTRL_REFRSEL(0) +#define DAC_CTRL_REFRSEL_16CYCLES DAC_CTRL_REFRSEL(1) +#define DAC_CTRL_REFRSEL_32CYCLES DAC_CTRL_REFRSEL(2) +#define DAC_CTRL_REFRSEL_64CYCLES DAC_CTRL_REFRSEL(3) + +#define DAC_CTRL_PRESC_SHIFT (16) +#define DAC_CTRL_PRESC_MASK (0x7 << DAC_CTRL_PRESC_SHIFT) +#define DAC_CTRL_PRESC(v) \ + (((v) << DAC_CTRL_PRESC_SHIFT) & DAC_CTRL_PRESC_MASK) +#define DAC_CTRL_PRESC_DIV1 DAC_CTRL_PRESC(0) +#define DAC_CTRL_PRESC_DIV2 DAC_CTRL_PRESC(1) +#define DAC_CTRL_PRESC_DIV4 DAC_CTRL_PRESC(2) +#define DAC_CTRL_PRESC_DIV8 DAC_CTRL_PRESC(3) +#define DAC_CTRL_PRESC_DIV16 DAC_CTRL_PRESC(4) +#define DAC_CTRL_PRESC_DIV32 DAC_CTRL_PRESC(5) +#define DAC_CTRL_PRESC_DIV64 DAC_CTRL_PRESC(6) +#define DAC_CTRL_PRESC_DIV128 DAC_CTRL_PRESC(7) +#define DAC_CTRL_PRESC_NODIV DAC_CTRL_PRESC_DIV1 + +#define DAC_CTRL_REFSEL_SHIFT (8) +#define DAC_CTRL_REFSEL_MASK (0x3 << DAC_CTRL_REFSEL_SHIFT) +#define DAC_CTRL_REFSEL(v) \ + (((v) << DAC_CTRL_REFSEL_SHIFT) & DAC_CTRL_REFSEL_MASK) +#define DAC_CTRL_REFSEL_1V25 DAC_CTRL_REFSEL(0) +#define DAC_CTRL_REFSEL_2V5 DAC_CTRL_REFSEL(1) +#define DAC_CTRL_REFSEL_VDD DAC_CTRL_REFSEL(2) + +#define DAC_CTRL_CH0PRESCRST (1 << 7) +#define DAC_CTRL_OUTENPRS (1 << 6) + +#define DAC_CTRL_OUTMODE_SHIFT (4) +#define DAC_CTRL_OUTMODE_MASK (0x3 << DAC_CTRL_OUTMODE_SHIFT) +#define DAC_CTRL_OUTMODE(v) \ + (((v) << DAC_CTRL_OUTMODE_SHIFT) & DAC_CTRL_OUTMODE_MASK) +#define DAC_CTRL_OUTMODE_DISABLE DAC_CTRL_OUTMODE(0) +#define DAC_CTRL_OUTMODE_PIN DAC_CTRL_OUTMODE(1) +#define DAC_CTRL_OUTMODE_ADC DAC_CTRL_OUTMODE(2) +#define DAC_CTRL_OUTMODE_PINADC DAC_CTRL_OUTMODE(3) + +#define DAC_CTRL_CONVMODE_SHIFT (2) +#define DAC_CTRL_CONVMODE_MASK (0x3 << DAC_CTRL_CONVMODE_SHIFT) +#define DAC_CTRL_CONVMODE(v) \ + (((v) << DAC_CTRL_CONVMODE_SHIFT) & DAC_CTRL_CONVMODE_MASK) +#define DAC_CTRL_CONVMODE_CONTINUOUS DAC_CTRL_CONVMODE(0) +#define DAC_CTRL_CONVMODE_SAMPLEHOLD DAC_CTRL_CONVMODE(1) +#define DAC_CTRL_CONVMODE_SAMPLEOFF DAC_CTRL_CONVMODE(2) + +#define DAC_CTRL_SINMODE (1 << 1) +#define DAC_CTRL_DIFF (1 << 0) + +/* DAC_STATUS */ +#define DAC_STATUS_CH1DV (1 << 1) +#define DAC_STATUS_CH0DV (1 << 0) + +/* DAC_CH_CTRL */ +#define DAC_CH_CTRL_PRSSEL_SHIFT (4) +#define DAC_CH_CTRL_PRSSEL_MASK (0xF << DAC_CH_CTRL_PRSSEL_SHIFT) +#define DAC_CH_CTRL_PRSSEL(v) \ + (((v) << DAC_CH_CTRL_PRSSEL_SHIFT) & DAC_CH_CTRL_PRSSEL_MASK) +#define DAC_CH_CTRL_PRSSEL_PRSCHx(x) DAC_CH_CTRL_PRSSEL(x) +#define DAC_CH_CTRL_PRSSEL_PRSCH0 DAC_CH_CTRL_PRSSEL_PRSCHx(0) +#define DAC_CH_CTRL_PRSSEL_PRSCH1 DAC_CH_CTRL_PRSSEL_PRSCHx(1) +#define DAC_CH_CTRL_PRSSEL_PRSCH2 DAC_CH_CTRL_PRSSEL_PRSCHx(2) +#define DAC_CH_CTRL_PRSSEL_PRSCH3 DAC_CH_CTRL_PRSSEL_PRSCHx(3) +#define DAC_CH_CTRL_PRSSEL_PRSCH4 DAC_CH_CTRL_PRSSEL_PRSCHx(4) +#define DAC_CH_CTRL_PRSSEL_PRSCH5 DAC_CH_CTRL_PRSSEL_PRSCHx(5) +#define DAC_CH_CTRL_PRSSEL_PRSCH6 DAC_CH_CTRL_PRSSEL_PRSCHx(6) +#define DAC_CH_CTRL_PRSSEL_PRSCH7 DAC_CH_CTRL_PRSSEL_PRSCHx(7) +#define DAC_CH_CTRL_PRSSEL_PRSCH8 DAC_CH_CTRL_PRSSEL_PRSCHx(8) +#define DAC_CH_CTRL_PRSSEL_PRSCH9 DAC_CH_CTRL_PRSSEL_PRSCHx(9) +#define DAC_CH_CTRL_PRSSEL_PRSCH10 DAC_CH_CTRL_PRSSEL_PRSCHx(10) +#define DAC_CH_CTRL_PRSSEL_PRSCH11 DAC_CH_CTRL_PRSSEL_PRSCHx(11) + +#define DAC_CH_CTRL_PRSEN (1 << 2) +#define DAC_CH_CTRL_REFREN (1 << 1) +#define DAC_CH_CTRL_EN (1 << 0) + +/* DAC_CH0CTRL */ +#define DAC_CH0CTRL_PRSSEL_SHIFT DAC_CH_CTRL_PRSSEL_SHIFT +#define DAC_CH0CTRL_PRSSEL_MASK DAC_CH_CTRL_PRSSEL_MASK +#define DAC_CH0CTRL_PRSSEL(v) DAC_CH_CTRL_PRSSEL(v) +#define DAC_CH0CTRL_PRSSEL_PRSCHx(x) DAC_CH_CTRL_PRSSEL_PRSCHx(x) +#define DAC_CH0CTRL_PRSSEL_PRSCH0 DAC_CH0CTRL_PRSSEL_PRSCH0 +#define DAC_CH0CTRL_PRSSEL_PRSCH1 DAC_CH_CTRL_PRSSEL_PRSCH1 +#define DAC_CH0CTRL_PRSSEL_PRSCH2 DAC_CH_CTRL_PRSSEL_PRSCH2 +#define DAC_CH0CTRL_PRSSEL_PRSCH3 DAC_CH_CTRL_PRSSEL_PRSCH3 +#define DAC_CH0CTRL_PRSSEL_PRSCH4 DAC_CH_CTRL_PRSSEL_PRSCH4 +#define DAC_CH0CTRL_PRSSEL_PRSCH5 DAC_CH_CTRL_PRSSEL_PRSCH5 +#define DAC_CH0CTRL_PRSSEL_PRSCH6 DAC_CH_CTRL_PRSSEL_PRSCH6 +#define DAC_CH0CTRL_PRSSEL_PRSCH7 DAC_CH_CTRL_PRSSEL_PRSCH7 +#define DAC_CH0CTRL_PRSSEL_PRSCH8 DAC_CH_CTRL_PRSSEL_PRSCH8 +#define DAC_CH0CTRL_PRSSEL_PRSCH9 DAC_CH_CTRL_PRSSEL_PRSCH9 +#define DAC_CH0CTRL_PRSSEL_PRSCH10 DAC_CH_CTRL_PRSSEL_PRSCH10 +#define DAC_CH0CTRL_PRSSEL_PRSCH11 DAC_CH_CTRL_PRSSEL_PRSCH11 + +#define DAC_CH0CTRL_PRSEN DAC_CH_CTRL_PRSEN +#define DAC_CH0CTRL_REFREN DAC_CH_CTRL_REFREN +#define DAC_CH0CTRL_EN DAC_CH_CTRL_EN + +/* DAC_CH1CTRL */ +#define DAC_CH1CTRL_PRSSEL_SHIFT DAC_CH_CTRL_PRSSEL_SHIFT +#define DAC_CH1CTRL_PRSSEL_MASK DAC_CH_CTRL_PRSSEL_MASK +#define DAC_CH1CTRL_PRSSEL(v) DAC_CH_CTRL_PRSSEL(v) +#define DAC_CH1CTRL_PRSSEL_PRSCHx(x) DAC_CH_CTRL_PRSSEL_PRSCHx(x) +#define DAC_CH1CTRL_PRSSEL_PRSCH0 DAC_CH_CTRL_PRSSEL_PRSCH0 +#define DAC_CH1CTRL_PRSSEL_PRSCH1 DAC_CH_CTRL_PRSSEL_PRSCH1 +#define DAC_CH1CTRL_PRSSEL_PRSCH2 DAC_CH_CTRL_PRSSEL_PRSCH2 +#define DAC_CH1CTRL_PRSSEL_PRSCH3 DAC_CH_CTRL_PRSSEL_PRSCH3 +#define DAC_CH1CTRL_PRSSEL_PRSCH4 DAC_CH_CTRL_PRSSEL_PRSCH4 +#define DAC_CH1CTRL_PRSSEL_PRSCH5 DAC_CH_CTRL_PRSSEL_PRSCH5 +#define DAC_CH1CTRL_PRSSEL_PRSCH6 DAC_CH_CTRL_PRSSEL_PRSCH6 +#define DAC_CH1CTRL_PRSSEL_PRSCH7 DAC_CH_CTRL_PRSSEL_PRSCH7 +#define DAC_CH1CTRL_PRSSEL_PRSCH8 DAC_CH_CTRL_PRSSEL_PRSCH8 +#define DAC_CH1CTRL_PRSSEL_PRSCH9 DAC_CH_CTRL_PRSSEL_PRSCH9 +#define DAC_CH1CTRL_PRSSEL_PRSCH10 DAC_CH_CTRL_PRSSEL_PRSCH10 +#define DAC_CH1CTRL_PRSSEL_PRSCH11 DAC_CH_CTRL_PRSSEL_PRSCH11 + +#define DAC_CH1CTRL_PRSEN DAC_CH_CTRL_PRSEN +#define DAC_CH1CTRL_REFREN DAC_CH_CTRL_REFREN +#define DAC_CH1CTRL_EN DAC_CH_CTRL_EN + +/* DAC_IEN */ +#define DAC_IEN_CH1UF (5 << 0) +#define DAC_IEN_CH0UF (4 << 0) +#define DAC_IEN_CH1 (1 << 1) +#define DAC_IEN_CH0 (1 << 0) + +/* DAC_IF */ +#define DAC_IF_CH1UF (5 << 0) +#define DAC_IF_CH0UF (4 << 0) +#define DAC_IF_CH1 (1 << 1) +#define DAC_IF_CH0 (1 << 0) + +/* DAC_IFS */ +#define DAC_IFS_CH1UF (5 << 0) +#define DAC_IFS_CH0UF (4 << 0) +#define DAC_IFS_CH1 (1 << 1) +#define DAC_IFS_CH0 (1 << 0) + +/* DAC_IFC */ +#define DAC_IFC_CH1UF (5 << 0) +#define DAC_IFC_CH0UF (4 << 0) +#define DAC_IFC_CH1 (1 << 1) +#define DAC_IFC_CH0 (1 << 0) + +/* DAC_CAL */ +#define DAC_CAL_GAIN_SHIFT (16) +#define DAC_CAL_GAIN_MASK (0x7F << DAC_CAL_GAIN_SHIFT) +#define DAC_CAL_GAIN(v) \ + (((v) << DAC_CAL_GAIN_SHIFT) & DAC_CAL_GAIN_MASK) + +#define DAC_CAL_CH1OFFSET_SHIFT (8) +#define DAC_CAL_CH1OFFSET_MASK (0x3F << DAC_CAL_CH1OFFSET_SHIFT) +#define DAC_CAL_CH1OFFSET(v) \ + (((v) << DAC_CAL_CH1OFFSET_SHIFT) & DAC_CAL_CH1OFFSET_MASK) + +#define DAC_CAL_CH0OFFSET_SHIFT (0) +#define DAC_CAL_CH0OFFSET_MASK (0x3F << DAC_CAL_CH0OFFSET_SHIFT) +#define DAC_CAL_CH0OFFSET(v) \ + (((v) << DAC_CAL_CH0OFFSET_SHIFT) & DAC_CAL_CH0OFFSET_MASK) + +/* DAC_BIASPROG */ +#define DAC_BIASPROG_OPA2HALFBIAS (1 << 14) + +#define DAC_BIASPROG_OPA2BIASPROG_SHIFT (8) +#define DAC_BIASPROG_OPA2BIASPROG_MASK (0xF << DAC_BIASPROG_OPA2BIASPROG_SHIFT) +#define DAC_BIASPROG_OPA2BIASPROG(v) \ + ((((v) << DAC_BIASPROG_OPA2BIASPROG_SHIFT)) & \ + DAC_BIASPROG_OPA2BIASPROG_MASK) + +#define DAC_BIASPROG_HALFBIAS (1 << 6) + +#define DAC_BIASPROG_BIASPROG_SHIFT (0) +#define DAC_BIASPROG_BIASPROG_MASK (0xF << DAC_BIASPROG_BIASPROG_SHIFT) +#define DAC_BIASPROG_BIASPROG(v) \ + ((((v) << DAC_BIASPROG_BIASPROG_SHIFT)) & DAC_BIASPROG_BIASPROG_MASK) + +/* DAC_OPACTRL */ +#define DAC_OPACTRL_OPA2SHORT (1 << 24) +#define DAC_OPACTRL_OPA1SHORT (1 << 23) +#define DAC_OPACTRL_OPA0SHORT (1 << 22) + +#define DAC_OPACTRL_OPA2LPFDIS_SHIFT (16) +#define DAC_OPACTRL_OPA2LPFDIS_MASK (0x3 << DAC_OPACTRL_OPA2LPFDIS_SHIFT) +#define DAC_OPACTRL_OPA2LPFDIS(v) \ + (((v) << DAC_OPACTRL_OPA2LPFDIS_SHIFT) & DAC_OPACTRL_OPA2LPFDIS_MASK) +#define DAC_OPACTRL_OPA2LPFDIS_PLPFDIS DAC_OPACTRL_OPA2LPFDIS(0b01) +#define DAC_OPACTRL_OPA2LPFDIS_NLPFDIS DAC_OPACTRL_OPA2LPFDIS(0b10) + +#define DAC_OPACTRL_OPA1LPFDIS_SHIFT (14) +#define DAC_OPACTRL_OPA1LPFDIS_MASK (0x3 << DAC_OPACTRL_OPA1LPFDIS_SHIFT) +#define DAC_OPACTRL_OPA1LPFDIS(v) \ + (((v) << DAC_OPACTRL_OPA1LPFDIS_SHIFT) & DAC_OPACTRL_OPA1LPFDIS_MASK) +#define DAC_OPACTRL_OPA1LPFDIS_PLPFDIS DAC_OPACTRL_OPA1LPFDIS(0b01) +#define DAC_OPACTRL_OPA1LPFDIS_NLPFDIS DAC_OPACTRL_OPA1LPFDIS(0b10) + +#define DAC_OPACTRL_OPA0LPFDIS_SHIFT (14) +#define DAC_OPACTRL_OPA0LPFDIS_MASK (0x3 << DAC_OPACTRL_OPA0LPFDIS_SHIFT) +#define DAC_OPACTRL_OPA0LPFDIS(v) \ + (((v) << DAC_OPACTRL_OPA0LPFDIS_SHIFT) & DAC_OPACTRL_OPA0LPFDIS_MASK) +#define DAC_OPACTRL_OPA0LPFDIS_PLPFDIS DAC_OPACTRL_OPA0LPFDIS(0b01) +#define DAC_OPACTRL_OPA0LPFDIS_NLPFDIS DAC_OPACTRL_OPA0LPFDIS(0b10) + +#define DAC_OPACTRL_OPA2HCMDIS (1 << 8) +#define DAC_OPACTRL_OPA1HCMDIS (1 << 7) +#define DAC_OPACTRL_OPA0HCMDIS (1 << 6) + +#define DAC_OPACTRL_OPA2EN (1 << 2) +#define DAC_OPACTRL_OPA1EN (1 << 1) +#define DAC_OPACTRL_OPA0EN (1 << 0) + +/* DAC_OPA0MUX */ +#define DAC_OPA0MUX_RESSEL_SHIFT (28) +#define DAC_OPA0MUX_RESSEL_MASK (0x7 << DAC_OPA0MUX_RESSEL_SHIFT) +#define DAC_OPA0MUX_RESSEL_RESSEL(v) \ + ((((v) << DAC_OPA0MUX_RESSEL_SHIFT)) & DAC_OPA0MUX_RESSEL_MASK) +#define DAC_OPA0MUX_RESSEL_RESSEL_RESx(x) DAC_OPA0MUX_RESSEL_RESSEL(x) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES0 DAC_OPA0MUX_RESSEL_RESSEL_RESx(0) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES1 DAC_OPA0MUX_RESSEL_RESSEL_RESx(1) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES2 DAC_OPA0MUX_RESSEL_RESSEL_RESx(2) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES3 DAC_OPA0MUX_RESSEL_RESSEL_RESx(3) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES4 DAC_OPA0MUX_RESSEL_RESSEL_RESx(4) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES5 DAC_OPA0MUX_RESSEL_RESSEL_RESx(5) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES6 DAC_OPA0MUX_RESSEL_RESSEL_RESx(6) +#define DAC_OPA0MUX_RESSEL_RESSEL_RES7 DAC_OPA0MUX_RESSEL_RESSEL_RESx(7) + +#define DAC_OPA0MUX_NEXTOUT (1 << 26) + +#define DAC_OPA0MUX_OUTMODE_SHIFT (22) +#define DAC_OPA0MUX_OUTMODE_MASK (0x3 << DAC_OPA0MUX_OUTMODE_SHIFT) +#define DAC_OPA0MUX_OUTMODE(v) \ + (((v) << DAC_OPA0MUX_OUTMODE_SHIFT) & DAC_OPA0MUX_OUTMODE_MASK) +#define DAC_OPA0MUX_OUTMODE_DISABLE DAC_OPA0MUX_OUTMODE(0) +#define DAC_OPA0MUX_OUTMODE_MAIN DAC_OPA0MUX_OUTMODE(1) +#define DAC_OPA0MUX_OUTMODE_ALT DAC_OPA0MUX_OUTMODE(2) +#define DAC_OPA0MUX_OUTMODE_ALL DAC_OPA0MUX_OUTMODE(3) + +#define DAC_OPA0MUX_OUTPEN_SHIFT (18) +#define DAC_OPA0MUX_OUTPEN_MASK (0x1F << DAC_OPA0MUX_OUTPEN_SHIFT) +#define DAC_OPA0MUX_OUTPEN(v) \ + (((v) << DAC_OPA0MUX_OUTPEN_SHIFT) & DAC_OPA0MUX_OUTPEN_MASK) +#define DAC_OPA0MUX_OUTPEN_OUT0 DAC_OPA0MUX_OUTPEN(1 << 0) +#define DAC_OPA0MUX_OUTPEN_OUT1 DAC_OPA0MUX_OUTPEN(1 << 1) +#define DAC_OPA0MUX_OUTPEN_OUT2 DAC_OPA0MUX_OUTPEN(1 << 2) +#define DAC_OPA0MUX_OUTPEN_OUT3 DAC_OPA0MUX_OUTPEN(1 << 3) +#define DAC_OPA0MUX_OUTPEN_OUT4 DAC_OPA0MUX_OUTPEN(1 << 4) + +#define DAC_OPA0MUX_NPEN (1 << 13) +#define DAC_OPA0MUX_PPEN (1 << 12) + +#define DAC_OPA0MUX_RESINMUX_SHIFT (8) +#define DAC_OPA0MUX_RESINMUX_MASK (0x7 << DAC_OPA0MUX_RESINMUX_SHIFT) +#define DAC_OPA0MUX_RESINMUX(v) \ + (((v) << DAC_OPA0MUX_RESINMUX_SHIFT) & DAC_OPA0MUX_RESINMUX_MASK) +#define DAC_OPA0MUX_RESINMUX_DISABLE DAC_OPA0MUX_RESINMUX(0) +#define DAC_OPA0MUX_RESINMUX_OPA0INP DAC_OPA0MUX_RESINMUX(1) +#define DAC_OPA0MUX_RESINMUX_NEGPAD DAC_OPA0MUX_RESINMUX(2) +#define DAC_OPA0MUX_RESINMUX_POSPAD DAC_OPA0MUX_RESINMUX(3) +#define DAC_OPA0MUX_RESINMUX_VSS DAC_OPA0MUX_RESINMUX(4) + +#define DAC_OPA0MUX_NEGSEL_SHIFT (4) +#define DAC_OPA0MUX_NEGSEL_MASK (0x3 << DAC_OPA0MUX_NEGSEL_SHIFT) +#define DAC_OPA0MUX_NEGSEL(v) \ + (((v) << DAC_OPA0MUX_NEGSEL_SHIFT) & DAC_OPA0MUX_NEGSEL_MASK) +#define DAC_OPA0MUX_NEGSEL_DISABLE DAC_OPA0MUX_NEGSEL(0) +#define DAC_OPA0MUX_NEGSEL_UG DAC_OPA0MUX_NEGSEL(1) +#define DAC_OPA0MUX_NEGSEL_OPATAP DAC_OPA0MUX_NEGSEL(2) +#define DAC_OPA0MUX_NEGSEL_NEGPAD DAC_OPA0MUX_NEGSEL(3) + +#define DAC_OPA0MUX_POSSEL_SHIFT (0) +#define DAC_OPA0MUX_POSSEL_MASK (0x7 << DAC_OPA0MUX_POSSEL_SHIFT) +#define DAC_OPA0MUX_POSSEL(v) \ + (((v) << DAC_OPA0MUX_POSSEL_SHIFT) & DAC_OPA0MUX_POSSEL_MASK) +#define DAC_OPA0MUX_POSSEL_DISABLE DAC_OPA0MUX_POSSEL(0) +#define DAC_OPA0MUX_POSSEL_DAC DAC_OPA0MUX_POSSEL(1) +#define DAC_OPA0MUX_POSSEL_POSPAD DAC_OPA0MUX_POSSEL(2) +#define DAC_OPA0MUX_POSSEL_OPA0INP DAC_OPA0MUX_POSSEL(3) +#define DAC_OPA0MUX_POSSEL_OPATAP DAC_OPA0MUX_POSSEL(4) + +/* DAC_OPA1MUX */ +#define DAC_OPA1MUX_RESSEL_SHIFT (28) +#define DAC_OPA1MUX_RESSEL_MASK (0x7 << DAC_OPA1MUX_RESSEL_SHIFT) +#define DAC_OPA1MUX_RESSEL_RESSEL(v) \ + ((((v) << DAC_OPA1MUX_RESSEL_SHIFT)) & DAC_OPA1MUX_RESSEL_MASK) +#define DAC_OPA1MUX_RESSEL_RESSEL_RESx(x) DAC_OPA1MUX_RESSEL_RESSEL(x) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES0 DAC_OPA1MUX_RESSEL_RESSEL_RESx(0) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES1 DAC_OPA1MUX_RESSEL_RESSEL_RESx(1) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES2 DAC_OPA1MUX_RESSEL_RESSEL_RESx(2) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES3 DAC_OPA1MUX_RESSEL_RESSEL_RESx(3) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES4 DAC_OPA1MUX_RESSEL_RESSEL_RESx(4) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES5 DAC_OPA1MUX_RESSEL_RESSEL_RESx(5) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES6 DAC_OPA1MUX_RESSEL_RESSEL_RESx(6) +#define DAC_OPA1MUX_RESSEL_RESSEL_RES7 DAC_OPA1MUX_RESSEL_RESSEL_RESx(7) + +#define DAC_OPA1MUX_NEXTOUT (1 << 26) + +#define DAC_OPA1MUX_OUTMODE_SHIFT (22) +#define DAC_OPA1MUX_OUTMODE_MASK (0x3 << DAC_OPA1MUX_OUTMODE_SHIFT) +#define DAC_OPA1MUX_OUTMODE(v) \ + (((v) << DAC_OPA1MUX_OUTMODE_SHIFT) & DAC_OPA1MUX_OUTMODE_MASK) +#define DAC_OPA1MUX_OUTMODE_DISABLE DAC_OPA1MUX_OUTMODE(0) +#define DAC_OPA1MUX_OUTMODE_MAIN DAC_OPA1MUX_OUTMODE(1) +#define DAC_OPA1MUX_OUTMODE_ALT DAC_OPA1MUX_OUTMODE(2) +#define DAC_OPA1MUX_OUTMODE_ALL DAC_OPA1MUX_OUTMODE(3) + +#define DAC_OPA1MUX_OUTPEN_SHIFT (18) +#define DAC_OPA1MUX_OUTPEN_MASK (0x1F << DAC_OPA1MUX_OUTPEN_SHIFT) +#define DAC_OPA1MUX_OUTPEN(v) \ + (((v) << DAC_OPA1MUX_OUTPEN_SHIFT) & DAC_OPA1MUX_OUTPEN_MASK) +#define DAC_OPA1MUX_OUTPEN_OUT0 DAC_OPA1MUX_OUTPEN(1 << 0) +#define DAC_OPA1MUX_OUTPEN_OUT1 DAC_OPA1MUX_OUTPEN(1 << 1) +#define DAC_OPA1MUX_OUTPEN_OUT2 DAC_OPA1MUX_OUTPEN(1 << 2) +#define DAC_OPA1MUX_OUTPEN_OUT3 DAC_OPA1MUX_OUTPEN(1 << 3) +#define DAC_OPA1MUX_OUTPEN_OUT4 DAC_OPA1MUX_OUTPEN(1 << 4) + +#define DAC_OPA1MUX_NPEN (1 << 13) +#define DAC_OPA1MUX_PPEN (1 << 12) + +#define DAC_OPA1MUX_RESINMUX_SHIFT (8) +#define DAC_OPA1MUX_RESINMUX_MASK (0x7 << DAC_OPA1MUX_RESINMUX_SHIFT) +#define DAC_OPA1MUX_RESINMUX(v) \ + (((v) << DAC_OPA1MUX_RESINMUX_SHIFT) & DAC_OPA1MUX_RESINMUX_MASK) +#define DAC_OPA1MUX_RESINMUX_DISABLE DAC_OPA1MUX_RESINMUX(0) +#define DAC_OPA1MUX_RESINMUX_OPA0INP DAC_OPA1MUX_RESINMUX(1) +#define DAC_OPA1MUX_RESINMUX_NEGPAD DAC_OPA1MUX_RESINMUX(2) +#define DAC_OPA1MUX_RESINMUX_POSPAD DAC_OPA1MUX_RESINMUX(3) +#define DAC_OPA1MUX_RESINMUX_VSS DAC_OPA1MUX_RESINMUX(4) + +#define DAC_OPA1MUX_NEGSEL_SHIFT (4) +#define DAC_OPA1MUX_NEGSEL_MASK (0x3 << DAC_OPA1MUX_NEGSEL_SHIFT) +#define DAC_OPA1MUX_NEGSEL(v) \ + (((v) << DAC_OPA1MUX_NEGSEL_SHIFT) & DAC_OPA1MUX_NEGSEL_MASK) +#define DAC_OPA1MUX_NEGSEL_DISABLE DAC_OPA1MUX_NEGSEL(0) +#define DAC_OPA1MUX_NEGSEL_UG DAC_OPA1MUX_NEGSEL(1) +#define DAC_OPA1MUX_NEGSEL_OPATAP DAC_OPA1MUX_NEGSEL(2) +#define DAC_OPA1MUX_NEGSEL_NEGPAD DAC_OPA1MUX_NEGSEL(3) + +#define DAC_OPA1MUX_POSSEL_SHIFT (0) +#define DAC_OPA1MUX_POSSEL_MASK (0x7 << DAC_OPA1MUX_POSSEL_SHIFT) +#define DAC_OPA1MUX_POSSEL(v) \ + (((v) << DAC_OPA1MUX_POSSEL_SHIFT) & DAC_OPA1MUX_POSSEL_MASK) +#define DAC_OPA1MUX_POSSEL_DISABLE DAC_OPA1MUX_POSSEL(0) +#define DAC_OPA1MUX_POSSEL_DAC DAC_OPA1MUX_POSSEL(1) +#define DAC_OPA1MUX_POSSEL_POSPAD DAC_OPA1MUX_POSSEL(2) +#define DAC_OPA1MUX_POSSEL_OPA0INP DAC_OPA1MUX_POSSEL(3) +#define DAC_OPA1MUX_POSSEL_OPATAP DAC_OPA1MUX_POSSEL(4) + + +/* DAC_OPA2MUX */ +#define DAC_OPA2MUX_RESSEL_SHIFT (28) +#define DAC_OPA2MUX_RESSEL_MASK (0x7 << DAC_OPA2MUX_RESSEL_SHIFT) +#define DAC_OPA2MUX_RESSEL_RESSEL(v) \ + ((((v) << DAC_OPA2MUX_RESSEL_SHIFT)) & DAC_OPA2MUX_RESSEL_MASK) +#define DAC_OPA2MUX_RESSEL_RESSEL_RESx(x) DAC_OPA2MUX_RESSEL_RESSEL(x) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES0 DAC_OPA2MUX_RESSEL_RESSEL_RESx(0) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES1 DAC_OPA2MUX_RESSEL_RESSEL_RESx(1) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES2 DAC_OPA2MUX_RESSEL_RESSEL_RESx(2) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES3 DAC_OPA2MUX_RESSEL_RESSEL_RESx(3) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES4 DAC_OPA2MUX_RESSEL_RESSEL_RESx(4) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES5 DAC_OPA2MUX_RESSEL_RESSEL_RESx(5) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES6 DAC_OPA2MUX_RESSEL_RESSEL_RESx(6) +#define DAC_OPA2MUX_RESSEL_RESSEL_RES7 DAC_OPA2MUX_RESSEL_RESSEL_RESx(7) + +#define DAC_OPA2MUX_NEXTOUT (1 << 26) + +#define DAC_OPA2MUX_OUTMODE (1 << 22) + +#define DAC_OPA2MUX_OUTPEN_SHIFT (14) +#define DAC_OPA2MUX_OUTPEN_MASK (0x3 << DAC_OPA2MUX_OUTPEN_SHIFT) +#define DAC_OPA2MUX_OUTPEN(v) \ + (((v) << DAC_OPA2MUX_OUTPEN_SHIFT) & DAC_OPA2MUX_OUTPEN_MASK) +#define DAC_OPA2MUX_OUTPEN_OUT0 DAC_OPA2MUX_OUTPEN(0) +#define DAC_OPA2MUX_OUTPEN_OUT1 DAC_OPA2MUX_OUTPEN(1) + +#define DAC_OPA2MUX_NPEN (1 << 13) +#define DAC_OPA2MUX_PPEN (1 << 12) + +#define DAC_OPA2MUX_RESINMUX_SHIFT (8) +#define DAC_OPA2MUX_RESINMUX_MASK (0x7 << DAC_OPA2MUX_RESINMUX_SHIFT) +#define DAC_OPA2MUX_RESINMUX(v) \ + (((v) << DAC_OPA2MUX_RESINMUX_SHIFT) & DAC_OPA2MUX_RESINMUX_MASK) +#define DAC_OPA2MUX_RESINMUX_DISABLE DAC_OPA2MUX_RESINMUX(0) +#define DAC_OPA2MUX_RESINMUX_OPA1INP DAC_OPA2MUX_RESINMUX(1) +#define DAC_OPA2MUX_RESINMUX_NEGPAD DAC_OPA2MUX_RESINMUX(2) +#define DAC_OPA2MUX_RESINMUX_POSPAD DAC_OPA2MUX_RESINMUX(3) +#define DAC_OPA2MUX_RESINMUX_VSS DAC_OPA2MUX_RESINMUX(4) + +#define DAC_OPA2MUX_NEGSEL_SHIFT (4) +#define DAC_OPA2MUX_NEGSEL_MASK (0x3 << DAC_OPA2MUX_NEGSEL_SHIFT) +#define DAC_OPA2MUX_NEGSEL(v) \ + (((v) << DAC_OPA2MUX_NEGSEL_SHIFT) & DAC_OPA2MUX_NEGSEL_MASK) +#define DAC_OPA2MUX_NEGSEL_DISABLE DAC_OPA2MUX_NEGSEL(0) +#define DAC_OPA2MUX_NEGSEL_UG DAC_OPA2MUX_NEGSEL(1) +#define DAC_OPA2MUX_NEGSEL_OPATAP DAC_OPA2MUX_NEGSEL(2) +#define DAC_OPA2MUX_NEGSEL_NEGPAD DAC_OPA2MUX_NEGSEL(3) + +#define DAC_OPA2MUX_POSSEL_SHIFT (0) +#define DAC_OPA2MUX_POSSEL_MASK (0x7 << DAC_OPA2MUX_POSSEL_SHIFT) +#define DAC_OPA2MUX_POSSEL(v) \ + (((v) << DAC_OPA2MUX_POSSEL_SHIFT) & DAC_OPA2MUX_POSSEL_MASK) +#define DAC_OPA2MUX_POSSEL_DISABLE DAC_OPA2MUX_POSSEL(0) +#define DAC_OPA2MUX_POSSEL_DAC DAC_OPA2MUX_POSSEL(1) +#define DAC_OPA2MUX_POSSEL_POSPAD DAC_OPA2MUX_POSSEL(2) +#define DAC_OPA2MUX_POSSEL_OPA1INP DAC_OPA2MUX_POSSEL(3) +#define DAC_OPA2MUX_POSSEL_OPATAP DAC_OPA2MUX_POSSEL(4) + +/* DAC0 */ +#define DAC0 DAC0_BASE +#define DAC0_CTRL DAC_CTRL(DAC0) +#define DAC0_STATUS DAC_STATUS(DAC0) +#define DAC0_CH0CTRL DAC_CH0CTRL(DAC0) +#define DAC0_CH1CTRL DAC_CH1CTRL(DAC0) +#define DAC0_IEN DAC_IEN(DAC0) +#define DAC0_IF DAC_IF(DAC0) +#define DAC0_IFS DAC_IFS(DAC0) +#define DAC0_IFC DAC_IFC(DAC0) +#define DAC0_CH0DATA DAC_CH0DATA(DAC0) +#define DAC0_CH1DATA DAC_CH1DATA(DAC0) +#define DAC0_COMBDATA DAC_COMBDATA(DAC0) +#define DAC0_CAL DAC_CAL(DAC0) +#define DAC0_BIASPROG DAC_BIASPROG(DAC0) +#define DAC0_OPACTRL DAC_OPACTRL(DAC0) +#define DAC0_OPAOFFSET DAC_OPAOFFSET(DAC0) +#define DAC0_OPAOFFSET DAC_OPAOFFSET(DAC0) +#define DAC0_OPA1MUX DAC_OPA1MUX(DAC0) +#define DAC0_OPA2MUX DAC_OPA2MUX(DAC0) + +/** @defgroup dac_ch DAC Channel Number +@ingroup dac_defines + +@{*/ +enum dac_ch { + DAC_CH0 = 0, + DAC_CH1 +}; +/**@}*/ + +BEGIN_DECLS + +void dac_set_refresh_cycle(uint32_t dac_base, uint32_t refrsel); +void dac_set_clock_prescaler(uint32_t dac_base, uint32_t presc); +void dac_set_reference(uint32_t dac_base, uint32_t refsel); +void dac_set_out_mode(uint32_t dac_base, uint32_t outmode); +void dac_set_conversion_mode(uint32_t dac_base, uint32_t convmode); +void dac_enable_sine(uint32_t dac_base); +void dac_disable_sine(uint32_t dac_base); + +void dac_set_prs_trigger(uint32_t dac_base, enum dac_ch dac_chan, + enum prs_ch prs_chan); +void dac_enable_prs_trigger(uint32_t dac_base, enum dac_ch ch); +void dac_disable_prs_trigger(uint32_t dac_base, enum dac_ch ch); +void dac_enable_auto_refresh(uint32_t dac_base, enum dac_ch ch); +void dac_disable_auto_refresh(uint32_t dac_base, enum dac_ch ch); + +void dac_enable_channel(uint32_t dac_base, enum dac_ch ch); +void dac_disable_channel(uint32_t dac_base, enum dac_ch ch); + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dma.h new file mode 100644 index 00000000..b6fffb8b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/dma.h @@ -0,0 +1,912 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_DMA_H +#define LIBOPENCM3_EFM32_DMA_H + +#include +#include + +/* + * As per the datasheet, it is an PL230 (licenced from ARM) + * note: but only implement 12 channel (PL230 can have upto 32 channels) + * + * in-future: we can move this to a common peripherial directory + * that is idependent of core and as well as uC. + * something like device tree in Linux kernel + * + * note: DMA_STATUS contain the number of PL230 channel are implemented + */ + +#define DMA DMA_BASE + +#define DMA_STATUS MMIO32(DMA_BASE + 0x000) +#define DMA_CONFIG MMIO32(DMA_BASE + 0x004) +#define DMA_CTRLBASE MMIO32(DMA_BASE + 0x008) +#define DMA_ALTCTRLBASE MMIO32(DMA_BASE + 0x00C) + +#define DMA_CHWAITSTATUS MMIO32(DMA_BASE + 0x010) +#define DMA_CHSWREQ MMIO32(DMA_BASE + 0x014) +#define DMA_CHUSEBURSTS MMIO32(DMA_BASE + 0x018) +#define DMA_CHUSEBURSTC MMIO32(DMA_BASE + 0x01C) +#define DMA_CHREQMASKS MMIO32(DMA_BASE + 0x020) +#define DMA_CHREQMASKC MMIO32(DMA_BASE + 0x024) +#define DMA_CHENS MMIO32(DMA_BASE + 0x028) +#define DMA_CHENC MMIO32(DMA_BASE + 0x02C) +#define DMA_CHALTS MMIO32(DMA_BASE + 0x030) +#define DMA_CHALTC MMIO32(DMA_BASE + 0x034) +#define DMA_CHPRIS MMIO32(DMA_BASE + 0x038) +#define DMA_CHPRIC MMIO32(DMA_BASE + 0x03C) +#define DMA_ERRORC MMIO32(DMA_BASE + 0x04C) +#define DMA_CHREQSTATUS MMIO32(DMA_BASE + 0xE10) +#define DMA_CHSREQSTATUS MMIO32(DMA_BASE + 0xE18) +#define DMA_IF MMIO32(DMA_BASE + 0x1000) +#define DMA_IFS MMIO32(DMA_BASE + 0x1004) +#define DMA_IFC MMIO32(DMA_BASE + 0x1008) +#define DMA_IEN MMIO32(DMA_BASE + 0x100C) +#define DMA_CTRL MMIO32(DMA_BASE + 0x1010) +#define DMA_RDS MMIO32(DMA_BASE + 0x1014) + +#define DMA_LOOPx(i) MMIO32(DMA_BASE + 0x1020 + ((i) * 0x4)) +#define DMA_LOOP0 DMA_LOOPx(0) +#define DMA_LOOP1 DMA_LOOPx(1) + +#define DMA_RECTx(i) MMIO32(DMA_BASE + 0x1060 + ((i) * 0x4)) +#define DMA_RECT0 DMA_RECT(0) + +#define DMA_CHx_CTRL(i) MMIO32(DMA_BASE + 0x1100 + ((i) * 0x4)) +#define DMA_CH0_CTRL DMA_CHx_CTRL(0) +#define DMA_CH1_CTRL DMA_CHx_CTRL(1) +#define DMA_CH2_CTRL DMA_CHx_CTRL(2) +#define DMA_CH3_CTRL DMA_CHx_CTRL(3) +#define DMA_CH4_CTRL DMA_CHx_CTRL(4) +#define DMA_CH5_CTRL DMA_CHx_CTRL(5) +#define DMA_CH6_CTRL DMA_CHx_CTRL(6) +#define DMA_CH7_CTRL DMA_CHx_CTRL(7) +#define DMA_CH8_CTRL DMA_CHx_CTRL(8) +#define DMA_CH9_CTRL DMA_CHx_CTRL(9) +#define DMA_CH10_CTRL DMA_CHx_CTRL(10) +#define DMA_CH11_CTRL DMA_CHx_CTRL(11) + +/* DMA_STATUS */ +#define DMA_STATUS_CHNUM_SHIFT (16) +#define DMA_STATUS_CHNUM_MASK (0x1F << DMA_STATUS_CHNUM_SHIFT) + +#define DMA_STATUS_STATE_SHIFT (4) +#define DMA_STATUS_STATE_MASK (0xF << DMA_STATUS_STATE_SHIFT) +#define DMA_STATUS_STATE(v) \ + (((v) << DMA_STATUS_STATE_SHIFT) & DMA_STATUS_STATE_MASK) +#define DMA_STATUS_STATE_IDLE DMA_STATUS_STATE(0) +#define DMA_STATUS_STATE_RDCHCTRLDATA DMA_STATUS_STATE(1) +#define DMA_STATUS_STATE_RDSRCENDPTR DMA_STATUS_STATE(2) +#define DMA_STATUS_STATE_RDDSTENDPTR DMA_STATUS_STATE(3) +#define DMA_STATUS_STATE_RDSRCDATA DMA_STATUS_STATE(4) +#define DMA_STATUS_STATE_WRDSTDATA DMA_STATUS_STATE(5) +#define DMA_STATUS_STATE_WAITREQCLR DMA_STATUS_STATE(6) +#define DMA_STATUS_STATE_WRCHCTRLDATA DMA_STATUS_STATE(7) +#define DMA_STATUS_STATE_STALLED DMA_STATUS_STATE(8) +#define DMA_STATUS_STATE_DONE DMA_STATUS_STATE(9) +#define DMA_STATUS_STATE_PERSCATTRANS DMA_STATUS_STATE(10) + +#define DMA_STATUS_EN (1 << 0) + +/* DMA_CONFIG */ +#define DMA_CONFIG_CHPROT (1 << 5) +#define DMA_CONFIG_EN (1 << 0) + +/* DMA_CHWAITSTATUS */ +#define DMA_CHWAITSTATUS_CHxWAITSTATUS(i) (1 << (i)) +#define DMA_CHWAITSTATUS_CH11WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(11) +#define DMA_CHWAITSTATUS_CH10WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(10) +#define DMA_CHWAITSTATUS_CH9WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(9) +#define DMA_CHWAITSTATUS_CH8WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(8) +#define DMA_CHWAITSTATUS_CH7WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(7) +#define DMA_CHWAITSTATUS_CH6WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(6) +#define DMA_CHWAITSTATUS_CH5WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(5) +#define DMA_CHWAITSTATUS_CH4WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(4) +#define DMA_CHWAITSTATUS_CH3WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(3) +#define DMA_CHWAITSTATUS_CH2WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(2) +#define DMA_CHWAITSTATUS_CH1WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(1) +#define DMA_CHWAITSTATUS_CH0WAITSTATUS DMA_CHWAITSTATUS_CHxWAITSTATUS(0) + +/* DMA_CHSWREQ */ +#define DMA_CHSWREQ_CHxSWREQ(i) (1 << (i)) +#define DMA_CHSWREQ_CH11SWREQ DMA_CHSWREQ_CHxSWREQ(11) +#define DMA_CHSWREQ_CH10SWREQ DMA_CHSWREQ_CHxSWREQ(10) +#define DMA_CHSWREQ_CH9SWREQ DMA_CHSWREQ_CHxSWREQ(9) +#define DMA_CHSWREQ_CH8SWREQ DMA_CHSWREQ_CHxSWREQ(8) +#define DMA_CHSWREQ_CH7SWREQ DMA_CHSWREQ_CHxSWREQ(7) +#define DMA_CHSWREQ_CH6SWREQ DMA_CHSWREQ_CHxSWREQ(6) +#define DMA_CHSWREQ_CH5SWREQ DMA_CHSWREQ_CHxSWREQ(5) +#define DMA_CHSWREQ_CH4SWREQ DMA_CHSWREQ_CHxSWREQ(4) +#define DMA_CHSWREQ_CH3SWREQ DMA_CHSWREQ_CHxSWREQ(3) +#define DMA_CHSWREQ_CH2SWREQ DMA_CHSWREQ_CHxSWREQ(2) +#define DMA_CHSWREQ_CH1SWREQ DMA_CHSWREQ_CHxSWREQ(1) +#define DMA_CHSWREQ_CH0SWREQ DMA_CHSWREQ_CHxSWREQ(0) + +/* DMA_CHUSEBURSTS */ +#define DMA_CHUSEBURSTS_CHxSUSEBURSTS(i) (1 << (i)) +#define DMA_CHUSEBURSTS_CH11SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(11) +#define DMA_CHUSEBURSTS_CH10SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(10) +#define DMA_CHUSEBURSTS_CH9SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(9) +#define DMA_CHUSEBURSTS_CH8SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(8) +#define DMA_CHUSEBURSTS_CH7SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(7) +#define DMA_CHUSEBURSTS_CH6SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(6) +#define DMA_CHUSEBURSTS_CH5SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(5) +#define DMA_CHUSEBURSTS_CH4SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(4) +#define DMA_CHUSEBURSTS_CH3SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(3) +#define DMA_CHUSEBURSTS_CH2SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(2) +#define DMA_CHUSEBURSTS_CH1SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(1) +#define DMA_CHUSEBURSTS_CH0SUSEBURSTS DMA_CHUSEBURSTS_CHxSUSEBURSTS(0) + +/* DMA_CHUSEBURSTC */ +#define DMA_CHUSEBURSTC_CHxSUSEBURSTC(i) (1 << (i)) +#define DMA_CHUSEBURSTC_CH11SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(11) +#define DMA_CHUSEBURSTC_CH10SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(10) +#define DMA_CHUSEBURSTC_CH9SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(9) +#define DMA_CHUSEBURSTC_CH8SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(8) +#define DMA_CHUSEBURSTC_CH7SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(7) +#define DMA_CHUSEBURSTC_CH6SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(6) +#define DMA_CHUSEBURSTC_CH5SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(5) +#define DMA_CHUSEBURSTC_CH4SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(4) +#define DMA_CHUSEBURSTC_CH3SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(3) +#define DMA_CHUSEBURSTC_CH2SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(2) +#define DMA_CHUSEBURSTC_CH1SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(1) +#define DMA_CHUSEBURSTC_CH0SUSEBURSTC DMA_CHUSEBURSTC_CHxSUSEBURSTC(0) + +/* DMA_CHREQMASKS */ +#define DMA_CHREQMASKS_CHxSREQMASKS(i) (1 << (i)) +#define DMA_CHREQMASKS_CH11SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(11) +#define DMA_CHREQMASKS_CH10SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(10) +#define DMA_CHREQMASKS_CH9SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(9) +#define DMA_CHREQMASKS_CH8SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(8) +#define DMA_CHREQMASKS_CH7SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(7) +#define DMA_CHREQMASKS_CH6SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(6) +#define DMA_CHREQMASKS_CH5SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(5) +#define DMA_CHREQMASKS_CH4SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(4) +#define DMA_CHREQMASKS_CH3SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(3) +#define DMA_CHREQMASKS_CH2SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(2) +#define DMA_CHREQMASKS_CH1SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(1) +#define DMA_CHREQMASKS_CH0SREQMASKS DMA_CHREQMASKS_CHxSREQMASKS(0) + +/* DMA_CHREQMASKC */ +#define DMA_CHREQMASKC_CHxSREQMASKC(i) (1 << (i)) +#define DMA_CHREQMASKC_CH11SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(11) +#define DMA_CHREQMASKC_CH10SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(10) +#define DMA_CHREQMASKC_CH9SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(9) +#define DMA_CHREQMASKC_CH8SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(8) +#define DMA_CHREQMASKC_CH7SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(7) +#define DMA_CHREQMASKC_CH6SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(6) +#define DMA_CHREQMASKC_CH5SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(5) +#define DMA_CHREQMASKC_CH4SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(4) +#define DMA_CHREQMASKC_CH3SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(3) +#define DMA_CHREQMASKC_CH2SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(2) +#define DMA_CHREQMASKC_CH1SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(1) +#define DMA_CHREQMASKC_CH0SREQMASKC DMA_CHREQMASKC_CHxSREQMASKC(0) + +/* DMA_CHENS */ +#define DMA_CHENS_CHxSENS(i) (1 << (i)) +#define DMA_CHENS_CH11SENS DMA_CHENS_CHxSENS(11) +#define DMA_CHENS_CH10SENS DMA_CHENS_CHxSENS(10) +#define DMA_CHENS_CH9SENS DMA_CHENS_CHxSENS(9) +#define DMA_CHENS_CH8SENS DMA_CHENS_CHxSENS(8) +#define DMA_CHENS_CH7SENS DMA_CHENS_CHxSENS(7) +#define DMA_CHENS_CH6SENS DMA_CHENS_CHxSENS(6) +#define DMA_CHENS_CH5SENS DMA_CHENS_CHxSENS(5) +#define DMA_CHENS_CH4SENS DMA_CHENS_CHxSENS(4) +#define DMA_CHENS_CH3SENS DMA_CHENS_CHxSENS(3) +#define DMA_CHENS_CH2SENS DMA_CHENS_CHxSENS(2) +#define DMA_CHENS_CH1SENS DMA_CHENS_CHxSENS(1) +#define DMA_CHENS_CH0SENS DMA_CHENS_CHxSENS(0) + +/* DMA_CHENC */ +#define DMA_CHENC_CHxSENC(i) (1 << (i)) +#define DMA_CHENC_CH11SENC DMA_CHENC_CHxSENC(11) +#define DMA_CHENC_CH10SENC DMA_CHENC_CHxSENC(10) +#define DMA_CHENC_CH9SENC DMA_CHENC_CHxSENC(9) +#define DMA_CHENC_CH8SENC DMA_CHENC_CHxSENC(8) +#define DMA_CHENC_CH7SENC DMA_CHENC_CHxSENC(7) +#define DMA_CHENC_CH6SENC DMA_CHENC_CHxSENC(6) +#define DMA_CHENC_CH5SENC DMA_CHENC_CHxSENC(5) +#define DMA_CHENC_CH4SENC DMA_CHENC_CHxSENC(4) +#define DMA_CHENC_CH3SENC DMA_CHENC_CHxSENC(3) +#define DMA_CHENC_CH2SENC DMA_CHENC_CHxSENC(2) +#define DMA_CHENC_CH1SENC DMA_CHENC_CHxSENC(1) +#define DMA_CHENC_CH0SENC DMA_CHENC_CHxSENC(0) + +/* DMA_CHALTS */ +#define DMA_CHALTS_CHxSALTS(i) (1 << (i)) +#define DMA_CHALTS_CH11SALTS DMA_CHALTS_CHxSALTS(11) +#define DMA_CHALTS_CH10SALTS DMA_CHALTS_CHxSALTS(10) +#define DMA_CHALTS_CH9SALTS DMA_CHALTS_CHxSALTS(9) +#define DMA_CHALTS_CH8SALTS DMA_CHALTS_CHxSALTS(8) +#define DMA_CHALTS_CH7SALTS DMA_CHALTS_CHxSALTS(7) +#define DMA_CHALTS_CH6SALTS DMA_CHALTS_CHxSALTS(6) +#define DMA_CHALTS_CH5SALTS DMA_CHALTS_CHxSALTS(5) +#define DMA_CHALTS_CH4SALTS DMA_CHALTS_CHxSALTS(4) +#define DMA_CHALTS_CH3SALTS DMA_CHALTS_CHxSALTS(3) +#define DMA_CHALTS_CH2SALTS DMA_CHALTS_CHxSALTS(2) +#define DMA_CHALTS_CH1SALTS DMA_CHALTS_CHxSALTS(1) +#define DMA_CHALTS_CH0SALTS DMA_CHALTS_CHxSALTS(0) + +/* DMA_CHALTC */ +#define DMA_CHALTC_CHxSALTC(i) (1 << (i)) +#define DMA_CHALTC_CH11SALTC DMA_CHALTC_CHxSALTC(11) +#define DMA_CHALTC_CH10SALTC DMA_CHALTC_CHxSALTC(10) +#define DMA_CHALTC_CH9SALTC DMA_CHALTC_CHxSALTC(9) +#define DMA_CHALTC_CH8SALTC DMA_CHALTC_CHxSALTC(8) +#define DMA_CHALTC_CH7SALTC DMA_CHALTC_CHxSALTC(7) +#define DMA_CHALTC_CH6SALTC DMA_CHALTC_CHxSALTC(6) +#define DMA_CHALTC_CH5SALTC DMA_CHALTC_CHxSALTC(5) +#define DMA_CHALTC_CH4SALTC DMA_CHALTC_CHxSALTC(4) +#define DMA_CHALTC_CH3SALTC DMA_CHALTC_CHxSALTC(3) +#define DMA_CHALTC_CH2SALTC DMA_CHALTC_CHxSALTC(2) +#define DMA_CHALTC_CH1SALTC DMA_CHALTC_CHxSALTC(1) +#define DMA_CHALTC_CH0SALTC DMA_CHALTC_CHxSALTC(0) + +/* DMA_CHPRIS */ +#define DMA_CHPRIS_CHxSPRIC(i) (1 << (i)) +#define DMA_CHPRIS_CH11SPRIC DMA_CHPRIS_CHxSPRIC(11) +#define DMA_CHPRIS_CH10SPRIC DMA_CHPRIS_CHxSPRIC(10) +#define DMA_CHPRIS_CH9SPRIC DMA_CHPRIS_CHxSPRIC(9) +#define DMA_CHPRIS_CH8SPRIC DMA_CHPRIS_CHxSPRIC(8) +#define DMA_CHPRIS_CH7SPRIC DMA_CHPRIS_CHxSPRIC(7) +#define DMA_CHPRIS_CH6SPRIC DMA_CHPRIS_CHxSPRIC(6) +#define DMA_CHPRIS_CH5SPRIC DMA_CHPRIS_CHxSPRIC(5) +#define DMA_CHPRIS_CH4SPRIC DMA_CHPRIS_CHxSPRIC(4) +#define DMA_CHPRIS_CH3SPRIC DMA_CHPRIS_CHxSPRIC(3) +#define DMA_CHPRIS_CH2SPRIC DMA_CHPRIS_CHxSPRIC(2) +#define DMA_CHPRIS_CH1SPRIC DMA_CHPRIS_CHxSPRIC(1) +#define DMA_CHPRIS_CH0SPRIC DMA_CHPRIS_CHxSPRIC(0) + +/* DMA_CHPRIC */ +#define DMA_CHPRIC_CHxSPRIC(i) (1 << (i)) +#define DMA_CHPRIC_CH11SPRIC DMA_CHPRIC_CHxSPRIC(11) +#define DMA_CHPRIC_CH10SPRIC DMA_CHPRIC_CHxSPRIC(10) +#define DMA_CHPRIC_CH9SPRIC DMA_CHPRIC_CHxSPRIC(9) +#define DMA_CHPRIC_CH8SPRIC DMA_CHPRIC_CHxSPRIC(8) +#define DMA_CHPRIC_CH7SPRIC DMA_CHPRIC_CHxSPRIC(7) +#define DMA_CHPRIC_CH6SPRIC DMA_CHPRIC_CHxSPRIC(6) +#define DMA_CHPRIC_CH5SPRIC DMA_CHPRIC_CHxSPRIC(5) +#define DMA_CHPRIC_CH4SPRIC DMA_CHPRIC_CHxSPRIC(4) +#define DMA_CHPRIC_CH3SPRIC DMA_CHPRIC_CHxSPRIC(3) +#define DMA_CHPRIC_CH2SPRIC DMA_CHPRIC_CHxSPRIC(2) +#define DMA_CHPRIC_CH1SPRIC DMA_CHPRIC_CHxSPRIC(1) +#define DMA_CHPRIC_CH0SPRIC DMA_CHPRIC_CHxSPRIC(0) + +/* DMA_ERRORC */ +#define DMA_ERRORC_ERRORC (1 << 0) + +/* DMA_CHREQSTATUS */ +#define DMA_CHREQSTATUS_CHxSREQSTATUS(i) (1 << (i)) +#define DMA_CHREQSTATUS_CH11SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(11) +#define DMA_CHREQSTATUS_CH10SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(10) +#define DMA_CHREQSTATUS_CH9SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(9) +#define DMA_CHREQSTATUS_CH8SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(8) +#define DMA_CHREQSTATUS_CH7SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(7) +#define DMA_CHREQSTATUS_CH6SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(6) +#define DMA_CHREQSTATUS_CH5SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(5) +#define DMA_CHREQSTATUS_CH4SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(4) +#define DMA_CHREQSTATUS_CH3SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(3) +#define DMA_CHREQSTATUS_CH2SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(2) +#define DMA_CHREQSTATUS_CH1SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(1) +#define DMA_CHREQSTATUS_CH0SREQSTATUS DMA_CHREQSTATUS_CHxSREQSTATUS(0) + +/* DMA_CHSREQSTATUS */ +#define DMA_CHSREQSTATUS_CHxSREQSTATUS(i) (1 << (i)) +#define DMA_CHSREQSTATUS_CH11SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(11) +#define DMA_CHSREQSTATUS_CH10SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(10) +#define DMA_CHSREQSTATUS_CH9SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(9) +#define DMA_CHSREQSTATUS_CH8SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(8) +#define DMA_CHSREQSTATUS_CH7SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(7) +#define DMA_CHSREQSTATUS_CH6SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(6) +#define DMA_CHSREQSTATUS_CH5SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(5) +#define DMA_CHSREQSTATUS_CH4SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(4) +#define DMA_CHSREQSTATUS_CH3SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(3) +#define DMA_CHSREQSTATUS_CH2SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(2) +#define DMA_CHSREQSTATUS_CH1SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(1) +#define DMA_CHSREQSTATUS_CH0SREQSTATUS DMA_CHSREQSTATUS_CHxSREQSTATUS(0) + +/* DMA_IF */ +#define DMA_IF_ERR (1UL << 31) +#define DMA_IF_CHxDONE(x) (1 << (x)) +#define DMA_IF_CH11DONE DMA_IF_CHxDONE(11) +#define DMA_IF_CH10DONE DMA_IF_CHxDONE(10) +#define DMA_IF_CH9DONE DMA_IF_CHxDONE(9) +#define DMA_IF_CH8DONE DMA_IF_CHxDONE(8) +#define DMA_IF_CH7DONE DMA_IF_CHxDONE(7) +#define DMA_IF_CH6DONE DMA_IF_CHxDONE(6) +#define DMA_IF_CH5DONE DMA_IF_CHxDONE(5) +#define DMA_IF_CH4DONE DMA_IF_CHxDONE(4) +#define DMA_IF_CH3DONE DMA_IF_CHxDONE(3) +#define DMA_IF_CH2DONE DMA_IF_CHxDONE(2) +#define DMA_IF_CH1DONE DMA_IF_CHxDONE(1) +#define DMA_IF_CH0DONE DMA_IF_CHxDONE(0) + + +/* DMA_IFS */ +#define DMA_IFS_ERR (1 << 31) +#define DMA_IFS_CHxDONE(x) (1 << (x)) +#define DMA_IFS_CH11DONE DMA_IFS_CHxDONE(11) +#define DMA_IFS_CH10DONE DMA_IFS_CHxDONE(10) +#define DMA_IFS_CH9DONE DMA_IFS_CHxDONE(9) +#define DMA_IFS_CH8DONE DMA_IFS_CHxDONE(8) +#define DMA_IFS_CH7DONE DMA_IFS_CHxDONE(7) +#define DMA_IFS_CH6DONE DMA_IFS_CHxDONE(6) +#define DMA_IFS_CH5DONE DMA_IFS_CHxDONE(5) +#define DMA_IFS_CH4DONE DMA_IFS_CHxDONE(4) +#define DMA_IFS_CH3DONE DMA_IFS_CHxDONE(3) +#define DMA_IFS_CH2DONE DMA_IFS_CHxDONE(2) +#define DMA_IFS_CH1DONE DMA_IFS_CHxDONE(1) +#define DMA_IFS_CH0DONE DMA_IFS_CHxDONE(0) + +/* DMA_IFC */ +#define DMA_IFC_ERR (1 << 31) +#define DMA_IFC_CHxDONE(x) (1 << (x)) +#define DMA_IFC_CH11DONE DMA_IFC_CHxDONE(11) +#define DMA_IFC_CH10DONE DMA_IFC_CHxDONE(10) +#define DMA_IFC_CH9DONE DMA_IFC_CHxDONE(9) +#define DMA_IFC_CH8DONE DMA_IFC_CHxDONE(8) +#define DMA_IFC_CH7DONE DMA_IFC_CHxDONE(7) +#define DMA_IFC_CH6DONE DMA_IFC_CHxDONE(6) +#define DMA_IFC_CH5DONE DMA_IFC_CHxDONE(5) +#define DMA_IFC_CH4DONE DMA_IFC_CHxDONE(4) +#define DMA_IFC_CH3DONE DMA_IFC_CHxDONE(3) +#define DMA_IFC_CH2DONE DMA_IFC_CHxDONE(2) +#define DMA_IFC_CH1DONE DMA_IFC_CHxDONE(1) +#define DMA_IFC_CH0DONE DMA_IFC_CHxDONE(0) + +/* DMA_IEN */ +#define DMA_IEN_ERR (1 << 31) +#define DMA_IEN_CHxDONE(x) (1 << (x)) +#define DMA_IEN_CH11DONE DMA_IEN_CHxDONE(11) +#define DMA_IEN_CH10DONE DMA_IEN_CHxDONE(10) +#define DMA_IEN_CH9DONE DMA_IEN_CHxDONE(9) +#define DMA_IEN_CH8DONE DMA_IEN_CHxDONE(8) +#define DMA_IEN_CH7DONE DMA_IEN_CHxDONE(7) +#define DMA_IEN_CH6DONE DMA_IEN_CHxDONE(6) +#define DMA_IEN_CH5DONE DMA_IEN_CHxDONE(5) +#define DMA_IEN_CH4DONE DMA_IEN_CHxDONE(4) +#define DMA_IEN_CH3DONE DMA_IEN_CHxDONE(3) +#define DMA_IEN_CH2DONE DMA_IEN_CHxDONE(2) +#define DMA_IEN_CH1DONE DMA_IEN_CHxDONE(1) +#define DMA_IEN_CH0DONE DMA_IEN_CHxDONE(0) + +/* DMA_CTRL */ +#define DMA_CTRL_PRDU (1 << 1) +#define DMA_CTRL_DESCRECT (1 << 0) + +/* DMA_RDS */ +#define DMA_RDS_RDSCHx(i) (1 << (i)) +#define DMA_RDS_RDSCH11 DMA_RDS_RDSCHx(11) +#define DMA_RDS_RDSCH10 DMA_RDS_RDSCHx(10) +#define DMA_RDS_RDSCH9 DMA_RDS_RDSCHx(9) +#define DMA_RDS_RDSCH8 DMA_RDS_RDSCHx(8) +#define DMA_RDS_RDSCH7 DMA_RDS_RDSCHx(7) +#define DMA_RDS_RDSCH6 DMA_RDS_RDSCHx(6) +#define DMA_RDS_RDSCH5 DMA_RDS_RDSCHx(5) +#define DMA_RDS_RDSCH4 DMA_RDS_RDSCHx(4) +#define DMA_RDS_RDSCH3 DMA_RDS_RDSCHx(3) +#define DMA_RDS_RDSCH2 DMA_RDS_RDSCHx(2) +#define DMA_RDS_RDSCH1 DMA_RDS_RDSCHx(1) +#define DMA_RDS_RDSCH0 DMA_RDS_RDSCHx(0) + +/* DMA_LOOP */ +#define DMA_LOOP_EN (1 << 16) +#define DMA_LOOP_WIDTH_SHIFT (0) +#define DMA_LOOP_WIDTH_MASK (0x3FF << DMA_LOOP_WIDTH_SHIFT) +#define DMA_LOOP_WIDTH(v) \ + (((v) << DMA_LOOP_WIDTH_SHIFT) & DMA_LOOP_WIDTH_MASK) + +/* DMA_RECT */ +#define DMA_RECT_DSTSTRIDE_SHIFT (21) +#define DMA_RECT_DSTSTRIDE_MASK (0x7FF << DMA_RECT_DSTSTRIDE_SHIFT) +#define DMA_RECT_DSTSTRIDE(v) \ + (((v) << DMA_RECT_DSTSTRIDE_SHIFT) & DMA_RECT_DSTSTRIDE_MASK) + +#define DMA_RECT_SRCSTRIDE_SHIFT (10) +#define DMA_RECT_SRCSTRIDE_MASK (0x7FF << DMA_RECT_SRCSTRIDE_SHIFT) +#define DMA_RECT_SRCSTRIDE(v) \ + (((v) << DMA_RECT_SRCSTRIDE_SHIFT) & DMA_RECT_SRCSTRIDE_MASK) + +#define DMA_RECT_HEIGHT_SHIFT (0) +#define DMA_RECT_HEIGHT_MASK (0x3FF << DMA_RECT_HEIGHT_SHIFT) +#define DMA_RECT_HEIGHT(v) \ + (((v) << DMA_RECT_HEIGHT_SHIFT) & DMA_RECT_HEIGHT_MASK) + +/* DMA_CH_CTRL */ +#define DMA_CH_CTRL_SOURCESEL_SHIFT (16) +#define DMA_CH_CTRL_SOURCESEL_MASK (0x3F << DMA_CH_CTRL_SOURCESEL_SHIFT) +#define DMA_CH_CTRL_SOURCESEL(v) \ + (((v) << DMA_CH_CTRL_SOURCESEL_SHIFT) & DMA_CH_CTRL_SOURCESEL_MASK) +#define DMA_CH_CTRL_SOURCESEL_NONE DMA_CH_CTRL_SOURCESEL(0b000000) +#define DMA_CH_CTRL_SOURCESEL_ADC0 DMA_CH_CTRL_SOURCESEL(0b001000) +#define DMA_CH_CTRL_SOURCESEL_DAC0 DMA_CH_CTRL_SOURCESEL(0b001010) +#define DMA_CH_CTRL_SOURCESEL_USART0 DMA_CH_CTRL_SOURCESEL(0b001100) +#define DMA_CH_CTRL_SOURCESEL_USART1 DMA_CH_CTRL_SOURCESEL(0b001101) +#define DMA_CH_CTRL_SOURCESEL_USART2 DMA_CH_CTRL_SOURCESEL(0b001110) +#define DMA_CH_CTRL_SOURCESEL_LEUART0 DMA_CH_CTRL_SOURCESEL(0b010000) +#define DMA_CH_CTRL_SOURCESEL_LEUART1 DMA_CH_CTRL_SOURCESEL(0b010001) +#define DMA_CH_CTRL_SOURCESEL_I2C0 DMA_CH_CTRL_SOURCESEL(0b010100) +#define DMA_CH_CTRL_SOURCESEL_I2C1 DMA_CH_CTRL_SOURCESEL(0b010101) +#define DMA_CH_CTRL_SOURCESEL_TIMER0 DMA_CH_CTRL_SOURCESEL(0b011000) +#define DMA_CH_CTRL_SOURCESEL_TIMER1 DMA_CH_CTRL_SOURCESEL(0b011001) +#define DMA_CH_CTRL_SOURCESEL_TIMER2 DMA_CH_CTRL_SOURCESEL(0b011010) +#define DMA_CH_CTRL_SOURCESEL_TIMER3 DMA_CH_CTRL_SOURCESEL(0b011011) +#define DMA_CH_CTRL_SOURCESEL_UART0 DMA_CH_CTRL_SOURCESEL(0b101100) +#define DMA_CH_CTRL_SOURCESEL_UART1 DMA_CH_CTRL_SOURCESEL(0b101101) +#define DMA_CH_CTRL_SOURCESEL_MSC DMA_CH_CTRL_SOURCESEL(0b110000) +#define DMA_CH_CTRL_SOURCESEL_AES DMA_CH_CTRL_SOURCESEL(0b110001) +#define DMA_CH_CTRL_SOURCESEL_LESENSE DMA_CH_CTRL_SOURCESEL(0b110010) +#define DMA_CH_CTRL_SOURCESEL_EBI DMA_CH_CTRL_SOURCESEL(0b110011) + +#define DMA_CH_CTRL_SIGSEL_SHIFT (0) +#define DMA_CH_CTRL_SIGSEL_MASK (0xF << DMA_CH_CTRL_SIGSEL_SHIFT) +#define DMA_CH_CTRL_SIGSEL(v) \ + (((v) << DMA_CH_CTRL_SIGSEL_SHIFT) & DMA_CH_CTRL_SIGSEL_MASK) + +#define DMA_CH_CTRL_SIGSEL_OFF DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_ADC0SINGLE DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_ADC0SCAN DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_DAC0CH0 DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_DAC0CH1 DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_USART0RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_USART0TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_USART0TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_USART1RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_USART1TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_USART1TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_USART1RXDATAVRIGHT DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_USART1TXBLRIGHT DMA_CH_CTRL_SIGSEL(4) +#define DMA_CH_CTRL_SIGSEL_USART2RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_USART2TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_USART2TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_USART2RXDATAVRIGHT DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_USART2TXBLRIGHT DMA_CH_CTRL_SIGSEL(4) +#define DMA_CH_CTRL_SIGSEL_LEUART0RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_LEUART0TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_LEUART0TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_LEUART1RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_LEUART1TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_LEUART1TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_I2C0RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_I2C0TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_I2C1RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_I2C1TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_TIMER0UFOF DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_TIMER0CC0 DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_TIMER0CC1 DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_TIMER0CC2 DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_TIMER1UFOF DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_TIMER1CC0 DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_TIMER1CC1 DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_TIMER1CC2 DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_TIMER2UFOF DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_TIMER2CC0 DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_TIMER2CC1 DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_TIMER2CC2 DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_TIMER3UFOF DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_TIMER3CC0 DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_TIMER3CC1 DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_TIMER3CC2 DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_UART0RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_UART0TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_UART0TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_UART1RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_UART1TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_UART1TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_MSCWDATA DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_AESDATAWR DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_AESXORDATAWR DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_AESDATARD DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_AESKEYWR DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_LESENSEBUFDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_EBIPXL0EMPTY DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_EBIPXL1EMPTY DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_EBIPXLFULL DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_EBIDDEMPTY DMA_CH_CTRL_SIGSEL(3) + +/* generic of above */ +#define DMA_CH_CTRL_SIGSEL_ADC_SINGLE DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_ADC_SCAN DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_DAC_CHx(x) DMA_CH_CTRL_SIGSEL(x) +#define DMA_CH_CTRL_SIGSEL_DAC_CH0 DMA_CH_CTRL_SIGSEL_DAC_CHx(0) +#define DMA_CH_CTRL_SIGSEL_DAC_CH1 DMA_CH_CTRL_SIGSEL_DAC_CHx(1) +#define DMA_CH_CTRL_SIGSEL_USART_RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_USART_TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_USART_TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_USART_RXDATAVRIGHT DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_USART_TXBLRIGHT DMA_CH_CTRL_SIGSEL(4) +#define DMA_CH_CTRL_SIGSEL_LEUART_RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_LEUART_TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_LEUART_TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_I2C_RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_I2C_TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_I2C_RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_I2C_TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_TIMER_UFOF DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_TIMER_CCx(x) DMA_CH_CTRL_SIGSEL((x) + 1) +#define DMA_CH_CTRL_SIGSEL_TIMER_CC0 DMA_CH_CTRL_SIGSEL_TIMER_CCx(0) +#define DMA_CH_CTRL_SIGSEL_TIMER_CC1 DMA_CH_CTRL_SIGSEL_TIMER_CCx(1) +#define DMA_CH_CTRL_SIGSEL_TIMER_CC2 DMA_CH_CTRL_SIGSEL_TIMER_CCx(3) +#define DMA_CH_CTRL_SIGSEL_UART_RXDATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_UART_TXBL DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_UART_TXEMPTY DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_MSC_WDATA DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_AES_DATA_WR DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_AES_XOR_DATA_WR DMA_CH_CTRL_SIGSEL(1) +#define DMA_CH_CTRL_SIGSEL_AES_DATA_RD DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_AES_KEY_WR DMA_CH_CTRL_SIGSEL(3) +#define DMA_CH_CTRL_SIGSEL_LESENSE_BUF_DATAV DMA_CH_CTRL_SIGSEL(0) +#define DMA_CH_CTRL_SIGSEL_EBI_PXLx_EMPTY(x) DMA_CH_CTRL_SIGSEL(x) +#define DMA_CH_CTRL_SIGSEL_EBI_PXL0_EMPTY \ + DMA_CH_CTRL_SIGSEL_EBI_PXLx_EMPTY(0) +#define DMA_CH_CTRL_SIGSEL_EBI_PXL1_EMPTY \ + DMA_CH_CTRL_SIGSEL_EBI_PXLx_EMPTY(1) +#define DMA_CH_CTRL_SIGSEL_EBI_PXL_FULL DMA_CH_CTRL_SIGSEL(2) +#define DMA_CH_CTRL_SIGSEL_EBI_DD_EMPTY DMA_CH_CTRL_SIGSEL(3) + +/** + * Application needs to allocate (DMA_DESC_CH_SIZE * N) byte + * where N is the number of first N channels to use. + * and this allocated memory needs to be assigned to DMA using + * dma_set_desc_address(). + * + * if the application code needs alternate descriptor facility also. + * it needs to allocate the required memory (usually equal to the one above) + * and assign the memory using dma_set_alternate_desc_address() + * + * rest of the work will be transparently managed by convience functions. + * + * all the memory above should be aligned to 256bit + * (ie LSB 8bits of array address should be 0) + * use gcc's __attribute__((aligned(256))) + */ +#define DMA_DESC_CH_SIZE (0x4 * 0x4) +#define DMA_DESC_CHx_BASE(base, x) \ + ((base) + ((x) * DMA_DESC_CH_SIZE)) +#define DMA_DESC_CHx_SRC_DATA_END_PTR(base, x) \ + MMIO32(DMA_DESC_CHx_BASE(base, x) + 0x00) +#define DMA_DESC_CHx_DEST_DATA_END_PTR(base, x) \ + MMIO32(DMA_DESC_CHx_BASE(base, x) + 0x04) +#define DMA_DESC_CHx_CFG(base, x) \ + MMIO32(DMA_DESC_CHx_BASE(base, x) + 0x08) +#define DMA_DESC_CHx_USER_DATA(base, x) \ + MMIO32(DMA_DESC_CHx_BASE(base, x) + 0x0C) + +/* DMA_DESC_CH_CFG */ +#define DMA_DESC_CH_CFG_DEST_INC_SHIFT (30) +#define DMA_DESC_CH_CFG_DEST_INC_MASK \ + (0x3 << DMA_DESC_CH_CFG_DEST_INC_SHIFT) +#define DMA_DESC_CH_CFG_DEST_INC(v) \ + (((v) << DMA_DESC_CH_CFG_DEST_INC_SHIFT) & \ + DMA_DESC_CH_CFG_DEST_INC_MASK) +#define DMA_DESC_CH_CFG_DEST_INC_BYTE DMA_DESC_CH_CFG_DEST_INC(0) +#define DMA_DESC_CH_CFG_DEST_INC_HALFWORD DMA_DESC_CH_CFG_DEST_INC(1) +#define DMA_DESC_CH_CFG_DEST_INC_WORD DMA_DESC_CH_CFG_DEST_INC(2) +#define DMA_DESC_CH_CFG_DEST_INC_NOINC DMA_DESC_CH_CFG_DEST_INC(3) + +#define DMA_DESC_CH_CFG_DEST_SIZE_SHIFT (28) +#define DMA_DESC_CH_CFG_DEST_SIZE_MASK \ + (0x3 << DMA_DESC_CH_CFG_DEST_SIZE_SHIFT) +#define DMA_DESC_CH_CFG_DEST_SIZE(v) \ + (((v) << DMA_DESC_CH_CFG_DEST_SIZE_SHIFT) & \ + DMA_DESC_CH_CFG_DEST_SIZE_MASK) +#define DMA_DESC_CH_CFG_DEST_SIZE_BYTE DMA_DESC_CH_CFG_DEST_SIZE(0) +#define DMA_DESC_CH_CFG_DEST_SIZE_HALFWORD DMA_DESC_CH_CFG_DEST_SIZE(1) +#define DMA_DESC_CH_CFG_DEST_SIZE_WORD DMA_DESC_CH_CFG_DEST_SIZE(2) +#define DMA_DESC_CH_CFG_DEST_SIZE_NOINC DMA_DESC_CH_CFG_DEST_SIZE(3) + +#define DMA_DESC_CH_CFG_SRC_INC_SHIFT (26) +#define DMA_DESC_CH_CFG_SRC_INC_MASK \ + (0x3 << DMA_DESC_CH_CFG_SRC_INC_SHIFT) +#define DMA_DESC_CH_CFG_SRC_INC(v) \ + (((v) << DMA_DESC_CH_CFG_SRC_INC_SHIFT) & \ + DMA_DESC_CH_CFG_SRC_INC_MASK) +#define DMA_DESC_CH_CFG_SRC_INC_BYTE DMA_DESC_CH_CFG_SRC_INC(0) +#define DMA_DESC_CH_CFG_SRC_INC_HALFWORD DMA_DESC_CH_CFG_SRC_INC(1) +#define DMA_DESC_CH_CFG_SRC_INC_WORD DMA_DESC_CH_CFG_SRC_INC(2) +#define DMA_DESC_CH_CFG_SRC_INC_NOINC DMA_DESC_CH_CFG_SRC_INC(3) + +#define DMA_DESC_CH_CFG_SRC_SIZE_SHIFT (24) +#define DMA_DESC_CH_CFG_SRC_SIZE_MASK \ + (0x3 << DMA_DESC_CH_CFG_SRC_SIZE_SHIFT) +#define DMA_DESC_CH_CFG_SRC_SIZE(v) \ + (((v) << DMA_DESC_CH_CFG_SRC_SIZE_SHIFT) & \ + DMA_DESC_CH_CFG_SRC_SIZE_MASK) +#define DMA_DESC_CH_CFG_SRC_SIZE_BYTE DMA_DESC_CH_CFG_SRC_SIZE(0) +#define DMA_DESC_CH_CFG_SRC_SIZE_HALFWORD DMA_DESC_CH_CFG_SRC_SIZE(1) +#define DMA_DESC_CH_CFG_SRC_SIZE_WORD DMA_DESC_CH_CFG_SRC_SIZE(2) +#define DMA_DESC_CH_CFG_SRC_SIZE_NOINC DMA_DESC_CH_CFG_SRC_SIZE(3) + +#define DMA_DESC_CH_CFG_R_POWER_SHIFT (14) +#define DMA_DESC_CH_CFG_R_POWER_MASK \ + (0xF << DMA_DESC_CH_CFG_R_POWER_SHIFT) +#define DMA_DESC_CH_CFG_R_POWER(v) \ + (((v) << DMA_DESC_CH_CFG_R_POWER_SHIFT) & \ + DMA_DESC_CH_CFG_R_POWER_MASK) + +#define DMA_DESC_CH_CFG_CYCLE_CTRL_SHIFT (0) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_MASK \ + (0x7 << DMA_DESC_CH_CFG_CYCLE_CTRL_SHIFT) +#define DMA_DESC_CH_CFG_CYCLE_CTRL(v) \ + (((v) << DMA_DESC_CH_CFG_CYCLE_CTRL_SHIFT) & \ + DMA_DESC_CH_CFG_CYCLE_CTRL_MASK) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_INVALD \ + DMA_DESC_CH_CFG_CYCLE_CTRL(0) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_BASIC \ + DMA_DESC_CH_CFG_CYCLE_CTRL(1) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_AUTOREQUEST \ + DMA_DESC_CH_CFG_CYCLE_CTRL(2) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_PINGPONG \ + DMA_DESC_CH_CFG_CYCLE_CTRL(3) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_MEM_SCAT_GATH_PRIM \ + DMA_DESC_CH_CFG_CYCLE_CTRL(4) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_MEM_SCAT_GATH_ALT \ + DMA_DESC_CH_CFG_CYCLE_CTRL(5) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_PERIPH_SCAT_GATH_PRIM \ + DMA_DESC_CH_CFG_CYCLE_CTRL(6) +#define DMA_DESC_CH_CFG_CYCLE_CTRL_PERIPH_SCAT_GATH_ALT \ + DMA_DESC_CH_CFG_CYCLE_CTRL(7) + +#define DMA_DESC_CH_CFG_DEST_PROT_CTRL_SHIFT (21) +#define DMA_DESC_CH_CFG_DEST_PROT_CTRL_MASK \ + (0x7 << DMA_DESC_CH_CFG_DEST_PROT_CTRL_SHIFT) +#define DMA_DESC_CH_CFG_DEST_PROT_CTRL(v) \ + (((v) << DMA_DESC_CH_CFG_DEST_PROT_CTRL_SHIFT) & \ + DMA_DESC_CH_CFG_DEST_PROT_CTRL_MASK) + +#define DMA_DESC_CH_CFG_SRC_PROT_CTRL_SHIFT (18) +#define DMA_DESC_CH_CFG_SRC_PROT_CTRL_MASK \ + (0x7 << DMA_DESC_CH_CFG_SRC_PROT_CTRL_SHIFT) +#define DMA_DESC_CH_CFG_SRC_PROT_CTRL(v) \ + (((v) << DMA_DESC_CH_CFG_SRC_PROT_CTRL_SHIFT) & \ + DMA_DESC_CH_CFG_SRC_PROT_CTRL_SHIFT) + +#define DMA_DESC_CH_CFG_N_MINUS_1_SHIFT (4) +#define DMA_DESC_CH_CFG_N_MINUS_1_MASK \ + (0x3FF << DMA_DESC_CH_CFG_N_MINUS_1_SHIFT) +#define DMA_DESC_CH_CFG_N_MINUS_1(v) \ + (((v) << DMA_DESC_CH_CFG_N_MINUS_1_SHIFT) & \ + DMA_DESC_CH_CFG_N_MINUS_1_MASK) + +#define DMA_DESC_CH_CFG_NEXT_USEBURST (1 << 3) + +/* DMA Channel Descriptor in structure style */ +struct dma_chan_desc { + uint32_t src_data_end_ptr; + uint32_t dst_data_end_ptr; + uint32_t cfg; + uint32_t user_data; +} __attribute__((packed)); + +/** @defgroup dma_ch DMA Channel Number +@ingroup dma_defines + +@{*/ +enum dma_ch { + DMA_CH0 = 0, + DMA_CH1, + DMA_CH2, + DMA_CH3, + DMA_CH4, + DMA_CH5, + DMA_CH6, + DMA_CH7, + DMA_CH8, + DMA_CH9, + DMA_CH10, + DMA_CH11 +}; +/**@}*/ + +/* API version for {src, dest} * {size, inc} */ +enum dma_mem { + DMA_MEM_BYTE = 0, + DMA_MEM_HALF_WORD, + DMA_MEM_WORD, + DMA_MEM_NONE +}; + +/* API version of DMA_DESC_CH_CFG_CYCLE_CTRL_* */ +enum dma_mode { + DMA_MODE_INVALID = 0, + DMA_MODE_BASIC, + DMA_MODE_AUTO_REQUEST, + DMA_MODE_PING_PONG, + DMA_MODE_MEM_SCAT_GATH_PRIM, + DMA_MODE_MEM_SCAT_GATH_ALT, + DMA_MODE_PERIPH_SCAT_GATH_PRIM, + DMA_MODE_PERIPH_SCAT_GATH_ALT, +}; + +/* API version of DMA_DESC_CH_CFG_R_POWER() */ +enum dma_r_power { + DMA_R_POWER_1 = 0, + DMA_R_POWER_2, + DMA_R_POWER_4, + DMA_R_POWER_8, + DMA_R_POWER_16, + DMA_R_POWER_32, + DMA_R_POWER_64, + DMA_R_POWER_128, + DMA_R_POWER_256, + DMA_R_POWER_512, + DMA_R_POWER_1024 +}; + +BEGIN_DECLS + +void dma_enable(void); +void dma_disable(void); + +bool dma_get_wait_on_request_flag(enum dma_ch ch); + +/*bool dma_get_wait_flag(enum dma_ch ch);*/ + +void dma_enable_with_unprivileged_access(void); +void dma_enable_with_privileged_access(void); + +void dma_set_desc_address(uint32_t desc_base); + +void dma_generate_software_request(enum dma_ch ch); + +void dma_enable_burst_only(enum dma_ch ch); +void dma_enable_single_and_burst(enum dma_ch ch); + +void dma_enable_periph_request(enum dma_ch ch); +void dma_disable_periph_request(enum dma_ch ch); + +void dma_enable_channel(enum dma_ch ch); +void dma_disable_channel(enum dma_ch ch); + +void dma_disable_alternate_structure(enum dma_ch ch); +void dma_enable_alternate_structure(enum dma_ch ch); + +void dma_enable_priority(enum dma_ch ch); +void dma_disable_priority(enum dma_ch ch); + +bool dma_get_bus_error_flag(void); +void dma_clear_bus_error_flag(void); + +bool dma_get_request_flag(enum dma_ch ch); + +/*bool dma_get_single_request_flag(enum dma_ch ch);*/ + +bool dma_get_bus_error_interrupt_flag(void); +bool dma_get_done_interrupt_flag(enum dma_ch ch); + +void dma_set_bus_error_interrupt_flag(void); +void dma_set_done_interrupt_flag(enum dma_ch ch); + +void dma_clear_bus_error_interrupt_flag(void); +void dma_clear_done_interrupt_flag(enum dma_ch ch); + +void dma_enable_bus_error_interrupt(void); +void dma_disable_bus_error_interrupt(void); +void dma_enable_done_interrupt(enum dma_ch ch); +void dma_disable_done_interrupt(enum dma_ch ch); + +/* TODO: DMA_CTRL, DMA_RDS, DMA_LOOP0, DMA_LOOP1, DMA_RECT0 */ + +void dma_set_source(enum dma_ch ch, uint32_t source); +void dma_set_signal(enum dma_ch ch, uint32_t signal); + +void dma_channel_reset(enum dma_ch ch); + +void dma_set_loop_count(enum dma_ch ch, uint16_t count); +void dma_enable_loop(enum dma_ch ch); +void dma_disable_loop(enum dma_ch ch); + +/* descriptor convient function. (prefix "dma_desc_") */ +void dma_desc_set_dest_size(uint32_t desc_base, enum dma_ch ch, + enum dma_mem size); +void dma_desc_set_dest_inc(uint32_t desc_base, enum dma_ch ch, + enum dma_mem inc); +void dma_desc_set_src_size(uint32_t desc_base, enum dma_ch ch, + enum dma_mem size); +void dma_desc_set_src_inc(uint32_t desc_base, enum dma_ch ch, + enum dma_mem inc); + +void dma_desc_set_r_power(uint32_t desc_base, enum dma_ch ch, + enum dma_r_power r_power); + +void dma_desc_enable_next_useburst(uint32_t desc_base, enum dma_ch ch); +void dma_desc_disable_next_useburst(uint32_t desc_base, enum dma_ch ch); + +void dma_desc_set_count(uint32_t desc_base, enum dma_ch ch, uint16_t count); + +void dma_desc_set_user_data(uint32_t desc_base, enum dma_ch ch, + uint32_t user_data); +uint32_t dma_desc_get_user_data(uint32_t desc_base, enum dma_ch ch); + +void dma_desc_set_src_address(uint32_t desc_base, enum dma_ch ch, + uint32_t src); +void dma_desc_set_dest_address(uint32_t desc_base, enum dma_ch ch, + uint32_t dest); + +void dma_desc_set_mode(uint32_t desc_base, enum dma_ch ch, enum dma_mode mode); + +/* based on descriptor convient, macro are passing + * {DMA_CTRLBASE, CTRL_ALTCTRLBASE} as per naming */ +#define dma_set_dest_size(ch, size) \ + dma_desc_set_dest_size(DMA_CTRLBASE, ch, size) +#define dma_set_dest_inc(ch, inc) \ + dma_desc_set_dest_inc(DMA_CTRLBASE, ch, inc) +#define dma_set_src_size(ch, size) \ + dma_desc_set_src_size(DMA_CTRLBASE, ch, size) +#define dma_set_src_inc(ch, inc) \ + dma_desc_set_src_inc(DMA_CTRLBASE, ch, inc) + +#define dma_set_alt_dest_size(ch, size) \ + dma_desc_set_dest_size(DMA_ALTCTRLBASE, ch, size) +#define dma_set_alt_dest_inc(ch, inc) \ + dma_desc_set_dest_inc(DMA_ALTCTRLBASE, ch, inc) +#define dma_set_alt_src_size(ch, size) \ + dma_desc_set_src_size(DMA_ALTCTRLBASE, ch, size) +#define dma_set_alt_src_inc(ch, inc) \ + dma_desc_set_src_inc(DMA_ALTCTRLBASE, ch, inc) + +#define dma_set_r_power(ch, r_power) \ + dma_desc_set_r_power(DMA_CTRLBASE, ch, r_power) +#define dma_set_alt_r_power(ch, r_power) \ + dma_desc_set_r_power(DMA_ALTCTRLBASE, ch, r_power) + +#define dma_enable_next_useburst(ch) \ + dma_desc_enable_next_useburst(DMA_CTRLBASE, ch) +#define dma_disable_next_useburst(ch) \ + dma_desc_disable_next_useburst(DMA_CTRLBASE, ch) +#define dma_enable_alt_next_useburst(ch) \ + dma_desc_enable_alt_next_useburst(DMA_CTRLBASE, ch) +#define dma_disable_alt_next_useburst(ch) \ + dma_desc_disable_alt_next_useburst(DMA_CTRLBASE, ch) + +#define dma_set_count(ch, count) \ + dma_desc_set_count(DMA_CTRLBASE, ch, count) +#define dma_set_alt_count(ch, count) \ + dma_desc_set_count(DMA_ALTCTRLBASE, ch, count) + +#define dma_set_user_data(ch, user_data) \ + dma_desc_set_user_data(DMA_CTRLBASE, ch, user_data) +#define dma_set_alt_user_data(ch, user_data) \ + dma_desc_set_user_data(DMA_ALTCTRLBASE, ch, user_data) + +#define dma_get_user_data(ch) \ + dma_desc_get_user_data(DMA_CTRLBASE, ch) +#define dma_get_alt_user_data(ch) \ + dma_desc_get_user_data(DMA_ALTCTRLBASE, ch) + +#define dma_set_src_address(ch, src) \ + dma_desc_set_src_address(DMA_CTRLBASE, ch, src) +#define dma_set_alt_src_address(ch, src) \ + dma_desc_set_src_address(DMA_ALTCTRLBASE, ch, src) +#define dma_set_dest_address(ch, dest) \ + dma_desc_set_dest_address(DMA_CTRLBASE, ch, dest) +#define dma_set_alt_dest_address(ch, dest) \ + dma_desc_set_dest_address(DMA_ALTCTRLBASE, ch, dest) + +#define dma_set_mode(ch, mode) \ + dma_desc_set_mode(DMA_CTRLBASE, ch, mode) +#define dma_set_alt_mode(ch, mode) \ + dma_desc_set_mode(DMA_ALTCTRLBASE, ch, mode) + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/doc-efm32lg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/doc-efm32lg.h new file mode 100644 index 00000000..7721239f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/doc-efm32lg.h @@ -0,0 +1,33 @@ +/** @mainpage libopencm3 EFM32 Leopard Gecko + +@version 1.0.0 + +@date 4 March 2013 + +API documentation for Energy Micro EFM32 Leopard Gecko Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32LG EFM32 LeopardGecko +Libraries for Energy Micro EFM32 Leopard Gecko series. + +@version 1.0.0 + +@date 4 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32LG_defines EFM32 Leopard Gecko Defines + +@brief Defined Constants and Types for the Energy Micro EFM32 Leopard Gecko +series + +@version 1.0.0 + +@date 4 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/emu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/emu.h new file mode 100644 index 00000000..96e5ddd6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/emu.h @@ -0,0 +1,189 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_EMU_H +#define LIBOPENCM3_EFM32_EMU_H + +#include +#include + +#define EMU_CTRL MMIO32(EMU_BASE + 0x000) +#define EMU_LOCK MMIO32(EMU_BASE + 0x008) +#define EMU_AUXCTRL MMIO32(EMU_BASE + 0x024) +#define EMU_EM4CONF MMIO32(EMU_BASE + 0x02C) +#define EMU_BUCTRL MMIO32(EMU_BASE + 0x030) +#define EMU_PWRCONF MMIO32(EMU_BASE + 0x034) +#define EMU_BUINACT MMIO32(EMU_BASE + 0x038) +#define EMU_BUACT MMIO32(EMU_BASE + 0x03C) +#define EMU_STATUS MMIO32(EMU_BASE + 0x040) +#define EMU_ROUTE MMIO32(EMU_BASE + 0x044) +#define EMU_IF MMIO32(EMU_BASE + 0x048) +#define EMU_IFS MMIO32(EMU_BASE + 0x04C) +#define EMU_IFC MMIO32(EMU_BASE + 0x050) +#define EMU_IEN MMIO32(EMU_BASE + 0x054) +#define EMU_BUBODBUVINCAL MMIO32(EMU_BASE + 0x058) +#define EMU_BUBODUNREGCAL MMIO32(EMU_BASE + 0x05C) + +/* EMU_CTRL */ +#define EMU_CTRL_EM4CTRL_SHIFT (2) +#define EMU_CTRL_EM4CTRL_MASK (0x3 << EMU_CTRL_EM4CTRL_SHIFT) +#define EMU_CTLR_EM4CTRL(v) \ + (((v) << EMU_CTRL_EM4CTRL_SHIFT) & EMU_CTRL_EM4CTRL_MASK) + +#define EMU_CTRL_EM2BLOCK (1 << 1) +#define EMU_CTRL_EMVREG (1 << 0) + +/* EMU_LOCK */ +#define EMU_LOCK_LOCKKEY_MASK (0xFFFF) +#define EMU_LOCK_LOCKKEY_LOCK (0) +#define EMU_LOCK_LOCKKEY_UNLOCK (0xADE8) + +/* EMU_AUXCTRL */ +#define EMU_AUXCTRL_HRCCLR (1 << 0) + +/* EMU_EM4CONF */ +#define EMU_EM4CONF_LOCKCONF (1 << 16) +#define EMU_EM4CONF_BUBODRSTDIS (1 << 4) + +#define EMU_EM4CONF_OSC_SHIFT (2) +#define EMU_EM4CONF_OSC_MASK (0x3 << EMU_EM4CONF_OSC_SHIFT) +#define EMU_EM4CONF_OSC(v) \ + (((v) << EMU_EM4CONF_OSC_SHIFT) & EMU_EM4CONF_OSC_MASK) +#define EMU_EM4CONF_OSC_ULFRCO EMU_EM4CONF_OSC(0) +#define EMU_EM4CONF_OSC_LFRCO EMU_EM4CONF_OSC(1) +#define EMU_EM4CONF_OSC_LFXO EMU_EM4CONF_OSC(2) + +#define EMU_EM4CONF_BURTCWU (1 << 1) +#define EMU_EM4CONF_VREGEN (1 << 0) + +/* EMU_BUCTRL */ +#define EMU_BUCTRL_PROBE_SHIFT (5) +#define EMU_BUCTRL_PROBE_MASK (0x3 << EMU_BUCTRL_PROBE_SHIFT) +#define EMU_BUCTRL_PROBE(v) \ + (((v) << EMU_BUCTRL_PROBE_SHIFT) & EMU_BUCTRL_PROBE_MASK) +#define EMU_BUCTRL_PROBE_DISABLE EMU_BUCTRL_PROBE(0) +#define EMU_BUCTRL_PROBE_VDDDREG EMU_BUCTRL_PROBE(1) +#define EMU_BUCTRL_PROBE_BUIN EMU_BUCTRL_PROBE(2) +#define EMU_BUCTRL_PROBE_BUOUT EMU_BUCTRL_PROBE(3) + +#define EMU_BUCTRL_BUMODEBODEN (1 << 3) +#define EMU_BUCTRL_BODCAL (1 << 2) +#define EMU_BUCTRL_STATEN (1 << 1) +#define EMU_BUCTRL_EN (1 << 0) + +/* EMU_PWRCONF */ +#define EMU_PWRCONF_PWRRES_SHIFT (3) +#define EMU_PWRCONF_PWRRES_MASK (0x3 << EMU_PWRCONF_PWRRES_SHIFT) +#define EMU_PWRCONF_PWRRES(v) \ + (((v) << EMU_PWRCONF_PWRRES_SHIFT) & EMU_PWRCONF_PWRRES_MASK) +#define EMU_PWRCONF_PWRRES_DISABLE EMU_PWRCONF_PWRRES(0) +#define EMU_PWRCONF_PWRRES_VDDDREG EMU_PWRCONF_PWRRES(1) +#define EMU_PWRCONF_PWRRES_BUIN EMU_PWRCONF_PWRRES(2) +#define EMU_PWRCONF_PWRRES_BUOUT EMU_PWRCONF_PWRRES(3) + +#define EMU_PWRCONF_VOUTSTRONG (1 << 2) +#define EMU_PWRCONF_VOUTMED (1 << 1) +#define EMU_PWRCONF_VOUTWEAK (1 << 0) + +/* EMU_BUINACT */ +#define EMU_BUINACT_PWRCON_SHIFT (5) +#define EMU_BUINACT_PWRCON_MASK (0x3 << EMU_BUINACT_PWRCON_SHIFT) +#define EMU_BUINACT_PWRCON(v) \ + (((v) << EMU_BUINACT_PWRCON_SHIFT) & EMU_BUINACT_PWRCON_MASK) +#define EMU_BUINACT_PWRCON_NONE EMU_BUINACT_PWRCON(0) +#define EMU_BUINACT_PWRCON_BUMAIN EMU_BUINACT_PWRCON(1) +#define EMU_BUINACT_PWRCON_MAINBU EMU_BUINACT_PWRCON(2) +#define EMU_BUINACT_PWRCON_NODIODE EMU_BUINACT_PWRCON(3) + +#define EMU_BUINACT_BUENRANGE_SHIFT (3) +#define EMU_BUINACT_BUENRANGE_MASK (0x3 << EMU_BUINACT_BUENRANGE_SHIFT) +#define EMU_BUINACT_BUENRANGE(v) \ + (((v) << EMU_BUINACT_BUENRANGE_SHIFT) & EMU_BUINACT_BUENRANGE_MASK) + +#define EMU_BUINACT_BUENTHRES_SHIFT (0) +#define EMU_BUINACT_BUENTHRES_MASK (0x7 << EMU_BUINACT_BUENTHRES_SHIFT) +#define EMU_BUINACT_BUENTHRES(v) \ + (((v) << EMU_BUINACT_BUENTHRES_SHIFT) & EMU_BUINACT_BUENTHRES_MASK) + +/* EMU_BUACT */ +#define EMU_BUACT_PWRCON_SHIFT (5) +#define EMU_BUACT_PWRCON_MASK (0x3 << EMU_BUACT_PWRCON_SHIFT) +#define EMU_BUACT_PWRCON(v) \ + (((v) << EMU_BUACT_PWRCON_SHIFT) & EMU_BUACT_PWRCON_MASK) +#define EMU_BUACT_PWRCON_NONE EMU_BUACT_PWRCON(0) +#define EMU_BUACT_PWRCON_BUMAIN EMU_BUACT_PWRCON(1) +#define EMU_BUACT_PWRCON_MAINBU EMU_BUACT_PWRCON(2) +#define EMU_BUACT_PWRCON_NODIODE EMU_BUACT_PWRCON(3) + +#define EMU_BUACT_BUEXRANGE_SHIFT (3) +#define EMU_BUACT_BUEXRANGE_MASK (0x3 << EMU_BUACT_BUEXRANGE_SHIFT) +#define EMU_BUACT_BUEXRANGE(v) \ + (((v) << EMU_BUACT_BUEXRANGE_SHIFT) & EMU_BUACT_BUEXRANGE_MASK) + +#define EMU_BUACT_BUEXTHRES_SHIFT (0) +#define EMU_BUACT_BUEXTHRES_MASK (0x7 << EMU_BUACT_BUEXTHRES_SHIFT) +#define EMU_BUACT_BUEXTHRES(v) \ + (((v) << EMU_BUACT_BUEXTHRES_SHIFT) & EMU_BUACT_BUEXTHRES_MASK) + +/* EMU_STATUS */ +#define EMU_STATUS_BURDY (1 << 0) + +/* EMU_ROUTE */ +#define EMU_ROUTE_BUVINPEN (1 << 0) + +/* EMU_IF */ +#define EMU_IF_BURDY (1 << 0) + +/* EMU_IFS */ +#define EMU_IFS_BURDY (1 << 0) + +/* EMU_IFC */ +#define EMU_IFC_BURDY (1 << 0) + +/* EMU_IEN */ +#define EMU_IEN_BURDY (1 << 0) + +/* EMU_BUBODBUVINCAL */ +#define EMU_BUBODBUVINCAL_RANGE_SHIFT (3) +#define EMU_BUBODBUVINCAL_RANGE_MASK (0x3 << EMU_BUBODBUVINCAL_RANGE_SHIFT) +#define EMU_BUBODBUVINCAL_RANGE(v) \ + (((v) << EMU_BUBODBUVINCAL_RANGE_SHIFT) & \ + EMU_BUBODBUVINCAL_RANGE_MASK) + +#define EMU_BUBODBUVINCAL_THRES_SHIFT (0) +#define EMU_BUBODBUVINCAL_THRES_MASK (0x7 << EMU_BUBODBUVINCAL_THRES_SHIFT) +#define EMU_BUBODBUVINCAL_THRES(v) \ + (((v) << EMU_BUBODBUVINCAL_THRES_SHIFT) & \ + EMU_BUBODBUVINCAL_THRES_MASK) + +/* EMU_BUBODUNREGCAL */ +#define EMU_BUBODUNREGCAL_RANGE_SHIFT (3) +#define EMU_BUBODUNREGCAL_RANGE_MASK (0x3 << EMU_BUBODUNREGCAL_RANGE_SHIFT) +#define EMU_BUBODUNREGCAL_RANGE(v) \ + (((v) << EMU_BUBODUNREGCAL_RANGE_SHIFT) & \ + EMU_BUBODUNREGCAL_RANGE_MASK) + +#define EMU_BUBODUNREGCAL_THRES_SHIFT (0) +#define EMU_BUBODUNREGCAL_THRES_MASK (0x7 << EMU_BUBODUNREGCAL_THRES_SHIFT) +#define EMU_BUBODUNREGCAL_THRES(v) \ + (((v) << EMU_BUBODUNREGCAL_THRES_SHIFT) & \ + EMU_BUBODUNREGCAL_THRES_MASK) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/gpio.h new file mode 100644 index 00000000..070a201f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/gpio.h @@ -0,0 +1,330 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_GPIO_H +#define LIBOPENCM3_EFM32_GPIO_H + +#include +#include + +#define GPIO_P(i) (GPIO_BASE + (0x24 * (i))) +#define GPIO_PA GPIO_P(0) +#define GPIO_PB GPIO_P(1) +#define GPIO_PC GPIO_P(2) +#define GPIO_PD GPIO_P(3) +#define GPIO_PE GPIO_P(4) +#define GPIO_PF GPIO_P(5) + +#define GPIO_P_CTRL(port) MMIO32((port) + 0x00) +#define GPIO_PA_CTRL GPIO_P_CTRL(GPIO_PA) +#define GPIO_PB_CTRL GPIO_P_CTRL(GPIO_PB) +#define GPIO_PC_CTRL GPIO_P_CTRL(GPIO_PC) +#define GPIO_PD_CTRL GPIO_P_CTRL(GPIO_PD) +#define GPIO_PE_CTRL GPIO_P_CTRL(GPIO_PE) +#define GPIO_PF_CTRL GPIO_P_CTRL(GPIO_PF) + +#define GPIO_P_CTRL_DRIVEMODE_SHIFT (0) +#define GPIO_P_CTRL_DRIVEMODE_MASK (0x03 << GPIO_P_CTRL_DRIVEMODE_SHIFT) +#define GPIO_P_CTRL_DRIVEMODE(v) \ + (((v) << GPIO_P_CTRL_DRIVEMODE_SHIFT) & GPIO_P_CTRL_DRIVEMODE_MASK) +#define GPIO_P_CTRL_DRIVEMODE_STANDARD GPIO_P_CTRL_DRIVEMODE(0) +#define GPIO_P_CTRL_DRIVEMODE_LOWEST GPIO_P_CTRL_DRIVEMODE(1) +#define GPIO_P_CTRL_DRIVEMODE_HIGH GPIO_P_CTRL_DRIVEMODE(2) +#define GPIO_P_CTRL_DRIVEMODE_LOW GPIO_P_CTRL_DRIVEMODE(3) + +/* NOTE: GPIO_MODE and GPIO_MODE_MASK is generic. + * it is used with both GPIO_Px_MODEL and GPIO_Px_MODEH */ +#define GPIO_P_MODE_MODEx_MASK(x) (0x0F << (((x) & 0x7) * 4)) +/* for mode: use GPIO_MODE_* */ +#define GPIO_P_MODE_MODEx(x, mode) \ + (((mode) << (((x) & 0x7) * 4)) & GPIO_P_MODE_MODEx_MASK(x)) + +#define GPIO_P_MODEL(port) MMIO32((port) + 0x04) +#define GPIO_PA_MODEL GPIO_P_MODEL(GPIO_PA) +#define GPIO_PB_MODEL GPIO_P_MODEL(GPIO_PB) +#define GPIO_PC_MODEL GPIO_P_MODEL(GPIO_PC) +#define GPIO_PD_MODEL GPIO_P_MODEL(GPIO_PD) +#define GPIO_PE_MODEL GPIO_P_MODEL(GPIO_PE) + +#define GPIO_P_MODEL_MODEx_MASK(x) GPIO_P_MODE_MODEx_MASK(x) +#define GPIO_P_MODEL_MODEx(x, mode) GPIO_P_MODE_MODEx(x, mode) + +#define GPIO_P_MODEL_MODE0_MASK GPIO_P_MODEL_MODEx_MASK(0) +#define GPIO_P_MODEL_MODE0(mode) GPIO_P_MODEL_MODEx(0, mode) + +#define GPIO_P_MODEL_MODE1_MASK GPIO_P_MODEL_MODEx_MASK(1) +#define GPIO_P_MODEL_MODE1(mode) GPIO_P_MODEL_MODEx(1, mode) + +#define GPIO_P_MODEL_MODE2_MASK GPIO_P_MODEL_MODEx_MASK(2) +#define GPIO_P_MODEL_MODE2(mode) GPIO_P_MODEL_MODEx(2, mode) + +#define GPIO_P_MODEL_MODE3_MASK GPIO_P_MODEL_MODEx_MASK(3) +#define GPIO_P_MODEL_MODE3(mode) GPIO_P_MODEL_MODEx(3, mode) + +#define GPIO_P_MODEL_MODE4_MASK GPIO_P_MODEL_MODEx_MASK(4) +#define GPIO_P_MODEL_MODE4(mode) GPIO_P_MODEL_MODEx(4, mode) + +#define GPIO_P_MODEL_MODE5_MASK GPIO_P_MODEL_MODEx_MASK(5) +#define GPIO_P_MODEL_MODE5(mode) GPIO_P_MODEL_MODEx(5, mode) + +#define GPIO_P_MODEL_MODE6_MASK GPIO_P_MODEL_MODEx_MASK(6) +#define GPIO_P_MODEL_MODE6(mode) GPIO_P_MODEL_MODEx(6, mode) + +#define GPIO_P_MODEL_MODE7_MASK GPIO_P_MODEL_MODEx_MASK(7) +#define GPIO_P_MODEL_MODE7(mode) GPIO_P_MODEL_MODEx(7, mode) + +#define GPIO_P_MODEH(port) MMIO32((port) + 0x08) +#define GPIO_PA_MODEH GPIO_P_MODEH(GPIO_PA) +#define GPIO_PB_MODEH GPIO_P_MODEH(GPIO_PB) +#define GPIO_PC_MODEH GPIO_P_MODEH(GPIO_PC) +#define GPIO_PD_MODEH GPIO_P_MODEH(GPIO_PD) +#define GPIO_PE_MODEH GPIO_P_MODEH(GPIO_PE) + +/* note: (x - 8) is because for MODEH, MODE8 refers to offset 0 */ +#define GPIO_P_MODEH_MODEx_MASK(x) GPIO_P_MODE_MODEx_MASK((x) - 8) +#define GPIO_P_MODEH_MODEx(x, mode) GPIO_P_MODE_MODEx((x) - 8, mode) + +#define GPIO_P_MODEH_MODE8_MASK GPIO_P_MODEH_MODEx_MASK(8) +#define GPIO_P_MODEH_MODE8(mode) GPIO_P_MODEH_MODEx(8, mode) + +#define GPIO_P_MODEH_MODE9_MASK GPIO_P_MODEH_MODEx_MASK(9) +#define GPIO_P_MODEH_MODE9(mode) GPIO_P_MODEH_MODEx(9, mode) + +#define GPIO_P_MODEH_MODE10_MASK GPIO_P_MODEH_MODEx_MASK(10) +#define GPIO_P_MODEH_MODE10(mode) GPIO_P_MODEH_MODEx(10, mode) + +#define GPIO_P_MODEH_MODE11_MASK GPIO_P_MODEH_MODEx_MASK(11) +#define GPIO_P_MODEH_MODE11(mode) GPIO_P_MODEH_MODEx(11, mode) + +#define GPIO_P_MODEH_MODE12_MASK GPIO_P_MODEH_MODEx_MASK(12) +#define GPIO_P_MODEH_MODE12(mode) GPIO_P_MODEH_MODEx(12, mode) + +#define GPIO_P_MODEH_MODE13_MASK GPIO_P_MODEH_MODEx_MASK(13) +#define GPIO_P_MODEH_MODE13(mode) GPIO_P_MODEH_MODEx(13, mode) + +#define GPIO_P_MODEH_MODE14_MASK GPIO_P_MODEH_MODEx_MASK(14) +#define GPIO_P_MODEH_MODE14(mode) GPIO_P_MODEH_MODEx(14, mode) + +#define GPIO_P_MODEH_MODE15_MASK GPIO_P_MODEH_MODEx_MASK(15) +#define GPIO_P_MODEH_MODE15(mode) GPIO_P_MODEH_MODEx(15, mode) + +#define GPIO_P_DOUT(port) MMIO32((port) + 0x0C) +#define GPIO_PA_DOUT GPIO_P_DOUT(GPIO_PA) +#define GPIO_PB_DOUT GPIO_P_DOUT(GPIO_PB) +#define GPIO_PC_DOUT GPIO_P_DOUT(GPIO_PC) +#define GPIO_PD_DOUT GPIO_P_DOUT(GPIO_PD) +#define GPIO_PE_DOUT GPIO_P_DOUT(GPIO_PE) + +#define GPIO_P_DOUTSET(port) MMIO32((port) + 0x10) +#define GPIO_PA_DOUTSET GPIO_P_DOUTSET(GPIO_PA) +#define GPIO_PB_DOUTSET GPIO_P_DOUTSET(GPIO_PB) +#define GPIO_PC_DOUTSET GPIO_P_DOUTSET(GPIO_PC) +#define GPIO_PD_DOUTSET GPIO_P_DOUTSET(GPIO_PD) +#define GPIO_PE_DOUTSET GPIO_P_DOUTSET(GPIO_PE) + +#define GPIO_P_DOUTCLR(port) MMIO32((port) + 0x14) +#define GPIO_PA_DOUTCLR GPIO_P_DOUTCLR(GPIO_PA) +#define GPIO_PB_DOUTCLR GPIO_P_DOUTCLR(GPIO_PB) +#define GPIO_PC_DOUTCLR GPIO_P_DOUTCLR(GPIO_PC) +#define GPIO_PD_DOUTCLR GPIO_P_DOUTCLR(GPIO_PD) +#define GPIO_PE_DOUTCLR GPIO_P_DOUTCLR(GPIO_PE) + +#define GPIO_P_DOUTTGL(port) MMIO32((port) + 0x18) +#define GPIO_PA_DOUTTGL GPIO_P_DOUTTGL(GPIO_PA) +#define GPIO_PB_DOUTTGL GPIO_P_DOUTTGL(GPIO_PB) +#define GPIO_PC_DOUTTGL GPIO_P_DOUTTGL(GPIO_PC) +#define GPIO_PD_DOUTTGL GPIO_P_DOUTTGL(GPIO_PD) +#define GPIO_PE_DOUTTGL GPIO_P_DOUTTGL(GPIO_PE) + +#define GPIO_P_DIN(port) MMIO32((port) + 0x1C) +#define GPIO_PA_DIN GPIO_P_DIN(GPIO_PA) +#define GPIO_PB_DIN GPIO_P_DIN(GPIO_PB) +#define GPIO_PC_DIN GPIO_P_DIN(GPIO_PC) +#define GPIO_PD_DIN GPIO_P_DIN(GPIO_PD) +#define GPIO_PE_DIN GPIO_P_DIN(GPIO_PE) + +#define GPIO_P_PINLOCKN(port) MMIO32((port) + 0x20) +#define GPIO_PA_PINLOCKN GPIO_P_PINLOCKN(GPIO_PA) +#define GPIO_PB_PINLOCKN GPIO_P_PINLOCKN(GPIO_PB) +#define GPIO_PC_PINLOCKN GPIO_P_PINLOCKN(GPIO_PC) +#define GPIO_PD_PINLOCKN GPIO_P_PINLOCKN(GPIO_PD) +#define GPIO_PE_PINLOCKN GPIO_P_PINLOCKN(GPIO_PE) + +#define GPIO_EXTIPSELL MMIO32(GPIO_BASE + 0x100) +#define GPIO_EXTIPSELH MMIO32(GPIO_BASE + 0x104) +#define GPIO_EXTIRISE MMIO32(GPIO_BASE + 0x108) +#define GPIO_EXTIFALL MMIO32(GPIO_BASE + 0x10C) +#define GPIO_IEN MMIO32(GPIO_BASE + 0x110) +#define GPIO_IF MMIO32(GPIO_BASE + 0x114) +#define GPIO_IFS MMIO32(GPIO_BASE + 0x118) +#define GPIO_IFC MMIO32(GPIO_BASE + 0x11C) +#define GPIO_ROUTE MMIO32(GPIO_BASE + 0x120) +#define GPIO_INSENSE MMIO32(GPIO_BASE + 0x124) +#define GPIO_LOCK MMIO32(GPIO_BASE + 0x128) +#define GPIO_CTRL MMIO32(GPIO_BASE + 0x12C) +#define GPIO_CMD MMIO32(GPIO_BASE + 0x130) +#define GPIO_EM4WUEN MMIO32(GPIO_BASE + 0x134) +#define GPIO_EM4WUPOL MMIO32(GPIO_BASE + 0x138) +#define GPIO_EM4WUCAUSE MMIO32(GPIO_BASE + 0x13C) + +/* mask is performed so that can be used with L and H */ +#define GPIO_EXTIPSEL_MASK(n) (0x7 << ((n) & 0xF)) +#define GPIO_EXTIPSEL_PORTMASK(n, v) ((v) << ((n) & 0xF)) +#define GPIO_EXTIPSEL_PORTA 0x0 +#define GPIO_EXTIPSEL_PORTB 0x1 +#define GPIO_EXTIPSEL_PORTC 0x2 +#define GPIO_EXTIPSEL_PORTD 0x3 +#define GPIO_EXTIPSEL_PORTE 0x4 +#define GPIO_EXTIPSEL_PORTF 0x5 + +#define GPIO_ROUTE_SWCLKPEN (1 << 0) +#define GPIO_ROUTE_SWDIOPEN (1 << 1) +#define GPIO_ROUTE_SWOPEN (1 << 3) + +#define GPIO_ROUTE_SWLOCATION_SHIFT (8) +#define GPIO_ROUTE_SWLOCATION_MASK (0x3 << GPIO_ROUTE_SWLOCATION_SHIFT) +#define GPIO_ROUTE_SWLOCATION(v) \ + (((v) << GPIO_ROUTE_SWLOCATION_SHIFT) & GPIO_ROUTE_SWLOCATION_MASK) + +#define GPIO_ROUTE_TCLKPEN (1 << 12) +#define GPIO_ROUTE_TD0PEN (1 << 13) +#define GPIO_ROUTE_TD1PEN (1 << 14) +#define GPIO_ROUTE_TD2PEN (1 << 15) +#define GPIO_ROUTE_TD3PEN (1 << 16) + +#define GPIO_ROUTE_ETMLOCATION_SHIFT (24) +#define GPIO_ROUTE_ETMLOCATION_MASK (0x3 << GPIO_ROUTE_ETMLOCATION_SHIFT) +#define GPIO_ROUTE_ETMLOCATION(v) \ + (((v) << GPIO_ROUTE_ETMLOCATION_SHIFT) & GPIO_ROUTE_ETMLOCATION_MASK) +#define GPIO_ROUTE_ETMLOCATION_LOCx(x) GPIO_ROUTE_ETMLOCATION(x) +#define GPIO_ROUTE_ETMLOCATION_LOC0 GPIO_ROUTE_ETMLOCATION_LOCx(0) +#define GPIO_ROUTE_ETMLOCATION_LOC1 GPIO_ROUTE_ETMLOCATION_LOCx(1) +#define GPIO_ROUTE_ETMLOCATION_LOC2 GPIO_ROUTE_ETMLOCATION_LOCx(2) +#define GPIO_ROUTE_ETMLOCATION_LOC3 GPIO_ROUTE_ETMLOCATION_LOCx(3) + +#define GPIO_INSENSE_INT (1 << 0) +#define GPIO_INSENSE_PRS (1 << 1) + +#define GPIO_LOCK_LOCKKEY_SHIFT (0) +#define GPIO_LOCK_LOCKKEY_MASK (0xFFFF << GPIO_LOCK_LOCKKEY_SHIFT) +#define GPIO_LOCK_LOCKKEY_UNLOCKED (0x0000 << GPIO_LOCK_LOCKKEY_SHIFT) +#define GPIO_LOCK_LOCKKEY_LOCKED (0x0001 << GPIO_LOCK_LOCKKEY_SHIFT) +#define GPIO_LOCK_LOCKKEY_LOCK (0x0000 << GPIO_LOCK_LOCKKEY_SHIFT) +#define GPIO_LOCK_LOCKKEY_UNLOCK (0xA534 << GPIO_LOCK_LOCKKEY_SHIFT) + +#define GPIO_CTRL_EM4RET (1 << 0) + +#define GPIO_CMD_EM4WUCLR (1 << 0) + +#define GPIO_EM4WUEN_EM4WUEN_A0 (1 << 0) +#define GPIO_EM4WUEN_EM4WUEN_A6 (1 << 1) +#define GPIO_EM4WUEN_EM4WUEN_C9 (1 << 2) +#define GPIO_EM4WUEN_EM4WUEN_F1 (1 << 3) +#define GPIO_EM4WUEN_EM4WUEN_F2 (1 << 4) +#define GPIO_EM4WUEN_EM4WUEN_E13 (1 << 5) + +#define GPIO_EM4WUPOL_EM4WUPOL_A0 (1 << 0) +#define GPIO_EM4WUPOL_EM4WUPOL_A6 (1 << 1) +#define GPIO_EM4WUPOL_EM4WUPOL_C9 (1 << 2) +#define GPIO_EM4WUPOL_EM4WUPOL_F1 (1 << 3) +#define GPIO_EM4WUPOL_EM4WUPOL_F2 (1 << 4) +#define GPIO_EM4WUPOL_EM4WUPOL_E13 (1 << 5) + +#define GPIO0 (1 << 0) +#define GPIO1 (1 << 1) +#define GPIO2 (1 << 2) +#define GPIO3 (1 << 3) +#define GPIO4 (1 << 4) +#define GPIO5 (1 << 5) +#define GPIO6 (1 << 6) +#define GPIO7 (1 << 7) +#define GPIO8 (1 << 8) +#define GPIO9 (1 << 9) +#define GPIO10 (1 << 10) +#define GPIO11 (1 << 11) +#define GPIO12 (1 << 12) +#define GPIO13 (1 << 13) +#define GPIO14 (1 << 14) +#define GPIO15 (1 << 15) +#define GPIO_ALL (0xFFFF) + +/* These are the acceptable mode values. + * (+ readable counterparts) + * do not confuse GPIO_MODE_* for GPIO_P_MODE_MODEx. + */ +enum gpio_mode { + GPIO_MODE_DISABLE = 0, + GPIO_MODE_INPUT, + GPIO_MODE_INPUT_PULL, + GPIO_MODE_INPUT_PULL_FILTER, + GPIO_MODE_PUSH_PULL, + GPIO_MODE_PUSH_PULL_DRIVE, + GPIO_MODE_WIRED_OR, + GPIO_MODE_WIRED_OR_PULL_DOWN, + GPIO_MODE_WIRED_AND, + GPIO_MODE_WIRED_AND_FILTER, + GPIO_MODE_WIRED_AND_PULLUP, + GPIO_MODE_WIRED_AND_PULLUP_FILTER, + GPIO_MODE_WIRED_AND_DRIVE, + GPIO_MODE_WIRED_AND_DRIVE_FILTER, + GPIO_MODE_WIRED_AND_DRIVE_PULLUP, + GPIO_MODE_WIRED_AND_DRIVE_PULLUP_FILTER +}; + +/* for readability. */ +enum gpio_drive_strength { + GPIO_STRENGTH_STANDARD = 0, + GPIO_STRENGTH_LOWEST, + GPIO_STRENGTH_HIGH, + GPIO_STRENGTH_LOW +}; + +/* for readability */ +#define GPIOA GPIO_PA +#define GPIOB GPIO_PB +#define GPIOC GPIO_PC +#define GPIOD GPIO_PD +#define GPIOE GPIO_PE +#define GPIOF GPIO_PF + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void gpio_enable_lock(void); +void gpio_disable_lock(void); +bool gpio_get_lock_flag(void); + +void gpio_set_drive_strength(uint32_t gpio_port, + enum gpio_drive_strength driver_stength); +void gpio_mode_setup(uint32_t gpio_port, enum gpio_mode mode, uint16_t gpios); + +void gpio_set(uint32_t gpio_port, uint16_t gpios); +void gpio_clear(uint32_t gpio_port, uint16_t gpios); +uint16_t gpio_get(uint32_t gpio_port, uint16_t gpios); +void gpio_toggle(uint32_t gpio_port, uint16_t gpios); +uint16_t gpio_port_read(uint32_t gpio_port); +void gpio_port_write(uint32_t gpio_port, uint16_t data); + +void gpio_port_config_lock(uint32_t gpio_port, uint16_t gpios); + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/i2c.h new file mode 100644 index 00000000..04ab83a0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/i2c.h @@ -0,0 +1,269 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_I2C_H +#define LIBOPENCM3_EFM32_I2C_H + +#include +#include + +#define I2C_CTRL(base) MMIO32((base) + 0x000) +#define I2C_CMD(base) MMIO32((base) + 0x004) +#define I2C_STATE(base) MMIO32((base) + 0x008) +#define I2C_STATUS(base) MMIO32((base) + 0x00C) +#define I2C_CLKDIV(base) MMIO32((base) + 0x010) +#define I2C_SADDR(base) MMIO32((base) + 0x014) +#define I2C_SADDRMASK(base) MMIO32((base) + 0x018) +#define I2C_RXDATA(base) MMIO32((base) + 0x01C) +#define I2C_RXDATAP(base) MMIO32((base) + 0x020) +#define I2C_TXDATA(base) MMIO32((base) + 0x024) +#define I2C_IF(base) MMIO32((base) + 0x028) +#define I2C_IFS(base) MMIO32((base) + 0x02C) +#define I2C_IFC(base) MMIO32((base) + 0x030) +#define I2C_IEN(base) MMIO32((base) + 0x034) +#define I2C_ROUTE(base) MMIO32((base) + 0x038) + +/* I2C_CTRL */ +#define I2C_CTRL_CLTO_SHIFT (16) +#define I2C_CTRL_CLTO_MASK (0x7 << I2C_CTRL_CLTO_SHIFT) +#define I2C_CTRL_CLTO(v) \ + (((v) << I2C_CTRL_CLTO_SHIFT) & I2C_CTRL_CLTO_MASK) +#define I2C_CTRL_CLTO_OFF I2C_CTRL_CLTO(0) +#define I2C_CTRL_CLTO_40PCC I2C_CTRL_CLTO(1) +#define I2C_CTRL_CLTO_80PCC I2C_CTRL_CLTO(2) +#define I2C_CTRL_CLTO_160PCC I2C_CTRL_CLTO(3) +#define I2C_CTRL_CLTO_320PPC I2C_CTRL_CLTO(4) +#define I2C_CTRL_CLTO_1024PPC I2C_CTRL_CLTO(5) + +#define I2C_CTRL_GIBITO (1 << 15) + +#define I2C_CTRL_BTO_SHIFT (12) +#define I2C_CTRL_BTO_MASK (0x3 << I2C_CTRL_BTO_SHIFT) +#define I2C_CTRL_BTO(v) \ + (((v) << I2C_CTRL_BTO_SHIFT) & I2C_CTRL_BTO_MASK) +#define I2C_CTRL_BTO_OFF I2C_CTRL_BTO(0) +#define I2C_CTRL_BTO_40PCC I2C_CTRL_BTO(1) +#define I2C_CTRL_BTO_80PCC I2C_CTRL_BTO(2) +#define I2C_CTRL_BTO_160PCC I2C_CTRL_BTO(3) + +#define I2C_CTRL_CLHR_SHIFT (12) +#define I2C_CTRL_CLHR_MASK (0x3 << I2C_CTRL_CLHR_SHIFT) +#define I2C_CTRL_CLHR(v) \ + (((v) << I2C_CTRL_CLHR_SHIFT) & I2C_CTRL_CLHR_MASK) +#define I2C_CTRL_CLHR_STANDARD I2C_CTRL_CLHR(0) +#define I2C_CTRL_CLHR_ASYMMETRIC I2C_CTRL_CLHR(1) +#define I2C_CTRL_CLHR_FAST I2C_CTRL_CLHR(2) + +#define I2C_CTRL_GCAMEN (1 << 6) +#define I2C_CTRL_ARBDIS (1 << 5) +#define I2C_CTRL_AUTOSN (1 << 4) +#define I2C_CTRL_AUTOSE (1 << 3) +#define I2C_CTRL_AUTOACK (1 << 2) +#define I2C_CTRL_SLAVE (1 << 1) +#define I2C_CTRL_EN (1 << 0) + +/* I2C_CMD */ +#define I2C_CMD_CLEARPC (1 << 7) +#define I2C_CMD_CLEARTX (1 << 6) +#define I2C_CMD_ABORT (1 << 5) +#define I2C_CMD_CONT (1 << 4) +#define I2C_CMD_NACK (1 << 3) +#define I2C_CMD_ACK (1 << 2) +#define I2C_CMD_STOP (1 << 1) +#define I2C_CMD_START (1 << 0) + +/* I2C_STATE */ +#define I2C_STATE_STATE_SHIFT (5) +#define I2C_STATE_STATE_MASK (0x7 << I2C_STATE_STATE_SHIFT) +#define I2C_STATE_STATE(v) \ + (((v) << I2C_STATE_STATE_SHIFT) & I2C_STATE_STATE_MASK) +#define I2C_STATE_STATE_IDLE I2C_STATE_STATE(0) +#define I2C_STATE_STATE_WAIT I2C_STATE_STATE(1) +#define I2C_STATE_STATE_START I2C_STATE_STATE(2) +#define I2C_STATE_STATE_ADDR I2C_STATE_STATE(3) +#define I2C_STATE_STATE_ADDRACK I2C_STATE_STATE(4) +#define I2C_STATE_STATE_DATA I2C_STATE_STATE(5) +#define I2C_STATE_STATE_DATAACK I2C_STATE_STATE(6) + +#define I2C_STATE_BUSHOLD (1 << 4) +#define I2C_STATE_NACKED (1 << 3) +#define I2C_STATE_TRANSMITTER (1 << 2) +#define I2C_STATE_MASTER (1 << 1) +#define I2C_STATE_BUSY (1 << 0) + +/* I2C_STATUS */ +#define I2C_STATUS_RXDATAV (1 << 8) +#define I2C_STATUS_TXBL (1 << 7) +#define I2C_STATUS_TXC (1 << 6) +#define I2C_STATUS_PABORT (1 << 5) +#define I2C_STATUS_PCONT (1 << 4) +#define I2C_STATUS_PNACK (1 << 3) +#define I2C_STATUS_PACK (1 << 2) +#define I2C_STATUS_PSTOP (1 << 1) +#define I2C_STATUS_PSTART (1 << 0) + +/* I2C_CLKDIV */ +#define I2C_CLKDIV_DIV_SHIFT (0) +#define I2C_CLKDIV_DIV_MASK (0xFF << I2C_CLKDIV_DIV_SHIFT) +#define I2C_CLKDIV_DIV(v) \ + (((v) << I2C_CLKDIV_DIV_SHIFT) & I2C_CLKDIV_DIV_MASK) + +/* I2C_SADDR */ +#define I2C_SADDR_ADDR_SHIFT (0) +#define I2C_SADDR_ADDR_MASK (0xFF << I2C_SADDR_ADDR_SHIFT) +#define I2C_SADDR_ADDR(v) \ + (((v) << I2C_SADDR_ADDR_SHIFT) & I2C_SADDR_ADDR_MASK) + +/* I2C_SADDRMASK */ +#define I2C_SADDRMASK_MASK_SHIFT (0) +#define I2C_SADDRMASK_MASK_MASK (0xFF << I2C_SADDRMASK_MASK_SHIFT) +#define I2C_SADDRMASK_MASK(v) \ + (((v) << I2C_SADDRMASK_MASK_SHIFT) & I2C_SADDRMASK_MASK_MASK) + +/* I2C_IF */ +#define I2C_IF_SSTOP (1 << 16) +#define I2C_IF_CLTO (1 << 15) +#define I2C_IF_BITO (1 << 14) +#define I2C_IF_RXUF (1 << 13) +#define I2C_IF_TXOF (1 << 12) +#define I2C_IF_BUSHOLD (1 << 11) +#define I2C_IF_BUSERR (1 << 10) +#define I2C_IF_ARBLOST (1 << 9) +#define I2C_IF_MSTOP (1 << 8) +#define I2C_IF_NACK (1 << 7) +#define I2C_IF_ACK (1 << 6) +#define I2C_IF_RXDATAV (1 << 5) +#define I2C_IF_TXBL (1 << 4) +#define I2C_IF_TXC (1 << 3) +#define I2C_IF_ADDR (1 << 2) +#define I2C_IF_RSTART (1 << 1) +#define I2C_IF_START (1 << 0) + +/* I2C_IFS */ +#define I2C_IFS_SSTOP (1 << 16) +#define I2C_IFS_CLTO (1 << 15) +#define I2C_IFS_BITO (1 << 14) +#define I2C_IFS_RXUF (1 << 13) +#define I2C_IFS_TXOF (1 << 12) +#define I2C_IFS_BUSHOLD (1 << 11) +#define I2C_IFS_BUSERR (1 << 10) +#define I2C_IFS_ARBLOST (1 << 9) +#define I2C_IFS_MSTOP (1 << 8) +#define I2C_IFS_NACK (1 << 7) +#define I2C_IFS_ACK (1 << 6) +#define I2C_IFS_RXDATAV (1 << 5) +#define I2C_IFS_TXBL (1 << 4) +#define I2C_IFS_TXC (1 << 3) +#define I2C_IFS_ADDR (1 << 2) +#define I2C_IFS_RSTART (1 << 1) +#define I2C_IFS_START (1 << 0) + +/* I2C_IFC */ +#define I2C_IFC_SSTOP (1 << 16) +#define I2C_IFC_CLTO (1 << 15) +#define I2C_IFC_BITO (1 << 14) +#define I2C_IFC_RXUF (1 << 13) +#define I2C_IFC_TXOF (1 << 12) +#define I2C_IFC_BUSHOLD (1 << 11) +#define I2C_IFC_BUSERR (1 << 10) +#define I2C_IFC_ARBLOST (1 << 9) +#define I2C_IFC_MSTOP (1 << 8) +#define I2C_IFC_NACK (1 << 7) +#define I2C_IFC_ACK (1 << 6) +#define I2C_IFC_RXDATAV (1 << 5) +#define I2C_IFC_TXBL (1 << 4) +#define I2C_IFC_TXC (1 << 3) +#define I2C_IFC_ADDR (1 << 2) +#define I2C_IFC_RSTART (1 << 1) +#define I2C_IFC_START (1 << 0) + +/* I2C_IEN */ +#define I2C_IEN_SSTOP (1 << 16) +#define I2C_IEN_CLTO (1 << 15) +#define I2C_IEN_BITO (1 << 14) +#define I2C_IEN_RXUF (1 << 13) +#define I2C_IEN_TXOF (1 << 12) +#define I2C_IEN_BUSHOLD (1 << 11) +#define I2C_IEN_BUSERR (1 << 10) +#define I2C_IEN_ARBLOST (1 << 9) +#define I2C_IEN_MSTOP (1 << 8) +#define I2C_IEN_NACK (1 << 7) +#define I2C_IEN_ACK (1 << 6) +#define I2C_IEN_RXDATAV (1 << 5) +#define I2C_IEN_TXBL (1 << 4) +#define I2C_IEN_TXC (1 << 3) +#define I2C_IEN_ADDR (1 << 2) +#define I2C_IEN_RSTART (1 << 1) +#define I2C_IEN_START (1 << 0) + +/* I2C_ROUTE */ +#define I2C_ROUTE_LOCATION_SHIFT (8) +#define I2C_ROUTE_LOCATION_MASK (0x7 << I2C_ROUTE_LOCATION_SHIFT) +#define I2C_ROUTE_LOCATION(v) \ + (((v) << I2C_ROUTE_LOCATION_SHIFT) & I2C_ROUTE_LOCATION_MASK) +#define I2C_ROUTE_LOCATION_LOCx(x) I2C_ROUTE_LOCATION(x) +#define I2C_ROUTE_LOCATION_LOC0 I2C_ROUTE_LOCATION_LOCx(0) +#define I2C_ROUTE_LOCATION_LOC1 I2C_ROUTE_LOCATION_LOCx(1) +#define I2C_ROUTE_LOCATION_LOC2 I2C_ROUTE_LOCATION_LOCx(2) +#define I2C_ROUTE_LOCATION_LOC3 I2C_ROUTE_LOCATION_LOCx(3) +#define I2C_ROUTE_LOCATION_LOC4 I2C_ROUTE_LOCATION_LOCx(4) +#define I2C_ROUTE_LOCATION_LOC5 I2C_ROUTE_LOCATION_LOCx(5) +#define I2C_ROUTE_LOCATION_LOC6 I2C_ROUTE_LOCATION_LOCx(6) + +#define I2C_ROUTE_SCLPEN (1 << 1) +#define I2C_ROUTE_SDAPEN (1 << 0) + +/* I2C0 */ +#define I2C0 I2C0_BASE +#define I2C0_CTRL I2C_CTRL(base) +#define I2C0_CMD I2C_CMD(base) +#define I2C0_STATE I2C_STATE(base) +#define I2C0_STATUS I2C_STATUS(base) +#define I2C0_CLKDIV I2C_CLKDIV(base) +#define I2C0_SADDR I2C_SADDR(base) +#define I2C0_SADDRMASK I2C_SADDRMASK(base) +#define I2C0_RXDATA I2C_RXDATA(base) +#define I2C0_RXDATAP I2C_RXDATAP(base) +#define I2C0_TXDATA I2C_TXDATA(base) +#define I2C0_IF I2C_IF(base) +#define I2C0_IFS I2C_IFS(base) +#define I2C0_IFC I2C_IFC(base) +#define I2C0_IEN I2C_IEN(base) +#define I2C0_ROUTE I2C_ROUTE(base) + +/* I2C1 */ +#define I2C1 I2C1_BASE +#define I2C1_CTRL I2C_CTRL(base) +#define I2C1_CMD I2C_CMD(base) +#define I2C1_STATE I2C_STATE(base) +#define I2C1_STATUS I2C_STATUS(base) +#define I2C1_CLKDIV I2C_CLKDIV(base) +#define I2C1_SADDR I2C_SADDR(base) +#define I2C1_SADDRMASK I2C_SADDRMASK(base) +#define I2C1_RXDATA I2C_RXDATA(base) +#define I2C1_RXDATAP I2C_RXDATAP(base) +#define I2C1_TXDATA I2C_TXDATA(base) +#define I2C1_IF I2C_IF(base) +#define I2C1_IFS I2C_IFS(base) +#define I2C1_IFC I2C_IFC(base) +#define I2C1_IEN I2C_IEN(base) +#define I2C1_ROUTE I2C_ROUTE(base) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/irq.json new file mode 100644 index 00000000..beb036dc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/irq.json @@ -0,0 +1,46 @@ +{ + "_source": "The names and sequence are taken from d0183_efm32lg_reference_manual.pdf table 4.1.", + "irqs": [ + "dma", + "gpio_even", + "timer0", + "usart0_rx", + "usart0_tx", + "usb", + "acmp01", + "adc0", + "dac0", + "i2c0", + "i2c1", + "gpio_odd", + "timer1", + "timer2", + "timer3", + "usart1_rx", + "usart1_tx", + "lesense", + "usart2_rx", + "usart2_tx", + "uart0_rx", + "uart0_tx", + "uart1_rx", + "uart1_tx", + "leuart0", + "leuart1", + "letimer0", + "pcnt0", + "pcnt1", + "pcnt2", + "rtc", + "burtc", + "cmu", + "vcmp", + "lcd", + "msc", + "aes", + "ebi" + ], + "partname_humanreadable": "EFM32 Leopard Gecko series", + "partname_doxygen": "EFM32LG", + "includeguard": "LIBOPENCM3_EFM32LG_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/letimer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/letimer.h new file mode 100644 index 00000000..3526c6ef --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/letimer.h @@ -0,0 +1,165 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_LETIMER_H +#define LIBOPENCM3_EFM32_LETIMER_H + +#include +#include + +#define LETIMER_CTRL(base) ((base) + 0x000) +#define LETIMER_CMD(base) ((base) + 0x004) +#define LETIMER_STATUS(base) ((base) + 0x008) +#define LETIMER_CNT(base) ((base) + 0x00C) +#define LETIMER_COMP0(base) ((base) + 0x010) +#define LETIMER_COMP1(base) ((base) + 0x014) +#define LETIMER_REP0(base) ((base) + 0x018) +#define LETIMER_REP1(base) ((base) + 0x01C) +#define LETIMER_IF(base) ((base) + 0x020) +#define LETIMER_IFS(base) ((base) + 0x024) +#define LETIMER_IFC(base) ((base) + 0x028) +#define LETIMER_IEN(base) ((base) + 0x02C) +#define LETIMER_FREEZE(base) ((base) + 0x030) +#define LETIMER_SYNCBUSY(base) ((base) + 0x034) +#define LETIMER_ROUTE(base) ((base) + 0x040) + +/* LETIMER_CTRL */ +#define LETIMER_CTRL_DEBUG (1 << 12) +#define LETIMER_CTRL_RTCC1TEN (1 << 11) +#define LETIMER_CTRL_RTCC0TEN (1 << 10) +#define LETIMER_CTRL_COMP0TOP (1 << 9) +#define LETIMER_CTRL_BUFTOP (1 << 8) +#define LETIMER_CTRL_OPOL1 (1 << 7) +#define LETIMER_CTRL_OPOL0 (1 << 6) + +#define LETIMER_CTRL_UFOA1_SHIFT (4) +#define LETIMER_CTRL_UFOA1_MASK (0x3 << LETIMER_CTRL_UFOA1_SHIFT) +#define LETIMER_CTRL_UFOA1(v) \ + (((v) << LETIMER_CTRL_UFOA1_SHIFT) & LETIMER_CTRL_UFOA1_MASK) +#define LETIMER_CTRL_UFOA1_NONE LETIMER_CTRL_UFOA1(0) +#define LETIMER_CTRL_UFOA1_TOGGLE LETIMER_CTRL_UFOA1(1) +#define LETIMER_CTRL_UFOA1_PULSE LETIMER_CTRL_UFOA1(2) +#define LETIMER_CTRL_UFOA1_PWM LETIMER_CTRL_UFOA1(3) + +#define LETIMER_CTRL_UFOA0_SHIFT (2) +#define LETIMER_CTRL_UFOA0_MASK (0x3 << LETIMER_CTRL_UFOA0_SHIFT) +#define LETIMER_CTRL_UFOA0(v) \ + (((v) << LETIMER_CTRL_UFOA0_SHIFT) & LETIMER_CTRL_UFOA0_MASK) +#define LETIMER_CTRL_UFOA0_NONE LETIMER_CTRL_UFOA0(0) +#define LETIMER_CTRL_UFOA0_TOGGLE LETIMER_CTRL_UFOA0(1) +#define LETIMER_CTRL_UFOA0_PULSE LETIMER_CTRL_UFOA0(2) +#define LETIMER_CTRL_UFOA0_PWM LETIMER_CTRL_UFOA0(3) + +#define LETIMER_CTRL_REPMODE_SHIFT (2) +#define LETIMER_CTRL_REPMODE_MASK (0x3 << LETIMER_CTRL_REPMODE_SHIFT) +#define LETIMER_CTRL_REPMODE(v) \ + (((v) << LETIMER_CTRL_REPMODE_SHIFT) & LETIMER_CTRL_REPMODE_MASK) +#define LETIMER_CTRL_REPMODE_FREE LETIMER_CTRL_REPMODE(0) +#define LETIMER_CTRL_REPMODE_ONESHOT LETIMER_CTRL_REPMODE(1) +#define LETIMER_CTRL_REPMODE_BUFFERED LETIMER_CTRL_REPMODE(2) +#define LETIMER_CTRL_REPMODE_DOUBLE LETIMER_CTRL_REPMODE(3) +#define LETIMER_CTRL_REPMODE_ONE_SHOT LETIMER_CTRL_REPMODE_ONESHOT + +/* LETIMER_CMD */ +#define LETIMER_CMD_CTO1 (1 << 4) +#define LETIMER_CMD_CTO0 (1 << 3) +#define LETIMER_CMD_CLEAR (1 << 2) +#define LETIMER_CMD_STOP (1 << 1) +#define LETIMER_CMD_START (1 << 0) + +/* LETIMER_STATUS */ +#define LETIMER_STATUS_RUNNING (1 << 0) + +/* LETIMER_IF */ +#define LETIMER_IF_REP1 (1 << 4) +#define LETIMER_IF_REP0 (1 << 3) +#define LETIMER_IF_UF (1 << 2) +#define LETIMER_IF_COMP1 (1 << 1) +#define LETIMER_IF_COMP0 (1 << 0) + +/* LETIMER_IFS */ +#define LETIMER_IFS_REP1 (1 << 4) +#define LETIMER_IFS_REP0 (1 << 3) +#define LETIMER_IFS_UF (1 << 2) +#define LETIMER_IFS_COMP1 (1 << 1) +#define LETIMER_IFS_COMP0 (1 << 0) + +/* LETIMER_IFC */ +#define LETIMER_IFC_REP1 (1 << 4) +#define LETIMER_IFC_REP0 (1 << 3) +#define LETIMER_IFC_UF (1 << 2) +#define LETIMER_IFC_COMP1 (1 << 1) +#define LETIMER_IFC_COMP0 (1 << 0) + +/* LETIMER_IFE */ +#define LETIMER_IFE_REP1 (1 << 4) +#define LETIMER_IFE_REP0 (1 << 3) +#define LETIMER_IFE_UF (1 << 2) +#define LETIMER_IFE_COMP1 (1 << 1) +#define LETIMER_IFE_COMP0 (1 << 0) + +/* LETIMER_FREEZE */ +#define LETIMER_FREEZE_REGFREEZE (1 << 0) + +/* LETIMER_SYNCBUSY */ +#define LETIMER_SYNCBUSY_REP1 (1 << 5) +#define LETIMER_SYNCBUSY_REP0 (1 << 4) +#define LETIMER_SYNCBUSY_COMP1 (1 << 3) +#define LETIMER_SYNCBUSY_COMP0 (1 << 2) +#define LETIMER_SYNCBUSY_CMD (1 << 1) +#define LETIMER_SYNCBUSY_CTRL (1 << 0) + +/* LETIMER_ROUTE */ +#define LETIMER_ROUTE_LOCATION_SHIFT (8) +#define LETIMER_ROUTE_LOCATION_MASK (0x7 << LETIMER_ROUTE_LOCATION_SHIFT) +#define LETIMER_ROUTE_LOCATION(v) \ + (((v) << LETIMER_ROUTE_LOCATION_SHIFT) & LETIMER_ROUTE_LOCATION_MASK) +#define LETIMER_ROUTE_LOCATION_LOCx(x) LETIMER_ROUTE_LOCATION(x) +#define LETIMER_ROUTE_LOCATION_LOC0 LETIMER_ROUTE_LOCATION_LOCx(0) +#define LETIMER_ROUTE_LOCATION_LOC1 LETIMER_ROUTE_LOCATION_LOCx(1) +#define LETIMER_ROUTE_LOCATION_LOC2 LETIMER_ROUTE_LOCATION_LOCx(2) +#define LETIMER_ROUTE_LOCATION_LOC3 LETIMER_ROUTE_LOCATION_LOCx(3) +#define LETIMER_ROUTE_LOCATION_LOC4 LETIMER_ROUTE_LOCATION_LOCx(4) +#define LETIMER_ROUTE_LOCATION_LOC5 LETIMER_ROUTE_LOCATION_LOCx(5) +#define LETIMER_ROUTE_LOCATION_LOC6 LETIMER_ROUTE_LOCATION_LOCx(6) +#define LETIMER_ROUTE_LOCATION_LOC7 LETIMER_ROUTE_LOCATION_LOCx(7) + +#define LETIMER_ROUTE_OUT1PEN (1 << 1) +#define LETIMER_ROUTE_OUT0PEN (1 << 0) + +/* LETIMER0 */ +#define LETIMER0 LETIMER0_BASE +#define LETIMER0_CTRL LETIMER_CTRL(LETIMER0) +#define LETIMER0_CMD LETIMER_CMD(LETIMER0) +#define LETIMER0_STATUS LETIMER_STATUS(LETIMER0) +#define LETIMER0_CNT LETIMER_CNT(LETIMER0) +#define LETIMER0_COMP0 LETIMER_COMP0(LETIMER0) +#define LETIMER0_COMP1 LETIMER_COMP1(LETIMER0) +#define LETIMER0_REP0 LETIMER_REP0(LETIMER0) +#define LETIMER0_REP1 LETIMER_REP1(LETIMER0) +#define LETIMER0_IF LETIMER_IF(LETIMER0) +#define LETIMER0_IFS LETIMER_IFS(LETIMER0) +#define LETIMER0_IFC LETIMER_IFC(LETIMER0) +#define LETIMER0_IEN LETIMER_IEN(LETIMER0) +#define LETIMER0_FREEZE LETIMER_FREEZE(LETIMER0) +#define LETIMER0_SYNCBUSY LETIMER_SYNCBUSY(LETIMER0) +#define LETIMER0_ROUTE LETIMER_ROUTE(LETIMER0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/memorymap.h new file mode 100644 index 00000000..22c0073d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/memorymap.h @@ -0,0 +1,117 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_MEMORYMAP_H +#define LIBOPENCM3_EFM32_MEMORYMAP_H + +#include + +#define PERIPH_BASE (0x40000000U) + +/* Device information */ +#define DI_BASE (0x0FE08000U) + +/* all names are "DI_" + */ +#define DI_CMU_LFRCOCTRL MMIO32(DI_BASE + 0x020) +#define DI_CMU_HFRCOCTRL MMIO32(DI_BASE + 0x028) +#define DI_CMU_AUXHFRCOCTRL MMIO32(DI_BASE + 0x030) +#define DI_ADC0_CAL MMIO32(DI_BASE + 0x040) +#define DI_ADC0_BIASPROG MMIO32(DI_BASE + 0x048) +#define DI_DAC0_CAL MMIO32(DI_BASE + 0x050) +#define DI_DAC0_BIASPROG MMIO32(DI_BASE + 0x058) +#define DI_ACMP0_CTRL MMIO32(DI_BASE + 0x060) +#define DI_ACMP1_CTRL MMIO32(DI_BASE + 0x068) +#define DI_CMU_LCDCTRL MMIO32(DI_BASE + 0x078) +#define DI_DAC0_OPACTRL MMIO32(DI_BASE + 0x0A0) +#define DI_DAC0_OPAOFFSET MMIO32(DI_BASE + 0x0A8) +#define DI_EMU_BUINACT MMIO32(DI_BASE + 0x0B0) +#define DI_EMU_BUACT MMIO32(DI_BASE + 0x0B8) +#define DI_EMU_BUBODBUVINCAL MMIO32(DI_BASE + 0x0C0) +#define DI_EMU_BUBODUNREGCAL MMIO32(DI_BASE + 0x0C8) +#define DI_DI_CRC MMIO16(DI_BASE + 0x1B0) +#define DI_CAL_TEMP_0 MMIO8(DI_BASE + 0x1B2) +#define DI_ADC0_CAL_1V25 MMIO16(DI_BASE + 0x1B4) +#define DI_ADC0_CAL_2V5 MMIO16(DI_BASE + 0x1B6) +#define DI_ADC0_CAL_VDD MMIO16(DI_BASE + 0x1B8) +#define DI_ADC0_CAL_5VDIFF MMIO16(DI_BASE + 0x1BA) +#define DI_ADC0_CAL_2XVDD MMIO16(DI_BASE + 0x1BC) +#define DI_ADC0_TEMP_0_READ_1V25 MMIO16(DI_BASE + 0x1BE) +#define DI_DAC0_CAL_1V25 MMIO32(DI_BASE + 0x1C8) +#define DI_DAC0_CAL_2V5 MMIO32(DI_BASE + 0x1CC) +#define DI_DAC0_CAL_VDD MMIO32(DI_BASE + 0x1D0) +#define DI_AUXHFRCO_CALIB_BAND_1 MMIO8(DI_BASE + 0x1D4) +#define DI_AUXHFRCO_CALIB_BAND_7 MMIO8(DI_BASE + 0x1D5) +#define DI_AUXHFRCO_CALIB_BAND_11 MMIO8(DI_BASE + 0x1D6) +#define DI_AUXHFRCO_CALIB_BAND_14 MMIO8(DI_BASE + 0x1D7) +#define DI_AUXHFRCO_CALIB_BAND_21 MMIO8(DI_BASE + 0x1D8) +#define DI_AUXHFRCO_CALIB_BAND_28 MMIO8(DI_BASE + 0x1D9) +#define DI_HFRCO_CALIB_BAND_1 MMIO8(DI_BASE + 0x1DC) +#define DI_HFRCO_CALIB_BAND_7 MMIO8(DI_BASE + 0x1DD) +#define DI_HFRCO_CALIB_BAND_11 MMIO8(DI_BASE + 0x1DE) +#define DI_HFRCO_CALIB_BAND_14 MMIO8(DI_BASE + 0x1DF) +#define DI_HFRCO_CALIB_BAND_21 MMIO8(DI_BASE + 0x1E0) +#define DI_HFRCO_CALIB_BAND_28 MMIO8(DI_BASE + 0x1E1) +#define DI_MEM_INFO_PAGE_SIZE MMIO8(DI_BASE + 0x1E7) +#define DI_UNIQUE_0 MMIO32(DI_BASE + 0x1F0) +#define DI_UNIQUE_1 MMIO32(DI_BASE + 0x1F4) +#define DI_MEM_INFO_FLASH MMIO16(DI_BASE + 0x1F8) +#define DI_MEM_INFO_RAM MMIO16(DI_BASE + 0x1FA) +#define DI_PART_NUMBER MMIO16(DI_BASE + 0x1FC) +#define DI_PART_FAMILY MMIO8(DI_BASE + 0x1FE) +#define DI_PROD_REV MMIO8(DI_BASE + 0x1FF) + +#define AES_BASE (PERIPH_BASE + 0xE0000) +#define PRS_BASE (PERIPH_BASE + 0xCC000) +#define RMU_BASE (PERIPH_BASE + 0xCA000) +#define CMU_BASE (PERIPH_BASE + 0xC8000) +#define EMU_BASE (PERIPH_BASE + 0xC6000) +#define USB_BASE (PERIPH_BASE + 0xC4000) +#define DMA_BASE (PERIPH_BASE + 0xC2000) +#define MSC_BASE (PERIPH_BASE + 0xC0000) +#define LESENSE_BASE (PERIPH_BASE + 0x8C000) +#define LCD_BASE (PERIPH_BASE + 0x8A000) +#define WDOG_BASE (PERIPH_BASE + 0x88000) +#define PCNT2_BASE (PERIPH_BASE + 0x86800) +#define PCNT1_BASE (PERIPH_BASE + 0x86400) +#define PCNT0_BASE (PERIPH_BASE + 0x86000) +#define LEUART1_BASE (PERIPH_BASE + 0x84400) +#define LEUART0_BASE (PERIPH_BASE + 0x84000) +#define LETIMER0_BASE (PERIPH_BASE + 0x82000) +#define BURTC_BASE (PERIPH_BASE + 0x81000) +#define RTC_BASE (PERIPH_BASE + 0x80000) +#define TIMER3_BASE (PERIPH_BASE + 0x10C00) +#define TIMER2_BASE (PERIPH_BASE + 0x10800) +#define TIMER1_BASE (PERIPH_BASE + 0x10400) +#define TIMER0_BASE (PERIPH_BASE + 0x10000) +#define UART1_BASE (PERIPH_BASE + 0x0E400) +#define UART0_BASE (PERIPH_BASE + 0x0E000) +#define USART2_BASE (PERIPH_BASE + 0x0C800) +#define USART1_BASE (PERIPH_BASE + 0x0C400) +#define USART0_BASE (PERIPH_BASE + 0x0C000) +#define I2C1_BASE (PERIPH_BASE + 0x0A400) +#define I2C0_BASE (PERIPH_BASE + 0x0A000) +#define EBI_BASE (PERIPH_BASE + 0x08000) +#define GPIO_BASE (PERIPH_BASE + 0x06000) +#define DAC0_BASE (PERIPH_BASE + 0x04000) +#define ADC0_BASE (PERIPH_BASE + 0x02000) +#define ACMP1_BASE (PERIPH_BASE + 0x01400) +#define ACMP0_BASE (PERIPH_BASE + 0x01000) +#define VCMP_BASE (PERIPH_BASE + 0x00000) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/msc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/msc.h new file mode 100644 index 00000000..168be572 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/msc.h @@ -0,0 +1,154 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_MSC_H +#define LIBOPENCM3_EFM32_MSC_H + +#include +#include + +#define MSC_CTRL MMIO32(MSC_BASE + 0x000) +#define MSC_READCTRL MMIO32(MSC_BASE + 0x004) +#define MSC_WRITECTRL MMIO32(MSC_BASE + 0x008) +#define MSC_WRITECMD MMIO32(MSC_BASE + 0x00C) +#define MSC_ADDRB MMIO32(MSC_BASE + 0x010) +#define MSC_WDATA MMIO32(MSC_BASE + 0x018) +#define MSC_STATUS MMIO32(MSC_BASE + 0x01C) +#define MSC_IF MMIO32(MSC_BASE + 0x02C) +#define MSC_IFS MMIO32(MSC_BASE + 0x030) +#define MSC_IFC MMIO32(MSC_BASE + 0x034) +#define MSC_IEN MMIO32(MSC_BASE + 0x038) +#define MSC_LOCK MMIO32(MSC_BASE + 0x03C) +#define MSC_CMD MMIO32(MSC_BASE + 0x040) +#define MSC_CACHEHITS MMIO32(MSC_BASE + 0x044) +#define MSC_CACHEMISSES MMIO32(MSC_BASE + 0x048) +#define MSC_TIMEBASE MMIO32(MSC_BASE + 0x050) +#define MSC_MASSLOCK MMIO32(MSC_BASE + 0x054) + +/* MSC_CTRL */ +#define MSC_CTRL_BUSFAULT (1 << 0) + +/* MSC_READCTRL */ +#define MSC_READCTRL_BUSSTRATEGY_SHIFT (16) +#define MSC_READCTRL_BUSSTRATEGY_MASK \ + (0x3 << MSC_READCTRL_BUSSTRATEGY_SHIFT) +#define MSC_READCTRL_BUSSTRATEGY(v) \ + (((v) << MSC_READCTRL_BUSSTRATEGY_SHIFT) & \ + MSC_READCTRL_BUSSTRATEGY_MASK) + +#define MSC_READCTRL_BUSSTRATEGY_CPU MSC_READCTRL_BUSSTRATEGY(0) +#define MSC_READCTRL_BUSSTRATEGY_DMA MSC_READCTRL_BUSSTRATEGY(1) +#define MSC_READCTRL_BUSSTRATEGY_DMAEM1 MSC_READCTRL_BUSSTRATEGY(2) +#define MSC_READCTRL_BUSSTRATEGY_NONE MSC_READCTRL_BUSSTRATEGY(3) + +#define MSC_READCTRL_RAMCEN (1 << 7) +#define MSC_READCTRL_EBICDIS (1 << 6) +#define MSC_READCTRL_ICCDIS (1 << 5) +#define MSC_READCTRL_AIDIS (1 << 4) +#define MSC_READCTRL_IFCDIS (1 << 3) + +#define MSC_READCTRL_MODE_SHIFT (0) +#define MSC_READCTRL_MODE_MASK (0x7 << MSC_READCTRL_MODE_SHIFT) +#define MSC_READCTRL_MODE(v) \ + (((v) << MSC_READCTRL_MODE_SHIFT) & MSC_READCTRL_MODE_MASK) +#define MSC_READCTRL_MODE_WS0 MSC_READCTRL_MODE(0) +#define MSC_READCTRL_MODE_WS1 MSC_READCTRL_MODE(1) +#define MSC_READCTRL_MODE_WS0SCBTP MSC_READCTRL_MODE(2) +#define MSC_READCTRL_MODE_WS1SCBTP MSC_READCTRL_MODE(3) +#define MSC_READCTRL_MODE_WS2 MSC_READCTRL_MODE(4) +#define MSC_READCTRL_MODE_WS2SCBTP MSC_READCTRL_MODE(5) + +/* MSC_WRITECTRL */ +#define MSC_WRITECTRL_IRQERASEABORT (1 << 1) +#define MSC_WRITECTRL_WREN (1 << 0) + +/* MSC_WRITECMD */ +#define MSC_WRITECMD_CLEARWDATA (1 << 12) +#define MSC_WRITECMD_ERASEMAIN0 (1 << 8) +#define MSC_WRITECMD_ERASEABORT (1 << 5) +#define MSC_WRITECMD_WRITETRIG (1 << 4) +#define MSC_WRITECMD_WRITEONCE (1 << 3) +#define MSC_WRITECMD_WRITEEND (1 << 2) +#define MSC_WRITECMD_ERASEPAGE (1 << 1) +#define MSC_WRITECMD_LADDRIM (1 << 0) + +/* MSC_STATUS */ +#define MSC_STATUS_PCRUNNING (1 << 6) +#define MSC_STATUS_ERASEABORTED (1 << 5) +#define MSC_STATUS_WORDTIMEOUT (1 << 4) +#define MSC_STATUS_WDATAREADY (1 << 3) +#define MSC_STATUS_INVADDR (1 << 2) +#define MSC_STATUS_LOCKED (1 << 1) +#define MSC_STATUS_BUSY (1 << 0) + +/* MSC_IF */ +#define MSC_IF_CMOF (1 << 3) +#define MSC_IF_CHOF (1 << 2) +#define MSC_IF_WRITE (1 << 1) +#define MSC_IF_ERASE (1 << 0) + +/* MSC_IFS */ +#define MSC_IFS_CMOF (1 << 3) +#define MSC_IFS_CHOF (1 << 2) +#define MSC_IFS_WRITE (1 << 1) +#define MSC_IFS_ERASE (1 << 0) + +/* MSC_IFC */ +#define MSC_IFC_CMOF (1 << 3) +#define MSC_IFC_CHOF (1 << 2) +#define MSC_IFC_WRITE (1 << 1) +#define MSC_IFC_ERASE (1 << 0) + +/* MSC_*IEN */ +#define MSC_IEN_CMOF (1 << 3) +#define MSC_IEN_CHOF (1 << 2) +#define MSC_IEN_WRITE (1 << 1) +#define MSC_IEN_ERASE (1 << 0) + +/* MSC_LOCK */ +#define MSC_LOCK_LOCKKEY_SHIFT (0) +#define MSC_LOCK_LOCKKEY(v) ((v) << MSC_LOCK_LOCKKEY_SHIFT) +#define MSC_LOCK_LOCKKEY_UNLOCKED MSC_LOCK_LOCKKEY(0) +#define MSC_LOCK_LOCKKEY_LOCKED MSC_LOCK_LOCKKEY(1) +#define MSC_LOCK_LOCKKEY_LOCK MSC_LOCK_LOCKKEY(0) +#define MSC_LOCK_LOCKKEY_UNLOCK MSC_LOCK_LOCKKEY(0x1B71) + +/* MSC_CMD */ +#define MSC_CMD_STOPPC (1 << 2) +#define MSC_CMD_STARTPC (1 << 1) +#define MSC_CMD_INVCACHE (1 << 0) + +/* MSC_TIMEBASE */ +#define MSC_TIMEBASE_PERIOD (1 << 16) + +#define MSC_TIMEBASE_BASE_SHIFT (0) +#define MSC_TIMEBASE_BASE_MASK (0x3F << MSC_TIMEBASE_BASE_SHIFT) +#define MSC_TIMEBASE_BASE(v) \ + (((v) << MSC_TIMEBASE_BASE_SHIFT) & MSC_TIMEBASE_BASE_MASK) + +/* MSC_MASSLOCK */ +#define MSC_MASSLOCK_LOCKKEY_SHIFT (0) +#define MSC_MASSLOCK_LOCKKEY(v) ((v) << MSC_MASSLOCK_LOCKKEY_SHIFT) +#define MSC_MASSLOCK_LOCKKEY_UNLOCKED MSC_MASSLOCK_LOCKKEY(0) +#define MSC_MASSLOCK_LOCKKEY_LOCKED MSC_MASSLOCK_LOCKKEY(1) +#define MSC_MASSLOCK_LOCKKEY_LOCK MSC_MASSLOCK_LOCKKEY(0) +#define MSC_MASSLOCK_LOCKKEY_UNLOCK MSC_MASSLOCK_LOCKKEY(0x631A) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/opamp.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/opamp.h new file mode 100644 index 00000000..29829098 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/opamp.h @@ -0,0 +1,21 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* OpAmp register are in dac.h */ +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/prs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/prs.h new file mode 100644 index 00000000..d5560ba0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/prs.h @@ -0,0 +1,363 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_PRS_H +#define LIBOPENCM3_EFM32_PRS_H + +#include +#include + +#define PRS_SWPULSE MMIO32(PRS_BASE + 0x000) +#define PRS_SWLEVEL MMIO32(PRS_BASE + 0x004) +#define PRS_ROUTE MMIO32(PRS_BASE + 0x008) +#define PRS_CHx_CTRL(x) MMIO32(PRS_BASE + 0x010 + (0x004 * (x))) +#define PRS_CH0_CTRL PRS_CHx_CTRL(0) +#define PRS_CH1_CTRL PRS_CHx_CTRL(1) +#define PRS_CH2_CTRL PRS_CHx_CTRL(2) +#define PRS_CH3_CTRL PRS_CHx_CTRL(3) +#define PRS_CH4_CTRL PRS_CHx_CTRL(4) +#define PRS_CH5_CTRL PRS_CHx_CTRL(5) +#define PRS_CH6_CTRL PRS_CHx_CTRL(6) +#define PRS_CH7_CTRL PRS_CHx_CTRL(71) +#define PRS_CH8_CTRL PRS_CHx_CTRL(8) +#define PRS_CH9_CTRL PRS_CHx_CTRL(9) +#define PRS_CH10_CTRL PRS_CHx_CTRL(10) +#define PRS_CH11_CTRL PRS_CHx_CTRL(11) + +/* PRS_SWPULSE */ +#define PRS_SWPULSE_CHxPULSE(x) (1 << (x)) +#define PRS_SWPULSE_CH0PULSE PRS_SWPULSE_CHxPULSE(0) +#define PRS_SWPULSE_CH1PULSE PRS_SWPULSE_CHxPULSE(1) +#define PRS_SWPULSE_CH2PULSE PRS_SWPULSE_CHxPULSE(2) +#define PRS_SWPULSE_CH3PULSE PRS_SWPULSE_CHxPULSE(3) +#define PRS_SWPULSE_CH4PULSE PRS_SWPULSE_CHxPULSE(4) +#define PRS_SWPULSE_CH5PULSE PRS_SWPULSE_CHxPULSE(5) +#define PRS_SWPULSE_CH6PULSE PRS_SWPULSE_CHxPULSE(6) +#define PRS_SWPULSE_CH7PULSE PRS_SWPULSE_CHxPULSE(7) +#define PRS_SWPULSE_CH8PULSE PRS_SWPULSE_CHxPULSE(8) +#define PRS_SWPULSE_CH9PULSE PRS_SWPULSE_CHxPULSE(9) +#define PRS_SWPULSE_CH10PULSE PRS_SWPULSE_CHxPULSE(10) +#define PRS_SWPULSE_CH11PULSE PRS_SWPULSE_CHxPULSE(11) + +/* PRS_SWLEVEL */ +#define PRS_SWLEVEL_CHxLEVEL(x) (1 << (x)) +#define PRS_SWLEVEL_CH0LEVEL PRS_SWLEVEL_CHxLEVEL(0) +#define PRS_SWLEVEL_CH1LEVEL PRS_SWLEVEL_CHxLEVEL(1) +#define PRS_SWLEVEL_CH2LEVEL PRS_SWLEVEL_CHxLEVEL(2) +#define PRS_SWLEVEL_CH3LEVEL PRS_SWLEVEL_CHxLEVEL(3) +#define PRS_SWLEVEL_CH4LEVEL PRS_SWLEVEL_CHxLEVEL(4) +#define PRS_SWLEVEL_CH5LEVEL PRS_SWLEVEL_CHxLEVEL(5) +#define PRS_SWLEVEL_CH6LEVEL PRS_SWLEVEL_CHxLEVEL(6) +#define PRS_SWLEVEL_CH7LEVEL PRS_SWLEVEL_CHxLEVEL(7) +#define PRS_SWLEVEL_CH8LEVEL PRS_SWLEVEL_CHxLEVEL(8) +#define PRS_SWLEVEL_CH9LEVEL PRS_SWLEVEL_CHxLEVEL(9) +#define PRS_SWLEVEL_CH10LEVEL PRS_SWLEVEL_CHxLEVEL(10) +#define PRS_SWLEVEL_CH11LEVEL PRS_SWLEVEL_CHxLEVEL(11) + +/* PRS_ROUTE */ +#define PRS_ROUTE_LOCATION_SHIFT (8) +#define PRS_ROUTE_LOCATION_MASK (0x7 << PRS_ROUTE_LOCATION_SHIFT) +#define PRS_ROUTE_LOCATION(v) \ + (((v) << PRS_ROUTE_LOCATION_SHIFT) & PRS_ROUTE_LOCATION_MASK) +#define PRS_ROUTE_LOCATION_LOCx(x) PRS_ROUTE_LOCATION(x) +#define PRS_ROUTE_LOCATION_LOC0 PRS_ROUTE_LOCATION_LOCx(0) +#define PRS_ROUTE_LOCATION_LOC1 PRS_ROUTE_LOCATION_LOCx(1) + +#define PRS_ROUTE_CHxPEN(x) (1 << (x)) +#define PRS_ROUTE_CH3PEN PRS_ROUTE_CHxPEN(3) +#define PRS_ROUTE_CH2PEN PRS_ROUTE_CHxPEN(2) +#define PRS_ROUTE_CH1PEN PRS_ROUTE_CHxPEN(1) +#define PRS_ROUTE_CH0PEN PRS_ROUTE_CHxPEN(0) + +/* PRS_CHx_CTRL */ +#define PRS_CH_CTRL_ASYNC (1 << 28) + +#define PRS_CH_CTRL_EDSEL_SHIFT (24) +#define PRS_CH_CTRL_EDSEL_MASK (0x3 << PRS_CH_CTRL_EDSEL_SHIFT) +#define PRS_CH_CTRL_EDSEL_OFF (0 << PRS_CH_CTRL_EDSEL_SHIFT) +#define PRS_CH_CTRL_EDSEL_POSEDGE (1 << PRS_CH_CTRL_EDSEL_SHIFT) +#define PRS_CH_CTRL_EDSEL_NEGEDGE (2 << PRS_CH_CTRL_EDSEL_SHIFT) +#define PRS_CH_CTRL_EDSEL_BOTHEDGES (3 << PRS_CH_CTRL_EDSEL_SHIFT) + +#define PRS_CH_CTRL_SOURCESEL_SHIFT (16) +#define PRS_CH_CTRL_SOURCESEL_MASK (0x3F << PRS_CH_CTRL_SOURCESEL_SHIFT) +#define PRS_CH_CTRL_SOURCESEL(v) \ + (((v) << PRS_CH_CTRL_SOURCESEL_SHIFT) & PRS_CH_CTRL_SOURCESEL_MASK) +#define PRS_CH_CTRL_SOURCESEL_NONE PRS_CH_CTRL_SOURCESEL(0b000000) +#define PRS_CH_CTRL_SOURCESEL_VCMP PRS_CH_CTRL_SOURCESEL(0b000001) +#define PRS_CH_CTRL_SOURCESEL_ACMP0 PRS_CH_CTRL_SOURCESEL(0b000010) +#define PRS_CH_CTRL_SOURCESEL_ACMP1 PRS_CH_CTRL_SOURCESEL(0b000011) +#define PRS_CH_CTRL_SOURCESEL_DAC0 PRS_CH_CTRL_SOURCESEL(0b000110) +#define PRS_CH_CTRL_SOURCESEL_ADC0 PRS_CH_CTRL_SOURCESEL(0b001000) +#define PRS_CH_CTRL_SOURCESEL_USART0 PRS_CH_CTRL_SOURCESEL(0b010000) +#define PRS_CH_CTRL_SOURCESEL_USART1 PRS_CH_CTRL_SOURCESEL(0b010001) +#define PRS_CH_CTRL_SOURCESEL_USART2 PRS_CH_CTRL_SOURCESEL(0b010010) +#define PRS_CH_CTRL_SOURCESEL_TIMER0 PRS_CH_CTRL_SOURCESEL(0b011100) +#define PRS_CH_CTRL_SOURCESEL_TIMER1 PRS_CH_CTRL_SOURCESEL(0b011101) +#define PRS_CH_CTRL_SOURCESEL_TIMER2 PRS_CH_CTRL_SOURCESEL(0b011110) +#define PRS_CH_CTRL_SOURCESEL_TIMER3 PRS_CH_CTRL_SOURCESEL(0b011111) +#define PRS_CH_CTRL_SOURCESEL_USB PRS_CH_CTRL_SOURCESEL(0b100100) +#define PRS_CH_CTRL_SOURCESEL_RTC PRS_CH_CTRL_SOURCESEL(0b101000) +#define PRS_CH_CTRL_SOURCESEL_UART0 PRS_CH_CTRL_SOURCESEL(0b101001) +#define PRS_CH_CTRL_SOURCESEL_UART1 PRS_CH_CTRL_SOURCESEL(0b101010) +#define PRS_CH_CTRL_SOURCESEL_GPIOL PRS_CH_CTRL_SOURCESEL(0b110000) +#define PRS_CH_CTRL_SOURCESEL_GPIOH PRS_CH_CTRL_SOURCESEL(0b110001) +#define PRS_CH_CTRL_SOURCESEL_LETIMER0 PRS_CH_CTRL_SOURCESEL(0b110100) +#define PRS_CH_CTRL_SOURCESEL_BURTC PRS_CH_CTRL_SOURCESEL(0b110111) +#define PRS_CH_CTRL_SOURCESEL_LESENSEL PRS_CH_CTRL_SOURCESEL(0b111001) +#define PRS_CH_CTRL_SOURCESEL_LESENSEH PRS_CH_CTRL_SOURCESEL(0b111010) +#define PRS_CH_CTRL_SOURCESEL_LESENSED PRS_CH_CTRL_SOURCESEL(0b111011) + +#define PRS_CH_CTRL_SIGSEL_SHIFT (0) +#define PRS_CH_CTRL_SIGSEL_MASK (0x7 << PRS_CH_CTRL_SIGSEL_SHIFT) +#define PRS_CH_CTRL_SIGSEL(v) \ + (((v) << PRS_CH_CTRL_SIGSEL_SHIFT) & PRS_CH_CTRL_SIGSEL_MASK) +#define PRS_CH_CTRL_SIGSEL_OFF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_VCMPOUT PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_ACMP0OUT PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_ACMP1OUT PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_DAC0CH0 PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_DAC0CH1 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_ADCSINGLE PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_ADCSCAN PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_USART0IRTX PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_USART0TXC PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_USART0RXDATA PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_USART1TXC PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_USART1RXDATAV PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_USART2TXC PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_USART2RXDATAV PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_TIMER0UF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_TIMER0OF PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_TIMER0CC0 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_TIMER0CC1 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_TIMER0CC2 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_TIMER1UF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_TIMER1OF PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_TIMER1CC0 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_TIMER1CC1 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_TIMER1CC2 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_TIMER2UF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_TIMER2OF PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_TIMER2CC0 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_TIMER2CC1 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_TIMER2CC2 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_TIMER3UF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_TIMER3OF PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_TIMER3CC0 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_TIMER3CC1 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_TIMER3CC2 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_USBSOF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_USBSOFSR PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_RTCOF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_RTCCOMP0 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_RTCCOMP1 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_UART0TXC PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_UART0RXDATAV PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_UART1TXC PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_UART1RXDATAV PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN0 PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN1 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN2 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN3 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN4 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN5 PRS_CH_CTRL_SIGSEL(5) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN6 PRS_CH_CTRL_SIGSEL(6) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN7 PRS_CH_CTRL_SIGSEL(7) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN8 PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN9 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN10 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN11 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN12 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN13 PRS_CH_CTRL_SIGSEL(5) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN14 PRS_CH_CTRL_SIGSEL(6) +#define PRS_CH_CTRL_SIGSEL_GPIOPIN15 PRS_CH_CTRL_SIGSEL(7) +#define PRS_CH_CTRL_SIGSEL_LETIMER0CH0 PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_LETIMER0CH1 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_BURTCOF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_BURTCCOMP0 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES0 PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES1 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES2 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES3 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES4 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES5 PRS_CH_CTRL_SIGSEL(5) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES6 PRS_CH_CTRL_SIGSEL(6) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES7 PRS_CH_CTRL_SIGSEL(7) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES8 PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES9 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES10 PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES11 PRS_CH_CTRL_SIGSEL(3) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES12 PRS_CH_CTRL_SIGSEL(4) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES13 PRS_CH_CTRL_SIGSEL(5) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES14 PRS_CH_CTRL_SIGSEL(6) +#define PRS_CH_CTRL_SIGSEL_LESENSESCANRES15 PRS_CH_CTRL_SIGSEL(7) +#define PRS_CH_CTRL_SIGSEL_LESENSEDEC0 PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_LESENSEDEC1 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_LESENSEDEC2 PRS_CH_CTRL_SIGSEL(2) + +/* generic of above */ +#define PRS_CH_CTRL_SIGSEL_VCMP_OUT PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_ACMP_OUT PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_DAC_CHx(x) PRS_CH_CTRL_SIGSEL(x) +#define PRS_CH_CTRL_SIGSEL_DAC_CH0 PRS_CH_CTRL_SIGSEL_DAC_CHx(0) +#define PRS_CH_CTRL_SIGSEL_DAC_CH1 PRS_CH_CTRL_SIGSEL_DAC_CHx(1) +#define PRS_CH_CTRL_SIGSEL_ADC_SINGLE PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_ADC_SCAN PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_USART_IRTX PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_USART_TXC PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_USART_RXDATAV PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_TIMER_UF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_TIMER_OF PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_TIMER_CCx(x) PRS_CH_CTRL_SIGSEL((x) + 2) +#define PRS_CH_CTRL_SIGSEL_TIMER_CC0 PRS_CH_CTRL_SIGSEL_TIMER_CCx(0) +#define PRS_CH_CTRL_SIGSEL_TIMER_CC1 PRS_CH_CTRL_SIGSEL_TIMER_CCx(1) +#define PRS_CH_CTRL_SIGSEL_TIMER_CC2 PRS_CH_CTRL_SIGSEL_TIMER_CCx(2) +#define PRS_CH_CTRL_SIGSEL_USB_SOF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_USB_SOFSR PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_RTC_OF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_RTC_COMPx(x) PRS_CH_CTRL_SIGSEL((x) + 1) +#define PRS_CH_CTRL_SIGSEL_RTC_COMP0 PRS_CH_CTRL_SIGSEL_RTC_COMPx(0) +#define PRS_CH_CTRL_SIGSEL_RTC_COMP1 PRS_CH_CTRL_SIGSEL_RTC_COMPx(1) +#define PRS_CH_CTRL_SIGSEL_UART_TXC PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_UART_RXDATAV PRS_CH_CTRL_SIGSEL(2) +#define PRS_CH_CTRL_SIGSEL_GPIOL_PINx(x) PRS_CH_CTRL_SIGSEL(x) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN0 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(0) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN1 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(1) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN2 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(2) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN3 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(3) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN4 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(4) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN5 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(5) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN6 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(6) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN7 \ + PRS_CH_CTRL_SIGSEL_GPIOL_PINx(7) +#define PRS_CH_CTRL_SIGSEL_GPIOH_PINx(x) PRS_CH_CTRL_SIGSEL((x) - 8) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN8 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(8) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN9 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(9) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN10 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(10) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN11 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(11) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN12 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(12) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN13 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(13) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN14 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(14) +#define PRS_CH_CTRL_SIGSEL_GPIO_PIN15 \ + PRS_CH_CTRL_SIGSEL_GPIOH_PINx(15) +#define PRS_CH_CTRL_SIGSEL_LETIMER_CHx(x) PRS_CH_CTRL_SIGSEL(x) +#define PRS_CH_CTRL_SIGSEL_LETIMER_CH0 \ + PRS_CH_CTRL_SIGSEL_LETIMER_CHx(0) +#define PRS_CH_CTRL_SIGSEL_LETIMER_CH1 \ + PRS_CH_CTRL_SIGSEL_LETIMER_CHx(1) +#define PRS_CH_CTRL_SIGSEL_BURTC_OF PRS_CH_CTRL_SIGSEL(0) +#define PRS_CH_CTRL_SIGSEL_BURTC_COMP0 PRS_CH_CTRL_SIGSEL(1) +#define PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(x) PRS_CH_CTRL_SIGSEL(x) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES0 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(0) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES1 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(1) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES2 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(2) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES3 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(3) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES4 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(4) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES5 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(5) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES6 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(6) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES7 \ + PRS_CH_CTRL_SIGSEL_LESENSEL_SCANRESx(7) +#define PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(x) \ + PRS_CH_CTRL_SIGSEL((x) - 8) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES8 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(8) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES9 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(9) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES10 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(10) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES11 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(11) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES12 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(12) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES13 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(13) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES14 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(14) +#define PRS_CH_CTRL_SIGSEL_LESENSE_SCANRES15 \ + PRS_CH_CTRL_SIGSEL_LESENSEH_SCANRESx(15) +#define PRS_CH_CTRL_SIGSEL_LESENSED_DECx(x) PRS_CH_CTRL_SIGSEL(x) +#define PRS_CH_CTRL_SIGSEL_LESENSE_DEC0 \ + PRS_CH_CTRL_SIGSEL_LESENSED_DECx(0) +#define PRS_CH_CTRL_SIGSEL_LESENSE_DEC1 \ + PRS_CH_CTRL_SIGSEL_LESENSED_DECx(1) +#define PRS_CH_CTRL_SIGSEL_LESENSE_DEC2 \ + PRS_CH_CTRL_SIGSEL_LESENSED_DECx(2) + +/** @defgroup prs_ch PRS Channel Number +@ingroup prs_defines + +@{*/ +enum prs_ch { + PRS_CH0 = 0, + PRS_CH1, + PRS_CH2, + PRS_CH3, + PRS_CH4, + PRS_CH5, + PRS_CH6, + PRS_CH7, + PRS_CH8, + PRS_CH9, + PRS_CH10, + PRS_CH11 +}; +/**@}*/ + +BEGIN_DECLS + +void prs_enable_gpio_output(enum prs_ch ch); +void prs_disable_gpio_output(enum prs_ch ch); +void prs_set_output_loc(uint32_t loc); + +void prs_software_pulse(enum prs_ch ch); +void prs_software_level_high(enum prs_ch ch); +void prs_software_level_low(enum prs_ch ch); + +void prs_enable_async(enum prs_ch ch); +void prs_disable_async(enum prs_ch ch); +void prs_set_edge(enum prs_ch ch, uint32_t edge); +void prs_set_source(enum prs_ch ch, uint32_t source); +void prs_set_signal(enum prs_ch ch, uint32_t sig); + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rmu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rmu.h new file mode 100644 index 00000000..4a7e721a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rmu.h @@ -0,0 +1,56 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_RMU_H +#define LIBOPENCM3_EFM32_RMU_H + +#include +#include + +#define RMU_CTRL MMIO32(RMU_BASE + 0x00) +#define RMU_RSTCAUSE MMIO32(RMU_BASE + 0x04) +#define RMU_CMD MMIO32(RMU_BASE + 0x08) + +/* RMU_CTRL */ +#define RMU_CTRL_BURSTEN (1 << 1) +#define RMU_CTRL_LOCKUPRDIS (1 << 0) + +/* RMU_RSTCAUSE */ +#define RMU_RSTCAUSE_BUMODERST (1 << 15) +#define RMU_RSTCAUSE_BUBODREG (1 << 14) +#define RMU_RSTCAUSE_BUBODUNREG (1 << 13) +#define RMU_RSTCAUSE_BUBODBUVIN (1 << 12) +#define RMU_RSTCAUSE_BUBODVDDDREG (1 << 11) +#define RMU_RSTCAUSE_BODAVDD1 (1 << 10) +#define RMU_RSTCAUSE_BODAVDD0 (1 << 9) +#define RMU_RSTCAUSE_EM4WURST (1 << 8) +#define RMU_RSTCAUSE_EM4RST (1 << 7) +#define RMU_RSTCAUSE_SYSREQRST (1 << 6) +#define RMU_RSTCAUSE_LOCKUPRST (1 << 5) +#define RMU_RSTCAUSE_WDOGRST (1 << 4) +#define RMU_RSTCAUSE_EXTRST (1 << 3) +#define RMU_RSTCAUSE_BODREGRST (1 << 2) +#define RMU_RSTCAUSE_BODUNREGRST (1 << 1) +#define RMU_RSTCAUSE_PORST (1 << 0) + +/* RMU_CMD */ +#define RMU_CMD_RCCLR (1 << 0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rtc.h new file mode 100644 index 00000000..ad50bcbd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/rtc.h @@ -0,0 +1,71 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_RTC_H +#define LIBOPENCM3_EFM32_RTC_H + +#include +#include + +#define RTC_CTRL (RTC_BASE + 0x000) +#define RTC_CNT (RTC_BASE + 0x004) +#define RTC_COMP0 (RTC_BASE + 0x008) +#define RTC_COMP1 (RTC_BASE + 0x00C) +#define RTC_IF (RTC_BASE + 0x010) +#define RTC_IFS (RTC_BASE + 0x014) +#define RTC_IFC (RTC_BASE + 0x018) +#define RTC_IEN (RTC_BASE + 0x01C) +#define RTC_FREEZE (RTC_BASE + 0x020) +#define RTC_SYNCBUSY (RTC_BASE + 0x024) + +/* RTC_CTRL */ +#define RTC_CTRL_COMP0TOP (1 << 2) +#define RTC_CTRL_DEBUGRUN (1 << 1) +#define RTC_CTRL_EN (1 << 0) + +/* RTC_IF */ +#define RTC_IF_COMP1 (1 << 2) +#define RTC_IF_COMP0 (1 << 1) +#define RTC_IF_OF (1 << 0) + +/* RTC_IFS */ +#define RTC_IFS_COMP1 (1 << 2) +#define RTC_IFS_COMP0 (1 << 1) +#define RTC_IFS_OF (1 << 0) + +/* RTC_IFC */ +#define RTC_IFC_COMP1 (1 << 2) +#define RTC_IFC_COMP0 (1 << 1) +#define RTC_IFC_OF (1 << 0) + +/* RTC_IFE */ +#define RTC_IFE_COMP1 (1 << 2) +#define RTC_IFE_COMP0 (1 << 1) +#define RTC_IFE_OF (1 << 0) + +/* RTC_FREEZE */ +#define RTC_FREEZE_REGFREEZE (1 << 0) + +/* RTC_SYNCBUSY */ +#define RTC_SYNCBUSY_COMP1 (1 << 2) +#define RTC_SYNCBUSY_COMP0 (1 << 1) +#define RTC_SYNCBUSY_CTRL (1 << 0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/timer.h new file mode 100644 index 00000000..cad50d4e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/timer.h @@ -0,0 +1,610 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_TIMER_H +#define LIBOPENCM3_EFM32_TIMER_H + +#include +#include + +#define TIMER_CTRL(base) MMIO32((base) + 0x000) +#define TIMER_CMD(base) MMIO32((base) + 0x004) +#define TIMER_STATUS(base) MMIO32((base) + 0x008) +#define TIMER_IEN(base) MMIO32((base) + 0x00C) +#define TIMER_IF(base) MMIO32((base) + 0x010) +#define TIMER_IFS(base) MMIO32((base) + 0x014) +#define TIMER_IFC(base) MMIO32((base) + 0x018) +#define TIMER_TOP(base) MMIO32((base) + 0x01C) +#define TIMER_TOPB(base) MMIO32((base) + 0x020) +#define TIMER_CNT(base) MMIO32((base) + 0x024) +#define TIMER_ROUTE(base) MMIO32((base) + 0x028) + +#define TIMER_CCx_CTRL(base, x) MMIO32((base) + 0x030 + (0x10 * (x))) +#define TIMER_CCx_CCV(base, x) MMIO32((base) + 0x034 + (0x10 * (x))) +#define TIMER_CCx_CCVP(base, x) MMIO32((base) + 0x038 + (0x10 * (x))) +#define TIMER_CCx_CCVB(base, x) MMIO32((base) + 0x03C + (0x10 * (x))) + +#define TIMER_CC0_CTRL(base) TIMER_CCx_CTRL(base, 0) +#define TIMER_CC0_CCV(base) TIMER_CCx_CCV(base, 0) +#define TIMER_CC0_CCVP(base) TIMER_CCx_CCVP(base, 0) +#define TIMER_CC0_CCVB(base) TIMER_CCx_CCVB(base, 0) + +#define TIMER_CC1_CTRL(base) TIMER_CCx_CTRL(base, 1) +#define TIMER_CC1_CCV(base) TIMER_CCx_CCV(base, 1) +#define TIMER_CC1_CCVP(base) TIMER_CCx_CCVP(base, 1) +#define TIMER_CC1_CCVB(base) TIMER_CCx_CCVB(base, 1) + +#define TIMER_CC2_CTRL(base) TIMER_CCx_CTRL(base, 2) +#define TIMER_CC2_CCV(base) TIMER_CCx_CCV(base, 2) +#define TIMER_CC2_CCVP(base) TIMER_CCx_CCVP(base, 2) +#define TIMER_CC2_CCVB(base) TIMER_CCx_CCVB(base, 2) + +#define TIMER_DTCTRL(base) MMIO32((base) + 0x070) +#define TIMER_DTTIME(base) MMIO32((base) + 0x074) +#define TIMER_DTFC(base) MMIO32((base) + 0x078) +#define TIMER_DTOGEN(base) MMIO32((base) + 0x07C) +#define TIMER_DTFAULT(base) MMIO32((base) + 0x080) +#define TIMER_DTFAULTC(base) MMIO32((base) + 0x084) +#define TIMER_DTLOCK(base) MMIO32((base) + 0x088) + +/* TIMER_CTRL */ +#define TIMER_CTRL_RSSCOIST (1 << 29) +#define TIMER_CTRL_ATI (1 << 28) + +#define TIMER_CTRL_PRESC_SHIFT (24) +#define TIMER_CTRL_PRESC_MASK (0xF << TIMER_CTRL_PRESC_SHIFT) +#define TIMER_CTRL_PRESC(v) \ + (((v) << TIMER_CTRL_PRESC_SHIFT) & TIMER_CTRL_PRESC_MASK) +#define TIMER_CTRL_PRESC_DIV1 TIMER_CTRL_PRESC(0) +#define TIMER_CTRL_PRESC_DIV2 TIMER_CTRL_PRESC(1) +#define TIMER_CTRL_PRESC_DIV4 TIMER_CTRL_PRESC(2) +#define TIMER_CTRL_PRESC_DIV8 TIMER_CTRL_PRESC(3) +#define TIMER_CTRL_PRESC_DIV16 TIMER_CTRL_PRESC(4) +#define TIMER_CTRL_PRESC_DIV32 TIMER_CTRL_PRESC(5) +#define TIMER_CTRL_PRESC_DIV64 TIMER_CTRL_PRESC(6) +#define TIMER_CTRL_PRESC_DIV128 TIMER_CTRL_PRESC(7) +#define TIMER_CTRL_PRESC_DIV256 TIMER_CTRL_PRESC(8) +#define TIMER_CTRL_PRESC_DIV512 TIMER_CTRL_PRESC(9) +#define TIMER_CTRL_PRESC_DIV1024 TIMER_CTRL_PRESC(10) +#define TIMER_CTRL_PRESC_NODIV TIMER_CTRL_PRESC_DIV1 + +#define TIMER_CTRL_CLKSEL_SHIFT (16) +#define TIMER_CTRL_CLKSEL_MASK (0x3 << TIMER_CTRL_CLKSEL_SHIFT) +#define TIMER_CTRL_CLKSEL(v) \ + (((v) << TIMER_CTRL_CLKSEL_SHIFT) & TIMER_CTRL_CLKSEL_MASK) +#define TIMER_CTRL_CLKSEL_PRESCHFPERCLK TIMER_CTRL_CLKSEL(0) +#define TIMER_CTRL_CLKSEL_CC1 TIMER_CTRL_CLKSEL(1) +#define TIMER_CTRL_CLKSEL_TIMEROUF TIMER_CTRL_CLKSEL(2) + +#define TIMER_CTRL_X2CNT (1 << 13) + +#define TIMER_CTRL_FALLA_SHIFT (10) +#define TIMER_CTRL_FALLA_MASK (0x3 << TIMER_CTRL_FALLA_SHIFT) +#define TIMER_CTRL_FALLA(v) \ + (((v) << TIMER_CTRL_FALLA_SHIFT) & TIMER_CTRL_FALLA_MASK) +#define TIMER_CTRL_FALLA_NONE TIMER_CTRL_FALLA(0) +#define TIMER_CTRL_FALLA_START TIMER_CTRL_FALLA(1) +#define TIMER_CTRL_FALLA_STOP TIMER_CTRL_FALLA(2) +#define TIMER_CTRL_FALLA_RELOADSTART TIMER_CTRL_FALLA(3) + +#define TIMER_CTRL_RISEA_SHIFT (8) +#define TIMER_CTRL_RISEA_MASK (0x3 << TIMER_CTRL_RISEA_SHIFT) +#define TIMER_CTRL_RISEA(v) \ + (((v) << TIMER_CTRL_RISEA_SHIFT) & TIMER_CTRL_RISEA_MASK) +#define TIMER_CTRL_RISEA_NONE TIMER_CTRL_RISEA(0) +#define TIMER_CTRL_RISEA_START TIMER_CTRL_RISEA(1) +#define TIMER_CTRL_RISEA_STOP TIMER_CTRL_RISEA(2) +#define TIMER_CTRL_RISEA_RELOADSTART TIMER_CTRL_RISEA(3) + +/* TIMER_CTRL_DMACLRACT bit is strangely documented. + * set this bit, + * in case you are doing one DMA transfer on every timer trigger event. + * if this bit is not set, strange behaviour is seen. +*/ + +#define TIMER_CTRL_DMACLRACT (1 << 7) +#define TIMER_CTRL_DEBUGRUN (1 << 6) +#define TIMER_CTRL_QDM (1 << 5) +#define TIMER_CTRL_OSMEN (1 << 4) +#define TIMER_CTRL_SYNC (1 << 3) + +#define TIMER_CTRL_MODE_SHIFT (0) +#define TIMER_CTRL_MODE_MASK (0x3 << TIMER_CTRL_MODE_SHIFT) +#define TIMER_CTRL_MODE(v) \ + (((v) << TIMER_CTRL_MODE_SHIFT) & TIMER_CTRL_MODE_MASK) +#define TIMER_CTRL_MODE_UP TIMER_CTRL_MODE(0) +#define TIMER_CTRL_MODE_DOWN TIMER_CTRL_MODE(1) +#define TIMER_CTRL_MODE_UPDOWN TIMER_CTRL_MODE(2) +#define TIMER_CTRL_MODE_QDEC TIMER_CTRL_MODE(3) + +/* TIMER_CMD */ +#define TIMER_CMD_STOP (1 << 1) +#define TIMER_CMD_START (1 << 0) + +/* TIMER_STATUS */ +#define TIMER_STATUS_CCPOLx(x) (1 << ((x) + 24)) +#define TIMER_STATUS_CCPOL2 TIMER_STATUS_CCPOLx(2) +#define TIMER_STATUS_CCPOL1 TIMER_STATUS_CCPOLx(1) +#define TIMER_STATUS_CCPOL0 TIMER_STATUS_CCPOLx(0) + +#define TIMER_STATUS_ICVx(x) (1 << ((x) + 16)) +#define TIMER_STATUS_ICV2 TIMER_STATUS_ICVx(2) +#define TIMER_STATUS_ICV1 TIMER_STATUS_ICVx(1) +#define TIMER_STATUS_ICV0 TIMER_STATUS_ICVx(0) + +#define TIMER_STATUS_CCVBVx(x) (1 << ((x) + 8)) +#define TIMER_STATUS_CCVBV2 TIMER_STATUS_CCVBVx(2) +#define TIMER_STATUS_CCVBV1 TIMER_STATUS_CCVBVx(1) +#define TIMER_STATUS_CCVBV0 TIMER_STATUS_CCVBVx(0) + +#define TIMER_STATUS_TOPBV (1 << 2) +#define TIMER_STATUS_DIR (1 << 1) +#define TIMER_STATUS_RUNNING (1 << 0) + +/* TIMER_IEN */ +#define TIMER_IEN_ICBOFx(x) (1 << ((x) + 8)) +#define TIMER_IEN_ICBOF0 TIMER_IEN_ICBOFx(0) +#define TIMER_IEN_ICBOF1 TIMER_IEN_ICBOFx(1) +#define TIMER_IEN_ICBOF2 TIMER_IEN_ICBOFx(2) + +#define TIMER_IEN_CCx(x) (1 << ((x) + 4)) +#define TIMER_IEN_CC0 TIMER_IEN_CCx(0) +#define TIMER_IEN_CC1 TIMER_IEN_CCx(1) +#define TIMER_IEN_CC2 TIMER_IEN_CCx(2) + +#define TIMER_IEN_UF (1 << 1) +#define TIMER_IEN_OF (1 << 0) + + +/* TIMER_IF */ +#define TIMER_IF_ICBOFx(x) (1 << ((x) + 8)) +#define TIMER_IF_ICBOF0 TIMER_IF_ICBOFx(0) +#define TIMER_IF_ICBOF1 TIMER_IF_ICBOFx(1) +#define TIMER_IF_ICBOF2 TIMER_IF_ICBOFx(2) + +#define TIMER_IF_CCx(x) (1 << ((x) + 4)) +#define TIMER_IF_CC0 TIMER_IF_CCx(0) +#define TIMER_IF_CC1 TIMER_IF_CCx(1) +#define TIMER_IF_CC2 TIMER_IF_CCx(2) + +#define TIMER_IF_UF (1 << 1) +#define TIMER_IF_OF (1 << 0) + +/* TIMER_IFS */ +#define TIMER_IFS_ICBOFx(x) (1 << ((x) + 8)) +#define TIMER_IFS_ICBOF0 TIMER_IFS_ICBOFx(0) +#define TIMER_IFS_ICBOF1 TIMER_IFS_ICBOFx(1) +#define TIMER_IFS_ICBOF2 TIMER_IFS_ICBOFx(2) + +#define TIMER_IFS_CCx(x) (1 << ((x) + 4)) +#define TIMER_IFS_CC0 TIMER_IFS_CCx(0) +#define TIMER_IFS_CC1 TIMER_IFS_CCx(1) +#define TIMER_IFS_CC2 TIMER_IFS_CCx(2) + +#define TIMER_IFS_UF (1 << 1) +#define TIMER_IFS_OF (1 << 0) + + +/* TIMER_IFC */ +#define TIMER_IFC_ICBOFx(x) (1 << ((x) + 8)) +#define TIMER_IFC_ICBOF0 TIMER_IFC_ICBOFx(0) +#define TIMER_IFC_ICBOF1 TIMER_IFC_ICBOFx(1) +#define TIMER_IFC_ICBOF2 TIMER_IFC_ICBOFx(2) + +#define TIMER_IFC_CCx(x) (1 << ((x) + 4)) +#define TIMER_IFC_CC0 TIMER_IFC_CCx(0) +#define TIMER_IFC_CC1 TIMER_IFC_CCx(1) +#define TIMER_IFC_CC2 TIMER_IFC_CCx(2) + +#define TIMER_IFC_UF (1 << 1) +#define TIMER_IFC_OF (1 << 0) + +/* TIMER_ROUTE */ +#define TIMER_ROUTE_LOCATION_SHIFT (16) +#define TIMER_ROUTE_LOCATION_MASK (0x7 << TIMER_ROUTE_LOCATION_SHIFT) +#define TIMER_ROUTE_LOCATION(v) \ + (((v) << TIMER_ROUTE_LOCATION_SHIFT) & TIMER_ROUTE_LOCATION_MASK) +#define TIMER_ROUTE_LOCATION_LOCx(x) TIMER_ROUTE_LOCATION(x) +#define TIMER_ROUTE_LOCATION_LOC0 TIMER_ROUTE_LOCATION_LOCx(0) +#define TIMER_ROUTE_LOCATION_LOC1 TIMER_ROUTE_LOCATION_LOCx(1) +#define TIMER_ROUTE_LOCATION_LOC2 TIMER_ROUTE_LOCATION_LOCx(2) +#define TIMER_ROUTE_LOCATION_LOC3 TIMER_ROUTE_LOCATION_LOCx(3) +#define TIMER_ROUTE_LOCATION_LOC4 TIMER_ROUTE_LOCATION_LOCx(4) +#define TIMER_ROUTE_LOCATION_LOC5 TIMER_ROUTE_LOCATION_LOCx(5) + +#define TIMER_ROUTE_CDTIxPEN(x) (1 << (8 + (x))) +#define TIMER_ROUTE_CDTI0PEN TIMER_ROUTE_CDTIxPEN(0) +#define TIMER_ROUTE_CDTI1PEN TIMER_ROUTE_CDTIxPEN(1) +#define TIMER_ROUTE_CDTI2PEN TIMER_ROUTE_CDTIxPEN(2) + +#define TIMER_ROUTE_CCxPEN(x) (1 << (0 + (x))) +#define TIMER_ROUTE_CC0PEN TIMER_ROUTE_CCxPEN(0) +#define TIMER_ROUTE_CC1PEN TIMER_ROUTE_CCxPEN(1) +#define TIMER_ROUTE_CC2PEN TIMER_ROUTE_CCxPEN(2) + +/* TIMER_CCx_CTRL */ +#define TIMER_CC_CTRL_ICEVCTRL_SHIFT (26) +#define TIMER_CC_CTRL_ICEVCTRL_MASK (0x3 << TIMER_CC_CTRL_ICEVCTRL_SHIFT) +#define TIMER_CC_CTRL_ICEVCTRL(v) \ + (((v) << TIMER_CC_CTRL_ICEVCTRL_SHIFT) & TIMER_CC_CTRL_ICEVCTRL_MASK) +#define TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE TIMER_CC_CTRL_ICEVCTRL(0) +#define TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE TIMER_CC_CTRL_ICEVCTRL(1) +#define TIMER_CC_CTRL_ICEVCTRL_RISING TIMER_CC_CTRL_ICEVCTRL(2) +#define TIMER_CC_CTRL_ICEVCTRL_FALLING TIMER_CC_CTRL_ICEVCTRL(3) + +#define TIMER_CC_CTRL_ICEVCTRL_EVERY_EDGE \ + TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE +#define TIMER_CC_CTRL_ICEVCTRL_EVERY_SECOND_EDGE \ + TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE + +#define TIMER_CC_CTRL_ICEDGE_SHIFT (24) +#define TIMER_CC_CTRL_ICEDGE_MASK (0x3 << TIMER_CC_CTRL_ICEDGE_SHIFT) +#define TIMER_CC_CTRL_ICEDGE(v) \ + (((v) << TIMER_CC_CTRL_ICEDGE_SHIFT) & TIMER_CC_CTRL_ICEDGE_MASK) +#define TIMER_CC_CTRL_ICEDGE_RISING TIMER_CC_CTRL_ICEDGE(0) +#define TIMER_CC_CTRL_ICEDGE_FALLING TIMER_CC_CTRL_ICEDGE(1) +#define TIMER_CC_CTRL_ICEDGE_BOTH TIMER_CC_CTRL_ICEDGE(2) +#define TIMER_CC_CTRL_ICEDGE_NONE TIMER_CC_CTRL_ICEDGE(3) + +#define TIMER_CC_CTRL_FILT (1 << 21) +#define TIMER_CC_CTRL_INSEL (1 << 21) + + +#define TIMER_CC_CTRL_PRSSEL_SHIFT (16) +#define TIMER_CC_CTRL_PRSSEL_MASK (0xF << TIMER_CC_CTRL_PRSSEL_SHIFT) +#define TIMER_CC_CTRL_PRSSEL(v) \ + (((v) << TIMER_CC_CTRL_PRSSEL_SHIFT) & TIMER_CC_CTRL_PRSSEL_MASK) +#define TIMER_CC_CTRL_PRSSEL_PRSCHx(x) TIMER_CC_CTRL_PRSSEL(x) +#define TIMER_CC_CTRL_PRSSEL_PRSCH0 TIMER_CC_CTRL_PRSSEL_PRSCHx(0) +#define TIMER_CC_CTRL_PRSSEL_PRSCH1 TIMER_CC_CTRL_PRSSEL_PRSCHx(1) +#define TIMER_CC_CTRL_PRSSEL_PRSCH2 TIMER_CC_CTRL_PRSSEL_PRSCHx(2) +#define TIMER_CC_CTRL_PRSSEL_PRSCH3 TIMER_CC_CTRL_PRSSEL_PRSCHx(3) +#define TIMER_CC_CTRL_PRSSEL_PRSCH4 TIMER_CC_CTRL_PRSSEL_PRSCHx(4) +#define TIMER_CC_CTRL_PRSSEL_PRSCH5 TIMER_CC_CTRL_PRSSEL_PRSCHx(5) +#define TIMER_CC_CTRL_PRSSEL_PRSCH6 TIMER_CC_CTRL_PRSSEL_PRSCHx(6) +#define TIMER_CC_CTRL_PRSSEL_PRSCH7 TIMER_CC_CTRL_PRSSEL_PRSCHx(7) +#define TIMER_CC_CTRL_PRSSEL_PRSCH8 TIMER_CC_CTRL_PRSSEL_PRSCHx(8) +#define TIMER_CC_CTRL_PRSSEL_PRSCH9 TIMER_CC_CTRL_PRSSEL_PRSCHx(9) +#define TIMER_CC_CTRL_PRSSEL_PRSCH10 TIMER_CC_CTRL_PRSSEL_PRSCHx(10) +#define TIMER_CC_CTRL_PRSSEL_PRSCH11 TIMER_CC_CTRL_PRSSEL_PRSCHx(11) + +#define TIMER_CC_CTRL_CUFOA_SHIFT (12) +#define TIMER_CC_CTRL_CUFOA_MASK (0x3 << TIMER_CC_CTRL_CUFOA_SHIFT) +#define TIMER_CC_CTRL_CUFOA(v) \ + (((v) << TIMER_CC_CTRL_CUFOA_SHIFT) & TIMER_CC_CTRL_CUFOA_MASK) +#define TIMER_CC_CTRL_CUFOA_NONE TIMER_CC_CTRL_CUFOA(0) +#define TIMER_CC_CTRL_CUFOA_TOGGLE TIMER_CC_CTRL_CUFOA(1) +#define TIMER_CC_CTRL_CUFOA_CLEAR TIMER_CC_CTRL_CUFOA(2) +#define TIMER_CC_CTRL_CUFOA_SET TIMER_CC_CTRL_CUFOA(3) + +#define TIMER_CC_CTRL_COFOA_SHIFT (10) +#define TIMER_CC_CTRL_COFOA_MASK (0x3 << TIMER_CC_CTRL_COFOA_SHIFT) +#define TIMER_CC_CTRL_COFOA(v) \ + (((v) << TIMER_CC_CTRL_COFOA_SHIFT) & TIMER_CC_CTRL_COFOA_MASK) +#define TIMER_CC_CTRL_COFOA_NONE TIMER_CC_CTRL_COFOA(0) +#define TIMER_CC_CTRL_COFOA_TOGGLE TIMER_CC_CTRL_COFOA(1) +#define TIMER_CC_CTRL_COFOA_CLEAR TIMER_CC_CTRL_COFOA(2) +#define TIMER_CC_CTRL_COFOA_SET TIMER_CC_CTRL_COFOA(3) + +#define TIMER_CC_CTRL_CMOA_SHIFT (8) +#define TIMER_CC_CTRL_CMOA_MASK (0x3 << TIMER_CC_CTRL_CMOA_SHIFT) +#define TIMER_CC_CTRL_CMOA(v) \ + (((v) << TIMER_CC_CTRL_CMOA_SHIFT) & TIMER_CC_CTRL_CMOA_MASK) +#define TIMER_CC_CTRL_CMOA_NONE TIMER_CC_CTRL_CMOA(0) +#define TIMER_CC_CTRL_CMOA_TOGGLE TIMER_CC_CTRL_CMOA(1) +#define TIMER_CC_CTRL_CMOA_CLEAR TIMER_CC_CTRL_CMOA(2) +#define TIMER_CC_CTRL_CMOA_SET TIMER_CC_CTRL_CMOA(3) + +#define TIMER_CC_CTRL_COIST (1 << 4) +#define TIMER_CC_CTRL_OUTINV (1 << 2) + +#define TIMER_CC_CTRL_MODE_SHIFT (0) +#define TIMER_CC_CTRL_MODE_MASK (0x3 << TIMER_CC_CTRL_MODE_SHIFT) +#define TIMER_CC_CTRL_MODE(v) \ + (((v) << TIMER_CC_CTRL_MODE_SHIFT) & TIMER_CC_CTRL_MODE_MASK) +#define TIMER_CC_CTRL_MODE_OFF TIMER_CC_CTRL_MODE(0) +#define TIMER_CC_CTRL_MODE_INPUTCAPTURE TIMER_CC_CTRL_MODE(1) +#define TIMER_CC_CTRL_MODE_OUTPUTCOMPARE TIMER_CC_CTRL_MODE(2) +#define TIMER_CC_CTRL_MODE_PWM TIMER_CC_CTRL_MODE(3) + +#define TIMER_CC_CTRL_MODE_INPUT_CAPTURE \ + TIMER_CC_CTRL_MODE_INPUTCAPTURE +#define TIMER_CC_CTRL_MODE_OUTPUT_CAPTURE \ + TIMER_CC_CTRL_MODE_OUTPUTCAPTURE + +/* TIMER_DTCTRL */ +#define TIMER_DTCTRL_DTPRSEN (1 << 24) + +#define TIMER_DTCTRL_DTPRSSEL_SHIFT (4) +#define TIMER_DTCTRL_DTPRSSEL_MASK (0xF << TIMER_DTCTRL_DTPRSSEL_SHIFT) +#define TIMER_DTCTRL_DTPRSSEL(v) \ + (((v) << TIMER_DTCTRL_DTPRSSEL_SHIFT) & TIMER_DTCTRL_DTPRSSEL_MASK) +#define TIMER_DTCTRL_DTPRSSEL_PRSCHx(x) TIMER_DTCTRL_DTPRSSEL(x) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH0 TIMER_DTCTRL_DTPRSSEL_PRSCHx(0) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH1 TIMER_DTCTRL_DTPRSSEL_PRSCHx(1) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH2 TIMER_DTCTRL_DTPRSSEL_PRSCHx(2) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH3 TIMER_DTCTRL_DTPRSSEL_PRSCHx(3) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH4 TIMER_DTCTRL_DTPRSSEL_PRSCHx(4) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH5 TIMER_DTCTRL_DTPRSSEL_PRSCHx(5) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH6 TIMER_DTCTRL_DTPRSSEL_PRSCHx(6) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH7 TIMER_DTCTRL_DTPRSSEL_PRSCHx(7) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH8 TIMER_DTCTRL_DTPRSSEL_PRSCHx(8) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH9 TIMER_DTCTRL_DTPRSSEL_PRSCHx(9) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH10 TIMER_DTCTRL_DTPRSSEL_PRSCHx(10) +#define TIMER_DTCTRL_DTPRSSEL_PRSCH11 TIMER_DTCTRL_DTPRSSEL_PRSCHx(11) + +#define TIMER_DTCTRL_DTCINV (1 << 3) +#define TIMER_DTCTRL_DTIPOL (1 << 2) +#define TIMER_DTCTRL_DTDAS (1 << 1) +#define TIMER_DTCTRL_DTEN (1 << 0) + +/* TIMER_DTTIME */ +#define TIMER_DTTIME_DTFALLT_SHIFT (16) +#define TIMER_DTTIME_DTFALLT_MASK (0x3F << TIMER_DTTIME_DTFALLT_SHIFT) +#define TIMER_DTTIME_DTFALLT(v) \ + (((v) << TIMER_DTTIME_DTFALLT_SHIFT) & TIMER_DTTIME_DTFALLT_MASK) + +#define TIMER_DTTIME_DTRISET_SHIFT (8) +#define TIMER_DTTIME_DTRISET_MASK (0x3F << TIMER_DTTIME_DTRISET_SHIFT) +#define TIMER_DTTIME_DTRISET(v) \ + (((v) << TIMER_DTTIME_DTRISET_SHIFT) & TIMER_DTTIME_DTRISET_MASK) + + +#define TIMER_DTTIME_DTPRESC_SHIFT (0) +#define TIMER_DTTIME_DTPRESC_MASK (0xF << TIMER_DTTIME_DTPRESC_SHIFT) +#define TIMER_DTTIME_DTPRESC(v) \ + (((v) << TIMER_DTTIME_DTPRESC_SHIFT) & TIMER_DTTIME_DTPRESC_MASK) +#define TIMER_DTTIME_DTPRESC_DIV1 TIMER_DTTIME_DTPRESC(0) +#define TIMER_DTTIME_DTPRESC_DIV2 TIMER_DTTIME_DTPRESC(1) +#define TIMER_DTTIME_DTPRESC_DIV4 TIMER_DTTIME_DTPRESC(2) +#define TIMER_DTTIME_DTPRESC_DIV8 TIMER_DTTIME_DTPRESC(3) +#define TIMER_DTTIME_DTPRESC_DIV16 TIMER_DTTIME_DTPRESC(4) +#define TIMER_DTTIME_DTPRESC_DIV32 TIMER_DTTIME_DTPRESC(5) +#define TIMER_DTTIME_DTPRESC_DIV64 TIMER_DTTIME_DTPRESC(6) +#define TIMER_DTTIME_DTPRESC_DIV128 TIMER_DTTIME_DTPRESC(7) +#define TIMER_DTTIME_DTPRESC_DIV256 TIMER_DTTIME_DTPRESC(8) +#define TIMER_DTTIME_DTPRESC_DIV512 TIMER_DTTIME_DTPRESC(8) +#define TIMER_DTTIME_DTPRESC_DIV1024 TIMER_DTTIME_DTPRESC(10) +#define TIMER_DTTIME_DTPRESC_NODIV TIMER_DTTIME_DTPRESC_DIV1 + +/* TIMER_DTFC */ +#define TIMER_DTFC_DTLOCKUPFEN (1 << 27) +#define TIMER_DTFC_DTDBGFEN (1 << 26) +#define TIMER_DTFC_DTPRS1FEN (1 << 25) +#define TIMER_DTFC_DTPRS0FEN (1 << 24) + +#define TIMER_DTFC_DTFA_SHIFT (16) +#define TIMER_DTFC_DTFA_MASK (0x3 << TIMER_DTFC_DTFA_SHIFT) +#define TIMER_DTFC_DTFA(v) \ + (((v) << TIMER_DTFC_DTFA_SHIFT) & TIMER_DTFC_DTFA_MASK) +#define TIMER_DTFC_DTFA_NONE TIMER_DTFC_DTFA(0) +#define TIMER_DTFC_DTFA_INACTIVE TIMER_DTFC_DTFA(1) +#define TIMER_DTFC_DTFA_CLEAR TIMER_DTFC_DTFA(2) +#define TIMER_DTFC_DTFA_TRISTATE TIMER_DTFC_DTFA(3) + +#define TIMER_DTFC_DTPRS1FSEL_SHIFT (8) +#define TIMER_DTFC_DTPRS1FSEL_MASK (0x3 << TIMER_DTFC_DTPRS1FSEL_SHIFT) +#define TIMER_DTFC_DTPRS1FSEL(v) \ + (((v) << TIMER_DTFC_DTPRS1FSEL_SHIFT) & TIMER_DTFC_DTPRS1FSEL_MASK) +#define TIMER_DTFC_DTPRS1FSEL_PRSCHx(x) TIMER_DTFC_DTPRS1FSEL(x) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH0 TIMER_DTFC_DTPRS1FSEL_PRSCHx(0) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH1 TIMER_DTFC_DTPRS1FSEL_PRSCHx(1) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH2 TIMER_DTFC_DTPRS1FSEL_PRSCHx(2) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH3 TIMER_DTFC_DTPRS1FSEL_PRSCHx(3) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH4 TIMER_DTFC_DTPRS1FSEL_PRSCHx(4) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH5 TIMER_DTFC_DTPRS1FSEL_PRSCHx(5) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH6 TIMER_DTFC_DTPRS1FSEL_PRSCHx(6) +#define TIMER_DTFC_DTPRS1FSEL_PRSCH7 TIMER_DTFC_DTPRS1FSEL_PRSCHx(7) + +#define TIMER_DTFC_DTPRS0FSEL_SHIFT (8) +#define TIMER_DTFC_DTPRS0FSEL_MASK (0x3 << TIMER_DTFC_DTPRS0FSEL_SHIFT) +#define TIMER_DTFC_DTPRS0FSEL(v) \ + (((v) << TIMER_DTFC_DTPRS0FSEL_SHIFT) & TIMER_DTFC_DTPRS0FSEL_MASK) +#define TIMER_DTFC_DTPRS0FSEL_PRSCHx(x) TIMER_DTFC_DTPRS0FSEL(x) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH0 TIMER_DTFC_DTPRS0FSEL_PRSCHx(0) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH1 TIMER_DTFC_DTPRS0FSEL_PRSCHx(1) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH2 TIMER_DTFC_DTPRS0FSEL_PRSCHx(2) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH3 TIMER_DTFC_DTPRS0FSEL_PRSCHx(3) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH4 TIMER_DTFC_DTPRS0FSEL_PRSCHx(4) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH5 TIMER_DTFC_DTPRS0FSEL_PRSCHx(5) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH6 TIMER_DTFC_DTPRS0FSEL_PRSCHx(6) +#define TIMER_DTFC_DTPRS0FSEL_PRSCH7 TIMER_DTFC_DTPRS0FSEL_PRSCHx(7) + +/* TIMER_DTOGEN */ +#define TIMER_DTOGEN_DTOGCDTI2EN (1 << 5) +#define TIMER_DTOGEN_DTOGCDTI1EN (1 << 4) +#define TIMER_DTOGEN_DTOGCDTI0EN (1 << 3) +#define TIMER_DTOGEN_DTOGCC2EN (1 << 2) +#define TIMER_DTOGEN_DTOGCC1EN (1 << 1) +#define TIMER_DTOGEN_DTOGCC0EN (1 << 0) + +/* TIMER_DTFAULT */ +#define TIMER_DTFAULT_DTLOCKUPF (1 << 3) +#define TIMER_DTFAULT_DTDBGF (1 << 2) +#define TIMER_DTFAULT_DTPRS1F (1 << 1) +#define TIMER_DTFAULT_DTPRS0F (1 << 0) + +/* TIMER_DTFAULTC */ +#define TIMER_DTFAULTC_TLOCKUPFC (1 << 3) +#define TIMER_DTFAULTC_DTDBGFC (1 << 2) +#define TIMER_DTFAULTC_DTPRS1FC (1 << 1) +#define TIMER_DTFAULTC_DTPRS0FC (1 << 0) + +/* TIMER_DTLOCK */ +#define TIMER_DTLOCK_LOCKKEY_SHIFT (0) +#define TIMER_DTLOCK_LOCKKEY_MASK (0xFFFF << TIMER_DTLOCK_LOCKKEY_SHIFT) +#define TIMER_DTLOCK_LOCKKEY_UNLOCKED (0x0000 << TIMER_DTLOCK_LOCKKEY_SHIFT) +#define TIMER_DTLOCK_LOCKKEY_LOCKED (0x0001 << TIMER_DTLOCK_LOCKKEY_SHIFT) +#define TIMER_DTLOCK_LOCKKEY_LOCK (0x0000 << TIMER_DTLOCK_LOCKKEY_SHIFT) +#define TIMER_DTLOCK_LOCKKEY_UNLOCK (0xCE80 << TIMER_DTLOCK_LOCKKEY_SHIFT) + +/* TIMER0 */ +#define TIMER0 TIMER0_BASE +#define TIMER0_CTRL TIMER_CTRL(TIMER0) +#define TIMER0_CMD TIMER_CMD(TIMER0) +#define TIMER0_STATUS TIMER_STATUS(TIMER0) +#define TIMER0_IEN TIMER_IEN(TIMER0) +#define TIMER0_IF TIMER_IF(TIMER0) +#define TIMER0_IFS TIMER_IFS(TIMER0) +#define TIMER0_IFC TIMER_IFC(TIMER0) +#define TIMER0_TOP TIMER_TOP(TIMER0) +#define TIMER0_TOPB TIMER_TOPB(TIMER0) +#define TIMER0_CNT TIMER_CNT(TIMER0) +#define TIMER0_ROUTE TIMER_ROUTE(TIMER0) + +#define TIMER0_CC0_CTRL TIMER_CC0_CTRL(TIMER0) +#define TIMER0_CC0_CCV TIMER_CC0_CCV(TIMER0) +#define TIMER0_CC0_CCVP TIMER_CC0_CCVP(TIMER0) +#define TIMER0_CC0_CCVB TIMER_CC0_CCVB(TIMER0) + +#define TIMER0_CC1_CTRL TIMER_CC1_CTRL(TIMER0) +#define TIMER0_CC1_CCV TIMER_CC1_CCV(TIMER0) +#define TIMER0_CC1_CCVP TIMER_CC1_CCVP(TIMER0) +#define TIMER0_CC1_CCVB TIMER_CC1_CCVB(TIMER0) + +#define TIMER0_CC2_CTRL TIMER_CC2_CTRL(TIMER0) +#define TIMER0_CC2_CCV TIMER_CC2_CCV(TIMER0) +#define TIMER0_CC2_CCVP TIMER_CC2_CCVP(TIMER0) +#define TIMER0_CC2_CCVB TIMER_CC2_CCVB(TIMER0) + +#define TIMER0_DTCTRL TIMER_DTCTRL(TIMER0) +#define TIMER0_DTTIME TIMER_DTTIME(TIMER0) +#define TIMER0_DTFC TIMER_DTFC(TIMER0) +#define TIMER0_DTOGEN TIMER_DTOGEN(TIMER0) +#define TIMER0_DTFAULT TIMER_DTFAULT(TIMER0) +#define TIMER0_DTFAULTC TIMER_DTFAULTC(TIMER0) +#define TIMER0_DTLOCK TIMER_DTLOCK(TIMER0) + +/* TIMER1 */ +#define TIMER1 TIMER1_BASE +#define TIMER1_CTRL TIMER_CTRL(TIMER1) +#define TIMER1_CMD TIMER_CMD(TIMER1) +#define TIMER1_STATUS TIMER_STATUS(TIMER1) +#define TIMER1_IEN TIMER_IEN(TIMER1) +#define TIMER1_IF TIMER_IF(TIMER1) +#define TIMER1_IFS TIMER_IFS(TIMER1) +#define TIMER1_IFC TIMER_IFC(TIMER1) +#define TIMER1_TOP TIMER_TOP(TIMER1) +#define TIMER1_TOPB TIMER_TOPB(TIMER1) +#define TIMER1_CNT TIMER_CNT(TIMER1) +#define TIMER1_ROUTE TIMER_ROUTE(TIMER1) + +#define TIMER1_CC0_CTRL TIMER_CC0_CTRL(TIMER1) +#define TIMER1_CC0_CCV TIMER_CC0_CCV(TIMER1) +#define TIMER1_CC0_CCVP TIMER_CC0_CCVP(TIMER1) +#define TIMER1_CC0_CCVB TIMER_CC0_CCVB(TIMER1) + +#define TIMER1_CC1_CTRL TIMER_CC1_CTRL(TIMER1) +#define TIMER1_CC1_CCV TIMER_CC1_CCV(TIMER1) +#define TIMER1_CC1_CCVP TIMER_CC1_CCVP(TIMER1) +#define TIMER1_CC1_CCVB TIMER_CC1_CCVB(TIMER1) + +#define TIMER1_CC2_CTRL TIMER_CC2_CTRL(TIMER1) +#define TIMER1_CC2_CCV TIMER_CC2_CCV(TIMER1) +#define TIMER1_CC2_CCVP TIMER_CC2_CCVP(TIMER1) +#define TIMER1_CC2_CCVB TIMER_CC2_CCVB(TIMER1) + +/* TIMER2 */ +#define TIMER2 TIMER2_BASE +#define TIMER2_CTRL TIMER_CTRL(TIMER2) +#define TIMER2_CMD TIMER_CMD(TIMER2) +#define TIMER2_STATUS TIMER_STATUS(TIMER2) +#define TIMER2_IEN TIMER_IEN(TIMER2) +#define TIMER2_IF TIMER_IF(TIMER2) +#define TIMER2_IFS TIMER_IFS(TIMER2) +#define TIMER2_IFC TIMER_IFC(TIMER2) +#define TIMER2_TOP TIMER_TOP(TIMER2) +#define TIMER2_TOPB TIMER_TOPB(TIMER2) +#define TIMER2_CNT TIMER_CNT(TIMER2) +#define TIMER2_ROUTE TIMER_ROUTE(TIMER2) + +#define TIMER2_CC0_CTRL TIMER_CC0_CTRL(TIMER2) +#define TIMER2_CC0_CCV TIMER_CC0_CCV(TIMER2) +#define TIMER2_CC0_CCVP TIMER_CC0_CCVP(TIMER2) +#define TIMER2_CC0_CCVB TIMER_CC0_CCVB(TIMER2) + +#define TIMER2_CC1_CTRL TIMER_CC1_CTRL(TIMER2) +#define TIMER2_CC1_CCV TIMER_CC1_CCV(TIMER2) +#define TIMER2_CC1_CCVP TIMER_CC1_CCVP(TIMER2) +#define TIMER2_CC1_CCVB TIMER_CC1_CCVB(TIMER2) + +#define TIMER2_CC2_CTRL TIMER_CC2_CTRL(TIMER2) +#define TIMER2_CC2_CCV TIMER_CC2_CCV(TIMER2) +#define TIMER2_CC2_CCVP TIMER_CC2_CCVP(TIMER2) +#define TIMER2_CC2_CCVB TIMER_CC2_CCVB(TIMER2) + +/* TIMER3 */ +#define TIMER3 TIMER3_BASE +#define TIMER3_CTRL TIMER_CTRL(TIMER3) +#define TIMER3_CMD TIMER_CMD(TIMER3) +#define TIMER3_STATUS TIMER_STATUS(TIMER3) +#define TIMER3_IEN TIMER_IEN(TIMER3) +#define TIMER3_IF TIMER_IF(TIMER3) +#define TIMER3_IFS TIMER_IFS(TIMER3) +#define TIMER3_IFC TIMER_IFC(TIMER3) +#define TIMER3_TOP TIMER_TOP(TIMER3) +#define TIMER3_TOPB TIMER_TOPB(TIMER3) +#define TIMER3_CNT TIMER_CNT(TIMER3) +#define TIMER3_ROUTE TIMER_ROUTE(TIMER3) + +#define TIMER3_CC0_CTRL TIMER_CC0_CTRL(TIMER3) +#define TIMER3_CC0_CCV TIMER_CC0_CCV(TIMER3) +#define TIMER3_CC0_CCVP TIMER_CC0_CCVP(TIMER3) +#define TIMER3_CC0_CCVB TIMER_CC0_CCVB(TIMER3) + +#define TIMER3_CC1_CTRL TIMER_CC1_CTRL(TIMER3) +#define TIMER3_CC1_CCV TIMER_CC1_CCV(TIMER3) +#define TIMER3_CC1_CCVP TIMER_CC1_CCVP(TIMER3) +#define TIMER3_CC1_CCVB TIMER_CC1_CCVB(TIMER3) + +#define TIMER3_CC2_CTRL TIMER_CC2_CTRL(TIMER3) +#define TIMER3_CC2_CCV TIMER_CC2_CCV(TIMER3) +#define TIMER3_CC2_CCVP TIMER_CC2_CCVP(TIMER3) +#define TIMER3_CC2_CCVB TIMER_CC2_CCVB(TIMER3) + +/** @defgroup timer_ch Timer Channel Number +@ingroup timer_defines + +@{*/ +enum tim_ch { + TIM_CH0 = 0, + TIM_CH1, + TIM_CH2 +}; +/**@}*/ + +BEGIN_DECLS + +void timer_start(uint32_t timer); +void timer_stop(uint32_t timer); + +void timer_set_clock_prescaler(uint32_t timer, uint32_t prescaler); + +void timer_set_top(uint32_t timer, uint32_t top); + +/* TODO: interrupt {enable, disable, read-flags} */ + +/* TODO: for channel (output value, input value) + * enable channel + * set location, set output mode */ + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/uart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/uart.h new file mode 100644 index 00000000..b69617ba --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/uart.h @@ -0,0 +1,100 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_UART_H +#define LIBOPENCM3_EFM32_UART_H + +/** + * USART and UART registers are equivalent except [in UART registers]: + * + * USART_CTRL: SYNC, CSMA, SMSDELAY, SSSEARLY, CSINV, CPOL and CPHA [1] + * USART_STATUS: MASTEREN [1] + * [1] Synchronous operation not available. + * USART_CTRL: MSBF (transmission LSB first only) + * USART_CTRL: AUTOCS (chip-select not available) + * USART_CTRL: SCMODE (SmartCard mode not available) + * USART_FRAME: DATABITS (limited framsize. 8-9 databits only) + * USART_IRCTRL: IREN (IrDA not available) + * (except DATABITS, all the above are 0) + * + * full text: (p495, "d0183_Rev1.10" EFM32LG-RM) + * - "18.3 Functional Description", + * - "18.4 Register Description" + * - "18.5 Register Map" + * + * use USART macro's to manipulate UART registers. + */ +#include +#include + +/* UART0 */ +#define UART0 UART0_BASE +#define UART0_CTRL USART_CTRL(UART0) +#define UART0_FRAME USART_FRAME(UART0) +#define UART0_TRIGCTRL USART_TRIGCTRL(UART0) +#define UART0_CMD USART_CMD(UART0) +#define UART0_STATUS USART_STATUS(UART0) +#define UART0_CLKDIV USART_CLKDIV(UART0) +#define UART0_RXDATAX USART_RXDATAX(UART0) +#define UART0_RXDATA USART_RXDATA(UART0) +#define UART0_RXDOUBLEX USART_RXDOUBLEX(UART0) +#define UART0_RXDOUBLE USART_RXDOUBLE(UART0) +#define UART0_RXDATAXP USART_RXDATAXP(UART0) +#define UART0_RXDOUBLEXP USART_RXDOUBLEXP(UART0) +#define UART0_TXDATAX USART_TXDATAX(UART0) +#define UART0_TXDATA USART_TXDATA(UART0) +#define UART0_TXDOUBLEX USART_TXDOUBLEX(UART0) +#define UART0_TXDOUBLE USART_TXDOUBLE(UART0) +#define UART0_IF USART_IF(UART0) +#define UART0_IFS USART_IFS(UART0) +#define UART0_IFC USART_IFC(UART0) +#define UART0_IEN USART_IEN(UART0) +#define UART0_IRCTRL USART_IRCTRL(UART0) +#define UART0_ROUTE USART_ROUTE(UART0) +#define UART0_INPUT USART_INPUT(UART0) +#define UART0_I2SCTRL USART_I2SCTRL(UART0) + +/* UART1 */ +#define UART1 UART1_BASE +#define UART1_CTRL USART_CTRL(UART1) +#define UART1_FRAME USART_FRAME(UART1) +#define UART1_TRIGCTRL USART_TRIGCTRL(UART1) +#define UART1_CMD USART_CMD(UART1) +#define UART1_STATUS USART_STATUS(UART1) +#define UART1_CLKDIV USART_CLKDIV(UART1) +#define UART1_RXDATAX USART_RXDATAX(UART1) +#define UART1_RXDATA USART_RXDATA(UART1) +#define UART1_RXDOUBLEX USART_RXDOUBLEX(UART1) +#define UART1_RXDOUBLE USART_RXDOUBLE(UART1) +#define UART1_RXDATAXP USART_RXDATAXP(UART1) +#define UART1_RXDOUBLEXP USART_RXDOUBLEXP(UART1) +#define UART1_TXDATAX USART_TXDATAX(UART1) +#define UART1_TXDATA USART_TXDATA(UART1) +#define UART1_TXDOUBLEX USART_TXDOUBLEX(UART1) +#define UART1_TXDOUBLE USART_TXDOUBLE(UART1) +#define UART1_IF USART_IF(UART1) +#define UART1_IFS USART_IFS(UART1) +#define UART1_IFC USART_IFC(UART1) +#define UART1_IEN USART_IEN(UART1) +#define UART1_IRCTRL USART_IRCTRL(UART1) +#define UART1_ROUTE USART_ROUTE(UART1) +#define UART1_INPUT USART_INPUT(UART1) +#define UART1_I2SCTRL USART_I2SCTRL(UART1) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usart.h new file mode 100644 index 00000000..daafe598 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usart.h @@ -0,0 +1,512 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_USART_H +#define LIBOPENCM3_EFM32_USART_H + +#include +#include + +#define USART_CTRL(base) MMIO32((base) + 0x000) +#define USART_FRAME(base) MMIO32((base) + 0x004) +#define USART_TRIGCTRL(base) MMIO32((base) + 0x008) +#define USART_CMD(base) MMIO32((base) + 0x00C) +#define USART_STATUS(base) MMIO32((base) + 0x010) +#define USART_CLKDIV(base) MMIO32((base) + 0x014) +#define USART_RXDATAX(base) MMIO32((base) + 0x018) +#define USART_RXDATA(base) MMIO32((base) + 0x01C) +#define USART_RXDOUBLEX(base) MMIO32((base) + 0x020) +#define USART_RXDOUBLE(base) MMIO32((base) + 0x024) +#define USART_RXDATAXP(base) MMIO32((base) + 0x028) +#define USART_RXDOUBLEXP(base) MMIO32((base) + 0x02C) +#define USART_TXDATAX(base) MMIO32((base) + 0x030) +#define USART_TXDATA(base) MMIO32((base) + 0x034) +#define USART_TXDOUBLEX(base) MMIO32((base) + 0x038) +#define USART_TXDOUBLE(base) MMIO32((base) + 0x03C) +#define USART_IF(base) MMIO32((base) + 0x040) +#define USART_IFS(base) MMIO32((base) + 0x044) +#define USART_IFC(base) MMIO32((base) + 0x048) +#define USART_IEN(base) MMIO32((base) + 0x04C) +#define USART_IRCTRL(base) MMIO32((base) + 0x050) +#define USART_ROUTE(base) MMIO32((base) + 0x054) +#define USART_INPUT(base) MMIO32((base) + 0x058) +#define USART_I2SCTRL(base) MMIO32((base) + 0x05C) + +/* USART_CTRL */ +#define USART_CTRL_SMSDELAY (1 << 31) +#define USART_CTRL_MVDIS (1 << 30) +#define USART_CTRL_AUTOTX (1 << 29) +#define USART_CTRL_BYTESWAP (1 << 28) + +#define USART_CTRL_TXDELAY_SHIFT (26) +#define USART_CTRL_TXDELAY_MASK (0x3 << USART_CTRL_TXDELAY_SHIFT) +#define USART_CTRL_TXDELAY(v) \ + (((v) << USART_CTRL_TXDELAY_SHIFT) & USART_CTRL_TXDELAY_MASK) +#define USART_CTRL_TXDELAY_NONE USART_CTRL_TXDELAY(0) +#define USART_CTRL_TXDELAY_SINGLE USART_CTRL_TXDELAY(1) +#define USART_CTRL_TXDELAY_DOUBLE USART_CTRL_TXDELAY(2) +#define USART_CTRL_TXDELAY_TRIPLE USART_CTRL_TXDELAY(3) + +#define USART_CTRL_SSSEARLY (1 << 25) +#define USART_CTRL_ERRSTX (1 << 24) +#define USART_CTRL_ERRSRX (1 << 23) +#define USART_CTRL_ERRSDMA (1 << 22) +#define USART_CTRL_BIT8DV (1 << 21) +#define USART_CTRL_SKIPPERRF (1 << 20) +#define USART_CTRL_SCRETRANS (1 << 19) +#define USART_CTRL_SCMODE (1 << 18) +#define USART_CTRL_AUTOTRI (1 << 17) +#define USART_CTRL_AUTOCS (1 << 16) +#define USART_CTRL_CSINV (1 << 15) +#define USART_CTRL_TXINV (1 << 14) +#define USART_CTRL_RXINV (1 << 13) +#define USART_CTRL_TXBIL (1 << 12) +#define USART_CTRL_CSMA (1 << 11) +#define USART_CTRL_MSBF (1 << 10) +#define USART_CTRL_CLKPHA (1 << 9) +#define USART_CTRL_CLKPOL (1 << 8) + +#define USART_CTRL_OVS_SHIFT (5) +#define USART_CTRL_OVS_MASK (0x3 << USART_CTRL_OVS_SHIFT) +#define USART_CTRL_OVS(v) \ + (((v) << USART_CTRL_OVS_SHIFT) & USART_CTRL_OVS_MASK) +#define USART_CTRL_OVS_X16 USART_CTRL_OVS(0) +#define USART_CTRL_OVS_X8 USART_CTRL_OVS(1) +#define USART_CTRL_OVS_X6 USART_CTRL_OVS(2) +#define USART_CTRL_OVS_X4 USART_CTRL_OVS(3) + +#define USART_CTRL_MPAB (1 << 4) +#define USART_CTRL_MPM (1 << 3) +#define USART_CTRL_CCEN (1 << 2) +#define USART_CTRL_LOOPBK (1 << 1) +#define USART_CTRL_SYNC (1 << 0) + +/* USART_FRAME */ + +#define USART_FRAME_STOPBITS_SHIFT (12) +#define USART_FRAME_STOPBITS_MASK (0x3 << USART_FRAME_STOPBITS_SHIFT) +#define USART_FRAME_STOPBITS(v) \ + (((v) << USART_FRAME_STOPBITS_SHIFT) & USART_FRAME_STOPBITS_MASK) +#define USART_FRAME_STOPBITS_HALF USART_FRAME_STOPBITS(0) +#define USART_FRAME_STOPBITS_ONE USART_FRAME_STOPBITS(1) +#define USART_FRAME_STOPBITS_ONEANDAHALF USART_FRAME_STOPBITS(2) +#define USART_FRAME_STOPBITS_ONE_AND_A_HALF \ + USART_FRAME_STOPBITS_ONEANDAHALF +#define USART_FRAME_STOPBITS_TWO USART_FRAME_STOPBITS(3) + +#define USART_FRAME_PARITY_SHIFT (8) +#define USART_FRAME_PARITY_MASK (0x3 << USART_FRAME_PARITY_SHIFT) +#define USART_FRAME_PARITY(v) \ + (((v) << USART_FRAME_PARITY_SHIFT) & USART_FRAME_PARITY_MASK) +#define USART_FRAME_PARITY_NONE USART_FRAME_PARITY(0) +#define USART_FRAME_PARITY_EVEN USART_FRAME_PARITY(2) +#define USART_FRAME_PARITY_ODD USART_FRAME_PARITY(3) + +#define USART_FRAME_DATABITS_SHIFT (0) +#define USART_FRAME_DATABITS_MASK (0xF << USART_FRAME_DATABITS_SHIFT) +#define USART_FRAME_DATABITS(v) \ + (((v) << USART_FRAME_DATABITS_SHIFT) & USART_FRAME_DATABITS_MASK) +#define USART_FRAME_DATABITS_FOUR USART_FRAME_DATABITS(1) +#define USART_FRAME_DATABITS_FIVE USART_FRAME_DATABITS(2) +#define USART_FRAME_DATABITS_SIX USART_FRAME_DATABITS(3) +#define USART_FRAME_DATABITS_SEVEN USART_FRAME_DATABITS(4) +#define USART_FRAME_DATABITS_EIGHT USART_FRAME_DATABITS(5) +#define USART_FRAME_DATABITS_NINE USART_FRAME_DATABITS(6) +#define USART_FRAME_DATABITS_TEN USART_FRAME_DATABITS(7) +#define USART_FRAME_DATABITS_ELEVEN USART_FRAME_DATABITS(8) +#define USART_FRAME_DATABITS_TWELVE USART_FRAME_DATABITS(9) +#define USART_FRAME_DATABITS_THIRTEEN USART_FRAME_DATABITS(10) +#define USART_FRAME_DATABITS_FOURTEEN USART_FRAME_DATABITS(11) +#define USART_FRAME_DATABITS_FIFTEEN USART_FRAME_DATABITS(12) +#define USART_FRAME_DATABITS_SIXTEEN USART_FRAME_DATABITS(13) + +/* USART_TRIGCTRL */ +#define USART_TRIGCTRL_AUTOTXTEN (1 << 6) +#define USART_TRIGCTRL_TXTEN (1 << 5) +#define USART_TRIGCTRL_RXTEN (1 << 4) + +#define USART_TRIGCTRL_TSEL_SHIFT (8) +#define USART_TRIGCTRL_TSEL_MASK (0x3 << USART_TRIGCTRL_TSEL_SHIFT) +#define USART_TRIGCTRL_TSEL_PRSCHx(v) \ + (((v) << USART_TRIGCTRL_TSEL_SHIFT) & USART_TRIGCTRL_TSEL_MASK) +#define USART_TRIGCTRL_TSEL_PRSCH0 USART_TRIGCTRL_TSEL_PRSCHx(0) +#define USART_TRIGCTRL_TSEL_PRSCH1 USART_TRIGCTRL_TSEL_PRSCHx(1) +#define USART_TRIGCTRL_TSEL_PRSCH2 USART_TRIGCTRL_TSEL_PRSCHx(2) +#define USART_TRIGCTRL_TSEL_PRSCH3 USART_TRIGCTRL_TSEL_PRSCHx(3) +#define USART_TRIGCTRL_TSEL_PRSCH4 USART_TRIGCTRL_TSEL_PRSCHx(4) +#define USART_TRIGCTRL_TSEL_PRSCH5 USART_TRIGCTRL_TSEL_PRSCHx(5) +#define USART_TRIGCTRL_TSEL_PRSCH6 USART_TRIGCTRL_TSEL_PRSCHx(6) +#define USART_TRIGCTRL_TSEL_PRSCH7 USART_TRIGCTRL_TSEL_PRSCHx(7) + +/* USART_CMD */ +#define USART_CMD_CLEARRX (1 << 11) +#define USART_CMD_CLEARTX (1 << 10) +#define USART_CMD_TXTRIDIS (1 << 9) +#define USART_CMD_TXTRIEN (1 << 8) +#define USART_CMD_RXBLOCKDIS (1 << 7) +#define USART_CMD_RXBLOCKEN (1 << 6) +#define USART_CMD_MASTERDIS (1 << 5) +#define USART_CMD_MASTEREN (1 << 4) +#define USART_CMD_TXDIS (1 << 3) +#define USART_CMD_TXEN (1 << 2) +#define USART_CMD_RXDIS (1 << 1) +#define USART_CMD_RXEN (1 << 0) + +/* USART_STATUS */ +#define USART_STATUS_RXFULLRIGHT (1 << 12) +#define USART_STATUS_RXDATAVRIGHT (1 << 11) +#define USART_STATUS_TXBSRIGHT (1 << 10) +#define USART_STATUS_TXBDRIGHT (1 << 9) +#define USART_STATUS_RXFULL (1 << 8) +#define USART_STATUS_RXDATAV (1 << 7) +#define USART_STATUS_TXBL (1 << 6) +#define USART_STATUS_TXC (1 << 5) +#define USART_STATUS_TXTRI (1 << 4) +#define USART_STATUS_RXBLOCK (1 << 3) +#define USART_STATUS_MASTER (1 << 2) +#define USART_STATUS_TXENS (1 << 1) +#define USART_STATUS_RXENS (1 << 0) + +/* USART_CLKDIV */ +#define USART_CLKDIV_DIV_SHIFT (6) +#define USART_CLKDIV_DIV_MASK (0x7FFF << USART_CLKDIV_DIV_SHIFT) +#define USART_CLKDIV_DIV(v) \ + (((v) << USART_CLKDIV_DIV_SHIFT) & USART_CLKDIV_DIV_MASK) + +/* USART_RXDATAX */ +#define USART_RXDATAX_FERR (1 << 15) +#define USART_RXDATAX_PERR (1 << 14) + +#define USART_RXDATAX_RXDATA_SHIFT (0) +#define USART_RXDATAX_RXDATA_MASK (0x1FF << USART_RXDATAX_RXDATA_SHIFT) + +/* USART_RXDOUBLEX */ +#define USART_RXDOUBLEX_FERR1 (1 << 31) +#define USART_RXDOUBLEX_PERR1 (1 << 30) + +#define USART_RXDOUBLEX_RXDATA1_SHIFT (16) +#define USART_RXDOUBLEX_RXDATA1_MASK \ + (0x1FF << USART_RXDOUBLEX_RXDATA1_SHIFT) + +#define USART_RXDOUBLEX_FERR0 (1 << 15) +#define USART_RXDOUBLEX_PERR0 (1 << 14) + +#define USART_RXDOUBLEX_RXDATA0_SHIFT (0) +#define USART_RXDOUBLEX_RXDATA0_MASK \ + (0x1FF << USART_RXDOUBLEX_RXDATA1_SHIFT) + +/* USART_RXDOUBLE */ +#define USART_RXDOUBLE_RXDATA1_SHIFT (8) +#define USART_RXDOUBLE_RXDATA1_MASK (0xFF << USART_RXDOUBLE_RXDATA1_SHIFT) + +#define USART_RXDOUBLE_RXDATA0_SHIFT (0) +#define USART_RXDOUBLE_RXDATA0_MASK (0xFF << USART_RXDOUBLE_RXDATA0_SHIFT) + +/* USART_RXDATAXP */ +#define USART_RXDATAXP_FERRP (1 << 15) +#define USART_RXDATAXP_PERRP (1 << 14) + +#define USART_RXDATAXP_RXDATAP_SHIFT (0) +#define USART_RXDATAXP_RXDATAP_MASK (0x1FF << USART_RXDATAXP_RXDATAP_SHIFT) + +/* USART_RXDOUBLEXP */ +#define USART_RXDOUBLEXP_FERR1 (1 << 31) +#define USART_RXDOUBLEXP_PERR1 (1 << 30) + +#define USART_RXDOUBLEXP_RXDATA1_SHIFT (16) +#define USART_RXDOUBLEXP_RXDATA1_MASK \ + (0x1FF << USART_RXDOUBLEXP_RXDATA1_SHIFT) + +#define USART_RXDOUBLEXP_FERR0 (1 << 15) +#define USART_RXDOUBLEXP_PERR0 (1 << 14) + +#define USART_RXDOUBLEXP_RXDATA0_SHIFT (0) +#define USART_RXDOUBLEXP_RXDATA0_MASK \ + (0x1FF << USART_RXDOUBLEXP_RXDATA1_SHIFT) + +/* USART_TXDATAX */ +#define USART_TXDATAX_RXENAT (1 << 15) +#define USART_TXDATAX_TXDISAT (1 << 14) +#define USART_TXDATAX_TXBREAK (1 << 13) +#define USART_TXDATAX_TXTRIAT (1 << 12) +#define USART_TXDATAX_UBRXAT (1 << 11) + +#define USART_TXDATAX_TXDATAX_SHIFT (0) +#define USART_TXDATAX_TXDATAX_MASK (0x1FF << USART_TXDATAX_TXDATAX_SHIFT) + +/* USART_TXDOUBLEX */ +#define USART_TXDOUBLEX_RXENAT1 (1 << 31) +#define USART_TXDOUBLEX_TXDISAT1 (1 << 30) +#define USART_TXDOUBLEX_TXBREAK1 (1 << 29) +#define USART_TXDOUBLEX_TXTRIAT1 (1 << 28) +#define USART_TXDOUBLEX_UBRXAT1 (1 << 27) + +#define USART_TXDOUBLEX_TXDATA1_SHIFT (16) +#define USART_TXDOUBLEX_TXDATA1_MASK \ + (0x1FF << USART_TXDOUBLEX_TXDATA1_SHIFT) + +#define USART_TXDOUBLEX_RXENAT0 (1 << 15) +#define USART_TXDOUBLEX_TXDISAT0 (1 << 14) +#define USART_TXDOUBLEX_TXBREAK0 (1 << 13) +#define USART_TXDOUBLEX_TXTRIAT0 (1 << 12) +#define USART_TXDOUBLEX_UBRXAT0 (1 << 11) + +#define USART_TXDOUBLEX_TXDATA0_SHIFT (0) +#define USART_TXDOUBLEX_TXDATA0_MASK \ + (0x1FF << USART_TXDOUBLEX_TXDATA0_SHIFT) + +/* USART_TXDOUBLE */ +#define USART_TXDOUBLE_TXDATA1_SHIFT (8) +#define USART_TXDOUBLE_TXDATA1_MASK (0xFF << USART_TXDOUBLE_TXDATA1_SHIFT) + +#define USART_TXDOUBLE_TXDATA0_SHIFT (0) +#define USART_TXDOUBLE_TXDATA0_MASK (0xFF << USART_TXDOUBLE_TXDATA0_SHIFT) + +/* USART_IF */ +#define USART_IF_CCF (1 << 12) +#define USART_IF_SSM (1 << 11) +#define USART_IF_MPAF (1 << 10) +#define USART_IF_FERR (1 << 9) +#define USART_IF_PERR (1 << 8) +#define USART_IF_TXUF (1 << 7) +#define USART_IF_TXOF (1 << 6) +#define USART_IF_RXUF (1 << 5) +#define USART_IF_RXOF (1 << 4) +#define USART_IF_RXFULL (1 << 3) +#define USART_IF_RXDATAV (1 << 2) +#define USART_IF_TXBL (1 << 1) +#define USART_IF_TXC (1 << 0) + +/* USART_IFS */ +#define USART_IFS_CCF (1 << 12) +#define USART_IFS_SSM (1 << 11) +#define USART_IFS_MPAF (1 << 10) +#define USART_IFS_FERR (1 << 9) +#define USART_IFS_PERR (1 << 8) +#define USART_IFS_TXUF (1 << 7) +#define USART_IFS_TXOF (1 << 6) +#define USART_IFS_RXUF (1 << 5) +#define USART_IFS_RXOF (1 << 4) +#define USART_IFS_RXFULL (1 << 3) +#define USART_IFS_RXDATAV (1 << 2) +#define USART_IFS_TXBL (1 << 1) +#define USART_IFS_TXC (1 << 0) + +/* USART_IFC */ +#define USART_IFC_CCF (1 << 12) +#define USART_IFC_SSM (1 << 11) +#define USART_IFC_MPAF (1 << 10) +#define USART_IFC_FERR (1 << 9) +#define USART_IFC_PERR (1 << 8) +#define USART_IFC_TXUF (1 << 7) +#define USART_IFC_TXOF (1 << 6) +#define USART_IFC_RXUF (1 << 5) +#define USART_IFC_RXOF (1 << 4) +#define USART_IFC_RXFULL (1 << 3) +#define USART_IFC_RXDATAV (1 << 2) +#define USART_IFC_TXBL (1 << 1) +#define USART_IFC_TXC (1 << 0) + +/* USART_IEN */ +#define USART_IEN_CCF (1 << 12) +#define USART_IEN_SSM (1 << 11) +#define USART_IEN_MPAF (1 << 10) +#define USART_IEN_FERR (1 << 9) +#define USART_IEN_PERR (1 << 8) +#define USART_IEN_TXUF (1 << 7) +#define USART_IEN_TXOF (1 << 6) +#define USART_IEN_RXUF (1 << 5) +#define USART_IEN_RXOF (1 << 4) +#define USART_IEN_RXFULL (1 << 3) +#define USART_IEN_RXDATAV (1 << 2) +#define USART_IEN_TXBL (1 << 1) +#define USART_IEN_TXC (1 << 0) + +/* USART_IRCTRL */ +#define USART_IRCTRL_IRPRSEN (1 << 7) + +#define USART_IRCTRL_IRPRSSEL_SHIFT (4) +#define USART_IRCTRL_IRPRSSEL_MASK (0x7 << USART_IRCTRL_IRPRSSEL_SHIFT) +#define USART_IRCTRL_IRPRSSEL(v) \ + (((v) << USART_IRCTRL_IRPRSSEL_SHIFT) & USART_IRCTRL_IRPRSSEL_MASK) +#define USART_IRCTRL_IRPRSSEL_PRSCHx(x) USART_IRCTRL_IRPRSSEL(x) +#define USART_IRCTRL_IRPRSSEL_PRSCH0 USART_IRCTRL_IRPRSSEL_PRSCHx(0) +#define USART_IRCTRL_IRPRSSEL_PRSCH1 USART_IRCTRL_IRPRSSEL_PRSCHx(1) +#define USART_IRCTRL_IRPRSSEL_PRSCH2 USART_IRCTRL_IRPRSSEL_PRSCHx(2) +#define USART_IRCTRL_IRPRSSEL_PRSCH3 USART_IRCTRL_IRPRSSEL_PRSCHx(3) +#define USART_IRCTRL_IRPRSSEL_PRSCH4 USART_IRCTRL_IRPRSSEL_PRSCHx(4) +#define USART_IRCTRL_IRPRSSEL_PRSCH5 USART_IRCTRL_IRPRSSEL_PRSCHx(5) +#define USART_IRCTRL_IRPRSSEL_PRSCH6 USART_IRCTRL_IRPRSSEL_PRSCHx(6) +#define USART_IRCTRL_IRPRSSEL_PRSCH7 USART_IRCTRL_IRPRSSEL_PRSCHx(7) + +#define USART_IRCTRL_IRFILT (1 << 3) + +#define USART_IRCTRL_IRPW_SHIFT (1) +#define USART_IRCTRL_IRPW_MASK (0x3 << USART_IRCTRL_IRPW_SHIFT) +#define USART_IRCTRL_IRPW(v) \ + (((v) << USART_IRCTRL_IRPW_SHIFT) & USART_IRCTRL_IRPW_MASK) +#define USART_IRCTRL_IRPW_ONE USART_IRCTRL_IRPW(0) +#define USART_IRCTRL_IRPW_TWO USART_IRCTRL_IRPW(1) +#define USART_IRCTRL_IRPW_THREE USART_IRCTRL_IRPW(2) +#define USART_IRCTRL_IRPW_FOUR USART_IRCTRL_IRPW(3) + +#define USART_IRCTRL_IREN (1 << 0) + +/* USART_ROUTE */ +#define USART_ROUTE_LOCATION_SHIFT (8) +#define USART_ROUTE_LOCATION_MASK (0x7 << USART_ROUTE_LOCATION_SHIFT) +#define USART_ROUTE_LOCATION(v) \ + (((v) << USART_ROUTE_LOCATION_SHIFT) & USART_ROUTE_LOCATION_MASK) +#define USART_ROUTE_LOCATION_LOCx(x) USART_ROUTE_LOCATION(x) +#define USART_ROUTE_LOCATION_LOC0 USART_ROUTE_LOCATION_LOCx(0) +#define USART_ROUTE_LOCATION_LOC1 USART_ROUTE_LOCATION_LOCx(1) +#define USART_ROUTE_LOCATION_LOC2 USART_ROUTE_LOCATION_LOCx(2) +#define USART_ROUTE_LOCATION_LOC3 USART_ROUTE_LOCATION_LOCx(3) +#define USART_ROUTE_LOCATION_LOC4 USART_ROUTE_LOCATION_LOCx(4) +#define USART_ROUTE_LOCATION_LOC5 USART_ROUTE_LOCATION_LOCx(5) + +#define USART_ROUTE_CLKPEN (1 << 3) +#define USART_ROUTE_CSPEN (1 << 2) +#define USART_ROUTE_TXPEN (1 << 1) +#define USART_ROUTE_RXPEN (1 << 0) + +/* USART_INPUT */ +#define USART_INPUT_RXPRS (1 << 4) + +#define USART_INPUT_RXPRSSEL_SHIFT (0) +#define USART_INPUT_RXPRSSEL_MASK (0xF << USART_INPUT_RXPRSSEL_SHIFT) +#define USART_INPUT_RXPRSSEL(v) \ + (((v) << USART_INPUT_RXPRSSEL_SHIFT) & USART_INPUT_RXPRSSEL_MASK) +#define USART_INPUT_RXPRSSEL_PRSCHx(x) USART_INPUT_RXPRSSEL(x) +#define USART_INPUT_RXPRSSEL_PRSCH0 USART_INPUT_RXPRSSEL_PRSCHx(0) +#define USART_INPUT_RXPRSSEL_PRSCH1 USART_INPUT_RXPRSSEL_PRSCHx(1) +#define USART_INPUT_RXPRSSEL_PRSCH2 USART_INPUT_RXPRSSEL_PRSCHx(2) +#define USART_INPUT_RXPRSSEL_PRSCH3 USART_INPUT_RXPRSSEL_PRSCHx(3) +#define USART_INPUT_RXPRSSEL_PRSCH4 USART_INPUT_RXPRSSEL_PRSCHx(4) +#define USART_INPUT_RXPRSSEL_PRSCH5 USART_INPUT_RXPRSSEL_PRSCHx(5) +#define USART_INPUT_RXPRSSEL_PRSCH6 USART_INPUT_RXPRSSEL_PRSCHx(6) +#define USART_INPUT_RXPRSSEL_PRSCH7 USART_INPUT_RXPRSSEL_PRSCHx(7) +#define USART_INPUT_RXPRSSEL_PRSCH8 USART_INPUT_RXPRSSEL_PRSCHx(8) +#define USART_INPUT_RXPRSSEL_PRSCH9 USART_INPUT_RXPRSSEL_PRSCHx(9) +#define USART_INPUT_RXPRSSEL_PRSCH10 USART_INPUT_RXPRSSEL_PRSCHx(10) +#define USART_INPUT_RXPRSSEL_PRSCH11 USART_INPUT_RXPRSSEL_PRSCHx(11) + +/* USART_I2SCTRL */ +#define USART_I2SCTRL_FORMAT_SHIFT (8) +#define USART_I2SCTRL_FORMAT_MASK (0x7 << USART_I2SCTRL_FORMAT_SHIFT) +#define USART_I2SCTRL_FORMAT(v) \ + (((v) << USART_I2SCTRL_FORMAT_SHIFT) & USART_I2SCTRL_FORMAT_MASK) +#define USART_I2SCTRL_FORMAT_W32D32 USART_I2SCTRL_FORMAT(0) +#define USART_I2SCTRL_FORMAT_W32D24M USART_I2SCTRL_FORMAT(1) +#define USART_I2SCTRL_FORMAT_W32D24 USART_I2SCTRL_FORMAT(2) +#define USART_I2SCTRL_FORMAT_W32D16 USART_I2SCTRL_FORMAT(3) +#define USART_I2SCTRL_FORMAT_W32D8 USART_I2SCTRL_FORMAT(4) +#define USART_I2SCTRL_FORMAT_W16D16 USART_I2SCTRL_FORMAT(5) +#define USART_I2SCTRL_FORMAT_W16D8 USART_I2SCTRL_FORMAT(6) +#define USART_I2SCTRL_FORMAT_W8D8 USART_I2SCTRL_FORMAT(7) + +#define USART_I2SCTRL_DELAY (1 << 4) +#define USART_I2SCTRL_DMASPLIT (1 << 3) +#define USART_I2SCTRL_JUSTIFY (1 << 2) +#define USART_I2SCTRL_MONO (1 << 1) +#define USART_I2SCTRL_EN (1 << 0) + +/* USART0 */ +#define USART0 USART0_BASE +#define USART0_CTRL USART_CTRL(USART0) +#define USART0_FRAME USART_FRAME(USART0) +#define USART0_TRIGCTRL USART_TRIGCTRL(USART0) +#define USART0_CMD USART_CMD(USART0) +#define USART0_STATUS USART_STATUS(USART0) +#define USART0_CLKDIV USART_CLKDIV(USART0) +#define USART0_RXDATAX USART_RXDATAX(USART0) +#define USART0_RXDATA USART_RXDATA(USART0) +#define USART0_RXDOUBLEX USART_RXDOUBLEX(USART0) +#define USART0_RXDOUBLE USART_RXDOUBLE(USART0) +#define USART0_RXDATAXP USART_RXDATAXP(USART0) +#define USART0_RXDOUBLEXP USART_RXDOUBLEXP(USART0) +#define USART0_TXDATAX USART_TXDATAX(USART0) +#define USART0_TXDATA USART_TXDATA(USART0) +#define USART0_TXDOUBLEX USART_TXDOUBLEX(USART0) +#define USART0_TXDOUBLE USART_TXDOUBLE(USART0) +#define USART0_IF USART_IF(USART0) +#define USART0_IFS USART_IFS(USART0) +#define USART0_IFC USART_IFC(USART0) +#define USART0_IEN USART_IEN(USART0) +#define USART0_IRCTRL USART_IRCTRL(USART0) +#define USART0_ROUTE USART_ROUTE(USART0) +#define USART0_INPUT USART_INPUT(USART0) +#define USART0_I2SCTRL USART_I2SCTRL(USART0) + +/* USART1 */ +#define USART1 USART1_BASE +#define USART1_CTRL USART_CTRL(USART1) +#define USART1_FRAME USART_FRAME(USART1) +#define USART1_TRIGCTRL USART_TRIGCTRL(USART1) +#define USART1_CMD USART_CMD(USART1) +#define USART1_STATUS USART_STATUS(USART1) +#define USART1_CLKDIV USART_CLKDIV(USART1) +#define USART1_RXDATAX USART_RXDATAX(USART1) +#define USART1_RXDATA USART_RXDATA(USART1) +#define USART1_RXDOUBLEX USART_RXDOUBLEX(USART1) +#define USART1_RXDOUBLE USART_RXDOUBLE(USART1) +#define USART1_RXDATAXP USART_RXDATAXP(USART1) +#define USART1_RXDOUBLEXP USART_RXDOUBLEXP(USART1) +#define USART1_TXDATAX USART_TXDATAX(USART1) +#define USART1_TXDATA USART_TXDATA(USART1) +#define USART1_TXDOUBLEX USART_TXDOUBLEX(USART1) +#define USART1_TXDOUBLE USART_TXDOUBLE(USART1) +#define USART1_IF USART_IF(USART1) +#define USART1_IFS USART_IFS(USART1) +#define USART1_IFC USART_IFC(USART1) +#define USART1_IEN USART_IEN(USART1) +#define USART1_IRCTRL USART_IRCTRL(USART1) +#define USART1_ROUTE USART_ROUTE(USART1) +#define USART1_INPUT USART_INPUT(USART1) +#define USART1_I2SCTRL USART_I2SCTRL(USART1) + +/* USART2 */ +#define USART2 USART2_BASE +#define USART2_CTRL USART_CTRL(USART2) +#define USART2_FRAME USART_FRAME(USART2) +#define USART2_TRIGCTRL USART_TRIGCTRL(USART2) +#define USART2_CMD USART_CMD(USART2) +#define USART2_STATUS USART_STATUS(USART2) +#define USART2_CLKDIV USART_CLKDIV(USART2) +#define USART2_RXDATAX USART_RXDATAX(USART2) +#define USART2_RXDATA USART_RXDATA(USART2) +#define USART2_RXDOUBLEX USART_RXDOUBLEX(USART2) +#define USART2_RXDOUBLE USART_RXDOUBLE(USART2) +#define USART2_RXDATAXP USART_RXDATAXP(USART2) +#define USART2_RXDOUBLEXP USART_RXDOUBLEXP(USART2) +#define USART2_TXDATAX USART_TXDATAX(USART2) +#define USART2_TXDATA USART_TXDATA(USART2) +#define USART2_TXDOUBLEX USART_TXDOUBLEX(USART2) +#define USART2_TXDOUBLE USART_TXDOUBLE(USART2) +#define USART2_IF USART_IF(USART2) +#define USART2_IFS USART_IFS(USART2) +#define USART2_IFC USART_IFC(USART2) +#define USART2_IEN USART_IEN(USART2) +#define USART2_IRCTRL USART_IRCTRL(USART2) +#define USART2_ROUTE USART_ROUTE(USART2) +#define USART2_INPUT USART_INPUT(USART2) +#define USART2_I2SCTRL USART_I2SCTRL(USART2) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usb.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usb.h new file mode 100644 index 00000000..891edbfb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/usb.h @@ -0,0 +1,369 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_USB_H +#define LIBOPENCM3_EFM32_USB_H + +#include +#include + +#define USB_CTRL MMIO32(USB_BASE + 0x000) +#define USB_STATUS MMIO32(USB_BASE + 0x004) +#define USB_IF MMIO32(USB_BASE + 0x008) +#define USB_IFS MMIO32(USB_BASE + 0x00C) +#define USB_IFC MMIO32(USB_BASE + 0x010) +#define USB_IEN MMIO32(USB_BASE + 0x014) +#define USB_ROUTE MMIO32(USB_BASE + 0x018) + +/* USB_CTRL */ +#define USB_CTRL_DMPUAP (1 << 1) + +/* USB_ROUTE */ +#define USB_ROUTE_DMPUPEN (1 << 2) +#define USB_ROUTE_VBUSENPEN (1 << 1) +#define USB_ROUTE_PHYPEN (1 << 0) + +/* Core Global Control and Status Registers */ +#define USB_OTG_BASE (USB_BASE + 0x3C000) +#define USB_GOTGCTL MMIO32(USB_OTG_BASE + 0x000) +#define USB_GOTGINT MMIO32(USB_OTG_BASE + 0x004) +#define USB_GAHBCFG MMIO32(USB_OTG_BASE + 0x008) +#define USB_GUSBCFG MMIO32(USB_OTG_BASE + 0x00C) +#define USB_GRSTCTL MMIO32(USB_OTG_BASE + 0x010) +#define USB_GINTSTS MMIO32(USB_OTG_BASE + 0x014) +#define USB_GINTMSK MMIO32(USB_OTG_BASE + 0x018) +#define USB_GRXSTSR MMIO32(USB_OTG_BASE + 0x01C) +#define USB_GRXSTSP MMIO32(USB_OTG_BASE + 0x020) +#define USB_GRXFSIZ MMIO32(USB_OTG_BASE + 0x024) +#define USB_GNPTXFSIZ MMIO32(USB_OTG_BASE + 0x028) +#define USB_GNPTXSTS MMIO32(USB_OTG_BASE + 0x02C) +#define USB_GDFIFOCFG MMIO32(USB_OTG_BASE + 0x05C) +#define USB_HPTXFSIZ MMIO32(USB_OTG_BASE + 0x100) +#define USB_DIEPTXF(x) \ + MMIO32(USB_OTG_BASE + 0x104 + (4 * ((x) - 1))) + +/* Host-mode Control and Status Registers */ +#define USB_HCFG MMIO32(USB_OTG_BASE + 0x400) +#define USB_HFIR MMIO32(USB_OTG_BASE + 0x404) +#define USB_HFNUM MMIO32(USB_OTG_BASE + 0x408) +#define USB_HPTXSTS MMIO32(USB_OTG_BASE + 0x410) +#define USB_HAINT MMIO32(USB_OTG_BASE + 0x414) +#define USB_HAINTMSK MMIO32(USB_OTG_BASE + 0x418) +#define USB_HPRT MMIO32(USB_OTG_BASE + 0x440) +#define USB_HCx_CHAR(x) \ + MMIO32(USB_OTG_BASE + 0x500 + ((x) * 0x20)) +#define USB_HCx_INT(x) \ + MMIO32(USB_OTG_BASE + 0x508 + ((x) * 0x20)) +#define USB_HCx_INTMSK(x) \ + MMIO32(USB_OTG_BASE + 0x50C + ((x) * 0x20)) +#define USB_HCx_TSIZ(x) \ + MMIO32(USB_OTG_BASE + 0x510 + ((x) * 0x20)) +#define USB_HCx_DMAADDR(x) \ + MMIO32(USB_OTG_BASE + 0x514 + ((x) * 0x20)) + +/* Device-mode Control and Status Registers */ +#define USB_DCFG MMIO32(USB_OTG_BASE + 0x800) +#define USB_DCTL MMIO32(USB_OTG_BASE + 0x804) +#define USB_DSTS MMIO32(USB_OTG_BASE + 0x808) +#define USB_DIEPMSK MMIO32(USB_OTG_BASE + 0x810) +#define USB_DOEPMSK MMIO32(USB_OTG_BASE + 0x814) +#define USB_DAINT MMIO32(USB_OTG_BASE + 0x818) +#define USB_DAINTMSK MMIO32(USB_OTG_BASE + 0x81C) +#define USB_DVBUSDIS MMIO32(USB_OTG_BASE + 0x828) +#define USB_DVBUSPULSE MMIO32(USB_OTG_BASE + 0x82C) +#define USB_DIEPEMPMSK MMIO32(USB_OTG_BASE + 0x834) + +#define USB_DIEPx_CTL(x) \ + MMIO32(USB_OTG_BASE + 0x900 + ((x) * 0x20)) +#define USB_DIEPx_INT(x) \ + MMIO32(USB_OTG_BASE + 0x908 + ((x) * 0x20)) +#define USB_DIEPx_TSIZ(x) \ + MMIO32(USB_OTG_BASE + 0x910 + ((x) * 0x20)) +#define USB_DIEP0CTL USB_DIEPx_CTL(0) +#define USB_DIEP0TSIZ USB_DIEPx_TSIZ(0) +#define USB_DIEP0INT USB_DIEPx_INT(0) + +#define USB_DOEPx_CTL(x) \ + MMIO32(USB_OTG_BASE + 0xB00 + ((x) * 0x20)) +#define USB_DOEPx_INT(x) \ + MMIO32(USB_OTG_BASE + 0xB08 + ((x) * 0x20)) +#define USB_DOEPx_TSIZ(x) \ + MMIO32(USB_OTG_BASE + 0xB10 + ((x) * 0x20)) +#define USB_DOEP0CTL USB_DOEPx_CTL(0) +#define USB_DOEP0TSIZ USB_DOEPx_TSIZ(0) +#define USB_DOEP0INT USB_DOEPx_INT(0) + +/* Power and clock gating control and status register */ +#define USB_PCGCCTL MMIO32(USB_OTG_BASE + 0xE00) + +/* Data FIFO */ +#define USB_FIFOxD(x) \ + (&MMIO32(USB_OTG_BASE + (((x) + 1) << 12))) + +/* Global CSRs */ +/* USB control registers (OTG_HS_GOTGCTL) */ +#define USB_GOTGCTL_BSVLD (1 << 19) +#define USB_GOTGCTL_ASVLD (1 << 18) +#define USB_GOTGCTL_DBCT (1 << 17) +#define USB_GOTGCTL_CIDSTS (1 << 16) +#define USB_GOTGCTL_DHNPEN (1 << 11) +#define USB_GOTGCTL_HSHNPEN (1 << 10) +#define USB_GOTGCTL_HNPRQ (1 << 9) +#define USB_GOTGCTL_HNGSCS (1 << 8) +#define USB_GOTGCTL_SRQ (1 << 1) +#define USB_GOTGCTL_SRQSCS (1 << 0) + +/* AHB configuration register (USB_GAHBCFG) */ +#define USB_GAHBCFG_GLBLINTRMSK 0x0001 +#define USB_GAHBCFG_TXFELVL 0x0080 +#define USB_GAHBCFG_PTXFELVL 0x0100 + +/* USB configuration register (USB_GUSBCFG) */ +#define USB_GUSBCFG_TOCAL 0x00000003 +#define USB_GUSBCFG_SRPCAP 0x00000100 +#define USB_GUSBCFG_HNPCAP 0x00000200 +#define USB_GUSBCFG_TRDT_MASK (0xf << 10) +#define USB_GUSBCFG_TRDT_16BIT (0x5 << 10) +#define USB_GUSBCFG_TRDT_8BIT (0x9 << 10) +#define USB_GUSBCFG_NPTXRWEN 0x00004000 +#define USB_GUSBCFG_FHMOD 0x20000000 +#define USB_GUSBCFG_FDMOD 0x40000000 +#define USB_GUSBCFG_CTXPKT 0x80000000 +#define USB_GUSBCFG_PHYSEL (1 << 7) + +/* reset register (USB_GRSTCTL) */ +#define USB_GRSTCTL_AHBIDL (1 << 31) +/* Bits 30:11 - Reserved */ +#define USB_GRSTCTL_TXFNUM_MASK (0x1f << 6) +#define USB_GRSTCTL_TXFFLSH (1 << 5) +#define USB_GRSTCTL_RXFFLSH (1 << 4) +/* Bit 3 - Reserved */ +#define USB_GRSTCTL_FCRST (1 << 2) +#define USB_GRSTCTL_HSRST (1 << 1) +#define USB_GRSTCTL_CSRST (1 << 0) + +/* interrupt status register (USB_GINTSTS) */ +#define USB_GINTSTS_WKUPINT (1 << 31) +#define USB_GINTSTS_SRQINT (1 << 30) +#define USB_GINTSTS_DISCINT (1 << 29) +#define USB_GINTSTS_CIDSCHG (1 << 28) +/* Bit 27 - Reserved */ +#define USB_GINTSTS_PTXFE (1 << 26) +#define USB_GINTSTS_HCINT (1 << 25) +#define USB_GINTSTS_HPRTINT (1 << 24) +/* Bits 23:22 - Reserved */ +#define USB_GINTSTS_IPXFR (1 << 21) +#define USB_GINTSTS_INCOMPISOOUT (1 << 21) +#define USB_GINTSTS_IISOIXFR (1 << 20) +#define USB_GINTSTS_OEPINT (1 << 19) +#define USB_GINTSTS_IEPINT (1 << 18) +/* Bits 17:16 - Reserved */ +#define USB_GINTSTS_EOPF (1 << 15) +#define USB_GINTSTS_ISOODRP (1 << 14) +#define USB_GINTSTS_ENUMDNE (1 << 13) +#define USB_GINTSTS_USBRST (1 << 12) +#define USB_GINTSTS_USBSUSP (1 << 11) +#define USB_GINTSTS_ESUSP (1 << 10) +/* Bits 9:8 - Reserved */ +#define USB_GINTSTS_GONAKEFF (1 << 7) +#define USB_GINTSTS_GINAKEFF (1 << 6) +#define USB_GINTSTS_NPTXFE (1 << 5) +#define USB_GINTSTS_RXFLVL (1 << 4) +#define USB_GINTSTS_SOF (1 << 3) +#define USB_GINTSTS_OTGINT (1 << 2) +#define USB_GINTSTS_MMIS (1 << 1) +#define USB_GINTSTS_CMOD (1 << 0) + +/* interrupt mask register (USB_GINTMSK) */ +#define USB_GINTMSK_MMISM 0x00000002 +#define USB_GINTMSK_OTGINT 0x00000004 +#define USB_GINTMSK_SOFM 0x00000008 +#define USB_GINTMSK_RXFLVLM 0x00000010 +#define USB_GINTMSK_NPTXFEM 0x00000020 +#define USB_GINTMSK_GINAKEFFM 0x00000040 +#define USB_GINTMSK_GONAKEFFM 0x00000080 +#define USB_GINTMSK_ESUSPM 0x00000400 +#define USB_GINTMSK_USBSUSPM 0x00000800 +#define USB_GINTMSK_USBRST 0x00001000 +#define USB_GINTMSK_ENUMDNEM 0x00002000 +#define USB_GINTMSK_ISOODRPM 0x00004000 +#define USB_GINTMSK_EOPFM 0x00008000 +#define USB_GINTMSK_EPMISM 0x00020000 +#define USB_GINTMSK_IEPINT 0x00040000 +#define USB_GINTMSK_OEPINT 0x00080000 +#define USB_GINTMSK_IISOIXFRM 0x00100000 +#define USB_GINTMSK_IISOOXFRM 0x00200000 +#define USB_GINTMSK_IPXFRM 0x00200000 +#define USB_GINTMSK_PRTIM 0x01000000 +#define USB_GINTMSK_HCIM 0x02000000 +#define USB_GINTMSK_PTXFEM 0x04000000 +#define USB_GINTMSK_CIDSCHGM 0x10000000 +#define USB_GINTMSK_DISCINT 0x20000000 +#define USB_GINTMSK_SRQIM 0x40000000 +#define USB_GINTMSK_WUIM 0x80000000 + +/* Receive Status Pop Register (USB_GRXSTSP) */ +/* Bits 31:25 - Reserved */ +#define USB_GRXSTSP_FRMNUM_MASK (0xf << 21) +#define USB_GRXSTSP_PKTSTS_MASK (0xf << 17) +#define USB_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) +#define USB_GRXSTSP_PKTSTS_OUT (0x2 << 17) +#define USB_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) +#define USB_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17) +#define USB_GRXSTSP_PKTSTS_SETUP (0x6 << 17) +#define USB_GRXSTSP_DPID_MASK (0x3 << 15) +#define USB_GRXSTSP_DPID_DATA0 (0x0 << 15) +#define USB_GRXSTSP_DPID_DATA1 (0x2 << 15) +#define USB_GRXSTSP_DPID_DATA2 (0x1 << 15) +#define USB_GRXSTSP_DPID_MDATA (0x3 << 15) +#define USB_GRXSTSP_BCNT_MASK (0x7ff << 4) +#define USB_GRXSTSP_EPNUM_MASK (0xf << 0) + +/* general core configuration register (USB_GCCFG) */ +/* Bits 31:22 - Reserved */ +#define USB_GCCFG_NOVBUSSENS (1 << 21) +#define USB_GCCFG_SOFOUTEN (1 << 20) +#define USB_GCCFG_VBUSBSEN (1 << 19) +#define USB_GCCFG_VBUSASEN (1 << 18) +/* Bit 17 - Reserved */ +#define USB_GCCFG_PWRDWN (1 << 16) +/* Bits 15:0 - Reserved */ + + +/* Device-mode CSRs */ +/* device control register (USB_DCTL) */ +/* Bits 31:12 - Reserved */ +#define USB_DCTL_POPRGDNE (1 << 11) +#define USB_DCTL_CGONAK (1 << 10) +#define USB_DCTL_SGONAK (1 << 9) +#define USB_DCTL_SGINAK (1 << 8) +#define USB_DCTL_TCTL_MASK (7 << 4) +#define USB_DCTL_GONSTS (1 << 3) +#define USB_DCTL_GINSTS (1 << 2) +#define USB_DCTL_SDIS (1 << 1) +#define USB_DCTL_RWUSIG (1 << 0) + +/* device configuration register (USB_DCFG) */ +#define USB_DCFG_DSPD 0x0003 +#define USB_DCFG_NZLSOHSK 0x0004 +#define USB_DCFG_DAD 0x07F0 +#define USB_DCFG_PFIVL 0x1800 + +/* Device IN Endpoint Common Interrupt Mask Register (USB_DIEPMSK) */ +/* Bits 31:10 - Reserved */ +#define USB_DIEPMSK_BIM (1 << 9) +#define USB_DIEPMSK_TXFURM (1 << 8) +/* Bit 7 - Reserved */ +#define USB_DIEPMSK_INEPNEM (1 << 6) +#define USB_DIEPMSK_INEPNMM (1 << 5) +#define USB_DIEPMSK_ITTXFEMSK (1 << 4) +#define USB_DIEPMSK_TOM (1 << 3) +/* Bit 2 - Reserved */ +#define USB_DIEPMSK_EPDM (1 << 1) +#define USB_DIEPMSK_XFRCM (1 << 0) + +/* Device OUT Endpoint Common Interrupt Mask Register (USB_DOEPMSK) */ +/* Bits 31:10 - Reserved */ +#define USB_DOEPMSK_BOIM (1 << 9) +#define USB_DOEPMSK_OPEM (1 << 8) +/* Bit 7 - Reserved */ +#define USB_DOEPMSK_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define USB_DOEPMSK_OTEPDM (1 << 4) +#define USB_DOEPMSK_STUPM (1 << 3) +/* Bit 2 - Reserved */ +#define USB_DOEPMSK_EPDM (1 << 1) +#define USB_DOEPMSK_XFRCM (1 << 0) + +/* Device Control IN Endpoint 0 Control Register (USB_DIEP0CTL) */ +#define USB_DIEP0CTL_EPENA (1 << 31) +#define USB_DIEP0CTL_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define USB_DIEP0CTL_SD0PID (1 << 28) +#define USB_DIEP0CTL_SNAK (1 << 27) +#define USB_DIEP0CTL_CNAK (1 << 26) +#define USB_DIEP0CTL_TXFNUM_MASK (0xf << 22) +#define USB_DIEP0CTL_STALL (1 << 21) +/* Bit 20 - Reserved */ +#define USB_DIEP0CTL_EPTYP_MASK (0x3 << 18) +#define USB_DIEP0CTL_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define USB_DIEP0CTL_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define USB_DIEP0CTL_MPSIZ_MASK (0x3 << 0) +#define USB_DIEP0CTL_MPSIZ_64 (0x0 << 0) +#define USB_DIEP0CTL_MPSIZ_32 (0x1 << 0) +#define USB_DIEP0CTL_MPSIZ_16 (0x2 << 0) +#define USB_DIEP0CTL_MPSIZ_8 (0x3 << 0) + +/* Device Control OUT Endpoint 0 Control Register (USB_DOEP0CTL) */ +#define USB_DOEP0CTL_EPENA (1 << 31) +#define USB_DOEP0CTL_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define USB_DOEP0CTL_SD0PID (1 << 28) +#define USB_DOEP0CTL_SNAK (1 << 27) +#define USB_DOEP0CTL_CNAK (1 << 26) +/* Bits 25:22 - Reserved */ +#define USB_DOEP0CTL_STALL (1 << 21) +#define USB_DOEP0CTL_SNPM (1 << 20) +#define USB_DOEP0CTL_EPTYP_MASK (0x3 << 18) +#define USB_DOEP0CTL_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define USB_DOEP0CTL_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define USB_DOEP0CTL_MPSIZ_MASK (0x3 << 0) +#define USB_DOEP0CTL_MPSIZ_64 (0x0 << 0) +#define USB_DOEP0CTL_MPSIZ_32 (0x1 << 0) +#define USB_DOEP0CTL_MPSIZ_16 (0x2 << 0) +#define USB_DOEP0CTL_MPSIZ_8 (0x3 << 0) + +/* Device IN Endpoint Interrupt Register (USB_DIEPINTx) */ +/* Bits 31:8 - Reserved */ +#define USB_DIEP_INT_TXFE (1 << 7) +#define USB_DIEP_INT_INEPNE (1 << 6) +/* Bit 5 - Reserved */ +#define USB_DIEP_INT_ITTXFE (1 << 4) +#define USB_DIEP_INT_TOC (1 << 3) +/* Bit 2 - Reserved */ +#define USB_DIEP_INT_EPDISD (1 << 1) +#define USB_DIEP_INT_XFRC (1 << 0) + +/* Device IN Endpoint Interrupt Register (USB_DOEPINTx) */ +/* Bits 31:7 - Reserved */ +#define USB_DOEP_INT_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define USB_DOEP_INT_OTEPDIS (1 << 4) +#define USB_DOEP_INT_SETUP (1 << 3) +/* Bit 2 - Reserved */ +#define USB_DOEP_INT_EPDISD (1 << 1) +#define USB_DOEP_INT_XFRC (1 << 0) + +/* Device OUT Endpoint 0 Transfer Size Register (USB_DOEP0TSIZ) */ +/* Bit 31 - Reserved */ +#define USB_DIEP0TSIZ_STUPCNT_1 (0x1 << 29) +#define USB_DIEP0TSIZ_STUPCNT_2 (0x2 << 29) +#define USB_DIEP0TSIZ_STUPCNT_3 (0x3 << 29) +#define USB_DIEP0TSIZ_STUPCNT_MASK (0x3 << 29) +/* Bits 28:20 - Reserved */ +#define USB_DIEP0TSIZ_PKTCNT (1 << 19) +/* Bits 18:7 - Reserved */ +#define USB_DIEP0TSIZ_XFRSIZ_MASK (0x7f << 0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/wdog.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/wdog.h new file mode 100644 index 00000000..552ad444 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/lg/wdog.h @@ -0,0 +1,76 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EFM32_WDOG_H +#define LIBOPENCM3_EFM32_WDOG_H + +#include +#include + +#define WDOG_CTRL MMIO32(WDOG_BASE + 0x000) +#define WDOG_CMD MMIO32(WDOG_BASE + 0x004) +#define WDOG_SYNCBUSY MMIO32(WDOG_BASE + 0x008) + +/* WDOG_CTRL */ +#define WDOG_CTRL_CLKSEL_SHIFT (12) +#define WDOG_CTRL_CLKSEL_MASK (0x3 << WDOG_CTRL_CLKSEL_SHIFT) +#define WDOG_CTRL_CLKSEL(v) \ + (((v) << WDOG_CTRL_CLKSEL_SHIFT) & WDOG_CTRL_CLKSEL_MASK) +#define WDOG_CTRL_CLKSEL_ULFRCO WDOG_CTRL_CLKSEL(0) +#define WDOG_CTRL_CLKSEL_LFRCO WDOG_CTRL_CLKSEL(1) +#define WDOG_CTRL_CLKSEL_LFXO WDOG_CTRL_CLKSEL(2) + +#define WDOG_CTRL_PERSEL_SHIFT (8) +#define WDOG_CTRL_PERSEL_MASK (0xF << WDOG_CTRL_PERSEL_SHIFT) +#define WDOG_CTRL_PERSEL(v) \ + (((v) << WDOG_CTRL_PERSEL_SHIFT) & WDOG_CTRL_PERSEL_MASK) +#define WDOG_CTRL_PERSEL_9CYCLES WDOG_CTRL_PERSEL(0) +#define WDOG_CTRL_PERSEL_17CYCLES WDOG_CTRL_PERSEL(1) +#define WDOG_CTRL_PERSEL_33CYCLES WDOG_CTRL_PERSEL(2) +#define WDOG_CTRL_PERSEL_65CYCLES WDOG_CTRL_PERSEL(3) +#define WDOG_CTRL_PERSEL_129CYCLES WDOG_CTRL_PERSEL(4) +#define WDOG_CTRL_PERSEL_257CYCLES WDOG_CTRL_PERSEL(5) +#define WDOG_CTRL_PERSEL_513CYCLES WDOG_CTRL_PERSEL(6) +#define WDOG_CTRL_PERSEL_1KCYCLES WDOG_CTRL_PERSEL(7) +#define WDOG_CTRL_PERSEL_2KCYCLES WDOG_CTRL_PERSEL(8) +#define WDOG_CTRL_PERSEL_4KCYCLES WDOG_CTRL_PERSEL(9) +#define WDOG_CTRL_PERSEL_8KCYCLES WDOG_CTRL_PERSEL(10) +#define WDOG_CTRL_PERSEL_16KCYCLES WDOG_CTRL_PERSEL(11) +#define WDOG_CTRL_PERSEL_32KCYCLES WDOG_CTRL_PERSEL(12) +#define WDOG_CTRL_PERSEL_64KCYCLES WDOG_CTRL_PERSEL(13) +#define WDOG_CTRL_PERSEL_128KCYCLES WDOG_CTRL_PERSEL(14) +#define WDOG_CTRL_PERSEL_256KCYCLES WDOG_CTRL_PERSEL(15) + +#define WDOG_CTRL_SWOSCBLOCK (1 << 6) +#define WDOG_CTRL_EM4BLOCK (1 << 5) +#define WDOG_CTRL_LOCK (1 << 4) +#define WDOG_CTRL_EM3RUN (1 << 3) +#define WDOG_CTRL_EM2RUN (1 << 2) +#define WDOG_CTRL_DEBUGRUN (1 << 1) +#define WDOG_CTRL_EN (1 << 0) + +/* WDOG_CMD */ +#define WDOG_CMD_CLEAR (1 << 0) + +/* WDOG_SYNCBUSY */ +#define WDOG_SYNCBUSY_CMD (1 << 1) +#define WDOG_SYNCBUSY_CTRL (1 << 0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/memorymap.h new file mode 100644 index 00000000..6c9e3b8c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/memorymap.h @@ -0,0 +1,36 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @file + * + * Dispatcher for the base address definitions, depending on the particular + * Gecko family. + * + * @see efm32tg/memorymap.h + * @see efm32lg/memorymap.h + */ + +#if defined(EFM32TG) +# include +#elif defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/msc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/msc.h new file mode 100644 index 00000000..347b5be5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/msc.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/opamp.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/opamp.h new file mode 100644 index 00000000..dbb1f844 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/opamp.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/prs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/prs.h new file mode 100644 index 00000000..14ef9b2b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/prs.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rmu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rmu.h new file mode 100644 index 00000000..82328877 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rmu.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rtc.h new file mode 100644 index 00000000..a3e21776 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/rtc.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/doc-efm32tg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/doc-efm32tg.h new file mode 100644 index 00000000..799048cd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/doc-efm32tg.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 EFM32 Tiny Gecko + +@version 1.0.0 + +@date 4 March 2013 + +API documentation for Energy Micro EFM32 Tiny Gecko Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32TG EFM32 TinyGecko +Libraries for Energy Micro EFM32 Tiny Gecko series. + +@version 1.0.0 + +@date 4 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup EFM32TG_defines EFM32 Tiny Gecko Defines + +@brief Defined Constants and Types for the Energy Micro EFM32 Tiny Gecko series + +@version 1.0.0 + +@date 4 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/irq.json new file mode 100644 index 00000000..95efa85e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/irq.json @@ -0,0 +1,31 @@ +{ + "_source": "The names and sequence are taken from d0034_efm32tg_reference_manual.pdf table 4.1.", + "irqs": [ + "dma", + "gpio_even", + "timer0", + "usart0_rx", + "usart0_tx", + "acmp01", + "adc0", + "dac0", + "i2c0", + "gpio_odd", + "timer1", + "usart1_rx", + "usart1_tx", + "lesense", + "leuart0", + "letimer0", + "pcnt0", + "rtc", + "cmu", + "vcmp", + "lcd", + "msc", + "aes" + ], + "partname_humanreadable": "EFM32 Tiny Gecko series", + "partname_doxygen": "EFM32TG", + "includeguard": "LIBOPENCM3_EFM32TG_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/memorymap.h new file mode 100644 index 00000000..d17bb60c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/tg/memorymap.h @@ -0,0 +1,76 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @file + * + * Layout of the system address space of Tiny Gecko devices. + * + * This reflects d0034_efm32tg_reference_manual.pdf figure 5.2. + */ + +/* The common cortex-m3 definitions were verified from + * d0034_efm32tg_reference_manual.pdf figure 5.2. The CM3 ROM Table seems to be + * missing there. The details (everything based on SCS_BASE) was verified from + * d0002_efm32_cortex-m3_reference_manual.pdf table 4.1, and seems to fit, but + * there are discrepancies. */ +#include + +#define CODE_BASE (0x00000000U) + +#define SRAM_BASE (0x20000000U) +#define SRAM_BASE_BITBAND (0x22000000U) + +#define PERIPH_BASE (0x40000000U) +#define PERIPH_BASE_BITBAND (0x42000000U) + +/* Details of the "Code" section */ + +#define FLASH_BASE (CODE_BASE + 0x00000000) +#define USERDATA_BASE (CODE_BASE + 0x0fe00000) +#define LOCKBITS_BASE (CODE_BASE + 0x0fe04000) +#define CHIPCONFIG_BASE (CODE_BASE + 0x0fe08000) +#define CODESPACESRAM_BASE (CODE_BASE + 0x10000000) + +/* Tiny Gecko peripherial definitions */ + +#define VCMP_BASE (PERIPH_BASE + 0x00000000) +#define ACMP0_BASE (PERIPH_BASE + 0x00001000) +#define ACMP1_BASE (PERIPH_BASE + 0x00001400) +#define ADC_BASE (PERIPH_BASE + 0x00002000) +#define DAC0_BASE (PERIPH_BASE + 0x00004000) +#define GPIO_BASE (PERIPH_BASE + 0x00006000) /**< @see gpio.h */ +#define I2C0_BASE (PERIPH_BASE + 0x0000a000) +#define USART0_BASE (PERIPH_BASE + 0x0000c000) +#define USART1_BASE (PERIPH_BASE + 0x0000c400) +#define TIMER0_BASE (PERIPH_BASE + 0x00010000) +#define TIMER1_BASE (PERIPH_BASE + 0x00010400) +#define RTC_BASE (PERIPH_BASE + 0x00080000) +#define LETIMER0_BASE (PERIPH_BASE + 0x00082000) +#define LEUART0_BASE (PERIPH_BASE + 0x00084000) +#define PCNT0_BASE (PERIPH_BASE + 0x00086000) +#define WDOG_BASE (PERIPH_BASE + 0x00088000) +#define LCD_BASE (PERIPH_BASE + 0x0008a000) +#define LESENSE_BASE (PERIPH_BASE + 0x0008c000) +#define MSC_BASE (PERIPH_BASE + 0x000c0000) +#define DMA_BASE (PERIPH_BASE + 0x000c2000) +#define EMU_BASE (PERIPH_BASE + 0x000c6000) +#define CMU_BASE (PERIPH_BASE + 0x000c8000) /**< @see cmu.h */ +#define RMU_BASE (PERIPH_BASE + 0x000ca000) +#define PRS_BASE (PERIPH_BASE + 0x000cc000) +#define AES_BASE (PERIPH_BASE + 0x000e0000) diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/timer.h new file mode 100644 index 00000000..bb717d09 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/timer.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/uart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/uart.h new file mode 100644 index 00000000..42a22987 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/uart.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usart.h new file mode 100644 index 00000000..af109b12 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usart.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usb.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usb.h new file mode 100644 index 00000000..ce72c237 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/usb.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/wdog.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/wdog.h new file mode 100644 index 00000000..98ba09fc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/efm32/wdog.h @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#el defined(EFM32LG) +# include +#else +# error "efm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac.h new file mode 100644 index 00000000..b047e4db --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac.h @@ -0,0 +1,46 @@ +/** @defgroup ethernet_mac_defines MAC Generic Defines + * + * @brief Defined Constants and Types for the Ethernet MAC + * + * @ingroup ETH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#if defined(STM32F1) +# include +#elif defined(STM32F4) +# include +#else +# error "stm32 family not defined." +#endif + +/**@}*/ + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac_stm32fxx7.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac_stm32fxx7.h new file mode 100644 index 00000000..881e822a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/mac_stm32fxx7.h @@ -0,0 +1,752 @@ +/** @defgroup ethernet_mac_stm32fxx7_defines MAC STM32Fxx7 Defines + * + * @brief Defined Constants and Types for the Ethernet MAC for STM32Fxx7 + * chips + * + * @ingroup ETH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ETHERNET_H +#define LIBOPENCM3_ETHERNET_H + +#include +#include + +/**@{*/ + +/* Ethernet MAC registers */ +#define ETH_MACCR MMIO32(ETHERNET_BASE + 0x00) +#define ETH_MACFFR MMIO32(ETHERNET_BASE + 0x04) +#define ETH_MACHTHR MMIO32(ETHERNET_BASE + 0x08) +#define ETH_MACHTLR MMIO32(ETHERNET_BASE + 0x0C) +#define ETH_MACMIIAR MMIO32(ETHERNET_BASE + 0x10) +#define ETH_MACMIIDR MMIO32(ETHERNET_BASE + 0x14) +#define ETH_MACFCR MMIO32(ETHERNET_BASE + 0x18) +#define ETH_MACVLANTR MMIO32(ETHERNET_BASE + 0x1C) +#define ETH_MACRWUFFR MMIO32(ETHERNET_BASE + 0x28) +#define ETH_MACPMTCSR MMIO32(ETHERNET_BASE + 0x2C) +/* not available on F1 ?*/ +#define ETH_MACDBGR MMIO32(ETHERNET_BASE + 0x34) +#define ETH_MACSR MMIO32(ETHERNET_BASE + 0x38) +#define ETH_MACIMR MMIO32(ETHERNET_BASE + 0x3C) + +/* i=[0..3] */ +#define ETH_MACAHR(i) MMIO32(ETHERNET_BASE + 0x40+(i)*8) +/* i=[0..3] */ +#define ETH_MACALR(i) MMIO32(ETHERNET_BASE + 0x44+(i)*8) + +/* Ethernet MMC registers */ +#define ETH_MMCCR MMIO32(ETHERNET_BASE + 0x100) +#define ETH_MMCRIR MMIO32(ETHERNET_BASE + 0x104) +#define ETH_MMCTIR MMIO32(ETHERNET_BASE + 0x108) +#define ETH_MMCRIMR MMIO32(ETHERNET_BASE + 0x10C) +#define ETH_MMCTIMR MMIO32(ETHERNET_BASE + 0x110) +#define ETH_MMCTGFSCCR MMIO32(ETHERNET_BASE + 0x14C) +#define ETH_MMCTGFMSCCR MMIO32(ETHERNET_BASE + 0x150) +#define ETH_MMCTGFCR MMIO32(ETHERNET_BASE + 0x168) +#define ETH_MMCRFCECR MMIO32(ETHERNET_BASE + 0x194) +#define ETH_MMCRFAECR MMIO32(ETHERNET_BASE + 0x198) +#define ETH_MMCRGUFCR MMIO32(ETHERNET_BASE + 0x1C4) + +/* Ethrenet IEEE 1588 time stamp registers */ +#define ETH_PTPTSCR MMIO32(ETHERNET_BASE + 0x700) +#define ETH_PTPSSIR MMIO32(ETHERNET_BASE + 0x704) +#define ETH_PTPTSHR MMIO32(ETHERNET_BASE + 0x708) +#define ETH_PTPTSLR MMIO32(ETHERNET_BASE + 0x70C) +#define ETH_PTPTSHUR MMIO32(ETHERNET_BASE + 0x710) +#define ETH_PTPTSLUR MMIO32(ETHERNET_BASE + 0x714) +#define ETH_PTPTSAR MMIO32(ETHERNET_BASE + 0x718) +#define ETH_PTPTTHR MMIO32(ETHERNET_BASE + 0x71C) +#define ETH_PTPTTLR MMIO32(ETHERNET_BASE + 0x720) +/* not available on F1 ?*/ +#define ETH_PTPTSSR MMIO32(ETHERNET_BASE + 0x728) + +/* Ethernet DMA registers */ +#define ETH_DMABMR MMIO32(ETHERNET_BASE + 0x1000) +#define ETH_DMATPDR MMIO32(ETHERNET_BASE + 0x1004) +#define ETH_DMARPDR MMIO32(ETHERNET_BASE + 0x1008) +#define ETH_DMARDLAR MMIO32(ETHERNET_BASE + 0x100C) +#define ETH_DMATDLAR MMIO32(ETHERNET_BASE + 0x1010) +#define ETH_DMASR MMIO32(ETHERNET_BASE + 0x1014) +#define ETH_DMAOMR MMIO32(ETHERNET_BASE + 0x1018) +#define ETH_DMAIER MMIO32(ETHERNET_BASE + 0x101C) +#define ETH_DMAMFBOCR MMIO32(ETHERNET_BASE + 0x1020) +#define ETH_DMACHTDR MMIO32(ETHERNET_BASE + 0x1048) +#define ETH_DMACHRDR MMIO32(ETHERNET_BASE + 0x104C) +#define ETH_DMACHTBAR MMIO32(ETHERNET_BASE + 0x1050) +#define ETH_DMACHRBAR MMIO32(ETHERNET_BASE + 0x1054) + +/* Ethernet Buffer Descriptors */ +#define ETH_DES(n, base) MMIO32((base) + (n)*4) +#define ETH_DES0(base) ETH_DES(0, base) +#define ETH_DES1(base) ETH_DES(1, base) +#define ETH_DES2(base) ETH_DES(2, base) +#define ETH_DES3(base) ETH_DES(3, base) + +/* Ethernet Extended buffer Descriptors */ +#define ETH_DES4(base) ETH_DES(4, base) +#define ETH_DES5(base) ETH_DES(5, base) +#define ETH_DES6(base) ETH_DES(6, base) +#define ETH_DES7(base) ETH_DES(7, base) + +/*---------------------------------------------------------------------------*/ +/* MACCR --------------------------------------------------------------------*/ + +#define ETH_MACCR_RE (1<<2) +#define ETH_MACCR_TE (1<<3) +#define ETH_MACCR_DC (1<<4) + +#define ETH_MACCR_BL_SHIFT 5 +#define ETH_MACCR_BL (3 << ETH_MACCR_BL_SHIFT) +#define ETH_MACCR_BL_MIN10 (0 << ETH_MACCR_BL_SHIFT) +#define ETH_MACCR_BL_MIN8 (1 << ETH_MACCR_BL_SHIFT) +#define ETH_MACCR_BL_MIN4 (2 << ETH_MACCR_BL_SHIFT) +#define ETH_MACCR_BL_MIN1 (3 << ETH_MACCR_BL_SHIFT) + +#define ETH_MACCR_APCS (1<<7) +#define ETH_MACCR_RD (1<<9) +#define ETH_MACCR_IPCO (1<<10) +#define ETH_MACCR_DM (1<<11) +#define ETH_MACCR_LM (1<<12) +#define ETH_MACCR_ROD (1<<13) +#define ETH_MACCR_FES (1<<14) +#define ETH_MACCR_CSD (1<<16) + +#define ETH_MACCR_IFG_SHIFT 17 +#define ETH_MACCR_IFG (7<Defined Constants and Types for the Ethernet PHY + * + * @ingroup ETH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#ifndef LIBOPENCM3_PHY_H +#define LIBOPENCM3_PHY_H + +#include + +/**@{*/ + +/* Registers */ + +#define PHY_REG_BCR 0x00 +#define PHY_REG_BSR 0x01 +#define PHY_REG_ID1 0x02 +#define PHY_REG_ID2 0x03 +#define PHY_REG_ANTX 0x04 +#define PHY_REG_ANRX 0x05 +#define PHY_REG_ANEXP 0x06 +#define PHY_REG_ANNPTX 0x07 +#define PHY_REG_ANNPRX 0x08 + +#define PHY_REG_BCR_COLTEST (1<<7) +#define PHY_REG_BCR_FD (1<<8) +#define PHY_REG_BCR_ANRST (1<<9) +#define PHY_REG_BCR_ISOLATE (1<<10) +#define PHY_REG_BCR_POWERDN (1<<11) +#define PHY_REG_BCR_AN (1<<12) +#define PHY_REG_BCR_100M (1<<13) +#define PHY_REG_BCR_LOOPBACK (1<<14) +#define PHY_REG_BCR_RESET (1<<15) + +#define PHY_REG_BSR_JABBER (1<<1) +#define PHY_REG_BSR_UP (1<<2) +#define PHY_REG_BSR_FAULT (1<<4) +#define PHY_REG_BSR_ANDONE (1<<5) + +#define PHY0 0 +#define PHY1 1 + +enum phy_status { + LINK_DOWN, + LINK_HD_10M, + LINK_HD_100M, + LINK_HD_1000M, + LINK_HD_10000M, + LINK_FD_10M, + LINK_FD_100M, + LINK_FD_1000M, + LINK_FD_10000M, +}; + +void phy_reset(uint8_t phy); +bool phy_link_isup(uint8_t phy); + +enum phy_status phy_link_status(uint8_t phy); + +void phy_autoneg_force(uint8_t phy, enum phy_status mode); +void phy_autoneg_enable(uint8_t phy); + +/**@}*/ + + +#endif /* LIBOPENCM3_PHY_H__ */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/phy_ksz8051mll.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/phy_ksz8051mll.h new file mode 100644 index 00000000..a7f9865e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/ethernet/phy_ksz8051mll.h @@ -0,0 +1,60 @@ +/** @defgroup ethernet_phy_ksz8051mll_defines PHY KSZ8051mll Defines + * + * @brief Defined Constants and Types for the Ethernet PHY KSZ8051mll + * chips + * + * @ingroup ETH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PHY_KSZ8051MLL_H +#define LIBOPENCM3_PHY_KSZ8051MLL_H + +#include + +/**@{*/ + +/* Registers */ + +#define PHY_REG_AFECTRL 0x11 +#define PHY_REG_RXERCTR 0x15 +#define PHY_REG_STRAPOVRD 0x16 +#define PHY_REG_STRAPSTAT 0x17 +#define PHY_REG_ECR 0x18 + +#define PHY_REG_ICSR 0x1B + +#define PHY_REG_LINKMD 0x1D + +#define PHY_REG_CR1 0x1E +#define PHY_REG_CR2 0x1E + +/**@}*/ + + +#endif /* LIBOPENCM3_PHY_KSZ8051MLL_H__ */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/license.dox b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/license.dox new file mode 100644 index 00000000..3aa9331a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/license.dox @@ -0,0 +1,16 @@ +/** @page lgpl_license libopencm3 License + +libopencm3 is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +libopencm3 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with this +program. If not, see . + +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/doc-lm3s.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/doc-lm3s.h new file mode 100644 index 00000000..1a4ecb80 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/doc-lm3s.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 LM3S + +@version 1.0.0 + +@date 14 September 2012 + +API documentation for TI Stellaris LM3S Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LM3Sxx LM3S +Libraries for TI Stellaris LM3S series. + +@version 1.0.0 + +@date 7 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LM3Sxx_defines LM3S Defines + +@brief Defined Constants and Types for the LM3S series + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/gpio.h new file mode 100644 index 00000000..f7fdd98c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/gpio.h @@ -0,0 +1,99 @@ +/** @defgroup gpio_defines General Purpose I/O Defines + +@brief Defined Constants and Types for the LM3S General Purpose I/O + +@ingroup LM3Sxx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2011 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM3S_GPIO_H +#define LM3S_GPIO_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +#define GPIOA GPIOA_APB_BASE +#define GPIOB GPIOB_APB_BASE +#define GPIOC GPIOC_APB_BASE +#define GPIOD GPIOD_APB_BASE +#define GPIOE GPIOE_APB_BASE +#define GPIOF GPIOF_APB_BASE +#define GPIOG GPIOG_APB_BASE +#define GPIOH GPIOH_APB_BASE + +/* GPIO number definitions (for convenience) */ +#define GPIO0 (1 << 0) +#define GPIO1 (1 << 1) +#define GPIO2 (1 << 2) +#define GPIO3 (1 << 3) +#define GPIO4 (1 << 4) +#define GPIO5 (1 << 5) +#define GPIO6 (1 << 6) +#define GPIO7 (1 << 7) + +/* --- GPIO registers ------------------------------------------------------ */ + +#define GPIO_DATA(port) (&MMIO32((port) + 0x000)) +#define GPIO_DIR(port) MMIO32((port) + 0x400) +#define GPIO_IS(port) MMIO32((port) + 0x404) +#define GPIO_IBE(port) MMIO32((port) + 0x408) +#define GPIO_IEV(port) MMIO32((port) + 0x40c) +#define GPIO_IM(port) MMIO32((port) + 0x410) +#define GPIO_RIS(port) MMIO32((port) + 0x414) +#define GPIO_MIS(port) MMIO32((port) + 0x418) +#define GPIO_ICR(port) MMIO32((port) + 0x41c) +#define GPIO_AFSEL(port) MMIO32((port) + 0x420) +#define GPIO_DR2R(port) MMIO32((port) + 0x500) +#define GPIO_DR4R(port) MMIO32((port) + 0x504) +#define GPIO_DR8R(port) MMIO32((port) + 0x508) +#define GPIO_ODR(port) MMIO32((port) + 0x50c) +#define GPIO_PUR(port) MMIO32((port) + 0x510) +#define GPIO_PDR(port) MMIO32((port) + 0x514) +#define GPIO_SLR(port) MMIO32((port) + 0x518) +#define GPIO_DEN(port) MMIO32((port) + 0x51c) +#define GPIO_LOCK(port) MMIO32((port) + 0x520) +#define GPIO_CR(port) MMIO32((port) + 0x524) +#define GPIO_AMSEL(port) MMIO32((port) + 0x528) + +BEGIN_DECLS + +void gpio_set(uint32_t gpioport, uint8_t gpios); +void gpio_clear(uint32_t gpioport, uint8_t gpios); + +END_DECLS + +/**@}*/ + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/irq.json new file mode 100644 index 00000000..0d8dcfc7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/irq.json @@ -0,0 +1,126 @@ +{ + "_comment": [ + "Although this says LM3S, the interrupt table applies to the", + "LM4F as well Some interrupt vectores marked as reserved in LM3S are", + "used in LM4F, and some vectors in LM3S are marked reserved for LM4F.", + "However, the common vectors are identical, and we can safely use the", + "same interrupt table. Reserved vectors will never be triggered, so", + "having them is perfectly safe." + ], + "irqs": { + "0": "GPIOA", + "1": "GPIOB", + "2": "GPIOC", + "3": "GPIOD", + "4": "GPIOE", + "5": "UART0", + "6": "UART1", + "7": "SSI0", + "8": "I2C0", + "9": "PWM0_FAULT", + "10": "PWM0_0", + "11": "PWM0_1", + "12": "PWM0_2", + "13": "QEI0", + "14": "ADC0SS0", + "15": "ADC0SS1", + "16": "ADC0SS2", + "17": "ADC0SS3", + "18": "WATCHDOG", + "19": "TIMER0A", + "20": "TIMER0B", + "21": "TIMER1A", + "22": "TIMER1B", + "23": "TIMER2A", + "24": "TIMER2B", + "25": "COMP0", + "26": "COMP1", + "27": "COMP2", + "28": "SYSCTL", + "29": "FLASH", + "30": "GPIOF", + "31": "GPIOG", + "32": "GPIOH", + "33": "UART2", + "34": "SSI1", + "35": "TIMER3A", + "36": "TIMER3B", + "37": "I2C1", + "38": "QEI1", + "39": "CAN0", + "40": "CAN1", + "41": "CAN2", + "42": "ETH", + "43": "HIBERNATE", + "44": "USB0", + "45": "PWM0_3", + "46": "UDMA", + "47": "UDMAERR", + "48": "ADC1SS0", + "49": "ADC1SS1", + "50": "ADC1SS2", + "51": "ADC1SS3", + "52": "I2S0", + "53": "EPI0", + "54": "GPIOJ", + "55": "GPIOK", + "56": "GPIOL", + "57": "SSI2", + "58": "SSI3", + "59": "UART3", + "60": "UART4", + "61": "UART5", + "62": "UART6", + "63": "UART7", + "68": "I2C2", + "69": "I2C3", + "70": "TIMER4A", + "71": "TIMER4B", + "92": "TIMER5A", + "93": "TIMER5B", + "94": "WTIMER0A", + "95": "WTIMER0B", + "96": "WTIMER1A", + "97": "WTIMER1B", + "98": "WTIMER2A", + "99": "WTIMER2B", + "100": "WTIMER3A", + "101": "WTIMER3B", + "102": "WTIMER4A", + "103": "WTIMER4B", + "104": "WTIMER5A", + "105": "WTIMER5B", + "106": "SYSEXC", + "107": "PECI0", + "108": "LPC0", + "109": "I2C4", + "110": "I2C5", + "111": "GPIOM", + "112": "GPION", + "114": "FAN0", + "116": "GPIOP0", + "117": "GPIOP1", + "118": "GPIOP2", + "119": "GPIOP3", + "120": "GPIOP4", + "121": "GPIOP5", + "122": "GPIOP6", + "123": "GPIOP7", + "124": "GPIOQ0", + "125": "GPIOQ1", + "126": "GPIOQ2", + "127": "GPIOQ3", + "128": "GPIOQ4", + "129": "GPIOQ5", + "130": "GPIOQ6", + "131": "GPIOQ7", + "134": "PWM1_0", + "135": "PWM1_1", + "136": "PWM1_2", + "137": "PWM1_3", + "138": "PWM1_FAULT" + }, + "partname_humanreadable": "LM3S series", + "partname_doxygen": "LM3S", + "includeguard": "LIBOPENCM3_LM3S_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/memorymap.h new file mode 100644 index 00000000..df5d6e34 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/memorymap.h @@ -0,0 +1,47 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM3S_MEMORYMAP_H +#define LM3S_MEMORYMAP_H + +#include + +/* --- LM3S specific peripheral definitions ----------------------------- */ + +#define GPIOA_APB_BASE (0x40004000U) +#define GPIOB_APB_BASE (0x40005000U) +#define GPIOC_APB_BASE (0x40006000U) +#define GPIOD_APB_BASE (0x40007000U) +#define GPIOE_APB_BASE (0x40024000U) +#define GPIOF_APB_BASE (0x40025000U) +#define GPIOG_APB_BASE (0x40026000U) +#define GPIOH_APB_BASE (0x40027000U) + +#define GPIOA_BASE (0x40058000U) +#define GPIOB_BASE (0x40059000U) +#define GPIOC_BASE (0x4005A000U) +#define GPIOD_BASE (0x4005B000U) +#define GPIOE_BASE (0x4005C000U) +#define GPIOF_BASE (0x4005D000U) +#define GPIOG_BASE (0x4005E000U) +#define GPIOH_BASE (0x4005F000U) + +#define SYSTEMCONTROL_BASE (0x400FE000U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/rcc.h new file mode 100644 index 00000000..853f90e4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/rcc.h @@ -0,0 +1,107 @@ +/** @defgroup rcc_defines RCC Defines + * + * @brief Defined Constants and Types for the LM3S Reset and Clock + * Control + * + * @ingroup LM3S_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2009 + * Daniele Lacamera \ + * + * @date 21 November 2015 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Daniele Lacamera + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H +#include + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_RIS MMIO32(0x400FE050) +#define RCC_CR MMIO32(0x400FE060) +#define RCC2_CR MMIO32(0x400FE070) + +/* RCC1 bits */ +#define RCC_SYSDIV_MASK (0x0F << 23) +#define RCC_SYSDIV_12_5MHZ (0x0F << 23) +#define RCC_SYSDIV_50MHZ (0x03 << 23) + +#define RCC_USESYSDIV (1 << 22) +#define RCC_USEPWMDIV (1 << 20) + +#define RCC_PWMDIV_MASK (0x07 << 17) +#define RCC_PWMDIV_64 (0x07 << 17) + +#define RCC_OFF (1 << 13) +#define RCC_BYPASS (1 << 11) + +#define RCC_XTAL_MASK (0x0F << 6) +/* For other values, see datasheet section 23.2.2 - table 23-9 */ +#define RCC_XTAL_6MHZ_RESET (0x0B << 6) +#define RCC_XTAL_8MHZ_400MHZ (0x0D << 6) + + +#define RCC_OSCRC_MASK (0x03 << 4) +#define RCC_OSCRC_MOSC (0x00 << 4) +#define RCC_OSCRC_IOSC (0x01 << 4) +#define RCC_OSCRC_IOSC_Q (0x02 << 4) +#define RCC_OSCRC_30KHZ (0x03 << 4) + +#define RCC_IOSCDIS (1 << 1) +#define RCC_MOSCDIS (1 << 0) + +/* RCC2 bits */ +#define RCC2_USERRCC2 (1 << 31) +#define RCC2_SYSDIV2_MASK 0x7f +#define RCC2_SYSDIV2_SHIFT 23 + +#define RCC2_OFF (1 << 13) +#define RCC2_BYPASS (1 << 11) + +/* RIS bit */ +#define RIS_PLLLRIS (1 << 6) + + +/* From Datasheet description for reset values + * Section 6.4 - Register Descriptions + */ + +/* Register 8: RCC + * Type R/W, reset 0x078E.3AD1 + */ +#define RCC_RESET_VALUE (0x078E3AD1) + +/* Register 10: RCC2 + * Type R/W, reset 0x0780.2810 + */ +#define RCC2_RESET_VALUE (0x07802810) + +BEGIN_DECLS + +int rcc_clock_setup_in_xtal_8mhz_out_50mhz(void); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/systemcontrol.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/systemcontrol.h new file mode 100644 index 00000000..dd02f0f3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/systemcontrol.h @@ -0,0 +1,81 @@ +/** @defgroup systemcontrol_defines System Control + +@brief Defined Constants and Types for the LM3S System Control + +@ingroup LM3Sxx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2011 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM3S_SYSTEMCONTROL_H +#define LM3S_SYSTEMCONTROL_H + +/**@{*/ + +#include + +#define SYSTEMCONTROL_DID0 MMIO32(SYSTEMCONTROL_BASE + 0x000) +#define SYSTEMCONTROL_DID1 MMIO32(SYSTEMCONTROL_BASE + 0x004) +#define SYSTEMCONTROL_DC0 MMIO32(SYSTEMCONTROL_BASE + 0x008) +#define SYSTEMCONTROL_DC1 MMIO32(SYSTEMCONTROL_BASE + 0x010) +#define SYSTEMCONTROL_DC2 MMIO32(SYSTEMCONTROL_BASE + 0x014) +#define SYSTEMCONTROL_DC3 MMIO32(SYSTEMCONTROL_BASE + 0x018) +#define SYSTEMCONTROL_DC4 MMIO32(SYSTEMCONTROL_BASE + 0x01C) +#define SYSTEMCONTROL_DC5 MMIO32(SYSTEMCONTROL_BASE + 0x020) +#define SYSTEMCONTROL_DC6 MMIO32(SYSTEMCONTROL_BASE + 0x024) +#define SYSTEMCONTROL_DC7 MMIO32(SYSTEMCONTROL_BASE + 0x028) +#define SYSTEMCONTROL_PBORCTL MMIO32(SYSTEMCONTROL_BASE + 0x030) +#define SYSTEMCONTROL_LDORCTL MMIO32(SYSTEMCONTROL_BASE + 0x034) +#define SYSTEMCONTROL_SRCR0 MMIO32(SYSTEMCONTROL_BASE + 0x040) +#define SYSTEMCONTROL_SRCR1 MMIO32(SYSTEMCONTROL_BASE + 0x044) +#define SYSTEMCONTROL_SRCR2 MMIO32(SYSTEMCONTROL_BASE + 0x048) +#define SYSTEMCONTROL_RIS MMIO32(SYSTEMCONTROL_BASE + 0x050) +#define SYSTEMCONTROL_IMC MMIO32(SYSTEMCONTROL_BASE + 0x054) +#define SYSTEMCONTROL_MISC MMIO32(SYSTEMCONTROL_BASE + 0x058) +#define SYSTEMCONTROL_RESC MMIO32(SYSTEMCONTROL_BASE + 0x05C) +#define SYSTEMCONTROL_RCC MMIO32(SYSTEMCONTROL_BASE + 0x060) +#define SYSTEMCONTROL_PLLCFG MMIO32(SYSTEMCONTROL_BASE + 0x064) +#define SYSTEMCONTROL_GPIOHBCTL MMIO32(SYSTEMCONTROL_BASE + 0x06C) +#define SYSTEMCONTROL_RCC2 MMIO32(SYSTEMCONTROL_BASE + 0x070) +#define SYSTEMCONTROL_MOSCCTL MMIO32(SYSTEMCONTROL_BASE + 0x07C) +#define SYSTEMCONTROL_RCGC0 MMIO32(SYSTEMCONTROL_BASE + 0x100) +#define SYSTEMCONTROL_RCGC1 MMIO32(SYSTEMCONTROL_BASE + 0x104) +#define SYSTEMCONTROL_RCGC2 MMIO32(SYSTEMCONTROL_BASE + 0x108) +#define SYSTEMCONTROL_SCGC0 MMIO32(SYSTEMCONTROL_BASE + 0x110) +#define SYSTEMCONTROL_SCGC1 MMIO32(SYSTEMCONTROL_BASE + 0x114) +#define SYSTEMCONTROL_SCGC2 MMIO32(SYSTEMCONTROL_BASE + 0x118) +#define SYSTEMCONTROL_DCGC0 MMIO32(SYSTEMCONTROL_BASE + 0x120) +#define SYSTEMCONTROL_DCGC1 MMIO32(SYSTEMCONTROL_BASE + 0x124) +#define SYSTEMCONTROL_DCGC2 MMIO32(SYSTEMCONTROL_BASE + 0x128) +#define SYSTEMCONTROL_DSLPCLKCFG MMIO32(SYSTEMCONTROL_BASE + 0x144) + +/**@}*/ + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/usart.h new file mode 100644 index 00000000..d6f8b329 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm3s/usart.h @@ -0,0 +1,123 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Daniele Lacamera + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM3S_USART_H +#define LM3S_USART_H + +#include + + + +#define USART0_BASE 0x4000C000 +#define USART1_BASE 0x4000D000 +#define USART2_BASE 0x4000E000 + +/* --- Universal Synchronous Asynchronous Receiver Transmitter (USART) */ +#define USART_DR(x) MMIO32((x) + 0x0000) +#define USART_IR(x) MMIO32((x) + 0x0004) +#define USART_FR(x) MMIO32((x) + 0x0018) +#define USART_ILPR(x) MMIO32((x) + 0x0020) +#define USART_IBRD(x) MMIO32((x) + 0x0024) +#define USART_FBRD(x) MMIO32((x) + 0x0028) +#define USART_LCRH(x) MMIO32((x) + 0x002c) +#define USART_CTL(x) MMIO32((x) + 0x0030) +#define USART_IFLS(x) MMIO32((x) + 0x0034) +#define USART_IM(x) MMIO32((x) + 0x0038) +#define USART_RIS(x) MMIO32((x) + 0x003c) +#define USART_MIS(x) MMIO32((x) + 0x0040) +#define USART_IC(x) MMIO32((x) + 0x0044) + +/* USART Data Register (USART_DR) */ +/* Bits [31:12] - Reserved */ +#define USART_DR_OE (0x01 << 11) +#define USART_DR_BE (0x01 << 10) +#define USART_DR_PE (0x01 << 9) +#define USART_DR_FE (0x01 << 8) + +/* USART Flags Register (USART_FR) */ +/* Bits [31:8] - Reserved */ +#define USART_FR_TXFE (0x01 << 7) +#define USART_FR_RXFF (0x01 << 6) +#define USART_FR_TXFF (0x01 << 5) +#define USART_FR_RXFE (0x01 << 4) +#define USART_FR_BUSY (0x01 << 3) +/* Bits [2:0] - Reserved */ + +/* USART Interrupt Mask Register (USART_IM) */ +/* Bits [31:11] - Reserved */ +#define USART_IM_OE (0x01 << 10) +#define USART_IM_BE (0x01 << 9) +#define USART_IM_PE (0x01 << 8) +#define USART_IM_FE (0x01 << 7) +#define USART_IM_RT (0x01 << 6) +#define USART_IM_TX (0x01 << 5) +#define USART_IM_RX (0x01 << 4) +/* Bits [3:0] - Reserved */ + +/* USART Interrupt Clear Register (USART_IC) */ +/* Bits [31:11] - Reserved */ +#define USART_IC_OE (0x01 << 10) +#define USART_IC_BE (0x01 << 9) +#define USART_IC_PE (0x01 << 8) +#define USART_IC_FE (0x01 << 7) +#define USART_IC_RT (0x01 << 6) +#define USART_IC_TX (0x01 << 5) +#define USART_IC_RX (0x01 << 4) +/* Bits [3:0] - Reserved */ + +enum usart_stopbits { + USART_STOPBITS_1, + USART_STOPBITS_1_5, + USART_STOPBITS_2, +}; + +enum usart_parity { + USART_PARITY_NONE, + USART_PARITY_ODD, + USART_PARITY_EVEN, +}; + +enum usart_mode { + USART_MODE_DISABLED, + USART_MODE_RX, + USART_MODE_TX, + USART_MODE_TX_RX, +}; + +enum usart_flowcontrol { + USART_FLOWCONTROL_NONE, + USART_FLOWCONTROL_RTS_CTS, +}; + +void usart_send(uint32_t usart, uint16_t data); +uint16_t usart_recv(uint32_t usart); +bool usart_is_send_ready(uint32_t usart); +bool usart_is_recv_ready(uint32_t usart); +void usart_send_blocking(uint32_t usart, uint16_t data); +uint16_t usart_recv_blocking(uint32_t usart); +void usart_enable_rx_interrupt(uint32_t usart); +void usart_disable_rx_interrupt(uint32_t usart); +void usart_clear_rx_interrupt(uint32_t usart); +void usart_enable_tx_interrupt(uint32_t usart); +void usart_disable_tx_interrupt(uint32_t usart); +void usart_clear_tx_interrupt(uint32_t usart); +bool usart_get_interrupt_source(uint32_t usart, uint32_t flag); + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/doc-lm4f.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/doc-lm4f.h new file mode 100644 index 00000000..4877721e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/doc-lm4f.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 LM4F + +@version 1.0.0 + +@date 22 November 2012 + +API documentation for TI Stellaris LM4F Cortex M4F series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LM4Fxx LM4F +Libraries for TI Stellaris LM4F series. + +@version 1.0.0 + +@date 22 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LM4Fxx_defines LM4F Defines + +@brief Defined Constants and Types for the LM4F series + +@version 1.0.0 + +@date 22 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/gpio.h new file mode 100644 index 00000000..a2b02b5c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/gpio.h @@ -0,0 +1,380 @@ +/** @defgroup gpio_defines General Purpose I/O Defines + * + * @brief Defined Constants and Types for the LM4F General Purpose I/O + * + * @ingroup LM4Fxx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2011 + * Gareth McMullin + * @author @htmlonly © @endhtmlonly 2013 + * Alexandru Gagniuc + * + * @date 16 March 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * Copyright (C) 2013 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM4F_GPIO_H +#define LM4F_GPIO_H + +/**@{*/ + +#include +#include + +/* ============================================================================= + * Convenience macros + * ---------------------------------------------------------------------------*/ +/** @defgroup gpio_reg_base GPIO register base addresses + * @{*/ +#define GPIOA GPIOA_BASE +#define GPIOB GPIOB_BASE +#define GPIOC GPIOC_BASE +#define GPIOD GPIOD_BASE +#define GPIOE GPIOE_BASE +#define GPIOF GPIOF_BASE +#define GPIOG GPIOG_BASE +#define GPIOH GPIOH_BASE +#define GPIOJ GPIOJ_BASE +#define GPIOK GPIOK_BASE +#define GPIOL GPIOL_BASE +#define GPIOM GPIOM_BASE +#define GPION GPION_BASE +#define GPIOP GPIOP_BASE +#define GPIOQ GPIOQ_BASE +/** @} */ + +/* ============================================================================= + * GPIO number definitions (for convenience) + * + * These are usable across all GPIO registers, + * except GPIO_LOCK and GPIO_PCTL + * ---------------------------------------------------------------------------*/ +/** @defgroup gpio_pin_id GPIO pin identifiers + * @{*/ +#define GPIO0 (1 << 0) +#define GPIO1 (1 << 1) +#define GPIO2 (1 << 2) +#define GPIO3 (1 << 3) +#define GPIO4 (1 << 4) +#define GPIO5 (1 << 5) +#define GPIO6 (1 << 6) +#define GPIO7 (1 << 7) +#define GPIO_ALL 0xff +/** @} */ + +/* ============================================================================= + * GPIO registers + * ---------------------------------------------------------------------------*/ + +/* GPIO Data */ +#define GPIO_DATA(port) (&MMIO32((port) + 0x000)) + +/* GPIO Direction */ +#define GPIO_DIR(port) MMIO32((port) + 0x400) + +/* GPIO Interrupt Sense */ +#define GPIO_IS(port) MMIO32((port) + 0x404) + +/* GPIO Interrupt Both Edges */ +#define GPIO_IBE(port) MMIO32((port) + 0x408) + +/* GPIO Interrupt Event */ +#define GPIO_IEV(port) MMIO32((port) + 0x40c) + +/* GPIO Interrupt Mask */ +#define GPIO_IM(port) MMIO32((port) + 0x410) + +/* GPIO Raw Interrupt Status */ +#define GPIO_RIS(port) MMIO32((port) + 0x414) + +/* GPIO Masked Interrupt Status */ +#define GPIO_MIS(port) MMIO32((port) + 0x418) + +/* GPIO Interrupt Clear */ +#define GPIO_ICR(port) MMIO32((port) + 0x41c) + +/* GPIO Alternate Function Select */ +#define GPIO_AFSEL(port) MMIO32((port) + 0x420) + +/* GPIO 2-mA Drive Select */ +#define GPIO_DR2R(port) MMIO32((port) + 0x500) + +/* GPIO 4-mA Drive Select */ +#define GPIO_DR4R(port) MMIO32((port) + 0x504) + +/* GPIO 8-mA Drive Select */ +#define GPIO_DR8R(port) MMIO32((port) + 0x508) + +/* GPIO Open Drain Select */ +#define GPIO_ODR(port) MMIO32((port) + 0x50c) + +/* GPIO Pull-Up Select */ +#define GPIO_PUR(port) MMIO32((port) + 0x510) + +/* GPIO Pull-Down Select */ +#define GPIO_PDR(port) MMIO32((port) + 0x514) + +/* GPIO Slew Rate Control Select */ +#define GPIO_SLR(port) MMIO32((port) + 0x518) + +/* GPIO Digital Enable */ +#define GPIO_DEN(port) MMIO32((port) + 0x51c) + +/* GPIO Lock */ +#define GPIO_LOCK(port) MMIO32((port) + 0x520) + +/* GPIO Commit */ +#define GPIO_CR(port) MMIO32((port) + 0x524) + +/* GPIO Analog Mode Select */ +#define GPIO_AMSEL(port) MMIO32((port) + 0x528) + +/* GPIO Port Control */ +#define GPIO_PCTL(port) MMIO32((port) + 0x52C) + +/* GPIO ADC Control */ +#define GPIO_ADCCTL(port) MMIO32((port) + 0x530) + +/* GPIO DMA Control */ +#define GPIO_DMACTL(port) MMIO32((port) + 0x534) + +/* GPIO Peripheral Identification */ +#define GPIO_PERIPH_ID4(port) MMIO32((port) + 0xFD0) +#define GPIO_PERIPH_ID5(port) MMIO32((port) + 0xFD4) +#define GPIO_PERIPH_ID6(port) MMIO32((port) + 0xFD8) +#define GPIO_PERIPH_ID7(port) MMIO32((port) + 0xFDC) +#define GPIO_PERIPH_ID0(port) MMIO32((port) + 0xFE0) +#define GPIO_PERIPH_ID1(port) MMIO32((port) + 0xFE4) +#define GPIO_PERIPH_ID2(port) MMIO32((port) + 0xFE8) +#define GPIO_PERIPH_ID3(port) MMIO32((port) + 0xFEC) + +/* GPIO PrimeCell Identification */ +#define GPIO_PCELL_ID0(port) MMIO32((port) + 0xFF0) +#define GPIO_PCELL_ID1(port) MMIO32((port) + 0xFF4) +#define GPIO_PCELL_ID2(port) MMIO32((port) + 0xFF8) +#define GPIO_PCELL_ID3(port) MMIO32((port) + 0xFFC) + +/* ============================================================================= + * Convenience enums + * ---------------------------------------------------------------------------*/ +enum gpio_mode { + GPIO_MODE_OUTPUT, /**< Configure pin as output */ + GPIO_MODE_INPUT, /**< Configure pin as input */ + GPIO_MODE_ANALOG, /**< Configure pin as analog function */ +}; + +enum gpio_pullup { + GPIO_PUPD_NONE, /**< Do not pull the pin high or low */ + GPIO_PUPD_PULLUP, /**< Pull the pin high */ + GPIO_PUPD_PULLDOWN, /**< Pull the pin low */ +}; + +enum gpio_output_type { + GPIO_OTYPE_PP, /**< Push-pull configuration */ + GPIO_OTYPE_OD, /**< Open drain configuration */ +}; + +enum gpio_drive_strength { + GPIO_DRIVE_2MA, /**< 2mA drive */ + GPIO_DRIVE_4MA, /**< 4mA drive */ + GPIO_DRIVE_8MA, /**< 8mA drive */ + GPIO_DRIVE_8MA_SLEW_CTL,/**< 8mA drive with slew rate control */ +}; + +enum gpio_trigger { + GPIO_TRIG_LVL_LOW, /**< Level trigger, signal low */ + GPIO_TRIG_LVL_HIGH, /**< Level trigger, signal high */ + GPIO_TRIG_EDGE_FALL, /**< Falling edge trigger */ + GPIO_TRIG_EDGE_RISE, /**< Rising edge trigger*/ + GPIO_TRIG_EDGE_BOTH, /**< Falling and Rising edges trigger*/ +}; +/* ============================================================================= + * Function prototypes + * ---------------------------------------------------------------------------*/ +BEGIN_DECLS + +void gpio_enable_ahb_aperture(void); +void gpio_mode_setup(uint32_t gpioport, enum gpio_mode mode, + enum gpio_pullup pullup, uint8_t gpios); +void gpio_set_output_config(uint32_t gpioport, enum gpio_output_type otype, + enum gpio_drive_strength drive, uint8_t gpios); +void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint8_t gpios); + +void gpio_toggle(uint32_t gpioport, uint8_t gpios); +void gpio_unlock_commit(uint32_t gpioport, uint8_t gpios); + +/* Let's keep these ones inlined. GPIO control should be fast */ +/** @ingroup gpio_control + * @{ */ + +/** + * \brief Get status of a Group of Pins (atomic) + * + * Reads the level of the given pins. Bit 0 of the returned data corresponds to + * GPIO0 level, bit 1 to GPIO1 level. and so on. Bits corresponding to masked + * pins (corresponding bit of gpios parameter set to zero) are returned as 0. + * + * This is an atomic operation. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together. + * + * @return The level of the GPIO port. The pins not specified in gpios are + * masked to zero. + */ +static inline uint8_t gpio_read(uint32_t gpioport, uint8_t gpios) +{ + return GPIO_DATA(gpioport)[gpios]; +} + +/** + * \brief Set level of a Group of Pins (atomic) + * + * Sets the level of the given pins. Bit 0 of the data parameter corresponds to + * GPIO0, bit 1 to GPIO1. and so on. Maskedpins (corresponding bit of gpios + * parameter set to zero) are returned not affected. + * + * This is an atomic operation. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together. + * @param[in] data Level to set pin to. Bit 0 of data corresponds to GPIO0, bit + * 1 to GPIO1. and so on. + */ +static inline void gpio_write(uint32_t gpioport, uint8_t gpios, uint8_t data) +{ + /* ipaddr[9:2] mask the bits to be set, hence the array index */ + GPIO_DATA(gpioport)[gpios] = data; +} + +/** + * \brief Set a Group of Pins (atomic) + * + * Set one or more pins of the given GPIO port. This is an atomic operation. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together. + */ +static inline void gpio_set(uint32_t gpioport, uint8_t gpios) +{ + gpio_write(gpioport, gpios, 0xff); +} + +/** + * \brief Clear a Group of Pins (atomic) + * + * Clear one or more pins of the given GPIO port. This is an atomic operation. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together. + */ +static inline void gpio_clear(uint32_t gpioport, uint8_t gpios) +{ + gpio_write(gpioport, gpios, 0); +} + +/** + * \brief Read level of all pins from a port (atomic) + * + * Read the current value of the given GPIO port. This is an atomic operation. + * + * This is functionally identical to @ref gpio_read (gpioport, GPIO_ALL). + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * + * @return The level of all the pins on the GPIO port. + */ +static inline uint8_t gpio_port_read(uint32_t gpioport) +{ + return gpio_read(gpioport, GPIO_ALL); +} + +/** + * \brief Set level of of all pins from a port (atomic) + * + * Set the level of all pins on the given GPIO port. This is an atomic + * operation. + * + * This is functionally identical to @ref gpio_write (gpioport, GPIO_ALL, data). + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together. + * @param[in] data Level to set pin to. Bit 0 of data corresponds to GPIO0, bit + * 1 to GPIO1. and so on. + */ +static inline void gpio_port_write(uint32_t gpioport, uint8_t data) +{ + gpio_write(gpioport, GPIO_ALL, data); +} +/** @} */ + +void gpio_configure_trigger(uint32_t gpioport, enum gpio_trigger trigger, + uint8_t gpios); +void gpio_enable_interrupts(uint32_t gpioport, uint8_t gpios); +void gpio_disable_interrupts(uint32_t gpioport, uint8_t gpios); + + +/* Let's keep these ones inlined. GPIO. They are designed to be used in ISRs */ +/** @ingroup gpio_irq + * @{ */ +/** \brief Determine if interrupt is generated by the given pin + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] srcpins source pin or group of pins to check. + */ +static inline bool gpio_is_interrupt_source(uint32_t gpioport, uint8_t srcpins) +{ + return GPIO_MIS(gpioport) & srcpins; +} + +/** + * \brief Mark interrupt as serviced + * + * After an interrupt is services, its flag must be cleared. If the flag is not + * cleared, then execution will jump back to the start of the ISR after the ISR + * returns. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together. + */ +static inline void gpio_clear_interrupt_flag(uint32_t gpioport, uint8_t gpios) +{ + GPIO_ICR(gpioport) |= gpios; +} + +/** @} */ +END_DECLS + +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/memorymap.h new file mode 100644 index 00000000..9a20f6dc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/memorymap.h @@ -0,0 +1,71 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM4F_MEMORYMAP_H +#define LM4F_MEMORYMAP_H + +#include + +/* --- LM4F specific peripheral definitions ----------------------------- */ + +#define GPIOA_APB_BASE (0x40004000U) +#define GPIOB_APB_BASE (0x40005000U) +#define GPIOC_APB_BASE (0x40006000U) +#define GPIOD_APB_BASE (0x40007000U) +#define GPIOE_APB_BASE (0x40024000U) +#define GPIOF_APB_BASE (0x40025000U) +#define GPIOG_APB_BASE (0x40026000U) +#define GPIOH_APB_BASE (0x40027000U) +#define GPIOJ_APB_BASE (0x4003D000U) + +#define GPIOA_BASE (0x40058000U) +#define GPIOB_BASE (0x40059000U) +#define GPIOC_BASE (0x4005A000U) +#define GPIOD_BASE (0x4005B000U) +#define GPIOE_BASE (0x4005C000U) +#define GPIOF_BASE (0x4005D000U) +#define GPIOG_BASE (0x4005E000U) +#define GPIOH_BASE (0x4005F000U) +#define GPIOJ_BASE (0x40060000U) +#define GPIOK_BASE (0x40061000U) +#define GPIOL_BASE (0x40062000U) +#define GPIOM_BASE (0x40063000U) +#define GPION_BASE (0x40064000U) +#define GPIOP_BASE (0x40065000U) +#define GPIOQ_BASE (0x40066000U) + +#define UART0_BASE (0x4000C000U) +#define UART1_BASE (0x4000D000U) +#define UART2_BASE (0x4000E000U) +#define UART3_BASE (0x4000F000U) +#define UART4_BASE (0x40010000U) +#define UART5_BASE (0x40011000U) +#define UART6_BASE (0x40012000U) +#define UART7_BASE (0x40013000U) + +#define SSI0_BASE (0x40008000U) +#define SSI1_BASE (0x40009000U) +#define SSI2_BASE (0x4000A000U) +#define SSI3_BASE (0x4000B000U) + +#define USB_BASE (0x40050000U) + +#define SYSCTL_BASE (0x400FE000U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/rcc.h new file mode 100644 index 00000000..98a92cfd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/rcc.h @@ -0,0 +1,133 @@ +/** @defgroup rcc_defines Reset and Clock Control + +@brief Defined Constants and Types for the LM4F Reset and Clock Control + +@ingroup LM4Fxx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 +Alexandru Gagniuc + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM4F_RCC_H +#define LM4F_RCC_H + +/**@{*/ + +#include + +/** + * \brief Oscillator source values + * + * Possible values of the oscillator source. + */ +enum osc_src { + OSCSRC_MOSC = SYSCTL_RCC2_OSCSRC2_MOSC, + OSCSRC_PIOSC = SYSCTL_RCC2_OSCSRC2_PIOSC, + OSCSRC_PIOSC_D4 = SYSCTL_RCC2_OSCSRC2_PIOSC_D4, + OSCSRC_30K_INT = SYSCTL_RCC2_OSCSRC2_30K, + OSCSRC_32K_EXT = SYSCTL_RCC2_OSCSRC2_32K768, +}; + +/** + * \brief PWM clock divisor values + * + * Possible values of the binary divisor used to predivide the system clock down + * for use as the timing reference for the PWM module. + */ +enum pwm_clkdiv { + PWMDIV_2 = SYSCTL_RCC_PWMDIV_2, + PWMDIV_4 = SYSCTL_RCC_PWMDIV_4, + PWMDIV_8 = SYSCTL_RCC_PWMDIV_8, + PWMDIV_16 = SYSCTL_RCC_PWMDIV_16, + PWMDIV_32 = SYSCTL_RCC_PWMDIV_32, + PWMDIV_64 = SYSCTL_RCC_PWMDIV_64, +}; + +/** + * \brief Predefined crystal values + * + * Predefined crystal values for the XTAL field in SYSCTL_RCC. + * Using these predefined values in the XTAL field, the SYSCTL_PLLFREQ0 and + * SYSCTL_PLLFREQ1 are automatically adjusted in hardware to provide a PLL clock + * of 400MHz. + */ +enum xtal_t { + XTAL_4M = SYSCTL_RCC_XTAL_4M, + XTAL_4M_096 = SYSCTL_RCC_XTAL_4M_096, + XTAL_4M_9152 = SYSCTL_RCC_XTAL_4M_9152, + XTAL_5M = SYSCTL_RCC_XTAL_5M, + XTAL_5M_12 = SYSCTL_RCC_XTAL_5M_12, + XTAL_6M = SYSCTL_RCC_XTAL_6M, + XTAL_6M_144 = SYSCTL_RCC_XTAL_6M_144, + XTAL_7M_3728 = SYSCTL_RCC_XTAL_7M_3728, + XTAL_8M = SYSCTL_RCC_XTAL_8M, + XTAL_8M_192 = SYSCTL_RCC_XTAL_8M_192, + XTAL_10M = SYSCTL_RCC_XTAL_10M, + XTAL_12M = SYSCTL_RCC_XTAL_12M, + XTAL_12M_288 = SYSCTL_RCC_XTAL_12M_288, + XTAL_13M_56 = SYSCTL_RCC_XTAL_13M_56, + XTAL_14M_31818 = SYSCTL_RCC_XTAL_14M_31818, + XTAL_16M = SYSCTL_RCC_XTAL_16M, + XTAL_16M_384 = SYSCTL_RCC_XTAL_16M_384, + XTAL_18M = SYSCTL_RCC_XTAL_18M, + XTAL_20M = SYSCTL_RCC_XTAL_20M, + XTAL_24M = SYSCTL_RCC_XTAL_24M, + XTAL_25M = SYSCTL_RCC_XTAL_25M, +}; + +/* ============================================================================= + * Function prototypes + * ---------------------------------------------------------------------------*/ +BEGIN_DECLS +/* Low-level clock API */ +void rcc_configure_xtal(enum xtal_t xtal); +void rcc_disable_main_osc(void); +void rcc_disable_interal_osc(void); +void rcc_enable_main_osc(void); +void rcc_enable_interal_osc(void); +void rcc_enable_rcc2(void); +void rcc_pll_off(void); +void rcc_pll_on(void); +void rcc_set_osc_source(enum osc_src src); +void rcc_pll_bypass_disable(void); +void rcc_pll_bypass_enable(void); +void rcc_set_pll_divisor(uint8_t div400); +void rcc_set_pwm_divisor(enum pwm_clkdiv div); +void rcc_usb_pll_off(void); +void rcc_usb_pll_on(void); +void rcc_wait_for_pll_ready(void); +/* High-level clock API */ +void rcc_change_pll_divisor(uint8_t plldiv400); +uint32_t rcc_get_system_clock_frequency(void); +void rcc_sysclk_config(enum osc_src src, enum xtal_t xtal, uint8_t pll_div400); + +END_DECLS + +/**@}*/ + +#endif /* LM4F_RCC_H */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/ssi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/ssi.h new file mode 100644 index 00000000..77a7555c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/ssi.h @@ -0,0 +1,118 @@ +/** @defgroup ssi_defines Synchronous Serial Interface + * + * @brief Defined Constants and Types for the LM4F Synchronous Serial Interface (SSI) + * + * @ingroup LM4Fxx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Tiago Costa + * + * @date 11 June 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Tiago Costa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM4F_SSI_H +#define LM4F_SSI_H + +/**@{*/ + +#include +#include + +/* ============================================================================= + * Convenience macros + * ---------------------------------------------------------------------------*/ +/** @defgroup ssi_base SSI register base addresses + * @{*/ +#define SSI0 SSI0_BASE +#define SSI1 SSI1_BASE +#define SSI2 SSI2_BASE +#define SSI3 SSI3_BASE +/** @} */ + +/* ============================================================================= + * SSI registers + * ---------------------------------------------------------------------------*/ + +/* SSI Control 0 */ +#define SSI_CR0(port) MMIO32((port) + 0x000) + +/* SSI Control 1 */ +#define SSI_CR1(port) MMIO32((port) + 0x004) + +/* SSI Data */ +#define SSI_DR(port) MMIO32((port) + 0x008) + +/* SSI Satus */ +#define SSI_SR(port) MMIO32((port) + 0x00C) + +/* SSI Clock Prescale */ +#define SSI_CPSR(port) MMIO32((port) + 0x010) + +/* SSI Interrupt Mask */ +#define SSI_IM(port) MMIO32((port) + 0x014) + +/* SSI Raw Interrupt Status */ +#define SSI_RIS(port) MMIO32((port) + 0x018) + +/* SSI Masked Interrupt Status */ +#define SSI_MIS(port) MMIO32((port) + 0x01C) + +/* SSI Interrupt Clear */ +#define SSI_ICR(port) MMIO32((port) + 0x020) + +/* SSI DMA Control */ +#define SSI_DMACTL(port) MMIO32((port) + 0x024) + +/* SSI Clock Configuration */ +#define SSI_CC(port) MMIO32((port) + 0xFC8) + +/* SSI Peripheral Identification */ +#define SSI_PERIPH_ID4(port) MMIO32((port) + 0xFD0) +#define SSI_PERIPH_ID5(port) MMIO32((port) + 0xFD4) +#define SSI_PERIPH_ID6(port) MMIO32((port) + 0xFD8) +#define SSI_PERIPH_ID7(port) MMIO32((port) + 0xFDC) +#define SSI_PERIPH_ID0(port) MMIO32((port) + 0xFE0) +#define SSI_PERIPH_ID1(port) MMIO32((port) + 0xFE4) +#define SSI_PERIPH_ID2(port) MMIO32((port) + 0xFE8) +#define SSI_PERIPH_ID3(port) MMIO32((port) + 0xFEC) + +/* SSI PrimeCell Identification */ +#define SSI_PCELL_ID0(port) MMIO32((port) + 0xFF0) +#define SSI_PCELL_ID1(port) MMIO32((port) + 0xFF4) +#define SSI_PCELL_ID2(port) MMIO32((port) + 0xFF8) +#define SSI_PCELL_ID3(port) MMIO32((port) + 0xFFC) + +/* ============================================================================= + * Function prototypes + * ---------------------------------------------------------------------------*/ +BEGIN_DECLS + +END_DECLS + +/**@}*/ + +#endif /* LM4F_SSI_H */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/systemcontrol.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/systemcontrol.h new file mode 100644 index 00000000..62e22313 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/systemcontrol.h @@ -0,0 +1,743 @@ +/** @defgroup systemcontrol_defines System Control + +@brief Defined Constants and Types for the LM4F System Control + +@ingroup LM4Fxx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 +Alexandru Gagniuc + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LM4F_SYSTEMCONTROL_H +#define LM4F_SYSTEMCONTROL_H + +/**@{*/ + +#include +#include + +#define SYSCTL_DID0 MMIO32(SYSCTL_BASE + 0x000) +#define SYSCTL_DID1 MMIO32(SYSCTL_BASE + 0x004) +#define SYSCTL_PBORCTL MMIO32(SYSCTL_BASE + 0x030) +#define SYSCTL_LDORCTL MMIO32(SYSCTL_BASE + 0x034) +#define SYSCTL_RIS MMIO32(SYSCTL_BASE + 0x050) +#define SYSCTL_IMC MMIO32(SYSCTL_BASE + 0x054) +#define SYSCTL_MISC MMIO32(SYSCTL_BASE + 0x058) +#define SYSCTL_RESC MMIO32(SYSCTL_BASE + 0x05C) +#define SYSCTL_RCC MMIO32(SYSCTL_BASE + 0x060) +#define SYSCTL_PLLCFG MMIO32(SYSCTL_BASE + 0x064) +#define SYSCTL_GPIOHBCTL MMIO32(SYSCTL_BASE + 0x06C) +#define SYSCTL_RCC2 MMIO32(SYSCTL_BASE + 0x070) +#define SYSCTL_MOSCCTL MMIO32(SYSCTL_BASE + 0x07C) +#define SYSCTL_DSLPCLKCFG MMIO32(SYSCTL_BASE + 0x144) +#define SYSCTL_SYSPROP MMIO32(SYSCTL_BASE + 0x14C) +#define SYSCTL_PIOSCCAL MMIO32(SYSCTL_BASE + 0x150) +#define SYSCTL_PIOSCSTAT MMIO32(SYSCTL_BASE + 0x154) +#define SYSCTL_PLLFREQ0 MMIO32(SYSCTL_BASE + 0x160) +#define SYSCTL_PLLFREQ1 MMIO32(SYSCTL_BASE + 0x164) +#define SYSCTL_PLLSTAT MMIO32(SYSCTL_BASE + 0x168) +/* Peripheral present */ +#define SYSCTL_PPWD MMIO32(SYSCTL_BASE + 0x300) +#define SYSCTL_PPTIMER MMIO32(SYSCTL_BASE + 0x304) +#define SYSCTL_PPGPIO MMIO32(SYSCTL_BASE + 0x308) +#define SYSCTL_PPDMA MMIO32(SYSCTL_BASE + 0x30C) +#define SYSCTL_PPHIB MMIO32(SYSCTL_BASE + 0x314) +#define SYSCTL_PPUART MMIO32(SYSCTL_BASE + 0x318) +#define SYSCTL_PPSSI MMIO32(SYSCTL_BASE + 0x31C) +#define SYSCTL_PPI2C MMIO32(SYSCTL_BASE + 0x320) +#define SYSCTL_PPUSB MMIO32(SYSCTL_BASE + 0x328) +#define SYSCTL_PPCAN MMIO32(SYSCTL_BASE + 0x334) +#define SYSCTL_PPADC MMIO32(SYSCTL_BASE + 0x338) +#define SYSCTL_PPACMP MMIO32(SYSCTL_BASE + 0x33C) +#define SYSCTL_PPPWM MMIO32(SYSCTL_BASE + 0x340) +#define SYSCTL_PPQEI MMIO32(SYSCTL_BASE + 0x344) +#define SYSCTL_PPEEPROM MMIO32(SYSCTL_BASE + 0x358) +#define SYSCTL_PPWTIMER MMIO32(SYSCTL_BASE + 0x35C) +/* Peripheral software reset */ +#define SYSCTL_SRWD MMIO32(SYSCTL_BASE + 0x500) +#define SYSCTL_SRTIMER MMIO32(SYSCTL_BASE + 0x504) +#define SYSCTL_SRGPIO MMIO32(SYSCTL_BASE + 0x508) +#define SYSCTL_SRDMA MMIO32(SYSCTL_BASE + 0x50C) +#define SYSCTL_SRHIB MMIO32(SYSCTL_BASE + 0x514) +#define SYSCTL_SRUART MMIO32(SYSCTL_BASE + 0x518) +#define SYSCTL_SRSSI MMIO32(SYSCTL_BASE + 0x51C) +#define SYSCTL_SRI2C MMIO32(SYSCTL_BASE + 0x520) +#define SYSCTL_SRUSB MMIO32(SYSCTL_BASE + 0x528) +#define SYSCTL_SRCAN MMIO32(SYSCTL_BASE + 0x534) +#define SYSCTL_SRADC MMIO32(SYSCTL_BASE + 0x538) +#define SYSCTL_SRACMP MMIO32(SYSCTL_BASE + 0x53C) +#define SYSCTL_SRPWM MMIO32(SYSCTL_BASE + 0x540) +#define SYSCTL_SRQEI MMIO32(SYSCTL_BASE + 0x544) +#define SYSCTL_SREEPROM MMIO32(SYSCTL_BASE + 0x558) +#define SYSCTL_SRWTIMER MMIO32(SYSCTL_BASE + 0x55C) +/* Peripheral run mode clock gating control */ +#define SYSCTL_RCGCWD MMIO32(SYSCTL_BASE + 0x600) +#define SYSCTL_RCGCTIMER MMIO32(SYSCTL_BASE + 0x604) +#define SYSCTL_RCGCGPIO MMIO32(SYSCTL_BASE + 0x608) +#define SYSCTL_RCGCDMA MMIO32(SYSCTL_BASE + 0x60C) +#define SYSCTL_RCGCHIB MMIO32(SYSCTL_BASE + 0x614) +#define SYSCTL_RCGCUART MMIO32(SYSCTL_BASE + 0x618) +#define SYSCTL_RCGCSSI MMIO32(SYSCTL_BASE + 0x61C) +#define SYSCTL_RCGCI2C MMIO32(SYSCTL_BASE + 0x620) +#define SYSCTL_RCGCUSB MMIO32(SYSCTL_BASE + 0x628) +#define SYSCTL_RCGCCAN MMIO32(SYSCTL_BASE + 0x634) +#define SYSCTL_RCGCADC MMIO32(SYSCTL_BASE + 0x638) +#define SYSCTL_RCGCACMP MMIO32(SYSCTL_BASE + 0x63C) +#define SYSCTL_RCGCPWM MMIO32(SYSCTL_BASE + 0x640) +#define SYSCTL_RCGCQEI MMIO32(SYSCTL_BASE + 0x644) +#define SYSCTL_RCGCEEPROM MMIO32(SYSCTL_BASE + 0x658) +#define SYSCTL_RCGCWTIMER MMIO32(SYSCTL_BASE + 0x65C) +/* Peripheral sleep mode clock gating control */ +#define SYSCTL_SCGCWD MMIO32(SYSCTL_BASE + 0x700) +#define SYSCTL_SCGCTIMER MMIO32(SYSCTL_BASE + 0x704) +#define SYSCTL_SCGCGPIO MMIO32(SYSCTL_BASE + 0x708) +#define SYSCTL_SCGCDMA MMIO32(SYSCTL_BASE + 0x70C) +#define SYSCTL_SCGCHIB MMIO32(SYSCTL_BASE + 0x714) +#define SYSCTL_SCGCUART MMIO32(SYSCTL_BASE + 0x718) +#define SYSCTL_SCGCSSI MMIO32(SYSCTL_BASE + 0x71C) +#define SYSCTL_SCGCI2C MMIO32(SYSCTL_BASE + 0x720) +#define SYSCTL_SCGCUSB MMIO32(SYSCTL_BASE + 0x728) +#define SYSCTL_SCGCCAN MMIO32(SYSCTL_BASE + 0x734) +#define SYSCTL_SCGCADC MMIO32(SYSCTL_BASE + 0x738) +#define SYSCTL_SCGCACMP MMIO32(SYSCTL_BASE + 0x73C) +#define SYSCTL_SCGCPWM MMIO32(SYSCTL_BASE + 0x740) +#define SYSCTL_SCGCQEI MMIO32(SYSCTL_BASE + 0x744) +#define SYSCTL_SCGCEEPROM MMIO32(SYSCTL_BASE + 0x758) +#define SYSCTL_SCGCWTIMER MMIO32(SYSCTL_BASE + 0x75C) +/* Peripheral deep-sleep mode clock gating control */ +#define SYSCTL_DCGCWD MMIO32(SYSCTL_BASE + 0x800) +#define SYSCTL_DCGCTIMER MMIO32(SYSCTL_BASE + 0x804) +#define SYSCTL_DCGCGPIO MMIO32(SYSCTL_BASE + 0x808) +#define SYSCTL_DCGCDMA MMIO32(SYSCTL_BASE + 0x80C) +#define SYSCTL_DCGCHIB MMIO32(SYSCTL_BASE + 0x814) +#define SYSCTL_DCGCUART MMIO32(SYSCTL_BASE + 0x818) +#define SYSCTL_DCGCSSI MMIO32(SYSCTL_BASE + 0x81C) +#define SYSCTL_DCGCI2C MMIO32(SYSCTL_BASE + 0x820) +#define SYSCTL_DCGCUSB MMIO32(SYSCTL_BASE + 0x828) +#define SYSCTL_DCGCCAN MMIO32(SYSCTL_BASE + 0x834) +#define SYSCTL_DCGCADC MMIO32(SYSCTL_BASE + 0x838) +#define SYSCTL_DCGCACMP MMIO32(SYSCTL_BASE + 0x83C) +#define SYSCTL_DCGCPWM MMIO32(SYSCTL_BASE + 0x840) +#define SYSCTL_DCGCQEI MMIO32(SYSCTL_BASE + 0x844) +#define SYSCTL_DCGCEEPROM MMIO32(SYSCTL_BASE + 0x858) +#define SYSCTL_DCGCWTIMER MMIO32(SYSCTL_BASE + 0x85C) +/* Peripheral ready */ +#define SYSCTL_PRWD MMIO32(SYSCTL_BASE + 0xA00) +#define SYSCTL_PRTIMER MMIO32(SYSCTL_BASE + 0xA04) +#define SYSCTL_PRGPIO MMIO32(SYSCTL_BASE + 0xA08) +#define SYSCTL_PRDMA MMIO32(SYSCTL_BASE + 0xA0C) +#define SYSCTL_PRHIB MMIO32(SYSCTL_BASE + 0xA14) +#define SYSCTL_PRUART MMIO32(SYSCTL_BASE + 0xA18) +#define SYSCTL_PRSSI MMIO32(SYSCTL_BASE + 0xA1C) +#define SYSCTL_PRI2C MMIO32(SYSCTL_BASE + 0xA20) +#define SYSCTL_PRUSB MMIO32(SYSCTL_BASE + 0xA28) +#define SYSCTL_PRCAN MMIO32(SYSCTL_BASE + 0xA34) +#define SYSCTL_PRADC MMIO32(SYSCTL_BASE + 0xA38) +#define SYSCTL_PRACMP MMIO32(SYSCTL_BASE + 0xA3C) +#define SYSCTL_PRPWM MMIO32(SYSCTL_BASE + 0xA40) +#define SYSCTL_PRQEI MMIO32(SYSCTL_BASE + 0xA44) +#define SYSCTL_PREEPROM MMIO32(SYSCTL_BASE + 0xA58) +#define SYSCTL_PRWTIMER MMIO32(SYSCTL_BASE + 0xA5C) +/* ============================================================================= + * System Control Legacy Registers + * ---------------------------------------------------------------------------*/ +#ifdef LM4F_LEGACY_SYSCTL +#define SYSCTL_DC0 MMIO32(SYSCTL_BASE + 0x008) +#define SYSCTL_DC1 MMIO32(SYSCTL_BASE + 0x010) +#define SYSCTL_DC2 MMIO32(SYSCTL_BASE + 0x014) +#define SYSCTL_DC3 MMIO32(SYSCTL_BASE + 0x018) +#define SYSCTL_DC4 MMIO32(SYSCTL_BASE + 0x01C) +#define SYSCTL_DC5 MMIO32(SYSCTL_BASE + 0x020) +#define SYSCTL_DC6 MMIO32(SYSCTL_BASE + 0x024) +#define SYSCTL_DC7 MMIO32(SYSCTL_BASE + 0x028) +#define SYSCTL_DC8 MMIO32(SYSCTL_BASE + 0x02C) +#define SYSCTL_SRCR0 MMIO32(SYSCTL_BASE + 0x040) +#define SYSCTL_SRCR1 MMIO32(SYSCTL_BASE + 0x044) +#define SYSCTL_SRCR2 MMIO32(SYSCTL_BASE + 0x048) +#define SYSCTL_RCGC0 MMIO32(SYSCTL_BASE + 0x100) +#define SYSCTL_RCGC1 MMIO32(SYSCTL_BASE + 0x104) +#define SYSCTL_RCGC2 MMIO32(SYSCTL_BASE + 0x108) +#define SYSCTL_SCGC0 MMIO32(SYSCTL_BASE + 0x110) +#define SYSCTL_SCGC1 MMIO32(SYSCTL_BASE + 0x114) +#define SYSCTL_SCGC2 MMIO32(SYSCTL_BASE + 0x118) +#define SYSCTL_DCGC0 MMIO32(SYSCTL_BASE + 0x120) +#define SYSCTL_DCGC1 MMIO32(SYSCTL_BASE + 0x124) +#define SYSCTL_DCGC2 MMIO32(SYSCTL_BASE + 0x128) +#define SYSCTL_DC9 MMIO32(SYSCTL_BASE + 0x190) +#define SYSCTL_NVMSTAT MMIO32(SYSCTL_BASE + 0x1A0) +#endif /* LM4F_LEGACY_SYSCTL */ + +/* ============================================================================= + * SYSCTL_DID0 values + * ---------------------------------------------------------------------------*/ +/** DID0 version */ +#define SYSCTL_DID0_VER_MASK (7 << 28) +/** Device class */ +#define SYSCTL_DID0_CLASS_MASK (0xFF << 16) +/** Major revision */ +#define SYSCTL_DID0_MAJOR_MASK (0xFF << 8) +/** Minor revision */ +#define SYSCTL_DID0_MAJOR_MASK (0xFF << 8) + +/* ============================================================================= + * SYSCTL_DID1 values + * ---------------------------------------------------------------------------*/ +/** DID1 version */ +#define SYSCTL_DID1_VER_MASK (0xF << 28) +/** Family */ +#define SYSCTL_DID1_FAM_MASK (0xF << 24) +/** Part number */ +#define SYSCTL_DID1_PARTNO_MASK (0xFF << 16) +/** Pin count */ +#define SYSCTL_DID1_PINCOUNT_MASK (0x7 << 13) +#define SYSCTL_DID1_PINCOUNT_28P (0x0 << 13) +#define SYSCTL_DID1_PINCOUNT_48P (0x1 << 13) +#define SYSCTL_DID1_PINCOUNT_100P (0x2 << 13) +#define SYSCTL_DID1_PINCOUNT_64P (0x3 << 13) +#define SYSCTL_DID1_PINCOUNT_144P (0x4 << 13) +#define SYSCTL_DID1_PINCOUNT_157P (0x5 << 13) +/** Temperature range */ +#define SYSCTL_DID1_TEMP_MASK (0x7 << 5) +#define SYSCTL_DID1_TEMP_0_70 (0x0 << 5) +#define SYSCTL_DID1_TEMP_M40_85 (0x1 << 5) +#define SYSCTL_DID1_TEMP_M40_105 (0x2 << 5) +/** Package */ +#define SYSCTL_DID1_PKG_MASK (0x3 << 5) +#define SYSCTL_DID1_PKG_SOIC (0x0 << 5) +#define SYSCTL_DID1_PKG_LQFP (0x1 << 5) +#define SYSCTL_DID1_PKG_BGA (0x2 << 5) +/** ROHS compliance */ +#define SYSCTL_DID1_ROHS (1 << 2) +/** Qualification status */ +#define SYSCTL_DID1_QUAL_MASK (3 << 0) + +/* ============================================================================= + * SYSCTL_PBORCTL values + * ---------------------------------------------------------------------------*/ +/** BOR interrupt or reset */ +#define SYSCTL_PBORCTL_BORIOR (1 << 1) + +/* ============================================================================= + * SYSCTL_RIS values + * ---------------------------------------------------------------------------*/ +/** MOSC Power Up Raw Interrupt Status */ +#define SYSCTL_RIS_MOSCPUPRIS (1 << 8) +/** USB PLL Lock Raw Interrupt Status */ +#define SYSCTL_RIS_USBPLLLRIS (1 << 7) +/** PLL Lock Raw Interrupt Status */ +#define SYSCTL_RIS_PLLLRIS (1 << 6) +/** Main Oscillator Failure Raw Interrupt Status */ +#define SYSCTL_RIS_MOFRIS (1 << 3) +/** Brown-Out Reset Raw Interrupt Status */ +#define SYSCTL_RIS_BORRIS (1 << 1) + +/* ============================================================================= + * SYSCTL_IMC values + * ---------------------------------------------------------------------------*/ +/** MOSC Power Up Raw Interrupt Status */ +#define SYSCTL_IMC_MOSCPUPIM (1 << 8) +/** USB PLL Lock Raw Interrupt Status */ +#define SYSCTL_IMC_USBPLLLIM (1 << 7) +/** PLL Lock Raw Interrupt Status */ +#define SYSCTL_IMC_PLLLIM (1 << 6) +/** Main Oscillator Failure Raw Interrupt Status */ +#define SYSCTL_IMC_MOFIM (1 << 3) +/** Brown-Out Reset Raw Interrupt Status */ +#define SYSCTL_IMC_BORIM (1 << 1) + +/* ============================================================================= + * SYSCTL_MISC values + * ---------------------------------------------------------------------------*/ +/** MOSC Power Up Raw Interrupt Status */ +#define SYSCTL_MISC_MOSCPUPMIS (1 << 8) +/** USB PLL Lock Raw Interrupt Status */ +#define SYSCTL_MISC_USBPLLLMIS (1 << 7) +/** PLL Lock Raw Interrupt Status */ +#define SYSCTL_MISC_PLLLMIS (1 << 6) +/** Main Oscillator Failure Raw Interrupt Status */ +#define SYSCTL_MISC_MOFMIS (1 << 3) +/** Brown-Out Reset Raw Interrupt Status */ +#define SYSCTL_MISC_BORMIS (1 << 1) + +/* ============================================================================= + * SYSCTL_RESC values + * ---------------------------------------------------------------------------*/ +/** MOSC Failure Reset */ +#define SYSCTL_RESC_MOSCFAIL (1 << 18) +/** Watchdog Timer 1 Reset */ +#define SYSCTL_RESC_WDT1 (1 << 5) +/** Software Reset */ +#define SYSCTL_RESC_SW (1 << 4) +/** Watchdog Timer 0 Reset */ +#define SYSCTL_RESC_WDT0 (1 << 3) +/** Brown-Out Reset */ +#define SYSCTL_RESC_BOR (1 << 2) +/** Power-On Reset */ +#define SYSCTL_RESC_POR (1 << 1) +/** External Reset */ +#define SYSCTL_RESC_EXT (1 << 0) + +/* ============================================================================= + * SYSCTL_RCC values + * ---------------------------------------------------------------------------*/ +/** Auto Clock Gating */ +#define SYSCTL_RCC_ACG (1 << 27) +/** System Clock Divisor */ +#define SYSCTL_RCC_SYSDIV_MASK (0xF << 23) +/** Enable System Clock Divider */ +#define SYSCTL_RCC_USESYSDIV (1 << 22) +/** Enable PWM Clock Divisor */ +#define SYSCTL_RCC_USEPWMDIV (1 << 20) +/** PWM Unit Clock Divisor */ +#define SYSCTL_RCC_PWMDIV_MASK (0xF << 17) +#define SYSCTL_RCC_PWMDIV_2 (0x0 << 17) +#define SYSCTL_RCC_PWMDIV_4 (0x1 << 17) +#define SYSCTL_RCC_PWMDIV_8 (0x2 << 17) +#define SYSCTL_RCC_PWMDIV_16 (0x3 << 17) +#define SYSCTL_RCC_PWMDIV_32 (0x4 << 17) +#define SYSCTL_RCC_PWMDIV_64 (0x5 << 17) +/** PLL Power Down */ +#define SYSCTL_RCC_PWRDN (1 << 13) +/** PLL Bypass */ +#define SYSCTL_RCC_BYPASS (1 << 11) +/** Crystal Value */ +#define SYSCTL_RCC_XTAL_MASK (0x1F << 6) +#define SYSCTL_RCC_XTAL_4M (0x06 << 6) +#define SYSCTL_RCC_XTAL_4M_096 (0x07 << 6) +#define SYSCTL_RCC_XTAL_4M_9152 (0x08 << 6) +#define SYSCTL_RCC_XTAL_5M (0x09 << 6) +#define SYSCTL_RCC_XTAL_5M_12 (0x0A << 6) +#define SYSCTL_RCC_XTAL_6M (0x0B << 6) +#define SYSCTL_RCC_XTAL_6M_144 (0x0C << 6) +#define SYSCTL_RCC_XTAL_7M_3728 (0x0D << 6) +#define SYSCTL_RCC_XTAL_8M (0x0E << 6) +#define SYSCTL_RCC_XTAL_8M_192 (0x0F << 6) +#define SYSCTL_RCC_XTAL_10M (0x10 << 6) +#define SYSCTL_RCC_XTAL_12M (0x11 << 6) +#define SYSCTL_RCC_XTAL_12M_288 (0x12 << 6) +#define SYSCTL_RCC_XTAL_13M_56 (0x13 << 6) +#define SYSCTL_RCC_XTAL_14M_31818 (0x14 << 6) +#define SYSCTL_RCC_XTAL_16M (0x15 << 6) +#define SYSCTL_RCC_XTAL_16M_384 (0x16 << 6) +#define SYSCTL_RCC_XTAL_18M (0x17 << 6) +#define SYSCTL_RCC_XTAL_20M (0x18 << 6) +#define SYSCTL_RCC_XTAL_24M (0x19 << 6) +#define SYSCTL_RCC_XTAL_25M (0x1A << 6) +/** Oscillator Source */ +#define SYSCTL_RCC_OSCSRC_MASK (0x3 << 4) +#define SYSCTL_RCC_OSCSRC_MOSC (0x0 << 4) +#define SYSCTL_RCC_OSCSRC_PIOSC (0x1 << 4) +#define SYSCTL_RCC_OSCSRC_PIOSC_D4 (0x2 << 4) +#define SYSCTL_RCC_OSCSRC_30K (0x3 << 4) +/** Precision Internal Oscillator Disable */ +#define SYSCTL_RCC_IOSCDIS (1 << 1) +/** Main Oscillator Disable */ +#define SYSCTL_RCC_MOSCDIS (1 << 0) + +/* ============================================================================= + * SYSCTL_GPIOHBCTL values + * ---------------------------------------------------------------------------*/ +#define SYSCTL_GPIOHBCTL_PORTQ (1 << 14) +#define SYSCTL_GPIOHBCTL_PORTP (1 << 13) +#define SYSCTL_GPIOHBCTL_PORTN (1 << 12) +#define SYSCTL_GPIOHBCTL_PORTM (1 << 11) +#define SYSCTL_GPIOHBCTL_PORTL (1 << 10) +#define SYSCTL_GPIOHBCTL_PORTK (1 << 9) +#define SYSCTL_GPIOHBCTL_PORTJ (1 << 8) +#define SYSCTL_GPIOHBCTL_PORTH (1 << 7) +#define SYSCTL_GPIOHBCTL_PORTG (1 << 6) +#define SYSCTL_GPIOHBCTL_PORTF (1 << 5) +#define SYSCTL_GPIOHBCTL_PORTE (1 << 4) +#define SYSCTL_GPIOHBCTL_PORTD (1 << 3) +#define SYSCTL_GPIOHBCTL_PORTC (1 << 2) +#define SYSCTL_GPIOHBCTL_PORTB (1 << 1) +#define SYSCTL_GPIOHBCTL_PORTA (1 << 0) + +/* ============================================================================= + * SYSCTL_RCC2 values + * ---------------------------------------------------------------------------*/ +/** RCC2 overides RCC */ +#define SYSCTL_RCC2_USERCC2 (1 << 31) +/** Divide PLL as 400 MHz vs. 200 MHz */ +#define SYSCTL_RCC2_DIV400 (1 << 30) +/** Auto Clock Gating */ +#define SYSCTL_RCC2_ACG (1 << 27) +/** System Clock Divisor 2 */ +#define SYSCTL_RCC2_SYSDIV2_MASK (0x3F << 23) +/** Additional LSB for SYSDIV2 */ +#define SYSCTL_RCC2_SYSDIV2LSB (1 << 22) +/** System clock divisor mask when RCC2_DIV400 is set */ +#define SYSCTL_RCC2_SYSDIV400_MASK (0x7F << 22) +/** Power-Down USB PLL */ +#define SYSCTL_RCC2_USBPWRDN (1 << 14) +/** PLL Power Down 2 */ +#define SYSCTL_RCC2_PWRDN2 (1 << 13) +/** PLL Bypass 2 */ +#define SYSCTL_RCC2_BYPASS2 (1 << 11) +/** Oscillator Source 2 */ +#define SYSCTL_RCC2_OSCSRC2_MASK (0x7 << 4) +#define SYSCTL_RCC2_OSCSRC2_MOSC (0x0 << 4) +#define SYSCTL_RCC2_OSCSRC2_PIOSC (0x1 << 4) +#define SYSCTL_RCC2_OSCSRC2_PIOSC_D4 (0x2 << 4) +#define SYSCTL_RCC2_OSCSRC2_30K (0x3 << 4) +#define SYSCTL_RCC2_OSCSRC2_32K768 (0x7 << 4) + +/* ============================================================================= + * SYSCTL_MOSCCTL values + * ---------------------------------------------------------------------------*/ +/** No Crystal Connected */ +#define SYSCTL_MOSCCTL_NOXTAL (1 << 2) +/** MOSC Failure Action */ +#define SYSCTL_MOSCCTL_MOSCIM (1 << 1) +/** Clock Validation for MOSC */ +#define SYSCTL_MOSCCTL_CVAL (1 << 0) + +/* ============================================================================= + * SYSCTL_DSLPCLKCFG values + * ---------------------------------------------------------------------------*/ +/*TODO*/ + +/* ============================================================================= + * SYSCTL_SYSPROP values + * ---------------------------------------------------------------------------*/ +/** FPU present */ +#define SYSCTL_SYSPROP_FPU (1 << 0) + +/* ============================================================================= + * SYSCTL_PIOSCCAL values + * ---------------------------------------------------------------------------*/ +/** Use User Trim Value */ +#define SYSCTL_PIOSCCAL_UTEN (1 << 31) +/** Start calibration */ +#define SYSCTL_PIOSCCAL_CAL (1 << 9) +/** Update trim */ +#define SYSCTL_PIOSCCAL_UPDATE (1 << 8) +/** User Trim Value */ +#define SYSCTL_PIOSCCAL_UT_MASK (0x7F << 0) + +/* ============================================================================= + * SYSCTL_PIOSCSTAT values + * ---------------------------------------------------------------------------*/ +/** Default Trim Value */ +#define SYSCTL_PIOSCSTAT_DT_MASK (0x7F << 16) +/** Calibration result */ +#define SYSCTL_PIOSCSTAT_RESULT_MASK (0x3 << 8) +/** Calibration Trim Value */ +#define SYSCTL_PIOSCSTAT_CT_MASK (0x7F << 0) +/* ============================================================================= + * SYSCTL_PLLFREQ0 values + * ---------------------------------------------------------------------------*/ +/** PLL M fractional value */ +#define SYSCTL_PLLFREQ0_MFRAC_MASK (0x3FF << 10) +/** PLL M integer value */ +#define SYSCTL_PLLFREQ0_MINT_MASK (0x3FF << 0) + +/* ============================================================================= + * SYSCTL_PLLFREQ1 values + * ---------------------------------------------------------------------------*/ +/** PLL Q value */ +#define SYSCTL_PLLFREQ1_Q_MASK (0x1F << 8) +/** PLL N value */ +#define SYSCTL_PLLFREQ1_N_MASK (0x1F << 0) + +/* ============================================================================= + * SYSCTL_PLLSTAT values + * ---------------------------------------------------------------------------*/ +/** PLL lock */ +#define SYSCTL_PLLSTAT_LOCK (1 << 0) + +/* ============================================================================= + * Convenience definitions for a readable API + * ---------------------------------------------------------------------------*/ +/** + * \brief Clock enable definitions + * + * The definitions are specified in the form + * 31:5 register offset from SYSCTL_BASE for the clock register + * 4:0 bit offset for the given peripheral + * + * The names have the form [clock_type]_[periph_type]_[periph_number] + * Where clock_type is + * RCC for run clock + * SCC for sleep clock + * DCC for deep-sleep clock + */ +enum lm4f_clken { + /* + * Run clock control + */ + RCC_WD0 = ((uint32_t)&SYSCTL_RCGCWD - SYSCTL_BASE) << 5, + RCC_WD1, + + RCC_TIMER0 = ((uint32_t)&SYSCTL_RCGCTIMER - SYSCTL_BASE) << 5, + RCC_TIMER1, + RCC_TIMER2, + RCC_TIMER3, + RCC_TIMER4, + RCC_TIMER5, + + RCC_GPIOA = ((uint32_t)&SYSCTL_RCGCGPIO - SYSCTL_BASE) << 5, + RCC_GPIOB, + RCC_GPIOC, + RCC_GPIOD, + RCC_GPIOE, + RCC_GPIOF, + RCC_GPIOG, + RCC_GPIOH, + RCC_GPIOJ, + RCC_GPIOK, + RCC_GPIOL, + RCC_GPIOM, + RCC_GPION, + RCC_GPIOP, + RCC_GPIOQ, + + RCC_DMA = ((uint32_t)&SYSCTL_RCGCDMA - SYSCTL_BASE) << 5, + + RCC_HIB = ((uint32_t)&SYSCTL_RCGCGPIO - SYSCTL_BASE) << 5, + + RCC_UART0 = ((uint32_t)&SYSCTL_RCGCUART - SYSCTL_BASE) << 5, + RCC_UART1, + RCC_UART2, + RCC_UART3, + RCC_UART4, + RCC_UART5, + RCC_UART6, + RCC_UART7, + + RCC_SSI0 = ((uint32_t)&SYSCTL_RCGCSSI - SYSCTL_BASE) << 5, + RCC_SSI1, + RCC_SSI2, + RCC_SSI3, + + RCC_I2C0 = ((uint32_t)&SYSCTL_RCGCI2C - SYSCTL_BASE) << 5, + RCC_I2C1, + RCC_I2C2, + RCC_I2C3, + RCC_I2C4, + RCC_I2C5, + + RCC_USB0 = ((uint32_t)&SYSCTL_RCGCUSB - SYSCTL_BASE) << 5, + + RCC_CAN0 = ((uint32_t)&SYSCTL_RCGCCAN - SYSCTL_BASE) << 5, + RCC_CAN1, + + RCC_ADC0 = ((uint32_t)&SYSCTL_RCGCADC - SYSCTL_BASE) << 5, + RCC_ADC1, + + RCC_ACMP0 = ((uint32_t)&SYSCTL_RCGCACMP - SYSCTL_BASE) << 5, + + RCC_PWM0 = ((uint32_t)&SYSCTL_RCGCPWM - SYSCTL_BASE) << 5, + RCC_PWM1, + + RCC_QEI0 = ((uint32_t)&SYSCTL_RCGCQEI - SYSCTL_BASE) << 5, + RCC_QEI1, + + RCC_EEPROM0 = ((uint32_t)&SYSCTL_RCGCEEPROM - SYSCTL_BASE) << 5, + + RCC_WTIMER0 = ((uint32_t)&SYSCTL_RCGCWTIMER - SYSCTL_BASE) << 5, + RCC_WTIMER1, + RCC_WTIMER2, + RCC_WTIMER3, + RCC_WTIMER4, + RCC_WTIMER5, + + + /* + * Sleep clock control + */ + SCC_WD0 = ((uint32_t)&SYSCTL_SCGCWD - SYSCTL_BASE) << 5, + SCC_WD1, + + SCC_TIMER0 = ((uint32_t)&SYSCTL_SCGCTIMER - SYSCTL_BASE) << 5, + SCC_TIMER1, + SCC_TIMER2, + SCC_TIMER3, + SCC_TIMER4, + SCC_TIMER5, + + SCC_GPIOA = ((uint32_t)&SYSCTL_SCGCGPIO - SYSCTL_BASE) << 5, + SCC_GPIOB, + SCC_GPIOC, + SCC_GPIOD, + SCC_GPIOE, + SCC_GPIOF, + SCC_GPIOG, + SCC_GPIOH, + SCC_GPIOJ, + SCC_GPIOK, + SCC_GPIOL, + SCC_GPIOM, + SCC_GPION, + SCC_GPIOP, + SCC_GPIOQ, + + SCC_DMA = ((uint32_t)&SYSCTL_SCGCDMA - SYSCTL_BASE) << 5, + + SCC_HIB = ((uint32_t)&SYSCTL_SCGCGPIO - SYSCTL_BASE) << 5, + + SCC_UART0 = ((uint32_t)&SYSCTL_SCGCUART - SYSCTL_BASE) << 5, + SCC_UART1, + SCC_UART2, + SCC_UART3, + SCC_UART4, + SCC_UART5, + SCC_UART6, + SCC_UART7, + + SCC_SSI0 = ((uint32_t)&SYSCTL_SCGCSSI - SYSCTL_BASE) << 5, + SCC_SSI1, + SCC_SSI2, + SCC_SSI3, + + SCC_I2C0 = ((uint32_t)&SYSCTL_SCGCI2C - SYSCTL_BASE) << 5, + SCC_I2C1, + SCC_I2C2, + SCC_I2C3, + SCC_I2C4, + SCC_I2C5, + + SCC_USB0 = ((uint32_t)&SYSCTL_SCGCUSB - SYSCTL_BASE) << 5, + + SCC_CAN0 = ((uint32_t)&SYSCTL_SCGCCAN - SYSCTL_BASE) << 5, + SCC_CAN1, + + SCC_ADC0 = ((uint32_t)&SYSCTL_SCGCADC - SYSCTL_BASE) << 5, + SCC_ADC1, + + SCC_ACMP0 = ((uint32_t)&SYSCTL_SCGCACMP - SYSCTL_BASE) << 5, + + SCC_PWM0 = ((uint32_t)&SYSCTL_SCGCPWM - SYSCTL_BASE) << 5, + SCC_PWM1, + + SCC_QEI0 = ((uint32_t)&SYSCTL_SCGCQEI - SYSCTL_BASE) << 5, + SCC_QEI1, + + SCC_EEPROM0 = ((uint32_t)&SYSCTL_SCGCEEPROM - SYSCTL_BASE) << 5, + + SCC_WTIMER0 = ((uint32_t)&SYSCTL_SCGCWTIMER - SYSCTL_BASE) << 5, + SCC_WTIMER1, + SCC_WTIMER2, + SCC_WTIMER3, + SCC_WTIMER4, + SCC_WTIMER5, + + /* + * Deep-sleep clock control + */ + DCC_WD0 = ((uint32_t)&SYSCTL_DCGCWD - SYSCTL_BASE) << 5, + DCC_WD1, + + DCC_TIMER0 = ((uint32_t)&SYSCTL_DCGCTIMER - SYSCTL_BASE) << 5, + DCC_TIMER1, + DCC_TIMER2, + DCC_TIMER3, + DCC_TIMER4, + DCC_TIMER5, + + DCC_GPIOA = ((uint32_t)&SYSCTL_DCGCGPIO - SYSCTL_BASE) << 5, + DCC_GPIOB, + DCC_GPIOC, + DCC_GPIOD, + DCC_GPIOE, + DCC_GPIOF, + DCC_GPIOG, + DCC_GPIOH, + DCC_GPIOJ, + DCC_GPIOK, + DCC_GPIOL, + DCC_GPIOM, + DCC_GPION, + DCC_GPIOP, + DCC_GPIOQ, + + DCC_DMA = ((uint32_t)&SYSCTL_DCGCDMA - SYSCTL_BASE) << 5, + + DCC_HIB = ((uint32_t)&SYSCTL_DCGCGPIO - SYSCTL_BASE) << 5, + + DCC_UART0 = ((uint32_t)&SYSCTL_DCGCUART - SYSCTL_BASE) << 5, + DCC_UART1, + DCC_UART2, + DCC_UART3, + DCC_UART4, + DCC_UART5, + DCC_UART6, + DCC_UART7, + + DCC_SSI0 = ((uint32_t)&SYSCTL_DCGCSSI - SYSCTL_BASE) << 5, + DCC_SSI1, + DCC_SSI2, + DCC_SSI3, + + DCC_I2C0 = ((uint32_t)&SYSCTL_DCGCI2C - SYSCTL_BASE) << 5, + DCC_I2C1, + DCC_I2C2, + DCC_I2C3, + DCC_I2C4, + DCC_I2C5, + + DCC_USB0 = ((uint32_t)&SYSCTL_DCGCUSB - SYSCTL_BASE) << 5, + + DCC_CAN0 = ((uint32_t)&SYSCTL_DCGCCAN - SYSCTL_BASE) << 5, + DCC_CAN1, + + DCC_ADC0 = ((uint32_t)&SYSCTL_DCGCADC - SYSCTL_BASE) << 5, + DCC_ADC1, + + DCC_ACMP0 = ((uint32_t)&SYSCTL_DCGCACMP - SYSCTL_BASE) << 5, + + DCC_PWM0 = ((uint32_t)&SYSCTL_DCGCPWM - SYSCTL_BASE) << 5, + DCC_PWM1, + + DCC_QEI0 = ((uint32_t)&SYSCTL_DCGCQEI - SYSCTL_BASE) << 5, + DCC_QEI1, + + DCC_EEPROM0 = ((uint32_t)&SYSCTL_DCGCEEPROM - SYSCTL_BASE) << 5, + + DCC_WTIMER0 = ((uint32_t)&SYSCTL_DCGCWTIMER - SYSCTL_BASE) << 5, + DCC_WTIMER1, + DCC_WTIMER2, + DCC_WTIMER3, + DCC_WTIMER4, + DCC_WTIMER5, + +}; + +/* ============================================================================ + * Function prototypes + * --------------------------------------------------------------------------*/ +BEGIN_DECLS + +void periph_clock_enable(enum lm4f_clken periph); +void periph_clock_disable(enum lm4f_clken periph); + +END_DECLS + +/**@}*/ + +#endif /* LM4F_SYSTEMCONTROL_H */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/uart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/uart.h new file mode 100644 index 00000000..f36556ee --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/uart.h @@ -0,0 +1,550 @@ +/** @defgroup uart_defines UART Control + * + * @brief Defined Constants and Types for the LM4F UART Control + * + * @ingroup LM4Fxx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Alexandru Gagniuc + * + * @date 07 May 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_LM4F_UART_H +#define LIBOPENCM3_LM4F_UART_H + +/**@{*/ + +#include +#include + +/* ============================================================================= + * Convenience macros + * ---------------------------------------------------------------------------*/ +/** @defgroup uart_reg_base UART register base addresses + * @{*/ +#define UART0 UART0_BASE +#define UART1 UART1_BASE +#define UART2 UART2_BASE +#define UART3 UART3_BASE +#define UART4 UART4_BASE +#define UART5 UART5_BASE +#define UART6 UART6_BASE +#define UART7 UART7_BASE +/** @} */ + +/* ============================================================================= + * UART registers + * ---------------------------------------------------------------------------*/ + +/* UART data register */ +#define UART_DR(uart_base) MMIO32((uart_base) + 0x00) + +/* UART Receive Status/Error Clear register */ +#define UART_RSR(uart_base) MMIO32((uart_base) + 0x04) +#define UART_ECR(uart_base) MMIO32((uart_base) + 0x04) + +/* UART Flag register */ +#define UART_FR(uart_base) MMIO32((uart_base) + 0x18) + +/* UART IrDA Low-Power register */ +#define UART_ILPR(uart_base) MMIO32((uart_base) + 0x20) + +/* UART Integer baudrate divisor */ +#define UART_IBRD(uart_base) MMIO32((uart_base) + 0x24) + +/* UART Fractional baudrate divisor */ +#define UART_FBRD(uart_base) MMIO32((uart_base) + 0x28) + +/* UART Line control */ +#define UART_LCRH(uart_base) MMIO32((uart_base) + 0x2C) + +/* UART Control */ +#define UART_CTL(uart_base) MMIO32((uart_base) + 0x30) + +/* UART Interrupt FIFO level select */ +#define UART_IFLS(uart_base) MMIO32((uart_base) + 0x34) + +/* UART Interrupt mask */ +#define UART_IM(uart_base) MMIO32((uart_base) + 0x38) + +/* UART Raw interrupt status */ +#define UART_RIS(uart_base) MMIO32((uart_base) + 0x3C) + +/* UART Masked Interrupt status */ +#define UART_MIS(uart_base) MMIO32((uart_base) + 0x40) + +/* UART Interrupt Clear */ +#define UART_ICR(uart_base) MMIO32((uart_base) + 0x44) + +/* UART DMA control */ +#define UART_DMACTL(uart_base) MMIO32((uart_base) + 0x48) + +/* UART LIN control */ +#define UART_LCTL(uart_base) MMIO32((uart_base) + 0x90) + +/* UART LIN snap shot */ +#define UART_LSS(uart_base) MMIO32((uart_base) + 0x94) + +/* UART LIN timer */ +#define UART_LTIM(uart_base) MMIO32((uart_base) + 0x98) + +/* UART 9-Bit self address */ +#define UART_9BITADDR(uart_base) MMIO32((uart_base) + 0xA4) + +/* UART 9-Bit self address mask */ +#define UART_9BITAMASK(uart_base) MMIO32((uart_base) + 0xA8) + +/* UART Peripheral properties */ +#define UART_PP(uart_base) MMIO32((uart_base) + 0xFC0) + +/* UART Clock configuration */ +#define UART_CC(uart_base) MMIO32((uart_base) + 0xFC8) + +/* UART Peripheral Identification 4 */ +#define UART_PERIPH_ID4(uart_base) MMIO32((uart_base) + 0xFD0) + +/* UART Peripheral Identification 5 */ +#define UART_PERIPH_ID5(uart_base) MMIO32((uart_base) + 0xFD4) + +/* UART Peripheral Identification 6 */ +#define UART_PERIPH_ID6(uart_base) MMIO32((uart_base) + 0xFD8) + +/* UART Peripheral Identification 7 */ +#define UART_PERIPH_ID7(uart_base) MMIO32((uart_base) + 0xFDC) + +/* UART Peripheral Identification 0 */ +#define UART_PERIPH_ID0(uart_base) MMIO32((uart_base) + 0xFE0) + +/* UART Peripheral Identification 1 */ +#define UART_PERIPH_ID1(uart_base) MMIO32((uart_base) + 0xFE4) + +/* UART Peripheral Identification 2 */ +#define UART_PERIPH_ID2(uart_base) MMIO32((uart_base) + 0xFE8) + +/* UART Peripheral Identification 3 */ +#define UART_PERIPH_ID3(uart_base) MMIO32((uart_base) + 0xFEC) + +/* UART PrimeCell Identification 0 */ +#define UART_PCELL_ID0(uart_base) MMIO32((uart_base) + 0xFF0) + +/* UART PrimeCell Identification 1 */ +#define UART_PCELL_ID1(uart_base) MMIO32((uart_base) + 0xFF4) + +/* UART PrimeCell Identification 2 */ +#define UART_PCELL_ID2(uart_base) MMIO32((uart_base) + 0xFF8) + +/* UART PrimeCell Identification 3 */ +#define UART_PCELL_ID3(uart_base) MMIO32((uart_base) + 0xFFC) + + +/* ============================================================================= + * UART_DR values + * ---------------------------------------------------------------------------*/ +/** Overrun Error */ +#define UART_DR_OE (1 << 11) +/** Break Error */ +#define UART_DR_BE (1 << 10) +/** Parity Error */ +#define UART_DR_PE (1 << 9) +/** Framing Error */ +#define UART_DR_FE (1 << 8) +/** Data transmitted or received */ +#define UART_DR_DATA_MASK (0xFF << 0) + +/* ============================================================================= + * Readonly UART_RSR values + * ---------------------------------------------------------------------------*/ +/** Overrun Error */ +#define UART_RSR_OE (1 << 3) +/** Break Error */ +#define UART_RSR_BE (1 << 2) +/** Parity Error */ +#define UART_RSR_PE (1 << 1) +/** Framing Error */ +#define UART_RSR_FE (1 << 0) + +/* ============================================================================= + * UART_FR values + * ---------------------------------------------------------------------------*/ +/** Tx FIFO empty */ +#define UART_FR_TXFE (1 << 7) +/** Rx FIFO full */ +#define UART_FR_RXFF (1 << 6) +/** Tx FIFO full */ +#define UART_FR_TXFF (1 << 5) +/** Rx FIFO empty */ +#define UART_FR_RXFE (1 << 4) +/** UART Busy */ +#define UART_FR_BUSY (1 << 3) +/** Clear To Send */ +#define UART_FR_CTS (1 << 0) + +/* ============================================================================= + * UART_LCRH values + * ---------------------------------------------------------------------------*/ +/** Stick parity select */ +#define UART_LCRH_SPS (1 << 7) +/** Word length */ +#define UART_LCRH_WLEN_MASK (3 << 5) +#define UART_LCRH_WLEN_5 (0 << 5) +#define UART_LCRH_WLEN_6 (1 << 5) +#define UART_LCRH_WLEN_7 (2 << 5) +#define UART_LCRH_WLEN_8 (3 << 5) +/** Enable FIFOs */ +#define UART_LCRH_FEN (1 << 4) +/** Two stop bits select */ +#define UART_LCRH_STP2 (1 << 3) +/** Even parity select */ +#define UART_LCRH_EPS (1 << 2) +/** Parity enable */ +#define UART_LCRH_PEN (1 << 1) +/** Send break */ +#define UART_LCRH_BRK (1 << 0) + +/* ============================================================================= + * UART_CTL values + * ---------------------------------------------------------------------------*/ +/** Enable Clear To Send */ +#define UART_CTL_CTSEN (1 << 15) +/** Enable Request To Send */ +#define UART_CTL_RTSEN (1 << 14) +/** Request To Send */ +#define UART_CTL_RTS (1 << 11) +/** Data terminal ready */ +#define UART_CTL_DTR (1 << 10) +/** Rx Enable */ +#define UART_CTL_RXE (1 << 9) +/** Tx Enable */ +#define UART_CTL_TXE (1 << 8) +/** Loop back enable */ +#define UART_CTL_LBE (1 << 7) +/** LIN mode enable */ +#define UART_CTL_LIN (1 << 6) +/** High speed Enable */ +#define UART_CTL_HSE (1 << 5) +/** End of transmission */ +#define UART_CTL_EOT (1 << 4) +/** ISO 7816 Smart Card support */ +#define UART_CTL_SMART (1 << 3) +/** SIR low-power mode */ +#define UART_CTL_SIRLIP (1 << 2) +/** SIR enable */ +#define UART_CTL_SIREN (1 << 1) +/** UART enable */ +#define UART_CTL_UARTEN (1 << 0) + +/* ============================================================================= + * UART_IFLS values + * ---------------------------------------------------------------------------*/ +/** UART Rx interrupt FIFO level select */ +#define UART_IFLS_RXIFLSEL_MASK (7 << 3) +#define UART_IFLS_RXIFLSEL_1_8 (0 << 3) +#define UART_IFLS_RXIFLSEL_1_4 (1 << 3) +#define UART_IFLS_RXIFLSEL_1_2 (2 << 3) +#define UART_IFLS_RXIFLSEL_3_4 (3 << 3) +#define UART_IFLS_RXIFLSEL_7_8 (4 << 3) +/** UART Tx interrupt FIFO level select */ +#define UART_IFLS_TXIFLSEL_MASK (7 << 0) +#define UART_IFLS_TXIFLSEL_7_8 (0 << 0) +#define UART_IFLS_TXIFLSEL_3_4 (1 << 0) +#define UART_IFLS_TXIFLSEL_1_2 (2 << 0) +#define UART_IFLS_TXIFLSEL_1_4 (3 << 0) +#define UART_IFLS_TXIFLSEL_1_8 (4 << 0) + +/* ============================================================================= + * UART interrupt mask values + * + * These are interchangeable across UART_IM, UART_RIS, UART_MIS, and UART_ICR + * registers. + * ---------------------------------------------------------------------------*/ +/** LIN mode edge 5 interrupt mask */ +#define UART_IM_LME5IM (1 << 15) +/** LIN mode edge 1 interrupt mask */ +#define UART_IM_LME1IM (1 << 14) +/** LIN mode sync break interrupt mask */ +#define UART_IM_LMSBIM (1 << 13) +/** 9-bit mode interrupt mask */ +#define UART_IM_9BITIM (1 << 12) +/** Overrun error interrupt mask */ +#define UART_IM_OEIM (1 << 10) +/** Break error interrupt mask */ +#define UART_IM_BEIM (1 << 9) +/** Parity error interrupt mask */ +#define UART_IM_PEIM (1 << 8) +/** Framing error interrupt mask */ +#define UART_IM_FEIM (1 << 7) +/** Receive time-out interrupt mask */ +#define UART_IM_RTIM (1 << 6) +/** Transmit interrupt mask */ +#define UART_IM_TXIM (1 << 5) +/** Receive interrupt mask */ +#define UART_IM_RXIM (1 << 4) +/** Data Set Ready modem interrupt mask */ +#define UART_IM_DSRIM (1 << 3) +/** Data Carrier Detect modem interrupt mask */ +#define UART_IM_DCDIM (1 << 2) +/** Clear To Send modem interrupt mask */ +#define UART_IM_CTSIM (1 << 1) +/** Ring Indicator modem interrupt mask */ +#define UART_IM_RIIM (1 << 0) + +/* ============================================================================= + * UART_DMACTL values + * ---------------------------------------------------------------------------*/ +/** DMA on error */ +#define UART_DMACTL_DMAERR (1 << 2) +/** Transmit DMA enable */ +#define UART_DMACTL_TXDMAE (1 << 1) +/** Receive DMA enable */ +#define UART_DMACTL_RXDMAE (1 << 0) + +/* ============================================================================= + * UART_LCTL values + * ---------------------------------------------------------------------------*/ +/** Sync break length */ +#define UART_LCTL_BLEN_MASK (3 << 4) +#define UART_LCTL_BLEN_16T (3 << 4) +#define UART_LCTL_BLEN_15T (2 << 4) +#define UART_LCTL_BLEN_14T (1 << 4) +#define UART_LCTL_BLEN_13T (0 << 4) +/** LIN master enable */ +#define UART_LCTL_MASTER (1 << 0) + +/* ============================================================================= + * UART_9BITADDR values + * ---------------------------------------------------------------------------*/ +/** Enable 9-bit mode */ +#define UART_UART_9BITADDR_9BITEN (1 << 15) +/** Self-address for 9-bit mode */ +#define UART_UART_9BITADDR_ADDR_MASK (0xFF << 0) + +/* ============================================================================= + * UART_PP values + * ---------------------------------------------------------------------------*/ +/** 9-bit support */ +#define UART_UART_PP_NB (1 << 1) +/** Smart Card support */ +#define UART_UART_PP_SC (1 << 0) + +/* ============================================================================= + * UART_CC values + * ---------------------------------------------------------------------------*/ +/** UART baud clock source */ +#define UART_CC_CS_MASK (0xF << 0) +#define UART_CC_CS_SYSCLK (0x0 << 0) +#define UART_CC_CS_PIOSC (0x5 << 0) + +/* ============================================================================= + * Convenience enums + * ---------------------------------------------------------------------------*/ +enum uart_parity { + UART_PARITY_NONE, + UART_PARITY_ODD, + UART_PARITY_EVEN, + UART_PARITY_STICK_0, + UART_PARITY_STICK_1, +}; + +enum uart_flowctl { + UART_FLOWCTL_NONE, + UART_FLOWCTL_RTS, + UART_FLOWCTL_CTS, + UART_FLOWCTL_RTS_CTS, +}; + +/** + * \brief UART interrupt masks + * + * These masks can be OR'ed together to specify more than one interrupt. For + * example, (UART_INT_TXIM | UART_INT_TXIM) specifies both Rx and Tx Interrupt. + */ +enum uart_interrupt_flag { + + UART_INT_LME5 = UART_IM_LME5IM, + UART_INT_LME1 = UART_IM_LME1IM, + UART_INT_LMSB = UART_IM_LMSBIM, + UART_INT_9BIT = UART_IM_9BITIM, + UART_INT_OE = UART_IM_OEIM, + UART_INT_BE = UART_IM_BEIM, + UART_INT_PE = UART_IM_PEIM, + UART_INT_FE = UART_IM_FEIM, + UART_INT_RT = UART_IM_RTIM, + UART_INT_TX = UART_IM_TXIM, + UART_INT_RX = UART_IM_RXIM, + UART_INT_DSR = UART_IM_DSRIM, + UART_INT_DCD = UART_IM_DCDIM, + UART_INT_CTS = UART_IM_CTSIM, + UART_INT_RI = UART_IM_RIIM, +}; + +/** + * \brief UART RX FIFO interrupt trigger levels + * + * The levels indicate how full the FIFO should be before an interrupt is + * generated. UART_FIFO_RX_TRIG_3_4 means that an interrupt is triggered when + * the FIFO is 3/4 full. As the FIFO is 8 elements deep, 1/8 is equal to being + * triggered by a single character. + */ +enum uart_fifo_rx_trigger_level { + UART_FIFO_RX_TRIG_1_8 = UART_IFLS_RXIFLSEL_1_8, + UART_FIFO_RX_TRIG_1_4 = UART_IFLS_RXIFLSEL_1_4, + UART_FIFO_RX_TRIG_1_2 = UART_IFLS_RXIFLSEL_1_2, + UART_FIFO_RX_TRIG_3_4 = UART_IFLS_RXIFLSEL_3_4, + UART_FIFO_RX_TRIG_7_8 = UART_IFLS_RXIFLSEL_7_8 +}; + +/** + * \brief UART TX FIFO interrupt trigger levels + * + * The levels indicate how empty the FIFO should be before an interrupt is + * generated. Note that this indicates the emptiness of the FIFO and not the + * fullness. This is somewhat confusing, but it follows the wording of the + * LM4F120H5QR datasheet. + * + * UART_FIFO_TX_TRIG_3_4 means that an interrupt is triggered when the FIFO is + * 3/4 empty. As the FIFO is 8 elements deep, 7/8 is equal to being triggered + * by a single character. + */ +enum uart_fifo_tx_trigger_level { + UART_FIFO_TX_TRIG_7_8 = UART_IFLS_TXIFLSEL_7_8, + UART_FIFO_TX_TRIG_3_4 = UART_IFLS_TXIFLSEL_3_4, + UART_FIFO_TX_TRIG_1_2 = UART_IFLS_TXIFLSEL_1_2, + UART_FIFO_TX_TRIG_1_4 = UART_IFLS_TXIFLSEL_1_4, + UART_FIFO_TX_TRIG_1_8 = UART_IFLS_TXIFLSEL_1_8 +}; + +/* ============================================================================= + * Function prototypes + * ---------------------------------------------------------------------------*/ +BEGIN_DECLS + +void uart_set_baudrate(uint32_t uart, uint32_t baud); +void uart_set_databits(uint32_t uart, uint8_t databits); +void uart_set_stopbits(uint32_t uart, uint8_t stopbits); +void uart_set_parity(uint32_t uart, enum uart_parity parity); +void uart_set_mode(uint32_t uart, uint32_t mode); +void uart_set_flow_control(uint32_t uart, enum uart_flowctl flow); +void uart_enable(uint32_t uart); +void uart_disable(uint32_t uart); +void uart_clock_from_piosc(uint32_t uart); +void uart_clock_from_sysclk(uint32_t uart); + +void uart_send(uint32_t uart, uint16_t data); +uint16_t uart_recv(uint32_t uart); +void uart_wait_send_ready(uint32_t uart); +void uart_wait_recv_ready(uint32_t uart); +void uart_send_blocking(uint32_t uart, uint16_t data); +uint16_t uart_recv_blocking(uint32_t uart); + +void uart_enable_rx_dma(uint32_t uart); +void uart_disable_rx_dma(uint32_t uart); +void uart_enable_tx_dma(uint32_t uart); +void uart_disable_tx_dma(uint32_t uart); + +void uart_enable_fifo(uint32_t uart); +void uart_disable_fifo(uint32_t uart); +void uart_set_fifo_trigger_levels(uint32_t uart, + enum uart_fifo_rx_trigger_level rx_level, + enum uart_fifo_tx_trigger_level tx_level); + +/* We inline FIFO full/empty checks as they are intended to be called from ISRs + * */ +/** @ingroup uart_fifo + * @{ + * \brief Determine if the TX fifo is full + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +static inline +bool uart_is_tx_fifo_full(uint32_t uart) +{ + return UART_FR(uart) & UART_FR_TXFF; +} + + +/** + * \brief Determine if the TX fifo is empty + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +static inline +bool uart_is_tx_fifo_empty(uint32_t uart) +{ + return UART_FR(uart) & UART_FR_TXFE; +} + +/** + * \brief Determine if the RX fifo is full + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +static inline +bool uart_is_rx_fifo_full(uint32_t uart) +{ + return UART_FR(uart) & UART_FR_RXFF; +} + +/** + * \brief Determine if the RX fifo is empty + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +static inline +bool uart_is_rx_fifo_empty(uint32_t uart) +{ + return UART_FR(uart) & UART_FR_RXFE; +} +/**@}*/ + +void uart_enable_interrupts(uint32_t uart, enum uart_interrupt_flag ints); +void uart_disable_interrupts(uint32_t uart, enum uart_interrupt_flag ints); +void uart_enable_rx_interrupt(uint32_t uart); +void uart_disable_rx_interrupt(uint32_t uart); +void uart_enable_tx_interrupt(uint32_t uart); +void uart_disable_tx_interrupt(uint32_t uart); +void uart_clear_interrupt_flag(uint32_t uart, enum uart_interrupt_flag ints); + +/* Let's keep this one inlined. It's designed to be used in ISRs */ +/** @ingroup uart_irq + * @{ + * \brief Determine if interrupt is generated by the given source + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] source source to check. + */ +static inline +bool uart_is_interrupt_source(uint32_t uart, enum uart_interrupt_flag source) +{ + return UART_MIS(uart) & source; +} +/**@}*/ + +END_DECLS + +/**@}*/ + +#endif /* LIBOPENCM3_LM4F_UART_H */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/usb.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/usb.h new file mode 100644 index 00000000..0463d4b1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lm4f/usb.h @@ -0,0 +1,422 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @defgroup usb_defines USB Controller + * + * @brief Defined Constants and Types for the LM4F USB Controller + * + * @ingroup LM4Fxx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 Alexandru Gagniuc + * + * @date 15 May 2013 + * + * LGPL License Terms @ref lgpl_license + */ + + +#ifndef LIBOPENCM3_LM4F_USB_H +#define LIBOPENCM3_LM4F_USB_H + +/**@{*/ + +#include +#include + +/* ============================================================================ + * USB registers + * --------------------------------------------------------------------------*/ + +/* USB Device Functional Address */ +#define USB_FADDR MMIO8(USB_BASE + 0x00) + +/* USB Power */ +#define USB_POWER MMIO8(USB_BASE + 0x01) + +/* USB Transmit Interrupt Status */ +#define USB_TXIS MMIO16(USB_BASE + 0x02) + +/* USB Receive Interrupt Status */ +#define USB_RXIS MMIO16(USB_BASE + 0x04) + +/* USB Transmit Interrupt Enable */ +#define USB_TXIE MMIO16(USB_BASE + 0x06) + +/* USB Receive Interrupt Enable */ +#define USB_RXIE MMIO16(USB_BASE + 0x08) + +/* USB General Interrupt Status */ +#define USB_IS MMIO8(USB_BASE + 0x0A) + +/* USB Interrupt Enable */ +#define USB_IE MMIO8(USB_BASE + 0x0B) + +/* USB Frame Value */ +#define USB_FRAME MMIO16(USB_BASE + 0x0C) + +/* USB Endpoint Index */ +#define USB_EPIDX MMIO8(USB_BASE + 0x0E) + +/* USB Test Mode */ +#define USB_TEST MMIO8(USB_BASE + 0x0F) + +/* USB FIFO Endpoint [0-7] */ +#define USB_FIFO8(n) MMIO8(USB_BASE + 0x20 + (n)*0x04) +#define USB_FIFO16(n) MMIO16(USB_BASE + 0x20 + (n)*0x04) +#define USB_FIFO32(n) MMIO32(USB_BASE + 0x20 + (n)*0x04) + +/* USB Transmit Dynamic FIFO Sizing */ +#define USB_TXFIFOSZ MMIO8(USB_BASE + 0x62) + +/* USB Receive Dynamic FIFO Sizing */ +#define USB_RXFIFOSZ MMIO8(USB_BASE + 0x63) + +/* USB Transmit FIFO Start Address */ +#define USB_TXFIFOADD MMIO16(USB_BASE + 0x64) + +/* USB Receive FIFO Start Address */ +#define USB_RXFIFOADD MMIO16(USB_BASE + 0x66) + +/* USB Connect Timing */ +#define USB_CONTIM MMIO8(USB_BASE + 0x7A) + +/* USB Full-Speed Last Transaction to End of Frame Timing */ +#define USB_FSEOF MMIO8(USB_BASE + 0x7D) + +/* USB Low-Speed Last Transaction to End of Frame Timing */ +#define USB_LSEOF MMIO8(USB_BASE + 0x7E) + +/* USB Control and Status Endpoint 0 Low */ +#define USB_CSRL0 MMIO8(USB_BASE + 0x102) + +/* USB Control and Status Endpoint 0 High */ +#define USB_CSRH0 MMIO8(USB_BASE + 0x103) + +/* USB Receive Byte Count Endpoint 0 */ +#define USB_COUNT0 MMIO8(USB_BASE + 0x108) + +/* USB Maximum Transmit Data Endpoint [1-7] */ +#define USB_TXMAXP(n) MMIO16(USB_BASE + 0x100 + (n)*0x10) + +/* USB Transmit Control and Status Endpoint [1-7] Low */ +#define USB_TXCSRL(n) MMIO8(USB_BASE + 0x102 + (n)*0x10) + +/* USB Transmit Control and Status Endpoint [1-7] High */ +#define USB_TXCSRH(n) MMIO8(USB_BASE + 0x103 + (n)*0x10) + +/* USB Maximum Receive Data Endpoint [1-7] */ +#define USB_RXMAXP(n) MMIO16(USB_BASE + 0x104 + (n)*0x10) + +/* USB Receive Control and Status Endpoint [1-7] Low */ +#define USB_RXCSRL(n) MMIO8(USB_BASE + 0x106 + (n)*0x10) + +/* USB Receive Control and Status Endpoint [1-7] High */ +#define USB_RXCSRH(n) MMIO8(USB_BASE + 0x107 + (n)*0x10) + +/* USB Receive Byte Count Endpoint [1-7] */ +#define USB_RXCOUNT(n) MMIO16(USB_BASE + 0x108 + (n)*0x10) + +/* USB Receive Double Packet Buffer Disable */ +#define USB_RXDPKTBUFDIS MMIO16(USB_BASE + 0x340) + +/* USB Transmit Double Packet Buffer Disable */ +#define USB_TXDPKTBUFDIS MMIO16(USB_BASE + 0x342) + +/* USB Device RESUME Raw Interrupt Status */ +#define USB_DRRIS MMIO32(USB_BASE + 0x410) + +/* USB Device RESUME Interrupt Mask */ +#define USB_DRIM MMIO32(USB_BASE + 0x414) + +/* USB Device RESUME Interrupt Status and Clear */ +#define USB_DRISC MMIO32(USB_BASE + 0x418) + +/* USB DMA Select */ +#define USB_DMASEL MMIO32(USB_BASE + 0x450) + +/* USB Peripheral Properties */ +#define USB_PP MMIO32(USB_BASE + 0xFC0) + + +/* ============================================================================= + * USB_FADDR values + * ---------------------------------------------------------------------------*/ +/** Function Address */ +#define USB_FADDR_FUNCADDR_MASK (0x3f << 0) + +/* ============================================================================= + * USB_POWER values + * ---------------------------------------------------------------------------*/ +/** Isochronous Update */ +#define USB_POWER_ISOUP (1 << 7) +/** Soft Connect/Disconnect */ +#define USB_POWER_SOFTCONN (1 << 6) +/** RESET signaling */ +#define USB_POWER_RESET (1 << 3) +/** RESUME signaling */ +#define USB_POWER_RESUME (1 << 2) +/** SUSPEND mode */ +#define USB_POWER_SUSPEND (1 << 1) +/** Power down PHY */ +#define USB_POWER_PWRDNPHY (1 << 0) + +/* ============================================================================= + * Endpoint bitmasks for interrupt status and control registers + * Applies to USB_TXIS, USB_RXIS, USB_TXIE, USB_RXIE, USB_RXDPKTBUFDIS, + * USB_TXDPKTBUFDIS + * ---------------------------------------------------------------------------*/ +#define USB_EP7 (1 << 7) +#define USB_EP6 (1 << 6) +#define USB_EP5 (1 << 5) +#define USB_EP4 (1 << 4) +#define USB_EP3 (1 << 3) +#define USB_EP2 (1 << 2) +#define USB_EP1 (1 << 1) +#define USB_EP0 (1 << 0) + +/* ============================================================================= + * USB interrupt mask values + * + * These are interchangeable across USB_IS, and USB_IE registers. + * ---------------------------------------------------------------------------*/ +/** USB disconnect interrupt */ +#define USB_IM_DISCON (1 << 5) +/** Start of frame */ +#define USB_IM_SOF (1 << 3) +/** RESET signaling detected */ +#define USB_IM_RESET (1 << 2) +/** RESUME signaling detected */ +#define USB_IM_RESUME (1 << 1) +/** SUSPEND signaling detected */ +#define USB_IM_SUSPEND (1 << 0) + +/* ============================================================================= + * USB_FRAME values + * ---------------------------------------------------------------------------*/ +/** Frame number */ +#define USB_FRAME_MASK (0x03FF) + +/* ============================================================================= + * USB_IDX values + * ---------------------------------------------------------------------------*/ +/** Endpoint Index */ +#define USB_EPIDX_MASK (0x0F) + +/* ============================================================================= + * USB_TEST values + * ---------------------------------------------------------------------------*/ +/** FIFO access */ +#define USB_TEST_FIFOACC (1 << 6) +/** Force full-speed mode */ +#define USB_TEST_FORCEFS (1 << 5) + +/* ============================================================================= + * USB_TXFIFOSZ and USB_RXFIFOSZ values + * ---------------------------------------------------------------------------*/ +/** Double packet buffer support */ +#define USB_FIFOSZ_DPB (1 << 4) +/* USB Transmit Dynamic FIFO Sizing */ +#define USB_FIFOSZ_SIZE_MASK (0x0F << 0) +#define USB_FIFOSZ_SIZE_8 (0x00 << 0) +#define USB_FIFOSZ_SIZE_16 (0x01 << 0) +#define USB_FIFOSZ_SIZE_32 (0x02 << 0) +#define USB_FIFOSZ_SIZE_64 (0x03 << 0) +#define USB_FIFOSZ_SIZE_128 (0x04 << 0) +#define USB_FIFOSZ_SIZE_256 (0x05 << 0) +#define USB_FIFOSZ_SIZE_512 (0x06 << 0) +#define USB_FIFOSZ_SIZE_1024 (0x07 << 0) +#define USB_FIFOSZ_SIZE_2048 (0x08 << 0) + + +/* ============================================================================= + * USB_CONTIM values + * ---------------------------------------------------------------------------*/ +/** Connect wait */ +#define USB_CONTIM_WTCON_MASK (0x0F << 4) +/** Wait ID */ +#define USB_CONTIM_WTID_MASK (0x0F << 0) + +/* ============================================================================= + * USB_CSRL0 values + * ---------------------------------------------------------------------------*/ +/** Setup End Clear */ +#define USB_CSRL0_SETENDC (1 << 7) +/** RXRDY Clear */ +#define USB_CSRL0_RXRDYC (1 << 6) +/** Send Stall */ +#define USB_CSRL0_STALL (1 << 5) +/** Setup End */ +#define USB_CSRL0_SETEND (1 << 4) +/** Data End */ +#define USB_CSRL0_DATAEND (1 << 3) +/** Endpoint Stalled */ +#define USB_CSRL0_STALLED (1 << 2) +/** Transmit Packet Ready */ +#define USB_CSRL0_TXRDY (1 << 1) +/** Receive Packet Ready */ +#define USB_CSRL0_RXRDY (1 << 0) + +/* ============================================================================= + * USB_CSRH0 values + * ---------------------------------------------------------------------------*/ +/** Flush FIFO */ +#define USB_CSRH0_FLUSH (1 << 0) + +/* ============================================================================= + * USB_TXCSRLx values + * ---------------------------------------------------------------------------*/ +/** Clear data toggle */ +#define USB_TXCSRL_CLRDT (1 << 6) +/** Endpoint Stalled */ +#define USB_TXCSRL_STALLED (1 << 5) +/** Send Stall */ +#define USB_TXCSRL_STALL (1 << 4) +/** Flush FIFO */ +#define USB_TXCSRL_FLUSH (1 << 3) +/** Underrun */ +#define USB_TXCSRL_UNDRN (1 << 2) +/** FIFO not empty */ +#define USB_TXCSRL_FIFONE (1 << 1) +/** Transmit Packet Ready */ +#define USB_TXCSRL_TXRDY (1 << 0) + +/* ============================================================================= + * USB_TXCSRHx values + * ---------------------------------------------------------------------------*/ +/** Auto set */ +#define USB_TXCSRH_AUTOSET (1 << 7) +/** Isochronous transfers */ +#define USB_TXCSRH_ISO (1 << 6) +/** Mode */ +#define USB_TXCSRH_MODE (1 << 5) +/** DMA request enable */ +#define USB_TXCSRH_DMAEN (1 << 4) +/** Force data toggle */ +#define USB_TXCSRH_FDT (1 << 3) +/** DMA request mode */ +#define USB_TXCSRH_DMAMOD (1 << 2) + +/* ============================================================================= + * USB_RXCSRLx values + * ---------------------------------------------------------------------------*/ +/** Clear data toggle */ +#define USB_RXCSRL_CLRDT (1 << 7) +/** Endpoint Stalled */ +#define USB_RXCSRL_STALLED (1 << 6) +/** Send Stall */ +#define USB_RXCSRL_STALL (1 << 5) +/** Flush FIFO */ +#define USB_RXCSRL_FLUSH (1 << 4) +/** Data error */ +#define USB_RXCSRL_DATAERR (1 << 2) +/** Overrun */ +#define USB_RXCSRL_OVER (1 << 2) +/** FIFO full */ +#define USB_RXCSRL_FULL (1 << 1) +/** Receive Packet Ready */ +#define USB_RXCSRL_RXRDY (1 << 0) + +/* ============================================================================= + * USB_RXCSRHx values + * ---------------------------------------------------------------------------*/ +/** Auto clear */ +#define USB_RXCSRH_AUTOCL (1 << 7) +/** Isochronous transfers */ +#define USB_RXCSRH_ISO (1 << 6) +/** DMA request enable */ +#define USB_RXCSRH_DMAEN (1 << 5) +/** Disable NYET / PID error */ +#define USB_RXCSRH_PIDERR (1 << 4) +/** DMA request mode */ +#define USB_RXCSRH_DMAMOD (1 << 3) + +/* ============================================================================= + * USB_DRRIS values + * ---------------------------------------------------------------------------*/ +/** RESUME interrupt status */ +#define USB_DRRIS_RESUME (1 << 0) + +/* ============================================================================= + * USB_DRIM values + * ---------------------------------------------------------------------------*/ +/** RESUME interrupt mask */ +#define USB_DRIM_RESUME (1 << 0) + +/* ============================================================================= + * USB_DRISC values + * ---------------------------------------------------------------------------*/ +/** RESUME interrupt status and clear */ +#define USB_DRISC_RESUME (1 << 0) + +/* ============================================================================= + * USB_PP values + * ---------------------------------------------------------------------------*/ +/** Endpoint count */ +#define USB_PP_ECNT_MASK (0xFF << 8) +/** USB capability */ +#define USB_PP_USB_MASK (0x03 << 6) +#define USB_PP_USB_NA (0x00 << 6) +#define USB_PP_USB_DEVICE (0x01 << 6) +#define USB_PP_USB_HOST (0x02 << 6) +#define USB_PP_USB_OTG (0x03 << 6) +/** PHY present */ +#define USB_PP_PHY (1 << 4) +/** Controller type */ +#define USB_PP_TYPE_MASK (0x0F << 0) + +/* ============================================================================= + * Convenience enums + * ---------------------------------------------------------------------------*/ +enum usb_interrupt { + USB_INT_DISCON = USB_IM_DISCON, + USB_INT_SOF = USB_IM_SOF, + USB_INT_RESET = USB_IM_RESET, + USB_INT_RESUME = USB_IM_RESUME, + USB_INT_SUSPEND = USB_IM_SUSPEND, +}; + +enum usb_ep_interrupt { + USB_EP0_INT = USB_EP0, + USB_EP1_INT = USB_EP1, + USB_EP2_INT = USB_EP2, + USB_EP3_INT = USB_EP3, + USB_EP4_INT = USB_EP4, + USB_EP5_INT = USB_EP5, + USB_EP6_INT = USB_EP6, + USB_EP7_INT = USB_EP7, +}; +/* ============================================================================= + * Function prototypes + * ---------------------------------------------------------------------------*/ +BEGIN_DECLS + +void usb_enable_interrupts(enum usb_interrupt ints, + enum usb_ep_interrupt rx_ints, + enum usb_ep_interrupt tx_ints); +void usb_disable_interrupts(enum usb_interrupt ints, + enum usb_ep_interrupt rx_ints, + enum usb_ep_interrupt tx_ints); + +END_DECLS + +/**@}*/ + +#endif /* LIBOPENCM3_LM4F_USB_H */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/doc-lpc13xx.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/doc-lpc13xx.h new file mode 100644 index 00000000..5ed7cae9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/doc-lpc13xx.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 LPC13xx + +@version 1.0.0 + +@date 14 September 2012 + +API documentation for NXP Semiconductors LPC13xx Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LPC13xx LPC13xx +Libraries for NXP Semiconductors LPC13xx series. + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LPC13xx_defines LPC13xx Defines + +@brief Defined Constants and Types for the LPC13xx series + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/gpio.h new file mode 100644 index 00000000..f827ecac --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/gpio.h @@ -0,0 +1,124 @@ +/** @defgroup gpio_defines GPIO Defines + +@brief Defined Constants and Types for the LPC13xx General Purpose I/O + +@ingroup LPC13xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LPC13XX_GPIO_H +#define LPC13XX_GPIO_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +#define GPIO0 GPIO_PIO0_BASE +#define GPIO1 GPIO_PIO1_BASE +#define GPIO2 GPIO_PIO2_BASE +#define GPIO3 GPIO_PIO3_BASE + +/* --- GPIO registers ------------------------------------------------------ */ + +/* GPIO data register (GPIOn_DATA) */ +#define GPIO_DATA(port) MMIO32((port) + 0x3ffc) +#define GPIO0_DATA GPIO_DATA(GPIO0) +#define GPIO1_DATA GPIO_DATA(GPIO1) +#define GPIO2_DATA GPIO_DATA(GPIO2) +#define GPIO3_DATA GPIO_DATA(GPIO3) + +/* GPIO data direction register (GPIOn_DIR) */ +#define GPIO_DIR(port) MMIO32((port) + 0x00) +#define GPIO0_DIR GPIO_DIR(GPIO0) +#define GPIO1_DIR GPIO_DIR(GPIO1) +#define GPIO2_DIR GPIO_DIR(GPIO2) +#define GPIO3_DIR GPIO_DIR(GPIO3) + +/* GPIO interrupt sense register (GPIOn_IS) */ +#define GPIO_IS(port) MMIO32((port) + 0x04) +#define GPIO0_IS GPIO_IS(GPIO0) +#define GPIO1_IS GPIO_IS(GPIO1) +#define GPIO2_IS GPIO_IS(GPIO2) +#define GPIO3_IS GPIO_IS(GPIO3) + +/* GPIO interrupt both edges sense register (GPIOn_IBE) */ +#define GPIO_IBE(port) MMIO32((port) + 0x08) +#define GPIO0_IBE GPIO_IBE(GPIO0) +#define GPIO1_IBE GPIO_IBE(GPIO1) +#define GPIO2_IBE GPIO_IBE(GPIO2) +#define GPIO3_IBE GPIO_IBE(GPIO3) + +/* GPIO interrupt event register (GPIOn_IEV) */ +#define GPIO_IEV(port) MMIO32((port) + 0x0c) +#define GPIO0_IEV GPIO_IEV(GPIO0) +#define GPIO1_IEV GPIO_IEV(GPIO1) +#define GPIO2_IEV GPIO_IEV(GPIO2) +#define GPIO3_IEV GPIO_IEV(GPIO3) + +/* GPIO interrupt mask register (GPIOn_IE) */ +#define GPIO_IE(port) MMIO16((port) + 0x10) +#define GPIO0_IE GPIO_IE(GPIO0) +#define GPIO1_IE GPIO_IE(GPIO1) +#define GPIO2_IE GPIO_IE(GPIO2) +#define GPIO3_IE GPIO_IE(GPIO3) + +/* FIXME: IRS or RIS? Datasheet is not consistent here. */ +/* GPIO raw interrupt status register (GPIOn_IRS) */ +#define GPIO_IRS(port) MMIO16((port) + 0x14) +#define GPIO0_IRS GPIO_IRS(GPIO0) +#define GPIO1_IRS GPIO_IRS(GPIO1) +#define GPIO2_IRS GPIO_IRS(GPIO2) +#define GPIO3_IRS GPIO_IRS(GPIO3) + +/* GPIO masked interrupt status register (GPIOn_MIS) */ +#define GPIO_MIS(port) MMIO16((port) + 0x18) +#define GPIO0_MIS GPIO_MIS(GPIO0) +#define GPIO1_MIS GPIO_MIS(GPIO1) +#define GPIO2_MIS GPIO_MIS(GPIO2) +#define GPIO3_MIS GPIO_MIS(GPIO3) + +/* GPIO interrupt clear register (GPIOn_IC) */ +#define GPIO_IC(port) MMIO16((port) + 0x1c) +#define GPIO0_IC GPIO_IC(GPIO0) +#define GPIO1_IC GPIO_IC(GPIO1) +#define GPIO2_IC GPIO_IC(GPIO2) +#define GPIO3_IC GPIO_IC(GPIO3) + +BEGIN_DECLS + +void gpio_set(uint32_t gpioport, uint16_t gpios); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/irq.json new file mode 100644 index 00000000..d9ac31fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/irq.json @@ -0,0 +1,63 @@ +{ + "irqs": { + "0": "pio0_0", + "1": "pio0_1", + "2": "pio0_2", + "3": "pio0_3", + "4": "pio0_4", + "5": "pio0_5", + "6": "pio0_6", + "7": "pio0_7", + "8": "pio0_8", + "9": "pio0_9", + "10": "pio0_10", + "11": "pio0_11", + "12": "pio1_0", + "13": "pio1_1", + "14": "pio1_2", + "15": "pio1_3", + "16": "pio1_4", + "17": "pio1_5", + "18": "pio1_6", + "19": "pio1_7", + "20": "pio1_8", + "21": "pio1_9", + "22": "pio1_10", + "23": "pio1_11", + "24": "pio2_0", + "25": "pio2_1", + "26": "pio2_2", + "27": "pio2_3", + "28": "pio2_4", + "29": "pio2_5", + "30": "pio2_6", + "31": "pio2_7", + "32": "pio2_8", + "33": "pio2_9", + "34": "pio2_10", + "35": "pio2_11", + "36": "pio3_0", + "37": "pio3_1", + "38": "pio3_2", + "39": "pio3_3", + "40": "i2c0", + "41": "ct16b0", + "42": "ct16b1", + "43": "ct32b0", + "44": "ct32b1", + "45": "ssp0", + "46": "uart", + "47": "usb", + "48": "usb_fiq", + "49": "adc", + "50": "wdt", + "51": "bod", + "53": "pio3", + "54": "pio2", + "55": "pio1", + "56": "ssp1" + }, + "partname_humanreadable": "LPC 13xx series", + "partname_doxygen": "LPC13xx", + "includeguard": "LIBOPENCM3_LPC13xx_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/memorymap.h new file mode 100644 index 00000000..01b94b22 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc13xx/memorymap.h @@ -0,0 +1,58 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC13XX_MEMORYMAP_H +#define LPC13XX_MEMORYMAP_H + +#include + +/* --- LPC13XX specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE_APB (0x40000000U) +#define PERIPH_BASE_AHB (0x50000000U) + +/* Register boundary addresses */ + +/* APB */ +#define I2C_BASE (PERIPH_BASE_APB + 0x00000) +#define WDT_BASE (PERIPH_BASE_APB + 0x04000) +#define UART_BASE (PERIPH_BASE_APB + 0x08000) +#define TIMER0_16BIT_BASE (PERIPH_BASE_APB + 0x0c000) +#define TIMER1_16BIT_BASE (PERIPH_BASE_APB + 0x10000) +#define TIMER0_32BIT_BASE (PERIPH_BASE_APB + 0x14000) +#define TIMER1_32BIT_BASE (PERIPH_BASE_APB + 0x18000) +#define ADC_BASE (PERIPH_BASE_APB + 0x1c000) +#define USB_BASE (PERIPH_BASE_APB + 0x20000) +/* PERIPH_BASE_APB + 0x28000 (0x4002 8000 - 0x4003 7FFF): Reserved */ +#define PMU_BASE (PERIPH_BASE_APB + 0x38000) +#define FLASH_BASE (PERIPH_BASE_APB + 0x3c000) +#define SSP_BASE (PERIPH_BASE_APB + 0x40000) +#define IOCONFIG_BASE (PERIPH_BASE_APB + 0x44000) +#define SYSCTRL_BASE (PERIPH_BASE_APB + 0x48000) +/* PERIPH_BASE_APB + 0x4c000 (0x4004 c000 - 0x4007 FFFF): Reserved */ + +/* AHB */ +#define GPIO_PIO0_BASE (PERIPH_BASE_AHB + 0x00000) +#define GPIO_PIO1_BASE (PERIPH_BASE_AHB + 0x10000) +#define GPIO_PIO2_BASE (PERIPH_BASE_AHB + 0x20000) +#define GPIO_PIO3_BASE (PERIPH_BASE_AHB + 0x30000) +/* PERIPH_BASE_AHB + 0x40000 (0x5004 0000 - 0x501F FFFF): Reserved */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/clock.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/clock.h new file mode 100644 index 00000000..8ad6f47e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/clock.h @@ -0,0 +1,160 @@ +/** @defgroup clock_defines Clock Defines + +@brief Defined Constants and Types for the LPC17xx Clock + +@ingroup LPC17xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2013 Silvio Gissi + +@date 17 August 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Silvio Gissi + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC17XX_CLOCK_H +#define LPC17XX_CLOCK_H + +#include +#include + +/* --- Clock registers ----------------------------------------------------- */ +/* System Control and Status */ +#define CLK_SCS MMIO32(SYSCON_BASE + 0x1a0) +/* Clock Source Selection */ +#define CLK_CLKSRCSEL MMIO32(SYSCON_BASE + 0x10c) +/* PLL0: Main */ +#define CLK_PLL0CON MMIO32(SYSCON_BASE + 0x080) +#define CLK_PLL0CFG MMIO32(SYSCON_BASE + 0x084) +#define CLK_PLL0STAT MMIO32(SYSCON_BASE + 0x088) +#define CLK_PLL0FEED MMIO32(SYSCON_BASE + 0x08c) +/* PLL1: USB */ +#define CLK_PLL1CON MMIO32(SYSCON_BASE + 0x0a0) +#define CLK_PLL1CFG MMIO32(SYSCON_BASE + 0x0a4) +#define CLK_PLL1STAT MMIO32(SYSCON_BASE + 0x0a8) +#define CLK_PLL1FEED MMIO32(SYSCON_BASE + 0x0ac) +/* Clock Dividers */ +#define CLK_CCLKCFG MMIO32(SYSCON_BASE + 0x104) +#define CLK_USBCLKCFG MMIO32(SYSCON_BASE + 0x108) +#define CLK_PCLKSEL0 MMIO32(SYSCON_BASE + 0x1a8) +#define CLK_PCLKSEL1 MMIO32(SYSCON_BASE + 0x1ac) +/* Clock Output */ +#define CLK_CLKOUTCFG MMIO32(SYSCON_BASE + 0x1c8) + +/* CLK_SCS Values*/ +/* Reserved: [3:0] */ +#define CLK_SCS_OSCRANGE_01_TO_20MHZ (0) +#define CLK_SCS_OSCRANGE_15_TO_25MHZ (1 << 4) +#define CLK_SCS_OSCEN (1 << 5) +#define CLK_SCS_OSCSTAT (1 << 6) +/* Reserved: [31:7] */ + +/* CLK_CLKSRCSEL Values*/ +#define CLK_CLKSRCSEL_IRC (0) +#define CLK_CLKSRCSEL_MAIN (1 << 0) +#define CLK_CLKSRCSEL_RTC (1 << 1) +/* Reserved: value 11b */ +/* Reserved: [31:2] */ + +/* CLK_PLL0CON and CLK_PLL1CON Values */ +#define CLK_PLLCON_ENABLE (1 << 0) +#define CLK_PLLCON_CONNECT (1 << 1) +/* Reserved: [31:2] */ + +/* CLK_PLL0CFG and CLK_PLL0STAT Values */ +#define CLK_PLL0_MSEL_SHIFT 0 +#define CLK_PLL0_MSEL_MASK 0x7fff +/* Reserved: [15] */ +#define CLK_PLL0_NSEL_SHIFT 16 +#define CLK_PLL0_NSEL_MASK 0xff +/* CFG Reserved: [31:24] */ +#define CLK_PLL0STAT_ENABLE (1 << 24) +#define CLK_PLL0STAT_CONNECT (1 << 25) +#define CLK_PLL0STAT_PLOCK (1 << 26) +/* STAT Reserved: [31:27] */ + +/* CLK_PLL1CFG and CLK_PLL1STAT Values */ +#define CLK_PLL1_MSEL_SHIFT 0 +#define CLK_PLL1_MSEL_MASK 0x1f +#define CLK_PLL1_PSEL_SHIFT 5 +#define CLK_PLL1_PSEL_MASK 0x3 +/* CFG Reserved: [31:7] */ +#define CLK_PLL1STAT_ENABLE (1 << 8) +#define CLK_PLL1STAT_CONNECT (1 << 9) +#define CLK_PLL1STAT_PLOCK (1 << 10) +/* STAT Reserved: [31:11] */ + +/* CLK_USBCLKCFG Values */ +#define CLK_USBCLKCFG_DIV6 0x5 +#define CLK_USBCLKCFG_DIV8 0x7 +#define CLK_USBCLKCFG_DIV10 0x9 + +/* CLK_PCLKSEL0 and CLK_PCLKSEL1 Values */ +#define CLK_PCLKSEL_DIV4 0x00 +#define CLK_PCLKSEL_DIV1 0x01 +#define CLK_PCLKSEL_DIV2 0x02 +#define CLK_PCLKSEL_DIV8 0x03 +#define CLK_PCLKSEL0_WDT_SHIFT 0 +#define CLK_PCLKSEL0_TIMER0_SHIFT 2 +#define CLK_PCLKSEL0_TIMER1_SHIFT 4 +#define CLK_PCLKSEL0_UART0_SHIFT 6 +#define CLK_PCLKSEL0_UART1_SHIFT 8 +/* Reserved: [11:10]*/ +#define CLK_PCLKSEL0_PWM1_SHIFT 12 +#define CLK_PCLKSEL0_I2C0_SHIFT 14 +#define CLK_PCLKSEL0_SPI_SHIFT 16 +/* Reserved: [19:18]*/ +#define CLK_PCLKSEL0_SSP1_SHIFT 20 +#define CLK_PCLKSEL0_DAC_SHIFT 22 +#define CLK_PCLKSEL0_ADC_SHIFT 24 +#define CLK_PCLKSEL0_CAN1_SHIFT 26 +#define CLK_PCLKSEL0_CAN2_SHIFT 28 +#define CLK_PCLKSEL0_ACF_SHIFT 30 +#define CLK_PCLKSEL1_QEI_SHIFT 0 +#define CLK_PCLKSEL1_GPIOINT_SHIFT 2 +#define CLK_PCLKSEL1_PCB_SHIFT 4 +#define CLK_PCLKSEL1_I2C1_SHIFT 6 +/* Reserved: [9:8]*/ +#define CLK_PCLKSEL1_SSP0_SHIFT 10 +#define CLK_PCLKSEL1_TIMER2_SHIFT 12 +#define CLK_PCLKSEL1_TIMER3_SHIFT 14 +#define CLK_PCLKSEL1_UART2_SHIFT 16 +#define CLK_PCLKSEL1_UART3_SHIFT 18 +#define CLK_PCLKSEL1_I2C2_SHIFT 20 +#define CLK_PCLKSEL1_I2S_SHIFT 22 +/* Reserved: [25:24]*/ +#define CLK_PCLKSEL1_RIT_SHIFT 26 +#define CLK_PCLKSEL1_SYSCON_SHIFT 28 +#define CLK_PCLKSEL1_MCPWM_SHIFT 30 + +/* CLK_CLKOUTCFG Values */ +#define CLK_CLKOUTCFG_SEL_CPU 0x00 +#define CLK_CLKOUTCFG_SEL_MAIN 0x01 +#define CLK_CLKOUTCFG_SEL_IRC 0x02 +#define CLK_CLKOUTCFG_SEL_USB 0x03 +#define CLK_CLKOUTCFG_SEL_RTC 0x04 +#define CLK_CLKOUTCFG_DIV_SHIFT 4 +#define CLK_CLKOUTCFG_ENABLE (1 << 8) +#define CLK_CLKOUTCFG_ACTIVITY (1 << 9) +/* Reserved: [31:10]*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/doc-lpc17xx.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/doc-lpc17xx.h new file mode 100644 index 00000000..4bc603de --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/doc-lpc17xx.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 LPC17xx + +@version 1.0.0 + +@date 14 September 2012 + +API documentation for NXP Semiconductors LPC17xx Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LPC17xx LPC17xx +Libraries for NXP Semiconductors LPC17xx series. + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LPC17xx_defines LPC17xx Defines + +@brief Defined Constants and Types for the LPC17xx series + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/gpio.h new file mode 100644 index 00000000..c357f470 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/gpio.h @@ -0,0 +1,160 @@ +/** @defgroup gpio_defines GPIO Defines + +@brief Defined Constants and Types for the LPC17xx General Purpose I/O + +@ingroup LPC17xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC17XX_GPIO_H +#define LPC17XX_GPIO_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +#define GPIO0 GPIO_PIO0_BASE +#define GPIO1 GPIO_PIO1_BASE +#define GPIO2 GPIO_PIO2_BASE +#define GPIO3 GPIO_PIO3_BASE +#define GPIO4 GPIO_PIO4_BASE + +/* GPIO number definitions (for convenience) */ +#define GPIOPIN0 (1 << 0) +#define GPIOPIN1 (1 << 1) +#define GPIOPIN2 (1 << 2) +#define GPIOPIN3 (1 << 3) +#define GPIOPIN4 (1 << 4) +#define GPIOPIN5 (1 << 5) +#define GPIOPIN6 (1 << 6) +#define GPIOPIN7 (1 << 7) +#define GPIOPIN8 (1 << 8) +#define GPIOPIN9 (1 << 9) +#define GPIOPIN10 (1 << 10) +#define GPIOPIN11 (1 << 11) +#define GPIOPIN12 (1 << 12) +#define GPIOPIN13 (1 << 13) +#define GPIOPIN14 (1 << 14) +#define GPIOPIN15 (1 << 15) +#define GPIOPIN16 (1 << 16) +#define GPIOPIN17 (1 << 17) +#define GPIOPIN18 (1 << 18) +#define GPIOPIN19 (1 << 19) +#define GPIOPIN20 (1 << 20) +#define GPIOPIN21 (1 << 21) +#define GPIOPIN22 (1 << 22) +#define GPIOPIN23 (1 << 23) +#define GPIOPIN24 (1 << 24) +#define GPIOPIN25 (1 << 25) +#define GPIOPIN26 (1 << 26) +#define GPIOPIN27 (1 << 27) +#define GPIOPIN28 (1 << 28) +#define GPIOPIN29 (1 << 29) +#define GPIOPIN30 (1 << 30) +#define GPIOPIN31 (1 << 31) + +/* --- GPIO registers ------------------------------------------------------ */ + +/* GPIO data direction register (GPIOn_DIR) */ +#define GPIO_DIR(port) MMIO32((port) + 0x00) +#define GPIO0_DIR GPIO_DIR(GPIO0) +#define GPIO1_DIR GPIO_DIR(GPIO1) +#define GPIO2_DIR GPIO_DIR(GPIO2) +#define GPIO3_DIR GPIO_DIR(GPIO3) +#define GPIO4_DIR GPIO_DIR(GPIO4) + +/* GPIO fast mask register (GPIOn_DIR) */ +#define GPIO_MASK(port) MMIO32((port) + 0x10) +#define GPIO0_MASK GPIO_MASK(GPIO0) +#define GPIO1_MASK GPIO_MASK(GPIO1) +#define GPIO2_MASK GPIO_MASK(GPIO2) +#define GPIO3_MASK GPIO_MASK(GPIO3) +#define GPIO4_MASK GPIO_MASK(GPIO4) + +/* GPIO port pin value register (GPIOn_PIN) */ +#define GPIO_PIN(port) MMIO32((port) + 0x14) +#define GPIO0_PIN GPIO_PIN(GPIO0) +#define GPIO1_PIN GPIO_PIN(GPIO1) +#define GPIO2_PIN GPIO_PIN(GPIO2) +#define GPIO3_PIN GPIO_PIN(GPIO3) +#define GPIO4_PIN GPIO_PIN(GPIO4) + +/* GPIO port output set register (GPIOn_SET) */ +#define GPIO_SET(port) MMIO32((port) + 0x18) +#define GPIO0_SET GPIO_SET(GPIO0) +#define GPIO1_SET GPIO_SET(GPIO1) +#define GPIO2_SET GPIO_SET(GPIO2) +#define GPIO3_SET GPIO_SET(GPIO3) +#define GPIO4_SET GPIO_SET(GPIO4) + +/* GPIO port output clear register (GPIOn_CLR) */ +#define GPIO_CLR(port) MMIO32((port) + 0x1C) +#define GPIO0_CLR GPIO_CLR(GPIO0) +#define GPIO1_CLR GPIO_CLR(GPIO1) +#define GPIO2_CLR GPIO_CLR(GPIO2) +#define GPIO3_CLR GPIO_CLR(GPIO3) +#define GPIO4_CLR GPIO_CLR(GPIO4) + +/* GPIO interrupt register map */ +/* Interrupt enable rising edge */ +#define GPIO0_IER MMIO32(GPIOINTERRUPT_BASE + 0x90) +#define GPIO2_IER MMIO32(GPIOINTERRUPT_BASE + 0xB0) + +/* Interrupt enable falling edge */ +#define GPIO0_IEF MMIO32(GPIOINTERRUPT_BASE + 0x94) +#define GPIO2_IEF MMIO32(GPIOINTERRUPT_BASE + 0xB4) + +/* Interrupt status rising edge */ +#define GPIO0_ISR MMIO32(GPIOINTERRUPT_BASE + 0x84) +#define GPIO2_ISR MMIO32(GPIOINTERRUPT_BASE + 0xA4) + +/* Interrupt status falling edge */ +#define GPIO0_ISF MMIO32(GPIOINTERRUPT_BASE + 0x88) +#define GPIO2_ISF MMIO32(GPIOINTERRUPT_BASE + 0xA8) + +/* Interrupt clear */ +#define GPIO0_IC MMIO32(GPIOINTERRUPT_BASE + 0x8C) +#define GPIO1_IC MMIO32(GPIOINTERRUPT_BASE + 0xAC) + +/* Overall interrupt status */ +#define GPIO_IS MMIO32(GPIOINTERRUPT_BASE + 0x80) + +BEGIN_DECLS + +void gpio_set(uint32_t gpioport, uint32_t gpios); +void gpio_clear(uint32_t gpioport, uint32_t gpios); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/irq.json new file mode 100644 index 00000000..94eec072 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/irq.json @@ -0,0 +1,42 @@ +{ + "irqs": { + "0": "wdt", + "1": "timer0", + "2": "timer1", + "3": "timer2", + "4": "timer3", + "5": "uart0", + "6": "uart1", + "7": "uart2", + "8": "uart3", + "9": "pwm", + "10": "i2c0", + "11": "i2c1", + "12": "i2c2", + "13": "spi", + "14": "ssp0", + "15": "ssp1", + "16": "pll0", + "17": "rtc", + "18": "eint0", + "19": "eint1", + "20": "eint2", + "21": "eint3", + "22": "adc", + "23": "bod", + "24": "usb", + "25": "can", + "26": "gpdma", + "27": "i2s", + "28": "ethernet", + "29": "rit", + "30": "motor_pwm", + "31": "qei", + "32": "pll1", + "33": "usb_act", + "34": "can_act" + }, + "partname_humanreadable": "LPC 17xx series", + "partname_doxygen": "LPC17xx", + "includeguard": "LIBOPENCM3_LPC17xx_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/memorymap.h new file mode 100644 index 00000000..4fab7506 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/memorymap.h @@ -0,0 +1,93 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Silvio Gissi + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC17XX_MEMORYMAP_H +#define LPC17XX_MEMORYMAP_H + +#include + +/* --- LPC17XX specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE_GPIO (0x2009C000U) +#define PERIPH_BASE_APB0 (0x40000000U) +#define PERIPH_BASE_APB1 (0x40080000U) +#define PERIPH_BASE_AHB (0x50000000U) + +/* Register boundary addresses */ + +/* GPIO */ +#define GPIO_PIO0_BASE (PERIPH_BASE_GPIO + 0x00) +#define GPIO_PIO1_BASE (PERIPH_BASE_GPIO + 0x20) +#define GPIO_PIO2_BASE (PERIPH_BASE_GPIO + 0x40) +#define GPIO_PIO3_BASE (PERIPH_BASE_GPIO + 0x60) +#define GPIO_PIO4_BASE (PERIPH_BASE_GPIO + 0x80) + +/* APB0 */ +#define WDT_BASE (PERIPH_BASE_APB0 + 0x00000) +#define TIMER0_BASE (PERIPH_BASE_APB0 + 0x04000) +#define TIMER1_BASE (PERIPH_BASE_APB0 + 0x08000) +#define UART0_BASE (PERIPH_BASE_APB0 + 0x0c000) +#define UART1_BASE (PERIPH_BASE_APB0 + 0x10000) +/* PERIPH_BASE_APB0 + 0X14000 (0x4001 4000 - 0x4001 7FFF): Reserved */ +#define PWM1_BASE (PERIPH_BASE_APB0 + 0x18000) +#define I2C0_BASE (PERIPH_BASE_APB0 + 0x1c000) +#define SPI_BASE (PERIPH_BASE_APB0 + 0x20000) +#define RTC_BASE (PERIPH_BASE_APB0 + 0x24000) +#define GPIOINTERRUPT_BASE (PERIPH_BASE_APB0 + 0x28000) +#define PINCONNECT_BASE (PERIPH_BASE_APB0 + 0x2c000) +#define SSP1_BASE (PERIPH_BASE_APB0 + 0x30000) +#define ADC_BASE (PERIPH_BASE_APB0 + 0x34000) +#define CANAFRAM_BASE (PERIPH_BASE_APB0 + 0x38000) +#define CANAFREG_BASE (PERIPH_BASE_APB0 + 0x3C000) +#define CANCOMMONREG_BASE (PERIPH_BASE_APB0 + 0x40000) +#define CAN1_BASE (PERIPH_BASE_APB0 + 0x44000) +#define CAN2_BASE (PERIPH_BASE_APB0 + 0x48000) +/* PERIPH_BASE_APB0 + 0X4C000 (0x4004 C000 - 0x4005 BFFF): Reserved */ +#define I2C1_BASE (PERIPH_BASE_APB0 + 0x5C000) +/* PERIPH_BASE_APB0 + 0X60000 (0x4006 0000 - 0x4007 BFFF): Reserved */ + +/* APB1 */ +/* PERIPH_BASE_APB1 + 0X00000 (0x4008 0000 - 0x4008 7FFF): Reserved */ +#define SSP0_BASE (PERIPH_BASE_APB1 + 0x08000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x0c000) +#define TIMER2_BASE (PERIPH_BASE_APB1 + 0x10000) +#define TIMER3_BASE (PERIPH_BASE_APB1 + 0x14000) +#define UART2_BASE (PERIPH_BASE_APB1 + 0x18000) +#define UART3_BASE (PERIPH_BASE_APB1 + 0x1c000) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x20000) +/* PERIPH_BASE_APB1 + 0X24000 (0x400A 4000 - 0x400A 7FFF): Reserved */ +#define I2S_BASE (PERIPH_BASE_APB1 + 0x28000) +/* PERIPH_BASE_APB1 + 0X2C000 (0x400A C000 - 0x400A FFFF): Reserved */ +#define RIT_BASE (PERIPH_BASE_APB1 + 0x30000) +/* PERIPH_BASE_APB1 + 0X34000 (0x400B 4000 - 0x400B 7FFF): Reserved */ +#define MCPWM_BASE (PERIPH_BASE_APB1 + 0x38000) +#define QEI_BASE (PERIPH_BASE_APB1 + 0x3c000) +/* PERIPH_BASE_APB1 + 0X40000 (0x400C 0000 - 0x400F BFFF): Reserved */ +#define SYSCON_BASE (PERIPH_BASE_APB1 + 0x7c000) + +/* AHB */ +#define ETHERNET_BASE (PERIPH_BASE_AHB + 0x00000) +#define GPDMA_BASE (PERIPH_BASE_AHB + 0x04000) +/* PERIPH_BASE_AHB + 0X08000 (0x5000 8000 - 0x5000 BFFF): Reserved */ +#define USB_BASE (PERIPH_BASE_AHB + 0x0c000) +/* PERIPH_BASE_AHB + 0X10000 (0x5001 0000 - 0x501F FFFF): Reserved */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/pwr.h new file mode 100644 index 00000000..7b42b632 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc17xx/pwr.h @@ -0,0 +1,102 @@ +/** @defgroup pwr_defines Power Defines + +@brief Defined Constants and Types for the LPC17xx Power Control + +@ingroup LPC17xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2013 Silvio Gissi + +@date 17 August 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Silvio Gissi + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC17XX_POWER_H +#define LPC17XX_POWER_H + +#include +#include + +/* --- Clock registers ----------------------------------------------------- */ +/* Power Control */ +#define PWR_PCON MMIO32(SYSCON_BASE + 0x0c0) +#define PWR_PCONP MMIO32(SYSCON_BASE + 0x0c4) + +/* PWR_PCON Values */ +#define PWR_PCON_MODE_SLEEP 0x00 +#define PWR_PCON_MODE_POWER_DOWN 0x01 +/* PWR_PCON_MODE_RESERVED 0x02*/ +#define PWR_PCON_MODE_DEEPSLEEP 0x03 +#define PWR_PCON_BODRPM (1 << 2) +#define PWR_PCON_BOGD (1 << 3) +#define PWR_PCON_BORD (1 << 4) +/* Reserved: [7:5] */ +#define PWR_PCON_SMFLAG (1 << 8) +#define PWR_PCON_DSFLAG (1 << 9) +#define PWR_PCON_PDFLAG (1 << 10) +#define PWR_PCON_DPDFLAG (1 << 11) +/* Reserved: [31:12] */ + +/* PWR_PCONP Values */ +/* Reserved: [0] */ +#define PWR_PCONP_TIMER0 (1 << 1) +#define PWR_PCONP_TIMER1 (1 << 2) +#define PWR_PCONP_UART0 (1 << 3) +#define PWR_PCONP_UART1 (1 << 4) +/* Reserved: [5] */ +#define PWR_PCONP_PWM1 (1 << 6) +#define PWR_PCONP_I2C0 (1 << 7) +#define PWR_PCONP_SPI (1 << 8) +#define PWR_PCONP_RTC (1 << 9) +#define PWR_PCONP_SSP1 (1 << 10) +/* Reserved: [11] */ +#define PWR_PCONP_ADC (1 << 12) +#define PWR_PCONP_CAN1 (1 << 13) +#define PWR_PCONP_CAN2 (1 << 14) +#define PWR_PCONP_GPIO (1 << 15) +#define PWR_PCONP_RIT (1 << 16) +#define PWR_PCONP_MCPWM (1 << 17) +#define PWR_PCONP_QEI (1 << 18) +#define PWR_PCONP_I2C1 (1 << 19) +/* Reserved: [20] */ +#define PWR_PCONP_SSP0 (1 << 21) +#define PWR_PCONP_TIMER2 (1 << 22) +#define PWR_PCONP_TIMER3 (1 << 23) +#define PWR_PCONP_UART2 (1 << 24) +#define PWR_PCONP_UART3 (1 << 25) +#define PWR_PCONP_I2C2 (1 << 26) +#define PWR_PCONP_I2S (1 << 27) +/* Reserved: [28] */ +#define PWR_PCONP_GPDMA (1 << 29) +#define PWR_PCONP_ETHERNET (1 << 30) +#define PWR_PCONP_USB (1 << 31) + +BEGIN_DECLS + +void pwr_enable_peripherals(uint32_t peripherals); +void pwr_disable_peripherals(uint32_t peripherals); +/* TODO Sleep, Deep Sleep, Power Down and Deep Power Down modes */ + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/adc.h new file mode 100644 index 00000000..d506524b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/adc.h @@ -0,0 +1,113 @@ +/** @defgroup adc_defines ADC Defines + +@brief Defined Constants and Types for the LPC43xx A/D Converter + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_ADC_H +#define LPC43XX_ADC_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* ADC port base addresses (for convenience) */ +#define ADC0 ADC0_BASE +#define ADC1 ADC1_BASE + + +/* --- ADC registers ------------------------------------------------------- */ + +/* A/D Control Register */ +#define ADC_CR(port) MMIO32((port) + 0x000) +#define ADC0_CR ADC_CR(ADC0) +#define ADC1_CR ADC_CR(ADC1) + +/* A/D Global Data Register */ +#define ADC_GDR(port) MMIO32((port) + 0x004) +#define ADC0_GDR ADC_GDR(ADC0) +#define ADC1_GDR ADC_GDR(ADC1) + +/* A/D Interrupt Enable Register */ +#define ADC_INTEN(port) MMIO32((port) + 0x00C) +#define ADC0_INTEN ADC_INTEN(ADC0) +#define ADC1_INTEN ADC_INTEN(ADC1) + +/* A/D Channel 0 Data Register */ +#define ADC_DR0(port) MMIO32((port) + 0x010) +#define ADC0_DR0 ADC_DR0(ADC0) +#define ADC1_DR0 ADC_DR0(ADC1) + +/* A/D Channel 1 Data Register */ +#define ADC_DR1(port) MMIO32((port) + 0x014) +#define ADC0_DR1 ADC_DR1(ADC0) +#define ADC1_DR1 ADC_DR1(ADC1) + +/* A/D Channel 2 Data Register */ +#define ADC_DR2(port) MMIO32((port) + 0x018) +#define ADC0_DR2 ADC_DR2(ADC0) +#define ADC1_DR2 ADC_DR2(ADC1) + +/* A/D Channel 3 Data Register */ +#define ADC_DR3(port) MMIO32((port) + 0x01C) +#define ADC0_DR3 ADC_DR3(ADC0) +#define ADC1_DR3 ADC_DR3(ADC1) + +/* A/D Channel 4 Data Register */ +#define ADC_DR4(port) MMIO32((port) + 0x020) +#define ADC0_DR4 ADC_DR4(ADC0) +#define ADC1_DR4 ADC_DR4(ADC1) + +/* A/D Channel 5 Data Register */ +#define ADC_DR5(port) MMIO32((port) + 0x024) +#define ADC0_DR5 ADC_DR5(ADC0) +#define ADC1_DR5 ADC_DR5(ADC1) + +/* A/D Channel 6 Data Register */ +#define ADC_DR6(port) MMIO32((port) + 0x028) +#define ADC0_DR6 ADC_DR6(ADC0) +#define ADC1_DR6 ADC_DR6(ADC1) + +/* A/D Channel 7 Data Register */ +#define ADC_DR7(port) MMIO32((port) + 0x02C) +#define ADC0_DR7 ADC_DR7(ADC0) +#define ADC1_DR7 ADC_DR7(ADC1) + +/* A/D Status Register */ +#define ADC_STAT(port) MMIO32((port) + 0x030) +#define ADC0_STAT ADC_STAT(ADC0) +#define ADC1_STAT ADC_STAT(ADC1) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/atimer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/atimer.h new file mode 100644 index 00000000..cbb70d72 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/atimer.h @@ -0,0 +1,70 @@ +/** @defgroup atimer_defines Alarm Timer Defines + +@brief Defined Constants and Types for the LPC43xx Alarm Timer + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_ATIMER_H +#define LPC43XX_ATIMER_H + +/**@{*/ + +#include +#include + +/* --- Alarm Timer registers ----------------------------------------------- */ + +/* Downcounter register */ +#define ATIMER_DOWNCOUNTER MMIO32(ATIMER_BASE + 0x000) + +/* Preset value register */ +#define ATIMER_PRESET MMIO32(ATIMER_BASE + 0x004) + +/* Interrupt clear enable register */ +#define ATIMER_CLR_EN MMIO32(ATIMER_BASE + 0xFD8) + +/* Interrupt set enable register */ +#define ATIMER_SET_EN MMIO32(ATIMER_BASE + 0xFDC) + +/* Status register */ +#define ATIMER_STATUS MMIO32(ATIMER_BASE + 0xFE0) + +/* Enable register */ +#define ATIMER_ENABLE MMIO32(ATIMER_BASE + 0xFE4) + +/* Clear register */ +#define ATIMER_CLR_STAT MMIO32(ATIMER_BASE + 0xFE8) + +/* Set register */ +#define ATIMER_SET_STAT MMIO32(ATIMER_BASE + 0xFEC) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ccu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ccu.h new file mode 100644 index 00000000..d3b1d500 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ccu.h @@ -0,0 +1,402 @@ +/** @defgroup ccu_defines Clock Control Unit Defines + +@brief Defined Constants and Types for the LPC43xx Clock Control Unit + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_CCU_H +#define LPC43XX_CCU_H + +/**@{*/ + +#include +#include + +/* --- CCU1 registers ------------------------------------------------------ */ + +/* CCU1 power mode register */ +#define CCU1_PM MMIO32(CCU1_BASE + 0x000) + +/* CCU1 base clock status register */ +#define CCU1_BASE_STAT MMIO32(CCU1_BASE + 0x004) + +/* CLK_APB3_BUS clock configuration register */ +#define CCU1_CLK_APB3_BUS_CFG MMIO32(CCU1_BASE + 0x100) + +/* CLK_APB3_BUS clock status register */ +#define CCU1_CLK_APB3_BUS_STAT MMIO32(CCU1_BASE + 0x104) + +/* CLK_APB3_I2C1 configuration register */ +#define CCU1_CLK_APB3_I2C1_CFG MMIO32(CCU1_BASE + 0x108) + +/* CLK_APB3_I2C1 status register */ +#define CCU1_CLK_APB3_I2C1_STAT MMIO32(CCU1_BASE + 0x10C) + +/* CLK_APB3_DAC configuration register */ +#define CCU1_CLK_APB3_DAC_CFG MMIO32(CCU1_BASE + 0x110) + +/* CLK_APB3_DAC status register */ +#define CCU1_CLK_APB3_DAC_STAT MMIO32(CCU1_BASE + 0x114) + +/* CLK_APB3_ADC0 configuration register */ +#define CCU1_CLK_APB3_ADC0_CFG MMIO32(CCU1_BASE + 0x118) + +/* CLK_APB3_ADC0 status register */ +#define CCU1_CLK_APB3_ADC0_STAT MMIO32(CCU1_BASE + 0x11C) + +/* CLK_APB3_ADC1 configuration register */ +#define CCU1_CLK_APB3_ADC1_CFG MMIO32(CCU1_BASE + 0x120) + +/* CLK_APB3_ADC1 status register */ +#define CCU1_CLK_APB3_ADC1_STAT MMIO32(CCU1_BASE + 0x124) + +/* CLK_APB3_CAN0 configuration register */ +#define CCU1_CLK_APB3_CAN0_CFG MMIO32(CCU1_BASE + 0x128) + +/* CLK_APB3_CAN0 status register */ +#define CCU1_CLK_APB3_CAN0_STAT MMIO32(CCU1_BASE + 0x12C) + +/* CLK_APB1_BUS configuration register */ +#define CCU1_CLK_APB1_BUS_CFG MMIO32(CCU1_BASE + 0x200) + +/* CLK_APB1_BUS status register */ +#define CCU1_CLK_APB1_BUS_STAT MMIO32(CCU1_BASE + 0x204) + +/* CLK_APB1_MOTOCON configuration register */ +#define CCU1_CLK_APB1_MOTOCONPWM_CFG MMIO32(CCU1_BASE + 0x208) + +/* CLK_APB1_MOTOCON status register */ +#define CCU1_CLK_APB1_MOTOCONPWM_STAT MMIO32(CCU1_BASE + 0x20C) + +/* CLK_APB1_I2C0 configuration register */ +#define CCU1_CLK_APB1_I2C0_CFG MMIO32(CCU1_BASE + 0x210) + +/* CLK_APB1_I2C0 status register */ +#define CCU1_CLK_APB1_I2C0_STAT MMIO32(CCU1_BASE + 0x214) + +/* CLK_APB1_I2S configuration register */ +#define CCU1_CLK_APB1_I2S_CFG MMIO32(CCU1_BASE + 0x218) + +/* CLK_APB1_I2S status register */ +#define CCU1_CLK_APB1_I2S_STAT MMIO32(CCU1_BASE + 0x21C) + +/* CLK_APB3_CAN1 configuration register */ +#define CCU1_CLK_APB1_CAN1_CFG MMIO32(CCU1_BASE + 0x220) + +/* CLK_APB3_CAN1 status register */ +#define CCU1_CLK_APB1_CAN1_STAT MMIO32(CCU1_BASE + 0x224) + +/* CLK_SPIFI configuration register */ +#define CCU1_CLK_SPIFI_CFG MMIO32(CCU1_BASE + 0x300) + +/* CLK_SPIFI status register */ +#define CCU1_CLK_SPIFI_STAT MMIO32(CCU1_BASE + 0x304) + +/* CLK_M4_BUS configuration register */ +#define CCU1_CLK_M4_BUS_CFG MMIO32(CCU1_BASE + 0x400) + +/* CLK_M4_BUS status register */ +#define CCU1_CLK_M4_BUS_STAT MMIO32(CCU1_BASE + 0x404) + +/* CLK_M4_SPIFI configuration register */ +#define CCU1_CLK_M4_SPIFI_CFG MMIO32(CCU1_BASE + 0x408) + +/* CLK_M4_SPIFI status register */ +#define CCU1_CLK_M4_SPIFI_STAT MMIO32(CCU1_BASE + 0x40C) + +/* CLK_M4_GPIO configuration register */ +#define CCU1_CLK_M4_GPIO_CFG MMIO32(CCU1_BASE + 0x410) + +/* CLK_M4_GPIO status register */ +#define CCU1_CLK_M4_GPIO_STAT MMIO32(CCU1_BASE + 0x414) + +/* CLK_M4_LCD configuration register */ +#define CCU1_CLK_M4_LCD_CFG MMIO32(CCU1_BASE + 0x418) + +/* CLK_M4_LCD status register */ +#define CCU1_CLK_M4_LCD_STAT MMIO32(CCU1_BASE + 0x41C) + +/* CLK_M4_ETHERNET configuration register */ +#define CCU1_CLK_M4_ETHERNET_CFG MMIO32(CCU1_BASE + 0x420) + +/* CLK_M4_ETHERNET status register */ +#define CCU1_CLK_M4_ETHERNET_STAT MMIO32(CCU1_BASE + 0x424) + +/* CLK_M4_USB0 configuration register */ +#define CCU1_CLK_M4_USB0_CFG MMIO32(CCU1_BASE + 0x428) + +/* CLK_M4_USB0 status register */ +#define CCU1_CLK_M4_USB0_STAT MMIO32(CCU1_BASE + 0x42C) + +/* CLK_M4_EMC configuration register */ +#define CCU1_CLK_M4_EMC_CFG MMIO32(CCU1_BASE + 0x430) + +/* CLK_M4_EMC status register */ +#define CCU1_CLK_M4_EMC_STAT MMIO32(CCU1_BASE + 0x434) + +/* CLK_M4_SDIO configuration register */ +#define CCU1_CLK_M4_SDIO_CFG MMIO32(CCU1_BASE + 0x438) + +/* CLK_M4_SDIO status register */ +#define CCU1_CLK_M4_SDIO_STAT MMIO32(CCU1_BASE + 0x43C) + +/* CLK_M4_DMA configuration register */ +#define CCU1_CLK_M4_DMA_CFG MMIO32(CCU1_BASE + 0x440) + +/* CLK_M4_DMA status register */ +#define CCU1_CLK_M4_DMA_STAT MMIO32(CCU1_BASE + 0x444) + +/* CLK_M4_M4CORE configuration register */ +#define CCU1_CLK_M4_M4CORE_CFG MMIO32(CCU1_BASE + 0x448) + +/* CLK_M4_M4CORE status register */ +#define CCU1_CLK_M4_M4CORE_STAT MMIO32(CCU1_BASE + 0x44C) + +/* CLK_M4_SCT configuration register */ +#define CCU1_CLK_M4_SCT_CFG MMIO32(CCU1_BASE + 0x468) + +/* CLK_M4_SCT status register */ +#define CCU1_CLK_M4_SCT_STAT MMIO32(CCU1_BASE + 0x46C) + +/* CLK_M4_USB1 configuration register */ +#define CCU1_CLK_M4_USB1_CFG MMIO32(CCU1_BASE + 0x470) + +/* CLK_M4_USB1 status register */ +#define CCU1_CLK_M4_USB1_STAT MMIO32(CCU1_BASE + 0x474) + +/* CLK_M4_EMCDIV configuration register */ +#define CCU1_CLK_M4_EMCDIV_CFG MMIO32(CCU1_BASE + 0x478) + +/* CLK_M4_EMCDIV status register */ +#define CCU1_CLK_M4_EMCDIV_STAT MMIO32(CCU1_BASE + 0x47C) + +/* CLK_M4_M0_CFG configuration register */ +#define CCU1_CLK_M4_M0APP_CFG MMIO32(CCU1_BASE + 0x490) + +/* CLK_M4_M0_STAT status register */ +#define CCU1_CLK_M4_M0APP_STAT MMIO32(CCU1_BASE + 0x494) + +/* CLK_M4_VADC_CFG configuration register */ +#define CCU1_CLK_M4_VADC_CFG MMIO32(CCU1_BASE + 0x498) + +/* CLK_M4_VADC_STAT configuration register */ +#define CCU1_CLK_M4_VADC_STAT MMIO32(CCU1_BASE + 0x49C) + +/* CLK_M4_WWDT configuration register */ +#define CCU1_CLK_M4_WWDT_CFG MMIO32(CCU1_BASE + 0x500) + +/* CLK_M4_WWDT status register */ +#define CCU1_CLK_M4_WWDT_STAT MMIO32(CCU1_BASE + 0x504) + +/* CLK_M4_UART0 configuration register */ +#define CCU1_CLK_M4_USART0_CFG MMIO32(CCU1_BASE + 0x508) + +/* CLK_M4_UART0 status register */ +#define CCU1_CLK_M4_USART0_STAT MMIO32(CCU1_BASE + 0x50C) + +/* CLK_M4_UART1 configuration register */ +#define CCU1_CLK_M4_UART1_CFG MMIO32(CCU1_BASE + 0x510) + +/* CLK_M4_UART1 status register */ +#define CCU1_CLK_M4_UART1_STAT MMIO32(CCU1_BASE + 0x514) + +/* CLK_M4_SSP0 configuration register */ +#define CCU1_CLK_M4_SSP0_CFG MMIO32(CCU1_BASE + 0x518) + +/* CLK_M4_SSP0 status register */ +#define CCU1_CLK_M4_SSP0_STAT MMIO32(CCU1_BASE + 0x51C) + +/* CLK_M4_TIMER0 configuration register */ +#define CCU1_CLK_M4_TIMER0_CFG MMIO32(CCU1_BASE + 0x520) + +/* CLK_M4_TIMER0 status register */ +#define CCU1_CLK_M4_TIMER0_STAT MMIO32(CCU1_BASE + 0x524) + +/* CLK_M4_TIMER1 configuration register */ +#define CCU1_CLK_M4_TIMER1_CFG MMIO32(CCU1_BASE + 0x528) + +/* CLK_M4_TIMER1 status register */ +#define CCU1_CLK_M4_TIMER1_STAT MMIO32(CCU1_BASE + 0x52C) + +/* CLK_M4_SCU configuration register */ +#define CCU1_CLK_M4_SCU_CFG MMIO32(CCU1_BASE + 0x530) + +/* CLK_M4_SCU status register */ +#define CCU1_CLK_M4_SCU_STAT MMIO32(CCU1_BASE + 0x534) + +/* CLK_M4_CREG configuration register */ +#define CCU1_CLK_M4_CREG_CFG MMIO32(CCU1_BASE + 0x538) + +/* CLK_M4_CREG status register */ +#define CCU1_CLK_M4_CREG_STAT MMIO32(CCU1_BASE + 0x53C) + +/* CLK_M4_RITIMER configuration register */ +#define CCU1_CLK_M4_RITIMER_CFG MMIO32(CCU1_BASE + 0x600) + +/* CLK_M4_RITIMER status register */ +#define CCU1_CLK_M4_RITIMER_STAT MMIO32(CCU1_BASE + 0x604) + +/* CLK_M4_UART2 configuration register */ +#define CCU1_CLK_M4_USART2_CFG MMIO32(CCU1_BASE + 0x608) + +/* CLK_M4_UART2 status register */ +#define CCU1_CLK_M4_USART2_STAT MMIO32(CCU1_BASE + 0x60C) + +/* CLK_M4_UART3 configuration register */ +#define CCU1_CLK_M4_USART3_CFG MMIO32(CCU1_BASE + 0x610) + +/* CLK_M4_UART3 status register */ +#define CCU1_CLK_M4_USART3_STAT MMIO32(CCU1_BASE + 0x614) + +/* CLK_M4_TIMER2 configuration register */ +#define CCU1_CLK_M4_TIMER2_CFG MMIO32(CCU1_BASE + 0x618) + +/* CLK_M4_TIMER2 status register */ +#define CCU1_CLK_M4_TIMER2_STAT MMIO32(CCU1_BASE + 0x61C) + +/* CLK_M4_TIMER3 configuration register */ +#define CCU1_CLK_M4_TIMER3_CFG MMIO32(CCU1_BASE + 0x620) + +/* CLK_M4_TIMER3 status register */ +#define CCU1_CLK_M4_TIMER3_STAT MMIO32(CCU1_BASE + 0x624) + +/* CLK_M4_SSP1 configuration register */ +#define CCU1_CLK_M4_SSP1_CFG MMIO32(CCU1_BASE + 0x628) + +/* CLK_M4_SSP1 status register */ +#define CCU1_CLK_M4_SSP1_STAT MMIO32(CCU1_BASE + 0x62C) + +/* CLK_M4_QEI configuration register */ +#define CCU1_CLK_M4_QEI_CFG MMIO32(CCU1_BASE + 0x630) + +/* CLK_M4_QEI status register */ +#define CCU1_CLK_M4_QEI_STAT MMIO32(CCU1_BASE + 0x634) + +/* CLK_PERIPH_BUS configuration register */ +#define CCU1_CLK_PERIPH_BUS_CFG MMIO32(CCU1_BASE + 0x700) + +/* CLK_PERIPH_BUS status register */ +#define CCU1_CLK_PERIPH_BUS_STAT MMIO32(CCU1_BASE + 0x704) + +/* CLK_PERIPH_CORE configuration register */ +#define CCU1_CLK_PERIPH_CORE_CFG MMIO32(CCU1_BASE + 0x710) + +/* CLK_PERIPH_CORE status register */ +#define CCU1_CLK_PERIPH_CORE_STAT MMIO32(CCU1_BASE + 0x714) + +/* CLK_PERIPH_SGPIO configuration register */ +#define CCU1_CLK_PERIPH_SGPIO_CFG MMIO32(CCU1_BASE + 0x718) + +/* CLK_PERIPH_SGPIO status register */ +#define CCU1_CLK_PERIPH_SGPIO_STAT MMIO32(CCU1_BASE + 0x71C) + +/* CLK_USB0 configuration register */ +#define CCU1_CLK_USB0_CFG MMIO32(CCU1_BASE + 0x800) + +/* CLK_USB0 status register */ +#define CCU1_CLK_USB0_STAT MMIO32(CCU1_BASE + 0x804) + +/* CLK_USB1 configuration register */ +#define CCU1_CLK_USB1_CFG MMIO32(CCU1_BASE + 0x900) + +/* CLK_USB1 status register */ +#define CCU1_CLK_USB1_STAT MMIO32(CCU1_BASE + 0x904) + +/* CLK_SPI configuration register */ +#define CCU1_CLK_SPI_CFG MMIO32(CCU1_BASE + 0xA00) + +/* CLK_SPI status register */ +#define CCU1_CLK_SPI_STAT MMIO32(CCU1_BASE + 0xA04) + +/* CLK_VADC configuration register */ +#define CCU1_CLK_VADC_CFG MMIO32(CCU1_BASE + 0xB00) + +/* CLK_VADC status register */ +#define CCU1_CLK_VADC_STAT MMIO32(CCU1_BASE + 0xB04) + +/* --- CCU2 registers ------------------------------------------------------ */ + +/* CCU2 power mode register */ +#define CCU2_PM MMIO32(CCU2_BASE + 0x000) + +/* CCU2 base clocks status register */ +#define CCU2_BASE_STAT MMIO32(CCU2_BASE + 0x004) + +/* CLK_APLL configuration register */ +#define CCU2_CLK_APLL_CFG MMIO32(CCU2_BASE + 0x100) + +/* CLK_APLL status register */ +#define CCU2_CLK_APLL_STAT MMIO32(CCU2_BASE + 0x104) + +/* CLK_APB2_UART3 configuration register */ +#define CCU2_CLK_APB2_USART3_CFG MMIO32(CCU2_BASE + 0x200) + +/* CLK_APB2_UART3 status register */ +#define CCU2_CLK_APB2_USART3_STAT MMIO32(CCU2_BASE + 0x204) + +/* CLK_APB2_UART2 configuration register */ +#define CCU2_CLK_APB2_USART2_CFG MMIO32(CCU2_BASE + 0x300) + +/* CLK_APB2_UART2 status register */ +#define CCU2_CLK_APB2_USART2_STAT MMIO32(CCU2_BASE + 0x304) + +/* CLK_APB0_UART1 configuration register */ +#define CCU2_CLK_APB0_UART1_CFG MMIO32(CCU2_BASE + 0x400) + +/* CLK_APB0_UART1 status register */ +#define CCU2_CLK_APB0_UART1_STAT MMIO32(CCU2_BASE + 0x404) + +/* CLK_APB0_UART0 configuration register */ +#define CCU2_CLK_APB0_USART0_CFG MMIO32(CCU2_BASE + 0x500) + +/* CLK_APB0_UART0 status register */ +#define CCU2_CLK_APB0_USART0_STAT MMIO32(CCU2_BASE + 0x504) + +/* CLK_APB2_SSP1 configuration register */ +#define CCU2_CLK_APB2_SSP1_CFG MMIO32(CCU2_BASE + 0x600) + +/* CLK_APB2_SSP1 status register */ +#define CCU2_CLK_APB2_SSP1_STAT MMIO32(CCU2_BASE + 0x604) + +/* CLK_APB0_SSP0 configuration register */ +#define CCU2_CLK_APB0_SSP0_CFG MMIO32(CCU2_BASE + 0x700) + +/* CLK_APB0_SSP0 status register */ +#define CCU2_CLK_APB0_SSP0_STAT MMIO32(CCU2_BASE + 0x704) + +/* CLK_SDIO configuration register (for SD/MMC) */ +#define CCU2_CLK_SDIO_CFG MMIO32(CCU2_BASE + 0x800) + +/* CLK_SDIO status register (for SD/MMC) */ +#define CCU2_CLK_SDIO_STAT MMIO32(CCU2_BASE + 0x804) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/cgu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/cgu.h new file mode 100644 index 00000000..0a169fd6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/cgu.h @@ -0,0 +1,964 @@ +/** @defgroup cgu_defines Clock Generation Unit Defines + * + * @brief Defined Constants and Types for the LPC43xx Clock Generation + * Unit + * + * @ingroup LPC43xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2012 Michael Ossmann + * + * + * @date 10 March 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_CGU_H +#define CGU_LPC43XX_CGU_H + +/**@{*/ + +#include +#include + +/* --- CGU registers ------------------------------------------------------- */ + +/* Frequency monitor register */ +#define CGU_FREQ_MON MMIO32(CGU_BASE + 0x014) + +/* Crystal oscillator control register */ +#define CGU_XTAL_OSC_CTRL MMIO32(CGU_BASE + 0x018) + +/* PLL0USB status register */ +#define CGU_PLL0USB_STAT MMIO32(CGU_BASE + 0x01C) + +/* PLL0USB control register */ +#define CGU_PLL0USB_CTRL MMIO32(CGU_BASE + 0x020) + +/* PLL0USB M-divider register */ +#define CGU_PLL0USB_MDIV MMIO32(CGU_BASE + 0x024) + +/* PLL0USB N/P-divider register */ +#define CGU_PLL0USB_NP_DIV MMIO32(CGU_BASE + 0x028) + +/* PLL0AUDIO status register */ +#define CGU_PLL0AUDIO_STAT MMIO32(CGU_BASE + 0x02C) + +/* PLL0AUDIO control register */ +#define CGU_PLL0AUDIO_CTRL MMIO32(CGU_BASE + 0x030) + +/* PLL0AUDIO M-divider register */ +#define CGU_PLL0AUDIO_MDIV MMIO32(CGU_BASE + 0x034) + +/* PLL0AUDIO N/P-divider register */ +#define CGU_PLL0AUDIO_NP_DIV MMIO32(CGU_BASE + 0x038) + +/* PLL0AUDIO fractional divider register */ +#define CGU_PLLAUDIO_FRAC MMIO32(CGU_BASE + 0x03C) + +/* PLL1 status register */ +#define CGU_PLL1_STAT MMIO32(CGU_BASE + 0x040) + +/* PLL1 control register */ +#define CGU_PLL1_CTRL MMIO32(CGU_BASE + 0x044) + +/* Integer divider A control register */ +#define CGU_IDIVA_CTRL MMIO32(CGU_BASE + 0x048) + +/* Integer divider B control register */ +#define CGU_IDIVB_CTRL MMIO32(CGU_BASE + 0x04C) + +/* Integer divider C control register */ +#define CGU_IDIVC_CTRL MMIO32(CGU_BASE + 0x050) + +/* Integer divider D control register */ +#define CGU_IDIVD_CTRL MMIO32(CGU_BASE + 0x054) + +/* Integer divider E control register */ +#define CGU_IDIVE_CTRL MMIO32(CGU_BASE + 0x058) + +/* Output stage 0 control register */ +#define CGU_BASE_SAFE_CLK MMIO32(CGU_BASE + 0x05C) + +/* Output stage 1 control register for base clock */ +#define CGU_BASE_USB0_CLK MMIO32(CGU_BASE + 0x060) + +/* Output stage 2 control register for base clock */ +#define CGU_BASE_PERIPH_CLK MMIO32(CGU_BASE + 0x064) + +/* Output stage 3 control register for base clock */ +#define CGU_BASE_USB1_CLK MMIO32(CGU_BASE + 0x068) + +/* Output stage 4 control register for base clock */ +#define CGU_BASE_M4_CLK MMIO32(CGU_BASE + 0x06C) + +/* Output stage 5 control register for base clock */ +#define CGU_BASE_SPIFI_CLK MMIO32(CGU_BASE + 0x070) + +/* Output stage 6 control register for base clock */ +#define CGU_BASE_SPI_CLK MMIO32(CGU_BASE + 0x074) + +/* Output stage 7 control register for base clock */ +#define CGU_BASE_PHY_RX_CLK MMIO32(CGU_BASE + 0x078) + +/* Output stage 8 control register for base clock */ +#define CGU_BASE_PHY_TX_CLK MMIO32(CGU_BASE + 0x07C) + +/* Output stage 9 control register for base clock */ +#define CGU_BASE_APB1_CLK MMIO32(CGU_BASE + 0x080) + +/* Output stage 10 control register for base clock */ +#define CGU_BASE_APB3_CLK MMIO32(CGU_BASE + 0x084) + +/* Output stage 11 control register for base clock */ +#define CGU_BASE_LCD_CLK MMIO32(CGU_BASE + 0x088) + +/* Output stage 12 control register for base clock */ +#define CGU_BASE_VADC_CLK MMIO32(CGU_BASE + 0x08C) + +/* Output stage 13 control register for base clock */ +#define CGU_BASE_SDIO_CLK MMIO32(CGU_BASE + 0x090) + +/* Output stage 14 control register for base clock */ +#define CGU_BASE_SSP0_CLK MMIO32(CGU_BASE + 0x094) + +/* Output stage 15 control register for base clock */ +#define CGU_BASE_SSP1_CLK MMIO32(CGU_BASE + 0x098) + +/* Output stage 16 control register for base clock */ +#define CGU_BASE_UART0_CLK MMIO32(CGU_BASE + 0x09C) + +/* Output stage 17 control register for base clock */ +#define CGU_BASE_UART1_CLK MMIO32(CGU_BASE + 0x0A0) + +/* Output stage 18 control register for base clock */ +#define CGU_BASE_UART2_CLK MMIO32(CGU_BASE + 0x0A4) + +/* Output stage 19 control register for base clock */ +#define CGU_BASE_UART3_CLK MMIO32(CGU_BASE + 0x0A8) + +/* Output stage 20 control register for base clock */ +#define CGU_BASE_OUT_CLK MMIO32(CGU_BASE + 0x0AC) + +/* Reserved output stage */ +#define CGU_OUTCLK_21_CTRL MMIO32(CGU_BASE + 0x0B0) + +/* Reserved output stage */ +#define CGU_OUTCLK_22_CTRL MMIO32(CGU_BASE + 0x0B4) + +/* Reserved output stage */ +#define CGU_OUTCLK_23_CTRL MMIO32(CGU_BASE + 0x0B8) + +/* Reserved output stage */ +#define CGU_OUTCLK_24_CTRL MMIO32(CGU_BASE + 0x0BC) + +/* Output stage 25 control register for base clock */ +#define CGU_BASE_APLL_CLK MMIO32(CGU_BASE + 0x0C0) + +/* Output stage 26 control CLK register for base clock */ +#define CGU_BASE_CGU_OUT0_CLK MMIO32(CGU_BASE + 0x0C4) + +/* Output stage 27 control CLK register for base clock */ +#define CGU_BASE_CGU_OUT1_CLK MMIO32(CGU_BASE + 0x0C8) + +/* --- CGU_FREQ_MON values -------------------------------------- */ + +/* RCNT: 9-bit reference clock-counter value */ +#define CGU_FREQ_MON_RCNT_SHIFT (0) +#define CGU_FREQ_MON_RCNT_MASK (0x1ff << CGU_FREQ_MON_RCNT_SHIFT) +#define CGU_FREQ_MON_RCNT(x) ((x) << CGU_FREQ_MON_RCNT_SHIFT) + +/* FCNT: 14-bit selected clock-counter value */ +#define CGU_FREQ_MON_FCNT_SHIFT (9) +#define CGU_FREQ_MON_FCNT_MASK (0x3fff << CGU_FREQ_MON_FCNT_SHIFT) +#define CGU_FREQ_MON_FCNT(x) ((x) << CGU_FREQ_MON_FCNT_SHIFT) + +/* MEAS: Measure frequency */ +#define CGU_FREQ_MON_MEAS_SHIFT (23) +#define CGU_FREQ_MON_MEAS (1 << CGU_FREQ_MON_MEAS_SHIFT) + +/* CLK_SEL: Clock-source selection for the clock to be measured */ +#define CGU_FREQ_MON_CLK_SEL_SHIFT (24) +#define CGU_FREQ_MON_CLK_SEL_MASK (0x1f << CGU_FREQ_MON_CLK_SEL_SHIFT) +#define CGU_FREQ_MON_CLK_SEL(x) ((x) << CGU_FREQ_MON_CLK_SEL_SHIFT) + +/* --- CGU_XTAL_OSC_CTRL values --------------------------------- */ + +/* ENABLE: Oscillator-pad enable */ +#define CGU_XTAL_OSC_CTRL_ENABLE_SHIFT (0) +#define CGU_XTAL_OSC_CTRL_ENABLE (1 << CGU_XTAL_OSC_CTRL_ENABLE_SHIFT) + +/* BYPASS: Configure crystal operation or external-clock input pin XTAL1 */ +#define CGU_XTAL_OSC_CTRL_BYPASS_SHIFT (1) +#define CGU_XTAL_OSC_CTRL_BYPASS (1 << CGU_XTAL_OSC_CTRL_BYPASS_SHIFT) + +/* HF: Select frequency range */ +#define CGU_XTAL_OSC_CTRL_HF_SHIFT (2) +#define CGU_XTAL_OSC_CTRL_HF (1 << CGU_XTAL_OSC_CTRL_HF_SHIFT) + +/* --- CGU_PLL0USB_STAT values ---------------------------------- */ + +/* LOCK: PLL0 lock indicator */ +#define CGU_PLL0USB_STAT_LOCK_SHIFT (0) +#define CGU_PLL0USB_STAT_LOCK (1 << CGU_PLL0USB_STAT_LOCK_SHIFT) + +/* FR: PLL0 free running indicator */ +#define CGU_PLL0USB_STAT_FR_SHIFT (1) +#define CGU_PLL0USB_STAT_FR (1 << CGU_PLL0USB_STAT_FR_SHIFT) + +/* --- CGU_PLL0USB_CTRL values ---------------------------------- */ + +/* PD: PLL0 power down */ +#define CGU_PLL0USB_CTRL_PD_SHIFT (0) +#define CGU_PLL0USB_CTRL_PD (1 << CGU_PLL0USB_CTRL_PD_SHIFT) + +/* BYPASS: Input clock bypass control */ +#define CGU_PLL0USB_CTRL_BYPASS_SHIFT (1) +#define CGU_PLL0USB_CTRL_BYPASS (1 << CGU_PLL0USB_CTRL_BYPASS_SHIFT) + +/* DIRECTI: PLL0 direct input */ +#define CGU_PLL0USB_CTRL_DIRECTI_SHIFT (2) +#define CGU_PLL0USB_CTRL_DIRECTI (1 << CGU_PLL0USB_CTRL_DIRECTI_SHIFT) + +/* DIRECTO: PLL0 direct output */ +#define CGU_PLL0USB_CTRL_DIRECTO_SHIFT (3) +#define CGU_PLL0USB_CTRL_DIRECTO (1 << CGU_PLL0USB_CTRL_DIRECTO_SHIFT) + +/* CLKEN: PLL0 clock enable */ +#define CGU_PLL0USB_CTRL_CLKEN_SHIFT (4) +#define CGU_PLL0USB_CTRL_CLKEN (1 << CGU_PLL0USB_CTRL_CLKEN_SHIFT) + +/* FRM: Free running mode */ +#define CGU_PLL0USB_CTRL_FRM_SHIFT (6) +#define CGU_PLL0USB_CTRL_FRM (1 << CGU_PLL0USB_CTRL_FRM_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_PLL0USB_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_PLL0USB_CTRL_AUTOBLOCK (1 << CGU_PLL0USB_CTRL_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_PLL0USB_CTRL_CLK_SEL_SHIFT (24) +#define CGU_PLL0USB_CTRL_CLK_SEL_MASK (0x1f << CGU_PLL0USB_CTRL_CLK_SEL_SHIFT) +#define CGU_PLL0USB_CTRL_CLK_SEL(x) ((x) << CGU_PLL0USB_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_PLL0USB_MDIV values ---------------------------------- */ + +/* MDEC: Decoded M-divider coefficient value */ +#define CGU_PLL0USB_MDIV_MDEC_SHIFT (0) +#define CGU_PLL0USB_MDIV_MDEC_MASK (0x1ffff << CGU_PLL0USB_MDIV_MDEC_SHIFT) +#define CGU_PLL0USB_MDIV_MDEC(x) ((x) << CGU_PLL0USB_MDIV_MDEC_SHIFT) + +/* SELP: Bandwidth select P value */ +#define CGU_PLL0USB_MDIV_SELP_SHIFT (17) +#define CGU_PLL0USB_MDIV_SELP_MASK (0x1f << CGU_PLL0USB_MDIV_SELP_SHIFT) +#define CGU_PLL0USB_MDIV_SELP(x) ((x) << CGU_PLL0USB_MDIV_SELP_SHIFT) + +/* SELI: Bandwidth select I value */ +#define CGU_PLL0USB_MDIV_SELI_SHIFT (22) +#define CGU_PLL0USB_MDIV_SELI_MASK (0x3f << CGU_PLL0USB_MDIV_SELI_SHIFT) +#define CGU_PLL0USB_MDIV_SELI(x) ((x) << CGU_PLL0USB_MDIV_SELI_SHIFT) + +/* SELR: Bandwidth select R value */ +#define CGU_PLL0USB_MDIV_SELR_SHIFT (28) +#define CGU_PLL0USB_MDIV_SELR_MASK (0xf << CGU_PLL0USB_MDIV_SELR_SHIFT) +#define CGU_PLL0USB_MDIV_SELR(x) ((x) << CGU_PLL0USB_MDIV_SELR_SHIFT) + +/* --- CGU_PLL0USB_NP_DIV values -------------------------------- */ + +/* PDEC: Decoded P-divider coefficient value */ +#define CGU_PLL0USB_NP_DIV_PDEC_SHIFT (0) +#define CGU_PLL0USB_NP_DIV_PDEC_MASK (0x7f << CGU_PLL0USB_NP_DIV_PDEC_SHIFT) +#define CGU_PLL0USB_NP_DIV_PDEC(x) ((x) << CGU_PLL0USB_NP_DIV_PDEC_SHIFT) + +/* NDEC: Decoded N-divider coefficient value */ +#define CGU_PLL0USB_NP_DIV_NDEC_SHIFT (12) +#define CGU_PLL0USB_NP_DIV_NDEC_MASK (0x3ff << CGU_PLL0USB_NP_DIV_NDEC_SHIFT) +#define CGU_PLL0USB_NP_DIV_NDEC(x) ((x) << CGU_PLL0USB_NP_DIV_NDEC_SHIFT) + +/* --- CGU_PLL0AUDIO_STAT values -------------------------------- */ + +/* LOCK: PLL0 lock indicator */ +#define CGU_PLL0AUDIO_STAT_LOCK_SHIFT (0) +#define CGU_PLL0AUDIO_STAT_LOCK (1 << CGU_PLL0AUDIO_STAT_LOCK_SHIFT) + +/* FR: PLL0 free running indicator */ +#define CGU_PLL0AUDIO_STAT_FR_SHIFT (1) +#define CGU_PLL0AUDIO_STAT_FR (1 << CGU_PLL0AUDIO_STAT_FR_SHIFT) + +/* --- CGU_PLL0AUDIO_CTRL values -------------------------------- */ + +/* PD: PLL0 power down */ +#define CGU_PLL0AUDIO_CTRL_PD_SHIFT (0) +#define CGU_PLL0AUDIO_CTRL_PD (1 << CGU_PLL0AUDIO_CTRL_PD_SHIFT) + +/* BYPASS: Input clock bypass control */ +#define CGU_PLL0AUDIO_CTRL_BYPASS_SHIFT (1) +#define CGU_PLL0AUDIO_CTRL_BYPASS (1 << CGU_PLL0AUDIO_CTRL_BYPASS_SHIFT) + +/* DIRECTI: PLL0 direct input */ +#define CGU_PLL0AUDIO_CTRL_DIRECTI_SHIFT (2) +#define CGU_PLL0AUDIO_CTRL_DIRECTI (1 << CGU_PLL0AUDIO_CTRL_DIRECTI_SHIFT) + +/* DIRECTO: PLL0 direct output */ +#define CGU_PLL0AUDIO_CTRL_DIRECTO_SHIFT (3) +#define CGU_PLL0AUDIO_CTRL_DIRECTO (1 << CGU_PLL0AUDIO_CTRL_DIRECTO_SHIFT) + +/* CLKEN: PLL0 clock enable */ +#define CGU_PLL0AUDIO_CTRL_CLKEN_SHIFT (4) +#define CGU_PLL0AUDIO_CTRL_CLKEN (1 << CGU_PLL0AUDIO_CTRL_CLKEN_SHIFT) + +/* FRM: Free running mode */ +#define CGU_PLL0AUDIO_CTRL_FRM_SHIFT (6) +#define CGU_PLL0AUDIO_CTRL_FRM (1 << CGU_PLL0AUDIO_CTRL_FRM_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_PLL0AUDIO_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_PLL0AUDIO_CTRL_AUTOBLOCK \ + (1 << CGU_PLL0AUDIO_CTRL_AUTOBLOCK_SHIFT) + +/* PLLFRACT_REQ: Fractional PLL word write request */ +#define CGU_PLL0AUDIO_CTRL_PLLFRACT_REQ_SHIFT (12) +#define CGU_PLL0AUDIO_CTRL_PLLFRACT_REQ \ + (1 << CGU_PLL0AUDIO_CTRL_PLLFRACT_REQ_SHIFT) + +/* SEL_EXT: Select fractional divider */ +#define CGU_PLL0AUDIO_CTRL_SEL_EXT_SHIFT (13) +#define CGU_PLL0AUDIO_CTRL_SEL_EXT (1 << CGU_PLL0AUDIO_CTRL_SEL_EXT_SHIFT) + +/* MOD_PD: Sigma-Delta modulator power-down */ +#define CGU_PLL0AUDIO_CTRL_MOD_PD_SHIFT (14) +#define CGU_PLL0AUDIO_CTRL_MOD_PD (1 << CGU_PLL0AUDIO_CTRL_MOD_PD_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_PLL0AUDIO_CTRL_CLK_SEL_SHIFT (24) +#define CGU_PLL0AUDIO_CTRL_CLK_SEL_MASK \ + (0x1f << CGU_PLL0AUDIO_CTRL_CLK_SEL_SHIFT) +#define CGU_PLL0AUDIO_CTRL_CLK_SEL(x) \ + ((x) << CGU_PLL0AUDIO_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_PLL0AUDIO_MDIV values -------------------------------- */ + +/* MDEC: Decoded M-divider coefficient value */ +#define CGU_PLL0AUDIO_MDIV_MDEC_SHIFT (0) +#define CGU_PLL0AUDIO_MDIV_MDEC_MASK \ + (0x1ffff << CGU_PLL0AUDIO_MDIV_MDEC_SHIFT) +#define CGU_PLL0AUDIO_MDIV_MDEC(x) \ + ((x) << CGU_PLL0AUDIO_MDIV_MDEC_SHIFT) + +/* --- CGU_PLL0AUDIO_NP_DIV values ------------------------------ */ + +/* PDEC: Decoded P-divider coefficient value */ +#define CGU_PLL0AUDIO_NP_DIV_PDEC_SHIFT (0) +#define CGU_PLL0AUDIO_NP_DIV_PDEC_MASK \ + (0x7f << CGU_PLL0AUDIO_NP_DIV_PDEC_SHIFT) +#define CGU_PLL0AUDIO_NP_DIV_PDEC(x) \ + ((x) << CGU_PLL0AUDIO_NP_DIV_PDEC_SHIFT) + +/* NDEC: Decoded N-divider coefficient value */ +#define CGU_PLL0AUDIO_NP_DIV_NDEC_SHIFT (12) +#define CGU_PLL0AUDIO_NP_DIV_NDEC_MASK \ + (0x3ff << CGU_PLL0AUDIO_NP_DIV_NDEC_SHIFT) +#define CGU_PLL0AUDIO_NP_DIV_NDEC(x) \ + ((x) << CGU_PLL0AUDIO_NP_DIV_NDEC_SHIFT) + +/* --- CGU_PLLAUDIO_FRAC values --------------------------------- */ + +/* PLLFRACT_CTRL: PLL fractional divider control word */ +#define CGU_PLLAUDIO_FRAC_PLLFRACT_CTRL_SHIFT (0) +#define CGU_PLLAUDIO_FRAC_PLLFRACT_CTRL_MASK \ + (0x3fffff << CGU_PLLAUDIO_FRAC_PLLFRACT_CTRL_SHIFT) +#define CGU_PLLAUDIO_FRAC_PLLFRACT_CTRL(x) \ + ((x) << CGU_PLLAUDIO_FRAC_PLLFRACT_CTRL_SHIFT) + +/* --- CGU_PLL1_STAT values ------------------------------------- */ + +/* LOCK: PLL1 lock indicator */ +#define CGU_PLL1_STAT_LOCK_SHIFT (0) +#define CGU_PLL1_STAT_LOCK (1 << CGU_PLL1_STAT_LOCK_SHIFT) + +/* --- CGU_PLL1_CTRL values ------------------------------------- */ + +/* PD: PLL1 power down */ +#define CGU_PLL1_CTRL_PD_SHIFT (0) +#define CGU_PLL1_CTRL_PD (1 << CGU_PLL1_CTRL_PD_SHIFT) + +/* BYPASS: Input clock bypass control */ +#define CGU_PLL1_CTRL_BYPASS_SHIFT (1) +#define CGU_PLL1_CTRL_BYPASS (1 << CGU_PLL1_CTRL_BYPASS_SHIFT) + +/* FBSEL: PLL feedback select */ +#define CGU_PLL1_CTRL_FBSEL_SHIFT (6) +#define CGU_PLL1_CTRL_FBSEL (1 << CGU_PLL1_CTRL_FBSEL_SHIFT) + +/* DIRECT: PLL direct CCO output */ +#define CGU_PLL1_CTRL_DIRECT_SHIFT (7) +#define CGU_PLL1_CTRL_DIRECT (1 << CGU_PLL1_CTRL_DIRECT_SHIFT) + +/* PSEL: Post-divider division ratio P */ +#define CGU_PLL1_CTRL_PSEL_SHIFT (8) +#define CGU_PLL1_CTRL_PSEL_MASK (0x3 << CGU_PLL1_CTRL_PSEL_SHIFT) +#define CGU_PLL1_CTRL_PSEL(x) ((x) << CGU_PLL1_CTRL_PSEL_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_PLL1_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_PLL1_CTRL_AUTOBLOCK (1 << CGU_PLL1_CTRL_AUTOBLOCK_SHIFT) + +/* NSEL: Pre-divider division ratio N */ +#define CGU_PLL1_CTRL_NSEL_SHIFT (12) +#define CGU_PLL1_CTRL_NSEL_MASK (0x3 << CGU_PLL1_CTRL_NSEL_SHIFT) +#define CGU_PLL1_CTRL_NSEL(x) ((x) << CGU_PLL1_CTRL_NSEL_SHIFT) + +/* MSEL: Feedback-divider division ratio (M) */ +#define CGU_PLL1_CTRL_MSEL_SHIFT (16) +#define CGU_PLL1_CTRL_MSEL_MASK (0xff << CGU_PLL1_CTRL_MSEL_SHIFT) +#define CGU_PLL1_CTRL_MSEL(x) ((x) << CGU_PLL1_CTRL_MSEL_SHIFT) + +/* CLK_SEL: Clock-source selection */ +#define CGU_PLL1_CTRL_CLK_SEL_SHIFT (24) +#define CGU_PLL1_CTRL_CLK_SEL_MASK (0x1f << CGU_PLL1_CTRL_CLK_SEL_SHIFT) +#define CGU_PLL1_CTRL_CLK_SEL(x) ((x) << CGU_PLL1_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_IDIVA_CTRL values ------------------------------------ */ + +/* PD: Integer divider power down */ +#define CGU_IDIVA_CTRL_PD_SHIFT (0) +#define CGU_IDIVA_CTRL_PD (1 << CGU_IDIVA_CTRL_PD_SHIFT) + +/* IDIV: Integer divider A divider value (1/(IDIV + 1)) */ +#define CGU_IDIVA_CTRL_IDIV_SHIFT (2) +#define CGU_IDIVA_CTRL_IDIV_MASK (0x3 << CGU_IDIVA_CTRL_IDIV_SHIFT) +#define CGU_IDIVA_CTRL_IDIV(x) ((x) << CGU_IDIVA_CTRL_IDIV_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_IDIVA_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_IDIVA_CTRL_AUTOBLOCK (1 << CGU_IDIVA_CTRL_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_IDIVA_CTRL_CLK_SEL_SHIFT (24) +#define CGU_IDIVA_CTRL_CLK_SEL_MASK (0x1f << CGU_IDIVA_CTRL_CLK_SEL_SHIFT) +#define CGU_IDIVA_CTRL_CLK_SEL(x) ((x) << CGU_IDIVA_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_IDIVB_CTRL values ------------------------------------ */ + +/* PD: Integer divider power down */ +#define CGU_IDIVB_CTRL_PD_SHIFT (0) +#define CGU_IDIVB_CTRL_PD (1 << CGU_IDIVB_CTRL_PD_SHIFT) + +/* IDIV: Integer divider B divider value (1/(IDIV + 1)) */ +#define CGU_IDIVB_CTRL_IDIV_SHIFT (2) +#define CGU_IDIVB_CTRL_IDIV_MASK (0xf << CGU_IDIVB_CTRL_IDIV_SHIFT) +#define CGU_IDIVB_CTRL_IDIV(x) ((x) << CGU_IDIVB_CTRL_IDIV_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_IDIVB_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_IDIVB_CTRL_AUTOBLOCK (1 << CGU_IDIVB_CTRL_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_IDIVB_CTRL_CLK_SEL_SHIFT (24) +#define CGU_IDIVB_CTRL_CLK_SEL_MASK (0x1f << CGU_IDIVB_CTRL_CLK_SEL_SHIFT) +#define CGU_IDIVB_CTRL_CLK_SEL(x) ((x) << CGU_IDIVB_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_IDIVC_CTRL values ------------------------------------ */ + +/* PD: Integer divider power down */ +#define CGU_IDIVC_CTRL_PD_SHIFT (0) +#define CGU_IDIVC_CTRL_PD (1 << CGU_IDIVC_CTRL_PD_SHIFT) + +/* IDIV: Integer divider C divider value (1/(IDIV + 1)) */ +#define CGU_IDIVC_CTRL_IDIV_SHIFT (2) +#define CGU_IDIVC_CTRL_IDIV_MASK (0xf << CGU_IDIVC_CTRL_IDIV_SHIFT) +#define CGU_IDIVC_CTRL_IDIV(x) ((x) << CGU_IDIVC_CTRL_IDIV_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_IDIVC_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_IDIVC_CTRL_AUTOBLOCK (1 << CGU_IDIVC_CTRL_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_IDIVC_CTRL_CLK_SEL_SHIFT (24) +#define CGU_IDIVC_CTRL_CLK_SEL_MASK (0x1f << CGU_IDIVC_CTRL_CLK_SEL_SHIFT) +#define CGU_IDIVC_CTRL_CLK_SEL(x) ((x) << CGU_IDIVC_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_IDIVD_CTRL values ------------------------------------ */ + +/* PD: Integer divider power down */ +#define CGU_IDIVD_CTRL_PD_SHIFT (0) +#define CGU_IDIVD_CTRL_PD (1 << CGU_IDIVD_CTRL_PD_SHIFT) + +/* IDIV: Integer divider D divider value (1/(IDIV + 1)) */ +#define CGU_IDIVD_CTRL_IDIV_SHIFT (2) +#define CGU_IDIVD_CTRL_IDIV_MASK (0xf << CGU_IDIVD_CTRL_IDIV_SHIFT) +#define CGU_IDIVD_CTRL_IDIV(x) ((x) << CGU_IDIVD_CTRL_IDIV_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_IDIVD_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_IDIVD_CTRL_AUTOBLOCK (1 << CGU_IDIVD_CTRL_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_IDIVD_CTRL_CLK_SEL_SHIFT (24) +#define CGU_IDIVD_CTRL_CLK_SEL_MASK (0x1f << CGU_IDIVD_CTRL_CLK_SEL_SHIFT) +#define CGU_IDIVD_CTRL_CLK_SEL(x) ((x) << CGU_IDIVD_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_IDIVE_CTRL values ------------------------------------ */ + +/* PD: Integer divider power down */ +#define CGU_IDIVE_CTRL_PD_SHIFT (0) +#define CGU_IDIVE_CTRL_PD (1 << CGU_IDIVE_CTRL_PD_SHIFT) + +/* IDIV: Integer divider E divider value (1/(IDIV + 1)) */ +#define CGU_IDIVE_CTRL_IDIV_SHIFT (2) +#define CGU_IDIVE_CTRL_IDIV_MASK (0xff << CGU_IDIVE_CTRL_IDIV_SHIFT) +#define CGU_IDIVE_CTRL_IDIV(x) ((x) << CGU_IDIVE_CTRL_IDIV_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_IDIVE_CTRL_AUTOBLOCK_SHIFT (11) +#define CGU_IDIVE_CTRL_AUTOBLOCK (1 << CGU_IDIVE_CTRL_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_IDIVE_CTRL_CLK_SEL_SHIFT (24) +#define CGU_IDIVE_CTRL_CLK_SEL_MASK (0x1f << CGU_IDIVE_CTRL_CLK_SEL_SHIFT) +#define CGU_IDIVE_CTRL_CLK_SEL(x) ((x) << CGU_IDIVE_CTRL_CLK_SEL_SHIFT) + +/* --- CGU_BASE_SAFE_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_SAFE_CLK_PD_SHIFT (0) +#define CGU_BASE_SAFE_CLK_PD (1 << CGU_BASE_SAFE_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_SAFE_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_SAFE_CLK_AUTOBLOCK (1 << CGU_BASE_SAFE_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_SAFE_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_SAFE_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_SAFE_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_SAFE_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_SAFE_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_USB0_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_USB0_CLK_PD_SHIFT (0) +#define CGU_BASE_USB0_CLK_PD (1 << CGU_BASE_USB0_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_USB0_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_USB0_CLK_AUTOBLOCK (1 << CGU_BASE_USB0_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_USB0_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_USB0_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_USB0_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_USB0_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_USB0_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_PERIPH_CLK values ------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_PERIPH_CLK_PD_SHIFT (0) +#define CGU_BASE_PERIPH_CLK_PD (1 << CGU_BASE_PERIPH_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_PERIPH_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_PERIPH_CLK_AUTOBLOCK \ + (1 << CGU_BASE_PERIPH_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_PERIPH_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_PERIPH_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_PERIPH_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_PERIPH_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_PERIPH_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_USB1_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_USB1_CLK_PD_SHIFT (0) +#define CGU_BASE_USB1_CLK_PD (1 << CGU_BASE_USB1_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_USB1_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_USB1_CLK_AUTOBLOCK (1 << CGU_BASE_USB1_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_USB1_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_USB1_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_USB1_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_USB1_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_USB1_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_M4_CLK values ----------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_M4_CLK_PD_SHIFT (0) +#define CGU_BASE_M4_CLK_PD (1 << CGU_BASE_M4_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_M4_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_M4_CLK_AUTOBLOCK (1 << CGU_BASE_M4_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_M4_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_M4_CLK_CLK_SEL_MASK (0x1f << CGU_BASE_M4_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_M4_CLK_CLK_SEL(x) ((x) << CGU_BASE_M4_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_SPIFI_CLK values -------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_SPIFI_CLK_PD_SHIFT (0) +#define CGU_BASE_SPIFI_CLK_PD (1 << CGU_BASE_SPIFI_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_SPIFI_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_SPIFI_CLK_AUTOBLOCK \ + (1 << CGU_BASE_SPIFI_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_SPIFI_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_SPIFI_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_SPIFI_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_SPIFI_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_SPIFI_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_SPI_CLK values ---------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_SPI_CLK_PD_SHIFT (0) +#define CGU_BASE_SPI_CLK_PD (1 << CGU_BASE_SPI_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_SPI_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_SPI_CLK_AUTOBLOCK (1 << CGU_BASE_SPI_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_SPI_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_SPI_CLK_CLK_SEL_MASK (0x1f << CGU_BASE_SPI_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_SPI_CLK_CLK_SEL(x) ((x) << CGU_BASE_SPI_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_PHY_RX_CLK values ------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_PHY_RX_CLK_PD_SHIFT (0) +#define CGU_BASE_PHY_RX_CLK_PD (1 << CGU_BASE_PHY_RX_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_PHY_RX_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_PHY_RX_CLK_AUTOBLOCK \ + (1 << CGU_BASE_PHY_RX_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_PHY_RX_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_PHY_RX_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_PHY_RX_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_PHY_RX_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_PHY_RX_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_PHY_TX_CLK values ------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_PHY_TX_CLK_PD_SHIFT (0) +#define CGU_BASE_PHY_TX_CLK_PD (1 << CGU_BASE_PHY_TX_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_PHY_TX_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_PHY_TX_CLK_AUTOBLOCK \ + (1 << CGU_BASE_PHY_TX_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_PHY_TX_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_PHY_TX_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_PHY_TX_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_PHY_TX_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_PHY_TX_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_APB1_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_APB1_CLK_PD_SHIFT (0) +#define CGU_BASE_APB1_CLK_PD (1 << CGU_BASE_APB1_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_APB1_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_APB1_CLK_AUTOBLOCK (1 << CGU_BASE_APB1_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_APB1_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_APB1_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_APB1_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_APB1_CLK_CLK_SEL(x) ((x) << CGU_BASE_APB1_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_APB3_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_APB3_CLK_PD_SHIFT (0) +#define CGU_BASE_APB3_CLK_PD (1 << CGU_BASE_APB3_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_APB3_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_APB3_CLK_AUTOBLOCK (1 << CGU_BASE_APB3_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_APB3_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_APB3_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_APB3_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_APB3_CLK_CLK_SEL(x) ((x) << CGU_BASE_APB3_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_LCD_CLK values ---------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_LCD_CLK_PD_SHIFT (0) +#define CGU_BASE_LCD_CLK_PD (1 << CGU_BASE_LCD_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_LCD_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_LCD_CLK_AUTOBLOCK (1 << CGU_BASE_LCD_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_LCD_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_LCD_CLK_CLK_SEL_MASK (0x1f << CGU_BASE_LCD_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_LCD_CLK_CLK_SEL(x) ((x) << CGU_BASE_LCD_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_VADC_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_VADC_CLK_PD_SHIFT (0) +#define CGU_BASE_VADC_CLK_PD (1 << CGU_BASE_VADC_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_VADC_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_VADC_CLK_AUTOBLOCK (1 << CGU_BASE_VADC_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_VADC_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_VADC_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_VADC_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_VADC_CLK_CLK_SEL(x) ((x) << CGU_BASE_VADC_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_SDIO_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_SDIO_CLK_PD_SHIFT (0) +#define CGU_BASE_SDIO_CLK_PD (1 << CGU_BASE_SDIO_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_SDIO_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_SDIO_CLK_AUTOBLOCK (1 << CGU_BASE_SDIO_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_SDIO_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_SDIO_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_SDIO_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_SDIO_CLK_CLK_SEL(x) ((x) << CGU_BASE_SDIO_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_SSP0_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_SSP0_CLK_PD_SHIFT (0) +#define CGU_BASE_SSP0_CLK_PD (1 << CGU_BASE_SSP0_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_SSP0_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_SSP0_CLK_AUTOBLOCK (1 << CGU_BASE_SSP0_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_SSP0_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_SSP0_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_SSP0_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_SSP0_CLK_CLK_SEL(x) ((x) << CGU_BASE_SSP0_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_SSP1_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_SSP1_CLK_PD_SHIFT (0) +#define CGU_BASE_SSP1_CLK_PD (1 << CGU_BASE_SSP1_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_SSP1_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_SSP1_CLK_AUTOBLOCK (1 << CGU_BASE_SSP1_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_SSP1_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_SSP1_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_SSP1_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_SSP1_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_SSP1_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_UART0_CLK values -------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_UART0_CLK_PD_SHIFT (0) +#define CGU_BASE_UART0_CLK_PD (1 << CGU_BASE_UART0_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_UART0_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_UART0_CLK_AUTOBLOCK \ + (1 << CGU_BASE_UART0_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_UART0_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_UART0_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_UART0_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_UART0_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_UART0_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_UART1_CLK values -------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_UART1_CLK_PD_SHIFT (0) +#define CGU_BASE_UART1_CLK_PD (1 << CGU_BASE_UART1_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_UART1_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_UART1_CLK_AUTOBLOCK \ + (1 << CGU_BASE_UART1_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_UART1_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_UART1_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_UART1_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_UART1_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_UART1_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_UART2_CLK values -------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_UART2_CLK_PD_SHIFT (0) +#define CGU_BASE_UART2_CLK_PD (1 << CGU_BASE_UART2_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_UART2_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_UART2_CLK_AUTOBLOCK \ + (1 << CGU_BASE_UART2_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_UART2_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_UART2_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_UART2_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_UART2_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_UART2_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_UART3_CLK values -------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_UART3_CLK_PD_SHIFT (0) +#define CGU_BASE_UART3_CLK_PD (1 << CGU_BASE_UART3_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_UART3_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_UART3_CLK_AUTOBLOCK \ + (1 << CGU_BASE_UART3_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_UART3_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_UART3_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_UART3_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_UART3_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_UART3_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_OUT_CLK values ---------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_OUT_CLK_PD_SHIFT (0) +#define CGU_BASE_OUT_CLK_PD (1 << CGU_BASE_OUT_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_OUT_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_OUT_CLK_AUTOBLOCK (1 << CGU_BASE_OUT_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_OUT_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_OUT_CLK_CLK_SEL_MASK (0x1f << CGU_BASE_OUT_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_OUT_CLK_CLK_SEL(x) ((x) << CGU_BASE_OUT_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_APLL_CLK values --------------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_APLL_CLK_PD_SHIFT (0) +#define CGU_BASE_APLL_CLK_PD (1 << CGU_BASE_APLL_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_APLL_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_APLL_CLK_AUTOBLOCK (1 << CGU_BASE_APLL_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_APLL_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_APLL_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_APLL_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_APLL_CLK_CLK_SEL(x) ((x) << CGU_BASE_APLL_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_CGU_OUT0_CLK values ----------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_CGU_OUT0_CLK_PD_SHIFT (0) +#define CGU_BASE_CGU_OUT0_CLK_PD (1 << CGU_BASE_CGU_OUT0_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_CGU_OUT0_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_CGU_OUT0_CLK_AUTOBLOCK \ + (1 << CGU_BASE_CGU_OUT0_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_CGU_OUT0_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_CGU_OUT0_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_CGU_OUT0_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_CGU_OUT0_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_CGU_OUT0_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_CGU_OUT1_CLK values ----------------------------- */ + +/* PD: Output stage power down */ +#define CGU_BASE_CGU_OUT1_CLK_PD_SHIFT (0) +#define CGU_BASE_CGU_OUT1_CLK_PD (1 << CGU_BASE_CGU_OUT1_CLK_PD_SHIFT) + +/* AUTOBLOCK: Block clock automatically during frequency change */ +#define CGU_BASE_CGU_OUT1_CLK_AUTOBLOCK_SHIFT (11) +#define CGU_BASE_CGU_OUT1_CLK_AUTOBLOCK \ + (1 << CGU_BASE_CGU_OUT1_CLK_AUTOBLOCK_SHIFT) + +/* CLK_SEL: Clock source selection */ +#define CGU_BASE_CGU_OUT1_CLK_CLK_SEL_SHIFT (24) +#define CGU_BASE_CGU_OUT1_CLK_CLK_SEL_MASK \ + (0x1f << CGU_BASE_CGU_OUT1_CLK_CLK_SEL_SHIFT) +#define CGU_BASE_CGU_OUT1_CLK_CLK_SEL(x) \ + ((x) << CGU_BASE_CGU_OUT1_CLK_CLK_SEL_SHIFT) + +/* --- CGU_BASE_x_CLK clock sources --------------------------------------- */ + +#define CGU_SRC_32K 0x00 +#define CGU_SRC_IRC 0x01 +#define CGU_SRC_ENET_RX 0x02 +#define CGU_SRC_ENET_TX 0x03 +#define CGU_SRC_GP_CLKIN 0x04 +#define CGU_SRC_XTAL 0x06 +#define CGU_SRC_PLL0USB 0x07 +#define CGU_SRC_PLL0AUDIO 0x08 +#define CGU_SRC_PLL1 0x09 +#define CGU_SRC_IDIVA 0x0C +#define CGU_SRC_IDIVB 0x0D +#define CGU_SRC_IDIVC 0x0E +#define CGU_SRC_IDIVD 0x0F +#define CGU_SRC_IDIVE 0x10 + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/creg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/creg.h new file mode 100644 index 00000000..2c695510 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/creg.h @@ -0,0 +1,354 @@ +/** @defgroup creg_defines Configuration Registers Defines + +@brief Defined Constants and Types for the LPC43xx Configuration +Registers + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_CREG_H +#define LPC43XX_CREG_H + +/**@{*/ + +#include +#include + +/* --- CREG registers ----------------------------------------------------- */ + +/* + * Chip configuration register 32 kHz oscillator output and BOD control + * register + */ +#define CREG_CREG0 MMIO32(CREG_BASE + 0x004) + +/* ARM Cortex-M4 memory mapping */ +#define CREG_M4MEMMAP MMIO32(CREG_BASE + 0x100) + +/* Chip configuration register 1 */ +#define CREG_CREG1 MMIO32(CREG_BASE + 0x108) + +/* Chip configuration register 2 */ +#define CREG_CREG2 MMIO32(CREG_BASE + 0x10C) + +/* Chip configuration register 3 */ +#define CREG_CREG3 MMIO32(CREG_BASE + 0x110) + +/* Chip configuration register 4 */ +#define CREG_CREG4 MMIO32(CREG_BASE + 0x114) + +/* Chip configuration register 5 */ +#define CREG_CREG5 MMIO32(CREG_BASE + 0x118) + +/* DMA muxing control */ +#define CREG_DMAMUX MMIO32(CREG_BASE + 0x11C) + +/* Flash accelerator configuration register for flash bank A */ +#define CREG_FLASHCFGA MMIO32(CREG_BASE + 0x120) + +/* Flash accelerator configuration register for flash bank B */ +#define CREG_FLASHCFGB MMIO32(CREG_BASE + 0x124) + +/* ETB RAM configuration */ +#define CREG_ETBCFG MMIO32(CREG_BASE + 0x128) + +/* + * Chip configuration register 6. Controls multiple functions: Ethernet + * interface, SCT output, I2S0/1 inputs, EMC clock. + */ +#define CREG_CREG6 MMIO32(CREG_BASE + 0x12C) + +/* Cortex-M4 TXEV event clear */ +#define CREG_M4TXEVENT MMIO32(CREG_BASE + 0x130) + +/* Part ID (Boundary scan ID code, read-only) */ +#define CREG_CHIPID MMIO32(CREG_BASE + 0x200) + +/* Cortex-M0 TXEV event clear */ +#define CREG_M0TXEVENT MMIO32(CREG_BASE + 0x400) + +/* ARM Cortex-M0 memory mapping */ +#define CREG_M0APPMEMMAP MMIO32(CREG_BASE + 0x404) + +/* USB0 frame length adjust register */ +#define CREG_USB0FLADJ MMIO32(CREG_BASE + 0x500) + +/* USB1 frame length adjust register */ +#define CREG_USB1FLADJ MMIO32(CREG_BASE + 0x600) + +/* --- CREG_CREG0 values ---------------------------------------- */ + +/* EN1KHZ: Enable 1 kHz output */ +#define CREG_CREG0_EN1KHZ_SHIFT (0) +#define CREG_CREG0_EN1KHZ (1 << CREG_CREG0_EN1KHZ_SHIFT) + +/* EN32KHZ: Enable 32 kHz output */ +#define CREG_CREG0_EN32KHZ_SHIFT (1) +#define CREG_CREG0_EN32KHZ (1 << CREG_CREG0_EN32KHZ_SHIFT) + +/* RESET32KHZ: 32 kHz oscillator reset */ +#define CREG_CREG0_RESET32KHZ_SHIFT (2) +#define CREG_CREG0_RESET32KHZ (1 << CREG_CREG0_RESET32KHZ_SHIFT) + +/* PD32KHZ: 32 kHz power control */ +#define CREG_CREG0_PD32KHZ_SHIFT (3) +#define CREG_CREG0_PD32KHZ (1 << CREG_CREG0_PD32KHZ_SHIFT) + +/* USB0PHY: USB0 PHY power control */ +#define CREG_CREG0_USB0PHY_SHIFT (5) +#define CREG_CREG0_USB0PHY (1 << CREG_CREG0_USB0PHY_SHIFT) + +/* ALARMCTRL: RTC_ALARM pin output control */ +#define CREG_CREG0_ALARMCTRL_SHIFT (6) +#define CREG_CREG0_ALARMCTRL_MASK (0x3 << CREG_CREG0_ALARMCTRL_SHIFT) +#define CREG_CREG0_ALARMCTRL(x) ((x) << CREG_CREG0_ALARMCTRL_SHIFT) + +/* BODLVL1: BOD trip level to generate an interrupt */ +#define CREG_CREG0_BODLVL1_SHIFT (8) +#define CREG_CREG0_BODLVL1_MASK (0x3 << CREG_CREG0_BODLVL1_SHIFT) +#define CREG_CREG0_BODLVL1(x) ((x) << CREG_CREG0_BODLVL1_SHIFT) + +/* BODLVL2: BOD trip level to generate a reset */ +#define CREG_CREG0_BODLVL2_SHIFT (10) +#define CREG_CREG0_BODLVL2_MASK (0x3 << CREG_CREG0_BODLVL2_SHIFT) +#define CREG_CREG0_BODLVL2(x) ((x) << CREG_CREG0_BODLVL2_SHIFT) + +/* SAMPLECTRL: SAMPLE pin input/output control */ +#define CREG_CREG0_SAMPLECTRL_SHIFT (12) +#define CREG_CREG0_SAMPLECTRL_MASK (0x3 << CREG_CREG0_SAMPLECTRL_SHIFT) +#define CREG_CREG0_SAMPLECTRL(x) ((x) << CREG_CREG0_SAMPLECTRL_SHIFT) + +/* WAKEUP0CTRL: WAKEUP0 pin input/output control */ +#define CREG_CREG0_WAKEUP0CTRL_SHIFT (14) +#define CREG_CREG0_WAKEUP0CTRL_MASK (0x3 << CREG_CREG0_WAKEUP0CTRL_SHIFT) +#define CREG_CREG0_WAKEUP0CTRL(x) ((x) << CREG_CREG0_WAKEUP0CTRL_SHIFT) + +/* WAKEUP1CTRL: WAKEUP1 pin input/output control */ +#define CREG_CREG0_WAKEUP1CTRL_SHIFT (16) +#define CREG_CREG0_WAKEUP1CTRL_MASK (0x3 << CREG_CREG0_WAKEUP1CTRL_SHIFT) +#define CREG_CREG0_WAKEUP1CTRL(x) ((x) << CREG_CREG0_WAKEUP1CTRL_SHIFT) + +/* --- CREG_M4MEMMAP values ------------------------------------- */ + +/* M4MAP: Shadow address when accessing memory at address 0x00000000 */ +#define CREG_M4MEMMAP_M4MAP_SHIFT (12) +#define CREG_M4MEMMAP_M4MAP_MASK (0xfffff << CREG_M4MEMMAP_M4MAP_SHIFT) +#define CREG_M4MEMMAP_M4MAP(x) ((x) << CREG_M4MEMMAP_M4MAP_SHIFT) + +/* --- CREG_CREG5 values ---------------------------------------- */ + +/* M4TAPSEL: JTAG debug select for M4 core */ +#define CREG_CREG5_M4TAPSEL_SHIFT (6) +#define CREG_CREG5_M4TAPSEL (1 << CREG_CREG5_M4TAPSEL_SHIFT) + +/* M0APPTAPSEL: JTAG debug select for M0 co-processor */ +#define CREG_CREG5_M0APPTAPSEL_SHIFT (9) +#define CREG_CREG5_M0APPTAPSEL (1 << CREG_CREG5_M0APPTAPSEL_SHIFT) + +/* --- CREG_DMAMUX values --------------------------------------- */ + +/* DMAMUXPER0: Select DMA to peripheral connection for DMA peripheral 0 */ +#define CREG_DMAMUX_DMAMUXPER0_SHIFT (0) +#define CREG_DMAMUX_DMAMUXPER0_MASK (0x3 << CREG_DMAMUX_DMAMUXPER0_SHIFT) +#define CREG_DMAMUX_DMAMUXPER0(x) ((x) << CREG_DMAMUX_DMAMUXPER0_SHIFT) + +/* DMAMUXPER1: Select DMA to peripheral connection for DMA peripheral 1 */ +#define CREG_DMAMUX_DMAMUXPER1_SHIFT (2) +#define CREG_DMAMUX_DMAMUXPER1_MASK (0x3 << CREG_DMAMUX_DMAMUXPER1_SHIFT) +#define CREG_DMAMUX_DMAMUXPER1(x) ((x) << CREG_DMAMUX_DMAMUXPER1_SHIFT) + +/* DMAMUXPER2: Select DMA to peripheral connection for DMA peripheral 2 */ +#define CREG_DMAMUX_DMAMUXPER2_SHIFT (4) +#define CREG_DMAMUX_DMAMUXPER2_MASK (0x3 << CREG_DMAMUX_DMAMUXPER2_SHIFT) +#define CREG_DMAMUX_DMAMUXPER2(x) ((x) << CREG_DMAMUX_DMAMUXPER2_SHIFT) + +/* DMAMUXPER3: Select DMA to peripheral connection for DMA peripheral 3 */ +#define CREG_DMAMUX_DMAMUXPER3_SHIFT (6) +#define CREG_DMAMUX_DMAMUXPER3_MASK (0x3 << CREG_DMAMUX_DMAMUXPER3_SHIFT) +#define CREG_DMAMUX_DMAMUXPER3(x) ((x) << CREG_DMAMUX_DMAMUXPER3_SHIFT) + +/* DMAMUXPER4: Select DMA to peripheral connection for DMA peripheral 4 */ +#define CREG_DMAMUX_DMAMUXPER4_SHIFT (8) +#define CREG_DMAMUX_DMAMUXPER4_MASK (0x3 << CREG_DMAMUX_DMAMUXPER4_SHIFT) +#define CREG_DMAMUX_DMAMUXPER4(x) ((x) << CREG_DMAMUX_DMAMUXPER4_SHIFT) + +/* DMAMUXPER5: Select DMA to peripheral connection for DMA peripheral 5 */ +#define CREG_DMAMUX_DMAMUXPER5_SHIFT (10) +#define CREG_DMAMUX_DMAMUXPER5_MASK (0x3 << CREG_DMAMUX_DMAMUXPER5_SHIFT) +#define CREG_DMAMUX_DMAMUXPER5(x) ((x) << CREG_DMAMUX_DMAMUXPER5_SHIFT) + +/* DMAMUXPER6: Select DMA to peripheral connection for DMA peripheral 6 */ +#define CREG_DMAMUX_DMAMUXPER6_SHIFT (12) +#define CREG_DMAMUX_DMAMUXPER6_MASK (0x3 << CREG_DMAMUX_DMAMUXPER6_SHIFT) +#define CREG_DMAMUX_DMAMUXPER6(x) ((x) << CREG_DMAMUX_DMAMUXPER6_SHIFT) + +/* DMAMUXPER7: Select DMA to peripheral connection for DMA peripheral 7 */ +#define CREG_DMAMUX_DMAMUXPER7_SHIFT (14) +#define CREG_DMAMUX_DMAMUXPER7_MASK (0x3 << CREG_DMAMUX_DMAMUXPER7_SHIFT) +#define CREG_DMAMUX_DMAMUXPER7(x) ((x) << CREG_DMAMUX_DMAMUXPER7_SHIFT) + +/* DMAMUXPER8: Select DMA to peripheral connection for DMA peripheral 8 */ +#define CREG_DMAMUX_DMAMUXPER8_SHIFT (16) +#define CREG_DMAMUX_DMAMUXPER8_MASK (0x3 << CREG_DMAMUX_DMAMUXPER8_SHIFT) +#define CREG_DMAMUX_DMAMUXPER8(x) ((x) << CREG_DMAMUX_DMAMUXPER8_SHIFT) + +/* DMAMUXPER9: Select DMA to peripheral connection for DMA peripheral 9 */ +#define CREG_DMAMUX_DMAMUXPER9_SHIFT (18) +#define CREG_DMAMUX_DMAMUXPER9_MASK (0x3 << CREG_DMAMUX_DMAMUXPER9_SHIFT) +#define CREG_DMAMUX_DMAMUXPER9(x) ((x) << CREG_DMAMUX_DMAMUXPER9_SHIFT) + +/* DMAMUXPER10: Select DMA to peripheral connection for DMA peripheral 10 */ +#define CREG_DMAMUX_DMAMUXPER10_SHIFT (20) +#define CREG_DMAMUX_DMAMUXPER10_MASK (0x3 << CREG_DMAMUX_DMAMUXPER10_SHIFT) +#define CREG_DMAMUX_DMAMUXPER10(x) ((x) << CREG_DMAMUX_DMAMUXPER10_SHIFT) + +/* DMAMUXPER11: Select DMA to peripheral connection for DMA peripheral 11 */ +#define CREG_DMAMUX_DMAMUXPER11_SHIFT (22) +#define CREG_DMAMUX_DMAMUXPER11_MASK (0x3 << CREG_DMAMUX_DMAMUXPER11_SHIFT) +#define CREG_DMAMUX_DMAMUXPER11(x) ((x) << CREG_DMAMUX_DMAMUXPER11_SHIFT) + +/* DMAMUXPER12: Select DMA to peripheral connection for DMA peripheral 12 */ +#define CREG_DMAMUX_DMAMUXPER12_SHIFT (24) +#define CREG_DMAMUX_DMAMUXPER12_MASK (0x3 << CREG_DMAMUX_DMAMUXPER12_SHIFT) +#define CREG_DMAMUX_DMAMUXPER12(x) ((x) << CREG_DMAMUX_DMAMUXPER12_SHIFT) + +/* DMAMUXPER13: Select DMA to peripheral connection for DMA peripheral 13 */ +#define CREG_DMAMUX_DMAMUXPER13_SHIFT (26) +#define CREG_DMAMUX_DMAMUXPER13_MASK (0x3 << CREG_DMAMUX_DMAMUXPER13_SHIFT) +#define CREG_DMAMUX_DMAMUXPER13(x) ((x) << CREG_DMAMUX_DMAMUXPER13_SHIFT) + +/* DMAMUXPER14: Select DMA to peripheral connection for DMA peripheral 14 */ +#define CREG_DMAMUX_DMAMUXPER14_SHIFT (28) +#define CREG_DMAMUX_DMAMUXPER14_MASK (0x3 << CREG_DMAMUX_DMAMUXPER14_SHIFT) +#define CREG_DMAMUX_DMAMUXPER14(x) ((x) << CREG_DMAMUX_DMAMUXPER14_SHIFT) + +/* DMAMUXPER15: Select DMA to peripheral connection for DMA peripheral 15 */ +#define CREG_DMAMUX_DMAMUXPER15_SHIFT (30) +#define CREG_DMAMUX_DMAMUXPER15_MASK (0x3 << CREG_DMAMUX_DMAMUXPER15_SHIFT) +#define CREG_DMAMUX_DMAMUXPER15(x) ((x) << CREG_DMAMUX_DMAMUXPER15_SHIFT) + +/* --- CREG_FLASHCFGA values ------------------------------------ */ + +/* FLASHTIM: Flash access time. The value of this field plus 1 gives the number + * of BASE_M4_CLK clocks used for a flash access */ +#define CREG_FLASHCFGA_FLASHTIM_SHIFT (12) +#define CREG_FLASHCFGA_FLASHTIM_MASK (0xf << CREG_FLASHCFGA_FLASHTIM_SHIFT) +#define CREG_FLASHCFGA_FLASHTIM(x) ((x) << CREG_FLASHCFGA_FLASHTIM_SHIFT) + +/* POW: Flash bank A power control */ +#define CREG_FLASHCFGA_POW_SHIFT (31) +#define CREG_FLASHCFGA_POW (1 << CREG_FLASHCFGA_POW_SHIFT) + +/* --- CREG_FLASHCFGB values ------------------------------------ */ + +/* FLASHTIM: Flash access time. The value of this field plus 1 gives the number + * of BASE_M4_CLK clocks used for a flash access */ +#define CREG_FLASHCFGB_FLASHTIM_SHIFT (12) +#define CREG_FLASHCFGB_FLASHTIM_MASK (0xf << CREG_FLASHCFGB_FLASHTIM_SHIFT) +#define CREG_FLASHCFGB_FLASHTIM(x) ((x) << CREG_FLASHCFGB_FLASHTIM_SHIFT) + +/* POW: Flash bank B power control */ +#define CREG_FLASHCFGB_POW_SHIFT (31) +#define CREG_FLASHCFGB_POW (1 << CREG_FLASHCFGB_POW_SHIFT) + +/* --- CREG_ETBCFG values --------------------------------------- */ + +/* ETB: Select SRAM interface */ +#define CREG_ETBCFG_ETB_SHIFT (0) +#define CREG_ETBCFG_ETB (1 << CREG_ETBCFG_ETB_SHIFT) + +/* --- CREG_CREG6 values ---------------------------------------- */ + +/* ETHMODE: Selects the Ethernet mode. Reset the ethernet after changing the + * PHY interface */ +#define CREG_CREG6_ETHMODE_SHIFT (0) +#define CREG_CREG6_ETHMODE_MASK (0x7 << CREG_CREG6_ETHMODE_SHIFT) +#define CREG_CREG6_ETHMODE(x) ((x) << CREG_CREG6_ETHMODE_SHIFT) + +/* CTOUTCTRL: Selects the functionality of the SCT outputs */ +#define CREG_CREG6_CTOUTCTRL_SHIFT (4) +#define CREG_CREG6_CTOUTCTRL (1 << CREG_CREG6_CTOUTCTRL_SHIFT) + +/* I2S0_TX_SCK_IN_SEL: I2S0_TX_SCK input select */ +#define CREG_CREG6_I2S0_TX_SCK_IN_SEL_SHIFT (12) +#define CREG_CREG6_I2S0_TX_SCK_IN_SEL (1 << CREG_CREG6_I2S0_TX_SCK_IN_SEL_SHIFT) + +/* I2S0_RX_SCK_IN_SEL: I2S0_RX_SCK input select */ +#define CREG_CREG6_I2S0_RX_SCK_IN_SEL_SHIFT (13) +#define CREG_CREG6_I2S0_RX_SCK_IN_SEL (1 << CREG_CREG6_I2S0_RX_SCK_IN_SEL_SHIFT) + +/* I2S1_TX_SCK_IN_SEL: I2S1_TX_SCK input select */ +#define CREG_CREG6_I2S1_TX_SCK_IN_SEL_SHIFT (14) +#define CREG_CREG6_I2S1_TX_SCK_IN_SEL (1 << CREG_CREG6_I2S1_TX_SCK_IN_SEL_SHIFT) + +/* I2S1_RX_SCK_IN_SEL: I2S1_RX_SCK input select */ +#define CREG_CREG6_I2S1_RX_SCK_IN_SEL_SHIFT (15) +#define CREG_CREG6_I2S1_RX_SCK_IN_SEL (1 << CREG_CREG6_I2S1_RX_SCK_IN_SEL_SHIFT) + +/* EMC_CLK_SEL: EMC_CLK divided clock select */ +#define CREG_CREG6_EMC_CLK_SEL_SHIFT (16) +#define CREG_CREG6_EMC_CLK_SEL (1 << CREG_CREG6_EMC_CLK_SEL_SHIFT) + +/* --- CREG_M4TXEVENT values ------------------------------------ */ + +/* TXEVCLR: Cortex-M4 TXEV event */ +#define CREG_M4TXEVENT_TXEVCLR_SHIFT (0) +#define CREG_M4TXEVENT_TXEVCLR (1 << CREG_M4TXEVENT_TXEVCLR_SHIFT) + +/* --- CREG_M0TXEVENT values ------------------------------------ */ + +/* TXEVCLR: Cortex-M0 TXEV event */ +#define CREG_M0TXEVENT_TXEVCLR_SHIFT (0) +#define CREG_M0TXEVENT_TXEVCLR (1 << CREG_M0TXEVENT_TXEVCLR_SHIFT) + +/* --- CREG_M0APPMEMMAP values ---------------------------------- */ + +/* M0APPMAP: Shadow address when accessing memory at address 0x00000000 */ +#define CREG_M0APPMEMMAP_M0APPMAP_SHIFT (12) +#define CREG_M0APPMEMMAP_M0APPMAP_MASK \ + (0xfffff << CREG_M0APPMEMMAP_M0APPMAP_SHIFT) +#define CREG_M0APPMEMMAP_M0APPMAP(x) ((x) << CREG_M0APPMEMMAP_M0APPMAP_SHIFT) + +/* --- CREG_USB0FLADJ values ------------------------------------ */ + +/* FLTV: Frame length timing value */ +#define CREG_USB0FLADJ_FLTV_SHIFT (0) +#define CREG_USB0FLADJ_FLTV_MASK (0x3f << CREG_USB0FLADJ_FLTV_SHIFT) +#define CREG_USB0FLADJ_FLTV(x) ((x) << CREG_USB0FLADJ_FLTV_SHIFT) + +/* --- CREG_USB1FLADJ values ------------------------------------ */ + +/* FLTV: Frame length timing value */ +#define CREG_USB1FLADJ_FLTV_SHIFT (0) +#define CREG_USB1FLADJ_FLTV_MASK (0x3f << CREG_USB1FLADJ_FLTV_SHIFT) +#define CREG_USB1FLADJ_FLTV(x) ((x) << CREG_USB1FLADJ_FLTV_SHIFT) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/doc-lpc43xx.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/doc-lpc43xx.h new file mode 100644 index 00000000..3c21aaeb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/doc-lpc43xx.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 LPC43xx + +@version 1.0.0 + +@date 14 September 2012 + +API documentation for NXP Semiconductors LPC43xx Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LPC43xx LPC43xx +Libraries for NXP Semiconductors LPC43xx series. + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup LPC43xx_defines LPC43xx Defines + +@brief Defined Constants and Types for the LPC43xx series + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/eventrouter.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/eventrouter.h new file mode 100644 index 00000000..d27c67ce --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/eventrouter.h @@ -0,0 +1,70 @@ +/** @defgroup eventrouter_defines Event Router Defines + +@brief Defined Constants and Types for the LPC43xx Event Router + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_EVENTROUTER_H +#define LPC43XX_EVENTROUTER_H + +/**@{*/ + +#include +#include + +/* --- Event Router registers ---------------------------------------------- */ + +/* Level configuration register */ +#define EVENTROUTER_HILO MMIO32(EVENTROUTER_BASE + 0x000) + +/* Edge configuration */ +#define EVENTROUTER_EDGE MMIO32(EVENTROUTER_BASE + 0x004) + +/* Clear event enable register */ +#define EVENTROUTER_CLR_EN MMIO32(EVENTROUTER_BASE + 0xFD8) + +/* Set event enable register */ +#define EVENTROUTER_SET_EN MMIO32(EVENTROUTER_BASE + 0xFDC) + +/* Event Status register */ +#define EVENTROUTER_STATUS MMIO32(EVENTROUTER_BASE + 0xFE0) + +/* Event Enable register */ +#define EVENTROUTER_ENABLE MMIO32(EVENTROUTER_BASE + 0xFE4) + +/* Clear event status register */ +#define EVENTROUTER_CLR_STAT MMIO32(EVENTROUTER_BASE + 0xFE8) + +/* Set event status register */ +#define EVENTROUTER_SET_STAT MMIO32(EVENTROUTER_BASE + 0xFEC) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gima.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gima.h new file mode 100644 index 00000000..6a36c76c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gima.h @@ -0,0 +1,137 @@ +/** @defgroup gima_defines Global Input Multiplexer Array Defines + +@brief Defined Constants and Types for the LPC43xx Global Input Multiplexer +Array + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_GIMA_H +#define LPC43XX_GIMA_H + +/**@{*/ + +#include +#include + +/* --- GIMA registers ----------------------------------------------------- */ + +/* Timer 0 CAP0_0 capture input multiplexer (GIMA output 0) */ +#define GIMA_CAP0_0_IN MMIO32(GIMA_BASE + 0x000) + +/* Timer 0 CAP0_1 capture input multiplexer (GIMA output 1) */ +#define GIMA_CAP0_1_IN MMIO32(GIMA_BASE + 0x004) + +/* Timer 0 CAP0_2 capture input multiplexer (GIMA output 2) */ +#define GIMA_CAP0_2_IN MMIO32(GIMA_BASE + 0x008) + +/* Timer 0 CAP0_3 capture input multiplexer (GIMA output 3) */ +#define GIMA_CAP0_3_IN MMIO32(GIMA_BASE + 0x00C) + +/* Timer 1 CAP1_0 capture input multiplexer (GIMA output 4) */ +#define GIMA_CAP1_0_IN MMIO32(GIMA_BASE + 0x010) + +/* Timer 1 CAP1_1 capture input multiplexer (GIMA output 5) */ +#define GIMA_CAP1_1_IN MMIO32(GIMA_BASE + 0x014) + +/* Timer 1 CAP1_2 capture input multiplexer (GIMA output 6) */ +#define GIMA_CAP1_2_IN MMIO32(GIMA_BASE + 0x018) + +/* Timer 1 CAP1_3 capture input multiplexer (GIMA output 7) */ +#define GIMA_CAP1_3_IN MMIO32(GIMA_BASE + 0x01C) + +/* Timer 2 CAP2_0 capture input multiplexer (GIMA output 8) */ +#define GIMA_CAP2_0_IN MMIO32(GIMA_BASE + 0x020) + +/* Timer 2 CAP2_1 capture input multiplexer (GIMA output 9) */ +#define GIMA_CAP2_1_IN MMIO32(GIMA_BASE + 0x024) + +/* Timer 2 CAP2_2 capture input multiplexer (GIMA output 10) */ +#define GIMA_CAP2_2_IN MMIO32(GIMA_BASE + 0x028) + +/* Timer 2 CAP2_3 capture input multiplexer (GIMA output 11) */ +#define GIMA_CAP2_3_IN MMIO32(GIMA_BASE + 0x02C) + +/* Timer 3 CAP3_0 capture input multiplexer (GIMA output 12) */ +#define GIMA_CAP3_0_IN MMIO32(GIMA_BASE + 0x030) + +/* Timer 3 CAP3_1 capture input multiplexer (GIMA output 13) */ +#define GIMA_CAP3_1_IN MMIO32(GIMA_BASE + 0x034) + +/* Timer 3 CAP3_2 capture input multiplexer (GIMA output 14) */ +#define GIMA_CAP3_2_IN MMIO32(GIMA_BASE + 0x038) + +/* Timer 3 CAP3_3 capture input multiplexer (GIMA output 15) */ +#define GIMA_CAP3_3_IN MMIO32(GIMA_BASE + 0x03C) + +/* SCT CTIN_0 capture input multiplexer (GIMA output 16) */ +#define GIMA_CTIN_0_IN MMIO32(GIMA_BASE + 0x040) + +/* SCT CTIN_1 capture input multiplexer (GIMA output 17) */ +#define GIMA_CTIN_1_IN MMIO32(GIMA_BASE + 0x044) + +/* SCT CTIN_2 capture input multiplexer (GIMA output 18) */ +#define GIMA_CTIN_2_IN MMIO32(GIMA_BASE + 0x048) + +/* SCT CTIN_3 capture input multiplexer (GIMA output 19) */ +#define GIMA_CTIN_3_IN MMIO32(GIMA_BASE + 0x04C) + +/* SCT CTIN_4 capture input multiplexer (GIMA output 20) */ +#define GIMA_CTIN_4_IN MMIO32(GIMA_BASE + 0x050) + +/* SCT CTIN_5 capture input multiplexer (GIMA output 21) */ +#define GIMA_CTIN_5_IN MMIO32(GIMA_BASE + 0x054) + +/* SCT CTIN_6 capture input multiplexer (GIMA output 22) */ +#define GIMA_CTIN_6_IN MMIO32(GIMA_BASE + 0x058) + +/* SCT CTIN_7 capture input multiplexer (GIMA output 23) */ +#define GIMA_CTIN_7_IN MMIO32(GIMA_BASE + 0x05C) + +/* VADC trigger input multiplexer (GIMA output 24) */ +#define GIMA_VADC_TRIGGER_IN MMIO32(GIMA_BASE + 0x060) + +/* Event router input 13 multiplexer (GIMA output 25) */ +#define GIMA_EVENTROUTER_13_IN MMIO32(GIMA_BASE + 0x064) + +/* Event router input 14 multiplexer (GIMA output 26) */ +#define GIMA_EVENTROUTER_14_IN MMIO32(GIMA_BASE + 0x068) + +/* Event router input 16 multiplexer (GIMA output 27) */ +#define GIMA_EVENTROUTER_16_IN MMIO32(GIMA_BASE + 0x06C) + +/* ADC start0 input multiplexer (GIMA output 28) */ +#define GIMA_ADCSTART0_IN MMIO32(GIMA_BASE + 0x070) + +/* ADC start1 input multiplexer (GIMA output 29) */ +#define GIMA_ADCSTART1_IN MMIO32(GIMA_BASE + 0x074) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpdma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpdma.h new file mode 100644 index 00000000..9df66989 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpdma.h @@ -0,0 +1,552 @@ +/** @defgroup gpdma_defines General Purpose DMA Defines + * + * @brief Defined Constants and Types for the LPC43xx General Purpose DMA + * + * @ingroup LPC43xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2012 Michael Ossmann + * + * @date 10 March 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_GPDMA_H +#define LPC43XX_GPDMA_H + +/**@{*/ + +#include +#include + +/* --- GPDMA registers ----------------------------------------------------- */ + +/* General registers */ + +/* DMA Interrupt Status Register */ +#define GPDMA_INTSTAT MMIO32(GPDMA_BASE + 0x000) + +/* DMA Interrupt Terminal Count Request Status Register */ +#define GPDMA_INTTCSTAT MMIO32(GPDMA_BASE + 0x004) + +/* DMA Interrupt Terminal Count Request Clear Register */ +#define GPDMA_INTTCCLEAR MMIO32(GPDMA_BASE + 0x008) + +/* DMA Interrupt Error Status Register */ +#define GPDMA_INTERRSTAT MMIO32(GPDMA_BASE + 0x00C) + +/* DMA Interrupt Error Clear Register */ +#define GPDMA_INTERRCLR MMIO32(GPDMA_BASE + 0x010) + +/* DMA Raw Interrupt Terminal Count Status Register */ +#define GPDMA_RAWINTTCSTAT MMIO32(GPDMA_BASE + 0x014) + +/* DMA Raw Error Interrupt Status Register */ +#define GPDMA_RAWINTERRSTAT MMIO32(GPDMA_BASE + 0x018) + +/* DMA Enabled Channel Register */ +#define GPDMA_ENBLDCHNS MMIO32(GPDMA_BASE + 0x01C) + +/* DMA Software Burst Request Register */ +#define GPDMA_SOFTBREQ MMIO32(GPDMA_BASE + 0x020) + +/* DMA Software Single Request Register */ +#define GPDMA_SOFTSREQ MMIO32(GPDMA_BASE + 0x024) + +/* DMA Software Last Burst Request Register */ +#define GPDMA_SOFTLBREQ MMIO32(GPDMA_BASE + 0x028) + +/* DMA Software Last Single Request Register */ +#define GPDMA_SOFTLSREQ MMIO32(GPDMA_BASE + 0x02C) + +/* DMA Configuration Register */ +#define GPDMA_CONFIG MMIO32(GPDMA_BASE + 0x030) + +/* DMA Synchronization Register */ +#define GPDMA_SYNC MMIO32(GPDMA_BASE + 0x034) + + +/* Channel registers */ + +/* Source Address Register */ +#define GPDMA_CSRCADDR(channel) MMIO32(GPDMA_BASE + 0x100 + \ + (channel * 0x20)) +#define GPDMA_C0SRCADDR GPDMA_CSRCADDR(0) +#define GPDMA_C1SRCADDR GPDMA_CSRCADDR(1) +#define GPDMA_C2SRCADDR GPDMA_CSRCADDR(2) +#define GPDMA_C3SRCADDR GPDMA_CSRCADDR(3) +#define GPDMA_C4SRCADDR GPDMA_CSRCADDR(4) +#define GPDMA_C5SRCADDR GPDMA_CSRCADDR(5) +#define GPDMA_C6SRCADDR GPDMA_CSRCADDR(6) +#define GPDMA_C7SRCADDR GPDMA_CSRCADDR(7) + +/* Destination Address Register */ +#define GPDMA_CDESTADDR(channel) MMIO32(GPDMA_BASE + 0x104 + \ + (channel * 0x20)) +#define GPDMA_C0DESTADDR GPDMA_CDESTADDR(0) +#define GPDMA_C1DESTADDR GPDMA_CDESTADDR(1) +#define GPDMA_C2DESTADDR GPDMA_CDESTADDR(2) +#define GPDMA_C3DESTADDR GPDMA_CDESTADDR(3) +#define GPDMA_C4DESTADDR GPDMA_CDESTADDR(4) +#define GPDMA_C5DESTADDR GPDMA_CDESTADDR(5) +#define GPDMA_C6DESTADDR GPDMA_CDESTADDR(6) +#define GPDMA_C7DESTADDR GPDMA_CDESTADDR(7) + +/* Linked List Item Register */ +#define GPDMA_CLLI(channel) MMIO32(GPDMA_BASE + 0x108 + \ + (channel * 0x20)) +#define GPDMA_C0LLI GPDMA_CLLI(0) +#define GPDMA_C1LLI GPDMA_CLLI(1) +#define GPDMA_C2LLI GPDMA_CLLI(2) +#define GPDMA_C3LLI GPDMA_CLLI(3) +#define GPDMA_C4LLI GPDMA_CLLI(4) +#define GPDMA_C5LLI GPDMA_CLLI(5) +#define GPDMA_C6LLI GPDMA_CLLI(6) +#define GPDMA_C7LLI GPDMA_CLLI(7) + +/* Control Register */ +#define GPDMA_CCONTROL(channel) MMIO32(GPDMA_BASE + 0x10C + \ + (channel * 0x20)) +#define GPDMA_C0CONTROL GPDMA_CCONTROL(0) +#define GPDMA_C1CONTROL GPDMA_CCONTROL(1) +#define GPDMA_C2CONTROL GPDMA_CCONTROL(2) +#define GPDMA_C3CONTROL GPDMA_CCONTROL(3) +#define GPDMA_C4CONTROL GPDMA_CCONTROL(4) +#define GPDMA_C5CONTROL GPDMA_CCONTROL(5) +#define GPDMA_C6CONTROL GPDMA_CCONTROL(6) +#define GPDMA_C7CONTROL GPDMA_CCONTROL(7) + +/* Configuration Register */ +#define GPDMA_CCONFIG(channel) MMIO32(GPDMA_BASE + 0x110 + \ + (channel * 0x20)) +#define GPDMA_C0CONFIG GPDMA_CCONFIG(0) +#define GPDMA_C1CONFIG GPDMA_CCONFIG(1) +#define GPDMA_C2CONFIG GPDMA_CCONFIG(2) +#define GPDMA_C3CONFIG GPDMA_CCONFIG(3) +#define GPDMA_C4CONFIG GPDMA_CCONFIG(4) +#define GPDMA_C5CONFIG GPDMA_CCONFIG(5) +#define GPDMA_C6CONFIG GPDMA_CCONFIG(6) +#define GPDMA_C7CONFIG GPDMA_CCONFIG(7) + +/* --- Common fields -------------------------------------------- */ + +#define GPDMA_CSRCADDR_SRCADDR_SHIFT (0) +#define GPDMA_CSRCADDR_SRCADDR_MASK (0xffffffff << GPDMA_CSRCADDR_SRCADDR_SHIFT) +#define GPDMA_CSRCADDR_SRCADDR(x) ((x) << GPDMA_CSRCADDR_SRCADDR_SHIFT) + +#define GPDMA_CDESTADDR_DESTADDR_SHIFT (0) +#define GPDMA_CDESTADDR_DESTADDR_MASK \ + (0xffffffff << GPDMA_CDESTADDR_DESTADDR_SHIFT) +#define GPDMA_CDESTADDR_DESTADDR(x) ((x) << GPDMA_CDESTADDR_DESTADDR_SHIFT) + +#define GPDMA_CLLI_LM_SHIFT (0) +#define GPDMA_CLLI_LM_MASK (0x1 << GPDMA_CLLI_LM_SHIFT) +#define GPDMA_CLLI_LM(x) ((x) << GPDMA_CLLI_LM_SHIFT) + +#define GPDMA_CLLI_LLI_SHIFT (2) +#define GPDMA_CLLI_LLI_MASK (0x3fffffff << GPDMA_CLLI_LLI_SHIFT) +#define GPDMA_CLLI_LLI(x) ((x) << GPDMA_CLLI_LLI_SHIFT) + +#define GPDMA_CCONTROL_TRANSFERSIZE_SHIFT (0) +#define GPDMA_CCONTROL_TRANSFERSIZE_MASK \ + (0xfff << GPDMA_CCONTROL_TRANSFERSIZE_SHIFT) +#define GPDMA_CCONTROL_TRANSFERSIZE(x) \ + ((x) << GPDMA_CCONTROL_TRANSFERSIZE_SHIFT) + +#define GPDMA_CCONTROL_SBSIZE_SHIFT (12) +#define GPDMA_CCONTROL_SBSIZE_MASK (0x7 << GPDMA_CCONTROL_SBSIZE_SHIFT) +#define GPDMA_CCONTROL_SBSIZE(x) ((x) << GPDMA_CCONTROL_SBSIZE_SHIFT) + +#define GPDMA_CCONTROL_DBSIZE_SHIFT (15) +#define GPDMA_CCONTROL_DBSIZE_MASK (0x7 << GPDMA_CCONTROL_DBSIZE_SHIFT) +#define GPDMA_CCONTROL_DBSIZE(x) ((x) << GPDMA_CCONTROL_DBSIZE_SHIFT) + +#define GPDMA_CCONTROL_SWIDTH_SHIFT (18) +#define GPDMA_CCONTROL_SWIDTH_MASK (0x7 << GPDMA_CCONTROL_SWIDTH_SHIFT) +#define GPDMA_CCONTROL_SWIDTH(x) ((x) << GPDMA_CCONTROL_SWIDTH_SHIFT) + +#define GPDMA_CCONTROL_DWIDTH_SHIFT (21) +#define GPDMA_CCONTROL_DWIDTH_MASK (0x7 << GPDMA_CCONTROL_DWIDTH_SHIFT) +#define GPDMA_CCONTROL_DWIDTH(x) ((x) << GPDMA_CCONTROL_DWIDTH_SHIFT) + +#define GPDMA_CCONTROL_S_SHIFT (24) +#define GPDMA_CCONTROL_S_MASK (0x1 << GPDMA_CCONTROL_S_SHIFT) +#define GPDMA_CCONTROL_S(x) ((x) << GPDMA_CCONTROL_S_SHIFT) + +#define GPDMA_CCONTROL_D_SHIFT (25) +#define GPDMA_CCONTROL_D_MASK (0x1 << GPDMA_CCONTROL_D_SHIFT) +#define GPDMA_CCONTROL_D(x) ((x) << GPDMA_CCONTROL_D_SHIFT) + +#define GPDMA_CCONTROL_SI_SHIFT (26) +#define GPDMA_CCONTROL_SI_MASK (0x1 << GPDMA_CCONTROL_SI_SHIFT) +#define GPDMA_CCONTROL_SI(x) ((x) << GPDMA_CCONTROL_SI_SHIFT) + +#define GPDMA_CCONTROL_DI_SHIFT (27) +#define GPDMA_CCONTROL_DI_MASK (0x1 << GPDMA_CCONTROL_DI_SHIFT) +#define GPDMA_CCONTROL_DI(x) ((x) << GPDMA_CCONTROL_DI_SHIFT) + +#define GPDMA_CCONTROL_PROT1_SHIFT (28) +#define GPDMA_CCONTROL_PROT1_MASK (0x1 << GPDMA_CCONTROL_PROT1_SHIFT) +#define GPDMA_CCONTROL_PROT1(x) ((x) << GPDMA_CCONTROL_PROT1_SHIFT) + +#define GPDMA_CCONTROL_PROT2_SHIFT (29) +#define GPDMA_CCONTROL_PROT2_MASK (0x1 << GPDMA_CCONTROL_PROT2_SHIFT) +#define GPDMA_CCONTROL_PROT2(x) ((x) << GPDMA_CCONTROL_PROT2_SHIFT) + +#define GPDMA_CCONTROL_PROT3_SHIFT (30) +#define GPDMA_CCONTROL_PROT3_MASK (0x1 << GPDMA_CCONTROL_PROT3_SHIFT) +#define GPDMA_CCONTROL_PROT3(x) ((x) << GPDMA_CCONTROL_PROT3_SHIFT) + +#define GPDMA_CCONTROL_I_SHIFT (31) +#define GPDMA_CCONTROL_I_MASK (0x1 << GPDMA_CCONTROL_I_SHIFT) +#define GPDMA_CCONTROL_I(x) ((x) << GPDMA_CCONTROL_I_SHIFT) + +#define GPDMA_CCONFIG_E_SHIFT (0) +#define GPDMA_CCONFIG_E_MASK (0x1 << GPDMA_CCONFIG_E_SHIFT) +#define GPDMA_CCONFIG_E(x) ((x) << GPDMA_CCONFIG_E_SHIFT) + +#define GPDMA_CCONFIG_SRCPERIPHERAL_SHIFT (1) +#define GPDMA_CCONFIG_SRCPERIPHERAL_MASK \ + (0x1f << GPDMA_CCONFIG_SRCPERIPHERAL_SHIFT) +#define GPDMA_CCONFIG_SRCPERIPHERAL(x) \ + ((x) << GPDMA_CCONFIG_SRCPERIPHERAL_SHIFT) + +#define GPDMA_CCONFIG_DESTPERIPHERAL_SHIFT (6) +#define GPDMA_CCONFIG_DESTPERIPHERAL_MASK \ + (0x1f << GPDMA_CCONFIG_DESTPERIPHERAL_SHIFT) +#define GPDMA_CCONFIG_DESTPERIPHERAL(x) \ + ((x) << GPDMA_CCONFIG_DESTPERIPHERAL_SHIFT) + +#define GPDMA_CCONFIG_FLOWCNTRL_SHIFT (11) +#define GPDMA_CCONFIG_FLOWCNTRL_MASK (0x7 << GPDMA_CCONFIG_FLOWCNTRL_SHIFT) +#define GPDMA_CCONFIG_FLOWCNTRL(x) ((x) << GPDMA_CCONFIG_FLOWCNTRL_SHIFT) + +#define GPDMA_CCONFIG_IE_SHIFT (14) +#define GPDMA_CCONFIG_IE_MASK (0x1 << GPDMA_CCONFIG_IE_SHIFT) +#define GPDMA_CCONFIG_IE(x) ((x) << GPDMA_CCONFIG_IE_SHIFT) + +#define GPDMA_CCONFIG_ITC_SHIFT (15) +#define GPDMA_CCONFIG_ITC_MASK (0x1 << GPDMA_CCONFIG_ITC_SHIFT) +#define GPDMA_CCONFIG_ITC(x) ((x) << GPDMA_CCONFIG_ITC_SHIFT) + +#define GPDMA_CCONFIG_L_SHIFT (16) +#define GPDMA_CCONFIG_L_MASK (0x1 << GPDMA_CCONFIG_L_SHIFT) +#define GPDMA_CCONFIG_L(x) ((x) << GPDMA_CCONFIG_L_SHIFT) + +#define GPDMA_CCONFIG_A_SHIFT (17) +#define GPDMA_CCONFIG_A_MASK (0x1 << GPDMA_CCONFIG_A_SHIFT) +#define GPDMA_CCONFIG_A(x) ((x) << GPDMA_CCONFIG_A_SHIFT) + +#define GPDMA_CCONFIG_H_SHIFT (18) +#define GPDMA_CCONFIG_H_MASK (0x1 << GPDMA_CCONFIG_H_SHIFT) +#define GPDMA_CCONFIG_H(x) ((x) << GPDMA_CCONFIG_H_SHIFT) + +/* --- AUTO-GENERATED STUFF FOLLOWS ----------------------------- */ + +/* --- GPDMA_NTSTAT values -------------------------------------- */ + +/* INTSTAT: Status of DMA channel interrupts after masking */ +#define GPDMA_NTSTAT_INTSTAT_SHIFT (0) +#define GPDMA_NTSTAT_INTSTAT_MASK (0xff << GPDMA_NTSTAT_INTSTAT_SHIFT) +#define GPDMA_NTSTAT_INTSTAT(x) ((x) << GPDMA_NTSTAT_INTSTAT_SHIFT) + +/* --- GPDMA_INTTCSTAT values ----------------------------------- */ + +/* INTTCSTAT: Terminal count interrupt request status for DMA channels */ +#define GPDMA_INTTCSTAT_INTTCSTAT_SHIFT (0) +#define GPDMA_INTTCSTAT_INTTCSTAT_MASK (0xff << GPDMA_INTTCSTAT_INTTCSTAT_SHIFT) +#define GPDMA_INTTCSTAT_INTTCSTAT(x) ((x) << GPDMA_INTTCSTAT_INTTCSTAT_SHIFT) + +/* --- GPDMA_INTTCCLEAR values ---------------------------------- */ + +/* INTTCCLEAR: Allows clearing the Terminal count interrupt request (IntTCStat) + for DMA channels */ +#define GPDMA_INTTCCLEAR_INTTCCLEAR_SHIFT (0) +#define GPDMA_INTTCCLEAR_INTTCCLEAR_MASK \ + (0xff << GPDMA_INTTCCLEAR_INTTCCLEAR_SHIFT) +#define GPDMA_INTTCCLEAR_INTTCCLEAR(x) \ + ((x) << GPDMA_INTTCCLEAR_INTTCCLEAR_SHIFT) + +/* --- GPDMA_INTERRSTAT values ---------------------------------- */ + +/* INTERRSTAT: Interrupt error status for DMA channels */ +#define GPDMA_INTERRSTAT_INTERRSTAT_SHIFT (0) +#define GPDMA_INTERRSTAT_INTERRSTAT_MASK \ + (0xff << GPDMA_INTERRSTAT_INTERRSTAT_SHIFT) +#define GPDMA_INTERRSTAT_INTERRSTAT(x) \ + ((x) << GPDMA_INTERRSTAT_INTERRSTAT_SHIFT) + +/* --- GPDMA_INTERRCLR values ----------------------------------- */ + +/* INTERRCLR: Writing a 1 clears the error interrupt request (IntErrStat) + for DMA channels */ +#define GPDMA_INTERRCLR_INTERRCLR_SHIFT (0) +#define GPDMA_INTERRCLR_INTERRCLR_MASK \ + (0xff << GPDMA_INTERRCLR_INTERRCLR_SHIFT) +#define GPDMA_INTERRCLR_INTERRCLR(x) \ + ((x) << GPDMA_INTERRCLR_INTERRCLR_SHIFT) + +/* --- GPDMA_RAWINTTCSTAT values -------------------------------- */ + +/* RAWINTTCSTAT: Status of the terminal count interrupt for DMA channels + prior to masking */ +#define GPDMA_RAWINTTCSTAT_RAWINTTCSTAT_SHIFT (0) +#define GPDMA_RAWINTTCSTAT_RAWINTTCSTAT_MASK \ + (0xff << GPDMA_RAWINTTCSTAT_RAWINTTCSTAT_SHIFT) +#define GPDMA_RAWINTTCSTAT_RAWINTTCSTAT(x) \ + ((x) << GPDMA_RAWINTTCSTAT_RAWINTTCSTAT_SHIFT) + +/* --- GPDMA_RAWINTERRSTAT values ------------------------------- */ + +/* RAWINTERRSTAT: Status of the error interrupt for DMA channels prior to + masking */ +#define GPDMA_RAWINTERRSTAT_RAWINTERRSTAT_SHIFT (0) +#define GPDMA_RAWINTERRSTAT_RAWINTERRSTAT_MASK \ + (0xff << GPDMA_RAWINTERRSTAT_RAWINTERRSTAT_SHIFT) +#define GPDMA_RAWINTERRSTAT_RAWINTERRSTAT(x) \ + ((x) << GPDMA_RAWINTERRSTAT_RAWINTERRSTAT_SHIFT) + +/* --- GPDMA_ENBLDCHNS values ----------------------------------- */ + +/* ENABLEDCHANNELS: Enable status for DMA channels */ +#define GPDMA_ENBLDCHNS_ENABLEDCHANNELS_SHIFT (0) +#define GPDMA_ENBLDCHNS_ENABLEDCHANNELS_MASK \ + (0xff << GPDMA_ENBLDCHNS_ENABLEDCHANNELS_SHIFT) +#define GPDMA_ENBLDCHNS_ENABLEDCHANNELS(x) \ + ((x) << GPDMA_ENBLDCHNS_ENABLEDCHANNELS_SHIFT) + +/* --- GPDMA_SOFTBREQ values ------------------------------------ */ + +/* SOFTBREQ: Software burst request flags for each of 16 possible sources */ +#define GPDMA_SOFTBREQ_SOFTBREQ_SHIFT (0) +#define GPDMA_SOFTBREQ_SOFTBREQ_MASK (0xffff << GPDMA_SOFTBREQ_SOFTBREQ_SHIFT) +#define GPDMA_SOFTBREQ_SOFTBREQ(x) ((x) << GPDMA_SOFTBREQ_SOFTBREQ_SHIFT) + +/* --- GPDMA_SOFTSREQ values ------------------------------------ */ + +/* SOFTSREQ: Software single transfer request flags for each of 16 possible + sources */ +#define GPDMA_SOFTSREQ_SOFTSREQ_SHIFT (0) +#define GPDMA_SOFTSREQ_SOFTSREQ_MASK (0xffff << GPDMA_SOFTSREQ_SOFTSREQ_SHIFT) +#define GPDMA_SOFTSREQ_SOFTSREQ(x) ((x) << GPDMA_SOFTSREQ_SOFTSREQ_SHIFT) + +/* --- GPDMA_SOFTLBREQ values ----------------------------------- */ + +/* SOFTLBREQ: Software last burst request flags for each of 16 possible + sources */ +#define GPDMA_SOFTLBREQ_SOFTLBREQ_SHIFT (0) +#define GPDMA_SOFTLBREQ_SOFTLBREQ_MASK \ + (0xffff << GPDMA_SOFTLBREQ_SOFTLBREQ_SHIFT) +#define GPDMA_SOFTLBREQ_SOFTLBREQ(x) \ + ((x) << GPDMA_SOFTLBREQ_SOFTLBREQ_SHIFT) + +/* --- GPDMA_SOFTLSREQ values ----------------------------------- */ + +/* SOFTLSREQ: Software last single transfer request flags for each of 16 + possible sources */ +#define GPDMA_SOFTLSREQ_SOFTLSREQ_SHIFT (0) +#define GPDMA_SOFTLSREQ_SOFTLSREQ_MASK \ + (0xffff << GPDMA_SOFTLSREQ_SOFTLSREQ_SHIFT) +#define GPDMA_SOFTLSREQ_SOFTLSREQ(x) \ + ((x) << GPDMA_SOFTLSREQ_SOFTLSREQ_SHIFT) + +/* --- GPDMA_CONFIG values -------------------------------------- */ + +/* E: DMA Controller enable */ +#define GPDMA_CONFIG_E_SHIFT (0) +#define GPDMA_CONFIG_E_MASK (0x1 << GPDMA_CONFIG_E_SHIFT) +#define GPDMA_CONFIG_E(x) ((x) << GPDMA_CONFIG_E_SHIFT) + +/* M0: AHB Master 0 endianness configuration */ +#define GPDMA_CONFIG_M0_SHIFT (1) +#define GPDMA_CONFIG_M0_MASK (0x1 << GPDMA_CONFIG_M0_SHIFT) +#define GPDMA_CONFIG_M0(x) ((x) << GPDMA_CONFIG_M0_SHIFT) + +/* M1: AHB Master 1 endianness configuration */ +#define GPDMA_CONFIG_M1_SHIFT (2) +#define GPDMA_CONFIG_M1_MASK (0x1 << GPDMA_CONFIG_M1_SHIFT) +#define GPDMA_CONFIG_M1(x) ((x) << GPDMA_CONFIG_M1_SHIFT) + +/* --- GPDMA_SYNC values ---------------------------------------- */ + +/* DMACSYNC: Controls the synchronization logic for DMA request signals */ +#define GPDMA_SYNC_DMACSYNC_SHIFT (0) +#define GPDMA_SYNC_DMACSYNC_MASK (0xffff << GPDMA_SYNC_DMACSYNC_SHIFT) +#define GPDMA_SYNC_DMACSYNC(x) ((x) << GPDMA_SYNC_DMACSYNC_SHIFT) + +/* --- GPDMA_C[0..7]SRCADDR values ----------------------------------- */ + +/* SRCADDR: DMA source address */ +#define GPDMA_CxSRCADDR_SRCADDR_SHIFT (0) +#define GPDMA_CxSRCADDR_SRCADDR_MASK \ + (0xffffffff << GPDMA_CxSRCADDR_SRCADDR_SHIFT) +#define GPDMA_CxSRCADDR_SRCADDR(x) ((x) << GPDMA_CxSRCADDR_SRCADDR_SHIFT) + +/* --- GPDMA_C[0..7]DESTADDR values ---------------------------------- */ + +/* DESTADDR: DMA source address */ +#define GPDMA_CxDESTADDR_DESTADDR_SHIFT (0) +#define GPDMA_CxDESTADDR_DESTADDR_MASK \ + (0xffffffff << GPDMA_CxDESTADDR_DESTADDR_SHIFT) +#define GPDMA_CxDESTADDR_DESTADDR(x) ((x) << GPDMA_CxDESTADDR_DESTADDR_SHIFT) + +/* --- GPDMA_C[0..7]LLI values --------------------------------------- */ + +/* LM: AHB master select for loading the next LLI */ +#define GPDMA_CxLLI_LM_SHIFT (0) +#define GPDMA_CxLLI_LM_MASK (0x1 << GPDMA_CxLLI_LM_SHIFT) +#define GPDMA_CxLLI_LM(x) ((x) << GPDMA_CxLLI_LM_SHIFT) + +/* LLI: Linked list item */ +#define GPDMA_CxLLI_LLI_SHIFT (2) +#define GPDMA_CxLLI_LLI_MASK (0x3fffffff << GPDMA_CxLLI_LLI_SHIFT) +#define GPDMA_CxLLI_LLI(x) ((x) << GPDMA_CxLLI_LLI_SHIFT) + +/* --- GPDMA_C[0..7]CONTROL values ----------------------------------- */ + +/* TRANSFERSIZE: Transfer size in number of transfers */ +#define GPDMA_CxCONTROL_TRANSFERSIZE_SHIFT (0) +#define GPDMA_CxCONTROL_TRANSFERSIZE_MASK \ + (0xfff << GPDMA_CxCONTROL_TRANSFERSIZE_SHIFT) +#define GPDMA_CxCONTROL_TRANSFERSIZE(x) \ + ((x) << GPDMA_CxCONTROL_TRANSFERSIZE_SHIFT) + +/* SBSIZE: Source burst size */ +#define GPDMA_CxCONTROL_SBSIZE_SHIFT (12) +#define GPDMA_CxCONTROL_SBSIZE_MASK (0x7 << GPDMA_CxCONTROL_SBSIZE_SHIFT) +#define GPDMA_CxCONTROL_SBSIZE(x) ((x) << GPDMA_CxCONTROL_SBSIZE_SHIFT) + +/* DBSIZE: Destination burst size */ +#define GPDMA_CxCONTROL_DBSIZE_SHIFT (15) +#define GPDMA_CxCONTROL_DBSIZE_MASK (0x7 << GPDMA_CxCONTROL_DBSIZE_SHIFT) +#define GPDMA_CxCONTROL_DBSIZE(x) ((x) << GPDMA_CxCONTROL_DBSIZE_SHIFT) + +/* SWIDTH: Source transfer width */ +#define GPDMA_CxCONTROL_SWIDTH_SHIFT (18) +#define GPDMA_CxCONTROL_SWIDTH_MASK (0x7 << GPDMA_CxCONTROL_SWIDTH_SHIFT) +#define GPDMA_CxCONTROL_SWIDTH(x) ((x) << GPDMA_CxCONTROL_SWIDTH_SHIFT) + +/* DWIDTH: Destination transfer width */ +#define GPDMA_CxCONTROL_DWIDTH_SHIFT (21) +#define GPDMA_CxCONTROL_DWIDTH_MASK (0x7 << GPDMA_CxCONTROL_DWIDTH_SHIFT) +#define GPDMA_CxCONTROL_DWIDTH(x) ((x) << GPDMA_CxCONTROL_DWIDTH_SHIFT) + +/* S: Source AHB master select */ +#define GPDMA_CxCONTROL_S_SHIFT (24) +#define GPDMA_CxCONTROL_S_MASK (0x1 << GPDMA_CxCONTROL_S_SHIFT) +#define GPDMA_CxCONTROL_S(x) ((x) << GPDMA_CxCONTROL_S_SHIFT) + +/* D: Destination AHB master select */ +#define GPDMA_CxCONTROL_D_SHIFT (25) +#define GPDMA_CxCONTROL_D_MASK (0x1 << GPDMA_CxCONTROL_D_SHIFT) +#define GPDMA_CxCONTROL_D(x) ((x) << GPDMA_CxCONTROL_D_SHIFT) + +/* SI: Source increment */ +#define GPDMA_CxCONTROL_SI_SHIFT (26) +#define GPDMA_CxCONTROL_SI_MASK (0x1 << GPDMA_CxCONTROL_SI_SHIFT) +#define GPDMA_Cx0CONTROL_SI(x) ((x) << GPDMA_CxCONTROL_SI_SHIFT) + +/* DI: Destination increment */ +#define GPDMA_CxCONTROL_DI_SHIFT (27) +#define GPDMA_CxCONTROL_DI_MASK (0x1 << GPDMA_CxCONTROL_DI_SHIFT) +#define GPDMA_CxCONTROL_DI(x) ((x) << GPDMA_CxCONTROL_DI_SHIFT) + +/* PROT1: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode */ +#define GPDMA_CxCONTROL_PROT1_SHIFT (28) +#define GPDMA_CxCONTROL_PROT1_MASK (0x1 << GPDMA_CxCONTROL_PROT1_SHIFT) +#define GPDMA_CxCONTROL_PROT1(x) ((x) << GPDMA_CxCONTROL_PROT1_SHIFT) + +/* PROT2: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or not + bufferable */ +#define GPDMA_CxCONTROL_PROT2_SHIFT (29) +#define GPDMA_CxCONTROL_PROT2_MASK (0x1 << GPDMA_CxCONTROL_PROT2_SHIFT) +#define GPDMA_CxCONTROL_PROT2(x) ((x) << GPDMA_CxCONTROL_PROT2_SHIFT) + +/* PROT3: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable */ +#define GPDMA_CxCONTROL_PROT3_SHIFT (30) +#define GPDMA_CxCONTROL_PROT3_MASK (0x1 << GPDMA_CxCONTROL_PROT3_SHIFT) +#define GPDMA_CxCONTROL_PROT3(x) ((x) << GPDMA_CxCONTROL_PROT3_SHIFT) + +/* I: Terminal count interrupt enable bit */ +#define GPDMA_CxCONTROL_I_SHIFT (31) +#define GPDMA_CxCONTROL_I_MASK (0x1 << GPDMA_CxCONTROL_I_SHIFT) +#define GPDMA_CxCONTROL_I(x) ((x) << GPDMA_CxCONTROL_I_SHIFT) + +/* --- GPDMA_C[0..7]CONFIG values ------------------------------------ */ + +/* E: Channel enable */ +#define GPDMA_CxCONFIG_E_SHIFT (0) +#define GPDMA_CxCONFIG_E_MASK (0x1 << GPDMA_CxCONFIG_E_SHIFT) +#define GPDMA_CxCONFIG_E(x) ((x) << GPDMA_CxCONFIG_E_SHIFT) + +/* SRCPERIPHERAL: Source peripheral */ +#define GPDMA_CxCONFIG_SRCPERIPHERAL_SHIFT (1) +#define GPDMA_CxCONFIG_SRCPERIPHERAL_MASK \ + (0x1f << GPDMA_CxCONFIG_SRCPERIPHERAL_SHIFT) +#define GPDMA_CxCONFIG_SRCPERIPHERAL(x) \ + ((x) << GPDMA_CxCONFIG_SRCPERIPHERAL_SHIFT) + +/* DESTPERIPHERAL: Destination peripheral */ +#define GPDMA_CxCONFIG_DESTPERIPHERAL_SHIFT (6) +#define GPDMA_CxCONFIG_DESTPERIPHERAL_MASK \ + (0x1f << GPDMA_CxCONFIG_DESTPERIPHERAL_SHIFT) +#define GPDMA_CxCONFIG_DESTPERIPHERAL(x) \ + ((x) << GPDMA_CxCONFIG_DESTPERIPHERAL_SHIFT) + +/* FLOWCNTRL: Flow control and transfer type */ +#define GPDMA_CxCONFIG_FLOWCNTRL_SHIFT (11) +#define GPDMA_CxCONFIG_FLOWCNTRL_MASK (0x7 << GPDMA_CxCONFIG_FLOWCNTRL_SHIFT) +#define GPDMA_CxCONFIG_FLOWCNTRL(x) ((x) << GPDMA_CxCONFIG_FLOWCNTRL_SHIFT) + +/* IE: Interrupt error mask */ +#define GPDMA_CxCONFIG_IE_SHIFT (14) +#define GPDMA_CxCONFIG_IE_MASK (0x1 << GPDMA_CxCONFIG_IE_SHIFT) +#define GPDMA_CxCONFIG_IE(x) ((x) << GPDMA_CxCONFIG_IE_SHIFT) + +/* ITC: Terminal count interrupt mask */ +#define GPDMA_CxCONFIG_ITC_SHIFT (15) +#define GPDMA_CxCONFIG_ITC_MASK (0x1 << GPDMA_CxCONFIG_ITC_SHIFT) +#define GPDMA_CxCONFIG_ITC(x) ((x) << GPDMA_CxCONFIG_ITC_SHIFT) + +/* L: Lock */ +#define GPDMA_CxCONFIG_L_SHIFT (16) +#define GPDMA_CxCONFIG_L_MASK (0x1 << GPDMA_CxCONFIG_L_SHIFT) +#define GPDMA_CxCONFIG_L(x) ((x) << GPDMA_CxCONFIG_L_SHIFT) + +/* A: Active */ +#define GPDMA_CxCONFIG_A_SHIFT (17) +#define GPDMA_CxCONFIG_A_MASK (0x1 << GPDMA_CxCONFIG_A_SHIFT) +#define GPDMA_CxCONFIG_A(x) ((x) << GPDMA_CxCONFIG_A_SHIFT) + +/* H: Halt */ +#define GPDMA_CxCONFIG_H_SHIFT (18) +#define GPDMA_CxCONFIG_H_MASK (0x1 << GPDMA_CxCONFIG_H_SHIFT) +#define GPDMA_CxCONFIG_H(x) ((x) << GPDMA_CxCONFIG_H_SHIFT) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpio.h new file mode 100644 index 00000000..c97521a8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/gpio.h @@ -0,0 +1,784 @@ +/** @defgroup gpio_defines General Purpose I/O Defines + +@brief Defined Constants and Types for the LPC43xx General Purpose I/O + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_GPIO_H +#define LPC43XX_GPIO_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +#define GPIO0 (GPIO_PORT_BASE + 0x2000) +#define GPIO1 (GPIO_PORT_BASE + 0x2004) +#define GPIO2 (GPIO_PORT_BASE + 0x2008) +#define GPIO3 (GPIO_PORT_BASE + 0x200C) +#define GPIO4 (GPIO_PORT_BASE + 0x2010) +#define GPIO5 (GPIO_PORT_BASE + 0x2014) +#define GPIO6 (GPIO_PORT_BASE + 0x2018) +#define GPIO7 (GPIO_PORT_BASE + 0x201C) + +/* GPIO number definitions (for convenience) */ +#define GPIOPIN0 (1 << 0) +#define GPIOPIN1 (1 << 1) +#define GPIOPIN2 (1 << 2) +#define GPIOPIN3 (1 << 3) +#define GPIOPIN4 (1 << 4) +#define GPIOPIN5 (1 << 5) +#define GPIOPIN6 (1 << 6) +#define GPIOPIN7 (1 << 7) +#define GPIOPIN8 (1 << 8) +#define GPIOPIN9 (1 << 9) +#define GPIOPIN10 (1 << 10) +#define GPIOPIN11 (1 << 11) +#define GPIOPIN12 (1 << 12) +#define GPIOPIN13 (1 << 13) +#define GPIOPIN14 (1 << 14) +#define GPIOPIN15 (1 << 15) +#define GPIOPIN16 (1 << 16) +#define GPIOPIN17 (1 << 17) +#define GPIOPIN18 (1 << 18) +#define GPIOPIN19 (1 << 19) +#define GPIOPIN20 (1 << 20) +#define GPIOPIN21 (1 << 21) +#define GPIOPIN22 (1 << 22) +#define GPIOPIN23 (1 << 23) +#define GPIOPIN24 (1 << 24) +#define GPIOPIN25 (1 << 25) +#define GPIOPIN26 (1 << 26) +#define GPIOPIN27 (1 << 27) +#define GPIOPIN28 (1 << 28) +#define GPIOPIN29 (1 << 29) +#define GPIOPIN30 (1 << 30) +#define GPIOPIN31 (1 << 31) + +/* --- GPIO registers ------------------------------------------------------ */ + +/* GPIO pin interrupts */ + +/* Pin Interrupt Mode register */ +#define GPIO_PIN_INTERRUPT_ISEL MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x000) + +/* Pin interrupt level (rising edge) interrupt enable register */ +#define GPIO_PIN_INTERRUPT_IENR MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x004) + +/* Pin interrupt level (rising edge) interrupt set register */ +#define GPIO_PIN_INTERRUPT_SIENR MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x008) + +/* Pin interrupt level (rising edge interrupt) clear register */ +#define GPIO_PIN_INTERRUPT_CIENR MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x00C) + +/* Pin interrupt active level (falling edge) interrupt enable register */ +#define GPIO_PIN_INTERRUPT_IENF MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x010) + +/* Pin interrupt active level (falling edge) interrupt set register */ +#define GPIO_PIN_INTERRUPT_SIENF MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x014) + +/* Pin interrupt active level (falling edge) interrupt clear register */ +#define GPIO_PIN_INTERRUPT_CIENF MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x018) + +/* Pin interrupt rising edge register */ +#define GPIO_PIN_INTERRUPT_RISE MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x01C) + +/* Pin interrupt falling edge register */ +#define GPIO_PIN_INTERRUPT_FALL MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x020) + +/* Pin interrupt status register */ +#define GPIO_PIN_INTERRUPT_IST MMIO32(GPIO_PIN_INTERRUPT_BASE + 0x024) + +/* GPIO GROUP0 interrupt */ + +/* GPIO grouped interrupt control register */ +#define GPIO_GROUP0_INTERRUPT_CTRL \ + MMIO32(GPIO_GROUP0_INTERRUPT_BASE + 0x000) + +/* GPIO grouped interrupt port [0..7] polarity register */ +#define GPIO_GROUP0_INTERRUPT_PORT_POL(x) \ + MMIO32(GPIO_GROUP0_INTERRUPT_BASE + 0x020 + ((x)*4)) + +/* GPIO grouped interrupt port [0..7] enable register */ +#define GPIO_GROUP0_INTERRUPT_PORT_ENA(x) \ + MMIO32(GPIO_GROUP0_INTERRUPT_BASE + 0x040 + ((x)*4)) + +/* GPIO GROUP1 interrupt */ + +/* GPIO grouped interrupt control register */ +#define GPIO_GROUP1_INTERRUPT_CTRL \ + MMIO32(GPIO_GROUP1_INTERRUPT_BASE + 0x000) + +/* GPIO grouped interrupt port [0..7] polarity register */ +#define GPIO_GROUP1_INTERRUPT_PORT_POL(x) \ + MMIO32(GPIO_GROUP1_INTERRUPT_BASE + 0x020 + ((x)*4)) + +/* GPIO grouped interrupt port [0..7] enable register */ +#define GPIO_GROUP1_INTERRUPT_PORT_ENA(x) \ + MMIO32(GPIO_GROUP1_INTERRUPT_BASE + 0x040 + ((x)*4)) + +/* Byte pin registers port 0; pins PIO0_0 to PIO0_31 (R/W) */ +#define GPIO_B0 (GPIO_PORT_BASE + 0x0000) +#define GPIO_B1 (GPIO_PORT_BASE + 0x0001) +#define GPIO_B2 (GPIO_PORT_BASE + 0x0002) +#define GPIO_B3 (GPIO_PORT_BASE + 0x0003) +#define GPIO_B4 (GPIO_PORT_BASE + 0x0004) +#define GPIO_B5 (GPIO_PORT_BASE + 0x0005) +#define GPIO_B6 (GPIO_PORT_BASE + 0x0006) +#define GPIO_B7 (GPIO_PORT_BASE + 0x0007) +#define GPIO_B8 (GPIO_PORT_BASE + 0x0008) +#define GPIO_B9 (GPIO_PORT_BASE + 0x0009) +#define GPIO_B10 (GPIO_PORT_BASE + 0x000A) +#define GPIO_B11 (GPIO_PORT_BASE + 0x000B) +#define GPIO_B12 (GPIO_PORT_BASE + 0x000C) +#define GPIO_B13 (GPIO_PORT_BASE + 0x000D) +#define GPIO_B14 (GPIO_PORT_BASE + 0x000E) +#define GPIO_B15 (GPIO_PORT_BASE + 0x000F) +#define GPIO_B16 (GPIO_PORT_BASE + 0x0010) +#define GPIO_B17 (GPIO_PORT_BASE + 0x0011) +#define GPIO_B18 (GPIO_PORT_BASE + 0x0012) +#define GPIO_B19 (GPIO_PORT_BASE + 0x0013) +#define GPIO_B20 (GPIO_PORT_BASE + 0x0014) +#define GPIO_B21 (GPIO_PORT_BASE + 0x0015) +#define GPIO_B22 (GPIO_PORT_BASE + 0x0016) +#define GPIO_B23 (GPIO_PORT_BASE + 0x0017) +#define GPIO_B24 (GPIO_PORT_BASE + 0x0018) +#define GPIO_B25 (GPIO_PORT_BASE + 0x0019) +#define GPIO_B26 (GPIO_PORT_BASE + 0x001A) +#define GPIO_B27 (GPIO_PORT_BASE + 0x001B) +#define GPIO_B28 (GPIO_PORT_BASE + 0x001C) +#define GPIO_B29 (GPIO_PORT_BASE + 0x001D) +#define GPIO_B30 (GPIO_PORT_BASE + 0x001E) +#define GPIO_B31 (GPIO_PORT_BASE + 0x001F) + +/* Byte pin registers port 1 (R/W) */ +#define GPIO_B32 (GPIO_PORT_BASE + 0x0020) +#define GPIO_B33 (GPIO_PORT_BASE + 0x0021) +#define GPIO_B34 (GPIO_PORT_BASE + 0x0022) +#define GPIO_B35 (GPIO_PORT_BASE + 0x0023) +#define GPIO_B36 (GPIO_PORT_BASE + 0x0024) +#define GPIO_B37 (GPIO_PORT_BASE + 0x0025) +#define GPIO_B38 (GPIO_PORT_BASE + 0x0026) +#define GPIO_B39 (GPIO_PORT_BASE + 0x0027) +#define GPIO_B40 (GPIO_PORT_BASE + 0x0028) +#define GPIO_B41 (GPIO_PORT_BASE + 0x0029) +#define GPIO_B42 (GPIO_PORT_BASE + 0x002A) +#define GPIO_B43 (GPIO_PORT_BASE + 0x002B) +#define GPIO_B44 (GPIO_PORT_BASE + 0x002C) +#define GPIO_B45 (GPIO_PORT_BASE + 0x002D) +#define GPIO_B46 (GPIO_PORT_BASE + 0x002E) +#define GPIO_B47 (GPIO_PORT_BASE + 0x002F) +#define GPIO_B48 (GPIO_PORT_BASE + 0x0030) +#define GPIO_B49 (GPIO_PORT_BASE + 0x0031) +#define GPIO_B50 (GPIO_PORT_BASE + 0x0032) +#define GPIO_B51 (GPIO_PORT_BASE + 0x0033) +#define GPIO_B52 (GPIO_PORT_BASE + 0x0034) +#define GPIO_B53 (GPIO_PORT_BASE + 0x0035) +#define GPIO_B54 (GPIO_PORT_BASE + 0x0036) +#define GPIO_B55 (GPIO_PORT_BASE + 0x0037) +#define GPIO_B56 (GPIO_PORT_BASE + 0x0038) +#define GPIO_B57 (GPIO_PORT_BASE + 0x0039) +#define GPIO_B58 (GPIO_PORT_BASE + 0x003A) +#define GPIO_B59 (GPIO_PORT_BASE + 0x003B) +#define GPIO_B60 (GPIO_PORT_BASE + 0x003C) +#define GPIO_B61 (GPIO_PORT_BASE + 0x003D) +#define GPIO_B62 (GPIO_PORT_BASE + 0x003E) +#define GPIO_B63 (GPIO_PORT_BASE + 0x003F) + +/* Byte pin registers port 2 (R/W) */ +#define GPIO_B64 (GPIO_PORT_BASE + 0x0040) +#define GPIO_B65 (GPIO_PORT_BASE + 0x0041) +#define GPIO_B66 (GPIO_PORT_BASE + 0x0042) +#define GPIO_B67 (GPIO_PORT_BASE + 0x0043) +#define GPIO_B68 (GPIO_PORT_BASE + 0x0044) +#define GPIO_B69 (GPIO_PORT_BASE + 0x0045) +#define GPIO_B70 (GPIO_PORT_BASE + 0x0046) +#define GPIO_B71 (GPIO_PORT_BASE + 0x0047) +#define GPIO_B72 (GPIO_PORT_BASE + 0x0048) +#define GPIO_B73 (GPIO_PORT_BASE + 0x0049) +#define GPIO_B74 (GPIO_PORT_BASE + 0x004A) +#define GPIO_B75 (GPIO_PORT_BASE + 0x004B) +#define GPIO_B76 (GPIO_PORT_BASE + 0x004C) +#define GPIO_B77 (GPIO_PORT_BASE + 0x004D) +#define GPIO_B78 (GPIO_PORT_BASE + 0x004E) +#define GPIO_B79 (GPIO_PORT_BASE + 0x004F) +#define GPIO_B80 (GPIO_PORT_BASE + 0x0050) +#define GPIO_B81 (GPIO_PORT_BASE + 0x0051) +#define GPIO_B82 (GPIO_PORT_BASE + 0x0052) +#define GPIO_B83 (GPIO_PORT_BASE + 0x0053) +#define GPIO_B84 (GPIO_PORT_BASE + 0x0054) +#define GPIO_B85 (GPIO_PORT_BASE + 0x0055) +#define GPIO_B86 (GPIO_PORT_BASE + 0x0056) +#define GPIO_B87 (GPIO_PORT_BASE + 0x0057) +#define GPIO_B88 (GPIO_PORT_BASE + 0x0058) +#define GPIO_B89 (GPIO_PORT_BASE + 0x0059) +#define GPIO_B90 (GPIO_PORT_BASE + 0x005A) +#define GPIO_B91 (GPIO_PORT_BASE + 0x005B) +#define GPIO_B92 (GPIO_PORT_BASE + 0x005C) +#define GPIO_B93 (GPIO_PORT_BASE + 0x005D) +#define GPIO_B94 (GPIO_PORT_BASE + 0x005E) +#define GPIO_B95 (GPIO_PORT_BASE + 0x005F) + +/* Byte pin registers port 3 (R/W) */ +#define GPIO_B96 (GPIO_PORT_BASE + 0x0060) +#define GPIO_B97 (GPIO_PORT_BASE + 0x0061) +#define GPIO_B98 (GPIO_PORT_BASE + 0x0062) +#define GPIO_B99 (GPIO_PORT_BASE + 0x0063) +#define GPIO_B100 (GPIO_PORT_BASE + 0x0064) +#define GPIO_B101 (GPIO_PORT_BASE + 0x0065) +#define GPIO_B102 (GPIO_PORT_BASE + 0x0066) +#define GPIO_B103 (GPIO_PORT_BASE + 0x0067) +#define GPIO_B104 (GPIO_PORT_BASE + 0x0068) +#define GPIO_B105 (GPIO_PORT_BASE + 0x0069) +#define GPIO_B106 (GPIO_PORT_BASE + 0x006A) +#define GPIO_B107 (GPIO_PORT_BASE + 0x006B) +#define GPIO_B108 (GPIO_PORT_BASE + 0x006C) +#define GPIO_B109 (GPIO_PORT_BASE + 0x006D) +#define GPIO_B110 (GPIO_PORT_BASE + 0x006E) +#define GPIO_B111 (GPIO_PORT_BASE + 0x006F) +#define GPIO_B112 (GPIO_PORT_BASE + 0x0070) +#define GPIO_B113 (GPIO_PORT_BASE + 0x0071) +#define GPIO_B114 (GPIO_PORT_BASE + 0x0072) +#define GPIO_B115 (GPIO_PORT_BASE + 0x0073) +#define GPIO_B116 (GPIO_PORT_BASE + 0x0074) +#define GPIO_B117 (GPIO_PORT_BASE + 0x0075) +#define GPIO_B118 (GPIO_PORT_BASE + 0x0076) +#define GPIO_B119 (GPIO_PORT_BASE + 0x0077) +#define GPIO_B120 (GPIO_PORT_BASE + 0x0078) +#define GPIO_B121 (GPIO_PORT_BASE + 0x0079) +#define GPIO_B122 (GPIO_PORT_BASE + 0x007A) +#define GPIO_B123 (GPIO_PORT_BASE + 0x007B) +#define GPIO_B124 (GPIO_PORT_BASE + 0x007C) +#define GPIO_B125 (GPIO_PORT_BASE + 0x007D) +#define GPIO_B126 (GPIO_PORT_BASE + 0x007E) +#define GPIO_B127 (GPIO_PORT_BASE + 0x007F) + +/* Byte pin registers port 4 (R/W) */ +#define GPIO_B128 (GPIO_PORT_BASE + 0x0080) +#define GPIO_B129 (GPIO_PORT_BASE + 0x0081) +#define GPIO_B130 (GPIO_PORT_BASE + 0x0082) +#define GPIO_B131 (GPIO_PORT_BASE + 0x0083) +#define GPIO_B132 (GPIO_PORT_BASE + 0x0084) +#define GPIO_B133 (GPIO_PORT_BASE + 0x0085) +#define GPIO_B134 (GPIO_PORT_BASE + 0x0086) +#define GPIO_B135 (GPIO_PORT_BASE + 0x0087) +#define GPIO_B136 (GPIO_PORT_BASE + 0x0088) +#define GPIO_B137 (GPIO_PORT_BASE + 0x0089) +#define GPIO_B138 (GPIO_PORT_BASE + 0x008A) +#define GPIO_B139 (GPIO_PORT_BASE + 0x008B) +#define GPIO_B140 (GPIO_PORT_BASE + 0x008C) +#define GPIO_B141 (GPIO_PORT_BASE + 0x008D) +#define GPIO_B142 (GPIO_PORT_BASE + 0x008E) +#define GPIO_B143 (GPIO_PORT_BASE + 0x008F) +#define GPIO_B144 (GPIO_PORT_BASE + 0x0090) +#define GPIO_B145 (GPIO_PORT_BASE + 0x0091) +#define GPIO_B146 (GPIO_PORT_BASE + 0x0092) +#define GPIO_B147 (GPIO_PORT_BASE + 0x0093) +#define GPIO_B148 (GPIO_PORT_BASE + 0x0094) +#define GPIO_B149 (GPIO_PORT_BASE + 0x0095) +#define GPIO_B150 (GPIO_PORT_BASE + 0x0096) +#define GPIO_B151 (GPIO_PORT_BASE + 0x0097) +#define GPIO_B152 (GPIO_PORT_BASE + 0x0098) +#define GPIO_B153 (GPIO_PORT_BASE + 0x0099) +#define GPIO_B154 (GPIO_PORT_BASE + 0x009A) +#define GPIO_B155 (GPIO_PORT_BASE + 0x009B) +#define GPIO_B156 (GPIO_PORT_BASE + 0x009C) +#define GPIO_B157 (GPIO_PORT_BASE + 0x009D) +#define GPIO_B158 (GPIO_PORT_BASE + 0x009E) +#define GPIO_B159 (GPIO_PORT_BASE + 0x009F) + +/* Byte pin registers port 5 (R/W) */ +#define GPIO_B160 (GPIO_PORT_BASE + 0x00A0) +#define GPIO_B161 (GPIO_PORT_BASE + 0x00A1) +#define GPIO_B162 (GPIO_PORT_BASE + 0x00A2) +#define GPIO_B163 (GPIO_PORT_BASE + 0x00A3) +#define GPIO_B164 (GPIO_PORT_BASE + 0x00A4) +#define GPIO_B165 (GPIO_PORT_BASE + 0x00A5) +#define GPIO_B166 (GPIO_PORT_BASE + 0x00A6) +#define GPIO_B167 (GPIO_PORT_BASE + 0x00A7) +#define GPIO_B168 (GPIO_PORT_BASE + 0x00A8) +#define GPIO_B169 (GPIO_PORT_BASE + 0x00A9) +#define GPIO_B170 (GPIO_PORT_BASE + 0x00AA) +#define GPIO_B171 (GPIO_PORT_BASE + 0x00AB) +#define GPIO_B172 (GPIO_PORT_BASE + 0x00AC) +#define GPIO_B173 (GPIO_PORT_BASE + 0x00AD) +#define GPIO_B174 (GPIO_PORT_BASE + 0x00AE) +#define GPIO_B175 (GPIO_PORT_BASE + 0x00AF) +#define GPIO_B176 (GPIO_PORT_BASE + 0x00B0) +#define GPIO_B177 (GPIO_PORT_BASE + 0x00B1) +#define GPIO_B178 (GPIO_PORT_BASE + 0x00B2) +#define GPIO_B179 (GPIO_PORT_BASE + 0x00B3) +#define GPIO_B180 (GPIO_PORT_BASE + 0x00B4) +#define GPIO_B181 (GPIO_PORT_BASE + 0x00B5) +#define GPIO_B182 (GPIO_PORT_BASE + 0x00B6) +#define GPIO_B183 (GPIO_PORT_BASE + 0x00B7) +#define GPIO_B184 (GPIO_PORT_BASE + 0x00B8) +#define GPIO_B185 (GPIO_PORT_BASE + 0x00B9) +#define GPIO_B186 (GPIO_PORT_BASE + 0x00BA) +#define GPIO_B187 (GPIO_PORT_BASE + 0x00BB) +#define GPIO_B188 (GPIO_PORT_BASE + 0x00BC) +#define GPIO_B189 (GPIO_PORT_BASE + 0x00BD) +#define GPIO_B190 (GPIO_PORT_BASE + 0x00BE) +#define GPIO_B191 (GPIO_PORT_BASE + 0x00BF) + +/* Byte pin registers port 6 (R/W) */ +#define GPIO_B192 (GPIO_PORT_BASE + 0x00C0) +#define GPIO_B193 (GPIO_PORT_BASE + 0x00C1) +#define GPIO_B194 (GPIO_PORT_BASE + 0x00C2) +#define GPIO_B195 (GPIO_PORT_BASE + 0x00C3) +#define GPIO_B196 (GPIO_PORT_BASE + 0x00C4) +#define GPIO_B197 (GPIO_PORT_BASE + 0x00C5) +#define GPIO_B198 (GPIO_PORT_BASE + 0x00C6) +#define GPIO_B199 (GPIO_PORT_BASE + 0x00C7) +#define GPIO_B200 (GPIO_PORT_BASE + 0x00C8) +#define GPIO_B201 (GPIO_PORT_BASE + 0x00C9) +#define GPIO_B202 (GPIO_PORT_BASE + 0x00CA) +#define GPIO_B203 (GPIO_PORT_BASE + 0x00CB) +#define GPIO_B204 (GPIO_PORT_BASE + 0x00CC) +#define GPIO_B205 (GPIO_PORT_BASE + 0x00CD) +#define GPIO_B206 (GPIO_PORT_BASE + 0x00CE) +#define GPIO_B207 (GPIO_PORT_BASE + 0x00CF) +#define GPIO_B208 (GPIO_PORT_BASE + 0x00D0) +#define GPIO_B209 (GPIO_PORT_BASE + 0x00D1) +#define GPIO_B210 (GPIO_PORT_BASE + 0x00D2) +#define GPIO_B211 (GPIO_PORT_BASE + 0x00D3) +#define GPIO_B212 (GPIO_PORT_BASE + 0x00D4) +#define GPIO_B213 (GPIO_PORT_BASE + 0x00D5) +#define GPIO_B214 (GPIO_PORT_BASE + 0x00D6) +#define GPIO_B215 (GPIO_PORT_BASE + 0x00D7) +#define GPIO_B216 (GPIO_PORT_BASE + 0x00D8) +#define GPIO_B217 (GPIO_PORT_BASE + 0x00D9) +#define GPIO_B218 (GPIO_PORT_BASE + 0x00DA) +#define GPIO_B219 (GPIO_PORT_BASE + 0x00DB) +#define GPIO_B220 (GPIO_PORT_BASE + 0x00DC) +#define GPIO_B221 (GPIO_PORT_BASE + 0x00DD) +#define GPIO_B222 (GPIO_PORT_BASE + 0x00DE) +#define GPIO_B223 (GPIO_PORT_BASE + 0x00DF) + +/* Byte pin registers port 7 (R/W) */ +#define GPIO_B224 (GPIO_PORT_BASE + 0x00E0) +#define GPIO_B225 (GPIO_PORT_BASE + 0x00E1) +#define GPIO_B226 (GPIO_PORT_BASE + 0x00E2) +#define GPIO_B227 (GPIO_PORT_BASE + 0x00E3) +#define GPIO_B228 (GPIO_PORT_BASE + 0x00E4) +#define GPIO_B229 (GPIO_PORT_BASE + 0x00E5) +#define GPIO_B230 (GPIO_PORT_BASE + 0x00E6) +#define GPIO_B231 (GPIO_PORT_BASE + 0x00E7) +#define GPIO_B232 (GPIO_PORT_BASE + 0x00E8) +#define GPIO_B233 (GPIO_PORT_BASE + 0x00E9) +#define GPIO_B234 (GPIO_PORT_BASE + 0x00EA) +#define GPIO_B235 (GPIO_PORT_BASE + 0x00EB) +#define GPIO_B236 (GPIO_PORT_BASE + 0x00EC) +#define GPIO_B237 (GPIO_PORT_BASE + 0x00ED) +#define GPIO_B238 (GPIO_PORT_BASE + 0x00EE) +#define GPIO_B239 (GPIO_PORT_BASE + 0x00EF) +#define GPIO_B240 (GPIO_PORT_BASE + 0x00F0) +#define GPIO_B241 (GPIO_PORT_BASE + 0x00F1) +#define GPIO_B242 (GPIO_PORT_BASE + 0x00F2) +#define GPIO_B243 (GPIO_PORT_BASE + 0x00F3) +#define GPIO_B244 (GPIO_PORT_BASE + 0x00F4) +#define GPIO_B245 (GPIO_PORT_BASE + 0x00F5) +#define GPIO_B246 (GPIO_PORT_BASE + 0x00F6) +#define GPIO_B247 (GPIO_PORT_BASE + 0x00F7) +#define GPIO_B248 (GPIO_PORT_BASE + 0x00F8) +#define GPIO_B249 (GPIO_PORT_BASE + 0x00F9) +#define GPIO_B250 (GPIO_PORT_BASE + 0x00FA) +#define GPIO_B251 (GPIO_PORT_BASE + 0x00FB) +#define GPIO_B252 (GPIO_PORT_BASE + 0x00FC) +#define GPIO_B253 (GPIO_PORT_BASE + 0x00FD) +#define GPIO_B254 (GPIO_PORT_BASE + 0x00FE) +#define GPIO_B255 (GPIO_PORT_BASE + 0x00FF) + +/* Word pin registers port 0 (R/W) */ +#define GPIO_W0 (GPIO_PORT_BASE + 0x1000) +#define GPIO_W1 (GPIO_PORT_BASE + 0x1004) +#define GPIO_W2 (GPIO_PORT_BASE + 0x1008) +#define GPIO_W3 (GPIO_PORT_BASE + 0x100C) +#define GPIO_W4 (GPIO_PORT_BASE + 0x1010) +#define GPIO_W5 (GPIO_PORT_BASE + 0x1014) +#define GPIO_W6 (GPIO_PORT_BASE + 0x1018) +#define GPIO_W7 (GPIO_PORT_BASE + 0x101C) +#define GPIO_W8 (GPIO_PORT_BASE + 0x1020) +#define GPIO_W9 (GPIO_PORT_BASE + 0x1024) +#define GPIO_W10 (GPIO_PORT_BASE + 0x1028) +#define GPIO_W11 (GPIO_PORT_BASE + 0x102C) +#define GPIO_W12 (GPIO_PORT_BASE + 0x1030) +#define GPIO_W13 (GPIO_PORT_BASE + 0x1034) +#define GPIO_W14 (GPIO_PORT_BASE + 0x1038) +#define GPIO_W15 (GPIO_PORT_BASE + 0x103C) +#define GPIO_W16 (GPIO_PORT_BASE + 0x1040) +#define GPIO_W17 (GPIO_PORT_BASE + 0x1044) +#define GPIO_W18 (GPIO_PORT_BASE + 0x1048) +#define GPIO_W19 (GPIO_PORT_BASE + 0x104C) +#define GPIO_W20 (GPIO_PORT_BASE + 0x1050) +#define GPIO_W21 (GPIO_PORT_BASE + 0x1054) +#define GPIO_W22 (GPIO_PORT_BASE + 0x1058) +#define GPIO_W23 (GPIO_PORT_BASE + 0x105C) +#define GPIO_W24 (GPIO_PORT_BASE + 0x1060) +#define GPIO_W25 (GPIO_PORT_BASE + 0x1064) +#define GPIO_W26 (GPIO_PORT_BASE + 0x1068) +#define GPIO_W27 (GPIO_PORT_BASE + 0x106C) +#define GPIO_W28 (GPIO_PORT_BASE + 0x1070) +#define GPIO_W29 (GPIO_PORT_BASE + 0x1074) +#define GPIO_W30 (GPIO_PORT_BASE + 0x1078) +#define GPIO_W31 (GPIO_PORT_BASE + 0x107C) + +/* Word pin registers port 1 (R/W) */ +#define GPIO_W32 (GPIO_PORT_BASE + 0x1080) +#define GPIO_W33 (GPIO_PORT_BASE + 0x1084) +#define GPIO_W34 (GPIO_PORT_BASE + 0x1088) +#define GPIO_W35 (GPIO_PORT_BASE + 0x108C) +#define GPIO_W36 (GPIO_PORT_BASE + 0x1090) +#define GPIO_W37 (GPIO_PORT_BASE + 0x1094) +#define GPIO_W38 (GPIO_PORT_BASE + 0x1098) +#define GPIO_W39 (GPIO_PORT_BASE + 0x109C) +#define GPIO_W40 (GPIO_PORT_BASE + 0x10A0) +#define GPIO_W41 (GPIO_PORT_BASE + 0x10A4) +#define GPIO_W42 (GPIO_PORT_BASE + 0x10A8) +#define GPIO_W43 (GPIO_PORT_BASE + 0x10AC) +#define GPIO_W44 (GPIO_PORT_BASE + 0x10B0) +#define GPIO_W45 (GPIO_PORT_BASE + 0x10B4) +#define GPIO_W46 (GPIO_PORT_BASE + 0x10B8) +#define GPIO_W47 (GPIO_PORT_BASE + 0x10BC) +#define GPIO_W48 (GPIO_PORT_BASE + 0x10C0) +#define GPIO_W49 (GPIO_PORT_BASE + 0x10C4) +#define GPIO_W50 (GPIO_PORT_BASE + 0x10C8) +#define GPIO_W51 (GPIO_PORT_BASE + 0x10CC) +#define GPIO_W52 (GPIO_PORT_BASE + 0x10D0) +#define GPIO_W53 (GPIO_PORT_BASE + 0x10D4) +#define GPIO_W54 (GPIO_PORT_BASE + 0x10D8) +#define GPIO_W55 (GPIO_PORT_BASE + 0x10DC) +#define GPIO_W56 (GPIO_PORT_BASE + 0x10E0) +#define GPIO_W57 (GPIO_PORT_BASE + 0x10E4) +#define GPIO_W58 (GPIO_PORT_BASE + 0x10E8) +#define GPIO_W59 (GPIO_PORT_BASE + 0x10EC) +#define GPIO_W60 (GPIO_PORT_BASE + 0x10F0) +#define GPIO_W61 (GPIO_PORT_BASE + 0x10F4) +#define GPIO_W62 (GPIO_PORT_BASE + 0x10F8) +#define GPIO_W63 (GPIO_PORT_BASE + 0x10FC) + +/* Word pin registers port 2 (R/W) */ +#define GPIO_W64 (GPIO_PORT_BASE + 0x1100) +#define GPIO_W65 (GPIO_PORT_BASE + 0x1104) +#define GPIO_W66 (GPIO_PORT_BASE + 0x1108) +#define GPIO_W67 (GPIO_PORT_BASE + 0x110C) +#define GPIO_W68 (GPIO_PORT_BASE + 0x1110) +#define GPIO_W69 (GPIO_PORT_BASE + 0x1114) +#define GPIO_W70 (GPIO_PORT_BASE + 0x1118) +#define GPIO_W71 (GPIO_PORT_BASE + 0x111C) +#define GPIO_W72 (GPIO_PORT_BASE + 0x1120) +#define GPIO_W73 (GPIO_PORT_BASE + 0x1124) +#define GPIO_W74 (GPIO_PORT_BASE + 0x1128) +#define GPIO_W75 (GPIO_PORT_BASE + 0x112C) +#define GPIO_W76 (GPIO_PORT_BASE + 0x1130) +#define GPIO_W77 (GPIO_PORT_BASE + 0x1134) +#define GPIO_W78 (GPIO_PORT_BASE + 0x1138) +#define GPIO_W79 (GPIO_PORT_BASE + 0x113C) +#define GPIO_W80 (GPIO_PORT_BASE + 0x1140) +#define GPIO_W81 (GPIO_PORT_BASE + 0x1144) +#define GPIO_W82 (GPIO_PORT_BASE + 0x1148) +#define GPIO_W83 (GPIO_PORT_BASE + 0x114C) +#define GPIO_W84 (GPIO_PORT_BASE + 0x1150) +#define GPIO_W85 (GPIO_PORT_BASE + 0x1154) +#define GPIO_W86 (GPIO_PORT_BASE + 0x1158) +#define GPIO_W87 (GPIO_PORT_BASE + 0x115C) +#define GPIO_W88 (GPIO_PORT_BASE + 0x1160) +#define GPIO_W89 (GPIO_PORT_BASE + 0x1164) +#define GPIO_W90 (GPIO_PORT_BASE + 0x1168) +#define GPIO_W91 (GPIO_PORT_BASE + 0x116C) +#define GPIO_W92 (GPIO_PORT_BASE + 0x1170) +#define GPIO_W93 (GPIO_PORT_BASE + 0x1174) +#define GPIO_W94 (GPIO_PORT_BASE + 0x1178) +#define GPIO_W95 (GPIO_PORT_BASE + 0x117C) + +/* Word pin registers port 3 (R/W) */ +#define GPIO_W96 (GPIO_PORT_BASE + 0x1180) +#define GPIO_W97 (GPIO_PORT_BASE + 0x1184) +#define GPIO_W98 (GPIO_PORT_BASE + 0x1188) +#define GPIO_W99 (GPIO_PORT_BASE + 0x118C) +#define GPIO_W100 (GPIO_PORT_BASE + 0x1190) +#define GPIO_W101 (GPIO_PORT_BASE + 0x1194) +#define GPIO_W102 (GPIO_PORT_BASE + 0x1198) +#define GPIO_W103 (GPIO_PORT_BASE + 0x119C) +#define GPIO_W104 (GPIO_PORT_BASE + 0x11A0) +#define GPIO_W105 (GPIO_PORT_BASE + 0x11A4) +#define GPIO_W106 (GPIO_PORT_BASE + 0x11A8) +#define GPIO_W107 (GPIO_PORT_BASE + 0x11AC) +#define GPIO_W108 (GPIO_PORT_BASE + 0x11B0) +#define GPIO_W109 (GPIO_PORT_BASE + 0x11B4) +#define GPIO_W110 (GPIO_PORT_BASE + 0x11B8) +#define GPIO_W111 (GPIO_PORT_BASE + 0x11BC) +#define GPIO_W112 (GPIO_PORT_BASE + 0x11C0) +#define GPIO_W113 (GPIO_PORT_BASE + 0x11C4) +#define GPIO_W114 (GPIO_PORT_BASE + 0x11C8) +#define GPIO_W115 (GPIO_PORT_BASE + 0x11CC) +#define GPIO_W116 (GPIO_PORT_BASE + 0x11D0) +#define GPIO_W117 (GPIO_PORT_BASE + 0x11D4) +#define GPIO_W118 (GPIO_PORT_BASE + 0x11D8) +#define GPIO_W119 (GPIO_PORT_BASE + 0x11DC) +#define GPIO_W120 (GPIO_PORT_BASE + 0x11E0) +#define GPIO_W121 (GPIO_PORT_BASE + 0x11E4) +#define GPIO_W122 (GPIO_PORT_BASE + 0x11E8) +#define GPIO_W123 (GPIO_PORT_BASE + 0x11EC) +#define GPIO_W124 (GPIO_PORT_BASE + 0x11F0) +#define GPIO_W125 (GPIO_PORT_BASE + 0x11F4) +#define GPIO_W126 (GPIO_PORT_BASE + 0x11F8) +#define GPIO_W127 (GPIO_PORT_BASE + 0x11FC) + +/* Word pin registers port 4 (R/W) */ +#define GPIO_W128 (GPIO_PORT_BASE + 0x1200) +#define GPIO_W129 (GPIO_PORT_BASE + 0x1204) +#define GPIO_W130 (GPIO_PORT_BASE + 0x1208) +#define GPIO_W131 (GPIO_PORT_BASE + 0x120C) +#define GPIO_W132 (GPIO_PORT_BASE + 0x1210) +#define GPIO_W133 (GPIO_PORT_BASE + 0x1214) +#define GPIO_W134 (GPIO_PORT_BASE + 0x1218) +#define GPIO_W135 (GPIO_PORT_BASE + 0x121C) +#define GPIO_W136 (GPIO_PORT_BASE + 0x1220) +#define GPIO_W137 (GPIO_PORT_BASE + 0x1224) +#define GPIO_W138 (GPIO_PORT_BASE + 0x1228) +#define GPIO_W139 (GPIO_PORT_BASE + 0x122C) +#define GPIO_W140 (GPIO_PORT_BASE + 0x1230) +#define GPIO_W141 (GPIO_PORT_BASE + 0x1234) +#define GPIO_W142 (GPIO_PORT_BASE + 0x1238) +#define GPIO_W143 (GPIO_PORT_BASE + 0x123C) +#define GPIO_W144 (GPIO_PORT_BASE + 0x1240) +#define GPIO_W145 (GPIO_PORT_BASE + 0x1244) +#define GPIO_W146 (GPIO_PORT_BASE + 0x1248) +#define GPIO_W147 (GPIO_PORT_BASE + 0x124C) +#define GPIO_W148 (GPIO_PORT_BASE + 0x1250) +#define GPIO_W149 (GPIO_PORT_BASE + 0x1254) +#define GPIO_W150 (GPIO_PORT_BASE + 0x1258) +#define GPIO_W151 (GPIO_PORT_BASE + 0x125C) +#define GPIO_W152 (GPIO_PORT_BASE + 0x1260) +#define GPIO_W153 (GPIO_PORT_BASE + 0x1264) +#define GPIO_W154 (GPIO_PORT_BASE + 0x1268) +#define GPIO_W155 (GPIO_PORT_BASE + 0x126C) +#define GPIO_W156 (GPIO_PORT_BASE + 0x1270) +#define GPIO_W157 (GPIO_PORT_BASE + 0x1274) +#define GPIO_W158 (GPIO_PORT_BASE + 0x1278) +#define GPIO_W159 (GPIO_PORT_BASE + 0x127C) + +/* Word pin registers port 5 (R/W) */ +#define GPIO_W160 (GPIO_PORT_BASE + 0x1280) +#define GPIO_W161 (GPIO_PORT_BASE + 0x1284) +#define GPIO_W162 (GPIO_PORT_BASE + 0x1288) +#define GPIO_W163 (GPIO_PORT_BASE + 0x128C) +#define GPIO_W164 (GPIO_PORT_BASE + 0x1290) +#define GPIO_W165 (GPIO_PORT_BASE + 0x1294) +#define GPIO_W166 (GPIO_PORT_BASE + 0x1298) +#define GPIO_W167 (GPIO_PORT_BASE + 0x129C) +#define GPIO_W168 (GPIO_PORT_BASE + 0x12A0) +#define GPIO_W169 (GPIO_PORT_BASE + 0x12A4) +#define GPIO_W170 (GPIO_PORT_BASE + 0x12A8) +#define GPIO_W171 (GPIO_PORT_BASE + 0x12AC) +#define GPIO_W172 (GPIO_PORT_BASE + 0x12B0) +#define GPIO_W173 (GPIO_PORT_BASE + 0x12B4) +#define GPIO_W174 (GPIO_PORT_BASE + 0x12B8) +#define GPIO_W175 (GPIO_PORT_BASE + 0x12BC) +#define GPIO_W176 (GPIO_PORT_BASE + 0x12C0) +#define GPIO_W177 (GPIO_PORT_BASE + 0x12C4) +#define GPIO_W178 (GPIO_PORT_BASE + 0x12C8) +#define GPIO_W179 (GPIO_PORT_BASE + 0x12CC) +#define GPIO_W180 (GPIO_PORT_BASE + 0x12D0) +#define GPIO_W181 (GPIO_PORT_BASE + 0x12D4) +#define GPIO_W182 (GPIO_PORT_BASE + 0x12D8) +#define GPIO_W183 (GPIO_PORT_BASE + 0x12DC) +#define GPIO_W184 (GPIO_PORT_BASE + 0x12E0) +#define GPIO_W185 (GPIO_PORT_BASE + 0x12E4) +#define GPIO_W186 (GPIO_PORT_BASE + 0x12E8) +#define GPIO_W187 (GPIO_PORT_BASE + 0x12EC) +#define GPIO_W188 (GPIO_PORT_BASE + 0x12F0) +#define GPIO_W189 (GPIO_PORT_BASE + 0x12F4) +#define GPIO_W190 (GPIO_PORT_BASE + 0x12F8) +#define GPIO_W191 (GPIO_PORT_BASE + 0x12FC) + +/* Word pin registers port 6 (R/W) */ +#define GPIO_W192 (GPIO_PORT_BASE + 0x1300) +#define GPIO_W193 (GPIO_PORT_BASE + 0x1304) +#define GPIO_W194 (GPIO_PORT_BASE + 0x1308) +#define GPIO_W195 (GPIO_PORT_BASE + 0x130C) +#define GPIO_W196 (GPIO_PORT_BASE + 0x1310) +#define GPIO_W197 (GPIO_PORT_BASE + 0x1314) +#define GPIO_W198 (GPIO_PORT_BASE + 0x1318) +#define GPIO_W199 (GPIO_PORT_BASE + 0x131C) +#define GPIO_W200 (GPIO_PORT_BASE + 0x1320) +#define GPIO_W201 (GPIO_PORT_BASE + 0x1324) +#define GPIO_W202 (GPIO_PORT_BASE + 0x1328) +#define GPIO_W203 (GPIO_PORT_BASE + 0x132C) +#define GPIO_W204 (GPIO_PORT_BASE + 0x1330) +#define GPIO_W205 (GPIO_PORT_BASE + 0x1334) +#define GPIO_W206 (GPIO_PORT_BASE + 0x1338) +#define GPIO_W207 (GPIO_PORT_BASE + 0x133C) +#define GPIO_W208 (GPIO_PORT_BASE + 0x1340) +#define GPIO_W209 (GPIO_PORT_BASE + 0x1344) +#define GPIO_W210 (GPIO_PORT_BASE + 0x1348) +#define GPIO_W211 (GPIO_PORT_BASE + 0x134C) +#define GPIO_W212 (GPIO_PORT_BASE + 0x1350) +#define GPIO_W213 (GPIO_PORT_BASE + 0x1354) +#define GPIO_W214 (GPIO_PORT_BASE + 0x1358) +#define GPIO_W215 (GPIO_PORT_BASE + 0x135C) +#define GPIO_W216 (GPIO_PORT_BASE + 0x1360) +#define GPIO_W217 (GPIO_PORT_BASE + 0x1364) +#define GPIO_W218 (GPIO_PORT_BASE + 0x1368) +#define GPIO_W219 (GPIO_PORT_BASE + 0x136C) +#define GPIO_W220 (GPIO_PORT_BASE + 0x1370) +#define GPIO_W221 (GPIO_PORT_BASE + 0x1374) +#define GPIO_W222 (GPIO_PORT_BASE + 0x1378) +#define GPIO_W223 (GPIO_PORT_BASE + 0x137C) + +/* Word pin registers port 7 (R/W) */ +#define GPIO_W224 (GPIO_PORT_BASE + 0x1380) +#define GPIO_W225 (GPIO_PORT_BASE + 0x1384) +#define GPIO_W226 (GPIO_PORT_BASE + 0x1388) +#define GPIO_W227 (GPIO_PORT_BASE + 0x138C) +#define GPIO_W228 (GPIO_PORT_BASE + 0x1390) +#define GPIO_W229 (GPIO_PORT_BASE + 0x1394) +#define GPIO_W230 (GPIO_PORT_BASE + 0x1398) +#define GPIO_W231 (GPIO_PORT_BASE + 0x139C) +#define GPIO_W232 (GPIO_PORT_BASE + 0x13A0) +#define GPIO_W233 (GPIO_PORT_BASE + 0x13A4) +#define GPIO_W234 (GPIO_PORT_BASE + 0x13A8) +#define GPIO_W235 (GPIO_PORT_BASE + 0x13AC) +#define GPIO_W236 (GPIO_PORT_BASE + 0x13B0) +#define GPIO_W237 (GPIO_PORT_BASE + 0x13B4) +#define GPIO_W238 (GPIO_PORT_BASE + 0x13B8) +#define GPIO_W239 (GPIO_PORT_BASE + 0x13BC) +#define GPIO_W240 (GPIO_PORT_BASE + 0x13C0) +#define GPIO_W241 (GPIO_PORT_BASE + 0x13C4) +#define GPIO_W242 (GPIO_PORT_BASE + 0x13C8) +#define GPIO_W243 (GPIO_PORT_BASE + 0x13CC) +#define GPIO_W244 (GPIO_PORT_BASE + 0x13D0) +#define GPIO_W245 (GPIO_PORT_BASE + 0x13D4) +#define GPIO_W246 (GPIO_PORT_BASE + 0x13D8) +#define GPIO_W247 (GPIO_PORT_BASE + 0x13DC) +#define GPIO_W248 (GPIO_PORT_BASE + 0x13E0) +#define GPIO_W249 (GPIO_PORT_BASE + 0x13E4) +#define GPIO_W250 (GPIO_PORT_BASE + 0x13E8) +#define GPIO_W251 (GPIO_PORT_BASE + 0x13EC) +#define GPIO_W252 (GPIO_PORT_BASE + 0x13F0) +#define GPIO_W253 (GPIO_PORT_BASE + 0x13F4) +#define GPIO_W254 (GPIO_PORT_BASE + 0x13F8) +#define GPIO_W255 (GPIO_PORT_BASE + 0x13FC) + +/* GPIO data direction register (GPIOn_DIR) */ +#define GPIO_DIR(port) MMIO32((port) + 0x00) +#define GPIO0_DIR GPIO_DIR(GPIO0) +#define GPIO1_DIR GPIO_DIR(GPIO1) +#define GPIO2_DIR GPIO_DIR(GPIO2) +#define GPIO3_DIR GPIO_DIR(GPIO3) +#define GPIO4_DIR GPIO_DIR(GPIO4) +#define GPIO5_DIR GPIO_DIR(GPIO5) +#define GPIO6_DIR GPIO_DIR(GPIO6) +#define GPIO7_DIR GPIO_DIR(GPIO7) + +/* GPIO fast mask register (GPIOn_MASK) */ +#define GPIO_MASK(port) MMIO32((port) + 0x80) +#define GPIO0_MASK GPIO_MASK(GPIO0) +#define GPIO1_MASK GPIO_MASK(GPIO1) +#define GPIO2_MASK GPIO_MASK(GPIO2) +#define GPIO3_MASK GPIO_MASK(GPIO3) +#define GPIO4_MASK GPIO_MASK(GPIO4) +#define GPIO5_MASK GPIO_MASK(GPIO5) +#define GPIO6_MASK GPIO_MASK(GPIO6) +#define GPIO7_MASK GPIO_MASK(GPIO7) + +/* GPIO port pin value register (GPIOn_PIN) */ +#define GPIO_PIN(port) MMIO32((port) + 0x100) +#define GPIO0_PIN GPIO_PIN(GPIO0) +#define GPIO1_PIN GPIO_PIN(GPIO1) +#define GPIO2_PIN GPIO_PIN(GPIO2) +#define GPIO3_PIN GPIO_PIN(GPIO3) +#define GPIO4_PIN GPIO_PIN(GPIO4) +#define GPIO5_PIN GPIO_PIN(GPIO5) +#define GPIO6_PIN GPIO_PIN(GPIO6) +#define GPIO7_PIN GPIO_PIN(GPIO7) + +/* GPIO port masked pin value register (GPIOn_MPIN) */ +#define GPIO_MPIN(port) MMIO32((port) + 0x180) +#define GPIO0_MPIN GPIO_MPIN(GPIO0) +#define GPIO1_MPIN GPIO_MPIN(GPIO1) +#define GPIO2_MPIN GPIO_MPIN(GPIO2) +#define GPIO3_MPIN GPIO_MPIN(GPIO3) +#define GPIO4_MPIN GPIO_MPIN(GPIO4) +#define GPIO5_MPIN GPIO_MPIN(GPIO5) +#define GPIO6_MPIN GPIO_MPIN(GPIO6) +#define GPIO7_MPIN GPIO_MPIN(GPIO7) + +/* GPIO port output set register (GPIOn_SET) */ +#define GPIO_SET(port) MMIO32((port) + 0x200) +#define GPIO0_SET GPIO_SET(GPIO0) +#define GPIO1_SET GPIO_SET(GPIO1) +#define GPIO2_SET GPIO_SET(GPIO2) +#define GPIO3_SET GPIO_SET(GPIO3) +#define GPIO4_SET GPIO_SET(GPIO4) +#define GPIO5_SET GPIO_SET(GPIO5) +#define GPIO6_SET GPIO_SET(GPIO6) +#define GPIO7_SET GPIO_SET(GPIO7) + +/* GPIO port output clear register (GPIOn_CLR) */ +#define GPIO_CLR(port) MMIO32((port) + 0x280) +#define GPIO0_CLR GPIO_CLR(GPIO0) +#define GPIO1_CLR GPIO_CLR(GPIO1) +#define GPIO2_CLR GPIO_CLR(GPIO2) +#define GPIO3_CLR GPIO_CLR(GPIO3) +#define GPIO4_CLR GPIO_CLR(GPIO4) +#define GPIO5_CLR GPIO_CLR(GPIO5) +#define GPIO6_CLR GPIO_CLR(GPIO6) +#define GPIO7_CLR GPIO_CLR(GPIO7) + +/* GPIO port toggle register (GPIOn_NOT) */ +#define GPIO_NOT(port) MMIO32((port) + 0x300) +#define GPIO0_NOT GPIO_NOT(GPIO0) +#define GPIO1_NOT GPIO_NOT(GPIO1) +#define GPIO2_NOT GPIO_NOT(GPIO2) +#define GPIO3_NOT GPIO_NOT(GPIO3) +#define GPIO4_NOT GPIO_NOT(GPIO4) +#define GPIO5_NOT GPIO_NOT(GPIO5) +#define GPIO6_NOT GPIO_NOT(GPIO6) +#define GPIO7_NOT GPIO_NOT(GPIO7) + +/* TODO interrupts */ + +BEGIN_DECLS + +void gpio_set(uint32_t gpioport, uint32_t gpios); +void gpio_clear(uint32_t gpioport, uint32_t gpios); +void gpio_toggle(uint32_t gpioport, uint32_t gpios); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2c.h new file mode 100644 index 00000000..23c88967 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2c.h @@ -0,0 +1,164 @@ +/** @defgroup i2c_defines I2C Defines + +@brief Defined Constants and Types for the LPC43xx I2C + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_I2C_H +#define LPC43XX_I2C_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* I2C port base addresses (for convenience) */ +#define I2C0 I2C0_BASE +#define I2C1 I2C1_BASE + +/* --- I2C registers ------------------------------------------------------- */ + +/* I2C Control Set Register */ +#define I2C_CONSET(port) MMIO32((port) + 0x000) +#define I2C0_CONSET I2C_CONSET(I2C0) +#define I2C1_CONSET I2C_CONSET(I2C1) + +/* I2C Status Register */ +#define I2C_STAT(port) MMIO32((port) + 0x004) +#define I2C0_STAT I2C_STAT(I2C0) +#define I2C1_STAT I2C_STAT(I2C1) + +/* I2C Data Register */ +#define I2C_DAT(port) MMIO32((port) + 0x008) +#define I2C0_DAT I2C_DAT(I2C0) +#define I2C1_DAT I2C_DAT(I2C1) + +/* I2C Slave Address Register 0 */ +#define I2C_ADR0(port) MMIO32((port) + 0x00C) +#define I2C0_ADR0 I2C_ADR0(I2C0) +#define I2C1_ADR0 I2C_ADR0(I2C1) + +/* SCH Duty Cycle Register High Half Word */ +#define I2C_SCLH(port) MMIO32((port) + 0x010) +#define I2C0_SCLH I2C_SCLH(I2C0) +#define I2C1_SCLH I2C_SCLH(I2C1) + +/* SCL Duty Cycle Register Low Half Word */ +#define I2C_SCLL(port) MMIO32((port) + 0x014) +#define I2C0_SCLL I2C_SCLL(I2C0) +#define I2C1_SCLL I2C_SCLL(I2C1) + +/* I2C Control Clear Register */ +#define I2C_CONCLR(port) MMIO32((port) + 0x018) +#define I2C0_CONCLR I2C_CONCLR(I2C0) +#define I2C1_CONCLR I2C_CONCLR(I2C1) + +/* Monitor mode control register */ +#define I2C_MMCTRL(port) MMIO32((port) + 0x01C) +#define I2C0_MMCTRL I2C_MMCTRL(I2C0) +#define I2C1_MMCTRL I2C_MMCTRL(I2C1) + +/* I2C Slave Address Register 1 */ +#define I2C_ADR1(port) MMIO32((port) + 0x020) +#define I2C0_ADR1 I2C_ADR1(I2C0) +#define I2C1_ADR1 I2C_ADR1(I2C1) + +/* I2C Slave Address Register 2 */ +#define I2C_ADR2(port) MMIO32((port) + 0x024) +#define I2C0_ADR2 I2C_ADR2(I2C0) +#define I2C1_ADR2 I2C_ADR2(I2C1) + +/* I2C Slave Address Register 3 */ +#define I2C_ADR3(port) MMIO32((port) + 0x028) +#define I2C0_ADR3 I2C_ADR3(I2C0) +#define I2C1_ADR3 I2C_ADR3(I2C1) + +/* Data buffer register */ +#define I2C_DATA_BUFFER(port) MMIO32((port) + 0x02C) +#define I2C0_DATA_BUFFER I2C_DATA_BUFFER(I2C0) +#define I2C1_DATA_BUFFER I2C_DATA_BUFFER(I2C1) + +/* I2C Slave address mask register 0 */ +#define I2C_MASK0(port) MMIO32((port) + 0x030) +#define I2C0_MASK0 I2C_MASK0(I2C0) +#define I2C1_MASK0 I2C_MASK0(I2C1) + +/* I2C Slave address mask register 1 */ +#define I2C_MASK1(port) MMIO32((port) + 0x034) +#define I2C0_MASK1 I2C_MASK1(I2C0) +#define I2C1_MASK1 I2C_MASK1(I2C1) + +/* I2C Slave address mask register 2 */ +#define I2C_MASK2(port) MMIO32((port) + 0x038) +#define I2C0_MASK2 I2C_MASK2(I2C0) +#define I2C1_MASK2 I2C_MASK2(I2C1) + +/* I2C Slave address mask register 3 */ +#define I2C_MASK3(port) MMIO32((port) + 0x03C) +#define I2C0_MASK3 I2C_MASK3(I2C0) +#define I2C1_MASK3 I2C_MASK3(I2C1) + +/* --- I2Cx_CONCLR values -------------------------------------------------- */ + +#define I2C_CONCLR_AAC (1 << 2) /* Assert acknowledge Clear */ +#define I2C_CONCLR_SIC (1 << 3) /* I2C interrupt Clear */ +#define I2C_CONCLR_STAC (1 << 5) /* START flag Clear */ +#define I2C_CONCLR_I2ENC (1 << 6) /* I2C interface Disable bit */ + +/* --- I2Cx_CONSET values -------------------------------------------------- */ + +#define I2C_CONSET_AA (1 << 2) /* Assert acknowledge flag */ +#define I2C_CONSET_SI (1 << 3) /* I2C interrupt flag */ +#define I2C_CONSET_STO (1 << 4) /* STOP flag */ +#define I2C_CONSET_STA (1 << 5) /* START flag */ +#define I2C_CONSET_I2EN (1 << 6) /* I2C interface enable */ + +/* --- I2C const definitions ----------------------------------------------- */ + +#define I2C_WRITE 0 +#define I2C_READ 1 + +/* --- I2C function prototypes --------------------------------------------- */ + +BEGIN_DECLS + +void i2c0_init(const uint16_t duty_cycle_count); +void i2c0_tx_start(void); +void i2c0_tx_byte(uint8_t byte); +uint8_t i2c0_rx_byte(void); +void i2c0_stop(void); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2s.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2s.h new file mode 100644 index 00000000..442f5bd5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/i2s.h @@ -0,0 +1,122 @@ +/** @defgroup i2s_defines I2S Defines + +@brief Defined Constants and Types for the LPC43xx I2S + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_I2S_H +#define LPC43XX_I2S_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* I2S port base addresses (for convenience) */ +#define I2S0 I2S0_BASE +#define I2S1 I2S1_BASE + +/* --- I2S registers ------------------------------------------------------- */ + +/* I2S Digital Audio Output Register */ +#define I2S_DAO(port) MMIO32((port) + 0x000) +#define I2S0_DAO I2S_DAO(I2S0) +#define I2S1_DAO I2S_DAO(I2S1) + +/* I2S Digital Audio Input Register */ +#define I2S_DAI(port) MMIO32((port) + 0x004) +#define I2S0_DAI I2S_DAI(I2S0) +#define I2S1_DAI I2S_DAI(I2S1) + +/* I2S Transmit FIFO */ +#define I2S_TXFIFO(port) MMIO32((port) + 0x008) +#define I2S0_TXFIFO I2S_TXFIFO(I2S0) +#define I2S1_TXFIFO I2S_TXFIFO(I2S1) + +/* I2S Receive FIFO */ +#define I2S_RXFIFO(port) MMIO32((port) + 0x00C) +#define I2S0_RXFIFO I2S_RXFIFO(I2S0) +#define I2S1_RXFIFO I2S_RXFIFO(I2S1) + +/* I2S Status Feedback Register */ +#define I2S_STATE(port) MMIO32((port) + 0x010) +#define I2S0_STATE I2S_STATE(I2S0) +#define I2S1_STATE I2S_STATE(I2S1) + +/* I2S DMA Configuration Register 1 */ +#define I2S_DMA1(port) MMIO32((port) + 0x014) +#define I2S0_DMA1 I2S_DMA1(I2S0) +#define I2S1_DMA1 I2S_DMA1(I2S1) + +/* I2S DMA Configuration Register 2 */ +#define I2S_DMA2(port) MMIO32((port) + 0x018) +#define I2S0_DMA2 I2S_DMA2(I2S0) +#define I2S1_DMA2 I2S_DMA2(I2S1) + +/* I2S Interrupt Request Control Register */ +#define I2S_IRQ(port) MMIO32((port) + 0x01C) +#define I2S0_IRQ I2S_IRQ(I2S0) +#define I2S1_IRQ I2S_IRQ(I2S1) + +/* I2S Transmit MCLK divider */ +#define I2S_TXRATE(port) MMIO32((port) + 0x020) +#define I2S0_TXRATE I2S_TXRATE(I2S0) +#define I2S1_TXRATE I2S_TXRATE(I2S1) + +/* I2S Receive MCLK divider */ +#define I2S_RXRATE(port) MMIO32((port) + 0x024) +#define I2S0_RXRATE I2S_RXRATE(I2S0) +#define I2S1_RXRATE I2S_RXRATE(I2S1) + +/* I2S Transmit bit rate divider */ +#define I2S_TXBITRATE(port) MMIO32((port) + 0x028) +#define I2S0_TXBITRATE I2S_TXBITRATE(I2S0) +#define I2S1_TXBITRATE I2S_TXBITRATE(I2S1) + +/* I2S Receive bit rate divider */ +#define I2S_RXBITRATE(port) MMIO32((port) + 0x02C) +#define I2S0_RXBITRATE I2S_RXBITRATE(I2S0) +#define I2S1_RXBITRATE I2S_RXBITRATE(I2S1) + +/* I2S Transmit mode control */ +#define I2S_TXMODE(port) MMIO32((port) + 0x030) +#define I2S0_TXMODE I2S_TXMODE(I2S0) +#define I2S1_TXMODE I2S_TXMODE(I2S1) + +/* I2S Receive mode control */ +#define I2S_RXMODE(port) MMIO32((port) + 0x034) +#define I2S0_RXMODE I2S_RXMODE(I2S0) +#define I2S1_RXMODE I2S_RXMODE(I2S1) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ipc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ipc.h new file mode 100644 index 00000000..ddd81b88 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ipc.h @@ -0,0 +1,30 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* This library is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This library 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this library. If not, see . +*/ + +#ifndef LPC43XX_IPC_H +#define LPC43XX_IPC_H + +#include +#include + +void ipc_halt_m0(void); + +void ipc_start_m0(uint32_t cm0_baseaddr); + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m0/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m0/irq.json new file mode 100644 index 00000000..828c1ddc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m0/irq.json @@ -0,0 +1,36 @@ +{ + "irqs": { + "0": "rtc", + "1": "m4core", + "2": "dma", + "4": "flasheepromat", + "5": "ethernet", + "6": "sdio", + "7": "lcd", + "8": "usb0", + "9": "usb1", + "10": "sct", + "11": "ritimer_or_wwdt", + "12": "timer0", + "13": "gint1", + "14": "pin_int4", + "15": "timer3", + "16": "mcpwm", + "17": "adc0", + "18": "i2c0_or_irc1", + "19": "sgpio", + "20": "spi_or_dac", + "21": "adc1", + "22": "ssp0_or_ssp1", + "23": "eventrouter", + "24": "usart0", + "25": "uart1", + "26": "usart2_or_c_can1", + "27": "usart3", + "28": "i2s0_or_i2s1", + "29": "c_can0" + }, + "partname_humanreadable": "LPC 43xx series M0 core", + "partname_doxygen": "LPC43xx (M0)", + "includeguard": "LIBOPENCM3_LPC43xx_M0_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m4/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m4/irq.json new file mode 100644 index 00000000..376fab11 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/m4/irq.json @@ -0,0 +1,54 @@ +{ + "irqs": { + "0": "dac", + "1": "m0core", + "2": "dma", + "5": "ethernet", + "6": "sdio", + "7": "lcd", + "8": "usb0", + "9": "usb1", + "10": "sct", + "11": "ritimer", + "12": "timer0", + "13": "timer1", + "14": "timer2", + "15": "timer3", + "16": "mcpwm", + "17": "adc0", + "18": "i2c0", + "19": "i2c1", + "20": "spi", + "21": "adc1", + "22": "ssp0", + "23": "ssp1", + "24": "usart0", + "25": "uart1", + "26": "usart2", + "27": "usart3", + "28": "i2s0", + "29": "i2s1", + "30": "spifi", + "31": "sgpio", + "32": "pin_int0", + "33": "pin_int1", + "34": "pin_int2", + "35": "pin_int3", + "36": "pin_int4", + "37": "pin_int5", + "38": "pin_int6", + "39": "pin_int7", + "40": "gint0", + "41": "gint1", + "42": "eventrouter", + "43": "c_can1", + "46": "atimer", + "47": "rtc", + "49": "wwdt", + "51": "c_can0", + "52": "qei" + }, + "partname_humanreadable": "LPC 43xx series M4 core", + "partname_doxygen": "LPC43xx (M4)", + "includeguard": "LIBOPENCM3_LPC43xx_M4_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/memorymap.h new file mode 100644 index 00000000..5d2bdc4d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/memorymap.h @@ -0,0 +1,138 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_MEMORYMAP_H +#define LPC43XX_MEMORYMAP_H + +#include + +/* --- LPC43XX specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE_AHB (0x40000000U) +#define PERIPH_BASE_APB0 (0x40080000U) +#define PERIPH_BASE_APB1 (0x400A0000U) +#define PERIPH_BASE_APB2 (0x400C0000U) +#define PERIPH_BASE_APB3 (0x400E0000U) + +/* Register boundary addresses */ + +/* AHB (0x4000 0000 - 0x4001 2000) */ +#define SCT_BASE (PERIPH_BASE_AHB + 0x00000) +/* PERIPH_BASE_AHB + 0x01000 (0x4000 1000 - 0x4000 1FFF): Reserved */ +#define GPDMA_BASE (PERIPH_BASE_AHB + 0x02000) +#define SPIFI_BASE (PERIPH_BASE_AHB + 0x03000) +#define SDIO_BASE (PERIPH_BASE_AHB + 0x04000) +#define EMC_BASE (PERIPH_BASE_AHB + 0x05000) +#define USB0_BASE (PERIPH_BASE_AHB + 0x06000) +#define USB1_BASE (PERIPH_BASE_AHB + 0x07000) +#define LCD_BASE (PERIPH_BASE_AHB + 0x08000) +/* PERIPH_BASE_AHB + 0x09000 (0x4000 9000 - 0x4000 FFFF): Reserved */ +#define ETHERNET_BASE (PERIPH_BASE_AHB + 0x10000) + +/* 0x4001 2000 - 0x4003 FFFF Reserved */ + +/* RTC domain peripherals */ +#define ATIMER_BASE (0x40040000U) +#define BACKUP_REG_BASE (0x40041000U) +#define PMC_BASE (0x40042000U) +#define CREG_BASE (0x40043000U) +#define EVENTROUTER_BASE (0x40044000U) +#define OTP_BASE (0x40045000U) +#define RTC_BASE (0x40046000U) +/* 0x4004 7000 - 0x4004 FFFF Reserved */ + +/* clocking/reset control peripherals */ +#define CGU_BASE (0x40050000U) +#define CCU1_BASE (0x40051000U) +#define CCU2_BASE (0x40052000U) +#define RGU_BASE (0x40053000U) +/* 0x4005 4000 - 0x4005 FFFF Reserved */ + +/* 0x4006 0000 - 0x4007 FFFF Reserved */ + +/* APB0 ( 0x4008 0000 - 0x4008 FFFF) */ +#define WWDT_BASE (PERIPH_BASE_APB0 + 0x00000) +#define USART0_BASE (PERIPH_BASE_APB0 + 0x01000) +#define UART1_BASE (PERIPH_BASE_APB0 + 0x02000) +#define SSP0_BASE (PERIPH_BASE_APB0 + 0x03000) +#define TIMER0_BASE (PERIPH_BASE_APB0 + 0x04000) +#define TIMER1_BASE (PERIPH_BASE_APB0 + 0x05000) +#define SCU_BASE (PERIPH_BASE_APB0 + 0x06000) +#define GPIO_PIN_INTERRUPT_BASE (PERIPH_BASE_APB0 + 0x07000) +#define GPIO_GROUP0_INTERRUPT_BASE (PERIPH_BASE_APB0 + 0x08000) +#define GPIO_GROUP1_INTERRUPT_BASE (PERIPH_BASE_APB0 + 0x09000) +/* 0x4008 A000 - 0x4008 FFFF Reserved */ + +/* 0x4009 0000 - 0x4009 FFFF Reserved */ + +/* APB1 (0x400A 0000 - 0x400A FFFF) */ +#define MCPWM_BASE (PERIPH_BASE_APB1 + 0x00000) +#define I2C0_BASE (PERIPH_BASE_APB1 + 0x01000) +#define I2S0_BASE (PERIPH_BASE_APB1 + 0x02000) +#define I2S1_BASE (PERIPH_BASE_APB1 + 0x03000) +#define C_CCAN1_BASE (PERIPH_BASE_APB1 + 0x04000) +/* 0x400A 5000 - 0x400A FFFF Reserved */ + +/* 0x400B 0000 - 0x400B FFFF Reserved */ + +/* APB2 (0x400C 0000 - 0x400C FFFF) */ +#define RITIMER_BASE (PERIPH_BASE_APB2 + 0x00000) +#define USART2_BASE (PERIPH_BASE_APB2 + 0x01000) +#define USART3_BASE (PERIPH_BASE_APB2 + 0x02000) +#define TIMER2_BASE (PERIPH_BASE_APB2 + 0x03000) +#define TIMER3_BASE (PERIPH_BASE_APB2 + 0x04000) +#define SSP1_BASE (PERIPH_BASE_APB2 + 0x05000) +#define QEI_BASE (PERIPH_BASE_APB2 + 0x06000) +#define GIMA_BASE (PERIPH_BASE_APB2 + 0x07000) +/* 0x400C 8000 - 0x400C FFFF Reserved */ + +/* 0x400D 0000 - 0x400D FFFF Reserved */ + +/* APB3 (0x400E 0000 - 0x400E FFFF) */ +#define I2C1_BASE (PERIPH_BASE_APB3 + 0x00000) +#define DAC_BASE (PERIPH_BASE_APB3 + 0x01000) +#define C_CAN0_BASE (PERIPH_BASE_APB3 + 0x02000) +#define ADC0_BASE (PERIPH_BASE_APB3 + 0x03000) +#define ADC1_BASE (PERIPH_BASE_APB3 + 0x04000) +/* 0x400E 5000 - 0x400E FFFF Reserved */ + +/* 0x400F 0000 - 0x400F 0FFF Reserved */ + +#define AES_BASE (0x400F1000U) + +/* 0x400F 2000 - 0x400F 3FFF Reserved */ + +#define GPIO_PORT_BASE (0x400F4000U) + +/* 0x400F 8000 - 0x400F FFFF Reserved */ + +#define SPI_PORT_BASE (0x40100000U) +#define SGPIO_PORT_BASE (0x40101000U) + +/* 0x4010 2000 - 0x41FF FFFF Reserved */ + +/* 0x4200 0000 - 0x43FF FFFF peripheral bit band alias region */ + +/* 0x4400 0000 - 0x5FFF FFFF Reserved */ + +/* 0x6000 0000 - 0xFFFF FFFF external memories and ARM private bus */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/rgu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/rgu.h new file mode 100644 index 00000000..0ec01466 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/rgu.h @@ -0,0 +1,1206 @@ +/** @defgroup rgu_defines Reset Generation Unit Defines + +@brief Defined Constants and Types for the LPC43xx Reset Generation Unit + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_RGU_H +#define LPC43XX_RGU_H + +/**@{*/ + +#include +#include + +/* --- RGU registers ------------------------------------------------------- */ + +/* Reset control register 0 */ +#define RESET_CTRL0 MMIO32(RGU_BASE + 0x100) + +/* Reset control register 1 */ +#define RESET_CTRL1 MMIO32(RGU_BASE + 0x104) + +/* Reset status register 0 */ +#define RESET_STATUS0 MMIO32(RGU_BASE + 0x110) + +/* Reset status register 1 */ +#define RESET_STATUS1 MMIO32(RGU_BASE + 0x114) + +/* Reset status register 2 */ +#define RESET_STATUS2 MMIO32(RGU_BASE + 0x118) + +/* Reset status register 3 */ +#define RESET_STATUS3 MMIO32(RGU_BASE + 0x11C) + +/* Reset active status register 0 */ +#define RESET_ACTIVE_STATUS0 MMIO32(RGU_BASE + 0x150) + +/* Reset active status register 1 */ +#define RESET_ACTIVE_STATUS1 MMIO32(RGU_BASE + 0x154) + +/* Reset external status register 0 for CORE_RST */ +#define RESET_EXT_STAT0 MMIO32(RGU_BASE + 0x400) + +/* Reset external status register 1 for PERIPH_RST */ +#define RESET_EXT_STAT1 MMIO32(RGU_BASE + 0x404) + +/* Reset external status register 2 for MASTER_RST */ +#define RESET_EXT_STAT2 MMIO32(RGU_BASE + 0x408) + +/* Reserved */ +#define RESET_EXT_STAT3 MMIO32(RGU_BASE + 0x40C) + +/* Reset external status register 4 for WWDT_RST */ +#define RESET_EXT_STAT4 MMIO32(RGU_BASE + 0x410) + +/* Reset external status register 5 for CREG_RST */ +#define RESET_EXT_STAT5 MMIO32(RGU_BASE + 0x414) + +/* Reserved */ +#define RESET_EXT_STAT6 MMIO32(RGU_BASE + 0x418) + +/* Reserved */ +#define RESET_EXT_STAT7 MMIO32(RGU_BASE + 0x41C) + +/* Reset external status register 8 for BUS_RST */ +#define RESET_EXT_STAT8 MMIO32(RGU_BASE + 0x420) + +/* Reset external status register 9 for SCU_RST */ +#define RESET_EXT_STAT9 MMIO32(RGU_BASE + 0x424) + +/* Reserved */ +#define RESET_EXT_STAT10 MMIO32(RGU_BASE + 0x428) + +/* Reserved */ +#define RESET_EXT_STAT11 MMIO32(RGU_BASE + 0x42C) + +/* Reserved */ +#define RESET_EXT_STAT12 MMIO32(RGU_BASE + 0x430) + +/* Reset external status register 13 for M4_RST */ +#define RESET_EXT_STAT13 MMIO32(RGU_BASE + 0x434) + +/* Reserved */ +#define RESET_EXT_STAT14 MMIO32(RGU_BASE + 0x438) + +/* Reserved */ +#define RESET_EXT_STAT15 MMIO32(RGU_BASE + 0x43C) + +/* Reset external status register 16 for LCD_RST */ +#define RESET_EXT_STAT16 MMIO32(RGU_BASE + 0x440) + +/* Reset external status register 17 for USB0_RST */ +#define RESET_EXT_STAT17 MMIO32(RGU_BASE + 0x444) + +/* Reset external status register 18 for USB1_RST */ +#define RESET_EXT_STAT18 MMIO32(RGU_BASE + 0x448) + +/* Reset external status register 19 for DMA_RST */ +#define RESET_EXT_STAT19 MMIO32(RGU_BASE + 0x44C) + +/* Reset external status register 20 for SDIO_RST */ +#define RESET_EXT_STAT20 MMIO32(RGU_BASE + 0x450) + +/* Reset external status register 21 for EMC_RST */ +#define RESET_EXT_STAT21 MMIO32(RGU_BASE + 0x454) + +/* Reset external status register 22 for ETHERNET_RST */ +#define RESET_EXT_STAT22 MMIO32(RGU_BASE + 0x458) + +/* Reserved */ +#define RESET_EXT_STAT23 MMIO32(RGU_BASE + 0x45C) + +/* Reserved */ +#define RESET_EXT_STAT24 MMIO32(RGU_BASE + 0x460) + +/* Reserved */ +#define RESET_EXT_STAT25 MMIO32(RGU_BASE + 0x464) + +/* Reserved */ +#define RESET_EXT_STAT26 MMIO32(RGU_BASE + 0x468) + +/* Reserved */ +#define RESET_EXT_STAT27 MMIO32(RGU_BASE + 0x46C) + +/* Reset external status register 28 for GPIO_RST */ +#define RESET_EXT_STAT28 MMIO32(RGU_BASE + 0x470) + +/* Reserved */ +#define RESET_EXT_STAT29 MMIO32(RGU_BASE + 0x474) + +/* Reserved */ +#define RESET_EXT_STAT30 MMIO32(RGU_BASE + 0x478) + +/* Reserved */ +#define RESET_EXT_STAT31 MMIO32(RGU_BASE + 0x47C) + +/* Reset external status register 32 for TIMER0_RST */ +#define RESET_EXT_STAT32 MMIO32(RGU_BASE + 0x480) + +/* Reset external status register 33 for TIMER1_RST */ +#define RESET_EXT_STAT33 MMIO32(RGU_BASE + 0x484) + +/* Reset external status register 34 for TIMER2_RST */ +#define RESET_EXT_STAT34 MMIO32(RGU_BASE + 0x488) + +/* Reset external status register 35 for TIMER3_RST */ +#define RESET_EXT_STAT35 MMIO32(RGU_BASE + 0x48C) + +/* Reset external status register 36 for RITIMER_RST */ +#define RESET_EXT_STAT36 MMIO32(RGU_BASE + 0x490) + +/* Reset external status register 37 for SCT_RST */ +#define RESET_EXT_STAT37 MMIO32(RGU_BASE + 0x494) + +/* Reset external status register 38 for MOTOCONPWM_RST */ +#define RESET_EXT_STAT38 MMIO32(RGU_BASE + 0x498) + +/* Reset external status register 39 for QEI_RST */ +#define RESET_EXT_STAT39 MMIO32(RGU_BASE + 0x49C) + +/* Reset external status register 40 for ADC0_RST */ +#define RESET_EXT_STAT40 MMIO32(RGU_BASE + 0x4A0) + +/* Reset external status register 41 for ADC1_RST */ +#define RESET_EXT_STAT41 MMIO32(RGU_BASE + 0x4A4) + +/* Reset external status register 42 for DAC_RST */ +#define RESET_EXT_STAT42 MMIO32(RGU_BASE + 0x4A8) + +/* Reserved */ +#define RESET_EXT_STAT43 MMIO32(RGU_BASE + 0x4AC) + +/* Reset external status register 44 for UART0_RST */ +#define RESET_EXT_STAT44 MMIO32(RGU_BASE + 0x4B0) + +/* Reset external status register 45 for UART1_RST */ +#define RESET_EXT_STAT45 MMIO32(RGU_BASE + 0x4B4) + +/* Reset external status register 46 for UART2_RST */ +#define RESET_EXT_STAT46 MMIO32(RGU_BASE + 0x4B8) + +/* Reset external status register 47 for UART3_RST */ +#define RESET_EXT_STAT47 MMIO32(RGU_BASE + 0x4BC) + +/* Reset external status register 48 for I2C0_RST */ +#define RESET_EXT_STAT48 MMIO32(RGU_BASE + 0x4C0) + +/* Reset external status register 49 for I2C1_RST */ +#define RESET_EXT_STAT49 MMIO32(RGU_BASE + 0x4C4) + +/* Reset external status register 50 for SSP0_RST */ +#define RESET_EXT_STAT50 MMIO32(RGU_BASE + 0x4C8) + +/* Reset external status register 51 for SSP1_RST */ +#define RESET_EXT_STAT51 MMIO32(RGU_BASE + 0x4CC) + +/* Reset external status register 52 for I2S_RST */ +#define RESET_EXT_STAT52 MMIO32(RGU_BASE + 0x4D0) + +/* Reset external status register 53 for SPIFI_RST */ +#define RESET_EXT_STAT53 MMIO32(RGU_BASE + 0x4D4) + +/* Reset external status register 54 for CAN1_RST */ +#define RESET_EXT_STAT54 MMIO32(RGU_BASE + 0x4D8) + +/* Reset external status register 55 for CAN0_RST */ +#define RESET_EXT_STAT55 MMIO32(RGU_BASE + 0x4DC) + +/* Reset external status register 56 for M0APP_RST */ +#define RESET_EXT_STAT56 MMIO32(RGU_BASE + 0x4E0) + +/* Reset external status register 57 for SGPIO_RST */ +#define RESET_EXT_STAT57 MMIO32(RGU_BASE + 0x4E4) + +/* Reset external status register 58 for SPI_RST */ +#define RESET_EXT_STAT58 MMIO32(RGU_BASE + 0x4E8) + +/* Reserved */ +#define RESET_EXT_STAT59 MMIO32(RGU_BASE + 0x4EC) + +/* Reserved */ +#define RESET_EXT_STAT60 MMIO32(RGU_BASE + 0x4F0) + +/* Reserved */ +#define RESET_EXT_STAT61 MMIO32(RGU_BASE + 0x4F4) + +/* Reserved */ +#define RESET_EXT_STAT62 MMIO32(RGU_BASE + 0x4F8) + +/* Reserved */ +#define RESET_EXT_STAT63 MMIO32(RGU_BASE + 0x4FC) + +/* --- RESET_CTRL0 values --------------------------------------- */ + +/* CORE_RST: Writing a one activates the reset */ +#define RESET_CTRL0_CORE_RST_SHIFT (0) +#define RESET_CTRL0_CORE_RST (1 << RESET_CTRL0_CORE_RST_SHIFT) + +/* PERIPH_RST: Writing a one activates the reset */ +#define RESET_CTRL0_PERIPH_RST_SHIFT (1) +#define RESET_CTRL0_PERIPH_RST (1 << RESET_CTRL0_PERIPH_RST_SHIFT) + +/* MASTER_RST: Writing a one activates the reset */ +#define RESET_CTRL0_MASTER_RST_SHIFT (2) +#define RESET_CTRL0_MASTER_RST (1 << RESET_CTRL0_MASTER_RST_SHIFT) + +/* WWDT_RST: Writing a one to this bit has no effect */ +#define RESET_CTRL0_WWDT_RST_SHIFT (4) +#define RESET_CTRL0_WWDT_RST (1 << RESET_CTRL0_WWDT_RST_SHIFT) + +/* CREG_RST: Writing a one to this bit has no effect */ +#define RESET_CTRL0_CREG_RST_SHIFT (5) +#define RESET_CTRL0_CREG_RST (1 << RESET_CTRL0_CREG_RST_SHIFT) + +/* BUS_RST: Writing a one activates the reset */ +#define RESET_CTRL0_BUS_RST_SHIFT (8) +#define RESET_CTRL0_BUS_RST (1 << RESET_CTRL0_BUS_RST_SHIFT) + +/* SCU_RST: Writing a one activates the reset */ +#define RESET_CTRL0_SCU_RST_SHIFT (9) +#define RESET_CTRL0_SCU_RST (1 << RESET_CTRL0_SCU_RST_SHIFT) + +/* M4_RST: Writing a one activates the reset */ +#define RESET_CTRL0_M4_RST_SHIFT (13) +#define RESET_CTRL0_M4_RST (1 << RESET_CTRL0_M4_RST_SHIFT) + +/* LCD_RST: Writing a one activates the reset */ +#define RESET_CTRL0_LCD_RST_SHIFT (16) +#define RESET_CTRL0_LCD_RST (1 << RESET_CTRL0_LCD_RST_SHIFT) + +/* USB0_RST: Writing a one activates the reset */ +#define RESET_CTRL0_USB0_RST_SHIFT (17) +#define RESET_CTRL0_USB0_RST (1 << RESET_CTRL0_USB0_RST_SHIFT) + +/* USB1_RST: Writing a one activates the reset */ +#define RESET_CTRL0_USB1_RST_SHIFT (18) +#define RESET_CTRL0_USB1_RST (1 << RESET_CTRL0_USB1_RST_SHIFT) + +/* DMA_RST: Writing a one activates the reset */ +#define RESET_CTRL0_DMA_RST_SHIFT (19) +#define RESET_CTRL0_DMA_RST (1 << RESET_CTRL0_DMA_RST_SHIFT) + +/* SDIO_RST: Writing a one activates the reset */ +#define RESET_CTRL0_SDIO_RST_SHIFT (20) +#define RESET_CTRL0_SDIO_RST (1 << RESET_CTRL0_SDIO_RST_SHIFT) + +/* EMC_RST: Writing a one activates the reset */ +#define RESET_CTRL0_EMC_RST_SHIFT (21) +#define RESET_CTRL0_EMC_RST (1 << RESET_CTRL0_EMC_RST_SHIFT) + +/* ETHERNET_RST: Writing a one activates the reset */ +#define RESET_CTRL0_ETHERNET_RST_SHIFT (22) +#define RESET_CTRL0_ETHERNET_RST (1 << RESET_CTRL0_ETHERNET_RST_SHIFT) + +/* FLASHA_RST: Writing a one activates the reset */ +#define RESET_CTRL0_FLASHA_RST_SHIFT (25) +#define RESET_CTRL0_FLASHA_RST (1 << RESET_CTRL0_FLASHA_RST_SHIFT) + +/* EEPROM_RST: Writing a one activates the reset */ +#define RESET_CTRL0_EEPROM_RST_SHIFT (27) +#define RESET_CTRL0_EEPROM_RST (1 << RESET_CTRL0_EEPROM_RST_SHIFT) + +/* GPIO_RST: Writing a one activates the reset */ +#define RESET_CTRL0_GPIO_RST_SHIFT (28) +#define RESET_CTRL0_GPIO_RST (1 << RESET_CTRL0_GPIO_RST_SHIFT) + +/* FLASHB_RST: Writing a one activates the reset */ +#define RESET_CTRL0_FLASHB_RST_SHIFT (29) +#define RESET_CTRL0_FLASHB_RST (1 << RESET_CTRL0_FLASHB_RST_SHIFT) + +/* --- RESET_CTRL1 values --------------------------------------- */ + +/* TIMER0_RST: Writing a one activates the reset */ +#define RESET_CTRL1_TIMER0_RST_SHIFT (0) +#define RESET_CTRL1_TIMER0_RST (1 << RESET_CTRL1_TIMER0_RST_SHIFT) + +/* TIMER1_RST: Writing a one activates the reset */ +#define RESET_CTRL1_TIMER1_RST_SHIFT (1) +#define RESET_CTRL1_TIMER1_RST (1 << RESET_CTRL1_TIMER1_RST_SHIFT) + +/* TIMER2_RST: Writing a one activates the reset */ +#define RESET_CTRL1_TIMER2_RST_SHIFT (2) +#define RESET_CTRL1_TIMER2_RST (1 << RESET_CTRL1_TIMER2_RST_SHIFT) + +/* TIMER3_RST: Writing a one activates the reset */ +#define RESET_CTRL1_TIMER3_RST_SHIFT (3) +#define RESET_CTRL1_TIMER3_RST (1 << RESET_CTRL1_TIMER3_RST_SHIFT) + +/* RTIMER_RST: Writing a one activates the reset */ +#define RESET_CTRL1_RTIMER_RST_SHIFT (4) +#define RESET_CTRL1_RTIMER_RST (1 << RESET_CTRL1_RTIMER_RST_SHIFT) + +/* SCT_RST: Writing a one activates the reset */ +#define RESET_CTRL1_SCT_RST_SHIFT (5) +#define RESET_CTRL1_SCT_RST (1 << RESET_CTRL1_SCT_RST_SHIFT) + +/* MOTOCONPWM_RST: Writing a one activates the reset */ +#define RESET_CTRL1_MOTOCONPWM_RST_SHIFT (6) +#define RESET_CTRL1_MOTOCONPWM_RST (1 << RESET_CTRL1_MOTOCONPWM_RST_SHIFT) + +/* QEI_RST: Writing a one activates the reset */ +#define RESET_CTRL1_QEI_RST_SHIFT (7) +#define RESET_CTRL1_QEI_RST (1 << RESET_CTRL1_QEI_RST_SHIFT) + +/* ADC0_RST: Writing a one activates the reset */ +#define RESET_CTRL1_ADC0_RST_SHIFT (8) +#define RESET_CTRL1_ADC0_RST (1 << RESET_CTRL1_ADC0_RST_SHIFT) + +/* ADC1_RST: Writing a one activates the reset */ +#define RESET_CTRL1_ADC1_RST_SHIFT (9) +#define RESET_CTRL1_ADC1_RST (1 << RESET_CTRL1_ADC1_RST_SHIFT) + +/* DAC_RST: Writing a one activates the reset */ +#define RESET_CTRL1_DAC_RST_SHIFT (10) +#define RESET_CTRL1_DAC_RST (1 << RESET_CTRL1_DAC_RST_SHIFT) + +/* UART0_RST: Writing a one activates the reset */ +#define RESET_CTRL1_UART0_RST_SHIFT (12) +#define RESET_CTRL1_UART0_RST (1 << RESET_CTRL1_UART0_RST_SHIFT) + +/* UART1_RST: Writing a one activates the reset */ +#define RESET_CTRL1_UART1_RST_SHIFT (13) +#define RESET_CTRL1_UART1_RST (1 << RESET_CTRL1_UART1_RST_SHIFT) + +/* UART2_RST: Writing a one activates the reset */ +#define RESET_CTRL1_UART2_RST_SHIFT (14) +#define RESET_CTRL1_UART2_RST (1 << RESET_CTRL1_UART2_RST_SHIFT) + +/* UART3_RST: Writing a one activates the reset */ +#define RESET_CTRL1_UART3_RST_SHIFT (15) +#define RESET_CTRL1_UART3_RST (1 << RESET_CTRL1_UART3_RST_SHIFT) + +/* I2C0_RST: Writing a one activates the reset */ +#define RESET_CTRL1_I2C0_RST_SHIFT (16) +#define RESET_CTRL1_I2C0_RST (1 << RESET_CTRL1_I2C0_RST_SHIFT) + +/* I2C1_RST: Writing a one activates the reset */ +#define RESET_CTRL1_I2C1_RST_SHIFT (17) +#define RESET_CTRL1_I2C1_RST (1 << RESET_CTRL1_I2C1_RST_SHIFT) + +/* SSP0_RST: Writing a one activates the reset */ +#define RESET_CTRL1_SSP0_RST_SHIFT (18) +#define RESET_CTRL1_SSP0_RST (1 << RESET_CTRL1_SSP0_RST_SHIFT) + +/* SSP1_RST: Writing a one activates the reset */ +#define RESET_CTRL1_SSP1_RST_SHIFT (19) +#define RESET_CTRL1_SSP1_RST (1 << RESET_CTRL1_SSP1_RST_SHIFT) + +/* I2S_RST: Writing a one activates the reset */ +#define RESET_CTRL1_I2S_RST_SHIFT (20) +#define RESET_CTRL1_I2S_RST (1 << RESET_CTRL1_I2S_RST_SHIFT) + +/* SPIFI_RST: Writing a one activates the reset */ +#define RESET_CTRL1_SPIFI_RST_SHIFT (21) +#define RESET_CTRL1_SPIFI_RST (1 << RESET_CTRL1_SPIFI_RST_SHIFT) + +/* CAN1_RST: Writing a one activates the reset */ +#define RESET_CTRL1_CAN1_RST_SHIFT (22) +#define RESET_CTRL1_CAN1_RST (1 << RESET_CTRL1_CAN1_RST_SHIFT) + +/* CAN0_RST: Writing a one activates the reset */ +#define RESET_CTRL1_CAN0_RST_SHIFT (23) +#define RESET_CTRL1_CAN0_RST (1 << RESET_CTRL1_CAN0_RST_SHIFT) + +/* M0APP_RST: Writing a one activates the reset */ +#define RESET_CTRL1_M0APP_RST_SHIFT (24) +#define RESET_CTRL1_M0APP_RST (1 << RESET_CTRL1_M0APP_RST_SHIFT) + +/* SGPIO_RST: Writing a one activates the reset */ +#define RESET_CTRL1_SGPIO_RST_SHIFT (25) +#define RESET_CTRL1_SGPIO_RST (1 << RESET_CTRL1_SGPIO_RST_SHIFT) + +/* SPI_RST: Writing a one activates the reset */ +#define RESET_CTRL1_SPI_RST_SHIFT (26) +#define RESET_CTRL1_SPI_RST (1 << RESET_CTRL1_SPI_RST_SHIFT) + +/* --- RESET_STATUS0 values ------------------------------------- */ + +/* CORE_RST: Status of the CORE_RST reset generator output */ +#define RESET_STATUS0_CORE_RST_SHIFT (0) +#define RESET_STATUS0_CORE_RST_MASK (0x3 << RESET_STATUS0_CORE_RST_SHIFT) +#define RESET_STATUS0_CORE_RST(x) ((x) << RESET_STATUS0_CORE_RST_SHIFT) + +/* PERIPH_RST: Status of the PERIPH_RST reset generator output */ +#define RESET_STATUS0_PERIPH_RST_SHIFT (2) +#define RESET_STATUS0_PERIPH_RST_MASK (0x3 << RESET_STATUS0_PERIPH_RST_SHIFT) +#define RESET_STATUS0_PERIPH_RST(x) ((x) << RESET_STATUS0_PERIPH_RST_SHIFT) + +/* MASTER_RST: Status of the MASTER_RST reset generator output */ +#define RESET_STATUS0_MASTER_RST_SHIFT (4) +#define RESET_STATUS0_MASTER_RST_MASK (0x3 << RESET_STATUS0_MASTER_RST_SHIFT) +#define RESET_STATUS0_MASTER_RST(x) ((x) << RESET_STATUS0_MASTER_RST_SHIFT) + +/* WWDT_RST: Status of the WWDT_RST reset generator output */ +#define RESET_STATUS0_WWDT_RST_SHIFT (8) +#define RESET_STATUS0_WWDT_RST_MASK (0x3 << RESET_STATUS0_WWDT_RST_SHIFT) +#define RESET_STATUS0_WWDT_RST(x) ((x) << RESET_STATUS0_WWDT_RST_SHIFT) + +/* CREG_RST: Status of the CREG_RST reset generator output */ +#define RESET_STATUS0_CREG_RST_SHIFT (10) +#define RESET_STATUS0_CREG_RST_MASK (0x3 << RESET_STATUS0_CREG_RST_SHIFT) +#define RESET_STATUS0_CREG_RST(x) ((x) << RESET_STATUS0_CREG_RST_SHIFT) + +/* BUS_RST: Status of the BUS_RST reset generator output */ +#define RESET_STATUS0_BUS_RST_SHIFT (16) +#define RESET_STATUS0_BUS_RST_MASK (0x3 << RESET_STATUS0_BUS_RST_SHIFT) +#define RESET_STATUS0_BUS_RST(x) ((x) << RESET_STATUS0_BUS_RST_SHIFT) + +/* SCU_RST: Status of the SCU_RST reset generator output */ +#define RESET_STATUS0_SCU_RST_SHIFT (18) +#define RESET_STATUS0_SCU_RST_MASK (0x3 << RESET_STATUS0_SCU_RST_SHIFT) +#define RESET_STATUS0_SCU_RST(x) ((x) << RESET_STATUS0_SCU_RST_SHIFT) + +/* M4_RST: Status of the M4_RST reset generator output */ +#define RESET_STATUS0_M4_RST_SHIFT (26) +#define RESET_STATUS0_M4_RST_MASK (0x3 << RESET_STATUS0_M4_RST_SHIFT) +#define RESET_STATUS0_M4_RST(x) ((x) << RESET_STATUS0_M4_RST_SHIFT) + +/* --- RESET_STATUS1 values ------------------------------------- */ + +/* LCD_RST: Status of the LCD_RST reset generator output */ +#define RESET_STATUS1_LCD_RST_SHIFT (0) +#define RESET_STATUS1_LCD_RST_MASK (0x3 << RESET_STATUS1_LCD_RST_SHIFT) +#define RESET_STATUS1_LCD_RST(x) ((x) << RESET_STATUS1_LCD_RST_SHIFT) + +/* USB0_RST: Status of the USB0_RST reset generator output */ +#define RESET_STATUS1_USB0_RST_SHIFT (2) +#define RESET_STATUS1_USB0_RST_MASK (0x3 << RESET_STATUS1_USB0_RST_SHIFT) +#define RESET_STATUS1_USB0_RST(x) ((x) << RESET_STATUS1_USB0_RST_SHIFT) + +/* USB1_RST: Status of the USB1_RST reset generator output */ +#define RESET_STATUS1_USB1_RST_SHIFT (4) +#define RESET_STATUS1_USB1_RST_MASK (0x3 << RESET_STATUS1_USB1_RST_SHIFT) +#define RESET_STATUS1_USB1_RST(x) ((x) << RESET_STATUS1_USB1_RST_SHIFT) + +/* DMA_RST: Status of the DMA_RST reset generator output */ +#define RESET_STATUS1_DMA_RST_SHIFT (6) +#define RESET_STATUS1_DMA_RST_MASK (0x3 << RESET_STATUS1_DMA_RST_SHIFT) +#define RESET_STATUS1_DMA_RST(x) ((x) << RESET_STATUS1_DMA_RST_SHIFT) + +/* SDIO_RST: Status of the SDIO_RST reset generator output */ +#define RESET_STATUS1_SDIO_RST_SHIFT (8) +#define RESET_STATUS1_SDIO_RST_MASK (0x3 << RESET_STATUS1_SDIO_RST_SHIFT) +#define RESET_STATUS1_SDIO_RST(x) ((x) << RESET_STATUS1_SDIO_RST_SHIFT) + +/* EMC_RST: Status of the EMC_RST reset generator output */ +#define RESET_STATUS1_EMC_RST_SHIFT (10) +#define RESET_STATUS1_EMC_RST_MASK (0x3 << RESET_STATUS1_EMC_RST_SHIFT) +#define RESET_STATUS1_EMC_RST(x) ((x) << RESET_STATUS1_EMC_RST_SHIFT) + +/* ETHERNET_RST: Status of the ETHERNET_RST reset generator output */ +#define RESET_STATUS1_ETHERNET_RST_SHIFT (12) +#define RESET_STATUS1_ETHERNET_RST_MASK \ + (0x3 << RESET_STATUS1_ETHERNET_RST_SHIFT) +#define RESET_STATUS1_ETHERNET_RST(x) ((x) << RESET_STATUS1_ETHERNET_RST_SHIFT) + +/* FLASHA_RST: Status of the FLASHA_RST reset generator output */ +#define RESET_STATUS1_FLASHA_RST_SHIFT (18) +#define RESET_STATUS1_FLASHA_RST_MASK (0x3 << RESET_STATUS1_FLASHA_RST_SHIFT) +#define RESET_STATUS1_FLASHA_RST(x) ((x) << RESET_STATUS1_FLASHA_RST_SHIFT) + +/* EEPROM_RST: Status of the EEPROM_RST reset generator output */ +#define RESET_STATUS1_EEPROM_RST_SHIFT (22) +#define RESET_STATUS1_EEPROM_RST_MASK (0x3 << RESET_STATUS1_EEPROM_RST_SHIFT) +#define RESET_STATUS1_EEPROM_RST(x) ((x) << RESET_STATUS1_EEPROM_RST_SHIFT) + +/* GPIO_RST: Status of the GPIO_RST reset generator output */ +#define RESET_STATUS1_GPIO_RST_SHIFT (24) +#define RESET_STATUS1_GPIO_RST_MASK (0x3 << RESET_STATUS1_GPIO_RST_SHIFT) +#define RESET_STATUS1_GPIO_RST(x) ((x) << RESET_STATUS1_GPIO_RST_SHIFT) + +/* FLASHB_RST: Status of the FLASHB_RST reset generator output */ +#define RESET_STATUS1_FLASHB_RST_SHIFT (26) +#define RESET_STATUS1_FLASHB_RST_MASK (0x3 << RESET_STATUS1_FLASHB_RST_SHIFT) +#define RESET_STATUS1_FLASHB_RST(x) ((x) << RESET_STATUS1_FLASHB_RST_SHIFT) + +/* --- RESET_STATUS2 values ------------------------------------- */ + +/* TIMER0_RST: Status of the TIMER0_RST reset generator output */ +#define RESET_STATUS2_TIMER0_RST_SHIFT (0) +#define RESET_STATUS2_TIMER0_RST_MASK (0x3 << RESET_STATUS2_TIMER0_RST_SHIFT) +#define RESET_STATUS2_TIMER0_RST(x) ((x) << RESET_STATUS2_TIMER0_RST_SHIFT) + +/* TIMER1_RST: Status of the TIMER1_RST reset generator output */ +#define RESET_STATUS2_TIMER1_RST_SHIFT (2) +#define RESET_STATUS2_TIMER1_RST_MASK (0x3 << RESET_STATUS2_TIMER1_RST_SHIFT) +#define RESET_STATUS2_TIMER1_RST(x) ((x) << RESET_STATUS2_TIMER1_RST_SHIFT) + +/* TIMER2_RST: Status of the TIMER2_RST reset generator output */ +#define RESET_STATUS2_TIMER2_RST_SHIFT (4) +#define RESET_STATUS2_TIMER2_RST_MASK (0x3 << RESET_STATUS2_TIMER2_RST_SHIFT) +#define RESET_STATUS2_TIMER2_RST(x) ((x) << RESET_STATUS2_TIMER2_RST_SHIFT) + +/* TIMER3_RST: Status of the TIMER3_RST reset generator output */ +#define RESET_STATUS2_TIMER3_RST_SHIFT (6) +#define RESET_STATUS2_TIMER3_RST_MASK (0x3 << RESET_STATUS2_TIMER3_RST_SHIFT) +#define RESET_STATUS2_TIMER3_RST(x) ((x) << RESET_STATUS2_TIMER3_RST_SHIFT) + +/* RITIMER_RST: Status of the RITIMER_RST reset generator output */ +#define RESET_STATUS2_RITIMER_RST_SHIFT (8) +#define RESET_STATUS2_RITIMER_RST_MASK (0x3 << RESET_STATUS2_RITIMER_RST_SHIFT) +#define RESET_STATUS2_RITIMER_RST(x) ((x) << RESET_STATUS2_RITIMER_RST_SHIFT) + +/* SCT_RST: Status of the SCT_RST reset generator output */ +#define RESET_STATUS2_SCT_RST_SHIFT (10) +#define RESET_STATUS2_SCT_RST_MASK (0x3 << RESET_STATUS2_SCT_RST_SHIFT) +#define RESET_STATUS2_SCT_RST(x) ((x) << RESET_STATUS2_SCT_RST_SHIFT) + +/* MOTOCONPWM_RST: Status of the MOTOCONPWM_RST reset generator output */ +#define RESET_STATUS2_MOTOCONPWM_RST_SHIFT (12) +#define RESET_STATUS2_MOTOCONPWM_RST_MASK \ + (0x3 << RESET_STATUS2_MOTOCONPWM_RST_SHIFT) +#define RESET_STATUS2_MOTOCONPWM_RST(x) \ + ((x) << RESET_STATUS2_MOTOCONPWM_RST_SHIFT) + +/* QEI_RST: Status of the QEI_RST reset generator output */ +#define RESET_STATUS2_QEI_RST_SHIFT (14) +#define RESET_STATUS2_QEI_RST_MASK (0x3 << RESET_STATUS2_QEI_RST_SHIFT) +#define RESET_STATUS2_QEI_RST(x) ((x) << RESET_STATUS2_QEI_RST_SHIFT) + +/* ADC0_RST: Status of the ADC0_RST reset generator output */ +#define RESET_STATUS2_ADC0_RST_SHIFT (16) +#define RESET_STATUS2_ADC0_RST_MASK (0x3 << RESET_STATUS2_ADC0_RST_SHIFT) +#define RESET_STATUS2_ADC0_RST(x) ((x) << RESET_STATUS2_ADC0_RST_SHIFT) + +/* ADC1_RST: Status of the ADC1_RST reset generator output */ +#define RESET_STATUS2_ADC1_RST_SHIFT (18) +#define RESET_STATUS2_ADC1_RST_MASK (0x3 << RESET_STATUS2_ADC1_RST_SHIFT) +#define RESET_STATUS2_ADC1_RST(x) ((x) << RESET_STATUS2_ADC1_RST_SHIFT) + +/* DAC_RST: Status of the DAC_RST reset generator output */ +#define RESET_STATUS2_DAC_RST_SHIFT (20) +#define RESET_STATUS2_DAC_RST_MASK (0x3 << RESET_STATUS2_DAC_RST_SHIFT) +#define RESET_STATUS2_DAC_RST(x) ((x) << RESET_STATUS2_DAC_RST_SHIFT) + +/* UART0_RST: Status of the UART0_RST reset generator output */ +#define RESET_STATUS2_UART0_RST_SHIFT (24) +#define RESET_STATUS2_UART0_RST_MASK (0x3 << RESET_STATUS2_UART0_RST_SHIFT) +#define RESET_STATUS2_UART0_RST(x) ((x) << RESET_STATUS2_UART0_RST_SHIFT) + +/* UART1_RST: Status of the UART1_RST reset generator output */ +#define RESET_STATUS2_UART1_RST_SHIFT (26) +#define RESET_STATUS2_UART1_RST_MASK (0x3 << RESET_STATUS2_UART1_RST_SHIFT) +#define RESET_STATUS2_UART1_RST(x) ((x) << RESET_STATUS2_UART1_RST_SHIFT) + +/* UART2_RST: Status of the UART2_RST reset generator output */ +#define RESET_STATUS2_UART2_RST_SHIFT (28) +#define RESET_STATUS2_UART2_RST_MASK (0x3 << RESET_STATUS2_UART2_RST_SHIFT) +#define RESET_STATUS2_UART2_RST(x) ((x) << RESET_STATUS2_UART2_RST_SHIFT) + +/* UART3_RST: Status of the UART3_RST reset generator output */ +#define RESET_STATUS2_UART3_RST_SHIFT (30) +#define RESET_STATUS2_UART3_RST_MASK (0x3 << RESET_STATUS2_UART3_RST_SHIFT) +#define RESET_STATUS2_UART3_RST(x) ((x) << RESET_STATUS2_UART3_RST_SHIFT) + +/* --- RESET_STATUS3 values ------------------------------------- */ + +/* I2C0_RST: Status of the I2C0_RST reset generator output */ +#define RESET_STATUS3_I2C0_RST_SHIFT (0) +#define RESET_STATUS3_I2C0_RST_MASK (0x3 << RESET_STATUS3_I2C0_RST_SHIFT) +#define RESET_STATUS3_I2C0_RST(x) ((x) << RESET_STATUS3_I2C0_RST_SHIFT) + +/* I2C1_RST: Status of the I2C1_RST reset generator output */ +#define RESET_STATUS3_I2C1_RST_SHIFT (2) +#define RESET_STATUS3_I2C1_RST_MASK (0x3 << RESET_STATUS3_I2C1_RST_SHIFT) +#define RESET_STATUS3_I2C1_RST(x) ((x) << RESET_STATUS3_I2C1_RST_SHIFT) + +/* SSP0_RST: Status of the SSP0_RST reset generator output */ +#define RESET_STATUS3_SSP0_RST_SHIFT (4) +#define RESET_STATUS3_SSP0_RST_MASK (0x3 << RESET_STATUS3_SSP0_RST_SHIFT) +#define RESET_STATUS3_SSP0_RST(x) ((x) << RESET_STATUS3_SSP0_RST_SHIFT) + +/* SSP1_RST: Status of the SSP1_RST reset generator output */ +#define RESET_STATUS3_SSP1_RST_SHIFT (6) +#define RESET_STATUS3_SSP1_RST_MASK (0x3 << RESET_STATUS3_SSP1_RST_SHIFT) +#define RESET_STATUS3_SSP1_RST(x) ((x) << RESET_STATUS3_SSP1_RST_SHIFT) + +/* I2S_RST: Status of the I2S_RST reset generator output */ +#define RESET_STATUS3_I2S_RST_SHIFT (8) +#define RESET_STATUS3_I2S_RST_MASK (0x3 << RESET_STATUS3_I2S_RST_SHIFT) +#define RESET_STATUS3_I2S_RST(x) ((x) << RESET_STATUS3_I2S_RST_SHIFT) + +/* SPIFI_RST: Status of the SPIFI_RST reset generator output */ +#define RESET_STATUS3_SPIFI_RST_SHIFT (10) +#define RESET_STATUS3_SPIFI_RST_MASK (0x3 << RESET_STATUS3_SPIFI_RST_SHIFT) +#define RESET_STATUS3_SPIFI_RST(x) ((x) << RESET_STATUS3_SPIFI_RST_SHIFT) + +/* CAN1_RST: Status of the CAN1_RST reset generator output */ +#define RESET_STATUS3_CAN1_RST_SHIFT (12) +#define RESET_STATUS3_CAN1_RST_MASK (0x3 << RESET_STATUS3_CAN1_RST_SHIFT) +#define RESET_STATUS3_CAN1_RST(x) ((x) << RESET_STATUS3_CAN1_RST_SHIFT) + +/* CAN0_RST: Status of the CAN0_RST reset generator output */ +#define RESET_STATUS3_CAN0_RST_SHIFT (14) +#define RESET_STATUS3_CAN0_RST_MASK (0x3 << RESET_STATUS3_CAN0_RST_SHIFT) +#define RESET_STATUS3_CAN0_RST(x) ((x) << RESET_STATUS3_CAN0_RST_SHIFT) + +/* M0APP_RST: Status of the M0APP_RST reset generator output */ +#define RESET_STATUS3_M0APP_RST_SHIFT (16) +#define RESET_STATUS3_M0APP_RST_MASK (0x3 << RESET_STATUS3_M0APP_RST_SHIFT) +#define RESET_STATUS3_M0APP_RST(x) ((x) << RESET_STATUS3_M0APP_RST_SHIFT) + +/* SGPIO_RST: Status of the SGPIO_RST reset generator output */ +#define RESET_STATUS3_SGPIO_RST_SHIFT (18) +#define RESET_STATUS3_SGPIO_RST_MASK (0x3 << RESET_STATUS3_SGPIO_RST_SHIFT) +#define RESET_STATUS3_SGPIO_RST(x) ((x) << RESET_STATUS3_SGPIO_RST_SHIFT) + +/* SPI_RST: Status of the SPI_RST reset generator output */ +#define RESET_STATUS3_SPI_RST_SHIFT (20) +#define RESET_STATUS3_SPI_RST_MASK (0x3 << RESET_STATUS3_SPI_RST_SHIFT) +#define RESET_STATUS3_SPI_RST(x) ((x) << RESET_STATUS3_SPI_RST_SHIFT) + +/* --- RESET_ACTIVE_STATUS0 values ------------------------------ */ + +/* CORE_RST: Current status of the CORE_RST */ +#define RESET_ACTIVE_STATUS0_CORE_RST_SHIFT (0) +#define RESET_ACTIVE_STATUS0_CORE_RST (1 << RESET_ACTIVE_STATUS0_CORE_RST_SHIFT) + +/* PERIPH_RST: Current status of the PERIPH_RST */ +#define RESET_ACTIVE_STATUS0_PERIPH_RST_SHIFT (1) +#define RESET_ACTIVE_STATUS0_PERIPH_RST \ + (1 << RESET_ACTIVE_STATUS0_PERIPH_RST_SHIFT) + +/* MASTER_RST: Current status of the MASTER_RST */ +#define RESET_ACTIVE_STATUS0_MASTER_RST_SHIFT (2) +#define RESET_ACTIVE_STATUS0_MASTER_RST \ + (1 << RESET_ACTIVE_STATUS0_MASTER_RST_SHIFT) + +/* WWDT_RST: Current status of the WWDT_RST */ +#define RESET_ACTIVE_STATUS0_WWDT_RST_SHIFT (4) +#define RESET_ACTIVE_STATUS0_WWDT_RST (1 << RESET_ACTIVE_STATUS0_WWDT_RST_SHIFT) + +/* CREG_RST: Current status of the CREG_RST */ +#define RESET_ACTIVE_STATUS0_CREG_RST_SHIFT (5) +#define RESET_ACTIVE_STATUS0_CREG_RST (1 << RESET_ACTIVE_STATUS0_CREG_RST_SHIFT) + +/* BUS_RST: Current status of the BUS_RST */ +#define RESET_ACTIVE_STATUS0_BUS_RST_SHIFT (8) +#define RESET_ACTIVE_STATUS0_BUS_RST (1 << RESET_ACTIVE_STATUS0_BUS_RST_SHIFT) + +/* SCU_RST: Current status of the SCU_RST */ +#define RESET_ACTIVE_STATUS0_SCU_RST_SHIFT (9) +#define RESET_ACTIVE_STATUS0_SCU_RST (1 << RESET_ACTIVE_STATUS0_SCU_RST_SHIFT) + +/* M4_RST: Current status of the M4_RST */ +#define RESET_ACTIVE_STATUS0_M4_RST_SHIFT (13) +#define RESET_ACTIVE_STATUS0_M4_RST (1 << RESET_ACTIVE_STATUS0_M4_RST_SHIFT) + +/* LCD_RST: Current status of the LCD_RST */ +#define RESET_ACTIVE_STATUS0_LCD_RST_SHIFT (16) +#define RESET_ACTIVE_STATUS0_LCD_RST (1 << RESET_ACTIVE_STATUS0_LCD_RST_SHIFT) + +/* USB0_RST: Current status of the USB0_RST */ +#define RESET_ACTIVE_STATUS0_USB0_RST_SHIFT (17) +#define RESET_ACTIVE_STATUS0_USB0_RST (1 << RESET_ACTIVE_STATUS0_USB0_RST_SHIFT) + +/* USB1_RST: Current status of the USB1_RST */ +#define RESET_ACTIVE_STATUS0_USB1_RST_SHIFT (18) +#define RESET_ACTIVE_STATUS0_USB1_RST (1 << RESET_ACTIVE_STATUS0_USB1_RST_SHIFT) + +/* DMA_RST: Current status of the DMA_RST */ +#define RESET_ACTIVE_STATUS0_DMA_RST_SHIFT (19) +#define RESET_ACTIVE_STATUS0_DMA_RST (1 << RESET_ACTIVE_STATUS0_DMA_RST_SHIFT) + +/* SDIO_RST: Current status of the SDIO_RST */ +#define RESET_ACTIVE_STATUS0_SDIO_RST_SHIFT (20) +#define RESET_ACTIVE_STATUS0_SDIO_RST (1 << RESET_ACTIVE_STATUS0_SDIO_RST_SHIFT) + +/* EMC_RST: Current status of the EMC_RST */ +#define RESET_ACTIVE_STATUS0_EMC_RST_SHIFT (21) +#define RESET_ACTIVE_STATUS0_EMC_RST (1 << RESET_ACTIVE_STATUS0_EMC_RST_SHIFT) + +/* ETHERNET_RST: Current status of the ETHERNET_RST */ +#define RESET_ACTIVE_STATUS0_ETHERNET_RST_SHIFT (22) +#define RESET_ACTIVE_STATUS0_ETHERNET_RST \ + (1 << RESET_ACTIVE_STATUS0_ETHERNET_RST_SHIFT) + +/* FLASHA_RST: Current status of the FLASHA_RST */ +#define RESET_ACTIVE_STATUS0_FLASHA_RST_SHIFT (25) +#define RESET_ACTIVE_STATUS0_FLASHA_RST \ + (1 << RESET_ACTIVE_STATUS0_FLASHA_RST_SHIFT) + +/* EEPROM_RST: Current status of the EEPROM_RST */ +#define RESET_ACTIVE_STATUS0_EEPROM_RST_SHIFT (27) +#define RESET_ACTIVE_STATUS0_EEPROM_RST \ + (1 << RESET_ACTIVE_STATUS0_EEPROM_RST_SHIFT) + +/* GPIO_RST: Current status of the GPIO_RST */ +#define RESET_ACTIVE_STATUS0_GPIO_RST_SHIFT (28) +#define RESET_ACTIVE_STATUS0_GPIO_RST (1 << RESET_ACTIVE_STATUS0_GPIO_RST_SHIFT) + +/* FLASHB_RST: Current status of the FLASHB_RST */ +#define RESET_ACTIVE_STATUS0_FLASHB_RST_SHIFT (29) +#define RESET_ACTIVE_STATUS0_FLASHB_RST \ + (1 << RESET_ACTIVE_STATUS0_FLASHB_RST_SHIFT) + +/* --- RESET_ACTIVE_STATUS1 values ------------------------------ */ + +/* TIMER0_RST: Current status of the TIMER0_RST */ +#define RESET_ACTIVE_STATUS1_TIMER0_RST_SHIFT (0) +#define RESET_ACTIVE_STATUS1_TIMER0_RST \ + (1 << RESET_ACTIVE_STATUS1_TIMER0_RST_SHIFT) + +/* TIMER1_RST: Current status of the TIMER1_RST */ +#define RESET_ACTIVE_STATUS1_TIMER1_RST_SHIFT (1) +#define RESET_ACTIVE_STATUS1_TIMER1_RST \ + (1 << RESET_ACTIVE_STATUS1_TIMER1_RST_SHIFT) + +/* TIMER2_RST: Current status of the TIMER2_RST */ +#define RESET_ACTIVE_STATUS1_TIMER2_RST_SHIFT (2) +#define RESET_ACTIVE_STATUS1_TIMER2_RST \ + (1 << RESET_ACTIVE_STATUS1_TIMER2_RST_SHIFT) + +/* TIMER3_RST: Current status of the TIMER3_RST */ +#define RESET_ACTIVE_STATUS1_TIMER3_RST_SHIFT (3) +#define RESET_ACTIVE_STATUS1_TIMER3_RST \ + (1 << RESET_ACTIVE_STATUS1_TIMER3_RST_SHIFT) + +/* RITIMER_RST: Current status of the RITIMER_RST */ +#define RESET_ACTIVE_STATUS1_RITIMER_RST_SHIFT (4) +#define RESET_ACTIVE_STATUS1_RITIMER_RST \ + (1 << RESET_ACTIVE_STATUS1_RITIMER_RST_SHIFT) + +/* SCT_RST: Current status of the SCT_RST */ +#define RESET_ACTIVE_STATUS1_SCT_RST_SHIFT (5) +#define RESET_ACTIVE_STATUS1_SCT_RST \ + (1 << RESET_ACTIVE_STATUS1_SCT_RST_SHIFT) + +/* MOTOCONPWM_RST: Current status of the MOTOCONPWM_RST */ +#define RESET_ACTIVE_STATUS1_MOTOCONPWM_RST_SHIFT (6) +#define RESET_ACTIVE_STATUS1_MOTOCONPWM_RST \ + (1 << RESET_ACTIVE_STATUS1_MOTOCONPWM_RST_SHIFT) + +/* QEI_RST: Current status of the QEI_RST */ +#define RESET_ACTIVE_STATUS1_QEI_RST_SHIFT (7) +#define RESET_ACTIVE_STATUS1_QEI_RST \ + (1 << RESET_ACTIVE_STATUS1_QEI_RST_SHIFT) + +/* ADC0_RST: Current status of the ADC0_RST */ +#define RESET_ACTIVE_STATUS1_ADC0_RST_SHIFT (8) +#define RESET_ACTIVE_STATUS1_ADC0_RST \ + (1 << RESET_ACTIVE_STATUS1_ADC0_RST_SHIFT) + +/* ADC1_RST: Current status of the ADC1_RST */ +#define RESET_ACTIVE_STATUS1_ADC1_RST_SHIFT (9) +#define RESET_ACTIVE_STATUS1_ADC1_RST \ + (1 << RESET_ACTIVE_STATUS1_ADC1_RST_SHIFT) + +/* DAC_RST: Current status of the DAC_RST */ +#define RESET_ACTIVE_STATUS1_DAC_RST_SHIFT (10) +#define RESET_ACTIVE_STATUS1_DAC_RST (1 << RESET_ACTIVE_STATUS1_DAC_RST_SHIFT) + +/* UART0_RST: Current status of the UART0_RST */ +#define RESET_ACTIVE_STATUS1_UART0_RST_SHIFT (12) +#define RESET_ACTIVE_STATUS1_UART0_RST \ + (1 << RESET_ACTIVE_STATUS1_UART0_RST_SHIFT) + +/* UART1_RST: Current status of the UART1_RST */ +#define RESET_ACTIVE_STATUS1_UART1_RST_SHIFT (13) +#define RESET_ACTIVE_STATUS1_UART1_RST \ + (1 << RESET_ACTIVE_STATUS1_UART1_RST_SHIFT) + +/* UART2_RST: Current status of the UART2_RST */ +#define RESET_ACTIVE_STATUS1_UART2_RST_SHIFT (14) +#define RESET_ACTIVE_STATUS1_UART2_RST \ + (1 << RESET_ACTIVE_STATUS1_UART2_RST_SHIFT) + +/* UART3_RST: Current status of the UART3_RST */ +#define RESET_ACTIVE_STATUS1_UART3_RST_SHIFT (15) +#define RESET_ACTIVE_STATUS1_UART3_RST \ + (1 << RESET_ACTIVE_STATUS1_UART3_RST_SHIFT) + +/* I2C0_RST: Current status of the I2C0_RST */ +#define RESET_ACTIVE_STATUS1_I2C0_RST_SHIFT (16) +#define RESET_ACTIVE_STATUS1_I2C0_RST \ + (1 << RESET_ACTIVE_STATUS1_I2C0_RST_SHIFT) + +/* I2C1_RST: Current status of the I2C1_RST */ +#define RESET_ACTIVE_STATUS1_I2C1_RST_SHIFT (17) +#define RESET_ACTIVE_STATUS1_I2C1_RST \ + (1 << RESET_ACTIVE_STATUS1_I2C1_RST_SHIFT) + +/* SSP0_RST: Current status of the SSP0_RST */ +#define RESET_ACTIVE_STATUS1_SSP0_RST_SHIFT (18) +#define RESET_ACTIVE_STATUS1_SSP0_RST \ + (1 << RESET_ACTIVE_STATUS1_SSP0_RST_SHIFT) + +/* SSP1_RST: Current status of the SSP1_RST */ +#define RESET_ACTIVE_STATUS1_SSP1_RST_SHIFT (19) +#define RESET_ACTIVE_STATUS1_SSP1_RST \ + (1 << RESET_ACTIVE_STATUS1_SSP1_RST_SHIFT) + +/* I2S_RST: Current status of the I2S_RST */ +#define RESET_ACTIVE_STATUS1_I2S_RST_SHIFT (20) +#define RESET_ACTIVE_STATUS1_I2S_RST (1 << RESET_ACTIVE_STATUS1_I2S_RST_SHIFT) + +/* SPIFI_RST: Current status of the SPIFI_RST */ +#define RESET_ACTIVE_STATUS1_SPIFI_RST_SHIFT (21) +#define RESET_ACTIVE_STATUS1_SPIFI_RST \ + (1 << RESET_ACTIVE_STATUS1_SPIFI_RST_SHIFT) + +/* CAN1_RST: Current status of the CAN1_RST */ +#define RESET_ACTIVE_STATUS1_CAN1_RST_SHIFT (22) +#define RESET_ACTIVE_STATUS1_CAN1_RST \ + (1 << RESET_ACTIVE_STATUS1_CAN1_RST_SHIFT) + +/* CAN0_RST: Current status of the CAN0_RST */ +#define RESET_ACTIVE_STATUS1_CAN0_RST_SHIFT (23) +#define RESET_ACTIVE_STATUS1_CAN0_RST \ + (1 << RESET_ACTIVE_STATUS1_CAN0_RST_SHIFT) + +/* M0APP_RST: Current status of the M0APP_RST */ +#define RESET_ACTIVE_STATUS1_M0APP_RST_SHIFT (24) +#define RESET_ACTIVE_STATUS1_M0APP_RST \ + (1 << RESET_ACTIVE_STATUS1_M0APP_RST_SHIFT) + +/* SGPIO_RST: Current status of the SGPIO_RST */ +#define RESET_ACTIVE_STATUS1_SGPIO_RST_SHIFT (25) +#define RESET_ACTIVE_STATUS1_SGPIO_RST \ + (1 << RESET_ACTIVE_STATUS1_SGPIO_RST_SHIFT) + +/* SPI_RST: Current status of the SPI_RST */ +#define RESET_ACTIVE_STATUS1_SPI_RST_SHIFT (26) +#define RESET_ACTIVE_STATUS1_SPI_RST (1 << RESET_ACTIVE_STATUS1_SPI_RST_SHIFT) + +/* --- RESET_EXT_STAT0 values ----------------------------------- */ + +/* EXT_RESET: Reset activated by external reset from reset pin */ +#define RESET_EXT_STAT0_EXT_RESET_SHIFT (0) +#define RESET_EXT_STAT0_EXT_RESET (1 << RESET_EXT_STAT0_EXT_RESET_SHIFT) + +/* BOD_RESET: Reset activated by BOD reset */ +#define RESET_EXT_STAT0_BOD_RESET_SHIFT (4) +#define RESET_EXT_STAT0_BOD_RESET (1 << RESET_EXT_STAT0_BOD_RESET_SHIFT) + +/* WWDT_RESET: Reset activated by WWDT time-out */ +#define RESET_EXT_STAT0_WWDT_RESET_SHIFT (5) +#define RESET_EXT_STAT0_WWDT_RESET (1 << RESET_EXT_STAT0_WWDT_RESET_SHIFT) + +/* --- RESET_EXT_STAT1 values ----------------------------------- */ + +/* CORE_RESET: Reset activated by CORE_RST output */ +#define RESET_EXT_STAT1_CORE_RESET_SHIFT (1) +#define RESET_EXT_STAT1_CORE_RESET (1 << RESET_EXT_STAT1_CORE_RESET_SHIFT) + +/* --- RESET_EXT_STAT2 values ----------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT2_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT2_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT2_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT4 values ----------------------------------- */ + +/* CORE_RESET: Reset activated by CORE_RST output */ +#define RESET_EXT_STAT4_CORE_RESET_SHIFT (1) +#define RESET_EXT_STAT4_CORE_RESET (1 << RESET_EXT_STAT4_CORE_RESET_SHIFT) + +/* --- RESET_EXT_STAT5 values ----------------------------------- */ + +/* CORE_RESET: Reset activated by CORE_RST output */ +#define RESET_EXT_STAT5_CORE_RESET_SHIFT (1) +#define RESET_EXT_STAT5_CORE_RESET (1 << RESET_EXT_STAT5_CORE_RESET_SHIFT) + +/* --- RESET_EXT_STAT8 values ----------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT8_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT8_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT8_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT9 values ----------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT9_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT9_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT9_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT13 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT13_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT13_MASTER_RESET (1 << RESET_EXT_STAT13_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT16 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT16_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT16_MASTER_RESET (1 << RESET_EXT_STAT16_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT17 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT17_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT17_MASTER_RESET (1 << RESET_EXT_STAT17_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT18 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT18_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT18_MASTER_RESET (1 << RESET_EXT_STAT18_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT19 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT19_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT19_MASTER_RESET (1 << RESET_EXT_STAT19_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT20 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT20_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT20_MASTER_RESET (1 << RESET_EXT_STAT20_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT21 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT21_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT21_MASTER_RESET (1 << RESET_EXT_STAT21_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT22 values ---------------------------------- */ + +/* MASTER_RESET: Reset activated by MASTER_RST output */ +#define RESET_EXT_STAT22_MASTER_RESET_SHIFT (3) +#define RESET_EXT_STAT22_MASTER_RESET (1 << RESET_EXT_STAT22_MASTER_RESET_SHIFT) + +/* --- RESET_EXT_STAT25 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT25_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT25_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT25_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT27 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT27_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT27_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT27_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT28 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT28_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT28_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT28_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT29 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT29_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT29_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT29_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT32 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT32_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT32_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT32_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT33 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT33_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT33_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT33_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT34 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT34_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT34_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT34_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT35 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT35_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT35_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT35_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT36 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT36_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT36_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT36_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT37 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT37_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT37_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT37_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT38 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT38_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT38_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT38_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT39 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT39_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT39_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT39_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT40 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT40_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT40_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT40_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT41 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT41_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT41_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT41_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT42 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT42_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT42_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT42_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT44 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT44_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT44_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT44_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT45 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT45_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT45_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT45_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT46 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT46_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT46_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT46_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT47 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT47_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT47_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT47_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT48 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT48_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT48_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT48_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT49 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT49_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT49_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT49_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT50 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT50_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT50_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT50_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT51 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT51_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT51_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT51_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT52 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT52_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT52_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT52_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT53 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT53_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT53_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT53_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT54 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT54_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT54_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT54_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT55 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT55_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT55_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT55_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT56 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT56_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT56_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT56_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT57 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT57_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT57_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT57_PERIPHERAL_RESET_SHIFT) + +/* --- RESET_EXT_STAT58 values ---------------------------------- */ + +/* PERIPHERAL_RESET: Reset activated by PERIPHERAL_RST output */ +#define RESET_EXT_STAT58_PERIPHERAL_RESET_SHIFT (2) +#define RESET_EXT_STAT58_PERIPHERAL_RESET \ + (1 << RESET_EXT_STAT58_PERIPHERAL_RESET_SHIFT) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ritimer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ritimer.h new file mode 100644 index 00000000..e736bc30 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ritimer.h @@ -0,0 +1,59 @@ +/** @defgroup ritimer_defines Repetitive Interrupt Timer Defines + +@brief Defined Constants and Types for the LPC43xx Repetitive Interrupt +Timer + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_RITIMER_H +#define LPC43XX_RITIMER_H + +/**@{*/ + +#include +#include + +/* --- Repetitive Interrupt Timer registers -------------------------------- */ + +/* Compare register */ +#define RITIMER_COMPVAL MMIO32(RITIMER_BASE + 0x000) + +/* Mask register */ +#define RITIMER_MASK MMIO32(RITIMER_BASE + 0x004) + +/* Control register */ +#define RITIMER_CTRL MMIO32(RITIMER_BASE + 0x008) + +/* 32-bit counter */ +#define RITIMER_COUNTER MMIO32(RITIMER_BASE + 0x00C) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/scu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/scu.h new file mode 100644 index 00000000..548ac888 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/scu.h @@ -0,0 +1,780 @@ +/** @defgroup scu_defines System Control Unit Defines + +@brief Defined Constants and Types for the LPC43xx System Control Unit + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Michael Ossmann +* Copyright (C) 2012 Benjamin Vernoux +* +* This library is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This library 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this library. If not, see . +*/ + +#ifndef LPC43XX_SCU_H +#define LPC43XX_SCU_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* Pin group base addresses */ +#define PIN_GROUP0 (SCU_BASE + 0x000) +#define PIN_GROUP1 (SCU_BASE + 0x080) +#define PIN_GROUP2 (SCU_BASE + 0x100) +#define PIN_GROUP3 (SCU_BASE + 0x180) +#define PIN_GROUP4 (SCU_BASE + 0x200) +#define PIN_GROUP5 (SCU_BASE + 0x280) +#define PIN_GROUP6 (SCU_BASE + 0x300) +#define PIN_GROUP7 (SCU_BASE + 0x380) +#define PIN_GROUP8 (SCU_BASE + 0x400) +#define PIN_GROUP9 (SCU_BASE + 0x480) +#define PIN_GROUPA (SCU_BASE + 0x500) +#define PIN_GROUPB (SCU_BASE + 0x580) +#define PIN_GROUPC (SCU_BASE + 0x600) +#define PIN_GROUPD (SCU_BASE + 0x680) +#define PIN_GROUPE (SCU_BASE + 0x700) +#define PIN_GROUPF (SCU_BASE + 0x780) + +#define PIN0 0x000 +#define PIN1 0x004 +#define PIN2 0x008 +#define PIN3 0x00C +#define PIN4 0x010 +#define PIN5 0x014 +#define PIN6 0x018 +#define PIN7 0x01C +#define PIN8 0x020 +#define PIN9 0x024 +#define PIN10 0x028 +#define PIN11 0x02C +#define PIN12 0x030 +#define PIN13 0x034 +#define PIN14 0x038 +#define PIN15 0x03C +#define PIN16 0x040 +#define PIN17 0x044 +#define PIN18 0x048 +#define PIN19 0x04C +#define PIN20 0x050 + + +/* --- SCU registers ------------------------------------------------------- */ + +/* Pin configuration registers */ + +#define SCU_SFS(group, pin) MMIO32((group) + (pin)) + +/* Pins P0_n */ +#define SCU_SFSP0_0 SCU_SFS(PIN_GROUP0, PIN0) +#define SCU_SFSP0_1 SCU_SFS(PIN_GROUP0, PIN1) + +/* Pins P1_n */ +#define SCU_SFSP1_0 SCU_SFS(PIN_GROUP1, PIN0) +#define SCU_SFSP1_1 SCU_SFS(PIN_GROUP1, PIN1) +#define SCU_SFSP1_2 SCU_SFS(PIN_GROUP1, PIN2) +#define SCU_SFSP1_3 SCU_SFS(PIN_GROUP1, PIN3) +#define SCU_SFSP1_4 SCU_SFS(PIN_GROUP1, PIN4) +#define SCU_SFSP1_5 SCU_SFS(PIN_GROUP1, PIN5) +#define SCU_SFSP1_6 SCU_SFS(PIN_GROUP1, PIN6) +#define SCU_SFSP1_7 SCU_SFS(PIN_GROUP1, PIN7) +#define SCU_SFSP1_8 SCU_SFS(PIN_GROUP1, PIN8) +#define SCU_SFSP1_9 SCU_SFS(PIN_GROUP1, PIN9) +#define SCU_SFSP1_10 SCU_SFS(PIN_GROUP1, PIN10) +#define SCU_SFSP1_11 SCU_SFS(PIN_GROUP1, PIN11) +#define SCU_SFSP1_12 SCU_SFS(PIN_GROUP1, PIN12) +#define SCU_SFSP1_13 SCU_SFS(PIN_GROUP1, PIN13) +#define SCU_SFSP1_14 SCU_SFS(PIN_GROUP1, PIN14) +#define SCU_SFSP1_15 SCU_SFS(PIN_GROUP1, PIN15) +#define SCU_SFSP1_16 SCU_SFS(PIN_GROUP1, PIN16) +#define SCU_SFSP1_17 SCU_SFS(PIN_GROUP1, PIN17) +#define SCU_SFSP1_18 SCU_SFS(PIN_GROUP1, PIN18) +#define SCU_SFSP1_19 SCU_SFS(PIN_GROUP1, PIN19) +#define SCU_SFSP1_20 SCU_SFS(PIN_GROUP1, PIN20) + +/* Pins P2_n */ +#define SCU_SFSP2_0 SCU_SFS(PIN_GROUP2, PIN0) +#define SCU_SFSP2_1 SCU_SFS(PIN_GROUP2, PIN1) +#define SCU_SFSP2_2 SCU_SFS(PIN_GROUP2, PIN2) +#define SCU_SFSP2_3 SCU_SFS(PIN_GROUP2, PIN3) +#define SCU_SFSP2_4 SCU_SFS(PIN_GROUP2, PIN4) +#define SCU_SFSP2_5 SCU_SFS(PIN_GROUP2, PIN5) +#define SCU_SFSP2_6 SCU_SFS(PIN_GROUP2, PIN6) +#define SCU_SFSP2_7 SCU_SFS(PIN_GROUP2, PIN7) +#define SCU_SFSP2_8 SCU_SFS(PIN_GROUP2, PIN8) +#define SCU_SFSP2_9 SCU_SFS(PIN_GROUP2, PIN9) +#define SCU_SFSP2_10 SCU_SFS(PIN_GROUP2, PIN10) +#define SCU_SFSP2_11 SCU_SFS(PIN_GROUP2, PIN11) +#define SCU_SFSP2_12 SCU_SFS(PIN_GROUP2, PIN12) +#define SCU_SFSP2_13 SCU_SFS(PIN_GROUP2, PIN13) + +/* Pins P3_n */ +#define SCU_SFSP3_0 SCU_SFS(PIN_GROUP3, PIN0) +#define SCU_SFSP3_1 SCU_SFS(PIN_GROUP3, PIN1) +#define SCU_SFSP3_2 SCU_SFS(PIN_GROUP3, PIN2) +#define SCU_SFSP3_3 SCU_SFS(PIN_GROUP3, PIN3) +#define SCU_SFSP3_4 SCU_SFS(PIN_GROUP3, PIN4) +#define SCU_SFSP3_5 SCU_SFS(PIN_GROUP3, PIN5) +#define SCU_SFSP3_6 SCU_SFS(PIN_GROUP3, PIN6) +#define SCU_SFSP3_7 SCU_SFS(PIN_GROUP3, PIN7) +#define SCU_SFSP3_8 SCU_SFS(PIN_GROUP3, PIN8) + +/* Pins P4_n */ +#define SCU_SFSP4_0 SCU_SFS(PIN_GROUP4, PIN0) +#define SCU_SFSP4_1 SCU_SFS(PIN_GROUP4, PIN1) +#define SCU_SFSP4_2 SCU_SFS(PIN_GROUP4, PIN2) +#define SCU_SFSP4_3 SCU_SFS(PIN_GROUP4, PIN3) +#define SCU_SFSP4_4 SCU_SFS(PIN_GROUP4, PIN4) +#define SCU_SFSP4_5 SCU_SFS(PIN_GROUP4, PIN5) +#define SCU_SFSP4_6 SCU_SFS(PIN_GROUP4, PIN6) +#define SCU_SFSP4_7 SCU_SFS(PIN_GROUP4, PIN7) +#define SCU_SFSP4_8 SCU_SFS(PIN_GROUP4, PIN8) +#define SCU_SFSP4_9 SCU_SFS(PIN_GROUP4, PIN9) +#define SCU_SFSP4_10 SCU_SFS(PIN_GROUP4, PIN10) + +/* Pins P5_n */ +#define SCU_SFSP5_0 SCU_SFS(PIN_GROUP5, PIN0) +#define SCU_SFSP5_1 SCU_SFS(PIN_GROUP5, PIN1) +#define SCU_SFSP5_2 SCU_SFS(PIN_GROUP5, PIN2) +#define SCU_SFSP5_3 SCU_SFS(PIN_GROUP5, PIN3) +#define SCU_SFSP5_4 SCU_SFS(PIN_GROUP5, PIN4) +#define SCU_SFSP5_5 SCU_SFS(PIN_GROUP5, PIN5) +#define SCU_SFSP5_6 SCU_SFS(PIN_GROUP5, PIN6) +#define SCU_SFSP5_7 SCU_SFS(PIN_GROUP5, PIN7) + +/* Pins P6_n */ +#define SCU_SFSP6_0 SCU_SFS(PIN_GROUP6, PIN0) +#define SCU_SFSP6_1 SCU_SFS(PIN_GROUP6, PIN1) +#define SCU_SFSP6_2 SCU_SFS(PIN_GROUP6, PIN2) +#define SCU_SFSP6_3 SCU_SFS(PIN_GROUP6, PIN3) +#define SCU_SFSP6_4 SCU_SFS(PIN_GROUP6, PIN4) +#define SCU_SFSP6_5 SCU_SFS(PIN_GROUP6, PIN5) +#define SCU_SFSP6_6 SCU_SFS(PIN_GROUP6, PIN6) +#define SCU_SFSP6_7 SCU_SFS(PIN_GROUP6, PIN7) +#define SCU_SFSP6_8 SCU_SFS(PIN_GROUP6, PIN8) +#define SCU_SFSP6_9 SCU_SFS(PIN_GROUP6, PIN9) +#define SCU_SFSP6_10 SCU_SFS(PIN_GROUP6, PIN10) +#define SCU_SFSP6_11 SCU_SFS(PIN_GROUP6, PIN11) +#define SCU_SFSP6_12 SCU_SFS(PIN_GROUP6, PIN12) + +/* Pins P7_n */ +#define SCU_SFSP7_0 SCU_SFS(PIN_GROUP7, PIN0) +#define SCU_SFSP7_1 SCU_SFS(PIN_GROUP7, PIN1) +#define SCU_SFSP7_2 SCU_SFS(PIN_GROUP7, PIN2) +#define SCU_SFSP7_3 SCU_SFS(PIN_GROUP7, PIN3) +#define SCU_SFSP7_4 SCU_SFS(PIN_GROUP7, PIN4) +#define SCU_SFSP7_5 SCU_SFS(PIN_GROUP7, PIN5) +#define SCU_SFSP7_6 SCU_SFS(PIN_GROUP7, PIN6) +#define SCU_SFSP7_7 SCU_SFS(PIN_GROUP7, PIN7) + +/* Pins P8_n */ +#define SCU_SFSP8_0 SCU_SFS(PIN_GROUP8, PIN0) +#define SCU_SFSP8_1 SCU_SFS(PIN_GROUP8, PIN1) +#define SCU_SFSP8_2 SCU_SFS(PIN_GROUP8, PIN2) +#define SCU_SFSP8_3 SCU_SFS(PIN_GROUP8, PIN3) +#define SCU_SFSP8_4 SCU_SFS(PIN_GROUP8, PIN4) +#define SCU_SFSP8_5 SCU_SFS(PIN_GROUP8, PIN5) +#define SCU_SFSP8_6 SCU_SFS(PIN_GROUP8, PIN6) +#define SCU_SFSP8_7 SCU_SFS(PIN_GROUP8, PIN7) +#define SCU_SFSP8_8 SCU_SFS(PIN_GROUP8, PIN8) + +/* Pins P9_n */ +#define SCU_SFSP9_0 SCU_SFS(PIN_GROUP9, PIN0) +#define SCU_SFSP9_1 SCU_SFS(PIN_GROUP9, PIN1) +#define SCU_SFSP9_2 SCU_SFS(PIN_GROUP9, PIN2) +#define SCU_SFSP9_3 SCU_SFS(PIN_GROUP9, PIN3) +#define SCU_SFSP9_4 SCU_SFS(PIN_GROUP9, PIN4) +#define SCU_SFSP9_5 SCU_SFS(PIN_GROUP9, PIN5) +#define SCU_SFSP9_6 SCU_SFS(PIN_GROUP9, PIN6) + +/* Pins PA_n */ +#define SCU_SFSPA_0 SCU_SFS(PIN_GROUPA, PIN0) +#define SCU_SFSPA_1 SCU_SFS(PIN_GROUPA, PIN1) +#define SCU_SFSPA_2 SCU_SFS(PIN_GROUPA, PIN2) +#define SCU_SFSPA_3 SCU_SFS(PIN_GROUPA, PIN3) +#define SCU_SFSPA_4 SCU_SFS(PIN_GROUPA, PIN4) + +/* Pins PB_n */ +#define SCU_SFSPB_0 SCU_SFS(PIN_GROUPB, PIN0) +#define SCU_SFSPB_1 SCU_SFS(PIN_GROUPB, PIN1) +#define SCU_SFSPB_2 SCU_SFS(PIN_GROUPB, PIN2) +#define SCU_SFSPB_3 SCU_SFS(PIN_GROUPB, PIN3) +#define SCU_SFSPB_4 SCU_SFS(PIN_GROUPB, PIN4) +#define SCU_SFSPB_5 SCU_SFS(PIN_GROUPB, PIN5) +#define SCU_SFSPB_6 SCU_SFS(PIN_GROUPB, PIN6) + +/* Pins PC_n */ +#define SCU_SFSPC_0 SCU_SFS(PIN_GROUPC, PIN0) +#define SCU_SFSPC_1 SCU_SFS(PIN_GROUPC, PIN1) +#define SCU_SFSPC_2 SCU_SFS(PIN_GROUPC, PIN2) +#define SCU_SFSPC_3 SCU_SFS(PIN_GROUPC, PIN3) +#define SCU_SFSPC_4 SCU_SFS(PIN_GROUPC, PIN4) +#define SCU_SFSPC_5 SCU_SFS(PIN_GROUPC, PIN5) +#define SCU_SFSPC_6 SCU_SFS(PIN_GROUPC, PIN6) +#define SCU_SFSPC_7 SCU_SFS(PIN_GROUPC, PIN7) +#define SCU_SFSPC_8 SCU_SFS(PIN_GROUPC, PIN8) +#define SCU_SFSPC_9 SCU_SFS(PIN_GROUPC, PIN9) +#define SCU_SFSPC_10 SCU_SFS(PIN_GROUPC, PIN10) +#define SCU_SFSPC_11 SCU_SFS(PIN_GROUPC, PIN11) +#define SCU_SFSPC_12 SCU_SFS(PIN_GROUPC, PIN12) +#define SCU_SFSPC_13 SCU_SFS(PIN_GROUPC, PIN13) +#define SCU_SFSPC_14 SCU_SFS(PIN_GROUPC, PIN14) + +/* Pins PD_n */ +#define SCU_SFSPD_0 SCU_SFS(PIN_GROUPD, PIN0) +#define SCU_SFSPD_1 SCU_SFS(PIN_GROUPD, PIN1) +#define SCU_SFSPD_2 SCU_SFS(PIN_GROUPD, PIN2) +#define SCU_SFSPD_3 SCU_SFS(PIN_GROUPD, PIN3) +#define SCU_SFSPD_4 SCU_SFS(PIN_GROUPD, PIN4) +#define SCU_SFSPD_5 SCU_SFS(PIN_GROUPD, PIN5) +#define SCU_SFSPD_6 SCU_SFS(PIN_GROUPD, PIN6) +#define SCU_SFSPD_7 SCU_SFS(PIN_GROUPD, PIN7) +#define SCU_SFSPD_8 SCU_SFS(PIN_GROUPD, PIN8) +#define SCU_SFSPD_9 SCU_SFS(PIN_GROUPD, PIN9) +#define SCU_SFSPD_10 SCU_SFS(PIN_GROUPD, PIN10) +#define SCU_SFSPD_11 SCU_SFS(PIN_GROUPD, PIN11) +#define SCU_SFSPD_12 SCU_SFS(PIN_GROUPD, PIN12) +#define SCU_SFSPD_13 SCU_SFS(PIN_GROUPD, PIN13) +#define SCU_SFSPD_14 SCU_SFS(PIN_GROUPD, PIN14) +#define SCU_SFSPD_15 SCU_SFS(PIN_GROUPD, PIN15) +#define SCU_SFSPD_16 SCU_SFS(PIN_GROUPD, PIN16) + +/* Pins PE_n */ +#define SCU_SFSPE_0 SCU_SFS(PIN_GROUPE, PIN0) +#define SCU_SFSPE_1 SCU_SFS(PIN_GROUPE, PIN1) +#define SCU_SFSPE_2 SCU_SFS(PIN_GROUPE, PIN2) +#define SCU_SFSPE_3 SCU_SFS(PIN_GROUPE, PIN3) +#define SCU_SFSPE_4 SCU_SFS(PIN_GROUPE, PIN4) +#define SCU_SFSPE_5 SCU_SFS(PIN_GROUPE, PIN5) +#define SCU_SFSPE_6 SCU_SFS(PIN_GROUPE, PIN6) +#define SCU_SFSPE_7 SCU_SFS(PIN_GROUPE, PIN7) +#define SCU_SFSPE_8 SCU_SFS(PIN_GROUPE, PIN8) +#define SCU_SFSPE_9 SCU_SFS(PIN_GROUPE, PIN9) +#define SCU_SFSPE_10 SCU_SFS(PIN_GROUPE, PIN10) +#define SCU_SFSPE_11 SCU_SFS(PIN_GROUPE, PIN11) +#define SCU_SFSPE_12 SCU_SFS(PIN_GROUPE, PIN12) +#define SCU_SFSPE_13 SCU_SFS(PIN_GROUPE, PIN13) +#define SCU_SFSPE_14 SCU_SFS(PIN_GROUPE, PIN14) +#define SCU_SFSPE_15 SCU_SFS(PIN_GROUPE, PIN15) + +/* Pins PF_n */ +#define SCU_SFSPF_0 SCU_SFS(PIN_GROUPF, PIN0) +#define SCU_SFSPF_1 SCU_SFS(PIN_GROUPF, PIN1) +#define SCU_SFSPF_2 SCU_SFS(PIN_GROUPF, PIN2) +#define SCU_SFSPF_3 SCU_SFS(PIN_GROUPF, PIN3) +#define SCU_SFSPF_4 SCU_SFS(PIN_GROUPF, PIN4) +#define SCU_SFSPF_5 SCU_SFS(PIN_GROUPF, PIN5) +#define SCU_SFSPF_6 SCU_SFS(PIN_GROUPF, PIN6) +#define SCU_SFSPF_7 SCU_SFS(PIN_GROUPF, PIN7) +#define SCU_SFSPF_8 SCU_SFS(PIN_GROUPF, PIN8) +#define SCU_SFSPF_9 SCU_SFS(PIN_GROUPF, PIN9) +#define SCU_SFSPF_10 SCU_SFS(PIN_GROUPF, PIN10) +#define SCU_SFSPF_11 SCU_SFS(PIN_GROUPF, PIN11) + +/* CLKn pins */ +#define SCU_SFSCLK0 MMIO32(SCU_BASE + 0xC00) +#define SCU_SFSCLK1 MMIO32(SCU_BASE + 0xC04) +#define SCU_SFSCLK2 MMIO32(SCU_BASE + 0xC08) +#define SCU_SFSCLK3 MMIO32(SCU_BASE + 0xC0C) + +/* USB1 USB1_DP/USB1_DM pins and I2C-bus open-drain pins */ +#define SCU_SFSUSB MMIO32(SCU_BASE + 0xC80) +#define SCU_SFSI2C0 MMIO32(SCU_BASE + 0xC84) + +/* ADC pin select registers */ + +/* ADC0 function select register */ +#define SCU_ENAIO0 MMIO32(SCU_BASE + 0xC88) + +/* ADC1 function select register */ +#define SCU_ENAIO1 MMIO32(SCU_BASE + 0xC8C) + +/* Analog function select register */ +#define SCU_ENAIO2 MMIO32(SCU_BASE + 0xC90) + +/* EMC clock delay register */ +#define SCU_EMCDELAYCLK MMIO32(SCU_BASE + 0xD00) + +/* Pin interrupt select registers */ + +/* Pin interrupt select register for pin interrupts 0 to 3 */ +#define SCU_PINTSEL0 MMIO32(SCU_BASE + 0xE00) + +/* Pin interrupt select register for pin interrupts 4 to 7 */ +#define SCU_PINTSEL1 MMIO32(SCU_BASE + 0xE04) + +/**************************/ +/* SCU I2C0 Configuration */ +/**************************/ +/* +* Select input glitch filter time constant for the SCL pin. +* 0 = 50 ns glitch filter. +* 1 = 3ns glitch filter. +*/ +#define SCU_SCL_EFP (BIT0) + +/* BIT1 Reserved. Always write a 0 to this bit. */ + +/* +* Select I2C mode for the SCL pin. +* 0 = Standard/Fast mode transmit. +* 1 = Fast-mode Plus transmit. +*/ +#define SCU_SCL_EHD (BIT2) + +/* +* Enable the input receiver for the SCL pin. +* Always write a 1 to this bit when using the +* I2C0. +* 0 = Disabled. +* 1 = Enabled. +*/ +#define SCU_SCL_EZI_EN (BIT3) + +/* BIT4-6 Reserved. */ + +/* +* Enable or disable input glitch filter for the +* SCL pin. The filter time constant is +* determined by bit EFP. +* 0 = Enable input filter. +* 1 = Disable input filter. +*/ +#define SCU_SCL_ZIF_DIS (BIT7) + +/* +* Select input glitch filter time constant for the SDA pin. +* 0 = 50 ns glitch filter. +* 1 = 3ns glitch filter. +*/ +#define SCU_SDA_EFP (BIT8) + +/* BIT9 Reserved. Always write a 0 to this bit. */ + +/* +* Select I2C mode for the SDA pin. +* 0 = Standard/Fast mode transmit. +* 1 = Fast-mode Plus transmit. +*/ +#define SCU_SDA_EHD (BIT10) + +/* +* Enable the input receiver for the SDA pin. +* Always write a 1 to this bit when using the +* I2C0. +* 0 = Disabled. +* 1 = Enabled. +*/ +#define SCU_SDA_EZI_EN (BIT11) + +/* BIT 12-14 - Reserved */ + +/* +* Enable or disable input glitch filter for the +* SDA pin. The filter time constant is +* determined by bit SDA_EFP. +* 0 = Enable input filter. +* 1 = Disable input filter. +*/ +#define SCU_SDA_ZIF_DIS (BIT15) + +/* Standard mode for I2C SCL/SDA Standard/Fast mode */ +#define SCU_I2C0_NOMINAL (SCU_SCL_EZI_EN | SCU_SDA_EZI_EN) + +/* Standard mode for I2C SCL/SDA Fast-mode Plus transmit */ +#define SCU_I2C0_FAST (SCU_SCL_EFP | SCU_SCL_EHD | SCU_SCL_EZI_EN | \ + SCU_SCL_ZIF_DIS | SCU_SDA_EFP | SCU_SDA_EHD | \ + SCU_SDA_EZI_EN) + +/* +* SCU PIN Normal Drive: +* The configuration registers for normal-drive pins control the following pins: +* - P0_0 and P0_1 +* - P1_0 to P1_16 and P1_18 to P1_20 +* - P2_0 to P2_2 and P2_6 to P2_13 +* - P3_0 to P3_2 and P3_4 to P3_8 +* - P4_0 to P4_10 +* - P5_0 to P5_7 +* - P6_0 to P6_12 +* - P7_0 to P7_7 +* - P8_3 to P8_8 +* - P9_0 to P9_6 +* - PA_0 and PA_4 +* - PB_0 to PB_6 +* - PC_0 to PC_14 +* - PE_0 to PE_15 +* - PF_0 to PF_11 +* +* Pin configuration registers for High-Drive pins. +* The configuration registers for high-drive pins control the following pins: +* - P1_17 +* - P2_3 to P2_5 +* - P8_0 to P8_2 +* - PA_1 to PA_3 +* +* Pin configuration registers for High-Speed pins. +* This register controls the following pins: +* - P3_3 and pins CLK0 to CLK3. +*/ +typedef enum { + /* Group Port 0 */ + P0_0 = (PIN_GROUP0+PIN0), + P0_1 = (PIN_GROUP0+PIN1), + + /* Group Port 1 */ + P1_0 = (PIN_GROUP1+PIN0), + P1_1 = (PIN_GROUP1+PIN1), + P1_2 = (PIN_GROUP1+PIN2), + P1_3 = (PIN_GROUP1+PIN3), + P1_4 = (PIN_GROUP1+PIN4), + P1_5 = (PIN_GROUP1+PIN5), + P1_6 = (PIN_GROUP1+PIN6), + P1_7 = (PIN_GROUP1+PIN7), + P1_8 = (PIN_GROUP1+PIN8), + P1_9 = (PIN_GROUP1+PIN9), + P1_10 = (PIN_GROUP1+PIN10), + P1_11 = (PIN_GROUP1+PIN11), + P1_12 = (PIN_GROUP1+PIN12), + P1_13 = (PIN_GROUP1+PIN13), + P1_14 = (PIN_GROUP1+PIN14), + P1_15 = (PIN_GROUP1+PIN15), + P1_16 = (PIN_GROUP1+PIN16), + + /* P1_17 is High-Drive pin */ + P1_17 = (PIN_GROUP1+PIN17), + + P1_18 = (PIN_GROUP1+PIN18), + P1_19 = (PIN_GROUP1+PIN19), + P1_20 = (PIN_GROUP1+PIN20), + + /* Group Port 2 */ + P2_0 = (PIN_GROUP2+PIN0), + P2_1 = (PIN_GROUP2+PIN1), + P2_2 = (PIN_GROUP2+PIN2), + + /* P2_3 to P2_5 are High-Drive pins */ + P2_3 = (PIN_GROUP2+PIN3), + P2_4 = (PIN_GROUP2+PIN4), + P2_5 = (PIN_GROUP2+PIN5), + + P2_6 = (PIN_GROUP2+PIN6), + P2_7 = (PIN_GROUP2+PIN7), + P2_8 = (PIN_GROUP2+PIN8), + P2_9 = (PIN_GROUP2+PIN9), + P2_10 = (PIN_GROUP2+PIN10), + P2_11 = (PIN_GROUP2+PIN11), + P2_12 = (PIN_GROUP2+PIN12), + P2_13 = (PIN_GROUP2+PIN13), + + /* Group Port 3 */ + P3_0 = (PIN_GROUP3+PIN0), + P3_1 = (PIN_GROUP3+PIN1), + P3_2 = (PIN_GROUP3+PIN2), + + /* P3_3 is High-Speed pin */ + P3_3 = (PIN_GROUP3+PIN3), + + P3_4 = (PIN_GROUP3+PIN4), + P3_5 = (PIN_GROUP3+PIN5), + P3_6 = (PIN_GROUP3+PIN6), + P3_7 = (PIN_GROUP3+PIN7), + P3_8 = (PIN_GROUP3+PIN8), + + /* Group Port 4 */ + P4_0 = (PIN_GROUP4+PIN0), + P4_1 = (PIN_GROUP4+PIN1), + P4_2 = (PIN_GROUP4+PIN2), + P4_3 = (PIN_GROUP4+PIN3), + P4_4 = (PIN_GROUP4+PIN4), + P4_5 = (PIN_GROUP4+PIN5), + P4_6 = (PIN_GROUP4+PIN6), + P4_7 = (PIN_GROUP4+PIN7), + P4_8 = (PIN_GROUP4+PIN8), + P4_9 = (PIN_GROUP4+PIN9), + P4_10 = (PIN_GROUP4+PIN10), + + /* Group Port 5 */ + P5_0 = (PIN_GROUP5+PIN0), + P5_1 = (PIN_GROUP5+PIN1), + P5_2 = (PIN_GROUP5+PIN2), + P5_3 = (PIN_GROUP5+PIN3), + P5_4 = (PIN_GROUP5+PIN4), + P5_5 = (PIN_GROUP5+PIN5), + P5_6 = (PIN_GROUP5+PIN6), + P5_7 = (PIN_GROUP5+PIN7), + + /* Group Port 6 */ + P6_0 = (PIN_GROUP6+PIN0), + P6_1 = (PIN_GROUP6+PIN1), + P6_2 = (PIN_GROUP6+PIN2), + P6_3 = (PIN_GROUP6+PIN3), + P6_4 = (PIN_GROUP6+PIN4), + P6_5 = (PIN_GROUP6+PIN5), + P6_6 = (PIN_GROUP6+PIN6), + P6_7 = (PIN_GROUP6+PIN7), + P6_8 = (PIN_GROUP6+PIN8), + P6_9 = (PIN_GROUP6+PIN9), + P6_10 = (PIN_GROUP6+PIN10), + P6_11 = (PIN_GROUP6+PIN11), + P6_12 = (PIN_GROUP6+PIN12), + + /* Group Port 7 */ + P7_0 = (PIN_GROUP7+PIN0), + P7_1 = (PIN_GROUP7+PIN1), + P7_2 = (PIN_GROUP7+PIN2), + P7_3 = (PIN_GROUP7+PIN3), + P7_4 = (PIN_GROUP7+PIN4), + P7_5 = (PIN_GROUP7+PIN5), + P7_6 = (PIN_GROUP7+PIN6), + P7_7 = (PIN_GROUP7+PIN7), + + /* Group Port 8 */ + /* P8_0 to P8_2 are High-Drive pins */ + P8_0 = (PIN_GROUP8+PIN0), + P8_1 = (PIN_GROUP8+PIN1), + P8_2 = (PIN_GROUP8+PIN2), + + P8_3 = (PIN_GROUP8+PIN3), + P8_4 = (PIN_GROUP8+PIN4), + P8_5 = (PIN_GROUP8+PIN5), + P8_6 = (PIN_GROUP8+PIN6), + P8_7 = (PIN_GROUP8+PIN7), + P8_8 = (PIN_GROUP8+PIN8), + + /* Group Port 9 */ + P9_0 = (PIN_GROUP9+PIN0), + P9_1 = (PIN_GROUP9+PIN1), + P9_2 = (PIN_GROUP9+PIN2), + P9_3 = (PIN_GROUP9+PIN3), + P9_4 = (PIN_GROUP9+PIN4), + P9_5 = (PIN_GROUP9+PIN5), + P9_6 = (PIN_GROUP9+PIN6), + + /* Group Port A */ + PA_0 = (PIN_GROUPA+PIN0), + /* PA_1 to PA_3 are Normal & High-Drive Pins */ + PA_1 = (PIN_GROUPA+PIN1), + PA_2 = (PIN_GROUPA+PIN2), + PA_3 = (PIN_GROUPA+PIN3), + PA_4 = (PIN_GROUPA+PIN4), + + /* Group Port B */ + PB_0 = (PIN_GROUPB+PIN0), + PB_1 = (PIN_GROUPB+PIN1), + PB_2 = (PIN_GROUPB+PIN2), + PB_3 = (PIN_GROUPB+PIN3), + PB_4 = (PIN_GROUPB+PIN4), + PB_5 = (PIN_GROUPB+PIN5), + PB_6 = (PIN_GROUPB+PIN6), + + /* Group Port C */ + PC_0 = (PIN_GROUPC+PIN0), + PC_1 = (PIN_GROUPC+PIN1), + PC_2 = (PIN_GROUPC+PIN2), + PC_3 = (PIN_GROUPC+PIN3), + PC_4 = (PIN_GROUPC+PIN4), + PC_5 = (PIN_GROUPC+PIN5), + PC_6 = (PIN_GROUPC+PIN6), + PC_7 = (PIN_GROUPC+PIN7), + PC_8 = (PIN_GROUPC+PIN8), + PC_9 = (PIN_GROUPC+PIN9), + PC_10 = (PIN_GROUPC+PIN10), + PC_11 = (PIN_GROUPC+PIN11), + PC_12 = (PIN_GROUPC+PIN12), + PC_13 = (PIN_GROUPC+PIN13), + PC_14 = (PIN_GROUPC+PIN14), + + /* Group Port D (seems not configurable through SCU, not defined in + * UM10503.pdf Rev.1, keep it here) + */ + PD_0 = (PIN_GROUPD+PIN0), + PD_1 = (PIN_GROUPD+PIN1), + PD_2 = (PIN_GROUPD+PIN2), + PD_3 = (PIN_GROUPD+PIN3), + PD_4 = (PIN_GROUPD+PIN4), + PD_5 = (PIN_GROUPD+PIN5), + PD_6 = (PIN_GROUPD+PIN6), + PD_7 = (PIN_GROUPD+PIN7), + PD_8 = (PIN_GROUPD+PIN8), + PD_9 = (PIN_GROUPD+PIN9), + PD_10 = (PIN_GROUPD+PIN10), + PD_11 = (PIN_GROUPD+PIN11), + PD_12 = (PIN_GROUPD+PIN12), + PD_13 = (PIN_GROUPD+PIN13), + PD_14 = (PIN_GROUPD+PIN14), + PD_15 = (PIN_GROUPD+PIN15), + PD_16 = (PIN_GROUPD+PIN16), + + /* Group Port E */ + PE_0 = (PIN_GROUPE+PIN0), + PE_1 = (PIN_GROUPE+PIN1), + PE_2 = (PIN_GROUPE+PIN2), + PE_3 = (PIN_GROUPE+PIN3), + PE_4 = (PIN_GROUPE+PIN4), + PE_5 = (PIN_GROUPE+PIN5), + PE_6 = (PIN_GROUPE+PIN6), + PE_7 = (PIN_GROUPE+PIN7), + PE_8 = (PIN_GROUPE+PIN8), + PE_9 = (PIN_GROUPE+PIN9), + PE_10 = (PIN_GROUPE+PIN10), + PE_11 = (PIN_GROUPE+PIN11), + PE_12 = (PIN_GROUPE+PIN12), + PE_13 = (PIN_GROUPE+PIN13), + PE_14 = (PIN_GROUPE+PIN14), + PE_15 = (PIN_GROUPE+PIN15), + + /* Group Port F */ + PF_0 = (PIN_GROUPF+PIN0), + PF_1 = (PIN_GROUPF+PIN1), + PF_2 = (PIN_GROUPF+PIN2), + PF_3 = (PIN_GROUPF+PIN3), + PF_4 = (PIN_GROUPF+PIN4), + PF_5 = (PIN_GROUPF+PIN5), + PF_6 = (PIN_GROUPF+PIN6), + PF_7 = (PIN_GROUPF+PIN7), + PF_8 = (PIN_GROUPF+PIN8), + PF_9 = (PIN_GROUPF+PIN9), + PF_10 = (PIN_GROUPF+PIN10), + PF_11 = (PIN_GROUPF+PIN11), + + /* Group Clock 0 to 3 High-Speed pins */ + CLK0 = (SCU_BASE + 0xC00), + CLK1 = (SCU_BASE + 0xC04), + CLK2 = (SCU_BASE + 0xC08), + CLK3 = (SCU_BASE + 0xC0C) + +} scu_grp_pin_t; + +/* +* Pin Configuration to be used for scu_pinmux() parameter scu_conf +* For normal-drive pins, high-drive pins, high-speed pins +*/ +/* +* Function BIT0 to 2. +* Common to normal-drive pins, high-drive pins, high-speed pins. +*/ +#define SCU_CONF_FUNCTION0 (0x0) +#define SCU_CONF_FUNCTION1 (0x1) +#define SCU_CONF_FUNCTION2 (0x2) +#define SCU_CONF_FUNCTION3 (0x3) +#define SCU_CONF_FUNCTION4 (0x4) +#define SCU_CONF_FUNCTION5 (0x5) +#define SCU_CONF_FUNCTION6 (0x6) +#define SCU_CONF_FUNCTION7 (0x7) + +/* +* Enable pull-down resistor at pad +* By default=0 Disable pull-down. +* Available to normal-drive pins, high-drive pins, high-speed pins +*/ +#define SCU_CONF_EPD_EN_PULLDOWN (BIT3) + +/* +* Disable pull-up resistor at pad. +* By default=0 the pull-up resistor is enabled at reset. +* Available to normal-drive pins, high-drive pins, high-speed pins +*/ +#define SCU_CONF_EPUN_DIS_PULLUP (BIT4) + +/* +* Select Slew Rate. +* By Default=0 Slow. +* Available to normal-drive and high-speed pins, reserved for high-drive pins. +*/ +#define SCU_CONF_EHS_FAST (BIT5) + +/* +* Input buffer enable. +* By Default=0 Disable Input Buffer. +* The input buffer is disabled by default at reset and must be enabled for +* receiving(in normal/highspeed-drive) or to transfer data from the I/O buffer +* to the pad(in high-drive pins). +* Available to normal-drive pins, high-drive pins, high-speed pins. +*/ +#define SCU_CONF_EZI_EN_IN_BUFFER (BIT6) + +/* +* Input glitch filter. Disable the input glitch filter for clocking signals +* higher than 30 MHz. +* Available to normal-drive pins, high-drive pins, high-speed pins. +*/ +#define SCU_CONF_ZIF_DIS_IN_GLITCH_FILT (BIT7) + +/* +* Select drive strength. (default=0 Normal-drive: 4 mA drive strength) (BIT8/9). +* Available to high-drive pins, reserved for others. +*/ +#define SCU_CONF_EHD_NORMAL_DRIVE_8MILLIA (0x100) +#define SCU_CONF_EHD_NORMAL_DRIVE_14MILLIA (0x200) +#define SCU_CONF_EHD_NORMAL_DRIVE_20MILLIA (0x300) + +/* BIT10 to 31 are Reserved */ + +/* Configuration for different I/O pins types */ +#define SCU_EMC_IO (SCU_CONF_EPD_EN_PULLDOWN | \ + SCU_CONF_EHS_FAST | \ + SCU_CONF_EZI_EN_IN_BUFFER | \ + SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_LCD (SCU_CONF_EPUN_DIS_PULLUP | \ + SCU_CONF_EHS_FAST | \ + SCU_CONF_EZI_EN_IN_BUFFER | \ + SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_CLK_IN (SCU_CONF_EPD_EN_PULLDOWN | \ + SCU_CONF_EHS_FAST | \ + SCU_CONF_EZI_EN_IN_BUFFER | \ + SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_CLK_OUT (SCU_CONF_EPD_EN_PULLDOWN | \ + SCU_CONF_EHS_FAST | \ + SCU_CONF_EZI_EN_IN_BUFFER | \ + SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_GPIO_PUP (SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_GPIO_PDN (SCU_CONF_EPUN_DIS_PULLUP | \ + SCU_CONF_EPD_EN_PULLDOWN | \ + SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_GPIO_NOPULL (SCU_CONF_EPUN_DIS_PULLUP | \ + SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_GPIO_FAST (SCU_CONF_EPUN_DIS_PULLUP | \ + SCU_CONF_EHS_FAST | \ + SCU_CONF_EZI_EN_IN_BUFFER | \ + SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_UART_RX_TX (SCU_CONF_EPUN_DIS_PULLUP | \ + SCU_CONF_EPD_EN_PULLDOWN | \ + SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_SSP_IO (SCU_CONF_EPUN_DIS_PULLUP | \ + SCU_CONF_EHS_FAST | \ + SCU_CONF_EZI_EN_IN_BUFFER | \ + SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) + +BEGIN_DECLS + +void scu_pinmux(scu_grp_pin_t group_pin, uint32_t scu_conf); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sdio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sdio.h new file mode 100644 index 00000000..164dda47 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sdio.h @@ -0,0 +1,151 @@ +/** @defgroup sdio_defines SDIO + +@brief Defined Constants and Types for the LPC43xx SDIO + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_SDIO_H +#define LPC43XX_SDIO_H + +/**@{*/ + +#include +#include + +/* --- SDIO registers ----------------------------------------------------- */ + +/* Control Register */ +#define SDIO_CTRL MMIO32(SDIO_BASE + 0x000) + +/* Power Enable Register */ +#define SDIO_PWREN MMIO32(SDIO_BASE + 0x004) + +/* Clock Divider Register */ +#define SDIO_CLKDIV MMIO32(SDIO_BASE + 0x008) + +/* SD Clock Source Register */ +#define SDIO_CLKSRC MMIO32(SDIO_BASE + 0x00C) + +/* Clock Enable Register */ +#define SDIO_CLKENA MMIO32(SDIO_BASE + 0x010) + +/* Time-out Register */ +#define SDIO_TMOUT MMIO32(SDIO_BASE + 0x014) + +/* Card Type Register */ +#define SDIO_CTYPE MMIO32(SDIO_BASE + 0x018) + +/* Block Size Register */ +#define SDIO_BLKSIZ MMIO32(SDIO_BASE + 0x01C) + +/* Byte Count Register */ +#define SDIO_BYTCNT MMIO32(SDIO_BASE + 0x020) + +/* Interrupt Mask Register */ +#define SDIO_INTMASK MMIO32(SDIO_BASE + 0x024) + +/* Command Argument Register */ +#define SDIO_CMDARG MMIO32(SDIO_BASE + 0x028) + +/* Command Register */ +#define SDIO_CMD MMIO32(SDIO_BASE + 0x02C) + +/* Response Register 0 */ +#define SDIO_RESP0 MMIO32(SDIO_BASE + 0x030) + +/* Response Register 1 */ +#define SDIO_RESP1 MMIO32(SDIO_BASE + 0x034) + +/* Response Register 2 */ +#define SDIO_RESP2 MMIO32(SDIO_BASE + 0x038) + +/* Response Register 3 */ +#define SDIO_RESP3 MMIO32(SDIO_BASE + 0x03C) + +/* Masked Interrupt Status Register */ +#define SDIO_MINTSTS MMIO32(SDIO_BASE + 0x040) + +/* Raw Interrupt Status Register */ +#define SDIO_RINTSTS MMIO32(SDIO_BASE + 0x044) + +/* Status Register */ +#define SDIO_STATUS MMIO32(SDIO_BASE + 0x048) + +/* FIFO Threshold Watermark Register */ +#define SDIO_FIFOTH MMIO32(SDIO_BASE + 0x04C) + +/* Card Detect Register */ +#define SDIO_CDETECT MMIO32(SDIO_BASE + 0x050) + +/* Write Protect Register */ +#define SDIO_WRTPRT MMIO32(SDIO_BASE + 0x054) + +/* Transferred CIU Card Byte Count Register */ +#define SDIO_TCBCNT MMIO32(SDIO_BASE + 0x05C) + +/* Transferred Host to BIU-FIFO Byte Count Register */ +#define SDIO_TBBCNT MMIO32(SDIO_BASE + 0x060) + +/* Debounce Count Register */ +#define SDIO_DEBNCE MMIO32(SDIO_BASE + 0x064) + +/* UHS-1 Register */ +#define SDIO_UHS_REG MMIO32(SDIO_BASE + 0x074) + +/* Hardware Reset */ +#define SDIO_RST_N MMIO32(SDIO_BASE + 0x078) + +/* Bus Mode Register */ +#define SDIO_BMOD MMIO32(SDIO_BASE + 0x080) + +/* Poll Demand Register */ +#define SDIO_PLDMND MMIO32(SDIO_BASE + 0x084) + +/* Descriptor List Base Address Register */ +#define SDIO_DBADDR MMIO32(SDIO_BASE + 0x088) + +/* Internal DMAC Status Register */ +#define SDIO_IDSTS MMIO32(SDIO_BASE + 0x08C) + +/* Internal DMAC Interrupt Enable Register */ +#define SDIO_IDINTEN MMIO32(SDIO_BASE + 0x090) + +/* Current Host Descriptor Address Register */ +#define SDIO_DSCADDR MMIO32(SDIO_BASE + 0x094) + +/* Current Buffer Descriptor Address Register */ +#define SDIO_BUFADDR MMIO32(SDIO_BASE + 0x098) + +/* Data FIFO read/write */ +#define SDIO_DATA MMIO32(SDIO_BASE + 0x100) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sgpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sgpio.h new file mode 100644 index 00000000..4b8d5b68 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/sgpio.h @@ -0,0 +1,691 @@ +/** @defgroup sgpio_defines Serial General Purpose I/O + +@brief Defined Constants and Types for the LPC43xx Serial General Purpose +I/O + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/** @defgroup sdio_defines SDIO + +@brief Defined Constants and Types for the LPC43xx SDIO + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Jared Boone + * Copyright (C) 2012 Benjamin Vernoux + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_SGPIO_H +#define LPC43XX_SGPIO_H + +/**@{*/ + +#include +#include + +/* --- SGPIO registers ----------------------------------------------------- */ + +/* Pin multiplexer configuration registers (OUT_MUX_CFG0 to 15) */ +#define SGPIO_OUT_MUX_CFG(pin) MMIO32(SGPIO_PORT_BASE + (pin * 0x04)) +#define SGPIO_OUT_MUX_CFG0 MMIO32(SGPIO_PORT_BASE + 0x00) +#define SGPIO_OUT_MUX_CFG1 MMIO32(SGPIO_PORT_BASE + 0x04) +#define SGPIO_OUT_MUX_CFG2 MMIO32(SGPIO_PORT_BASE + 0x08) +#define SGPIO_OUT_MUX_CFG3 MMIO32(SGPIO_PORT_BASE + 0x0C) +#define SGPIO_OUT_MUX_CFG4 MMIO32(SGPIO_PORT_BASE + 0x10) +#define SGPIO_OUT_MUX_CFG5 MMIO32(SGPIO_PORT_BASE + 0x14) +#define SGPIO_OUT_MUX_CFG6 MMIO32(SGPIO_PORT_BASE + 0x18) +#define SGPIO_OUT_MUX_CFG7 MMIO32(SGPIO_PORT_BASE + 0x1C) +#define SGPIO_OUT_MUX_CFG8 MMIO32(SGPIO_PORT_BASE + 0x20) +#define SGPIO_OUT_MUX_CFG9 MMIO32(SGPIO_PORT_BASE + 0x24) +#define SGPIO_OUT_MUX_CFG10 MMIO32(SGPIO_PORT_BASE + 0x28) +#define SGPIO_OUT_MUX_CFG11 MMIO32(SGPIO_PORT_BASE + 0x2C) +#define SGPIO_OUT_MUX_CFG12 MMIO32(SGPIO_PORT_BASE + 0x30) +#define SGPIO_OUT_MUX_CFG13 MMIO32(SGPIO_PORT_BASE + 0x34) +#define SGPIO_OUT_MUX_CFG14 MMIO32(SGPIO_PORT_BASE + 0x38) +#define SGPIO_OUT_MUX_CFG15 MMIO32(SGPIO_PORT_BASE + 0x3C) + +/* SGPIO multiplexer configuration registers (SGPIO_MUX_CFG0 to 15) */ +#define SGPIO_MUX_CFG(slice) MMIO32(SGPIO_PORT_BASE + 0x40 + \ + (slice * 0x04)) +#define SGPIO_MUX_CFG0 MMIO32(SGPIO_PORT_BASE + 0x40) +#define SGPIO_MUX_CFG1 MMIO32(SGPIO_PORT_BASE + 0x44) +#define SGPIO_MUX_CFG2 MMIO32(SGPIO_PORT_BASE + 0x48) +#define SGPIO_MUX_CFG3 MMIO32(SGPIO_PORT_BASE + 0x4C) +#define SGPIO_MUX_CFG4 MMIO32(SGPIO_PORT_BASE + 0x50) +#define SGPIO_MUX_CFG5 MMIO32(SGPIO_PORT_BASE + 0x54) +#define SGPIO_MUX_CFG6 MMIO32(SGPIO_PORT_BASE + 0x58) +#define SGPIO_MUX_CFG7 MMIO32(SGPIO_PORT_BASE + 0x5C) +#define SGPIO_MUX_CFG8 MMIO32(SGPIO_PORT_BASE + 0x60) +#define SGPIO_MUX_CFG9 MMIO32(SGPIO_PORT_BASE + 0x64) +#define SGPIO_MUX_CFG10 MMIO32(SGPIO_PORT_BASE + 0x68) +#define SGPIO_MUX_CFG11 MMIO32(SGPIO_PORT_BASE + 0x6C) +#define SGPIO_MUX_CFG12 MMIO32(SGPIO_PORT_BASE + 0x70) +#define SGPIO_MUX_CFG13 MMIO32(SGPIO_PORT_BASE + 0x74) +#define SGPIO_MUX_CFG14 MMIO32(SGPIO_PORT_BASE + 0x78) +#define SGPIO_MUX_CFG15 MMIO32(SGPIO_PORT_BASE + 0x7C) + +/* Slice multiplexer configuration registers (SLICE_MUX_CFG0 to 15) */ +#define SGPIO_SLICE_MUX_CFG(slice) MMIO32(SGPIO_PORT_BASE + 0x80 + \ + (slice * 0x04)) +#define SGPIO_SLICE_MUX_CFG0 MMIO32(SGPIO_PORT_BASE + 0x80) +#define SGPIO_SLICE_MUX_CFG1 MMIO32(SGPIO_PORT_BASE + 0x84) +#define SGPIO_SLICE_MUX_CFG2 MMIO32(SGPIO_PORT_BASE + 0x88) +#define SGPIO_SLICE_MUX_CFG3 MMIO32(SGPIO_PORT_BASE + 0x8C) +#define SGPIO_SLICE_MUX_CFG4 MMIO32(SGPIO_PORT_BASE + 0x90) +#define SGPIO_SLICE_MUX_CFG5 MMIO32(SGPIO_PORT_BASE + 0x94) +#define SGPIO_SLICE_MUX_CFG6 MMIO32(SGPIO_PORT_BASE + 0x98) +#define SGPIO_SLICE_MUX_CFG7 MMIO32(SGPIO_PORT_BASE + 0x9C) +#define SGPIO_SLICE_MUX_CFG8 MMIO32(SGPIO_PORT_BASE + 0xA0) +#define SGPIO_SLICE_MUX_CFG9 MMIO32(SGPIO_PORT_BASE + 0xA4) +#define SGPIO_SLICE_MUX_CFG10 MMIO32(SGPIO_PORT_BASE + 0xA8) +#define SGPIO_SLICE_MUX_CFG11 MMIO32(SGPIO_PORT_BASE + 0xAC) +#define SGPIO_SLICE_MUX_CFG12 MMIO32(SGPIO_PORT_BASE + 0xB0) +#define SGPIO_SLICE_MUX_CFG13 MMIO32(SGPIO_PORT_BASE + 0xB4) +#define SGPIO_SLICE_MUX_CFG14 MMIO32(SGPIO_PORT_BASE + 0xB8) +#define SGPIO_SLICE_MUX_CFG15 MMIO32(SGPIO_PORT_BASE + 0xBC) + +/* Slice data registers (REG0 to 15) */ +#define SGPIO_REG(slice) MMIO32(SGPIO_PORT_BASE + 0xC0 + \ + (slice * 0x04)) +#define SGPIO_REG0 MMIO32(SGPIO_PORT_BASE + 0xC0) +#define SGPIO_REG1 MMIO32(SGPIO_PORT_BASE + 0xC4) +#define SGPIO_REG2 MMIO32(SGPIO_PORT_BASE + 0xC8) +#define SGPIO_REG3 MMIO32(SGPIO_PORT_BASE + 0xCC) +#define SGPIO_REG4 MMIO32(SGPIO_PORT_BASE + 0xD0) +#define SGPIO_REG5 MMIO32(SGPIO_PORT_BASE + 0xD4) +#define SGPIO_REG6 MMIO32(SGPIO_PORT_BASE + 0xD8) +#define SGPIO_REG7 MMIO32(SGPIO_PORT_BASE + 0xDC) +#define SGPIO_REG8 MMIO32(SGPIO_PORT_BASE + 0xE0) +#define SGPIO_REG9 MMIO32(SGPIO_PORT_BASE + 0xE4) +#define SGPIO_REG10 MMIO32(SGPIO_PORT_BASE + 0xE8) +#define SGPIO_REG11 MMIO32(SGPIO_PORT_BASE + 0xEC) +#define SGPIO_REG12 MMIO32(SGPIO_PORT_BASE + 0xF0) +#define SGPIO_REG13 MMIO32(SGPIO_PORT_BASE + 0xF4) +#define SGPIO_REG14 MMIO32(SGPIO_PORT_BASE + 0xF8) +#define SGPIO_REG15 MMIO32(SGPIO_PORT_BASE + 0xFC) + +/* Slice data shadow registers (REG_SS0 to 15) */ +#define SGPIO_REG_SS(slice) MMIO32(SGPIO_PORT_BASE + 0x100 + \ + (slice * 0x04)) +#define SGPIO_REG_SS0 MMIO32(SGPIO_PORT_BASE + 0x100) +#define SGPIO_REG_SS1 MMIO32(SGPIO_PORT_BASE + 0x104) +#define SGPIO_REG_SS2 MMIO32(SGPIO_PORT_BASE + 0x108) +#define SGPIO_REG_SS3 MMIO32(SGPIO_PORT_BASE + 0x10C) +#define SGPIO_REG_SS4 MMIO32(SGPIO_PORT_BASE + 0x110) +#define SGPIO_REG_SS5 MMIO32(SGPIO_PORT_BASE + 0x114) +#define SGPIO_REG_SS6 MMIO32(SGPIO_PORT_BASE + 0x118) +#define SGPIO_REG_SS7 MMIO32(SGPIO_PORT_BASE + 0x11C) +#define SGPIO_REG_SS8 MMIO32(SGPIO_PORT_BASE + 0x120) +#define SGPIO_REG_SS9 MMIO32(SGPIO_PORT_BASE + 0x124) +#define SGPIO_REG_SS10 MMIO32(SGPIO_PORT_BASE + 0x128) +#define SGPIO_REG_SS11 MMIO32(SGPIO_PORT_BASE + 0x12C) +#define SGPIO_REG_SS12 MMIO32(SGPIO_PORT_BASE + 0x130) +#define SGPIO_REG_SS13 MMIO32(SGPIO_PORT_BASE + 0x134) +#define SGPIO_REG_SS14 MMIO32(SGPIO_PORT_BASE + 0x138) +#define SGPIO_REG_SS15 MMIO32(SGPIO_PORT_BASE + 0x13C) + +/* Reload registers (PRESET0 to 15) */ +#define SGPIO_PRESET(slice) MMIO32(SGPIO_PORT_BASE + 0x140 + \ + (slice * 0x04)) +#define SGPIO_PRESET0 MMIO32(SGPIO_PORT_BASE + 0x140) +#define SGPIO_PRESET1 MMIO32(SGPIO_PORT_BASE + 0x144) +#define SGPIO_PRESET2 MMIO32(SGPIO_PORT_BASE + 0x148) +#define SGPIO_PRESET3 MMIO32(SGPIO_PORT_BASE + 0x14C) +#define SGPIO_PRESET4 MMIO32(SGPIO_PORT_BASE + 0x150) +#define SGPIO_PRESET5 MMIO32(SGPIO_PORT_BASE + 0x154) +#define SGPIO_PRESET6 MMIO32(SGPIO_PORT_BASE + 0x158) +#define SGPIO_PRESET7 MMIO32(SGPIO_PORT_BASE + 0x15C) +#define SGPIO_PRESET8 MMIO32(SGPIO_PORT_BASE + 0x160) +#define SGPIO_PRESET9 MMIO32(SGPIO_PORT_BASE + 0x164) +#define SGPIO_PRESET10 MMIO32(SGPIO_PORT_BASE + 0x168) +#define SGPIO_PRESET11 MMIO32(SGPIO_PORT_BASE + 0x16C) +#define SGPIO_PRESET12 MMIO32(SGPIO_PORT_BASE + 0x170) +#define SGPIO_PRESET13 MMIO32(SGPIO_PORT_BASE + 0x174) +#define SGPIO_PRESET14 MMIO32(SGPIO_PORT_BASE + 0x178) +#define SGPIO_PRESET15 MMIO32(SGPIO_PORT_BASE + 0x17C) + +/* Down counter registers (COUNT0 to 15) */ +#define SGPIO_COUNT(slice) MMIO32(SGPIO_PORT_BASE + 0x180 + \ + (slice * 0x04)) +#define SGPIO_COUNT0 MMIO32(SGPIO_PORT_BASE + 0x180) +#define SGPIO_COUNT1 MMIO32(SGPIO_PORT_BASE + 0x184) +#define SGPIO_COUNT2 MMIO32(SGPIO_PORT_BASE + 0x188) +#define SGPIO_COUNT3 MMIO32(SGPIO_PORT_BASE + 0x18C) +#define SGPIO_COUNT4 MMIO32(SGPIO_PORT_BASE + 0x190) +#define SGPIO_COUNT5 MMIO32(SGPIO_PORT_BASE + 0x194) +#define SGPIO_COUNT6 MMIO32(SGPIO_PORT_BASE + 0x198) +#define SGPIO_COUNT7 MMIO32(SGPIO_PORT_BASE + 0x19C) +#define SGPIO_COUNT8 MMIO32(SGPIO_PORT_BASE + 0x1A0) +#define SGPIO_COUNT9 MMIO32(SGPIO_PORT_BASE + 0x1A4) +#define SGPIO_COUNT10 MMIO32(SGPIO_PORT_BASE + 0x1A8) +#define SGPIO_COUNT11 MMIO32(SGPIO_PORT_BASE + 0x1AC) +#define SGPIO_COUNT12 MMIO32(SGPIO_PORT_BASE + 0x1B0) +#define SGPIO_COUNT13 MMIO32(SGPIO_PORT_BASE + 0x1B4) +#define SGPIO_COUNT14 MMIO32(SGPIO_PORT_BASE + 0x1B8) +#define SGPIO_COUNT15 MMIO32(SGPIO_PORT_BASE + 0x1BC) + +/* Position registers (POS0 to 15) */ +#define SGPIO_POS(slice) MMIO32(SGPIO_PORT_BASE + 0x1C0 + \ + (slice * 0x04)) +#define SGPIO_POS0 MMIO32(SGPIO_PORT_BASE + 0x1C0) +#define SGPIO_POS1 MMIO32(SGPIO_PORT_BASE + 0x1C4) +#define SGPIO_POS2 MMIO32(SGPIO_PORT_BASE + 0x1C8) +#define SGPIO_POS3 MMIO32(SGPIO_PORT_BASE + 0x1CC) +#define SGPIO_POS4 MMIO32(SGPIO_PORT_BASE + 0x1D0) +#define SGPIO_POS5 MMIO32(SGPIO_PORT_BASE + 0x1D4) +#define SGPIO_POS6 MMIO32(SGPIO_PORT_BASE + 0x1D8) +#define SGPIO_POS7 MMIO32(SGPIO_PORT_BASE + 0x1DC) +#define SGPIO_POS8 MMIO32(SGPIO_PORT_BASE + 0x1E0) +#define SGPIO_POS9 MMIO32(SGPIO_PORT_BASE + 0x1E4) +#define SGPIO_POS10 MMIO32(SGPIO_PORT_BASE + 0x1E8) +#define SGPIO_POS11 MMIO32(SGPIO_PORT_BASE + 0x1EC) +#define SGPIO_POS12 MMIO32(SGPIO_PORT_BASE + 0x1F0) +#define SGPIO_POS13 MMIO32(SGPIO_PORT_BASE + 0x1F4) +#define SGPIO_POS14 MMIO32(SGPIO_PORT_BASE + 0x1F8) +#define SGPIO_POS15 MMIO32(SGPIO_PORT_BASE + 0x1FC) + +/* Slice name to slice index mapping */ +#define SGPIO_SLICE_A 0 +#define SGPIO_SLICE_B 1 +#define SGPIO_SLICE_C 2 +#define SGPIO_SLICE_D 3 +#define SGPIO_SLICE_E 4 +#define SGPIO_SLICE_F 5 +#define SGPIO_SLICE_G 6 +#define SGPIO_SLICE_H 7 +#define SGPIO_SLICE_I 8 +#define SGPIO_SLICE_J 9 +#define SGPIO_SLICE_K 10 +#define SGPIO_SLICE_L 11 +#define SGPIO_SLICE_M 12 +#define SGPIO_SLICE_N 13 +#define SGPIO_SLICE_O 14 +#define SGPIO_SLICE_P 15 + +/* Mask for pattern match function of slice A */ +#define SGPIO_MASK_A MMIO32(SGPIO_PORT_BASE + 0x200) + +/* Mask for pattern match function of slice H */ +#define SGPIO_MASK_H MMIO32(SGPIO_PORT_BASE + 0x204) + +/* Mask for pattern match function of slice I */ +#define SGPIO_MASK_I MMIO32(SGPIO_PORT_BASE + 0x208) + +/* Mask for pattern match function of slice P */ +#define SGPIO_MASK_P MMIO32(SGPIO_PORT_BASE + 0x20C) + +/* GPIO input status register */ +#define SGPIO_GPIO_INREG MMIO32(SGPIO_PORT_BASE + 0x210) + +/* GPIO output control register */ +#define SGPIO_GPIO_OUTREG MMIO32(SGPIO_PORT_BASE + 0x214) + +/* GPIO OE control register */ +#define SGPIO_GPIO_OENREG MMIO32(SGPIO_PORT_BASE + 0x218) + +/* Enables the slice COUNT counter */ +#define SGPIO_CTRL_ENABLE MMIO32(SGPIO_PORT_BASE + 0x21C) + +/* Disables the slice COUNT counter */ +#define SGPIO_CTRL_DISABLE MMIO32(SGPIO_PORT_BASE + 0x220) + +/* Shift clock interrupt clear mask */ +#define SGPIO_CLR_EN_0 MMIO32(SGPIO_PORT_BASE + 0xF00) + +/* Shift clock interrupt set mask */ +#define SGPIO_SET_EN_0 MMIO32(SGPIO_PORT_BASE + 0xF04) + +/* Shift clock interrupt enable */ +#define SGPIO_ENABLE_0 MMIO32(SGPIO_PORT_BASE + 0xF08) + +/* Shift clock interrupt status */ +#define SGPIO_STATUS_0 MMIO32(SGPIO_PORT_BASE + 0xF0C) + +/* Shift clock interrupt clear status */ +#define SGPIO_CLR_STATUS_0 MMIO32(SGPIO_PORT_BASE + 0xF10) + +/* Shift clock interrupt set status */ +#define SGPIO_SET_STATUS_0 MMIO32(SGPIO_PORT_BASE + 0xF14) + +/* Exchange clock interrupt clear mask */ +#define SGPIO_CLR_EN_1 MMIO32(SGPIO_PORT_BASE + 0xF20) + +/* Exchange clock interrupt set mask */ +#define SGPIO_SET_EN_1 MMIO32(SGPIO_PORT_BASE + 0xF24) + +/* Exchange clock interrupt enable */ +#define SGPIO_ENABLE_1 MMIO32(SGPIO_PORT_BASE + 0xF28) + +/* Exchange clock interrupt status */ +#define SGPIO_STATUS_1 MMIO32(SGPIO_PORT_BASE + 0xF2C) + +/* Exchange clock interrupt clear status */ +#define SGPIO_CLR_STATUS_1 MMIO32(SGPIO_PORT_BASE + 0xF30) + +/* Exchange clock interrupt set status */ +#define SGPIO_SET_STATUS_1 MMIO32(SGPIO_PORT_BASE + 0xF34) + +/* Pattern match interrupt clear mask */ +#define SGPIO_CLR_EN_2 MMIO32(SGPIO_PORT_BASE + 0xF40) + +/* Pattern match interrupt set mask */ +#define SGPIO_SET_EN_2 MMIO32(SGPIO_PORT_BASE + 0xF44) + +/* Pattern match interrupt enable */ +#define SGPIO_ENABLE_2 MMIO32(SGPIO_PORT_BASE + 0xF48) + +/* Pattern match interrupt status */ +#define SGPIO_STATUS_2 MMIO32(SGPIO_PORT_BASE + 0xF4C) + +/* Pattern match interrupt clear status */ +#define SGPIO_CLR_STATUS_2 MMIO32(SGPIO_PORT_BASE + 0xF50) + +/* Pattern match interrupt set status */ +#define SGPIO_SET_STATUS_2 MMIO32(SGPIO_PORT_BASE + 0xF54) + +/* Input interrupt clear mask */ +#define SGPIO_CLR_EN_3 MMIO32(SGPIO_PORT_BASE + 0xF60) + +/* Input bit match interrupt set mask */ +#define SGPIO_SET_EN_3 MMIO32(SGPIO_PORT_BASE + 0xF64) + +/* Input bit match interrupt enable */ +#define SGPIO_ENABLE_3 MMIO32(SGPIO_PORT_BASE + 0xF68) + +/* Input bit match interrupt status */ +#define SGPIO_STATUS_3 MMIO32(SGPIO_PORT_BASE + 0xF6C) + +/* Input bit match interrupt clear status */ +#define SGPIO_CLR_STATUS_3 MMIO32(SGPIO_PORT_BASE + 0xF70) + +/* Input bit match interrupt set status */ +#define SGPIO_SET_STATUS_3 MMIO32(SGPIO_PORT_BASE + 0xF74) + +/* --- Common register fields ----------------------------------- */ +/* TODO: Generate this stuff with the gen.py script as well! */ + +#define SGPIO_OUT_MUX_CFG_P_OUT_CFG_SHIFT (0) +#define SGPIO_OUT_MUX_CFG_P_OUT_CFG_MASK \ + (0xf << SGPIO_OUT_MUX_CFG_P_OUT_CFG_SHIFT) +#define SGPIO_OUT_MUX_CFG_P_OUT_CFG(x) \ + ((x) << SGPIO_OUT_MUX_CFG_P_OUT_CFG_SHIFT) + +#define SGPIO_OUT_MUX_CFG_P_OE_CFG_SHIFT (4) +#define SGPIO_OUT_MUX_CFG_P_OE_CFG_MASK \ + (0x7 << SGPIO_OUT_MUX_CFG_P_OE_CFG_SHIFT) +#define SGPIO_OUT_MUX_CFG_P_OE_CFG(x) \ + ((x) << SGPIO_OUT_MUX_CFG_P_OE_CFG_SHIFT) + +#define SGPIO_MUX_CFG_EXT_CLK_ENABLE_SHIFT (0) +#define SGPIO_MUX_CFG_EXT_CLK_ENABLE_MASK \ + (1 << SGPIO_MUX_CFG_EXT_CLK_ENABLE_SHIFT) +#define SGPIO_MUX_CFG_EXT_CLK_ENABLE(x) \ + ((x) << SGPIO_MUX_CFG_EXT_CLK_ENABLE_SHIFT) + +#define SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE_SHIFT (1) +#define SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE_MASK \ + (0x3 << SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE_SHIFT) +#define SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE(x) \ + ((x) << SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE_SHIFT) + +#define SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE_SHIFT (3) +#define SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE_MASK \ + (0x3 << SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE_SHIFT) +#define SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE(x) \ + ((x) << SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE_SHIFT) + +#define SGPIO_MUX_CFG_QUALIFIER_MODE_SHIFT (5) +#define SGPIO_MUX_CFG_QUALIFIER_MODE_MASK \ + (0x3 << SGPIO_MUX_CFG_QUALIFIER_MODE_SHIFT) +#define SGPIO_MUX_CFG_QUALIFIER_MODE(x) \ + ((x) << SGPIO_MUX_CFG_QUALIFIER_MODE_SHIFT) + +#define SGPIO_MUX_CFG_QUALIFIER_PIN_MODE_SHIFT (7) +#define SGPIO_MUX_CFG_QUALIFIER_PIN_MODE_MASK \ + (0x3 << SGPIO_MUX_CFG_QUALIFIER_PIN_MODE_SHIFT) +#define SGPIO_MUX_CFG_QUALIFIER_PIN_MODE(x) \ + ((x) << SGPIO_MUX_CFG_QUALIFIER_PIN_MODE_SHIFT) + +#define SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE_SHIFT (9) +#define SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE_MASK \ + (0x3 << SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE_SHIFT) +#define SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE(x) \ + ((x) << SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE_SHIFT) + +#define SGPIO_MUX_CFG_CONCAT_ENABLE_SHIFT (11) +#define SGPIO_MUX_CFG_CONCAT_ENABLE_MASK \ + (1 << SGPIO_MUX_CFG_CONCAT_ENABLE_SHIFT) +#define SGPIO_MUX_CFG_CONCAT_ENABLE(x) \ + ((x) << SGPIO_MUX_CFG_CONCAT_ENABLE_SHIFT) + +#define SGPIO_MUX_CFG_CONCAT_ORDER_SHIFT (12) +#define SGPIO_MUX_CFG_CONCAT_ORDER_MASK \ + (0x3 << SGPIO_MUX_CFG_CONCAT_ORDER_SHIFT) +#define SGPIO_MUX_CFG_CONCAT_ORDER(x) \ + ((x) << SGPIO_MUX_CFG_CONCAT_ORDER_SHIFT) + +#define SGPIO_SLICE_MUX_CFG_MATCH_MODE_SHIFT (0) +#define SGPIO_SLICE_MUX_CFG_MATCH_MODE_MASK \ + (1 << SGPIO_SLICE_MUX_CFG_MATCH_MODE_SHIFT) +#define SGPIO_SLICE_MUX_CFG_MATCH_MODE(x) \ + ((x) << SGPIO_SLICE_MUX_CFG_MATCH_MODE_SHIFT) + +#define SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE_SHIFT (1) +#define SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE_MASK \ + (1 << SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE_SHIFT) +#define SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE(x) \ + ((x) << SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE_SHIFT) + +#define SGPIO_SLICE_MUX_CFG_CLKGEN_MODE_SHIFT (2) +#define SGPIO_SLICE_MUX_CFG_CLKGEN_MODE_MASK \ + (1 << SGPIO_SLICE_MUX_CFG_CLKGEN_MODE_SHIFT) +#define SGPIO_SLICE_MUX_CFG_CLKGEN_MODE(x) \ + ((x) << SGPIO_SLICE_MUX_CFG_CLKGEN_MODE_SHIFT) + +#define SGPIO_SLICE_MUX_CFG_INV_OUT_CLK_SHIFT (3) +#define SGPIO_SLICE_MUX_CFG_INV_OUT_CLK_MASK \ + (1 << SGPIO_SLICE_MUX_CFG_INV_OUT_CLK_SHIFT) +#define SGPIO_SLICE_MUX_CFG_INV_OUT_CLK(x) \ + ((x) << SGPIO_SLICE_MUX_CFG_INV_OUT_CLK_SHIFT) + +#define SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE_SHIFT (4) +#define SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE_MASK \ + (0x3 << SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE_SHIFT) +#define SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE(x) \ + ((x) << SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE_SHIFT) + +#define SGPIO_SLICE_MUX_CFG_PARALLEL_MODE_SHIFT (6) +#define SGPIO_SLICE_MUX_CFG_PARALLEL_MODE_MASK \ + (0x3 << SGPIO_SLICE_MUX_CFG_PARALLEL_MODE_SHIFT) +#define SGPIO_SLICE_MUX_CFG_PARALLEL_MODE(x) \ + ((x) << SGPIO_SLICE_MUX_CFG_PARALLEL_MODE_SHIFT) + +#define SGPIO_SLICE_MUX_CFG_INV_QUALIFIER_SHIFT (8) +#define SGPIO_SLICE_MUX_CFG_INV_QUALIFIER_MASK \ + (1 << SGPIO_SLICE_MUX_CFG_INV_QUALIFIER_SHIFT) +#define SGPIO_SLICE_MUX_CFG_INV_QUALIFIER(x) \ + ((x) << SGPIO_SLICE_MUX_CFG_INV_QUALIFIER_SHIFT) + +#define SGPIO_POS_POS_SHIFT (0) +#define SGPIO_POS_POS_MASK (0xff << SGPIO_POS_POS_SHIFT) +#define SGPIO_POS_POS(x) ((x) << SGPIO_POS_POS_SHIFT) + +#define SGPIO_POS_POS_RESET_SHIFT (8) +#define SGPIO_POS_POS_RESET_MASK (0xff << SGPIO_POS_POS_RESET_SHIFT) +#define SGPIO_POS_POS_RESET(x) ((x) << SGPIO_POS_POS_RESET_SHIFT) + +/* --- AUTO-GENERATED STUFF FOLLOWS ----------------------------- */ + +/* --- SGPIO_OUT_MUX_CFG[0..15] values ------------------------------------ */ + +/* P_OUT_CFG: Output control of output SGPIOn */ +#define SGPIO_OUT_MUX_CFGx_P_OUT_CFG_SHIFT (0) +#define SGPIO_OUT_MUX_CFGx_P_OUT_CFG_MASK \ + (0xf << SGPIO_OUT_MUX_CFGx_P_OUT_CFG_SHIFT) +#define SGPIO_OUT_MUX_CFGx_P_OUT_CFG(x) \ + ((x) << SGPIO_OUT_MUX_CFGx_P_OUT_CFG_SHIFT) + +/* P_OE_CFG: Output enable source */ +#define SGPIO_OUT_MUX_CFGx_P_OE_CFG_SHIFT (4) +#define SGPIO_OUT_MUX_CFGx_P_OE_CFG_MASK \ + (0x7 << SGPIO_OUT_MUX_CFGx_P_OE_CFG_SHIFT) +#define SGPIO_OUT_MUX_CFGx_P_OE_CFG(x) \ + ((x) << SGPIO_OUT_MUX_CFGx_P_OE_CFG_SHIFT) + +/* --- SGPIO_MUX_CFG[0..15] values ---------------------------------------- */ + +/* EXT_CLK_ENABLE: Select clock signal */ +#define SGPIO_MUX_CFGx_EXT_CLK_ENABLE_SHIFT (0) +#define SGPIO_MUX_CFGx_EXT_CLK_ENABLE \ + (1 << SGPIO_MUX_CFGx_EXT_CLK_ENABLE_SHIFT) + +/* CLK_SOURCE_PIN_MODE: Select source clock pin */ +#define SGPIO_MUX_CFGx_CLK_SOURCE_PIN_MODE_SHIFT (1) +#define SGPIO_MUX_CFGx_CLK_SOURCE_PIN_MODE_MASK \ + (0x3 << SGPIO_MUX_CFGx_CLK_SOURCE_PIN_MODE_SHIFT) +#define SGPIO_MUX_CFGx_CLK_SOURCE_PIN_MODE(x) \ + ((x) << SGPIO_MUX_CFGx_CLK_SOURCE_PIN_MODE_SHIFT) + +/* CLK_SOURCE_SLICE_MODE: Select clock source slice */ +#define SGPIO_MUX_CFGx_CLK_SOURCE_SLICE_MODE_SHIFT (3) +#define SGPIO_MUX_CFGx_CLK_SOURCE_SLICE_MODE_MASK \ + (0x3 << SGPIO_MUX_CFGx_CLK_SOURCE_SLICE_MODE_SHIFT) +#define SGPIO_MUX_CFGx_CLK_SOURCE_SLICE_MODE(x) \ + ((x) << SGPIO_MUX_CFGx_CLK_SOURCE_SLICE_MODE_SHIFT) + +/* QUALIFIER_MODE: Select qualifier mode */ +#define SGPIO_MUX_CFGx_QUALIFIER_MODE_SHIFT (5) +#define SGPIO_MUX_CFGx_QUALIFIER_MODE_MASK \ + (0x3 << SGPIO_MUX_CFGx_QUALIFIER_MODE_SHIFT) +#define SGPIO_MUX_CFGx_QUALIFIER_MODE(x) \ + ((x) << SGPIO_MUX_CFGx_QUALIFIER_MODE_SHIFT) + +/* QUALIFIER_PIN_MODE: Select qualifier pin */ +#define SGPIO_MUX_CFGx_QUALIFIER_PIN_MODE_SHIFT (7) +#define SGPIO_MUX_CFGx_QUALIFIER_PIN_MODE_MASK \ + (0x3 << SGPIO_MUX_CFGx_QUALIFIER_PIN_MODE_SHIFT) +#define SGPIO_MUX_CFGx_QUALIFIER_PIN_MODE(x) \ + ((x) << SGPIO_MUX_CFGx_QUALIFIER_PIN_MODE_SHIFT) + +/* QUALIFIER_SLICE_MODE: Select qualifier slice */ +#define SGPIO_MUX_CFGx_QUALIFIER_SLICE_MODE_SHIFT (9) +#define SGPIO_MUX_CFGx_QUALIFIER_SLICE_MODE_MASK \ + (0x3 << SGPIO_MUX_CFGx_QUALIFIER_SLICE_MODE_SHIFT) +#define SGPIO_MUX_CFGx_QUALIFIER_SLICE_MODE(x) \ + ((x) << SGPIO_MUX_CFG0_QUALIFIER_SLICE_MODE_SHIFT) + +/* CONCAT_ENABLE: Enable concatenation */ +#define SGPIO_MUX_CFGx_CONCAT_ENABLE_SHIFT (11) +#define SGPIO_MUX_CFGx_CONCAT_ENABLE \ + (1 << SGPIO_MUX_CFGx_CONCAT_ENABLE_SHIFT) + +/* CONCAT_ORDER: Select concatenation order */ +#define SGPIO_MUX_CFGx_CONCAT_ORDER_SHIFT (12) +#define SGPIO_MUX_CFGx_CONCAT_ORDER_MASK \ + (0x3 << SGPIO_MUX_CFGx_CONCAT_ORDER_SHIFT) +#define SGPIO_MUX_CFGx_CONCAT_ORDER(x) \ + ((x) << SGPIO_MUX_CFGx_CONCAT_ORDER_SHIFT) + +/* --- SGPIO_SLICE_MUX_CFG[0..15] values ---------------------------------- */ + +/* MATCH_MODE: Match mode */ +#define SGPIO_SLICE_MUX_CFGx_MATCH_MODE_SHIFT (0) +#define SGPIO_SLICE_MUX_CFGx_MATCH_MODE \ + (1 << SGPIO_SLICE_MUX_CFG0_MATCH_MODE_SHIFT) + +/* CLK_CAPTURE_MODE: Capture clock mode */ +#define SGPIO_SLICE_MUX_CFGx_CLK_CAPTURE_MODE_SHIFT (1) +#define SGPIO_SLICE_MUX_CFGx_CLK_CAPTURE_MODE \ + (1 << SGPIO_SLICE_MUX_CFGx_CLK_CAPTURE_MODE_SHIFT) + +/* CLKGEN_MODE: Clock generation mode */ +#define SGPIO_SLICE_MUX_CFGx_CLKGEN_MODE_SHIFT (2) +#define SGPIO_SLICE_MUX_CFGx_CLKGEN_MODE \ + (1 << SGPIO_SLICE_MUX_CFGx_CLKGEN_MODE_SHIFT) + +/* INV_OUT_CLK: Invert output clock */ +#define SGPIO_SLICE_MUX_CFGx_INV_OUT_CLK_SHIFT (3) +#define SGPIO_SLICE_MUX_CFGx_INV_OUT_CLK \ + (1 << SGPIO_SLICE_MUX_CFGx_INV_OUT_CLK_SHIFT) + +/* DATA_CAPTURE_MODE: Condition for input bit match interrupt */ +#define SGPIO_SLICE_MUX_CFGx_DATA_CAPTURE_MODE_SHIFT (4) +#define SGPIO_SLICE_MUX_CFGx_DATA_CAPTURE_MODE_MASK \ + (0x3 << SGPIO_SLICE_MUX_CFGx_DATA_CAPTURE_MODE_SHIFT) +#define SGPIO_SLICE_MUX_CFGx_DATA_CAPTURE_MODE(x) \ + ((x) << SGPIO_SLICE_MUX_CFGx_DATA_CAPTURE_MODE_SHIFT) + +/* PARALLEL_MODE: Parallel mode */ +#define SGPIO_SLICE_MUX_CFGx_PARALLEL_MODE_SHIFT (6) +#define SGPIO_SLICE_MUX_CFGx_PARALLEL_MODE_MASK \ + (0x3 << SGPIO_SLICE_MUX_CFGx_PARALLEL_MODE_SHIFT) +#define SGPIO_SLICE_MUX_CFGx_PARALLEL_MODE(x) \ + ((x) << SGPIO_SLICE_MUX_CFGx_PARALLEL_MODE_SHIFT) + +/* INV_QUALIFIER: Inversion qualifier */ +#define SGPIO_SLICE_MUX_CFGx_INV_QUALIFIER_SHIFT (8) +#define SGPIO_SLICE_MUX_CFGx_INV_QUALIFIER \ + (1 << SGPIO_SLICE_MUX_CFGx_INV_QUALIFIER_SHIFT) + + +/* --- SGPIO_POS[0..15] values -------------------------------------------- */ + +/* POS: Each time COUNT reaches 0x0 POS counts down */ +#define SGPIO_POSx_POS_SHIFT (0) +#define SGPIO_POSx_POS_MASK (0xff << SGPIO_POSx_POS_SHIFT) +#define SGPIO_POSx_POS(x) ((x) << SGPIO_POSx_POS_SHIFT) + +/* POS_RESET: Reload value for POS after POS reaches 0x0 */ +#define SGPIO_POSx_POS_RESET_SHIFT (8) +#define SGPIO_POSx_POS_RESET_MASK (0xff << SGPIO_POSx_POS_RESET_SHIFT) +#define SGPIO_POSx_POS_RESET(x) ((x) << SGPIO_POSx_POS_RESET_SHIFT) + + +/* SGPIO structure for faster/better code generation (especially when optimized + * with -O2/-O3) + */ +/* This structure is compliant with LPC43xx User Manual UM10503 Rev.1.4 - 3 + * September 2012 + */ +typedef struct { + /* Pin multiplexer configuration registers. RW */ + volatile uint32_t OUT_MUX_CFG[16]; + /* SGPIO multiplexer configuration registers. RW */ + volatile uint32_t SGPIO_MUX_CFG[16]; + /* Slice multiplexer configuration registers. RW */ + volatile uint32_t SLICE_MUX_CFG[16]; + /* Slice data registers. RW */ + volatile uint32_t REG[16]; + /* Slice data shadow registers. Each time POS reaches 0x0 the contents + * of REG_SS is exchanged with the content of REG. RW + */ + volatile uint32_t REG_SS[16]; + /* Reload registers. Counter reload value; loaded when COUNT reaches + * 0x0 RW + */ + volatile uint32_t PRESET[16]; + /* Down counter registers, counts down each shift clock cycle. RW */ + volatile uint32_t COUNT[16]; + /* Position registers. POS Each time COUNT reaches 0x0 POS counts down. + * POS_RESET Reload value for POS after POS reaches 0x0. RW + */ + volatile uint32_t POS[16]; + /* Slice A mask register. Mask for pattern match function of slice A. + * RW + */ + volatile uint32_t MASK_A; + /* Slice H mask register. Mask for pattern match function of slice H. + * RW + */ + volatile uint32_t MASK_H; + /* Slice I mask register. Mask for pattern match function of slice I. + * RW + */ + volatile uint32_t MASK_I; + /* Slice P mask register. Mask for pattern match function of slice P. + * RW + */ + volatile uint32_t MASK_P; + /* GPIO input status register. R */ + volatile uint32_t GPIO_INREG; + /* GPIO output control register. RW */ + volatile uint32_t GPIO_OUTREG; + /* GPIO output enable register. RW */ + volatile uint32_t GPIO_OENREG; + /* Slice count enable register. RW */ + volatile uint32_t CTRL_ENABLE; + /* Slice count disable register. RW */ + volatile uint32_t CTRL_DISABLE; + volatile uint32_t RES0[823]; + /* Shift clock interrupt clear mask register. W */ + volatile uint32_t CLR_EN_0; + /* Shift clock interrupt set mask register. W */ + volatile uint32_t SET_EN_0; + /* Shift clock interrupt enable register. R */ + volatile uint32_t ENABLE_0; + /* Shift clock interrupt status register. R */ + volatile uint32_t STATUS_0; + /* Shift clock interrupt clear status register. W */ + volatile uint32_t CLR_STATUS_0; + /* Shift clock interrupt set status register. W */ + volatile uint32_t SET_STATUS_0; + volatile uint32_t RES1[2]; + /* Exchange clock interrupt clear mask register. W */ + volatile uint32_t CLR_EN_1; + /* Exchange clock interrupt set mask register. W */ + volatile uint32_t SET_EN_1; + /* Exchange clock interrupt enable. R */ + volatile uint32_t ENABLE_1; + /* Exchange clock interrupt status register. R */ + volatile uint32_t STATUS_1; + /* Exchange clock interrupt clear status register. W */ + volatile uint32_t CLR_STATUS_1; + /* Exchange clock interrupt set status register. W */ + volatile uint32_t SET_STATUS_1; + volatile uint32_t RES2[2]; + /* Pattern match interrupt clear mask register. W */ + volatile uint32_t CLR_EN_2; + /* Pattern match interrupt set mask register. W */ + volatile uint32_t SET_EN_2; + /* Pattern match interrupt enable register. R */ + volatile uint32_t ENABLE_2; + /* Pattern match interrupt status register. R */ + volatile uint32_t STATUS_2; + /* Pattern match interrupt clear status register. W */ + volatile uint32_t CLR_STATUS_2; + /* Pattern match interrupt set status register. W */ + volatile uint32_t SET_STATUS_2; + volatile uint32_t RES3[2]; + /* Input interrupt clear mask register. W */ + volatile uint32_t CLR_EN_3; + /* Input bit match interrupt set mask register. W */ + volatile uint32_t SET_EN_3; + /* Input bit match interrupt enable register. R */ + volatile uint32_t ENABLE_3; + /* Input bit match interrupt status register. R */ + volatile uint32_t STATUS_3; + /* Input bit match interrupt clear status register. W */ + volatile uint32_t CLR_STATUS_3; + /* Input bit match interrupt set status register. W */ + volatile uint32_t SET_STATUS_3; +} sgpio_t; + +/* Global access to SGPIO structure */ +#define SGPIO ((sgpio_t *)SGPIO_PORT_BASE) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ssp.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ssp.h new file mode 100644 index 00000000..554f7076 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/ssp.h @@ -0,0 +1,209 @@ +/** @defgroup ssp_defines Synchronous Serial Port + +@brief Defined Constants and Types for the LPC43xx Synchronous Serial +Port + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Michael Ossmann +* +* This library is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This library 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this library. If not, see . +*/ + +#ifndef LPC43XX_SSP_H +#define LPC43XX_SSP_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* SSP port base addresses (for convenience) */ +#define SSP0 SSP0_BASE +#define SSP1 SSP1_BASE + + +/* --- SSP registers ------------------------------------------------------- */ + +/* Control Register 0 */ +#define SSP_CR0(port) MMIO32((port) + 0x000) +#define SSP0_CR0 SSP_CR0(SSP0) +#define SSP1_CR0 SSP_CR0(SSP1) + +/* Control Register 1 */ +#define SSP_CR1(port) MMIO32((port) + 0x004) +#define SSP0_CR1 SSP_CR1(SSP0) +#define SSP1_CR1 SSP_CR1(SSP1) + +/* Data Register */ +#define SSP_DR(port) MMIO32((port) + 0x008) +#define SSP0_DR SSP_DR(SSP0) +#define SSP1_DR SSP_DR(SSP1) + +/* Status Register */ +#define SSP_SR(port) MMIO32((port) + 0x00C) +#define SSP0_SR SSP_SR(SSP0) +#define SSP1_SR SSP_SR(SSP1) + +#define SSP_SR_TFE BIT0 +#define SSP_SR_TNF BIT1 +#define SSP_SR_RNE BIT2 +#define SSP_SR_RFF BIT3 +#define SSP_SR_BSY BIT4 + +/* Clock Prescale Register */ +#define SSP_CPSR(port) MMIO32((port) + 0x010) +#define SSP0_CPSR SSP_CPSR(SSP0) +#define SSP1_CPSR SSP_CPSR(SSP1) + +/* Interrupt Mask Set and Clear Register */ +#define SSP_IMSC(port) MMIO32((port) + 0x014) +#define SSP0_IMSC SSP_IMSC(SSP0) +#define SSP1_IMSC SSP_IMSC(SSP1) + +/* Raw Interrupt Status Register */ +#define SSP_RIS(port) MMIO32((port) + 0x018) +#define SSP0_RIS SSP_RIS(SSP0) +#define SSP1_RIS SSP_RIS(SSP1) + +/* Masked Interrupt Status Register */ +#define SSP_MIS(port) MMIO32((port) + 0x01C) +#define SSP0_MIS SSP_MIS(SSP0) +#define SSP1_MIS SSP_MIS(SSP1) + +/* SSPICR Interrupt Clear Register */ +#define SSP_ICR(port) MMIO32((port) + 0x020) +#define SSP0_ICR SSP_ICR(SSP0) +#define SSP1_ICR SSP_ICR(SSP1) + +/* SSP1 DMA control register */ +#define SSP_DMACR(port) MMIO32((port) + 0x024) +#define SSP0_DMACR SSP_DMACR(SSP0) +#define SSP1_DMACR SSP_DMACR(SSP1) + +/* RXDMAE: Receive DMA enable */ +#define SSP_DMACR_RXDMAE 0x1 + +/* RXDMAE: Transmit DMA enable */ +#define SSP_DMACR_TXDMAE 0x2 + +typedef enum { + SSP0_NUM = 0x0, + SSP1_NUM = 0x1 +} ssp_num_t; + +/* + * SSP Control Register 0 + */ +/* SSP Data Size Bits 0 to 3 */ +typedef enum { + SSP_DATA_4BITS = 0x3, + SSP_DATA_5BITS = 0x4, + SSP_DATA_6BITS = 0x5, + SSP_DATA_7BITS = 0x6, + SSP_DATA_8BITS = 0x7, + SSP_DATA_9BITS = 0x8, + SSP_DATA_10BITS = 0x9, + SSP_DATA_11BITS = 0xA, + SSP_DATA_12BITS = 0xB, + SSP_DATA_13BITS = 0xC, + SSP_DATA_14BITS = 0xD, + SSP_DATA_15BITS = 0xE, + SSP_DATA_16BITS = 0xF +} ssp_datasize_t; + +/* SSP Frame Format/Type Bits 4 & 5 */ +typedef enum { + SSP_FRAME_SPI = 0x00, + SSP_FRAME_TI = BIT4, + SSP_FRAM_MICROWIRE = BIT5 +} ssp_frame_format_t; + +/* Clock Out Polarity / Clock Out Phase Bits Bits 6 & 7 */ +typedef enum { + SSP_CPOL_0_CPHA_0 = 0x0, + SSP_CPOL_1_CPHA_0 = BIT6, + SSP_CPOL_0_CPHA_1 = BIT7, + SSP_CPOL_1_CPHA_1 = (BIT6|BIT7) +} ssp_cpol_cpha_t; + +/* + * SSP Control Register 1 + */ +/* SSP Mode Bit0 */ +typedef enum { + SSP_MODE_NORMAL = 0x0, + SSP_MODE_LOOPBACK = BIT0 +} ssp_mode_t; + +/* SSP Enable Bit1 */ +#define SSP_ENABLE BIT1 + +/* SSP Master/Slave Mode Bit2 */ +typedef enum { + SSP_MASTER = 0x0, + SSP_SLAVE = BIT2 +} ssp_master_slave_t; + +/* +* SSP Slave Output Disable Bit3 +* Slave Output Disable. This bit is relevant only in slave mode +* (MS = 1). If it is 1, this blocks this SSP controller from driving the +* transmit data line (MISO). +*/ +typedef enum { + SSP_SLAVE_OUT_ENABLE = 0x0, + SSP_SLAVE_OUT_DISABLE = BIT3 +} ssp_slave_option_t; /* This option is relevant only in slave mode */ + +BEGIN_DECLS + +void ssp_disable(ssp_num_t ssp_num); + +/* + * SSP Init + * clk_prescale shall be in range 2 to 254 (even number only). + * Clock computation: PCLK / (CPSDVSR * [SCR+1]) => CPSDVSR=clk_prescale, + * SCR=serial_clock_rate + */ +void ssp_init(ssp_num_t ssp_num, + ssp_datasize_t data_size, + ssp_frame_format_t frame_format, + ssp_cpol_cpha_t cpol_cpha_format, + uint8_t serial_clock_rate, + uint8_t clk_prescale, + ssp_mode_t mode, + ssp_master_slave_t master_slave, + ssp_slave_option_t slave_option); + +uint16_t ssp_transfer(ssp_num_t ssp_num, uint16_t data); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/timer.h new file mode 100644 index 00000000..660c618e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/timer.h @@ -0,0 +1,270 @@ +/** @defgroup timer_defines Timer + +@brief Defined Constants and Types for the LPC43xx timer + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_TIMER_H +#define LPC43XX_TIMER_H + +/**@{*/ + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* Timer base addresses */ +#define TIMER0 TIMER0_BASE +#define TIMER1 TIMER1_BASE +#define TIMER2 TIMER2_BASE +#define TIMER3 TIMER3_BASE + + +/* --- Timer registers ----------------------------------------------------- */ + +/* Interrupt Register */ +#define TIMER_IR(timer) MMIO32((timer) + 0x000) +#define TIMER0_IR TIMER_IR(TIMER0) +#define TIMER1_IR TIMER_IR(TIMER1) +#define TIMER2_IR TIMER_IR(TIMER2) +#define TIMER3_IR TIMER_IR(TIMER3) + +/* Timer Control Register */ +#define TIMER_TCR(timer) MMIO32((timer) + 0x004) +#define TIMER0_TCR TIMER_TCR(TIMER0) +#define TIMER1_TCR TIMER_TCR(TIMER1) +#define TIMER2_TCR TIMER_TCR(TIMER2) +#define TIMER3_TCR TIMER_TCR(TIMER3) + +/* Timer Counter */ +#define TIMER_TC(timer) MMIO32((timer) + 0x008) +#define TIMER0_TC TIMER_TC(TIMER0) +#define TIMER1_TC TIMER_TC(TIMER1) +#define TIMER2_TC TIMER_TC(TIMER2) +#define TIMER3_TC TIMER_TC(TIMER3) + +/* Prescale Register */ +#define TIMER_PR(timer) MMIO32((timer) + 0x00C) +#define TIMER0_PR TIMER_PR(TIMER0) +#define TIMER1_PR TIMER_PR(TIMER1) +#define TIMER2_PR TIMER_PR(TIMER2) +#define TIMER3_PR TIMER_PR(TIMER3) + +/* Prescale Counter */ +#define TIMER_PC(timer) MMIO32((timer) + 0x010) +#define TIMER0_PC TIMER_PC(TIMER0) +#define TIMER1_PC TIMER_PC(TIMER1) +#define TIMER2_PC TIMER_PC(TIMER2) +#define TIMER3_PC TIMER_PC(TIMER3) + +/* Match Control Register */ +#define TIMER_MCR(timer) MMIO32((timer) + 0x014) +#define TIMER0_MCR TIMER_MCR(TIMER0) +#define TIMER1_MCR TIMER_MCR(TIMER1) +#define TIMER2_MCR TIMER_MCR(TIMER2) +#define TIMER3_MCR TIMER_MCR(TIMER3) + +/* Match Register 0 */ +#define TIMER_MR0(timer) MMIO32((timer) + 0x018) +#define TIMER0_MR0 TIMER_MR0(TIMER0) +#define TIMER1_MR0 TIMER_MR0(TIMER1) +#define TIMER2_MR0 TIMER_MR0(TIMER2) +#define TIMER3_MR0 TIMER_MR0(TIMER3) + +/* Match Register 1 */ +#define TIMER_MR1(timer) MMIO32((timer) + 0x01C) +#define TIMER0_MR1 TIMER_MR1(TIMER0) +#define TIMER1_MR1 TIMER_MR1(TIMER1) +#define TIMER2_MR1 TIMER_MR1(TIMER2) +#define TIMER3_MR1 TIMER_MR1(TIMER3) + +/* Match Register 2 */ +#define TIMER_MR2(timer) MMIO32((timer) + 0x020) +#define TIMER0_MR2 TIMER_MR2(TIMER0) +#define TIMER1_MR2 TIMER_MR2(TIMER1) +#define TIMER2_MR2 TIMER_MR2(TIMER2) +#define TIMER3_MR2 TIMER_MR2(TIMER3) + +/* Match Register 3 */ +#define TIMER_MR3(timer) MMIO32((timer) + 0x024) +#define TIMER0_MR3 TIMER_MR3(TIMER0) +#define TIMER1_MR3 TIMER_MR3(TIMER1) +#define TIMER2_MR3 TIMER_MR3(TIMER2) +#define TIMER3_MR3 TIMER_MR3(TIMER3) + +/* Capture Control Register */ +#define TIMER_CCR(timer) MMIO32((timer) + 0x028) +#define TIMER0_CCR TIMER_CCR(TIMER0) +#define TIMER1_CCR TIMER_CCR(TIMER1) +#define TIMER2_CCR TIMER_CCR(TIMER2) +#define TIMER3_CCR TIMER_CCR(TIMER3) + +/* Capture Register 0 */ +#define TIMER_CR0(timer) MMIO32((timer) + 0x02C) +#define TIMER0_CR0 TIMER_CR0(TIMER0) +#define TIMER1_CR0 TIMER_CR0(TIMER1) +#define TIMER2_CR0 TIMER_CR0(TIMER2) +#define TIMER3_CR0 TIMER_CR0(TIMER3) + +/* Capture Register 1 */ +#define TIMER_CR1(timer) MMIO32((timer) + 0x030) +#define TIMER0_CR1 TIMER_CR1(TIMER0) +#define TIMER1_CR1 TIMER_CR1(TIMER1) +#define TIMER2_CR1 TIMER_CR1(TIMER2) +#define TIMER3_CR1 TIMER_CR1(TIMER3) + +/* Capture Register 2 */ +#define TIMER_CR2(timer) MMIO32((timer) + 0x034) +#define TIMER0_CR2 TIMER_CR2(TIMER0) +#define TIMER1_CR2 TIMER_CR2(TIMER1) +#define TIMER2_CR2 TIMER_CR2(TIMER2) +#define TIMER3_CR2 TIMER_CR2(TIMER3) + +/* Capture Register 3 */ +#define TIMER_CR3(timer) MMIO32((timer) + 0x038) +#define TIMER0_CR3 TIMER_CR3(TIMER0) +#define TIMER1_CR3 TIMER_CR3(TIMER1) +#define TIMER2_CR3 TIMER_CR3(TIMER2) +#define TIMER3_CR3 TIMER_CR3(TIMER3) + +/* External Match Register */ +#define TIMER_EMR(timer) MMIO32((timer) + 0x03C) +#define TIMER0_EMR TIMER_EMR(TIMER0) +#define TIMER1_EMR TIMER_EMR(TIMER1) +#define TIMER2_EMR TIMER_EMR(TIMER2) +#define TIMER3_EMR TIMER_EMR(TIMER3) + +/* Count Control Register */ +#define TIMER_CTCR(timer) MMIO32((timer) + 0x070) +#define TIMER0_CTCR TIMER_CTCR(TIMER0) +#define TIMER1_CTCR TIMER_CTCR(TIMER1) +#define TIMER2_CTCR TIMER_CTCR(TIMER2) +#define TIMER3_CTCR TIMER_CTCR(TIMER3) + +/* --- TIMERx_IR values ----------------------------------------------------- */ + +#define TIMER_IR_MR0INT (1 << 0) +#define TIMER_IR_MR1INT (1 << 1) +#define TIMER_IR_MR2INT (1 << 2) +#define TIMER_IR_MR3INT (1 << 3) +#define TIMER_IR_CR0INT (1 << 4) +#define TIMER_IR_CR1INT (1 << 5) +#define TIMER_IR_CR2INT (1 << 6) +#define TIMER_IR_CR3INT (1 << 7) + +/* --- TIMERx_TCR values --------------------------------------------------- */ + +#define TIMER_TCR_CEN (1 << 0) +#define TIMER_TCR_CRST (1 << 1) + +/* --- TIMERx_MCR values --------------------------------------------------- */ + +#define TIMER_MCR_MR0I (1 << 0) +#define TIMER_MCR_MR0R (1 << 1) +#define TIMER_MCR_MR0S (1 << 2) +#define TIMER_MCR_MR1I (1 << 3) +#define TIMER_MCR_MR1R (1 << 4) +#define TIMER_MCR_MR1S (1 << 5) +#define TIMER_MCR_MR2I (1 << 6) +#define TIMER_MCR_MR2R (1 << 7) +#define TIMER_MCR_MR2S (1 << 8) +#define TIMER_MCR_MR3I (1 << 9) +#define TIMER_MCR_MR3R (1 << 10) +#define TIMER_MCR_MR3S (1 << 11) + +/* --- TIMERx_MCR values --------------------------------------------------- */ + +#define TIMER_CCR_CAP0RE (1 << 0) +#define TIMER_CCR_CAP0FE (1 << 1) +#define TIMER_CCR_CAP0I (1 << 2) +#define TIMER_CCR_CAP1RE (1 << 3) +#define TIMER_CCR_CAP1FE (1 << 4) +#define TIMER_CCR_CAP1I (1 << 5) +#define TIMER_CCR_CAP2RE (1 << 6) +#define TIMER_CCR_CAP2FE (1 << 7) +#define TIMER_CCR_CAP2I (1 << 8) +#define TIMER_CCR_CAP3RE (1 << 9) +#define TIMER_CCR_CAP3FE (1 << 10) +#define TIMER_CCR_CAP3I (1 << 11) + +/* --- TIMERx_EMR values --------------------------------------------------- */ + +#define TIMER_EMR_EM0 (1 << 0) +#define TIMER_EMR_EM1 (1 << 1) +#define TIMER_EMR_EM2 (1 << 2) +#define TIMER_EMR_EM3 (1 << 3) +#define TIMER_EMR_EMC0_SHIFT 4 +#define TIMER_EMR_EMC0_MASK (0x3 << TIMER_EMR_EMC0_SHIFT) +#define TIMER_EMR_EMC1_SHIFT 6 +#define TIMER_EMR_EMC1_MASK (0x3 << TIMER_EMR_EMC1_SHIFT) +#define TIMER_EMR_EMC2_SHIFT 8 +#define TIMER_EMR_EMC2_MASK (0x3 << TIMER_EMR_EMC2_SHIFT) +#define TIMER_EMR_EMC3_SHIFT 10 +#define TIMER_EMR_EMC3_MASK (0x3 << TIMER_EMR_EMC3_SHIFT) + +#define TIMER_EMR_EMC_NOTHING 0x0 +#define TIMER_EMR_EMC_CLEAR 0x1 +#define TIMER_EMR_EMC_SET 0x2 +#define TIMER_EMR_EMC_TOGGLE 0x3 + +/* --- TIMERx_CTCR values -------------------------------------------------- */ + +#define TIMER_CTCR_MODE_TIMER (0x0 << 0) +#define TIMER_CTCR_MODE_COUNTER_RISING (0x1 << 0) +#define TIMER_CTCR_MODE_COUNTER_FALLING (0x2 << 0) +#define TIMER_CTCR_MODE_COUNTER_BOTH (0x3 << 0) +#define TIMER_CTCR_MODE_MASK (0x3 << 0) + +#define TIMER_CTCR_CINSEL_CAPN_0 (0x0 << 2) +#define TIMER_CTCR_CINSEL_CAPN_1 (0x1 << 2) +#define TIMER_CTCR_CINSEL_CAPN_2 (0x2 << 2) +#define TIMER_CTCR_CINSEL_CAPN_3 (0x3 << 2) +#define TIMER_CTCR_CINSEL_MASK (0x3 << 2) + +/* --- TIMER function prototypes ------------------------------------------- */ + +BEGIN_DECLS + +void timer_reset(uint32_t timer_peripheral); +void timer_enable_counter(uint32_t timer_peripheral); +void timer_disable_counter(uint32_t timer_peripheral); +uint32_t timer_get_counter(uint32_t timer_peripheral); +void timer_set_counter(uint32_t timer_peripheral, uint32_t count); +uint32_t timer_get_prescaler(uint32_t timer_peripheral); +void timer_set_prescaler(uint32_t timer_peripheral, uint32_t prescaler); +void timer_set_mode(uint32_t timer_peripheral, uint32_t mode); +void timer_set_count_input(uint32_t timer_peripheral, uint32_t input); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/uart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/uart.h new file mode 100644 index 00000000..5ec45336 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/uart.h @@ -0,0 +1,438 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* This library is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This library 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this library. If not, see . +*/ + +#ifndef LPC43XX_UART_H +#define LPC43XX_UART_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* UART port base addresses (for convenience) */ +#define UART0 USART0_BASE /* APB0 */ +#define UART1 UART1_BASE /* APB0 */ +#define UART2 USART2_BASE /* APB2 */ +#define UART3 USART3_BASE /* APB2 */ + +/* --- UART registers ------------------------------------------------------- */ + +/* Receiver Buffer Register (DLAB=0) Read Only */ +#define UART_RBR(port) MMIO32((port) + 0x000) /* 8bits */ + +/* Transmitter Holding Register (DLAB=0) Write Only */ +#define UART_THR(port) MMIO32((port) + 0x000) /* 8bits */ + +/* Divisor Latch LSB Register (DLAB=1) */ +#define UART_DLL(port) MMIO32((port) + 0x000) /* 8bits */ + +/* Divisor Latch MSB Register (DLAB=1) */ +#define UART_DLM(port) MMIO32((port) + 0x004) /* 8bits */ + +/* Interrupt Enable Register (DLAB=0) */ +#define UART_IER(port) MMIO32((port) + 0x004) + +/* Interrupt ID Register Read Only */ +#define UART_IIR(port) MMIO32((port) + 0x008) + +/* FIFO Control Register Write Only */ +#define UART_FCR(port) MMIO32((port) + 0x008) + +/* Line Control Register */ +#define UART_LCR(port) MMIO32((port) + 0x00C) + +/* MCR only for UART1 */ + +/* Line Status Register */ +#define UART_LSR(port) MMIO32((port) + 0x014) + +/* Auto Baud Control Register */ +#define UART_ACR(port) MMIO32((port) + 0x020) + +/* IrDA Control Register only for UART0/2/3 */ +#define UART_ICR(port) MMIO32((port) + 0x024) + +/* Fractional Divider Register */ +#define UART_FDR(port) MMIO32((port) + 0x028) + +/* Oversampling Register only for UART0/2/3 */ +#define UART_OSR(port) MMIO32((port) + 0x02C) + +/* Half-Duplex enable Register only for UART0/2/3 */ +#define UART_HDEN(port) MMIO32((port) + 0x040) + +/* Smart card Interface Register Only for UART0/2/3 */ +#define UART_SCICTRL(port) MMIO32((port) + 0x048) + +/* RS-485/EIA-485 Control Register */ +#define UART_RS485CTRL(port) MMIO32((port) + 0x04C) + +/* RS-485/EIA-485 Address Match Register */ +#define UART_RS485ADRMATCH(port) MMIO32((port) + 0x050) + +/* RS-485/EIA-485 Direction Control Delay Register */ +#define UART_RS485DLY(port) MMIO32((port) + 0x054) + +/* Synchronous Mode Control Register only for UART0/2/3 */ +#define UART_SYNCCTRL(port) MMIO32((port) + 0x058) + +/* Transmit Enable Register */ +#define UART_TER(port) MMIO32((port) + 0x05C) + +/* --------------------- BIT DEFINITIONS ----------------------------------- */ +/*********************************************************************** +* Macro defines for Macro defines for UARTn Receiver Buffer Register +**********************************************************************/ +/* UART Received Buffer mask bit (8 bits) */ +#define UART_RBR_MASKBIT ((uint8_t)0xFF) + +/*********************************************************************** +* Macro defines for Macro defines for UARTn Transmit Holding Register +**********************************************************************/ +/* UART Transmit Holding mask bit (8 bits) */ +#define UART_THR_MASKBIT ((uint8_t)0xFF) + +/*********************************************************************** +* Macro defines for Macro defines for UARTn Divisor Latch LSB register +**********************************************************************/ +/* Macro for loading least significant halfs of divisors */ +#define UART_LOAD_DLL(div) ((div) & 0xFF) + +/* Divisor latch LSB bit mask */ +#define UART_DLL_MASKBIT ((uint8_t)0xFF) + +/*********************************************************************** +* Macro defines for Macro defines for UARTn Divisor Latch MSB register +**********************************************************************/ +/* Divisor latch MSB bit mask */ +#define UART_DLM_MASKBIT ((uint8_t)0xFF) + +/* Macro for loading most significant halfs of divisors */ +#define UART_LOAD_DLM(div) (((div) >> 8) & 0xFF) + +/*********************************************************************** +* Macro defines for Macro defines for UART interrupt enable register +**********************************************************************/ +/* RBR Interrupt enable*/ +#define UART_IER_RBRINT_EN (1 << 0) +/* THR Interrupt enable*/ +#define UART_IER_THREINT_EN (1 << 1) +/* RX line status interrupt enable*/ +#define UART_IER_RLSINT_EN (1 << 2) +/* Modem status interrupt enable */ +#define UART1_IER_MSINT_EN (1 << 3) +/* CTS1 signal transition interrupt enable */ +#define UART1_IER_CTSINT_EN (1 << 7) +/* Enables the end of auto-baud interrupt */ +#define UART_IER_ABEOINT_EN (1 << 8) +/* Enables the auto-baud time-out interrupt */ +#define UART_IER_ABTOINT_EN (1 << 9) +/* UART interrupt enable register bit mask */ +#define UART_IER_BITMASK ((uint32_t)(0x307)) +/* UART1 interrupt enable register bit mask */ +#define UART1_IER_BITMASK ((uint32_t)(0x38F)) + +/********************************************************************** +* Macro defines for Macro defines for UART interrupt identification register +**********************************************************************/ + +/* Interrupt Status - Active low */ +#define UART_IIR_INTSTAT_PEND (1 << 0) +/* Interrupt identification: Modem interrupt*/ +#define UART1_IIR_INTID_MODEM (0 << 1) +/* Interrupt identification: THRE interrupt*/ +#define UART_IIR_INTID_THRE (1 << 1) +/* Interrupt identification: Receive data available*/ +#define UART_IIR_INTID_RDA (2 << 1) +/* Interrupt identification: Receive line status*/ +#define UART_IIR_INTID_RLS (3 << 1) +/* Interrupt identification: Character time-out indicator*/ +#define UART_IIR_INTID_CTI (6 << 1) +/* Interrupt identification: Interrupt ID mask */ +#define UART_IIR_INTID_MASK (7 << 1) +/* These bits are equivalent to UnFCR[0] */ +#define UART_IIR_FIFO_EN (3 << 6) +/* End of auto-baud interrupt */ +#define UART_IIR_ABEO_INT (1 << 8) +/* Auto-baud time-out interrupt */ +#define UART_IIR_ABTO_INT (1 << 9) +/* UART interrupt identification register bit mask */ +#define UART_IIR_BITMASK ((uint32_t)(0x3CF)) + +/********************************************************************** +* Macro defines for Macro defines for UART FIFO control register +**********************************************************************/ +/* UART FIFO enable */ +#define UART_FCR_FIFO_EN (1 << 0) +/* UART FIFO RX reset */ +#define UART_FCR_RX_RS (1 << 1) +/* UART FIFO TX reset */ +#define UART_FCR_TX_RS (1 << 2) +/* UART DMA mode selection */ +#define UART_FCR_DMAMODE_SEL (1 << 3) +/* UART FIFO trigger level 0: 1 character */ +#define UART_FCR_TRG_LEV0 (0 << 6) +/* UART FIFO trigger level 1: 4 character */ +#define UART_FCR_TRG_LEV1 (1 << 6) +/* UART FIFO trigger level 2: 8 character */ +#define UART_FCR_TRG_LEV2 (2 << 6) +/* UART FIFO trigger level 3: 14 character */ +#define UART_FCR_TRG_LEV3 (3 << 6) +/* UART FIFO control bit mask */ +#define UART_FCR_BITMASK ((uint8_t)(0xCF)) +#define UART_TX_FIFO_SIZE (16) + +/********************************************************************** +* Macro defines for Macro defines for UART line control register +**********************************************************************/ +/* UART 5 bit data mode */ +#define UART_LCR_WLEN5 (0 << 0) +/* UART 6 bit data mode */ +#define UART_LCR_WLEN6 (1 << 0) +/* UART 7 bit data mode */ +#define UART_LCR_WLEN7 (2 << 0) +/* UART 8 bit data mode */ +#define UART_LCR_WLEN8 (3 << 0) +/* UART One Stop Bits */ +#define UART_LCR_ONE_STOPBIT (0 << 2) +/* UART Two Stop Bits */ +#define UART_LCR_TWO_STOPBIT (1 << 2) + +/* UART Parity Disabled / No Parity */ +#define UART_LCR_NO_PARITY (0 << 3) +/* UART Parity Enable */ +#define UART_LCR_PARITY_EN (1 << 3) +/* UART Odd Parity Select */ +#define UART_LCR_PARITY_ODD (0 << 4) +/* UART Even Parity Select */ +#define UART_LCR_PARITY_EVEN (1 << 4) +/* UART force 1 stick parity */ +#define UART_LCR_PARITY_SP_1 (1 << 5) +/* UART force 0 stick parity */ +#define UART_LCR_PARITY_SP_0 ((1 << 5) | (1 << 4)) +/* UART Transmission Break enable */ +#define UART_LCR_BREAK_EN (1 << 6) +/* UART Divisor Latches Access bit enable */ +#define UART_LCR_DLAB_EN (1 << 7) +/* UART line control bit mask */ +#define UART_LCR_BITMASK ((uint8_t)(0xFF)) + +/********************************************************************** +* Macro defines for Macro defines for UART line status register +**********************************************************************/ +/* Line status register: Receive data ready */ +#define UART_LSR_RDR (1 << 0) +/* Line status register: Overrun error */ +#define UART_LSR_OE (1 << 1) +/* Line status register: Parity error */ +#define UART_LSR_PE (1 << 2) +/* Line status register: Framing error */ +#define UART_LSR_FE (1 << 3) +/* Line status register: Break interrupt */ +#define UART_LSR_BI (1 << 4) +/* Line status register: Transmit holding register empty */ +#define UART_LSR_THRE (1 << 5) +/* Line status register: Transmitter empty */ +#define UART_LSR_TEMT (1 << 6) +/* Error in RX FIFO */ +#define UART_LSR_RXFE (1 << 7) +/* UART Line status bit mask */ +#define UART_LSR_BITMASK ((uint8_t)(0xFF)) +#define UART_LSR_ERROR_MASK \ + (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE | UART_LSR_BI | UART_LSR_RXFE) + +/********************************************************************** +* Macro defines for Macro defines for UART Scratch Pad Register +**********************************************************************/ + +/* UART Scratch Pad bit mask */ +#define UART_SCR_BIMASK ((uint8_t)(0xFF)) + +/*********************************************************************** +* Macro defines for Macro defines for UART Auto baudrate control register +**********************************************************************/ + +/* UART Auto-baud start */ +#define UART_ACR_START (1 << 0) +/* UART Auto baudrate Mode 1 */ +#define UART_ACR_MODE (1 << 1) +/* UART Auto baudrate restart */ +#define UART_ACR_AUTO_RESTART (1 << 2) +/* UART End of auto-baud interrupt clear */ +#define UART_ACR_ABEOINT_CLR (1 << 8) +/* UART Auto-baud time-out interrupt clear */ +#define UART_ACR_ABTOINT_CLR (1 << 9) +/* UART Auto Baudrate register bit mask */ +#define UART_ACR_BITMASK ((uint32_t)(0x307)) + +/********************************************************************* +* Macro defines for Macro defines for UART IrDA control register +**********************************************************************/ +/* IrDA mode enable */ +#define UART_ICR_IRDAEN (1 << 0) +/* IrDA serial input inverted */ +#define UART_ICR_IRDAINV (1 << 1) +/* IrDA fixed pulse width mode */ +#define UART_ICR_FIXPULSE_EN (1 << 2) +/* PulseDiv - Configures the pulse when FixPulseEn = 1 */ +#define UART_ICR_PULSEDIV(n) ((uint32_t)(((n)&0x07)<<3)) +/* UART IRDA bit mask */ +#define UART_ICR_BITMASK ((uint32_t)(0x3F)) + +/********************************************************************** +* Macro defines for Macro defines for UART half duplex register +**********************************************************************/ +/* enable half-duplex mode*/ +#define UART_HDEN_HDEN (1 << 0) + +/********************************************************************** +* Macro defines for Macro defines for UART smart card interface control register +**********************************************************************/ +/* enable asynchronous half-duplex smart card interface*/ +#define UART_SCICTRL_SCIEN (1 << 0) +/* NACK response is inhibited*/ +#define UART_SCICTRL_NACKDIS (1 << 1) +/* ISO7816-3 protocol T1 is selected*/ +#define UART_SCICTRL_PROTSEL_T1 (1 << 2) +/* number of retransmission*/ +#define UART_SCICTRL_TXRETRY(n) ((uint32_t)(((n)&0x07)<<5)) +/* Extra guard time*/ +#define UART_SCICTRL_GUARDTIME(n) ((uint32_t)(((n)&0xFF)<<8)) + +/********************************************************************* +* Macro defines for Macro defines for UART synchronous control register +**********************************************************************/ +/* enable synchronous mode*/ +#define UART_SYNCCTRL_SYNC (1 << 0) +/* synchronous master mode*/ +#define UART_SYNCCTRL_CSRC_MASTER (1 << 1) +/* sample on falling edge*/ +#define UART_SYNCCTRL_FES (1 << 2) +/* to be defined*/ +#define UART_SYNCCTRL_TSBYPASS (1 << 3) +/* continuous running clock enable (master mode only) */ +#define UART_SYNCCTRL_CSCEN (1 << 4) +/* Do not send start/stop bit */ +#define UART_SYNCCTRL_NOSTARTSTOP (1 << 5) +/* stop continuous clock */ +#define UART_SYNCCTRL_CCCLR (1 << 6) + +/********************************************************************* +* Macro defines for Macro defines for UART Fractional divider register +**********************************************************************/ + +/* Baud-rate generation pre-scaler divisor */ +#define UART_FDR_DIVADDVAL(n) ((uint32_t)((n)&0x0F)) +/* Baud-rate pre-scaler multiplier value */ +#define UART_FDR_MULVAL(n) ((uint32_t)(((n)<<4)&0xF0)) +/* UART Fractional Divider register bit mask */ +#define UART_FDR_BITMASK ((uint32_t)(0xFF)) + +/********************************************************************* +* Macro defines for Macro defines for UART Tx Enable register +**********************************************************************/ + +#define UART_TER_TXEN (1 << 0) /* Transmit enable bit */ + +/********************************************************************** +* Macro defines for Macro defines for UART FIFO Level register +**********************************************************************/ +/* Reflects the current level of the UART receiver FIFO */ +#define UART_FIFOLVL_RX(n) ((uint32_t)((n)&0x0F)) +/* Reflects the current level of the UART transmitter FIFO */ +#define UART_FIFOLVL_TX(n) ((uint32_t)(((n)>>8)&0x0F)) +/* UART FIFO Level Register bit mask */ +#define UART_FIFOLVL_BITMASK ((uint32_t)(0x0F0F)) + +/********************************************************************* +* UART enum +**********************************************************************/ + +/* +* UART Databit type definitions +*/ +typedef enum { + UART_DATABIT_5 = UART_LCR_WLEN5,/* UART 5 bit data mode */ + UART_DATABIT_6 = UART_LCR_WLEN6,/* UART 6 bit data mode */ + UART_DATABIT_7 = UART_LCR_WLEN7,/* UART 7 bit data mode */ + UART_DATABIT_8 = UART_LCR_WLEN8/* UART 8 bit data mode */ +} uart_databit_t; + +/* +* UART Stop bit type definitions +*/ +typedef enum { + /* UART 1 Stop Bits Select */ + UART_STOPBIT_1 = UART_LCR_ONE_STOPBIT, + /* UART 2 Stop Bits Select */ + UART_STOPBIT_2 = UART_LCR_TWO_STOPBIT +} uart_stopbit_t; + +/* +* UART Parity type definitions +*/ +typedef enum { + /* No parity */ + UART_PARITY_NONE = UART_LCR_NO_PARITY, + /* Odd parity */ + UART_PARITY_ODD = (UART_LCR_PARITY_ODD | UART_LCR_PARITY_EN), + /* Even parity */ + UART_PARITY_EVEN = (UART_LCR_PARITY_EVEN | UART_LCR_PARITY_EN), + /* Forced 1 stick parity */ + UART_PARITY_SP_1 = (UART_LCR_PARITY_SP_1 | UART_LCR_PARITY_EN), + /* Forced 0 stick parity */ + UART_PARITY_SP_0 = (UART_LCR_PARITY_SP_0 | UART_LCR_PARITY_EN) +} uart_parity_t; + +typedef enum { + UART0_NUM = UART0, + UART1_NUM = UART1, + UART2_NUM = UART2, + UART3_NUM = UART3 +} uart_num_t; + +typedef enum { + UART_NO_ERROR = 0, + UART_TIMEOUT_ERROR = 1 +} uart_error_t; + +typedef enum { + UART_RX_NO_DATA = 0, + UART_RX_DATA_READY = 1, + UART_RX_DATA_ERROR = 2 +} uart_rx_data_ready_t; + +/* function prototypes */ + +BEGIN_DECLS + +/* Init UART and set PLL1 as clock source (PCLK) */ +void uart_init(uart_num_t uart_num, uart_databit_t data_nb_bits, + uart_stopbit_t data_nb_stop, uart_parity_t data_parity, + uint16_t uart_divisor, uint8_t uart_divaddval, uint8_t uart_mulval); + +uart_rx_data_ready_t uart_rx_data_ready(uart_num_t uart_num); +uint8_t uart_read(uart_num_t uart_num); +uint8_t uart_read_timeout(uart_num_t uart_num, uint32_t rx_timeout_nb_cycles, + uart_error_t *error); +void uart_write(uart_num_t uart_num, uint8_t data); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/usb.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/usb.h new file mode 100644 index 00000000..9132fb7f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/usb.h @@ -0,0 +1,1337 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_USB_H +#define LPC43XX_USB_H + +#include +#include + +#define BIT_MASK(base_name) \ + (((1 << base_name##_WIDTH) - 1) << base_name##_SHIFT) +#define BIT_ARG(base_name, x) ((x) << base_name##_SHIFT) + +/* USB device data structures */ + +/* "The software must ensure that no interface data structure reachable + * by the Device controller crosses a 4kB-page boundary." + */ + +/* --- Endpoint Transfer Descriptor (dTD) ---------------------------------- */ + +typedef struct usb_transfer_descriptor_t usb_transfer_descriptor_t; +struct usb_transfer_descriptor_t { + volatile usb_transfer_descriptor_t *next_dtd_pointer; + volatile uint32_t total_bytes; + volatile uint32_t buffer_pointer_page[5]; + volatile uint32_t _reserved; +}; + +#define USB_TD_NEXT_DTD_POINTER_TERMINATE_SHIFT (0) +#define USB_TD_NEXT_DTD_POINTER_TERMINATE \ + ((volatile usb_transfer_descriptor_t *) \ + (1 << USB_TD_NEXT_DTD_POINTER_TERMINATE_SHIFT)) + +#define USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT (16) +#define USB_TD_DTD_TOKEN_TOTAL_BYTES_WIDTH (15) +#define USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK BIT_MASK(USB_TD_DTD_TOKEN_TOTAL_BYTES) +#define USB_TD_DTD_TOKEN_TOTAL_BYTES(x) BIT_ARG(USB_TD_DTD_TOKEN_TOTAL_BYTES, (x)) + +#define USB_TD_DTD_TOKEN_IOC_SHIFT (15) +#define USB_TD_DTD_TOKEN_IOC (1 << USB_TD_DTD_TOKEN_IOC_SHIFT) + +#define USB_TD_DTD_TOKEN_MULTO_SHIFT (10) +#define USB_TD_DTD_TOKEN_MULTO_WIDTH (2) +#define USB_TD_DTD_TOKEN_MULTO_MASK BIT_MASK(USB_TD_DTD_TOKEN_MULTO) +#define USB_TD_DTD_TOKEN_MULTO(x) BIT_ARG(USB_TD_DTD_TOKEN_MULTO, (x)) + +#define USB_TD_DTD_TOKEN_STATUS_ACTIVE_SHIFT (7) +#define USB_TD_DTD_TOKEN_STATUS_ACTIVE \ + (1 << USB_TD_DTD_TOKEN_STATUS_ACTIVE_SHIFT) + +#define USB_TD_DTD_TOKEN_STATUS_HALTED_SHIFT (6) +#define USB_TD_DTD_TOKEN_STATUS_HALTED \ + (1 << USB_TD_DTD_TOKEN_STATUS_HALTED_SHIFT) + +#define USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR_SHIFT (5) +#define USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR \ + (1 << USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR_SHIFT) + +#define USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR_SHIFT (3) +#define USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR \ + (1 << USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR_SHIFT) + +/* --- Endpoint Queue Head (dQH) ------------------------------------------- */ + +/* - must be aligned on 64-byte boundaries. */ +typedef struct { + volatile uint32_t capabilities; + volatile usb_transfer_descriptor_t *current_dtd_pointer; + volatile usb_transfer_descriptor_t *next_dtd_pointer; + volatile uint32_t total_bytes; + volatile uint32_t buffer_pointer_page[5]; + volatile uint32_t _reserved_0; + volatile uint8_t setup[8]; + volatile uint32_t _reserved_1[4]; +} usb_queue_head_t; + +#define USB_QH_CAPABILITIES_IOS_SHIFT (15) +#define USB_QH_CAPABILITIES_IOS (1 << USB_QH_CAPABILITIES_IOS_SHIFT) + +#define USB_QH_CAPABILITIES_MPL_SHIFT (16) +#define USB_QH_CAPABILITIES_MPL_WIDTH (11) +#define USB_QH_CAPABILITIES_MPL_MASK BIT_MASK(USB_QH_CAPABILITIES_MPL) +#define USB_QH_CAPABILITIES_MPL(x) BIT_ARG(USB_QH_CAPABILITIES_MPL, (x)) + +#define USB_QH_CAPABILITIES_ZLT_SHIFT (29) +#define USB_QH_CAPABILITIES_ZLT (1 << USB_QH_CAPABILITIES_ZLT_SHIFT) + +#define USB_QH_CAPABILITIES_MULT_SHIFT (30) +#define USB_QH_CAPABILITIES_MULT_WIDTH (2) +#define USB_QH_CAPABILITIES_MULT_MASK BIT_MASK(USB_QH_CAPABILITIES_MULT) +#define USB_QH_CAPABILITIES_MULT(x) BIT_ARG(USB_QH_CAPABILITIES_MULT, (x)) + +/* --- USB0 registers ------------------------------------------------------ */ + +/* Device/host capability registers */ + +/* Capability register length */ +#define USB0_CAPLENGTH MMIO32(USB0_BASE + 0x100) + +/* Host controller structural parameters */ +#define USB0_HCSPARAMS MMIO32(USB0_BASE + 0x104) + +/* Host controller capability parameters */ +#define USB0_HCCPARAMS MMIO32(USB0_BASE + 0x108) + +/* Device interface version number */ +#define USB0_DCIVERSION MMIO32(USB0_BASE + 0x120) + +/* Device controller capability parameters */ +#define USB0_DCCPARAMS MMIO32(USB0_BASE + 0x124) + + +/* Device/host operational registers */ + +/* USB command (device mode) */ +#define USB0_USBCMD_D MMIO32(USB0_BASE + 0x140) + +/* USB command (host mode) */ +#define USB0_USBCMD_H MMIO32(USB0_BASE + 0x140) + +/* USB status (device mode) */ +#define USB0_USBSTS_D MMIO32(USB0_BASE + 0x144) + +/* USB status (host mode) */ +#define USB0_USBSTS_H MMIO32(USB0_BASE + 0x144) + +/* USB interrupt enable (device mode) */ +#define USB0_USBINTR_D MMIO32(USB0_BASE + 0x148) + +/* USB interrupt enable (host mode) */ +#define USB0_USBINTR_H MMIO32(USB0_BASE + 0x148) + +/* USB frame index (device mode) */ +#define USB0_FRINDEX_D MMIO32(USB0_BASE + 0x14C) + +/* USB frame index (host mode) */ +#define USB0_FRINDEX_H MMIO32(USB0_BASE + 0x14C) + +/* USB device address (device mode) */ +#define USB0_DEVICEADDR MMIO32(USB0_BASE + 0x154) + +/* Frame list base address (host mode) */ +#define USB0_PERIODICLISTBASE MMIO32(USB0_BASE + 0x154) + +/* Address of endpoint list in memory */ +#define USB0_ENDPOINTLISTADDR MMIO32(USB0_BASE + 0x158) + +/* Asynchronous list address */ +#define USB0_ASYNCLISTADDR MMIO32(USB0_BASE + 0x158) + +/* Asynchronous buffer status for embedded TT (host mode) */ +#define USB0_TTCTRL MMIO32(USB0_BASE + 0x15C) + +/* Programmable burst size */ +#define USB0_BURSTSIZE MMIO32(USB0_BASE + 0x160) + +/* Host transmit pre-buffer packet tuning (host mode) */ +#define USB0_TXFILLTUNING MMIO32(USB0_BASE + 0x164) + +/* Length of virtual frame */ +#define USB0_BINTERVAL MMIO32(USB0_BASE + 0x174) + +/* Endpoint NAK (device mode) */ +#define USB0_ENDPTNAK MMIO32(USB0_BASE + 0x178) + +/* Endpoint NAK Enable (device mode) */ +#define USB0_ENDPTNAKEN MMIO32(USB0_BASE + 0x17C) + +/* Port 1 status/control (device mode) */ +#define USB0_PORTSC1_D MMIO32(USB0_BASE + 0x184) + +/* Port 1 status/control (host mode) */ +#define USB0_PORTSC1_H MMIO32(USB0_BASE + 0x184) + +/* OTG status and control */ +#define USB0_OTGSC MMIO32(USB0_BASE + 0x1A4) + +/* USB device mode (device mode) */ +#define USB0_USBMODE_D MMIO32(USB0_BASE + 0x1A8) + +/* USB device mode (host mode) */ +#define USB0_USBMODE_H MMIO32(USB0_BASE + 0x1A8) + + +/* Device endpoint registers */ + +/* Endpoint setup status */ +#define USB0_ENDPTSETUPSTAT MMIO32(USB0_BASE + 0x1AC) + +/* Endpoint initialization */ +#define USB0_ENDPTPRIME MMIO32(USB0_BASE + 0x1B0) + +/* Endpoint de-initialization */ +#define USB0_ENDPTFLUSH MMIO32(USB0_BASE + 0x1B4) + +/* Endpoint status */ +#define USB0_ENDPTSTAT MMIO32(USB0_BASE + 0x1B8) + +/* Endpoint complete */ +#define USB0_ENDPTCOMPLETE MMIO32(USB0_BASE + 0x1BC) + +/* Endpoint control */ +#define USB0_ENDPTCTRL(logical_ep) MMIO32(USB0_BASE + 0x1C0 + \ + ((logical_ep) * 4)) + +/* Endpoint control 0 */ +#define USB0_ENDPTCTRL0 USB0_ENDPTCTRL(0) + +/* Endpoint control 1 */ +#define USB0_ENDPTCTRL1 USB0_ENDPTCTRL(1) + +/* Endpoint control 2 */ +#define USB0_ENDPTCTRL2 USB0_ENDPTCTRL(2) + +/* Endpoint control 3 */ +#define USB0_ENDPTCTRL3 USB0_ENDPTCTRL(3) + +/* Endpoint control 4 */ +#define USB0_ENDPTCTRL4 USB0_ENDPTCTRL(4) + +/* Endpoint control 5 */ +#define USB0_ENDPTCTRL5 USB0_ENDPTCTRL(5) + +/* --- USB0_CAPLENGTH values ------------------------------------ */ + +/* CAPLENGTH: Indicates offset to add to the register base address at the + beginning of the Operational Register */ +#define USB0_CAPLENGTH_CAPLENGTH_SHIFT (0) +#define USB0_CAPLENGTH_CAPLENGTH_MASK (0xff << USB0_CAPLENGTH_CAPLENGTH_SHIFT) +#define USB0_CAPLENGTH_CAPLENGTH(x) ((x) << USB0_CAPLENGTH_CAPLENGTH_SHIFT) + +/* HCIVERSION: BCD encoding of the EHCI revision number supported by this host + controller */ +#define USB0_CAPLENGTH_HCIVERSION_SHIFT (8) +#define USB0_CAPLENGTH_HCIVERSION_MASK \ + (0xffff << USB0_CAPLENGTH_HCIVERSION_SHIFT) +#define USB0_CAPLENGTH_HCIVERSION(x) ((x) << USB0_CAPLENGTH_HCIVERSION_SHIFT) + +/* --- USB0_HCSPARAMS values ------------------------------------ */ + +/* N_PORTS: Number of downstream ports */ +#define USB0_HCSPARAMS_N_PORTS_SHIFT (0) +#define USB0_HCSPARAMS_N_PORTS_MASK (0xf << USB0_HCSPARAMS_N_PORTS_SHIFT) +#define USB0_HCSPARAMS_N_PORTS(x) ((x) << USB0_HCSPARAMS_N_PORTS_SHIFT) + +/* PPC: Port Power Control */ +#define USB0_HCSPARAMS_PPC_SHIFT (4) +#define USB0_HCSPARAMS_PPC (1 << USB0_HCSPARAMS_PPC_SHIFT) + +/* N_PCC: Number of Ports per Companion Controller */ +#define USB0_HCSPARAMS_N_PCC_SHIFT (8) +#define USB0_HCSPARAMS_N_PCC_MASK (0xf << USB0_HCSPARAMS_N_PCC_SHIFT) +#define USB0_HCSPARAMS_N_PCC(x) ((x) << USB0_HCSPARAMS_N_PCC_SHIFT) + +/* N_CC: Number of Companion Controller */ +#define USB0_HCSPARAMS_N_CC_SHIFT (12) +#define USB0_HCSPARAMS_N_CC_MASK (0xf << USB0_HCSPARAMS_N_CC_SHIFT) +#define USB0_HCSPARAMS_N_CC(x) ((x) << USB0_HCSPARAMS_N_CC_SHIFT) + +/* PI: Port indicators */ +#define USB0_HCSPARAMS_PI_SHIFT (16) +#define USB0_HCSPARAMS_PI (1 << USB0_HCSPARAMS_PI_SHIFT) + +/* N_PTT: Number of Ports per Transaction Translator */ +#define USB0_HCSPARAMS_N_PTT_SHIFT (20) +#define USB0_HCSPARAMS_N_PTT_MASK (0xf << USB0_HCSPARAMS_N_PTT_SHIFT) +#define USB0_HCSPARAMS_N_PTT(x) ((x) << USB0_HCSPARAMS_N_PTT_SHIFT) + +/* N_TT: Number of Transaction Translators */ +#define USB0_HCSPARAMS_N_TT_SHIFT (24) +#define USB0_HCSPARAMS_N_TT_MASK (0xf << USB0_HCSPARAMS_N_TT_SHIFT) +#define USB0_HCSPARAMS_N_TT(x) ((x) << USB0_HCSPARAMS_N_TT_SHIFT) + +/* --- USB0_HCCPARAMS values ------------------------------------ */ + +/* ADC: 64-bit Addressing Capability */ +#define USB0_HCCPARAMS_ADC_SHIFT (0) +#define USB0_HCCPARAMS_ADC (1 << USB0_HCCPARAMS_ADC_SHIFT) + +/* PFL: Programmable Frame List Flag */ +#define USB0_HCCPARAMS_PFL_SHIFT (1) +#define USB0_HCCPARAMS_PFL (1 << USB0_HCCPARAMS_PFL_SHIFT) + +/* ASP: Asynchronous Schedule Park Capability */ +#define USB0_HCCPARAMS_ASP_SHIFT (2) +#define USB0_HCCPARAMS_ASP (1 << USB0_HCCPARAMS_ASP_SHIFT) + +/* IST: Isochronous Scheduling Threshold */ +#define USB0_HCCPARAMS_IST_SHIFT (4) +#define USB0_HCCPARAMS_IST_MASK (0xf << USB0_HCCPARAMS_IST_SHIFT) +#define USB0_HCCPARAMS_IST(x) ((x) << USB0_HCCPARAMS_IST_SHIFT) + +/* EECP: EHCI Extended Capabilities Pointer */ +#define USB0_HCCPARAMS_EECP_SHIFT (8) +#define USB0_HCCPARAMS_EECP_MASK (0xf << USB0_HCCPARAMS_EECP_SHIFT) +#define USB0_HCCPARAMS_EECP(x) ((x) << USB0_HCCPARAMS_EECP_SHIFT) + +/* --- USB0_DCCPARAMS values ------------------------------------ */ + +/* DEN: Device Endpoint Number */ +#define USB0_DCCPARAMS_DEN_SHIFT (0) +#define USB0_DCCPARAMS_DEN_MASK (0x1f << USB0_DCCPARAMS_DEN_SHIFT) +#define USB0_DCCPARAMS_DEN(x) ((x) << USB0_DCCPARAMS_DEN_SHIFT) + +/* DC: Device Capable */ +#define USB0_DCCPARAMS_DC_SHIFT (7) +#define USB0_DCCPARAMS_DC (1 << USB0_DCCPARAMS_DC_SHIFT) + +/* HC: Host Capable */ +#define USB0_DCCPARAMS_HC_SHIFT (8) +#define USB0_DCCPARAMS_HC (1 << USB0_DCCPARAMS_HC_SHIFT) + +/* --- USB0_USBCMD_D values ------------------------------------- */ + +/* RS: Run/Stop */ +#define USB0_USBCMD_D_RS_SHIFT (0) +#define USB0_USBCMD_D_RS (1 << USB0_USBCMD_D_RS_SHIFT) + +/* RST: Controller reset */ +#define USB0_USBCMD_D_RST_SHIFT (1) +#define USB0_USBCMD_D_RST (1 << USB0_USBCMD_D_RST_SHIFT) + +/* SUTW: Setup trip wire */ +#define USB0_USBCMD_D_SUTW_SHIFT (13) +#define USB0_USBCMD_D_SUTW (1 << USB0_USBCMD_D_SUTW_SHIFT) + +/* ATDTW: Add dTD trip wire */ +#define USB0_USBCMD_D_ATDTW_SHIFT (14) +#define USB0_USBCMD_D_ATDTW (1 << USB0_USBCMD_D_ATDTW_SHIFT) + +/* ITC: Interrupt threshold control */ +#define USB0_USBCMD_D_ITC_SHIFT (16) +#define USB0_USBCMD_D_ITC_MASK (0xff << USB0_USBCMD_D_ITC_SHIFT) +#define USB0_USBCMD_D_ITC(x) ((x) << USB0_USBCMD_D_ITC_SHIFT) + +/* --- USB0_USBCMD_H values ------------------------------------- */ + +/* RS: Run/Stop */ +#define USB0_USBCMD_H_RS_SHIFT (0) +#define USB0_USBCMD_H_RS (1 << USB0_USBCMD_H_RS_SHIFT) + +/* RST: Controller reset */ +#define USB0_USBCMD_H_RST_SHIFT (1) +#define USB0_USBCMD_H_RST (1 << USB0_USBCMD_H_RST_SHIFT) + +/* FS0: Bit 0 of the Frame List Size bits */ +#define USB0_USBCMD_H_FS0_SHIFT (2) +#define USB0_USBCMD_H_FS0 (1 << USB0_USBCMD_H_FS0_SHIFT) + +/* FS1: Bit 1 of the Frame List Size bits */ +#define USB0_USBCMD_H_FS1_SHIFT (3) +#define USB0_USBCMD_H_FS1 (1 << USB0_USBCMD_H_FS1_SHIFT) + +/* PSE: This bit controls whether the host controller skips processing the +periodic schedule */ +#define USB0_USBCMD_H_PSE_SHIFT (4) +#define USB0_USBCMD_H_PSE (1 << USB0_USBCMD_H_PSE_SHIFT) + +/* ASE: This bit controls whether the host controller skips processing the +asynchronous schedule */ +#define USB0_USBCMD_H_ASE_SHIFT (5) +#define USB0_USBCMD_H_ASE (1 << USB0_USBCMD_H_ASE_SHIFT) + +/* IAA: This bit is used as a doorbell by software to tell the host controller +to issue an interrupt the next time it advances asynchronous schedule */ +#define USB0_USBCMD_H_IAA_SHIFT (6) +#define USB0_USBCMD_H_IAA (1 << USB0_USBCMD_H_IAA_SHIFT) + +/* ASP1_0: Asynchronous schedule park mode */ +#define USB0_USBCMD_H_ASP1_0_SHIFT (8) +#define USB0_USBCMD_H_ASP1_0_MASK (0x3 << USB0_USBCMD_H_ASP1_0_SHIFT) +#define USB0_USBCMD_H_ASP1_0(x) ((x) << USB0_USBCMD_H_ASP1_0_SHIFT) + +/* ASPE: Asynchronous Schedule Park Mode Enable */ +#define USB0_USBCMD_H_ASPE_SHIFT (11) +#define USB0_USBCMD_H_ASPE (1 << USB0_USBCMD_H_ASPE_SHIFT) + +/* FS2: Bit 2 of the Frame List Size bits */ +#define USB0_USBCMD_H_FS2_SHIFT (15) +#define USB0_USBCMD_H_FS2 (1 << USB0_USBCMD_H_FS2_SHIFT) + +/* ITC: Interrupt threshold control */ +#define USB0_USBCMD_H_ITC_SHIFT (16) +#define USB0_USBCMD_H_ITC_MASK (0xff << USB0_USBCMD_H_ITC_SHIFT) +#define USB0_USBCMD_H_ITC(x) ((x) << USB0_USBCMD_H_ITC_SHIFT) + +/* --- USB0_USBSTS_D values ------------------------------------- */ + +/* UI: USB interrupt */ +#define USB0_USBSTS_D_UI_SHIFT (0) +#define USB0_USBSTS_D_UI (1 << USB0_USBSTS_D_UI_SHIFT) + +/* UEI: USB error interrupt */ +#define USB0_USBSTS_D_UEI_SHIFT (1) +#define USB0_USBSTS_D_UEI (1 << USB0_USBSTS_D_UEI_SHIFT) + +/* PCI: Port change detect */ +#define USB0_USBSTS_D_PCI_SHIFT (2) +#define USB0_USBSTS_D_PCI (1 << USB0_USBSTS_D_PCI_SHIFT) + +/* URI: USB reset received */ +#define USB0_USBSTS_D_URI_SHIFT (6) +#define USB0_USBSTS_D_URI (1 << USB0_USBSTS_D_URI_SHIFT) + +/* SRI: SOF received */ +#define USB0_USBSTS_D_SRI_SHIFT (7) +#define USB0_USBSTS_D_SRI (1 << USB0_USBSTS_D_SRI_SHIFT) + +/* SLI: DCSuspend */ +#define USB0_USBSTS_D_SLI_SHIFT (8) +#define USB0_USBSTS_D_SLI (1 << USB0_USBSTS_D_SLI_SHIFT) + +/* NAKI: NAK interrupt bit */ +#define USB0_USBSTS_D_NAKI_SHIFT (16) +#define USB0_USBSTS_D_NAKI (1 << USB0_USBSTS_D_NAKI_SHIFT) + +/* --- USB0_USBSTS_H values ------------------------------------- */ + +/* UI: USB interrupt */ +#define USB0_USBSTS_H_UI_SHIFT (0) +#define USB0_USBSTS_H_UI (1 << USB0_USBSTS_H_UI_SHIFT) + +/* UEI: USB error interrupt */ +#define USB0_USBSTS_H_UEI_SHIFT (1) +#define USB0_USBSTS_H_UEI (1 << USB0_USBSTS_H_UEI_SHIFT) + +/* PCI: Port change detect */ +#define USB0_USBSTS_H_PCI_SHIFT (2) +#define USB0_USBSTS_H_PCI (1 << USB0_USBSTS_H_PCI_SHIFT) + +/* FRI: Frame list roll-over */ +#define USB0_USBSTS_H_FRI_SHIFT (3) +#define USB0_USBSTS_H_FRI (1 << USB0_USBSTS_H_FRI_SHIFT) + +/* AAI: Interrupt on async advance */ +#define USB0_USBSTS_H_AAI_SHIFT (5) +#define USB0_USBSTS_H_AAI (1 << USB0_USBSTS_H_AAI_SHIFT) + +/* SRI: SOF received */ +#define USB0_USBSTS_H_SRI_SHIFT (7) +#define USB0_USBSTS_H_SRI (1 << USB0_USBSTS_H_SRI_SHIFT) + +/* HCH: HCHalted */ +#define USB0_USBSTS_H_HCH_SHIFT (12) +#define USB0_USBSTS_H_HCH (1 << USB0_USBSTS_H_HCH_SHIFT) + +/* RCL: Reclamation */ +#define USB0_USBSTS_H_RCL_SHIFT (13) +#define USB0_USBSTS_H_RCL (1 << USB0_USBSTS_H_RCL_SHIFT) + +/* PS: Periodic schedule status */ +#define USB0_USBSTS_H_PS_SHIFT (14) +#define USB0_USBSTS_H_PS (1 << USB0_USBSTS_H_PS_SHIFT) + +/* AS: Asynchronous schedule status */ +#define USB0_USBSTS_H_AS_SHIFT (15) +#define USB0_USBSTS_H_AS (1 << USB0_USBSTS_H_AS_SHIFT) + +/* UAI: USB host asynchronous interrupt (USBHSTASYNCINT) */ +#define USB0_USBSTS_H_UAI_SHIFT (18) +#define USB0_USBSTS_H_UAI (1 << USB0_USBSTS_H_UAI_SHIFT) + +/* UPI: USB host periodic interrupt (USBHSTPERINT) */ +#define USB0_USBSTS_H_UPI_SHIFT (19) +#define USB0_USBSTS_H_UPI (1 << USB0_USBSTS_H_UPI_SHIFT) + +/* --- USB0_USBINTR_D values ------------------------------------ */ + +/* UE: USB interrupt enable */ +#define USB0_USBINTR_D_UE_SHIFT (0) +#define USB0_USBINTR_D_UE (1 << USB0_USBINTR_D_UE_SHIFT) + +/* UEE: USB error interrupt enable */ +#define USB0_USBINTR_D_UEE_SHIFT (1) +#define USB0_USBINTR_D_UEE (1 << USB0_USBINTR_D_UEE_SHIFT) + +/* PCE: Port change detect enable */ +#define USB0_USBINTR_D_PCE_SHIFT (2) +#define USB0_USBINTR_D_PCE (1 << USB0_USBINTR_D_PCE_SHIFT) + +/* URE: USB reset enable */ +#define USB0_USBINTR_D_URE_SHIFT (6) +#define USB0_USBINTR_D_URE (1 << USB0_USBINTR_D_URE_SHIFT) + +/* SRE: SOF received enable */ +#define USB0_USBINTR_D_SRE_SHIFT (7) +#define USB0_USBINTR_D_SRE (1 << USB0_USBINTR_D_SRE_SHIFT) + +/* SLE: Sleep enable */ +#define USB0_USBINTR_D_SLE_SHIFT (8) +#define USB0_USBINTR_D_SLE (1 << USB0_USBINTR_D_SLE_SHIFT) + +/* NAKE: NAK interrupt enable */ +#define USB0_USBINTR_D_NAKE_SHIFT (16) +#define USB0_USBINTR_D_NAKE (1 << USB0_USBINTR_D_NAKE_SHIFT) + +/* --- USB0_USBINTR_H values ------------------------------------ */ + +/* UE: USB interrupt enable */ +#define USB0_USBINTR_H_UE_SHIFT (0) +#define USB0_USBINTR_H_UE (1 << USB0_USBINTR_H_UE_SHIFT) + +/* UEE: USB error interrupt enable */ +#define USB0_USBINTR_H_UEE_SHIFT (1) +#define USB0_USBINTR_H_UEE (1 << USB0_USBINTR_H_UEE_SHIFT) + +/* PCE: Port change detect enable */ +#define USB0_USBINTR_H_PCE_SHIFT (2) +#define USB0_USBINTR_H_PCE (1 << USB0_USBINTR_H_PCE_SHIFT) + +/* FRE: Frame list rollover enable */ +#define USB0_USBINTR_H_FRE_SHIFT (3) +#define USB0_USBINTR_H_FRE (1 << USB0_USBINTR_H_FRE_SHIFT) + +/* AAE: Interrupt on asynchronous advance enable */ +#define USB0_USBINTR_H_AAE_SHIFT (5) +#define USB0_USBINTR_H_AAE (1 << USB0_USBINTR_H_AAE_SHIFT) + +/* SRE: SOF received enable */ +#define USB0_USBINTR_H_SRE_SHIFT (7) +#define USB0_USBINTR_H_SRE (1 << USB0_USBINTR_H_SRE_SHIFT) + +/* UAIE: USB host asynchronous interrupt enable */ +#define USB0_USBINTR_H_UAIE_SHIFT (18) +#define USB0_USBINTR_H_UAIE (1 << USB0_USBINTR_H_UAIE_SHIFT) + +/* UPIA: USB host periodic interrupt enable */ +#define USB0_USBINTR_H_UPIA_SHIFT (19) +#define USB0_USBINTR_H_UPIA (1 << USB0_USBINTR_H_UPIA_SHIFT) + +/* --- USB0_FRINDEX_D values ------------------------------------ */ + +/* FRINDEX2_0: Current micro frame number */ +#define USB0_FRINDEX_D_FRINDEX2_0_SHIFT (0) +#define USB0_FRINDEX_D_FRINDEX2_0_MASK (0x7 << USB0_FRINDEX_D_FRINDEX2_0_SHIFT) +#define USB0_FRINDEX_D_FRINDEX2_0(x) ((x) << USB0_FRINDEX_D_FRINDEX2_0_SHIFT) + +/* FRINDEX13_3: Current frame number of the last frame transmitted */ +#define USB0_FRINDEX_D_FRINDEX13_3_SHIFT (3) +#define USB0_FRINDEX_D_FRINDEX13_3_MASK \ + (0x7ff << USB0_FRINDEX_D_FRINDEX13_3_SHIFT) +#define USB0_FRINDEX_D_FRINDEX13_3(x) ((x) << USB0_FRINDEX_D_FRINDEX13_3_SHIFT) + +/* --- USB0_FRINDEX_H values ------------------------------------ */ + +/* FRINDEX2_0: Current micro frame number */ +#define USB0_FRINDEX_H_FRINDEX2_0_SHIFT (0) +#define USB0_FRINDEX_H_FRINDEX2_0_MASK (0x7 << USB0_FRINDEX_H_FRINDEX2_0_SHIFT) +#define USB0_FRINDEX_H_FRINDEX2_0(x) ((x) << USB0_FRINDEX_H_FRINDEX2_0_SHIFT) + +/* FRINDEX12_3: Frame list current index */ +#define USB0_FRINDEX_H_FRINDEX12_3_SHIFT (3) +#define USB0_FRINDEX_H_FRINDEX12_3_MASK \ + (0x3ff << USB0_FRINDEX_H_FRINDEX12_3_SHIFT) +#define USB0_FRINDEX_H_FRINDEX12_3(x) ((x) << USB0_FRINDEX_H_FRINDEX12_3_SHIFT) + +/* --- USB0_DEVICEADDR values ----------------------------------- */ + +/* USBADRA: Device address advance */ +#define USB0_DEVICEADDR_USBADRA_SHIFT (24) +#define USB0_DEVICEADDR_USBADRA (1 << USB0_DEVICEADDR_USBADRA_SHIFT) + +/* USBADR: USB device address */ +#define USB0_DEVICEADDR_USBADR_SHIFT (25) +#define USB0_DEVICEADDR_USBADR_MASK (0x7f << USB0_DEVICEADDR_USBADR_SHIFT) +#define USB0_DEVICEADDR_USBADR(x) ((x) << USB0_DEVICEADDR_USBADR_SHIFT) + +/* --- USB0_PERIODICLISTBASE values ----------------------------- */ + +/* PERBASE31_12: Base Address (Low) */ +#define USB0_PERIODICLISTBASE_PERBASE31_12_SHIFT (12) +#define USB0_PERIODICLISTBASE_PERBASE31_12_MASK \ + (0xfffff << USB0_PERIODICLISTBASE_PERBASE31_12_SHIFT) +#define USB0_PERIODICLISTBASE_PERBASE31_12(x) \ + ((x) << USB0_PERIODICLISTBASE_PERBASE31_12_SHIFT) + +/* --- USB0_ENDPOINTLISTADDR values ----------------------------- */ + +/* EPBASE31_11: Endpoint list pointer (low) */ +#define USB0_ENDPOINTLISTADDR_EPBASE31_11_SHIFT (11) +#define USB0_ENDPOINTLISTADDR_EPBASE31_11_MASK \ + (0x1fffff << USB0_ENDPOINTLISTADDR_EPBASE31_11_SHIFT) +#define USB0_ENDPOINTLISTADDR_EPBASE31_11(x) \ + ((x) << USB0_ENDPOINTLISTADDR_EPBASE31_11_SHIFT) + +/* --- USB0_ASYNCLISTADDR values -------------------------------- */ + +/* ASYBASE31_5: Link pointer (Low) LPL */ +#define USB0_ASYNCLISTADDR_ASYBASE31_5_SHIFT (5) +#define USB0_ASYNCLISTADDR_ASYBASE31_5_MASK \ + (0x7ffffff << USB0_ASYNCLISTADDR_ASYBASE31_5_SHIFT) +#define USB0_ASYNCLISTADDR_ASYBASE31_5(x) \ + ((x) << USB0_ASYNCLISTADDR_ASYBASE31_5_SHIFT) + +/* --- USB0_TTCTRL values --------------------------------------- */ + +/* TTHA: Hub address when FS or LS device are connected directly */ +#define USB0_TTCTRL_TTHA_SHIFT (24) +#define USB0_TTCTRL_TTHA_MASK (0x7f << USB0_TTCTRL_TTHA_SHIFT) +#define USB0_TTCTRL_TTHA(x) ((x) << USB0_TTCTRL_TTHA_SHIFT) + +/* --- USB0_BURSTSIZE values ------------------------------------ */ + +/* RXPBURST: Programmable RX burst length */ +#define USB0_BURSTSIZE_RXPBURST_SHIFT (0) +#define USB0_BURSTSIZE_RXPBURST_MASK (0xff << USB0_BURSTSIZE_RXPBURST_SHIFT) +#define USB0_BURSTSIZE_RXPBURST(x) ((x) << USB0_BURSTSIZE_RXPBURST_SHIFT) + +/* TXPBURST: Programmable TX burst length */ +#define USB0_BURSTSIZE_TXPBURST_SHIFT (8) +#define USB0_BURSTSIZE_TXPBURST_MASK (0xff << USB0_BURSTSIZE_TXPBURST_SHIFT) +#define USB0_BURSTSIZE_TXPBURST(x) ((x) << USB0_BURSTSIZE_TXPBURST_SHIFT) + +/* --- USB0_TXFILLTUNING values --------------------------------- */ + +/* TXSCHOH: FIFO burst threshold */ +#define USB0_TXFILLTUNING_TXSCHOH_SHIFT (0) +#define USB0_TXFILLTUNING_TXSCHOH_MASK (0xff << USB0_TXFILLTUNING_TXSCHOH_SHIFT) +#define USB0_TXFILLTUNING_TXSCHOH(x) ((x) << USB0_TXFILLTUNING_TXSCHOH_SHIFT) + +/* TXSCHEATLTH: Scheduler health counter */ +#define USB0_TXFILLTUNING_TXSCHEATLTH_SHIFT (8) +#define USB0_TXFILLTUNING_TXSCHEATLTH_MASK \ + (0x1f << USB0_TXFILLTUNING_TXSCHEATLTH_SHIFT) +#define USB0_TXFILLTUNING_TXSCHEATLTH(x) \ + ((x) << USB0_TXFILLTUNING_TXSCHEATLTH_SHIFT) + +/* TXFIFOTHRES: Scheduler overhead */ +#define USB0_TXFILLTUNING_TXFIFOTHRES_SHIFT (16) +#define USB0_TXFILLTUNING_TXFIFOTHRES_MASK \ + (0x3f << USB0_TXFILLTUNING_TXFIFOTHRES_SHIFT) +#define USB0_TXFILLTUNING_TXFIFOTHRES(x) \ + ((x) << USB0_TXFILLTUNING_TXFIFOTHRES_SHIFT) + +/* --- USB0_BINTERVAL values ------------------------------------ */ + +/* BINT: bInterval value */ +#define USB0_BINTERVAL_BINT_SHIFT (0) +#define USB0_BINTERVAL_BINT_MASK (0xf << USB0_BINTERVAL_BINT_SHIFT) +#define USB0_BINTERVAL_BINT(x) ((x) << USB0_BINTERVAL_BINT_SHIFT) + +/* --- USB0_ENDPTNAK values ------------------------------------- */ + +/* EPRN: Rx endpoint NAK */ +#define USB0_ENDPTNAK_EPRN_SHIFT (0) +#define USB0_ENDPTNAK_EPRN_MASK (0x3f << USB0_ENDPTNAK_EPRN_SHIFT) +#define USB0_ENDPTNAK_EPRN(x) ((x) << USB0_ENDPTNAK_EPRN_SHIFT) + +/* EPTN: Tx endpoint NAK */ +#define USB0_ENDPTNAK_EPTN_SHIFT (16) +#define USB0_ENDPTNAK_EPTN_MASK (0x3f << USB0_ENDPTNAK_EPTN_SHIFT) +#define USB0_ENDPTNAK_EPTN(x) ((x) << USB0_ENDPTNAK_EPTN_SHIFT) + +/* --- USB0_ENDPTNAKEN values ----------------------------------- */ + +/* EPRNE: Rx endpoint NAK enable */ +#define USB0_ENDPTNAKEN_EPRNE_SHIFT (0) +#define USB0_ENDPTNAKEN_EPRNE_MASK (0x3f << USB0_ENDPTNAKEN_EPRNE_SHIFT) +#define USB0_ENDPTNAKEN_EPRNE(x) ((x) << USB0_ENDPTNAKEN_EPRNE_SHIFT) + +/* EPTNE: Tx endpoint NAK */ +#define USB0_ENDPTNAKEN_EPTNE_SHIFT (16) +#define USB0_ENDPTNAKEN_EPTNE_MASK (0x3f << USB0_ENDPTNAKEN_EPTNE_SHIFT) +#define USB0_ENDPTNAKEN_EPTNE(x) ((x) << USB0_ENDPTNAKEN_EPTNE_SHIFT) + +/* --- USB0_PORTSC1_D values ------------------------------------ */ + +/* CCS: Current connect status */ +#define USB0_PORTSC1_D_CCS_SHIFT (0) +#define USB0_PORTSC1_D_CCS (1 << USB0_PORTSC1_D_CCS_SHIFT) + +/* PE: Port enable */ +#define USB0_PORTSC1_D_PE_SHIFT (2) +#define USB0_PORTSC1_D_PE (1 << USB0_PORTSC1_D_PE_SHIFT) + +/* PEC: Port enable/disable change */ +#define USB0_PORTSC1_D_PEC_SHIFT (3) +#define USB0_PORTSC1_D_PEC (1 << USB0_PORTSC1_D_PEC_SHIFT) + +/* FPR: Force port resume */ +#define USB0_PORTSC1_D_FPR_SHIFT (6) +#define USB0_PORTSC1_D_FPR (1 << USB0_PORTSC1_D_FPR_SHIFT) + +/* SUSP: Suspend */ +#define USB0_PORTSC1_D_SUSP_SHIFT (7) +#define USB0_PORTSC1_D_SUSP (1 << USB0_PORTSC1_D_SUSP_SHIFT) + +/* PR: Port reset */ +#define USB0_PORTSC1_D_PR_SHIFT (8) +#define USB0_PORTSC1_D_PR (1 << USB0_PORTSC1_D_PR_SHIFT) + +/* HSP: High-speed status */ +#define USB0_PORTSC1_D_HSP_SHIFT (9) +#define USB0_PORTSC1_D_HSP (1 << USB0_PORTSC1_D_HSP_SHIFT) + +/* PIC1_0: Port indicator control */ +#define USB0_PORTSC1_D_PIC1_0_SHIFT (14) +#define USB0_PORTSC1_D_PIC1_0_MASK (0x3 << USB0_PORTSC1_D_PIC1_0_SHIFT) +#define USB0_PORTSC1_D_PIC1_0(x) ((x) << USB0_PORTSC1_D_PIC1_0_SHIFT) + +/* PTC3_0: Port test control */ +#define USB0_PORTSC1_D_PTC3_0_SHIFT (16) +#define USB0_PORTSC1_D_PTC3_0_MASK (0xf << USB0_PORTSC1_D_PTC3_0_SHIFT) +#define USB0_PORTSC1_D_PTC3_0(x) ((x) << USB0_PORTSC1_D_PTC3_0_SHIFT) + +/* PHCD: PHY low power suspend - clock disable (PLPSCD) */ +#define USB0_PORTSC1_D_PHCD_SHIFT (23) +#define USB0_PORTSC1_D_PHCD (1 << USB0_PORTSC1_D_PHCD_SHIFT) + +/* PFSC: Port force full speed connect */ +#define USB0_PORTSC1_D_PFSC_SHIFT (24) +#define USB0_PORTSC1_D_PFSC (1 << USB0_PORTSC1_D_PFSC_SHIFT) + +/* PSPD: Port speed */ +#define USB0_PORTSC1_D_PSPD_SHIFT (26) +#define USB0_PORTSC1_D_PSPD_MASK (0x3 << USB0_PORTSC1_D_PSPD_SHIFT) +#define USB0_PORTSC1_D_PSPD(x) ((x) << USB0_PORTSC1_D_PSPD_SHIFT) + +/* --- USB0_PORTSC1_H values ------------------------------------ */ + +/* CCS: Current connect status */ +#define USB0_PORTSC1_H_CCS_SHIFT (0) +#define USB0_PORTSC1_H_CCS (1 << USB0_PORTSC1_H_CCS_SHIFT) + +/* CSC: Connect status change */ +#define USB0_PORTSC1_H_CSC_SHIFT (1) +#define USB0_PORTSC1_H_CSC (1 << USB0_PORTSC1_H_CSC_SHIFT) + +/* PE: Port enable */ +#define USB0_PORTSC1_H_PE_SHIFT (2) +#define USB0_PORTSC1_H_PE (1 << USB0_PORTSC1_H_PE_SHIFT) + +/* PEC: Port disable/enable change */ +#define USB0_PORTSC1_H_PEC_SHIFT (3) +#define USB0_PORTSC1_H_PEC (1 << USB0_PORTSC1_H_PEC_SHIFT) + +/* OCA: Over-current active */ +#define USB0_PORTSC1_H_OCA_SHIFT (4) +#define USB0_PORTSC1_H_OCA (1 << USB0_PORTSC1_H_OCA_SHIFT) + +/* OCC: Over-current change */ +#define USB0_PORTSC1_H_OCC_SHIFT (5) +#define USB0_PORTSC1_H_OCC (1 << USB0_PORTSC1_H_OCC_SHIFT) + +/* FPR: Force port resume */ +#define USB0_PORTSC1_H_FPR_SHIFT (6) +#define USB0_PORTSC1_H_FPR (1 << USB0_PORTSC1_H_FPR_SHIFT) + +/* SUSP: Suspend */ +#define USB0_PORTSC1_H_SUSP_SHIFT (7) +#define USB0_PORTSC1_H_SUSP (1 << USB0_PORTSC1_H_SUSP_SHIFT) + +/* PR: Port reset */ +#define USB0_PORTSC1_H_PR_SHIFT (8) +#define USB0_PORTSC1_H_PR (1 << USB0_PORTSC1_H_PR_SHIFT) + +/* HSP: High-speed status */ +#define USB0_PORTSC1_H_HSP_SHIFT (9) +#define USB0_PORTSC1_H_HSP (1 << USB0_PORTSC1_H_HSP_SHIFT) + +/* LS: Line status */ +#define USB0_PORTSC1_H_LS_SHIFT (10) +#define USB0_PORTSC1_H_LS_MASK (0x3 << USB0_PORTSC1_H_LS_SHIFT) +#define USB0_PORTSC1_H_LS(x) ((x) << USB0_PORTSC1_H_LS_SHIFT) + +/* PP: Port power control */ +#define USB0_PORTSC1_H_PP_SHIFT (12) +#define USB0_PORTSC1_H_PP (1 << USB0_PORTSC1_H_PP_SHIFT) + +/* PIC1_0: Port indicator control */ +#define USB0_PORTSC1_H_PIC1_0_SHIFT (14) +#define USB0_PORTSC1_H_PIC1_0_MASK (0x3 << USB0_PORTSC1_H_PIC1_0_SHIFT) +#define USB0_PORTSC1_H_PIC1_0(x) ((x) << USB0_PORTSC1_H_PIC1_0_SHIFT) + +/* PTC3_0: Port test control */ +#define USB0_PORTSC1_H_PTC3_0_SHIFT (16) +#define USB0_PORTSC1_H_PTC3_0_MASK (0xf << USB0_PORTSC1_H_PTC3_0_SHIFT) +#define USB0_PORTSC1_H_PTC3_0(x) ((x) << USB0_PORTSC1_H_PTC3_0_SHIFT) + +/* WKCN: Wake on connect enable (WKCNNT_E) */ +#define USB0_PORTSC1_H_WKCN_SHIFT (20) +#define USB0_PORTSC1_H_WKCN (1 << USB0_PORTSC1_H_WKCN_SHIFT) + +/* WKDC: Wake on disconnect enable (WKDSCNNT_E) */ +#define USB0_PORTSC1_H_WKDC_SHIFT (21) +#define USB0_PORTSC1_H_WKDC (1 << USB0_PORTSC1_H_WKDC_SHIFT) + +/* WKOC: Wake on over-current enable (WKOC_E) */ +#define USB0_PORTSC1_H_WKOC_SHIFT (22) +#define USB0_PORTSC1_H_WKOC (1 << USB0_PORTSC1_H_WKOC_SHIFT) + +/* PHCD: PHY low power suspend - clock disable (PLPSCD) */ +#define USB0_PORTSC1_H_PHCD_SHIFT (23) +#define USB0_PORTSC1_H_PHCD (1 << USB0_PORTSC1_H_PHCD_SHIFT) + +/* PFSC: Port force full speed connect */ +#define USB0_PORTSC1_H_PFSC_SHIFT (24) +#define USB0_PORTSC1_H_PFSC (1 << USB0_PORTSC1_H_PFSC_SHIFT) + +/* PSPD: Port speed */ +#define USB0_PORTSC1_H_PSPD_SHIFT (26) +#define USB0_PORTSC1_H_PSPD_MASK (0x3 << USB0_PORTSC1_H_PSPD_SHIFT) +#define USB0_PORTSC1_H_PSPD(x) ((x) << USB0_PORTSC1_H_PSPD_SHIFT) + +/* --- USB0_OTGSC values ---------------------------------------- */ + +/* VD: VBUS_Discharge */ +#define USB0_OTGSC_VD_SHIFT (0) +#define USB0_OTGSC_VD (1 << USB0_OTGSC_VD_SHIFT) + +/* VC: VBUS_Charge */ +#define USB0_OTGSC_VC_SHIFT (1) +#define USB0_OTGSC_VC (1 << USB0_OTGSC_VC_SHIFT) + +/* HAAR: Hardware assist auto_reset */ +#define USB0_OTGSC_HAAR_SHIFT (2) +#define USB0_OTGSC_HAAR (1 << USB0_OTGSC_HAAR_SHIFT) + +/* OT: OTG termination */ +#define USB0_OTGSC_OT_SHIFT (3) +#define USB0_OTGSC_OT (1 << USB0_OTGSC_OT_SHIFT) + +/* DP: Data pulsing */ +#define USB0_OTGSC_DP_SHIFT (4) +#define USB0_OTGSC_DP (1 << USB0_OTGSC_DP_SHIFT) + +/* IDPU: ID pull-up */ +#define USB0_OTGSC_IDPU_SHIFT (5) +#define USB0_OTGSC_IDPU (1 << USB0_OTGSC_IDPU_SHIFT) + +/* HADP: Hardware assist data pulse */ +#define USB0_OTGSC_HADP_SHIFT (6) +#define USB0_OTGSC_HADP (1 << USB0_OTGSC_HADP_SHIFT) + +/* HABA: Hardware assist B-disconnect to A-connect */ +#define USB0_OTGSC_HABA_SHIFT (7) +#define USB0_OTGSC_HABA (1 << USB0_OTGSC_HABA_SHIFT) + +/* ID: USB ID */ +#define USB0_OTGSC_ID_SHIFT (8) +#define USB0_OTGSC_ID (1 << USB0_OTGSC_ID_SHIFT) + +/* AVV: A-VBUS valid */ +#define USB0_OTGSC_AVV_SHIFT (9) +#define USB0_OTGSC_AVV (1 << USB0_OTGSC_AVV_SHIFT) + +/* ASV: A-session valid */ +#define USB0_OTGSC_ASV_SHIFT (10) +#define USB0_OTGSC_ASV (1 << USB0_OTGSC_ASV_SHIFT) + +/* BSV: B-session valid */ +#define USB0_OTGSC_BSV_SHIFT (11) +#define USB0_OTGSC_BSV (1 << USB0_OTGSC_BSV_SHIFT) + +/* BSE: B-session end */ +#define USB0_OTGSC_BSE_SHIFT (12) +#define USB0_OTGSC_BSE (1 << USB0_OTGSC_BSE_SHIFT) + +/* MS1T: 1 millisecond timer toggle */ +#define USB0_OTGSC_MS1T_SHIFT (13) +#define USB0_OTGSC_MS1T (1 << USB0_OTGSC_MS1T_SHIFT) + +/* DPS: Data bus pulsing status */ +#define USB0_OTGSC_DPS_SHIFT (14) +#define USB0_OTGSC_DPS (1 << USB0_OTGSC_DPS_SHIFT) + +/* IDIS: USB ID interrupt status */ +#define USB0_OTGSC_IDIS_SHIFT (16) +#define USB0_OTGSC_IDIS (1 << USB0_OTGSC_IDIS_SHIFT) + +/* AVVIS: A-VBUS valid interrupt status */ +#define USB0_OTGSC_AVVIS_SHIFT (17) +#define USB0_OTGSC_AVVIS (1 << USB0_OTGSC_AVVIS_SHIFT) + +/* ASVIS: A-Session valid interrupt status */ +#define USB0_OTGSC_ASVIS_SHIFT (18) +#define USB0_OTGSC_ASVIS (1 << USB0_OTGSC_ASVIS_SHIFT) + +/* BSVIS: B-Session valid interrupt status */ +#define USB0_OTGSC_BSVIS_SHIFT (19) +#define USB0_OTGSC_BSVIS (1 << USB0_OTGSC_BSVIS_SHIFT) + +/* BSEIS: B-Session end interrupt status */ +#define USB0_OTGSC_BSEIS_SHIFT (20) +#define USB0_OTGSC_BSEIS (1 << USB0_OTGSC_BSEIS_SHIFT) + +/* MS1S: 1 millisecond timer interrupt status */ +#define USB0_OTGSC_MS1S_SHIFT (21) +#define USB0_OTGSC_MS1S (1 << USB0_OTGSC_MS1S_SHIFT) + +/* DPIS: Data pulse interrupt status */ +#define USB0_OTGSC_DPIS_SHIFT (22) +#define USB0_OTGSC_DPIS (1 << USB0_OTGSC_DPIS_SHIFT) + +/* IDIE: USB ID interrupt enable */ +#define USB0_OTGSC_IDIE_SHIFT (24) +#define USB0_OTGSC_IDIE (1 << USB0_OTGSC_IDIE_SHIFT) + +/* AVVIE: A-VBUS valid interrupt enable */ +#define USB0_OTGSC_AVVIE_SHIFT (25) +#define USB0_OTGSC_AVVIE (1 << USB0_OTGSC_AVVIE_SHIFT) + +/* ASVIE: A-session valid interrupt enable */ +#define USB0_OTGSC_ASVIE_SHIFT (26) +#define USB0_OTGSC_ASVIE (1 << USB0_OTGSC_ASVIE_SHIFT) + +/* BSVIE: B-session valid interrupt enable */ +#define USB0_OTGSC_BSVIE_SHIFT (27) +#define USB0_OTGSC_BSVIE (1 << USB0_OTGSC_BSVIE_SHIFT) + +/* BSEIE: B-session end interrupt enable */ +#define USB0_OTGSC_BSEIE_SHIFT (28) +#define USB0_OTGSC_BSEIE (1 << USB0_OTGSC_BSEIE_SHIFT) + +/* MS1E: 1 millisecond timer interrupt enable */ +#define USB0_OTGSC_MS1E_SHIFT (29) +#define USB0_OTGSC_MS1E (1 << USB0_OTGSC_MS1E_SHIFT) + +/* DPIE: Data pulse interrupt enable */ +#define USB0_OTGSC_DPIE_SHIFT (30) +#define USB0_OTGSC_DPIE (1 << USB0_OTGSC_DPIE_SHIFT) + +/* --- USB0_USBMODE_D values ------------------------------------ */ + +/* CM1_0: Controller mode */ +#define USB0_USBMODE_D_CM1_0_SHIFT (0) +#define USB0_USBMODE_D_CM1_0_MASK (0x3 << USB0_USBMODE_D_CM1_0_SHIFT) +#define USB0_USBMODE_D_CM1_0(x) ((x) << USB0_USBMODE_D_CM1_0_SHIFT) + +/* ES: Endian select */ +#define USB0_USBMODE_D_ES_SHIFT (2) +#define USB0_USBMODE_D_ES (1 << USB0_USBMODE_D_ES_SHIFT) + +/* SLOM: Setup Lockout mode */ +#define USB0_USBMODE_D_SLOM_SHIFT (3) +#define USB0_USBMODE_D_SLOM (1 << USB0_USBMODE_D_SLOM_SHIFT) + +/* SDIS: Setup Lockout mode */ +#define USB0_USBMODE_D_SDIS_SHIFT (4) +#define USB0_USBMODE_D_SDIS (1 << USB0_USBMODE_D_SDIS_SHIFT) + +/* --- USB0_USBMODE_H values ------------------------------------ */ + +/* CM: Controller mode */ +#define USB0_USBMODE_H_CM_SHIFT (0) +#define USB0_USBMODE_H_CM_MASK (0x3 << USB0_USBMODE_H_CM_SHIFT) +#define USB0_USBMODE_H_CM(x) ((x) << USB0_USBMODE_H_CM_SHIFT) + +/* ES: Endian select */ +#define USB0_USBMODE_H_ES_SHIFT (2) +#define USB0_USBMODE_H_ES (1 << USB0_USBMODE_H_ES_SHIFT) + +/* SDIS: Stream disable mode */ +#define USB0_USBMODE_H_SDIS_SHIFT (4) +#define USB0_USBMODE_H_SDIS (1 << USB0_USBMODE_H_SDIS_SHIFT) + +/* VBPS: VBUS power select */ +#define USB0_USBMODE_H_VBPS_SHIFT (5) +#define USB0_USBMODE_H_VBPS (1 << USB0_USBMODE_H_VBPS_SHIFT) + +/* --- USB0_ENDPTSETUPSTAT values ------------------------------- */ + +/* ENDPSETUPSTAT: Setup endpoint status for logical endpoints 0 to 5 */ +#define USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT (0) +#define USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT_MASK \ + (0x3f << USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT) +#define USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT(x) \ + ((x) << USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT) + +/* --- USB0_ENDPTPRIME values ----------------------------------- */ + +/* PERB: Prime endpoint receive buffer for physical OUT endpoints 5 to 0 */ +#define USB0_ENDPTPRIME_PERB_SHIFT (0) +#define USB0_ENDPTPRIME_PERB_MASK (0x3f << USB0_ENDPTPRIME_PERB_SHIFT) +#define USB0_ENDPTPRIME_PERB(x) ((x) << USB0_ENDPTPRIME_PERB_SHIFT) + +/* PETB: Prime endpoint transmit buffer for physical IN endpoints 5 to 0 */ +#define USB0_ENDPTPRIME_PETB_SHIFT (16) +#define USB0_ENDPTPRIME_PETB_MASK (0x3f << USB0_ENDPTPRIME_PETB_SHIFT) +#define USB0_ENDPTPRIME_PETB(x) ((x) << USB0_ENDPTPRIME_PETB_SHIFT) + +/* --- USB0_ENDPTFLUSH values ----------------------------------- */ + +/* FERB: Flush endpoint receive buffer for physical OUT endpoints 5 to 0 */ +#define USB0_ENDPTFLUSH_FERB_SHIFT (0) +#define USB0_ENDPTFLUSH_FERB_MASK (0x3f << USB0_ENDPTFLUSH_FERB_SHIFT) +#define USB0_ENDPTFLUSH_FERB(x) ((x) << USB0_ENDPTFLUSH_FERB_SHIFT) + +/* FETB: Flush endpoint transmit buffer for physical IN endpoints 5 to 0 */ +#define USB0_ENDPTFLUSH_FETB_SHIFT (16) +#define USB0_ENDPTFLUSH_FETB_MASK (0x3f << USB0_ENDPTFLUSH_FETB_SHIFT) +#define USB0_ENDPTFLUSH_FETB(x) ((x) << USB0_ENDPTFLUSH_FETB_SHIFT) + +/* --- USB0_ENDPTSTAT values ------------------------------------ */ + +/* ERBR: Endpoint receive buffer ready for physical OUT endpoints 5 to 0 */ +#define USB0_ENDPTSTAT_ERBR_SHIFT (0) +#define USB0_ENDPTSTAT_ERBR_MASK (0x3f << USB0_ENDPTSTAT_ERBR_SHIFT) +#define USB0_ENDPTSTAT_ERBR(x) ((x) << USB0_ENDPTSTAT_ERBR_SHIFT) + +/* ETBR: Endpoint transmit buffer ready for physical IN endpoints 3 to 0 */ +#define USB0_ENDPTSTAT_ETBR_SHIFT (16) +#define USB0_ENDPTSTAT_ETBR_MASK (0x3f << USB0_ENDPTSTAT_ETBR_SHIFT) +#define USB0_ENDPTSTAT_ETBR(x) ((x) << USB0_ENDPTSTAT_ETBR_SHIFT) + +/* --- USB0_ENDPTCOMPLETE values -------------------------------- */ + +/* ERCE: Endpoint receive complete event for physical OUT endpoints 5 to 0 */ +#define USB0_ENDPTCOMPLETE_ERCE_SHIFT (0) +#define USB0_ENDPTCOMPLETE_ERCE_MASK (0x3f << USB0_ENDPTCOMPLETE_ERCE_SHIFT) +#define USB0_ENDPTCOMPLETE_ERCE(x) ((x) << USB0_ENDPTCOMPLETE_ERCE_SHIFT) + +/* ETCE: Endpoint transmit complete event for physical IN endpoints 5 to 0 */ +#define USB0_ENDPTCOMPLETE_ETCE_SHIFT (16) +#define USB0_ENDPTCOMPLETE_ETCE_MASK (0x3f << USB0_ENDPTCOMPLETE_ETCE_SHIFT) +#define USB0_ENDPTCOMPLETE_ETCE(x) ((x) << USB0_ENDPTCOMPLETE_ETCE_SHIFT) + +/* --- USB0_ENDPTCTRL0 values ----------------------------------- */ + +/* RXS: Rx endpoint stall */ +#define USB0_ENDPTCTRL0_RXS_SHIFT (0) +#define USB0_ENDPTCTRL0_RXS (1 << USB0_ENDPTCTRL0_RXS_SHIFT) + +/* RXT1_0: Endpoint type */ +#define USB0_ENDPTCTRL0_RXT1_0_SHIFT (2) +#define USB0_ENDPTCTRL0_RXT1_0_MASK (0x3 << USB0_ENDPTCTRL0_RXT1_0_SHIFT) +#define USB0_ENDPTCTRL0_RXT1_0(x) ((x) << USB0_ENDPTCTRL0_RXT1_0_SHIFT) + +/* RXE: Rx endpoint enable */ +#define USB0_ENDPTCTRL0_RXE_SHIFT (7) +#define USB0_ENDPTCTRL0_RXE (1 << USB0_ENDPTCTRL0_RXE_SHIFT) + +/* TXS: Tx endpoint stall */ +#define USB0_ENDPTCTRL0_TXS_SHIFT (16) +#define USB0_ENDPTCTRL0_TXS (1 << USB0_ENDPTCTRL0_TXS_SHIFT) + +/* TXT1_0: Endpoint type */ +#define USB0_ENDPTCTRL0_TXT1_0_SHIFT (18) +#define USB0_ENDPTCTRL0_TXT1_0_MASK (0x3 << USB0_ENDPTCTRL0_TXT1_0_SHIFT) +#define USB0_ENDPTCTRL0_TXT1_0(x) ((x) << USB0_ENDPTCTRL0_TXT1_0_SHIFT) + +/* TXE: Tx endpoint enable */ +#define USB0_ENDPTCTRL0_TXE_SHIFT (23) +#define USB0_ENDPTCTRL0_TXE (1 << USB0_ENDPTCTRL0_TXE_SHIFT) + +/* --- USB0_ENDPTCTRL1 values ----------------------------------- */ + +/* RXS: Rx endpoint stall */ +#define USB0_ENDPTCTRL1_RXS_SHIFT (0) +#define USB0_ENDPTCTRL1_RXS (1 << USB0_ENDPTCTRL1_RXS_SHIFT) + +/* RXT: Endpoint type */ +#define USB0_ENDPTCTRL1_RXT_SHIFT (2) +#define USB0_ENDPTCTRL1_RXT_MASK (0x3 << USB0_ENDPTCTRL1_RXT_SHIFT) +#define USB0_ENDPTCTRL1_RXT(x) ((x) << USB0_ENDPTCTRL1_RXT_SHIFT) + +/* RXI: Rx data toggle inhibit */ +#define USB0_ENDPTCTRL1_RXI_SHIFT (5) +#define USB0_ENDPTCTRL1_RXI (1 << USB0_ENDPTCTRL1_RXI_SHIFT) + +/* RXR: Rx data toggle reset */ +#define USB0_ENDPTCTRL1_RXR_SHIFT (6) +#define USB0_ENDPTCTRL1_RXR (1 << USB0_ENDPTCTRL1_RXR_SHIFT) + +/* RXE: Rx endpoint enable */ +#define USB0_ENDPTCTRL1_RXE_SHIFT (7) +#define USB0_ENDPTCTRL1_RXE (1 << USB0_ENDPTCTRL1_RXE_SHIFT) + +/* TXS: Tx endpoint stall */ +#define USB0_ENDPTCTRL1_TXS_SHIFT (16) +#define USB0_ENDPTCTRL1_TXS (1 << USB0_ENDPTCTRL1_TXS_SHIFT) + +/* TXT1_0: Tx Endpoint type */ +#define USB0_ENDPTCTRL1_TXT1_0_SHIFT (18) +#define USB0_ENDPTCTRL1_TXT1_0_MASK (0x3 << USB0_ENDPTCTRL1_TXT1_0_SHIFT) +#define USB0_ENDPTCTRL1_TXT1_0(x) ((x) << USB0_ENDPTCTRL1_TXT1_0_SHIFT) + +/* TXI: Tx data toggle inhibit */ +#define USB0_ENDPTCTRL1_TXI_SHIFT (21) +#define USB0_ENDPTCTRL1_TXI (1 << USB0_ENDPTCTRL1_TXI_SHIFT) + +/* TXR: Tx data toggle reset */ +#define USB0_ENDPTCTRL1_TXR_SHIFT (22) +#define USB0_ENDPTCTRL1_TXR (1 << USB0_ENDPTCTRL1_TXR_SHIFT) + +/* TXE: Tx endpoint enable */ +#define USB0_ENDPTCTRL1_TXE_SHIFT (23) +#define USB0_ENDPTCTRL1_TXE (1 << USB0_ENDPTCTRL1_TXE_SHIFT) + +/* --- USB0_ENDPTCTRL2 values ----------------------------------- */ + +/* RXS: Rx endpoint stall */ +#define USB0_ENDPTCTRL2_RXS_SHIFT (0) +#define USB0_ENDPTCTRL2_RXS (1 << USB0_ENDPTCTRL2_RXS_SHIFT) + +/* RXT: Endpoint type */ +#define USB0_ENDPTCTRL2_RXT_SHIFT (2) +#define USB0_ENDPTCTRL2_RXT_MASK (0x3 << USB0_ENDPTCTRL2_RXT_SHIFT) +#define USB0_ENDPTCTRL2_RXT(x) ((x) << USB0_ENDPTCTRL2_RXT_SHIFT) + +/* RXI: Rx data toggle inhibit */ +#define USB0_ENDPTCTRL2_RXI_SHIFT (5) +#define USB0_ENDPTCTRL2_RXI (1 << USB0_ENDPTCTRL2_RXI_SHIFT) + +/* RXR: Rx data toggle reset */ +#define USB0_ENDPTCTRL2_RXR_SHIFT (6) +#define USB0_ENDPTCTRL2_RXR (1 << USB0_ENDPTCTRL2_RXR_SHIFT) + +/* RXE: Rx endpoint enable */ +#define USB0_ENDPTCTRL2_RXE_SHIFT (7) +#define USB0_ENDPTCTRL2_RXE (1 << USB0_ENDPTCTRL2_RXE_SHIFT) + +/* TXS: Tx endpoint stall */ +#define USB0_ENDPTCTRL2_TXS_SHIFT (16) +#define USB0_ENDPTCTRL2_TXS (1 << USB0_ENDPTCTRL2_TXS_SHIFT) + +/* TXT1_0: Tx Endpoint type */ +#define USB0_ENDPTCTRL2_TXT1_0_SHIFT (18) +#define USB0_ENDPTCTRL2_TXT1_0_MASK (0x3 << USB0_ENDPTCTRL2_TXT1_0_SHIFT) +#define USB0_ENDPTCTRL2_TXT1_0(x) ((x) << USB0_ENDPTCTRL2_TXT1_0_SHIFT) + +/* TXI: Tx data toggle inhibit */ +#define USB0_ENDPTCTRL2_TXI_SHIFT (21) +#define USB0_ENDPTCTRL2_TXI (1 << USB0_ENDPTCTRL2_TXI_SHIFT) + +/* TXR: Tx data toggle reset */ +#define USB0_ENDPTCTRL2_TXR_SHIFT (22) +#define USB0_ENDPTCTRL2_TXR (1 << USB0_ENDPTCTRL2_TXR_SHIFT) + +/* TXE: Tx endpoint enable */ +#define USB0_ENDPTCTRL2_TXE_SHIFT (23) +#define USB0_ENDPTCTRL2_TXE (1 << USB0_ENDPTCTRL2_TXE_SHIFT) + +/* --- USB0_ENDPTCTRL3 values ----------------------------------- */ + +/* RXS: Rx endpoint stall */ +#define USB0_ENDPTCTRL3_RXS_SHIFT (0) +#define USB0_ENDPTCTRL3_RXS (1 << USB0_ENDPTCTRL3_RXS_SHIFT) + +/* RXT: Endpoint type */ +#define USB0_ENDPTCTRL3_RXT_SHIFT (2) +#define USB0_ENDPTCTRL3_RXT_MASK (0x3 << USB0_ENDPTCTRL3_RXT_SHIFT) +#define USB0_ENDPTCTRL3_RXT(x) ((x) << USB0_ENDPTCTRL3_RXT_SHIFT) + +/* RXI: Rx data toggle inhibit */ +#define USB0_ENDPTCTRL3_RXI_SHIFT (5) +#define USB0_ENDPTCTRL3_RXI (1 << USB0_ENDPTCTRL3_RXI_SHIFT) + +/* RXR: Rx data toggle reset */ +#define USB0_ENDPTCTRL3_RXR_SHIFT (6) +#define USB0_ENDPTCTRL3_RXR (1 << USB0_ENDPTCTRL3_RXR_SHIFT) + +/* RXE: Rx endpoint enable */ +#define USB0_ENDPTCTRL3_RXE_SHIFT (7) +#define USB0_ENDPTCTRL3_RXE (1 << USB0_ENDPTCTRL3_RXE_SHIFT) + +/* TXS: Tx endpoint stall */ +#define USB0_ENDPTCTRL3_TXS_SHIFT (16) +#define USB0_ENDPTCTRL3_TXS (1 << USB0_ENDPTCTRL3_TXS_SHIFT) + +/* TXT1_0: Tx Endpoint type */ +#define USB0_ENDPTCTRL3_TXT1_0_SHIFT (18) +#define USB0_ENDPTCTRL3_TXT1_0_MASK (0x3 << USB0_ENDPTCTRL3_TXT1_0_SHIFT) +#define USB0_ENDPTCTRL3_TXT1_0(x) ((x) << USB0_ENDPTCTRL3_TXT1_0_SHIFT) + +/* TXI: Tx data toggle inhibit */ +#define USB0_ENDPTCTRL3_TXI_SHIFT (21) +#define USB0_ENDPTCTRL3_TXI (1 << USB0_ENDPTCTRL3_TXI_SHIFT) + +/* TXR: Tx data toggle reset */ +#define USB0_ENDPTCTRL3_TXR_SHIFT (22) +#define USB0_ENDPTCTRL3_TXR (1 << USB0_ENDPTCTRL3_TXR_SHIFT) + +/* TXE: Tx endpoint enable */ +#define USB0_ENDPTCTRL3_TXE_SHIFT (23) +#define USB0_ENDPTCTRL3_TXE (1 << USB0_ENDPTCTRL3_TXE_SHIFT) + +/* --- USB0_ENDPTCTRL4 values ----------------------------------- */ + +/* RXS: Rx endpoint stall */ +#define USB0_ENDPTCTRL4_RXS_SHIFT (0) +#define USB0_ENDPTCTRL4_RXS (1 << USB0_ENDPTCTRL4_RXS_SHIFT) + +/* RXT: Endpoint type */ +#define USB0_ENDPTCTRL4_RXT_SHIFT (2) +#define USB0_ENDPTCTRL4_RXT_MASK (0x3 << USB0_ENDPTCTRL4_RXT_SHIFT) +#define USB0_ENDPTCTRL4_RXT(x) ((x) << USB0_ENDPTCTRL4_RXT_SHIFT) + +/* RXI: Rx data toggle inhibit */ +#define USB0_ENDPTCTRL4_RXI_SHIFT (5) +#define USB0_ENDPTCTRL4_RXI (1 << USB0_ENDPTCTRL4_RXI_SHIFT) + +/* RXR: Rx data toggle reset */ +#define USB0_ENDPTCTRL4_RXR_SHIFT (6) +#define USB0_ENDPTCTRL4_RXR (1 << USB0_ENDPTCTRL4_RXR_SHIFT) + +/* RXE: Rx endpoint enable */ +#define USB0_ENDPTCTRL4_RXE_SHIFT (7) +#define USB0_ENDPTCTRL4_RXE (1 << USB0_ENDPTCTRL4_RXE_SHIFT) + +/* TXS: Tx endpoint stall */ +#define USB0_ENDPTCTRL4_TXS_SHIFT (16) +#define USB0_ENDPTCTRL4_TXS (1 << USB0_ENDPTCTRL4_TXS_SHIFT) + +/* TXT1_0: Tx Endpoint type */ +#define USB0_ENDPTCTRL4_TXT1_0_SHIFT (18) +#define USB0_ENDPTCTRL4_TXT1_0_MASK (0x3 << USB0_ENDPTCTRL4_TXT1_0_SHIFT) +#define USB0_ENDPTCTRL4_TXT1_0(x) ((x) << USB0_ENDPTCTRL4_TXT1_0_SHIFT) + +/* TXI: Tx data toggle inhibit */ +#define USB0_ENDPTCTRL4_TXI_SHIFT (21) +#define USB0_ENDPTCTRL4_TXI (1 << USB0_ENDPTCTRL4_TXI_SHIFT) + +/* TXR: Tx data toggle reset */ +#define USB0_ENDPTCTRL4_TXR_SHIFT (22) +#define USB0_ENDPTCTRL4_TXR (1 << USB0_ENDPTCTRL4_TXR_SHIFT) + +/* TXE: Tx endpoint enable */ +#define USB0_ENDPTCTRL4_TXE_SHIFT (23) +#define USB0_ENDPTCTRL4_TXE (1 << USB0_ENDPTCTRL4_TXE_SHIFT) + +/* --- USB0_ENDPTCTRL5 values ----------------------------------- */ + +/* RXS: Rx endpoint stall */ +#define USB0_ENDPTCTRL5_RXS_SHIFT (0) +#define USB0_ENDPTCTRL5_RXS (1 << USB0_ENDPTCTRL5_RXS_SHIFT) + +/* RXT: Endpoint type */ +#define USB0_ENDPTCTRL5_RXT_SHIFT (2) +#define USB0_ENDPTCTRL5_RXT_MASK (0x3 << USB0_ENDPTCTRL5_RXT_SHIFT) +#define USB0_ENDPTCTRL5_RXT(x) ((x) << USB0_ENDPTCTRL5_RXT_SHIFT) + +/* RXI: Rx data toggle inhibit */ +#define USB0_ENDPTCTRL5_RXI_SHIFT (5) +#define USB0_ENDPTCTRL5_RXI (1 << USB0_ENDPTCTRL5_RXI_SHIFT) + +/* RXR: Rx data toggle reset */ +#define USB0_ENDPTCTRL5_RXR_SHIFT (6) +#define USB0_ENDPTCTRL5_RXR (1 << USB0_ENDPTCTRL5_RXR_SHIFT) + +/* RXE: Rx endpoint enable */ +#define USB0_ENDPTCTRL5_RXE_SHIFT (7) +#define USB0_ENDPTCTRL5_RXE (1 << USB0_ENDPTCTRL5_RXE_SHIFT) + +/* TXS: Tx endpoint stall */ +#define USB0_ENDPTCTRL5_TXS_SHIFT (16) +#define USB0_ENDPTCTRL5_TXS (1 << USB0_ENDPTCTRL5_TXS_SHIFT) + +/* TXT1_0: Tx Endpoint type */ +#define USB0_ENDPTCTRL5_TXT1_0_SHIFT (18) +#define USB0_ENDPTCTRL5_TXT1_0_MASK (0x3 << USB0_ENDPTCTRL5_TXT1_0_SHIFT) +#define USB0_ENDPTCTRL5_TXT1_0(x) ((x) << USB0_ENDPTCTRL5_TXT1_0_SHIFT) + +/* TXI: Tx data toggle inhibit */ +#define USB0_ENDPTCTRL5_TXI_SHIFT (21) +#define USB0_ENDPTCTRL5_TXI (1 << USB0_ENDPTCTRL5_TXI_SHIFT) + +/* TXR: Tx data toggle reset */ +#define USB0_ENDPTCTRL5_TXR_SHIFT (22) +#define USB0_ENDPTCTRL5_TXR (1 << USB0_ENDPTCTRL5_TXR_SHIFT) + +/* TXE: Tx endpoint enable */ +#define USB0_ENDPTCTRL5_TXE_SHIFT (23) +#define USB0_ENDPTCTRL5_TXE (1 << USB0_ENDPTCTRL5_TXE_SHIFT) + +/* -------------------------------------------------------------- */ + + +/* --- USB0_ENDPTCTRL common values ----------------------------- */ + +/* RXS: Rx endpoint stall */ +#define USB0_ENDPTCTRL_RXS_SHIFT (0) +#define USB0_ENDPTCTRL_RXS (1 << USB0_ENDPTCTRL_RXS_SHIFT) + +/* RXT: Endpoint type */ +#define USB0_ENDPTCTRL_RXT_SHIFT (2) +#define USB0_ENDPTCTRL_RXT_MASK (0x3 << USB0_ENDPTCTRL_RXT_SHIFT) +#define USB0_ENDPTCTRL_RXT(x) ((x) << USB0_ENDPTCTRL_RXT_SHIFT) + +/* RXI: Rx data toggle inhibit */ +#define USB0_ENDPTCTRL_RXI_SHIFT (5) +#define USB0_ENDPTCTRL_RXI (1 << USB0_ENDPTCTRL_RXI_SHIFT) + +/* RXR: Rx data toggle reset */ +#define USB0_ENDPTCTRL_RXR_SHIFT (6) +#define USB0_ENDPTCTRL_RXR (1 << USB0_ENDPTCTRL_RXR_SHIFT) + +/* RXE: Rx endpoint enable */ +#define USB0_ENDPTCTRL_RXE_SHIFT (7) +#define USB0_ENDPTCTRL_RXE (1 << USB0_ENDPTCTRL_RXE_SHIFT) + +/* TXS: Tx endpoint stall */ +#define USB0_ENDPTCTRL_TXS_SHIFT (16) +#define USB0_ENDPTCTRL_TXS (1 << USB0_ENDPTCTRL_TXS_SHIFT) + +/* TXT1_0: Tx Endpoint type */ +#define USB0_ENDPTCTRL_TXT1_0_SHIFT (18) +#define USB0_ENDPTCTRL_TXT1_0_MASK (0x3 << USB0_ENDPTCTRL_TXT1_0_SHIFT) +#define USB0_ENDPTCTRL_TXT1_0(x) ((x) << USB0_ENDPTCTRL_TXT1_0_SHIFT) + +/* TXI: Tx data toggle inhibit */ +#define USB0_ENDPTCTRL_TXI_SHIFT (21) +#define USB0_ENDPTCTRL_TXI (1 << USB0_ENDPTCTRL_TXI_SHIFT) + +/* TXR: Tx data toggle reset */ +#define USB0_ENDPTCTRL_TXR_SHIFT (22) +#define USB0_ENDPTCTRL_TXR (1 << USB0_ENDPTCTRL_TXR_SHIFT) + +/* TXE: Tx endpoint enable */ +#define USB0_ENDPTCTRL_TXE_SHIFT (23) +#define USB0_ENDPTCTRL_TXE (1 << USB0_ENDPTCTRL_TXE_SHIFT) + + + + + +/* --- USB1 registers ------------------------------------------------------ */ +/* TODO */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/wwdt.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/wwdt.h new file mode 100644 index 00000000..30ff6a7e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/lpc43xx/wwdt.h @@ -0,0 +1,65 @@ +/** @defgroup wwdt_defines Windowed Watchdog Timer + +@brief Defined Constants and Types for the LPC43xx Windowed Watchdog +Timer + +@ingroup LPC43xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LPC43XX_WWDT_H +#define LPC43XX_WWDT_H + +/**@{*/ + +#include +#include + +/* --- Windowed Watchdog Timer (WWDT) registers ---------------------------- */ + +/* Watchdog mode register */ +#define WWDT_MOD MMIO32(WWDT_BASE + 0x000) + +/* Watchdog timer constant register */ +#define WWDT_TC MMIO32(WWDT_BASE + 0x004) + +/* Watchdog feed sequence register */ +#define WWDT_FEED MMIO32(WWDT_BASE + 0x008) + +/* Watchdog timer value register */ +#define WWDT_TV MMIO32(WWDT_BASE + 0x00C) + +/* Watchdog warning interrupt register */ +#define WWDT_WARNINT MMIO32(WWDT_BASE + 0x014) + +/* Watchdog timer window register */ +#define WWDT_WINDOW MMIO32(WWDT_BASE + 0x018) + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/gpio.h new file mode 100644 index 00000000..852085e8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/gpio.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/irq.json new file mode 100644 index 00000000..c3d8c109 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/irq.json @@ -0,0 +1,52 @@ +{ + "irqs": [ + "supc", + "rstc", + "rtc", + "rtt", + "wdt", + "pmc", + "eefc0", + "eefc1", + "uart", + "smc_sdramc", + "sdramc", + "pioa", + "piob", + "pioc", + "piod", + "pioe", + "piof", + "usart0", + "usart1", + "usart2", + "usart3", + "hsmci", + "twi0", + "twi1", + "spi0", + "spi1", + "ssc", + "tc0", + "tc1", + "tc2", + "tc3", + "tc4", + "tc5", + "tc6", + "tc7", + "tc8", + "pwm", + "adc", + "dacc", + "dmac", + "uotghs", + "trng", + "reserved0", + "can0", + "can1" + ], + "partname_humanreadable": "Atmel SAM3A series", + "partname_doxygen": "SAM3A", + "includeguard": "LIBOPENCM3_SAM3A_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/memorymap.h new file mode 100644 index 00000000..90d97c6c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/memorymap.h @@ -0,0 +1,77 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3A_MEMORYMAP_H +#define SAM3A_MEMORYMAP_H + +#include + +/* --- SAM3A peripheral space -------------------------------------------- */ +#define HSMCI_BASE (0x40000000U) +#define SSC_BASE (0x40004000U) +#define SPI0_BASE (0x40008000U) +#define SPI1_BASE (0x4000C000U) +#define TC0_BASE (0x40080000U) +#define TC1_BASE (0x40080040U) +#define TC2_BASE (0x40080080U) +#define TC3_BASE (0x40084000U) +#define TC4_BASE (0x40084040U) +#define TC5_BASE (0x40084080U) +#define TC6_BASE (0x40088000U) +#define TC7_BASE (0x40088040U) +#define TC8_BASE (0x40088080U) +#define TWI0_BASE (0x4008C000U) +#define TWI1_BASE (0x40090000U) +#define PWM_BASE (0x40094000U) +#define USART0_BASE (0x40098000U) +#define USART1_BASE (0x4009C000U) +#define USART2_BASE (0x400A0000U) +#define USART3_BASE (0x400A4000U) +#define UOTGHS_BASE (0x400AC000U) +#define CAN0_BASE (0x400B4000U) +#define CAN1_BASE (0x400B8000U) +#define TRNG_BASE (0x400BC000U) +#define ADC_BASE (0x400C0000U) +#define DMAC_BASE (0x400C4000U) +#define DACC_BASE (0x400C8000U) + +/* --- SAM3A system controller space ------------------------------------- */ +#define SMC_BASE (0x400E0000U) +#define SDRAM_BASE (0x400E0200U) +#define MATRIX_BASE (0x400E0400U) +#define PMC_BASE (0x400E0600U) +#define UART_BASE (0x400E0800U) +#define CHIPID_BASE (0x400E0940U) +#define EEFC0_BASE (0x400E0A00U) +#define EEFC1_BASE (0x400E0C00U) +#define PIOA_BASE (0x400E0E00U) +#define PIOB_BASE (0x400E1000U) +#define PIOC_BASE (0x400E1200U) +#define PIOD_BASE (0x400E1400U) +#define PIOE_BASE (0x400E1600U) +#define PIOF_BASE (0x400E1800U) +#define RSTC_BASE (0x400E1A00U) +#define SUPC_BASE (0x400E1A10U) +#define RTT_BASE (0x400E1A30U) +#define WDT_BASE (0x400E1A50U) +#define RTC_BASE (0x400E1A60U) +#define GPBR_BASE (0x400E1A90U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pio.h new file mode 100644 index 00000000..10fafae0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pio.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PIO_H +#define LIBOPENCM3_PIO_H + +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pmc.h new file mode 100644 index 00000000..1db09bbf --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3a/pmc.h @@ -0,0 +1,64 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PMC_H +#define LIBOPENCM3_PMC_H + +#include +#include +#include +#include + +/* --- Power Management Controller (PMC) registers ------------------------- */ + +/* Peripheral Control Register */ +#define PMC_PCR MMIO32(PMC_BASE + 0x010C) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC Master Clock Register (PMC_MCKR) -------------------------------- */ + +/* PLLA Divide by 2 */ +#define PMC_MCKR_PLLADIV2 (0x01 << 12) + + +/* --- PMC Peripheral Control Register (PMC_PCR) --------------------------- */ + +/* Enable */ +#define PMC_PCR_EN (0x01 << 28) + +/* Divisor Value */ +#define PMC_PCR_DIV_SHIFT 16 +#define PMC_PCR_DIV_MASK (0x03 << PMC_PCR_DIV_SHIFT) +#define PMC_PCR_DIV_PERIPH_DIV_MCK (0x00 << PMC_PCR_DIV_SHIFT) +#define PMC_PCR_DIV_PERIPH_DIV2_MCK (0x01 << PMC_PCR_DIV_SHIFT) +#define PMC_PCR_DIV_PERIPH_DIV4_MCK (0x02 << PMC_PCR_DIV_SHIFT) + +/* Command */ +#define PMC_PCR_CMD (0x01 << 12) + +/* Peripheral ID */ +#define PMC_PCR_PID_SHIFT 0 +#define PMC_PCR_PID_MASK (0x3F << PMC_PCR_PID_SHIFT) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/gpio.h new file mode 100644 index 00000000..bb00ac48 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/gpio.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/irq.json new file mode 100644 index 00000000..9d1d39ea --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/irq.json @@ -0,0 +1,39 @@ +{ + "irqs": [ + "supc", + "rstc", + "rtc", + "rtt", + "wdt", + "pmc", + "eefc", + "reserved0", + "uart0", + "uart1", + "reserved1", + "pioa", + "piob", + "pioc", + "usart0", + "usart1", + "reserved2", + "reserved3", + "reserved4", + "twi0", + "twi1", + "spi", + "reserved5", + "tc0", + "tc1", + "tc2", + "tc3", + "tc4", + "tc5", + "adc", + "dacc", + "pwm" + ], + "partname_humanreadable": "Atmel SAM3N series", + "partname_doxygen": "SAM3N", + "includeguard": "LIBOPENCM3_SAM3N_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/memorymap.h new file mode 100644 index 00000000..34c193fa --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/memorymap.h @@ -0,0 +1,60 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3N_MEMORYMAP_H +#define SAM3N_MEMORYMAP_H + +#include + +/* --- SAM3N peripheral space -------------------------------------------- */ + +#define SPI_BASE (0x40008000U) +#define TC0_BASE (0x40010000U) +#define TC1_BASE (0x40010040U) +#define TC2_BASE (0x40010080U) +#define TC3_BASE (0x40014000U) +#define TC4_BASE (0x40014040U) +#define TC5_BASE (0x40014080U) +#define TWI0_BASE (0x40018000U) +#define TWI1_BASE (0x4001C000U) +#define PWM_BASE (0x40020000U) +#define USART0_BASE (0x40024000U) +#define USART1_BASE (0x40028000U) +#define ADC_BASE (0x40038000U) +#define DACC_BASE (0x4003C000U) + +/* --- SAM3N system controller space ------------------------------------- */ +#define SMC_BASE (0x400E0000U) +#define MATRIX_BASE (0x400E0200U) +#define PMC_BASE (0x400E0400U) +#define UART0_BASE (0x400E0600U) +#define CHIPID_BASE (0x400E0740U) +#define UART1_BASE (0x400E0800U) +#define EEFC_BASE (0x400E0A00U) +#define PIOA_BASE (0x400E0E00U) +#define PIOB_BASE (0x400E1000U) +#define PIOC_BASE (0x400E1200U) +#define RSTC_BASE (0x400E1400U) +#define SUPC_BASE (0x400E1410U) +#define RTT_BASE (0x400E1430U) +#define WDT_BASE (0x400E1450U) +#define RTC_BASE (0x400E1460U) +#define GPBR_BASE (0x400E1490U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/periph.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/periph.h new file mode 100644 index 00000000..ca14059c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/periph.h @@ -0,0 +1,52 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PERIPH_H +#define LIBOPENCM3_PERIPH_H + +/* --- Peripheral Identifiers ---------------------------------------------- */ +#define PERIPH_SUPC 0 +#define PERIPH_RSTC 1 +#define PERIPH_RTC 2 +#define PERIPH_RTT 3 +#define PERIPH_WDG 4 +#define PERIPH_PMC 5 +#define PERIPH_EEFC 6 +#define PERIPH_UART0 8 +#define PERIPH_UART1 9 +#define PERIPH_PIOA 11 +#define PERIPH_PIOB 12 +#define PERIPH_PIOC 13 +#define PERIPH_USART0 14 +#define PERIPH_USART1 15 +#define PERIPH_TWI0 19 +#define PERIPH_TWI1 20 +#define PERIPH_SPI 21 +#define PERIPH_TC0 23 +#define PERIPH_TC1 24 +#define PERIPH_TC2 25 +#define PERIPH_TC3 26 +#define PERIPH_TC4 27 +#define PERIPH_TC5 28 +#define PERIPH_ADC 29 +#define PERIPH_DACC 30 +#define PERIPH_PWM 31 + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pio.h new file mode 100644 index 00000000..cf06243f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pio.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PIO_H +#define LIBOPENCM3_PIO_H + +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pmc.h new file mode 100644 index 00000000..bd03e5d7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3n/pmc.h @@ -0,0 +1,139 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PMC_H +#define LIBOPENCM3_PMC_H + +#include +#include +#include + +/* --- Power Management Controller (PMC) registers ----------------------- */ + +/* PMC Clock Generator PLL Register */ +#define CKGR_PLLR CKGR_PLLAR + +/* Oscillator Calibration Register */ +#define PMC_OCR MMIO32(PMC_BASE + 0x0110) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC Clock Generator Main Oscillator Register (CKGR_MOR) ------------- */ + +/* Wait Mode Command */ +#define CKGR_MOR_WAITMODE (0x01 << 2) + + +/* --- PMC Clock Generator PLL Register (CKGR_PLLR) ---------------------- */ +/* CKGR_PLLAR on all other device subfamilies */ + +/* must be set to program CKGR_PLLR */ +#define CKGR_PLLR_ONE CKGR_PLLAR_ONE + +/* PLLA Multiplier */ +#define CKGR_PLLR_MUL_SHIFT CKGR_PLLAR_MULA_SHIFT +#define CKGR_PLLR_MUL_MASK CKGR_PLLAR_MULA_MASK + +/* PLLA Counter */ +#define CKGR_PLLR_PLLCOUNT_SHIFT CKGR_PLLAR_PLLACOUNT_SHIFT +#define CKGR_PLLR_PLLCOUNT_MASK CKGR_PLLAR_PLLACOUNT_MASK + +/* Divider */ +#define CKGR_PLLR_DIV_SHIFT CKGR_PLLAR_DIVA_SHIFT +#define CKGR_PLLR_DIV_MASK CKGR_PLLAR_DIVA_MASK + + +/* --- PMC Master Clock Register (PMC_MCKR) -------------------------------- */ + +/* PLL Divide by 2 */ +#define PMC_MCKR_PLLDIV2 (0x01 << 12) + +/* Master Clock Source Selection */ +#define PMC_MCKR_CSS_PLL_CLK (2 << PMC_MCKR_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 0 (PMC_PCK0) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK0_CSS_PLL_CLK (2 << PMC_PCK0_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 1 (PMC_PCK1) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK1_CSS_PLL_CLK (2 << PMC_PCK1_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 2 (PMC_PCK2) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK2_CSS_PLL_CLK (2 << PMC_PCK2_CSS_SHIFT) + + +/* --- PMC Interrupt Enable Register (PMC_IER) ----------------------------- */ + +/* PLL Lock Interrupt Enable */ +#define PMC_IER_LOCK PMC_IER_LOCKA + + +/* --- PMC Interrupt Disable Register (PMC_IDR) ----------------------------- */ + +/* PLL Lock Interrupt Disable */ +#define PMC_IDR_LOCK PMC_IDR_LOCKA + + +/* --- PMC Status Register (PMC_SR) ---------------------------------------- */ + +/* PLL Lock Status */ +#define PMC_SR_LOCK PMC_SR_LOCKA + + +/* --- PMC Interrupt Mask Register (PMC_IMR) ----------------------------- */ + +/* PLL Lock Interrupt Mask */ +#define PMC_IMR_LOCK PMC_IMR_LOCKA + + +/* --- PMC Oscillator Calibration Register (PMC_OCR) ----------------------- */ + +/* Selection of RC Oscillator Calibration bits for 12 Mhz */ +#define PMC_OCR_SEL12 (0x01 << 23) + +/* RC Oscillator Calibration bits for 12 Mhz */ +#define PMC_OCR_CAL12_SHIFT 16 +#define PMC_OCR_CAL12_MASK (0x7F << PMC_OCR_CAL12_SHIFT) + +/* Selection of RC Oscillator Calibration bits for 8 Mhz */ +#define PMC_OCR_SEL8 (0x01 << 15) + +/* RC Oscillator Calibration bits for 8 Mhz */ +#define PMC_OCR_CAL8_SHIFT 8 +#define PMC_OCR_CAL8_MASK (0x7F << PMC_OCR_CAL8_SHIFT) + +/* Selection of RC Oscillator Calibration bits for 4 Mhz */ +#define PMC_OCR_SEL4 (0x01 << 7) + +/* RC Oscillator Calibration bits for 4 Mhz */ +#define PMC_OCR_CAL4_SHIFT 0 +#define PMC_OCR_CAL4_MASK (0x7F << PMC_OCR_CAL12_SHIFT) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/gpio.h new file mode 100644 index 00000000..bb00ac48 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/gpio.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/irq.json new file mode 100644 index 00000000..ddf76f63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/irq.json @@ -0,0 +1,42 @@ +{ + "irqs": [ + "supc", + "rstc", + "rtc", + "rtt", + "wdt", + "pmc", + "eefc", + "reserved0", + "uart0", + "uart1", + "smc", + "pioa", + "piob", + "pioc", + "usart0", + "usart1", + "usart2", + "reserved1", + "hsmci", + "twi0", + "twi1", + "spi", + "ssc", + "tc0", + "tc1", + "tc2", + "tc3", + "tc4", + "tc5", + "adc", + "dacc", + "pwm", + "crccu", + "acc", + "udp" + ], + "partname_humanreadable": "Atmel SAM3S series", + "partname_doxygen": "SAM3S", + "includeguard": "LIBOPENCM3_SAM3S_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/memorymap.h new file mode 100644 index 00000000..0ce72008 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/memorymap.h @@ -0,0 +1,66 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3S_MEMORYMAP_H +#define SAM3S_MEMORYMAP_H + +#include + +/* --- SAM3S peripheral space -------------------------------------------- */ +#define HSMCI_BASE (0x40000000U) +#define SSC_BASE (0x40004000U) +#define SPI_BASE (0x40008000U) +#define TC0_BASE (0x40010000U) +#define TC1_BASE (0x40010040U) +#define TC2_BASE (0x40010080U) +#define TC3_BASE (0x40014000U) +#define TC4_BASE (0x40014040U) +#define TC5_BASE (0x40014080U) +#define TWI0_BASE (0x40018000U) +#define TWI1_BASE (0x4001C000U) +#define PWM_BASE (0x40020000U) +#define USART0_BASE (0x40024000U) +#define USART1_BASE (0x40028000U) +#define USART2_BASE (0x4002C000U) +#define UDP_BASE (0x40034000U) +#define ADC_BASE (0x40038000U) +#define DACC_BASE (0x4003C000U) +#define ACC_BASE (0x40040000U) +#define CRCCU_BASE (0x40044000U) + +/* --- SAM3S system controller space ------------------------------------- */ +#define SMC_BASE (0x400E0000U) +#define MATRIX_BASE (0x400E0200U) +#define PMC_BASE (0x400E0400U) +#define UART0_BASE (0x400E0600U) +#define CHIPID_BASE (0x400E0740U) +#define UART1_BASE (0x400E0800U) +#define EEFC_BASE (0x400E0A00U) +#define PIOA_BASE (0x400E0E00U) +#define PIOB_BASE (0x400E1000U) +#define PIOC_BASE (0x400E1200U) +#define RSTC_BASE (0x400E1400U) +#define SUPC_BASE (0x400E1410U) +#define RTT_BASE (0x400E1430U) +#define WDT_BASE (0x400E1450U) +#define RTC_BASE (0x400E1460U) +#define GPBR_BASE (0x400E1490U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/periph.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/periph.h new file mode 100644 index 00000000..fb0ee5c3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/periph.h @@ -0,0 +1,59 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PERIPH_H +#define LIBOPENCM3_PERIPH_H + +/* --- Peripheral Identifiers ---------------------------------------------- */ +#define PERIPH_SUPC 0 +#define PERIPH_RSTC 1 +#define PERIPH_RTC 2 +#define PERIPH_RTT 3 +#define PERIPH_WDG 4 +#define PERIPH_PMC 5 +#define PERIPH_EEFC 6 +#define PERIPH_UART0 8 +#define PERIPH_UART1 9 +#define PERIPH_SMC 10 +#define PERIPH_PIOA 11 +#define PERIPH_PIOB 12 +#define PERIPH_PIOC 13 +#define PERIPH_USART0 14 +#define PERIPH_USART1 15 +#define PERIPH_USART2 16 +#define PERIPH_HSMCI 18 +#define PERIPH_TWI0 19 +#define PERIPH_TWI1 20 +#define PERIPH_SPI 21 +#define PERIPH_SSC 22 +#define PERIPH_TC0 23 +#define PERIPH_TC1 24 +#define PERIPH_TC2 25 +#define PERIPH_TC3 26 +#define PERIPH_TC4 27 +#define PERIPH_TC5 28 +#define PERIPH_ADC 29 +#define PERIPH_DACC 30 +#define PERIPH_PWM 31 +#define PERIPH_CRCCU 32 +#define PERIPH_ACC 33 +#define PERIPH_UDP 34 + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pio.h new file mode 100644 index 00000000..a559f506 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pio.h @@ -0,0 +1,47 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PIO_H +#define LIBOPENCM3_PIO_H + +#include +#include + +/* --- PIO registers ----------------------------------------------------- */ + +/* Parallel Capture Mode Register */ +#define PIO_PCMR(port) MMIO32((port) + 0x0150) + +/* Parallel Capture Interrupt Enable Register */ +#define PIO_PCIER(port) MMIO32((port) + 0x0154) + +/* Parallel Capture Interrupt Disable Register */ +#define PIO_PCIDR(port) MMIO32((port) + 0x0158) + +/* Parallel Capture Interrupt Mask Register */ +#define PIO_PCIMR(port) MMIO32((port) + 0x015C) + +/* Parallel Capture Interrupt Status Register */ +#define PIO_PCISR(port) MMIO32((port) + 0x0160) + +/* Parallel Capture Reception Holding Register */ +#define PIO_PCRHR(port) MMIO32((port) + 0x0164) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pmc.h new file mode 100644 index 00000000..5f0e061d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/pmc.h @@ -0,0 +1,138 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PMC_H +#define LIBOPENCM3_PMC_H + +#include +#include +#include + +/* --- Power Management Controller (PMC) registers ----------------------- */ + +/* PLLB Register */ +#define CKGR_PLLBR MMIO32(PMC_BASE + 0x002C) + +/* Oscillator Calibration Register */ +#define PMC_OCR MMIO32(PMC_BASE + 0x0110) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC Clock Generator Main Clock Frequency Register (CKGR_MCFR) ------- */ + +/* RC Oscillator Frequency Measure (write-only, only on atsam3s8) */ +#define CKGR_MCFR_RCMEAS (0x01 << 20) + + +/* --- PMC Clock Generator PLLB Register (CKGR_PLLBR) ---------------------- */ + +/* PLLB Multiplier */ +#define CKGR_PLLBR_MULB_SHIFT 16 +#define CKGR_PLLBR_MULB_MASK (0x7FF << CKGR_PLLBR_MULB_SHIFT) + +/* PLLA Counter */ +#define CKGR_PLLBR_PLLBCOUNT_SHIFT 8 +#define CKGR_PLLBR_PLLBCOUNT_MASK (0x3F << CKGR_PLLBR_PLLBCOUNT_SHIFT) + +/* Divider */ +#define CKGR_PLLBR_DIVB_SHIFT 0 +#define CKGR_PLLBR_DIVB_MASK (0xFF << CKGR_PLLBR_DIVB_SHIFT) + + +/* --- PMC Master Clock Register (PMC_MCKR) -------------------------------- */ + +/* PLLB Divide by 2 */ +#define PMC_MCKR_PLLBDIV2 (0x01 << 13) + +/* PLLA Divide by 2 */ +#define PMC_MCKR_PLLADIV2 (0x01 << 12) + +/* Master Clock Source Selection */ +#define PMC_MCKR_CSS_PLLB_CLK (3 << PMC_MCKR_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 0 (PMC_PCK0) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK0_CSS_PLLB_CLK (3 << PMC_PCK0_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 1 (PMC_PCK1) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK1_CSS_PLLB_CLK (3 << PMC_PCK1_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 2 (PMC_PCK2) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK2_CSS_PLLB_CLK (3 << PMC_PCK2_CSS_SHIFT) + + +/* --- PMC Interrupt Enable Register (PMC_IER) ----------------------------- */ + +/* PLLB Lock Interrupt Enable */ +#define PMC_IER_LOCKB (0x01 << 2) + + +/* --- PMC Interrupt Disable Register (PMC_IDR) ---------------------------- */ + +/* PLLB Lock Interrupt Disable */ +#define PMC_IDR_LOCKB (0x01 << 2) + + +/* --- PMC Status Register (PMC_SR) ---------------------------------------- */ + +/* PLLB Lock Status */ +#define PMC_SR_LOCKB (0x01 << 2) + + +/* --- PMC Interrupt Mask Register (PMC_IDR) ------------------------------- */ + +/* PLLB Lock Interrupt Mask */ +#define PMC_IMR_LOCKB (0x01 << 2) + + +/* --- PMC Oscillator Calibration Register (PMC_OCR) ----------------------- */ + +/* Selection of RC Oscillator Calibration bits for 12 Mhz */ +#define PMC_OCR_SEL12 (0x01 << 23) + +/* RC Oscillator Calibration bits for 12 Mhz */ +#define PMC_OCR_CAL12_SHIFT 16 +#define PMC_OCR_CAL12_MASK (0x7F << PMC_OCR_CAL12_SHIFT) + +/* Selection of RC Oscillator Calibration bits for 8 Mhz */ +#define PMC_OCR_SEL8 (0x01 << 15) + +/* RC Oscillator Calibration bits for 8 Mhz */ +#define PMC_OCR_CAL8_SHIFT 8 +#define PMC_OCR_CAL8_MASK (0x7F << PMC_OCR_CAL8_SHIFT) + +/* Selection of RC Oscillator Calibration bits for 4 Mhz */ +#define PMC_OCR_SEL4 (0x01 << 7) + +/* RC Oscillator Calibration bits for 4 Mhz */ +#define PMC_OCR_CAL4_SHIFT 0 +#define PMC_OCR_CAL4_MASK (0x7F << PMC_OCR_CAL12_SHIFT) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/smc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/smc.h new file mode 100644 index 00000000..53cbeaef --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3s/smc.h @@ -0,0 +1,204 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SMC_H +#define LIBOPENCM3_SMC_H + +#include + + +/* Chip Select Defines */ +#define SMC_CS_0 0 +#define SMC_CS_1 1 +#define SMC_CS_2 2 +#define SMC_CS_3 3 + + +/* --- Static Memory Controller (SMC) registers ---------------------------- */ + +/* Setup Register */ +#define SMC_SETUP(CS_number) MMIO32(SMC_BASE + 0x10*(CS_number) \ + + 0x00) + +/* Pulse Register */ +#define SMC_PULSE(CS_number) MMIO32(SMC_BASE + 0x10*(CS_number) \ + + 0x04) + +/* Cycle Register */ +#define SMC_CYCLE(CS_number) MMIO32(SMC_BASE + 0x10*(CS_number) \ + + 0x08) + +/* Mode Register */ +#define SMC_MODE(CS_number) MMIO32(SMC_BASE + 0x10*(CS_number) \ + + 0x0C) + +/* Off Chip Memory Scrambling Mode Register */ +#define SMC_OCMS MMIO32(SMC_BASE + 0x80) + +/* Off Chip Memory Scrambling KEY1 Register */ +#define SMC_KEY1 MMIO32(SMC_BASE + 0x84) + +/* Off Chip Memory Scrambling KEY2 Register */ +#define SMC_KEY2 MMIO32(SMC_BASE + 0x88) + +/* Write Protect Mode Register */ +#define SMC_WPMR MMIO32(SMC_BASE + 0xE4) + +/* Write Protect Status Register */ +#define SMC_WPSR MMIO32(SMC_BASE + 0xE8) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- SMC Setup Register (SMC_SETUPx) ------------------------------------- */ + +/* NCS Setup length in Read access */ +#define SMC_SETUP_NCS_RD_SETUP_SHIFT 24 +#define SMC_SETUP_NCS_RD_SETUP_MASK (0x3F << SMC_SETUP_NCS_RD_SETUP_SHIFT) + +/* NRD Setup length */ +#define SMC_SETUP_NRD_SETUP_SHIFT 16 +#define SMC_SETUP_NRD_SETUP_MASK (0x3F << SMC_SETUP_NRD_SETUP_SHIFT) + +/* NCS Setup length in Write access */ +#define SMC_SETUP_NCS_WR_SETUP_SHIFT 8 +#define SMC_SETUP_NCS_WR_SETUP_MASK (0x3F << SMC_SETUP_NCS_WR_SETUP_SHIFT) + +/* NWE Setup Length */ +#define SMC_SETUP_NWE_SETUP_SHIFT 0 +#define SMC_SETUP_NWE_SETUP_MASK (0x3F << SMC_SETUP_NWE_SETUP_SHIFT) + + +/* --- SMC Pulse Register (SMC_PULSEx) ------------------------------------- */ + +/* NCS Pulse Length in READ Access */ +#define SMC_PULSE_NCS_RD_PULSE_SHIFT 24 +#define SMC_PULSE_NCS_RD_PULSE_MASK (0x7F << SMC_PULSE_NCS_RD_PULSE_SHIFT) + +/* NRD Pulse Length */ +#define SMC_PULSE_NRD_PULSE_SHIFT 16 +#define SMC_PULSE_NRD_PULSE_MASK (0x7F << SMC_PULSE_NRD_PULSE_SHIFT) + +/* NCS Pulse Length in WRITE Access */ +#define SMC_PULSE_NCS_WR_PULSE_SHIFT 8 +#define SMC_PULSE_NCS_WR_PULSE_MASK (0x7F << SMC_PULSE_NCS_WR_PULSE_SHIFT) + +/* NWE Pulse Length */ +#define SMC_PULSE_NWE_PULSE_SHIFT 0 +#define SMC_PULSE_NWE_PULSE_MASK (0x7F << SMC_PULSE_NWE_PULSE_SHIFT) + + +/* --- SMC Cycle Register (SMC_CYCLEx) ------------------------------------- */ + +/* Total Read Cycle Length */ +#define SMC_CYCLE_NRD_CYCLE_SHIFT 16 +#define SMC_CYCLE_NRD_CYCLE_MASK (0x1FF << SMC_CYCLE_NRD_CYCLE_SHIFT) + +/* Total Write Cycle Length */ +#define SMC_CYCLE_NWE_CYCLE_SHIFT 0 +#define SMC_CYCLE_NWE_CYCLE_MASK (0x1FF << SMC_CYCLE_NWE_CYCLE_SHIFT) + + +/* --- SMC MODE Register (SMC_MODEx) --------------------------------------- */ + +/* Page Size */ +#define SMC_MODE_PS_SHIFT 28 +#define SMC_MODE_PS_MASK (0x03 << SMC_MODE_PS_SHIFT) + +/* Page Size Values */ +#define SMC_MODE_PS_4_BYTE (0x00 << SMC_MODE_PS_SHIFT) +#define SMC_MODE_PS_8_BYTE (0x01 << SMC_MODE_PS_SHIFT) +#define SMC_MODE_PS_16_BYTE (0x02 << SMC_MODE_PS_SHIFT) +#define SMC_MODE_PS_32_BYTE (0x03 << SMC_MODE_PS_SHIFT) + +/* Page Mode Enabled */ +#define SMC_MODE_PMEN (1 << 24) + +/* TDF Optimization */ +#define SMC_MODE_TDF_MODE (1 << 20) + +/* Data Float Time */ +#define SMC_MODE_TDF_CYCLES_SHIFT 16 +#define SMC_MODE_TDF_CYCLES_MASK (0x0F << SMC_MODE_TDF_CYCLES_SHIFT) + +/* Data Bus Width */ +#define SMC_MODE_DBW_SHIFT 12 +#define SMC_MODE_DBW_MASK (0x03 << SMC_MODE_DBW_SHIFT) + +/* Data Bus Width Values */ +#define SMC_MODE_DBW_8_BIT (0x00 << SMC_MODE_DBW_SHIFT) +#define SMC_MODE_DBW_16_BIT (0x01 << SMC_MODE_DBW_SHIFT) +#define SMC_MODE_DBW_32_BIT (0x02 << SMC_MODE_DBW_SHIFT) + +/* NWAIT Mode */ +#define SMC_MODE_EXNW_MODE_SHIFT 4 +#define SMC_MODE_EXNW_MODE_MASK (0x03 << SMC_MODE_EXNW_MODE_SHIFT) + +/* NWAIT Mode Values */ +#define SMC_MODE_EXNW_MODE_DISABLED (0x00 << SMC_MODE_EXNW_MODE_SHIFT) +#define SMC_MODE_EXNW_MODE_FROZEN (0x02 << SMC_MODE_EXNW_MODE_SHIFT) +#define SMC_MODE_EXNW_MODE_READY (0x03 << SMC_MODE_EXNW_MODE_SHIFT) + +/* Write Mode */ +#define SMC_MODE_WRITE_MODE (1 << 1) + +/* Read Mode */ +#define SMC_MODE_READ_MODE (1 << 0) + + +/* --- SMC OCMS Mode Register (SMC_OCMS) ----------------------------------- */ + +/* Chip Select 3 Scrambling Enable */ +#define SMC_OCMS_CS3SE (1 << 19) + +/* Chip Select 2 Scrambling Enable */ +#define SMC_OCMS_CS2SE (1 << 18) + +/* Chip Select 1 Scrambling Enable */ +#define SMC_OCMS_CS1SE (1 << 17) + +/* Chip Select 0 Scrambling Enable */ +#define SMC_OCMS_CS0SE (1 << 16) + +/* Static Memory Controller Scrambling Enable */ +#define SMC_OCMS_SMSE (1 << 0) + + +/* --- SMC Write Protect Mode Register (SMC_WPMR) -------------------------- */ + +/* Write Protect Key */ +#define SMC_WPMR_WPKEY_SHIFT 8 +#define SMC_WPMR_WPKEY_KEY (0x534D43 << SMC_WPMR_WPKEY_SHIFT) + +/* Write Protect Enable */ +#define SMC_WPMR_WPEN (1 << 0) + + +/* --- SMC Write Protect Status Register (SMC_WPSR) ------------------------ */ + +/* Write Protection Violation Source */ +#define SMC_WPSR_WP_VSRC_SHIFT 8 +#define SMC_WPSR_WP_VSRC_MASK (0xFFFF << SMC_WPSR_WP_VSRC_SHIFT) + +/* Write Protect Enable */ +#define SMC_WPSR_WPVS (1 << 0) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/gpio.h new file mode 100644 index 00000000..852085e8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/gpio.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/irq.json new file mode 100644 index 00000000..c52f1832 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/irq.json @@ -0,0 +1,37 @@ +{ + "irqs": [ + "supc", + "rstc", + "rtc", + "rtt", + "wdt", + "pmc", + "eefc0", + "eefc1", + "uart", + "smc", + "pioa", + "piob", + "pioc", + "usart0", + "usart1", + "usart2", + "usart3", + "hsmci", + "twi0", + "twi1", + "spi", + "ssc", + "tc0", + "tc1", + "tc2", + "pwm", + "adc12b", + "adc", + "dmac", + "udphs" + ], + "partname_humanreadable": "Atmel SAM3U series", + "partname_doxygen": "SAM3U", + "includeguard": "LIBOPENCM3_SAM3U_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/memorymap.h new file mode 100644 index 00000000..edd2f29f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/memorymap.h @@ -0,0 +1,63 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3U_MEMORYMAP_H +#define SAM3U_MEMORYMAP_H + +#include + +/* --- SAM3U peripheral space -------------------------------------------- */ +#define HSMCI_BASE (0x40000000U) +#define SSC_BASE (0x40004000U) +#define SPI_BASE (0x40008000U) +#define TC0_BASE (0x40080000U) +#define TC1_BASE (0x40080040U) +#define TC2_BASE (0x40080080U) +#define TWI0_BASE (0x40084000U) +#define TWI1_BASE (0x40088000U) +#define PWM_BASE (0x4008C000U) +#define USART0_BASE (0x40090000U) +#define USART1_BASE (0x40094000U) +#define USART2_BASE (0x40098000U) +#define USART3_BASE (0x4009C000U) +#define UDPHS_BASE (0x400A4000U) +#define ADC12B_BASE (0x400A8000U) +#define ADC_BASE (0x400AC000U) +#define DMAC_BASE (0x400B0000U) + +/* --- SAM3U system controller space ------------------------------------- */ +#define SMC_BASE (0x400E0000U) +#define MATRIX_BASE (0x400E0200U) +#define PMC_BASE (0x400E0400U) +#define UART_BASE (0x400E0600U) +#define CHIPID_BASE (0x400E0740U) +#define EEFC0_BASE (0x400E0800U) +#define EEFC1_BASE (0x400E0A00U) +#define PIOA_BASE (0x400E0C00U) +#define PIOB_BASE (0x400E0E00U) +#define PIOC_BASE (0x400E1000U) +#define RSTC_BASE (0x400E1200U) +#define SUPC_BASE (0x400E1210U) +#define RTT_BASE (0x400E1230U) +#define WDT_BASE (0x400E1250U) +#define RTC_BASE (0x400E1260U) +#define GPBR_BASE (0x400E1290U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/periph.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/periph.h new file mode 100644 index 00000000..507f18b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/periph.h @@ -0,0 +1,56 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PERIPH_H +#define LIBOPENCM3_PERIPH_H + +/* --- Peripheral Identifiers ---------------------------------------------- */ +#define PERIPH_SUPC 0 +#define PERIPH_RSTC 1 +#define PERIPH_RTC 2 +#define PERIPH_RTT 3 +#define PERIPH_WDG 4 +#define PERIPH_PMC 5 +#define PERIPH_EEFC0 6 +#define PERIPH_EEFC1 7 +#define PERIPH_UART 8 +#define PERIPH_SMC 9 +#define PERIPH_PIOA 10 +#define PERIPH_PIOB 11 +#define PERIPH_PIOC 12 +#define PERIPH_USART0 13 +#define PERIPH_USART1 14 +#define PERIPH_USART2 15 +#define PERIPH_USART3 16 +#define PERIPH_HSMCI 17 +#define PERIPH_TWI0 18 +#define PERIPH_TWI1 19 +#define PERIPH_SPI 20 +#define PERIPH_SSC 21 +#define PERIPH_TC0 22 +#define PERIPH_TC1 23 +#define PERIPH_TC2 24 +#define PERIPH_PWM 25 +#define PERIPH_ADC12B 26 +#define PERIPH_ADC 27 +#define PERIPH_DMAC 28 +#define PERIPH_UDPHS 29 + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pio.h new file mode 100644 index 00000000..10fafae0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pio.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PIO_H +#define LIBOPENCM3_PIO_H + +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pmc.h new file mode 100644 index 00000000..888bfb1a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3u/pmc.h @@ -0,0 +1,38 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PMC_H +#define LIBOPENCM3_PMC_H + +#include +#include +#include +#include + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC Clock Generator Main Oscillator Register (CKGR_MOR) ------------- */ + +/* Wait Mode Command */ +#define CKGR_MOR_WAITMODE (0x01 << 2) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/gpio.h new file mode 100644 index 00000000..852085e8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/gpio.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/irq.json new file mode 100644 index 00000000..c53d63cc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/irq.json @@ -0,0 +1,52 @@ +{ + "irqs": [ + "supc", + "rstc", + "rtc", + "rtt", + "wdt", + "pmc", + "eefc0", + "eefc1", + "uart", + "smc_sdramc", + "sdramc", + "pioa", + "piob", + "pioc", + "piod", + "pioe", + "piof", + "usart0", + "usart1", + "usart2", + "usart3", + "hsmci", + "twi0", + "twi1", + "spi0", + "spi1", + "ssc", + "tc0", + "tc1", + "tc2", + "tc3", + "tc4", + "tc5", + "tc6", + "tc7", + "tc8", + "pwm", + "adc", + "dacc", + "dmac", + "uotghs", + "trng", + "emac", + "can0", + "can1" + ], + "partname_humanreadable": "Atmel SAM3X series", + "partname_doxygen": "SAM3X", + "includeguard": "LIBOPENCM3_SAM3X_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/memorymap.h new file mode 100644 index 00000000..dea04bbc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/memorymap.h @@ -0,0 +1,78 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3X_MEMORYMAP_H +#define SAM3X_MEMORYMAP_H + +#include + +/* --- SAM3X peripheral space -------------------------------------------- */ + +#define HSMCI_BASE (0x40000000U) +#define SSC_BASE (0x40004000U) +#define SPI0_BASE (0x40008000U) +#define SPI1_BASE (0x4000C000U) +#define TC0_BASE (0x40080000U) +#define TC1_BASE (0x40080040U) +#define TC2_BASE (0x40080080U) +#define TC3_BASE (0x40084000U) +#define TC4_BASE (0x40084040U) +#define TC5_BASE (0x40084080U) +#define TC6_BASE (0x40088000U) +#define TC7_BASE (0x40088040U) +#define TC8_BASE (0x40088080U) +#define TWI0_BASE (0x4008C000U) +#define TWI1_BASE (0x40090000U) +#define PWM_BASE (0x40094000U) +#define USART0_BASE (0x40098000U) +#define USART1_BASE (0x4009C000U) +#define USART2_BASE (0x400A0000U) +#define USART3_BASE (0x400A4000U) +#define UOTGHS_BASE (0x400AC000U) +#define EMAC_BASE (0x400B0000U) +#define CAN0_BASE (0x400B4000U) +#define CAN1_BASE (0x400B8000U) +#define TRNG_BASE (0x400BC000U) +#define ADC_BASE (0x400C0000U) +#define DMAC_BASE (0x400C4000U) +#define DACC_BASE (0x400C8000U) + +/* --- SAM3X system controller space ------------------------------------- */ +#define SMC_BASE (0x400E0000U) +#define SDRAM_BASE (0x400E0200U) +#define MATRIX_BASE (0x400E0400U) +#define PMC_BASE (0x400E0600U) +#define UART_BASE (0x400E0800U) +#define CHIPID_BASE (0x400E0940U) +#define EEFC0_BASE (0x400E0A00U) +#define EEFC1_BASE (0x400E0C00U) +#define PIOA_BASE (0x400E0E00U) +#define PIOB_BASE (0x400E1000U) +#define PIOC_BASE (0x400E1200U) +#define PIOD_BASE (0x400E1400U) +#define PIOE_BASE (0x400E1600U) +#define PIOF_BASE (0x400E1800U) +#define RSTC_BASE (0x400E1A00U) +#define SUPC_BASE (0x400E1A10U) +#define RTT_BASE (0x400E1A30U) +#define WDT_BASE (0x400E1A50U) +#define RTC_BASE (0x400E1A60U) +#define GPBR_BASE (0x400E1A90U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pio.h new file mode 100644 index 00000000..10fafae0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pio.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PIO_H +#define LIBOPENCM3_PIO_H + +#include +#include + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pmc.h new file mode 100644 index 00000000..e11b5541 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/3x/pmc.h @@ -0,0 +1,64 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PMC_H +#define LIBOPENCM3_PMC_H + +#include +#include +#include +#include + +/* --- Power Management Controller (PMC) registers ----------------------- */ + +/* Peripheral Control Register */ +#define PMC_PCR MMIO32(PMC_BASE + 0x010C) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC Master Clock Register (PMC_MCKR) -------------------------------- */ + +/* PLLA Divide by 2 */ +#define PMC_MCKR_PLLADIV2 (0x01 << 12) + + +/* --- PMC Peripheral Control Register (PMC_PCR) --------------------------- */ + +/* Enable */ +#define PMC_PCR_EN (0x01 << 28) + +/* Divisor Value */ +#define PMC_PCR_DIV_SHIFT 16 +#define PMC_PCR_DIV_MASK (0x03 << PMC_PCR_DIV_SHIFT) +#define PMC_PCR_DIV_PERIPH_DIV_MCK (0x00 << PMC_PCR_DIV_SHIFT) +#define PMC_PCR_DIV_PERIPH_DIV2_MCK (0x01 << PMC_PCR_DIV_SHIFT) +#define PMC_PCR_DIV_PERIPH_DIV4_MCK (0x02 << PMC_PCR_DIV_SHIFT) + +/* Command */ +#define PMC_PCR_CMD (0x01 << 12) + +/* Peripheral ID */ +#define PMC_PCR_PID_SHIFT 0 +#define PMC_PCR_PID_MASK (0x3F << PMC_PCR_PID_SHIFT) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3a3u3x.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3a3u3x.h new file mode 100644 index 00000000..f397d3e7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3a3u3x.h @@ -0,0 +1,52 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * COpyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA GPIO.H +The order of header inclusion is important. gpio.h includes the device +specific memorymap.h header before including this header file.*/ + +#if defined(LIBOPENCM3_GPIO_H) + +#ifndef LIBOPENCM3_GPIO_COMMON_3A3U3X_H +#define LIBOPENCM3_GPIO_COMMON_3A3U3X_H + +#include + + +/* flags may be or'd together, but only contain one of + * GPOUTPUT, PERIPHA and PERIPHB */ +enum gpio_flags { + GPIO_FLAG_GPINPUT = 0, + GPIO_FLAG_GPOUTPUT = 1, + GPIO_FLAG_PERIPHA = 2, + GPIO_FLAG_PERIPHB = 3, + GPIO_FLAG_OPEN_DRAIN = (1 << 3), + GPIO_FLAG_PULL_UP = (1 << 4), +}; + + +void gpio_init(uint32_t gpioport, uint32_t pins, enum gpio_flags flags); + + +#endif + +#else +#warning "gpio_common_3a3u3x.h should not be included explicitly, only via gpio.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3n3s.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3n3s.h new file mode 100644 index 00000000..348dd6e4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_3n3s.h @@ -0,0 +1,54 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA GPIO.H +The order of header inclusion is important. gpio.h includes the device +specific memorymap.h header before including this header file.*/ + +#if defined(LIBOPENCM3_GPIO_H) + +#ifndef LIBOPENCM3_GPIO_COMMON_3N3S_H +#define LIBOPENCM3_GPIO_COMMON_3N3S_H + +#include + + +/* flags may be or'd together, but only contain one of + * GPOUTPUT, PERIPHA, PERIPHB, PERIPHC and PERIPHD */ +enum gpio_flags { + GPIO_FLAG_GPINPUT = 0, + GPIO_FLAG_GPOUTPUT = 1, + GPIO_FLAG_PERIPHA = 2, + GPIO_FLAG_PERIPHB = 3, + GPIO_FLAG_PERIPHC = 4, + GPIO_FLAG_PERIPHD = 5, + GPIO_FLAG_OPEN_DRAIN = (1 << 3), + GPIO_FLAG_PULL_UP = (1 << 4), +}; + + +void gpio_init(uint32_t gpioport, uint32_t pins, enum gpio_flags flags); + + +#endif + +#else +#warning "gpio_common_3n3s.h should not be included explicitly, only via gpio.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_all.h new file mode 100644 index 00000000..375e429c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/gpio_common_all.h @@ -0,0 +1,41 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA GPIO.H +The order of header inclusion is important. gpio.h includes the device +specific memorymap.h header before including this header file.*/ + +#if defined(LIBOPENCM3_GPIO_H) + +#ifndef LIBOPENCM3_GPIO_COMMON_ALL_H +#define LIBOPENCM3_GPIO_COMMON_ALL_H + +#include + +void gpio_set(uint32_t gpioport, uint32_t gpios); +void gpio_clear(uint32_t gpioport, uint32_t gpios); +void gpio_toggle(uint32_t gpioport, uint32_t gpios); + + +#endif + +#else +#warning "gpio_common_all.h should not be included explicitly, only via gpio.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/periph_common_3a3x.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/periph_common_3a3x.h new file mode 100644 index 00000000..a0dcae23 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/periph_common_3a3x.h @@ -0,0 +1,71 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PERIPH_H +#define LIBOPENCM3_PERIPH_H + +/* --- Peripheral Identifiers ---------------------------------------------- */ +#define PERIPH_SUPC 0 +#define PERIPH_RSTC 1 +#define PERIPH_RTC 2 +#define PERIPH_RTT 3 +#define PERIPH_WDG 4 +#define PERIPH_PMC 5 +#define PERIPH_EEFC0 6 +#define PERIPH_EEFC1 7 +#define PERIPH_UART 8 +#define PERIPH_SMC_SDRAMC 9 +#define PERIPH_SDRAMC 10 +#define PERIPH_PIOA 11 +#define PERIPH_PIOB 12 +#define PERIPH_PIOC 13 +#define PERIPH_PIOD 14 +#define PERIPH_PIOE 15 +#define PERIPH_PIOF 16 +#define PERIPH_USART0 17 +#define PERIPH_USART1 18 +#define PERIPH_USART2 19 +#define PERIPH_USART3 20 +#define PERIPH_HSMCI 21 +#define PERIPH_TWI0 22 +#define PERIPH_TWI1 23 +#define PERIPH_SPI0 24 +#define PERIPH_SPI1 25 +#define PERIPH_SSC 26 +#define PERIPH_TC0 27 +#define PERIPH_TC1 28 +#define PERIPH_TC2 29 +#define PERIPH_TC3 30 +#define PERIPH_TC4 31 +#define PERIPH_TC5 32 +#define PERIPH_TC6 33 +#define PERIPH_TC7 34 +#define PERIPH_TC8 35 +#define PERIPH_PWM 36 +#define PERIPH_ADC 37 +#define PERIPH_DACC 38 +#define PERIPH_DMAC 39 +#define PERIPH_UOTGHS 40 +#define PERIPH_TRNG 41 +#define PERIPH_EMAC 42 +#define PERIPH_CAN0 43 +#define PERIPH_CAN1 44 + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3a3u3x.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3a3u3x.h new file mode 100644 index 00000000..45f016e1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3a3u3x.h @@ -0,0 +1,50 @@ +/* + * This file is part of the libopencm3 project. + * + * COpyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA PIO.H +The order of header inclusion is important. pio.h includes the device +specific memorymap.h header before including this header file.*/ + +#if defined(LIBOPENCM3_PIO_H) + +#ifndef LIBOPENCM3_PIO_COMMON_3A3U3X_H +#define LIBOPENCM3_PIO_COMMON_3A3U3X_H + +#include + +/* --- PIO registers ----------------------------------------------------- */ + +/* Peripheral AB Select Register */ +#define PIO_ABSR(port) MMIO32((port) + 0x0070) + +/* System Clock Glitch Input Filter Select Register */ +#define PIO_SCIFSR(port) MMIO32((port) + 0x0080) + +/* Debouncing Input Filter Select Register */ +#define PIO_DIFSR(port) MMIO32((port) + 0x0084) + +/* Glitch or Debouncing Input Filter Clock Selection Status Register */ +#define PIO_IFDGSR(port) MMIO32((port) + 0x0088) + + +#endif + +#else +#warning "pio_common_3a3u3x.h should not be included explicitly, only via pio.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3n3s.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3n3s.h new file mode 100644 index 00000000..09d54dcd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_3n3s.h @@ -0,0 +1,65 @@ +/* + * This file is part of the libopencm3 project. + * + * COpyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA PIO.H +The order of header inclusion is important. pio.h includes the device +specific memorymap.h header before including this header file.*/ + +#if defined(LIBOPENCM3_PIO_H) + +#ifndef LIBOPENCM3_PIO_COMMON_3N3S_H +#define LIBOPENCM3_PIO_COMMON_3N3S_H + +#include + +/* --- PIO registers ----------------------------------------------------- */ + +/* Peripheral Select Register 1 */ +#define PIO_ABCDSR1(port) MMIO32((port) + 0x0070) + +/* Peripheral Select Register 2 */ +#define PIO_ABCDSR2(port) MMIO32((port) + 0x0074) + +/* Input Filter Slow Clock Disable Register */ +#define PIO_IFSCDR(port) MMIO32((port) + 0x0080) + +/* Input Filter Slow Clock Enable Register */ +#define PIO_IFSCER(port) MMIO32((port) + 0x0084) + +/* Input Filter Slow Clock Status Register */ +#define PIO_IFSCSR(port) MMIO32((port) + 0x0088) + +/* Pad Pull-down Disable Register */ +#define PIO_PPDDR(port) MMIO32((port) + 0x0090) + +/* Pad Pull-down Enable Register */ +#define PIO_PPDER(port) MMIO32((port) + 0x0094) + +/* Pad Pull-down Status Register */ +#define PIO_PPDSR(port) MMIO32((port) + 0x0098) + +/* Schmitt Trigger Register */ +#define PIO_SCHMITT(port) MMIO32((port) + 0x0100) + + +#endif + +#else +#warning "pio_common_3n3s.h should not be included explicitly, only via pio.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_all.h new file mode 100644 index 00000000..2c262f4d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pio_common_all.h @@ -0,0 +1,168 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA PIO.H +The order of header inclusion is important. pio.h includes the device +specific memorymap.h header before including this header file.*/ + +#if defined(LIBOPENCM3_PIO_H) + +#ifndef LIBOPENCM3_PIO_COMMON_ALL_H +#define LIBOPENCM3_PIO_COMMON_ALL_H + +#include + +/* --- Convenience macros ------------------------------------------------ */ + +/* GPIO port base addresses (for convenience) */ +#define PIOA PIOA_BASE +#define PIOB PIOB_BASE +#define PIOC PIOC_BASE +#define PIOD PIOD_BASE +#define PIOE PIOE_BASE +#define PIOF PIOF_BASE +#define PIOG PIOG_BASE +#define PIOH PIOH_BASE + +/* --- PIO registers ----------------------------------------------------- */ + +/* PIO Enable Register */ +#define PIO_PER(port) MMIO32((port) + 0x0000) + +/* PIO Disable Register */ +#define PIO_PDR(port) MMIO32((port) + 0x0004) + +/* PIO Status Register */ +#define PIO_PSR(port) MMIO32((port) + 0x0008) + +/* Output Enable Register */ +#define PIO_OER(port) MMIO32((port) + 0x0010) + +/* Output Disable Register */ +#define PIO_ODR(port) MMIO32((port) + 0x0014) + +/* Output Status Register */ +#define PIO_OSR(port) MMIO32((port) + 0x0018) + +/* Glitch Input Filter Enable Register */ +#define PIO_IFER(port) MMIO32((port) + 0x0020) + +/* Glitch Input Filter Disable Register */ +#define PIO_IFDR(port) MMIO32((port) + 0x0024) + +/* Glitch Input Filter Status Register */ +#define PIO_IFSR(port) MMIO32((port) + 0x0028) + +/* Set Output Data Register */ +#define PIO_SODR(port) MMIO32((port) + 0x0030) + +/* Clear Output Data Register */ +#define PIO_CODR(port) MMIO32((port) + 0x0034) + +/* Output Data Status Register */ +#define PIO_ODSR(port) MMIO32((port) + 0x0038) + +/* Pin Data Status Register */ +#define PIO_PDSR(port) MMIO32((port) + 0x003C) + +/* Interrupt Enable Register */ +#define PIO_IER(port) MMIO32((port) + 0x0040) + +/* Interrupt Disable Register */ +#define PIO_IDR(port) MMIO32((port) + 0x0044) + +/* Interrupt Mask Register */ +#define PIO_IMR(port) MMIO32((port) + 0x0048) + +/* Interrupt Status Register */ +#define PIO_ISR(port) MMIO32((port) + 0x004C) + +/* Multi-driver Enable Register */ +#define PIO_MDER(port) MMIO32((port) + 0x0050) + +/* Multi-driver Disable Register */ +#define PIO_MDDR(port) MMIO32((port) + 0x0054) + +/* Multi-driver Status Register */ +#define PIO_MDSR(port) MMIO32((port) + 0x0058) + +/* Pull-up Disable Register */ +#define PIO_PUDR(port) MMIO32((port) + 0x0060) + +/* Pull-up Enable Register */ +#define PIO_PUER(port) MMIO32((port) + 0x0064) + +/* Pad Pull-up Status Register */ +#define PIO_PUSR(port) MMIO32((port) + 0x0068) + +/* Slow Clock Divider Debouncing Register */ +#define PIO_SCDR(port) MMIO32((port) + 0x008C) + +/* Output Write Enable */ +#define PIO_OWER(port) MMIO32((port) + 0x00A0) + +/* Output Write Disable */ +#define PIO_OWDR(port) MMIO32((port) + 0x00A4) + +/* Output Write Status Register */ +#define PIO_OWSR(port) MMIO32((port) + 0x00A8) + +/* Additional Interrupt Modes Enable Register */ +#define PIO_AIMER(port) MMIO32((port) + 0x00B0) + +/* Additional Interrupt Modes Disables Register */ +#define PIO_AIMDR(port) MMIO32((port) + 0x00B4) + +/* Additional Interrupt Modes Mask Register */ +#define PIO_AIMMR(port) MMIO32((port) + 0x00B8) + +/* Edge Select Register */ +#define PIO_ESR(port) MMIO32((port) + 0x00C0) + +/* Level Select Register */ +#define PIO_LSR(port) MMIO32((port) + 0x00C4) + +/* Edge/Level Status Register */ +#define PIO_ELSR(port) MMIO32((port) + 0x00C8) + +/* Falling Edge/Low Level Select Register */ +#define PIO_FELLSR(port) MMIO32((port) + 0x00D0) + +/* Rising Edge/High Level Select Register */ +#define PIO_REHLSR(port) MMIO32((port) + 0x00D4) + +/* Fall/Rise - Low/High Status Register */ +#define PIO_FRLHSR(port) MMIO32((port) + 0x00D8) + +/* Lock Status */ +#define PIO_LOCKSR(port) MMIO32((port) + 0x00E0) + +/* Write Protect Mode Register */ +#define PIO_WPMR(port) MMIO32((port) + 0x00E4) + +/* Write Protect Status Register */ +#define PIO_WPSR(port) MMIO32((port) + 0x00E8) + + +#endif + +#else +#warning "pio_common_all.h should not be included explicitly, only via pio.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3s3x.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3s3x.h new file mode 100644 index 00000000..b009e081 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3s3x.h @@ -0,0 +1,68 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(LIBOPENCM3_PMC_H) + +#ifndef LIBOPENCM3_PMC_COMMON_3A3S3X_H +#define LIBOPENCM3_PMC_COMMON_3A3S3X_H + + +/* --- Power Management Controller (PMC) registers ----------------------- */ + +/* Peripheral Clock Enable Register 0 */ +#define PMC_PCER0 MMIO32(PMC_BASE + 0x0010) + +/* Peripheral Clock Disable Register 0 */ +#define PMC_PCDR0 MMIO32(PMC_BASE + 0x0014) + +/* Peripheral Clock Status Register 0 */ +#define PMC_PCSR0 MMIO32(PMC_BASE + 0x0018) + +/* USB Clock Register */ +#define PMC_USB MMIO32(PMC_BASE + 0x0038) + +/* Peripheral Clock Enable Register 1 */ +#define PMC_PCER1 MMIO32(PMC_BASE + 0x0100) + +/* Peripheral Clock Disable Register 1 */ +#define PMC_PCDR1 MMIO32(PMC_BASE + 0x0104) + +/* Peripheral Clock Status Register 1 */ +#define PMC_PCSR1 MMIO32(PMC_BASE + 0x0108) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC USB Clock Register (PMC_USB) ------------------------------------ */ + +/* Divider for USB Clock */ +#define PMC_USB_USBDIV_SHIFT 8 +#define PMC_USB_USBDIV_MASK (0x0F << PMC_USB_USBDIV_SHIFT) + +/* USB Input Clock Selection */ +#define PMC_USB_USBS (0x01 << 0) + + +#endif + +#else +#warning "pmc_common_3a3s3x.h should not be included explicitly, only via pmc.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3u3x.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3u3x.h new file mode 100644 index 00000000..39917b28 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3a3u3x.h @@ -0,0 +1,100 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(LIBOPENCM3_PMC_H) + +#ifndef LIBOPENCM3_PMC_COMMON_3A3U3X_H +#define LIBOPENCM3_PMC_COMMON_3A3U3X_H + + +/* --- Power Management Controller (PMC) registers ----------------------- */ + +/* UTMI Clock Register */ +#define CKGR_UCKR MMIO32(PMC_BASE + 0x001C) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC UTMI Clock Configuration Register (CKGR_UCKR) ------------------- */ + +/* UTMI PLL Start-up Time */ +#define CKGR_UCKR_UPLLCOUNT_SHIFT 20 +#define CKGR_UCKR_UPLLCOUNT_MASK (0x0F << CKGR_UCKR_UPLLCOUNT_SHIFT) + +/* UTMI PLL Enable */ +#define CKGR_UCKR_UPLLEN (0x01 << 16) + +/* --- PMC Master Clock Register (PMC_MCKR) -------------------------------- */ + +/* UPLL Divide by 2 */ +#define PMC_MCKR_UPLLDIV2 (0x01 << 13) + +/* Master Clock Source Selection */ +#define PMC_MCKR_CSS_UPLL_CLK (3 << PMC_MCKR_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 0 (PMC_PCK0) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK0_CSS_UPLL_CLK (3 << PMC_PCK0_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 1 (PMC_PCK1) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK1_CSS_UPLL_CLK (3 << PMC_PCK1_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 2 (PMC_PCK2) ------------------------ */ + +/* Master Clock Source Selection */ +#define PMC_PCK2_CSS_UPLL_CLK (3 << PMC_PCK2_CSS_SHIFT) + + +/* --- PMC Interrupt Enable Register (PMC_IER) ----------------------------- */ + +/* UTMI PLL Lock Interrupt Enable */ +#define PMC_IER_LOCKU (0x01 << 6) + + +/* --- PMC Interrupt Disable Register (PMC_IDR) ----------------------------- */ + +/* UTMI PLL Lock Interrupt Disable */ +#define PMC_IDR_LOCKU (0x01 << 6) + + +/* --- PMC Status Register (PMC_SR) ---------------------------------------- */ + +/* UTMI PLL Lock Status */ +#define PMC_SR_LOCKU (0x01 << 6) + + +/* --- PMC Interrupt Mask Register (PMC_IMR) ----------------------------- */ + +/* UTMI PLL Lock Interrupt Mask */ +#define PMC_IMR_LOCKU (0x01 << 6) + + +#endif + +#else +#warning "pmc_common_3a3u3x.h should not be included explicitly, only via pmc.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3n3u.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3n3u.h new file mode 100644 index 00000000..5f053554 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_3n3u.h @@ -0,0 +1,39 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(LIBOPENCM3_PMC_H) + +#ifndef LIBOPENCM3_PMC_COMMON_3N3U_H +#define LIBOPENCM3_PMC_COMMON_3N3U_H + +/* Peripheral Clock Enable Register */ +#define PMC_PCER MMIO32(PMC_BASE + 0x0010) + +/* Peripheral Clock Disable Register */ +#define PMC_PCDR MMIO32(PMC_BASE + 0x0014) + +/* Peripheral Clock Status Register */ +#define PMC_PCSR MMIO32(PMC_BASE + 0x0018) + + +#endif + +#else +#warning "pmc_common_3n3u.h should not be included explicitly, only via pmc.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_all.h new file mode 100644 index 00000000..66676597 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/pmc_common_all.h @@ -0,0 +1,501 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(LIBOPENCM3_PMC_H) + +#ifndef LIBOPENCM3_PMC_COMMON_ALL_H +#define LIBOPENCM3_PMC_COMMON_ALL_H + +#include + +/* --- Power Management Controller (PMC) registers ----------------------- */ + +/* System Clock Enable Register */ +#define PMC_SCER MMIO32(PMC_BASE + 0x0000) + +/* System Clock Disable Register */ +#define PMC_SCDR MMIO32(PMC_BASE + 0x0004) + +/* System Clock Status Register */ +#define PMC_SCSR MMIO32(PMC_BASE + 0x0008) + +/* Main Oscillator Register */ +#define CKGR_MOR MMIO32(PMC_BASE + 0x0020) + +/* Main Clock Frequency Register */ +#define CKGR_MCFR MMIO32(PMC_BASE + 0x0024) + +/* PLLA Register */ +#define CKGR_PLLAR MMIO32(PMC_BASE + 0x0028) + +/* Master Clock Register */ +#define PMC_MCKR MMIO32(PMC_BASE + 0x0030) + +/* Programmable Clock 0 Register */ +#define PMC_PCK0 MMIO32(PMC_BASE + 0x0040) + +/* Programmable Clock 1 Register */ +#define PMC_PCK1 MMIO32(PMC_BASE + 0x0044) + +/* Programmable Clock 2 Register */ +#define PMC_PCK2 MMIO32(PMC_BASE + 0x0048) + +/* Interrupt Enable Register */ +#define PMC_IER MMIO32(PMC_BASE + 0x0060) + +/* Interrupt Disable Register */ +#define PMC_IDR MMIO32(PMC_BASE + 0x0064) + +/* Status Register */ +#define PMC_SR MMIO32(PMC_BASE + 0x0068) + +/* Interrupt Mask Register */ +#define PMC_IMR MMIO32(PMC_BASE + 0x006C) + +/* Fast Startup Mode Register */ +#define PMC_FSMR MMIO32(PMC_BASE + 0x0070) + +/* Fast Startup Polarity Register */ +#define PMC_FSPR MMIO32(PMC_BASE + 0x0074) + +/* Fault Output Clear Register */ +#define PMC_FOCR MMIO32(PMC_BASE + 0x0078) + +/* Write Protect Mode Register */ +#define PMC_WPMR MMIO32(PMC_BASE + 0x00E4) + +/* Write Protect Status Register */ +#define PMC_WPSR MMIO32(PMC_BASE + 0x00E8) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- PMC System Clock Enable Register (PMC_SCER) ------------------------- */ + +/* Programmable Clock Output Enable */ +#define PMC_SCER_PCK0 (0x01 << 8) +#define PMC_SCER_PCK1 (0x01 << 9) +#define PMC_SCER_PCK2 (0x01 << 10) + + +/* --- PMC System Clock Disable Register (PMC_SCDR) ------------------------ */ + +/* Programmable Clock Output Disable */ +#define PMC_SCDR_PCK0 (0x01 << 8) +#define PMC_SCDR_PCK1 (0x01 << 9) +#define PMC_SCDR_PCK2 (0x01 << 10) + + +/* --- PMC System Clock Status Register (PMC_SCSR) ------------------------- */ + +/* Programmable Clock Output Status */ +#define PMC_SCSR_PCK0 (0x01 << 8) +#define PMC_SCSR_PCK1 (0x01 << 9) +#define PMC_SCSR_PCK2 (0x01 << 10) + + +/* for bit definitions for PMC System Clock Enable/Disable/Status Register see + * periph.h */ + + +/* --- PMC Clock Generator Main Oscillator Register (CKGR_MOR) ------------- */ + +/* Clock Failure Detector Enable */ +#define CKGR_MOR_CFDEN (0x01 << 25) + +/* Main Oscillator Selection */ +#define CKGR_MOR_MOSCSEL (0x01 << 24) + +/* Password for changing settings */ +#define CKGR_MOR_KEY (0x37 << 16) + +/* Main Crystal Oscillator Start-up Time */ +#define CKGR_MOR_MOSCXTST_SHIFT 8 +#define CKGR_MOR_MOSCXTST_MASK (0xFF << 8) + +/* Main On-Chip RC Oscillator Frequency Selection */ +#define CKGR_MOR_MOSCRCF_SHIFT 4 +#define CKGR_MOR_MOSCRCF_MASK (0x07 << CKGR_MOR_MOSCRCF_SHIFT) + +/* Main On-Chip RC Oscillator selectable frequencies */ +#define CKGR_MOR_MOSCRCF_4MHZ (0 << CKGR_MOR_MOSCRCF_SHIFT) +#define CKGR_MOR_MOSCRCF_8MHZ (1 << CKGR_MOR_MOSCRCF_SHIFT) +#define CKGR_MOR_MOSCRCF_12MHZ (2 << CKGR_MOR_MOSCRCF_SHIFT) + +/* Main On-Chip RC Oscillator Enable */ +#define CKGR_MOR_MOSCRCEN (0x01 << 3) + +/* Main Crystal Oscillator Bypass */ +#define CKGR_MOR_MOSCXTBY (0x01 << 1) + +/* Main Crystal Oscillator Enable */ +#define CKGR_MOR_MOSCXTEN (0x01 << 0) + + +/* --- PMC Clock Generator Main Clock Frequency Register (CKGR_MCFR) ------- */ + +/* Main Clock Ready */ +#define CKGR_MCFR_MAINFRDY (0x01 << 16) + +/* Main Clock Frequency */ +#define CKGR_MCFR_MAINF_SHIFT 0 +#define CKGR_MCFR_MAINF_MASK (0xFFFF << CKGR_MCFR_MAINF_SHIFT) + + +/* --- PMC Clock Generator PLLA Register (CKGR_PLLAR) ---------------------- */ + +/* must be set to program CKGR_PLLAR */ +#define CKGR_PLLAR_ONE (0x01 << 29) + +/* PLLA Multiplier */ +#define CKGR_PLLAR_MULA_SHIFT 16 +#define CKGR_PLLAR_MULA_MASK (0x7FF << CKGR_PLLAR_MULA_SHIFT) + +/* PLLA Counter */ +#define CKGR_PLLAR_PLLACOUNT_SHIFT 8 +#define CKGR_PLLAR_PLLACOUNT_MASK (0x3F << CKGR_PLLAR_PLLACOUNT_SHIFT) + +/* Divider */ +#define CKGR_PLLAR_DIVA_SHIFT 0 +#define CKGR_PLLAR_DIVA_MASK (0xFF << CKGR_PLLAR_DIVA_SHIFT) + + +/* --- PMC Master Clock Register (PMC_MCKR) -------------------------------- */ + +/* Processor Clock Prescaler */ +#define PMC_MCKR_PRES_SHIFT 4 +#define PMC_MCKR_PRES_MASK (0x07 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_1 (0 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_2 (1 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_4 (2 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_8 (3 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_16 (4 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_32 (5 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_64 (6 << PMC_MCKR_PRES_SHIFT) +#define PMC_MCKR_PRES_CLK_3 (7 << PMC_MCKR_PRES_SHIFT) + +/* Master Clock Source Selection */ +#define PMC_MCKR_CSS_SHIFT 0 +#define PMC_MCKR_CSS_MASK (0x03 << PMC_MCKR_CSS_SHIFT) +#define PMC_MCKR_CSS_SLOW_CLK (0 << PMC_MCKR_CSS_SHIFT) +#define PMC_MCKR_CSS_MAIN_CLK (1 << PMC_MCKR_CSS_SHIFT) +#define PMC_MCKR_CSS_PLLA_CLK (2 << PMC_MCKR_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 0 (PMC_PCK0) ------------------------ */ + +/* Programmable Clock Prescaler */ +#define PMC_PCK0_PRES_SHIFT 4 +#define PMC_PCK0_PRES_MASK (0x07 << PMC_PCK0_PRES_SHIFT) +#define PMC_PCK0_PRES_CLK_1 (0 << PMC_PCK0_PRES_SHIFT) +#define PMC_PCK0_PRES_CLK_2 (1 << PMC_PCK0_PRES_SHIFT) +#define PMC_PCK0_PRES_CLK_4 (2 << PMC_PCK0_PRES_SHIFT) +#define PMC_PCK0_PRES_CLK_8 (3 << PMC_PCK0_PRES_SHIFT) +#define PMC_PCK0_PRES_CLK_16 (4 << PMC_PCK0_PRES_SHIFT) +#define PMC_PCK0_PRES_CLK_32 (5 << PMC_PCK0_PRES_SHIFT) +#define PMC_PCK0_PRES_CLK_64 (6 << PMC_PCK0_PRES_SHIFT) + +/* Master Clock Source Selection */ +#define PMC_PCK0_CSS_SHIFT 0 +#define PMC_PCK0_CSS_MASK (0x07 << PMC_PCK0_CSS_SHIFT) +#define PMC_PCK0_CSS_SLOW_CLK (0 << PMC_PCK0_CSS_SHIFT) +#define PMC_PCK0_CSS_MAIN_CLK (1 << PMC_PCK0_CSS_SHIFT) +#define PMC_PCK0_CSS_PLLA_CLK (2 << PMC_PCK0_CSS_SHIFT) +#define PMC_PCK0_CSS_MCK (4 << PMC_PCK0_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 1 (PMC_PCK1) ------------------------ */ + +/* Programmable Clock Prescaler */ +#define PMC_PCK1_PRES_SHIFT 4 +#define PMC_PCK1_PRES_MASK (0x07 << PMC_PCK1_PRES_SHIFT) +#define PMC_PCK1_PRES_CLK_1 (0 << PMC_PCK1_PRES_SHIFT) +#define PMC_PCK1_PRES_CLK_2 (1 << PMC_PCK1_PRES_SHIFT) +#define PMC_PCK1_PRES_CLK_4 (2 << PMC_PCK1_PRES_SHIFT) +#define PMC_PCK1_PRES_CLK_8 (3 << PMC_PCK1_PRES_SHIFT) +#define PMC_PCK1_PRES_CLK_16 (4 << PMC_PCK1_PRES_SHIFT) +#define PMC_PCK1_PRES_CLK_32 (5 << PMC_PCK1_PRES_SHIFT) +#define PMC_PCK1_PRES_CLK_64 (6 << PMC_PCK1_PRES_SHIFT) + +/* Master Clock Source Selection */ +#define PMC_PCK1_CSS_SHIFT 0 +#define PMC_PCK1_CSS_MASK (0x07 << PMC_PCK1_CSS_SHIFT) +#define PMC_PCK1_CSS_SLOW_CLK (0 << PMC_PCK1_CSS_SHIFT) +#define PMC_PCK1_CSS_MAIN_CLK (1 << PMC_PCK1_CSS_SHIFT) +#define PMC_PCK1_CSS_PLLA_CLK (2 << PMC_PCK1_CSS_SHIFT) +#define PMC_PCK1_CSS_MCK (4 << PMC_PCK1_CSS_SHIFT) + + +/* --- PMC Programmable Clock Register 2 (PMC_PCK2) ------------------------ */ + +/* Programmable Clock Prescaler */ +#define PMC_PCK2_PRES_SHIFT 4 +#define PMC_PCK2_PRES_MASK (0x07 << PMC_PCK2_PRES_SHIFT) +#define PMC_PCK2_PRES_CLK_1 (0 << PMC_PCK2_PRES_SHIFT) +#define PMC_PCK2_PRES_CLK_2 (1 << PMC_PCK2_PRES_SHIFT) +#define PMC_PCK2_PRES_CLK_4 (2 << PMC_PCK2_PRES_SHIFT) +#define PMC_PCK2_PRES_CLK_8 (3 << PMC_PCK2_PRES_SHIFT) +#define PMC_PCK2_PRES_CLK_16 (4 << PMC_PCK2_PRES_SHIFT) +#define PMC_PCK2_PRES_CLK_32 (5 << PMC_PCK2_PRES_SHIFT) +#define PMC_PCK2_PRES_CLK_64 (6 << PMC_PCK2_PRES_SHIFT) + +/* Master Clock Source Selection */ +#define PMC_PCK2_CSS_SHIFT 0 +#define PMC_PCK2_CSS_MASK (0x07 << PMC_PCK2_CSS_SHIFT) +#define PMC_PCK2_CSS_SLOW_CLK (0 << PMC_PCK2_CSS_SHIFT) +#define PMC_PCK2_CSS_MAIN_CLK (1 << PMC_PCK2_CSS_SHIFT) +#define PMC_PCK2_CSS_PLLA_CLK (2 << PMC_PCK2_CSS_SHIFT) +#define PMC_PCK2_CSS_MCK (4 << PMC_PCK2_CSS_SHIFT) + + +/* --- PMC Interrupt Enable Register (PMC_IER) ----------------------------- */ + +/* Clock Failure Detector Event Interrupt Enable */ +#define PMC_IER_CFDEV (0x01 << 18) + +/* Main On-Chip RC Status Interrupt Enable */ +#define PMC_IER_MOSCRCS (0x01 << 17) + +/* Main Oscillator Selection Status Interrupt Enable */ +#define PMC_IER_MOSCSELS (0x01 << 16) + +/* Programmable Clock Ready 2 Interrupt Enable */ +#define PMC_IER_PCKRDY2 (0x01 << 10) + +/* Programmable Clock Ready 1 Interrupt Enable */ +#define PMC_IER_PCKRDY1 (0x01 << 9) + +/* Programmable Clock Ready 0 Interrupt Enable */ +#define PMC_IER_PCKRDY0 (0x01 << 8) + +/* Master Clock Ready Interrupt Enable */ +#define PMC_IER_MCKRDY (0x01 << 3) + +/* PLLA Lock Interrupt Enable */ +#define PMC_IER_LOCKA (0x01 << 1) + +/* Main Crystal Oscillator Status Interrupt Enable */ +#define PMC_IER_MOSCXTS (0x01 << 0) + + +/* --- PMC Interrupt Disable Register (PMC_IDR) ----------------------------- */ + +/* Clock Failure Detector Event Interrupt Disable */ +#define PMC_IDR_CFDEV (0x01 << 18) + +/* Main On-Chip RC Status Interrupt Disable */ +#define PMC_IDR_MOSCRCS (0x01 << 17) + +/* Main Oscillator Selection Status Interrupt Disable */ +#define PMC_IDR_MOSCSELS (0x01 << 16) + +/* Programmable Clock Ready 2 Interrupt Disable */ +#define PMC_IDR_PCKRDY2 (0x01 << 10) + +/* Programmable Clock Ready 1 Interrupt Disable */ +#define PMC_IDR_PCKRDY1 (0x01 << 9) + +/* Programmable Clock Ready 0 Interrupt Disable */ +#define PMC_IDR_PCKRDY0 (0x01 << 8) + +/* Master Clock Ready Interrupt Disable */ +#define PMC_IDR_MCKRDY (0x01 << 3) + +/* PLLA Lock Interrupt Disable */ +#define PMC_IDR_LOCKA (0x01 << 1) + +/* Main Crystal Oscillator Status Interrupt Disable */ +#define PMC_IDR_MOSCXTS (0x01 << 0) + + +/* --- PMC Status Register (PMC_SR) ---------------------------------------- */ + +/* Clock Failure Detector Fault Output Status */ +#define PMC_SR_FOS (0x01 << 20) + +/* Clock Failure Detector Status */ +#define PMC_SR_CFDS (0x01 << 19) + +/* Clock Failure Detector Event */ +#define PMC_SR_CFDEV (0x01 << 18) + +/* Main On-Chip RC Oscillator Status */ +#define PMC_SR_MOSCRCS (0x01 << 17) + +/* Main Oscillator Selection Status */ +#define PMC_SR_MOSCSELS (0x01 << 16) + +/* Programmable Clock 2 Ready Status */ +#define PMC_SR_PCKRDY2 (0x01 << 10) + +/* Programmable Clock 1 Ready Status */ +#define PMC_SR_PCKRDY1 (0x01 << 9) + +/* Programmable Clock 0 Ready Status */ +#define PMC_SR_PCKRDY0 (0x01 << 8) + +/* Slow Clock Oscillator Selection */ +#define PMC_SR_OSCSELS (0x01 << 7) + +/* Master Clock Status */ +#define PMC_SR_MCKRDY (0x01 << 3) + +/* PLLA Lock Status */ +#define PMC_SR_LOCKA (0x01 << 1) + +/* Main XTAL Oscillator Status */ +#define PMC_SR_MOSCXTS (0x01 << 0) + + +/* --- PMC Interrupt Mask Register (PMC_IMR) ------------------------------- */ + +/* Clock Failure Detector Event Interrupt Mask */ +#define PMC_IMR_CFDEV (0x01 << 18) + +/* Main On-Chip RC Status Interrupt Mask */ +#define PMC_IMR_MOSCRCS (0x01 << 17) + +/* Main Oscillator Selection Status Interrupt Mask */ +#define PMC_IMR_MOSCSELS (0x01 << 16) + +/* Programmable Clock Ready 2 Interrupt Mask */ +#define PMC_IMR_PCKRDY2 (0x01 << 10) + +/* Programmable Clock Ready 1 Interrupt Mask */ +#define PMC_IMR_PCKRDY1 (0x01 << 9) + +/* Programmable Clock Ready 0 Interrupt Mask */ +#define PMC_IMR_PCKRDY0 (0x01 << 8) + +/* Master Clock Ready Interrupt Mask */ +#define PMC_IMR_MCKRDY (0x01 << 3) + +/* PLLA Lock Interrupt Mask */ +#define PMC_IMR_LOCKA (0x01 << 1) + +/* Main Crystal Oscillator Status Interrupt Mask */ +#define PMC_IMR_MOSCXTS (0x01 << 0) + + +/* --- PMC Fast Startup Mode Register (PMC_FSMR) --------------------------- */ + +/* Low Power Mode */ +#define PMC_FSMR_LPM (0x01 << 20) + +/* USB Alarm Enable */ +#define PMC_FSMR_USBAL (0x01 << 18) + +/* RTC Alarm Enable */ +#define PMC_FSMR_RTCAL (0x01 << 17) + +/* RTC Alarm Enable */ +#define PMC_FSMR_RTTAL (0x01 << 16) + +/* Fast Startup Input Enable 0 to 15 */ +#define PMC_FSMR_FSTT15 (0x01 << 15) +#define PMC_FSMR_FSTT14 (0x01 << 14) +#define PMC_FSMR_FSTT13 (0x01 << 13) +#define PMC_FSMR_FSTT12 (0x01 << 12) +#define PMC_FSMR_FSTT11 (0x01 << 11) +#define PMC_FSMR_FSTT10 (0x01 << 10) +#define PMC_FSMR_FSTT9 (0x01 << 9) +#define PMC_FSMR_FSTT8 (0x01 << 8) +#define PMC_FSMR_FSTT7 (0x01 << 7) +#define PMC_FSMR_FSTT6 (0x01 << 6) +#define PMC_FSMR_FSTT5 (0x01 << 5) +#define PMC_FSMR_FSTT4 (0x01 << 4) +#define PMC_FSMR_FSTT3 (0x01 << 3) +#define PMC_FSMR_FSTT2 (0x01 << 2) +#define PMC_FSMR_FSTT1 (0x01 << 1) +#define PMC_FSMR_FSTT0 (0x01 << 0) + + +/* --- PMC Fast Startup Polarity Register (PMC_FSPR) ----------------------- */ + +/* Fast Startup Input Polarity x */ +#define PMC_FSPR_FSTP15 (0x01 << 15) +#define PMC_FSPR_FSTP14 (0x01 << 14) +#define PMC_FSPR_FSTP13 (0x01 << 13) +#define PMC_FSPR_FSTP12 (0x01 << 12) +#define PMC_FSPR_FSTP11 (0x01 << 11) +#define PMC_FSPR_FSTP10 (0x01 << 10) +#define PMC_FSPR_FSTP9 (0x01 << 9) +#define PMC_FSPR_FSTP8 (0x01 << 8) +#define PMC_FSPR_FSTP7 (0x01 << 7) +#define PMC_FSPR_FSTP6 (0x01 << 6) +#define PMC_FSPR_FSTP5 (0x01 << 5) +#define PMC_FSPR_FSTP4 (0x01 << 4) +#define PMC_FSPR_FSTP3 (0x01 << 3) +#define PMC_FSPR_FSTP2 (0x01 << 2) +#define PMC_FSPR_FSTP1 (0x01 << 1) +#define PMC_FSPR_FSTP0 (0x01 << 0) + + +/* --- PMC Fault Output Clear Register (PMC_FOCR) -------------------------- */ + +/* Fault Output Clear */ +#define PMC_FOCR_FOCLR (0x01 << 0) + + +/* --- PMC Write Protect Mode Register (PMC_WPMR) -------------------------- */ + +/* Write Protect Key */ +#define PMC_WPMR_WPKEY_SHIFT 8 +#define PMC_WPMR_WPKEY (0x504D43 << PMC_WPMR_WPKEY_SHIFT) + +/* Write Protect Enable */ +#define PMC_WPMR_WPEN (0x01 << 0) + + +/* --- PMC Write Protect Status Register (PMC_WPSR) ------------------------ */ + +/* Write Protect Violation Source */ +#define PMC_WPSR_WPVSRC_SHIFT 8 +#define PMC_WPSR_WPVSRC_MASK (0xFFFF << PMC_WPSR_WPVSRC_SHIFT) + +/* Write Protect Violation Status */ +#define PMC_WPSR_WPVS (0x01 << 0) + + + + +extern uint32_t pmc_mck_frequency; + +enum mck_src { + MCK_SRC_SLOW = 0, + MCK_SRC_MAIN = 1, + MCK_SRC_PLLA = 2, + MCK_SRC_UPLL = 3, +}; + +void pmc_mck_set_source(enum mck_src src); +void pmc_xtal_enable(bool en, uint8_t startup_time); +void pmc_plla_config(uint8_t mul, uint8_t div); +void pmc_peripheral_clock_enable(uint8_t pid); +void pmc_peripheral_clock_disable(uint8_t pid); +void pmc_clock_setup_in_xtal_12mhz_out_84mhz(void); +void pmc_clock_setup_in_rc_4mhz_out_84mhz(void); + +#endif + +#else +#warning "pmc_common_all.h should not be included explicitly, only via pmc.h" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/smc_common_3a3u3x.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/smc_common_3a3u3x.h new file mode 100644 index 00000000..59a16c2e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/common/smc_common_3a3u3x.h @@ -0,0 +1,559 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SMC_H +#define LIBOPENCM3_SMC_H + +#include + + +/* Chip Select Defines */ +#define SMC_CS_0 0 +#define SMC_CS_1 1 +#define SMC_CS_2 2 +#define SMC_CS_3 3 + + +/* --- Static Memory Controller (SMC) registers ---------------------------- */ + +/* NFC Configuration Register */ +#define SMC_CFG MMIO32(SMC_BASE + 0x00) + +/* NFC Control Register */ +#define SMC_CTRL MMIO32(SMC_BASE + 0x04) + +/* NFC Status Register */ +#define SMC_SR MMIO32(SMC_BASE + 0x08) + +/* NFC Interrupt Enable Register */ +#define SMC_IER MMIO32(SMC_BASE + 0x0C) + +/* NFC Interrupt Disable Register */ +#define SMC_IDR MMIO32(SMC_BASE + 0x10) + +/* Interrupt Mask Register */ +#define SMC_IMR MMIO32(SMC_BASE + 0x14) + +/* NFC Address Cycle Zero Register */ +#define SMC_ADDR MMIO32(SMC_BASE + 0x18) + +/* Bank Address Register */ +#define SMC_BANK MMIO32(SMC_BASE + 0x1C) + +/* ECC Control Register */ +#define SMC_ECC_CTRL MMIO32(SMC_BASE + 0x20) + +/* ECC Mode Register */ +#define SMC_ECC_MD MMIO32(SMC_BASE + 0x24) + +/* ECC Status 1 Register */ +#define SMC_ECC_SR1 MMIO32(SMC_BASE + 0x28) + +/* ECC Parity 0 Register */ +#define SMC_ECC_PR0 MMIO32(SMC_BASE + 0x2C) + +/* ECC parity 1 Register */ +#define SMC_ECC_PR1 MMIO32(SMC_BASE + 0x30) + +/* ECC status 2 Register */ +#define SMC_ECC_SR2 MMIO32(SMC_BASE + 0x34) + +/* ECC parity 2 Register */ +#define SMC_ECC_PR2 MMIO32(SMC_BASE + 0x38) + +/* ECC parity 3 Register */ +#define SMC_ECC_PR3 MMIO32(SMC_BASE + 0x3C) + +/* ECC parity 4 Register */ +#define SMC_ECC_PR4 MMIO32(SMC_BASE + 0x40) + +/* ECC parity 5 Register */ +#define SMC_ECC_PR5 MMIO32(SMC_BASE + 0x44) + +/* ECC parity 6 Register */ +#define SMC_ECC_PR6 MMIO32(SMC_BASE + 0x48) + +/* ECC parity 7 Register */ +#define SMC_ECC_PR7 MMIO32(SMC_BASE + 0x4C) + +/* ECC parity 8 Register */ +#define SMC_ECC_PR8 MMIO32(SMC_BASE + 0x50) + +/* ECC parity 9 Register */ +#define SMC_ECC_PR9 MMIO32(SMC_BASE + 0x54) + +/* ECC parity 10 Register */ +#define SMC_ECC_PR10 MMIO32(SMC_BASE + 0x58) + +/* ECC parity 11 Register */ +#define SMC_ECC_PR11 MMIO32(SMC_BASE + 0x5C) + +/* ECC parity 12 Register */ +#define SMC_ECC_PR12 MMIO32(SMC_BASE + 0x60) + +/* ECC parity 13 Register */ +#define SMC_ECC_PR13 MMIO32(SMC_BASE + 0x64) + +/* ECC parity 14 Register */ +#define SMC_ECC_PR14 MMIO32(SMC_BASE + 0x68) + +/* ECC parity 15 Register */ +#define SMC_ECC_PR15 MMIO32(SMC_BASE + 0x6C) + +/* Setup Register */ +#define SMC_SETUP(CS_number) MMIO32(SMC_BASE + 0x14*(CS_number) \ + + 0x70) + +/* Pulse Register */ +#define SMC_PULSE(CS_number) MMIO32(SMC_BASE + 0x14*(CS_number) \ + + 0x74) + +/* Cycle Register */ +#define SMC_CYCLE(CS_number) MMIO32(SMC_BASE + 0x14*(CS_number) \ + + 0x78) + +/* Timings Register */ +#define SMC_TIMINGS(CS_number) MMIO32(SMC_BASE + 0x14*(CS_number) \ + + 0x7C) + +/* Mode Register */ +#define SMC_MODE(CS_number) MMIO32(SMC_BASE + 0x14*(CS_number) \ + + 0x80) + +/* Off Chip Memory Scrambling Mode Register */ +#define SMC_OCMS MMIO32(SMC_BASE + 0x110) + +/* Off Chip Memory Scrambling KEY1 Register */ +#define SMC_KEY1 MMIO32(SMC_BASE + 0x114) + +/* Off Chip Memory Scrambling KEY2 Register */ +#define SMC_KEY2 MMIO32(SMC_BASE + 0x118) + +/* Write Protection Control Register */ +#define SMC_WPCR MMIO32(SMC_BASE + 0x1E4) + +/* Write Protect Status Register */ +#define SMC_WPSR MMIO32(SMC_BASE + 0x1E8) + + +/* --- Register contents --------------------------------------------------- */ + + +/* --- SMC NFC Configuration Register (SMC_CFG) ---------------------------- */ + +/* Data Timeout Multiplier */ +#define SMC_CFG_DTOMUL_SHIFT 20 +#define SMC_CFG_DTOMUL_MASK (0x07 << SMC_DTOMUL_SHIFT) + +/* Data Timeout Multiplier Values */ +#define SMC_CFG_DTOMUL_X1 (0x00 << SMC_DTOMUL_SHIFT) +#define SMC_CFG_DTOMUL_X16 (0x01 << SMC_DTOMUL_SHIFT) +#define SMC_CFG_DTOMUL_X128 (0x02 << SMC_DTOMUL_SHIFT) +#define SMC_CFG_DTOMUL_X256 (0x03 << SMC_DTOMUL_SHIFT) +#define SMC_CFG_DTOMUL_X1024 (0x04 << SMC_DTOMUL_SHIFT) +#define SMC_CFG_DTOMUL_X4096 (0x05 << SMC_DTOMUL_SHIFT) +#define SMC_CFG_DTOMUL_X65536 (0x06 << SMC_DTOMUL_SHIFT) +#define SMC_CFG_DTOMUL_X1048576 (0x07 << SMC_DTOMUL_SHIFT) + +/* Data Timeout Cycle Number */ +#define SMC_CFG_DTOCYC_SHIFT 16 +#define SMC_CFG_DTOCYC_MASK (0x0F << SMC_DTOCYC_SHIFT) + +/* Ready/Busy Signal Edge Detection */ +#define SMC_CFG_RBEDGE (1 << 13) + +/* Rising/Falling Edge Detection Control */ +#define SMC_CFG_EDGECTRL (1 << 12) + +/* Read Spare Area */ +#define SMC_CFG_RSPARE (1 << 9) + +/* Write Spare Area */ +#define SMC_CFG_WSPARE (1 << 8) + +/* NAND Flash Page Size */ +#define SMC_CFG_PAGESIZE_SHIFT 0 +#define SMC_CFG_PAGESIZE_MASK (0x03 << SMC_CFG_PAGESIZE_SHIFT) + +/* NAND Flash Page Size Values */ +#define SMC_CFG_PAGESIZE_PS512_16 (0x00 << SMC_CFG_PAGESIZE_SHIFT) +#define SMC_CFG_PAGESIZE_PS1024_32 (0x01 << SMC_CFG_PAGESIZE_SHIFT) +#define SMC_CFG_PAGESIZE_PS2048_64 (0x02 << SMC_CFG_PAGESIZE_SHIFT) +#define SMC_CFG_PAGESIZE_PS4096_128 (0x03 << SMC_CFG_PAGESIZE_SHIFT) + + +/* --- SMC NFC Control Register (SMC_CTRL) --------------------------------- */ + +/* NAND Flash Controller Disable */ +#define SMC_CTRL_NFCDIS (1 << 1) + +/* NAND Flash Controller Enable */ +#define SMC_CTRL_NFCEN (1 << 0) + + +/* --- SMC NFC Status Register (SMC_SR) ------------------------------------ */ + +/* Ready/Busy Line 0 Edge Detected */ +#define SMC_SR_RB_EDGE0 (1 << 24) + +/* NFC Access Size Error */ +#define SMC_SR_NFCASE (1 << 23) + +/* Accessing While Busy */ +#define SMC_SR_AWB (1 << 22) + +/* Undefined Area Error */ +#define SMC_SR_UNDEF (1 << 21) + +/* Data Timeout Error */ +#define SMC_SR_DTOE (1 << 20) + +/* Command Done */ +#define SMC_SR_CMDDONE (1 << 17) + +/* NFC Data Transfer Terminated */ +#define SMC_SR_XFRDONE (1 << 16) + +/* NFC Chip Select ID */ +#define SMC_SR_NFCSID_SHIFT 12 +#define SMC_SR_NFCSID_MASK (0x07 << SMC_SR_NFCSID_SHIFT) + +/* NFC Write/Read Operation */ +#define SMC_SR_NFCWR (1 << 11) + +/* NFC Busy */ +#define SMC_SR_NFCBUSY (1 << 8) + +/* Selected Ready Busy Falling Edge Detected */ +#define SMC_SR_RB_FALL (1 << 5) + +/* Selected Ready Busy Rising Edge Detected */ +#define SMC_SR_RB_RISE (1 << 4) + +/* NAND Flash Controller status */ +#define SMC_SR_SMCSTS (1 << 0) + + +/* --- SMC NFC Interrupt Enable Register (SMC_IER) ------------------------- */ + +/* Ready/Busy Line 0 Interrupt Enable */ +#define SMC_IER_RB_EDGE0 (1 << 24) + +/* NFC Access Size Error Interrupt Enable */ +#define SMC_IER_NFCASE (1 << 23) + +/* Accessing While Busy Interrupt Enable */ +#define SMC_IER_AWB (1 << 22) + +/* Undefined Area Access Interrupt Enable */ +#define SMC_IER_UNDEF (1 << 21) + +/* Data Timeout Error Interrupt Enable */ +#define SMC_IER_DTOE (1 << 20) + +/* Command Done Interrupt Enable */ +#define SMC_IER_CMDDONE (1 << 17) + +/* Transfer Done Interrupt Enable */ +#define SMC_IER_XFRDONE (1 << 16) + +/* Ready Busy Falling Edge Detection Interrupt Enable */ +#define SMC_IER_RB_FALL (1 << 5) + +/* Ready Busy Rising Edge Detection Interrupt Enable */ +#define SMC_IER_RB_RISE (1 << 4) + + +/* --- SMC NFC Interrupt Disable Register (SMC_IDR) ------------------------ */ + +/* Ready/Busy Line 0 Interrupt Disable */ +#define SMC_IDR_RB_EDGE0 (1 << 24) + +/* NFC Access Size Error Interrupt Disable */ +#define SMC_IDR_NFCASE (1 << 23) + +/* Accessing While Busy Interrupt Disable */ +#define SMC_IDR_AWB (1 << 22) + +/* Undefined Area Access Interrupt Disable */ +#define SMC_IDR_UNDEF (1 << 21) + +/* Data Timeout Error Interrupt Disable */ +#define SMC_IDR_DTOE (1 << 20) + +/* Command Done Interrupt Disable */ +#define SMC_IDR_CMDDONE (1 << 17) + +/* Transfer Done Interrupt Disable */ +#define SMC_IDR_XFRDONE (1 << 16) + +/* Ready Busy Falling Edge Detection Interrupt Disable */ +#define SMC_IDR_RB_FALL (1 << 5) + +/* Ready Busy Rising Edge Detection Interrupt Disable */ +#define SMC_IDR_RB_RISE (1 << 4) + + +/* --- SMC NFC Interrupt Mask Register (SMC_IMR) --------------------------- */ + +/* Ready/Busy Line 0 Interrupt Mask */ +#define SMC_IMR_RB_EDGE0 (1 << 24) + +/* NFC Access Size Error Interrupt Mask */ +#define SMC_IMR_NFCASE (1 << 23) + +/* Accessing While Busy Interrupt Mask */ +#define SMC_IMR_AWB (1 << 22) + +/* Undefined Area Access Interrupt Mask */ +#define SMC_IMR_UNDEF (1 << 21) + +/* Data Timeout Error Interrupt Mask */ +#define SMC_IMR_DTOE (1 << 20) + +/* Command Done Interrupt Mask */ +#define SMC_IMR_CMDDONE (1 << 17) + +/* Transfer Done Interrupt Mask */ +#define SMC_IMR_XFRDONE (1 << 16) + +/* Ready Busy Falling Edge Detection Interrupt Mask */ +#define SMC_IMR_RB_FALL (1 << 5) + +/* Ready Busy Rising Edge Detection Interrupt Mask */ +#define SMC_IMR_RB_RISE (1 << 4) + + +/* --- SMC NFC Address Cycle Zero Register (SMC_ADDR) ---------------------- */ + +/* NAND Flash Array Address cycle 0 */ +#define SMC_ADDR_ADDR_CYCLE0_SHIFT 0 +#define SMC_ADDR_ADDR_CYCLE0_MASK (0xFF << SMC_ADDR_ADDR_CYCLE0_SHIFT) + + +/* --- SMC NFC Bank Register (SMC_BANK) ------------------------------------ */ + +/* Bank Identifier */ +#define SMC_BANK_BANK_SHIFT 0 +#define SMC_BANK_BANK_MASK (0x07 << SMC_BANK_BANK_SHIFT) + + +/* --- SMC ECC Control Register (SMC_ECC_CTRL) ----------------------------- */ + +/* Software Reset */ +#define SMC_ECC_CTRL_SWRST (1 << 1) + +/* Reset ECC */ +#define SMC_ECC_CTRL_RST (1 << 0) + + +/* --- SMC ECC MODE Register (SMC_ECC_MD) ---------------------------------- */ + +/* Type of Correction */ +#define SMC_ECC_MD_TYPCORREC_SHIFT 4 +#define SMC_ECC_MD_TYPCORREC_MASK (0x03 << SMC_ECC_MD_TYPCORREC_SHIFT) + +/* Type of Correction Values */ +#define SMC_ECC_MD_TYPCORREC_CPAGE (0x00 << SMC_ECC_MD_TYPCORREC_SHIFT) +#define SMC_ECC_MD_TYPCORREC_C256B (0x01 << SMC_ECC_MD_TYPCORREC_SHIFT) +#define SMC_ECC_MD_TYPCORREC_C512B (0x02 << SMC_ECC_MD_TYPCORREC_SHIFT) + +/* ECC Page Size */ +#define SMC_ECC_MD_ECC_PAGESIZE_SHIFT 0 +#define SMC_ECC_MD_ECC_PAGESIZE_MASK (0x03 << SMC_ECC_MD_ECC_PAGESIZE_SHIFT) + +/* ECC Page Size Values */ +#define SMC_ECC_MD_ECC_PAGESIZE_PS512_16 \ + (0x00 << SMC_ECC_MD_ECC_PAGESIZE_SHIFT) +#define SMC_ECC_MD_ECC_PAGESIZE_PS1024_32 \ + (0x01 << SMC_ECC_MD_ECC_PAGESIZE_SHIFT) +#define SMC_ECC_MD_ECC_PAGESIZE_PS2048_64 \ + (0x02 << SMC_ECC_MD_ECC_PAGESIZE_SHIFT) +#define SMC_ECC_MD_ECC_PAGESIZE_PS4096_128 \ + (0x03 << SMC_ECC_MD_ECC_PAGESIZE_SHIFT) + + +/* --- SMC ECC Status Register 1 (SMC_ECC_SR1) ----------------------------- */ +/* currently unimplemented */ + + +/* --- SMC ECC Status Register 2 (SMC_ECC_SR2) ----------------------------- */ +/* currently unimplemented */ + + +/* --- SMC ECC Parity Register 0 (SMC_ECC_PR0) ----------------------------- */ +/* currently unimplemented */ + + +/* --- SMC ECC Parity Register 1 (SMC_ECC_PR1) ----------------------------- */ +/* currently unimplemented */ + + +/* --- SMC ECC Parity Registers (SMC_ECC_PRx) ------------------------------ */ +/* currently unimplemented */ + + +/* --- SMC Setup Register (SMC_SETUPx) ------------------------------------- */ + +/* NCS Setup length in Read access */ +#define SMC_SETUP_NCS_RD_SETUP_SHIFT 24 +#define SMC_SETUP_NCS_RD_SETUP_MASK (0x3F << SMC_SETUP_NCS_RD_SETUP_SHIFT) + +/* NRD Setup length */ +#define SMC_SETUP_NRD_SETUP_SHIFT 16 +#define SMC_SETUP_NRD_SETUP_MASK (0x3F << SMC_SETUP_NRD_SETUP_SHIFT) + +/* NCS Setup length in Write access */ +#define SMC_SETUP_NCS_WR_SETUP_SHIFT 8 +#define SMC_SETUP_NCS_WR_SETUP_MASK (0x3F << SMC_SETUP_NCS_WR_SETUP_SHIFT) + +/* NWE Setup Length */ +#define SMC_SETUP_NWE_SETUP_SHIFT 0 +#define SMC_SETUP_NWE_SETUP_MASK (0x3F << SMC_SETUP_NWE_SETUP_SHIFT) + + +/* --- SMC Pulse Register (SMC_PULSEx) ------------------------------------- */ + +/* NCS Pulse Length in READ Access */ +#define SMC_PULSE_NCS_RD_PULSE_SHIFT 24 +#define SMC_PULSE_NCS_RD_PULSE_MASK (0x3F << SMC_PULSE_NCS_RD_PULSE_SHIFT) + +/* NRD Pulse Length */ +#define SMC_PULSE_NRD_PULSE_SHIFT 16 +#define SMC_PULSE_NRD_PULSE_MASK (0x3F << SMC_PULSE_NRD_PULSE_SHIFT) + +/* NCS Pulse Length in WRITE Access */ +#define SMC_PULSE_NCS_WR_PULSE_SHIFT 8 +#define SMC_PULSE_NCS_WR_PULSE_MASK (0x3F << SMC_PULSE_NCS_WR_PULSE_SHIFT) + +/* NWE Pulse Length */ +#define SMC_PULSE_NWE_PULSE_SHIFT 0 +#define SMC_PULSE_NWE_PULSE_MASK (0x3F << SMC_PULSE_NWE_PULSE_SHIFT) + + +/* --- SMC Cycle Register (SMC_CYCLEx) ------------------------------------- */ + +/* Total Read Cycle Length */ +#define SMC_CYCLE_NRD_CYCLE_SHIFT 16 +#define SMC_CYCLE_NRD_CYCLE_MASK (0x1FF << SMC_CYCLE_NRD_CYCLE_SHIFT) + +/* Total Write Cycle Length */ +#define SMC_CYCLE_NWE_CYCLE_SHIFT 0 +#define SMC_CYCLE_NWE_CYCLE_MASK (0x1FF << SMC_CYCLE_NWE_CYCLE_SHIFT) + + +/* --- SMC Timings Register (SMC_TIMINGSx) --------------------------------- */ + +/* NAND Flash Selection */ +#define SMC_TIMINGS_NFSEL (1 << 31) + +/* Ready/Busy Line Selection */ +#define SMC_TIMINGS_RBNSEL_SHIFT 28 +#define SMC_TIMINGS_RBNSEL_MASK (0x07 << SMC_TIMINGS_RBNSEL_SHIFT) + +/* WEN High to REN to Busy */ +#define SMC_TIMINGS_TWB_SHIFT 24 +#define SMC_TIMINGS_TWB_MASK (0x0F << SMC_TIMINGS_TWB_SHIFT) + +/* Ready to REN Low Delay */ +#define SMC_TIMINGS_TRR_SHIFT 16 +#define SMC_TIMINGS_TRR_MASK (0x0F << SMC_TIMINGS_TRR_SHIFT) + +/* Off Chip Memory Scrambling Enable */ +#define SMC_TIMINGS_OCMS (1 << 12) + +/* ALE to REN Low Delay */ +#define SMC_TIMINGS_TAR_SHIFT 8 +#define SMC_TIMINGS_TAR_MASK (0x0F << SMC_TIMINGS_TAR_SHIFT) + +/* ALE to Data Start */ +#define SMC_TIMINGS_TADL_SHIFT 4 +#define SMC_TIMINGS_TADL_MASK (0x0F << SMC_TIMINGS_TADL_SHIFT) + +/* CLE to REN Low Delay */ +#define SMC_TIMINGS_TCLR_SHIFT 0 +#define SMC_TIMINGS_TCLR_MASK (0x0F << SMC_TIMINGS_TCLR_SHIFT) + + +/* --- SMC Mode Register (SMC_MODEx) --------------------------------------- */ + +/* TDF Optimization */ +#define SMC_MODE_TDF_MODE (1 << 20) + +/* Data Float Time */ +#define SMC_MODE_TDF_CYCLES_SHIFT 16 +#define SMC_MODE_TDF_CYCLES_MASK (0x0F << SMC_MODE_TDF_CYCLES_SHIFT) + +/* Data Bus Width */ +#define SMC_MODE_DBW (1 << 12) + +/* Data Bus Width Values */ +#define SMC_MODE_DBW_BIT_8 (0 << 12) +#define SMC_MODE_DBW_BIT_16 (1 << 12) + +/* Byte Access Type */ +#define SMC_MODE_BAT (1 << 8) + +/* NWAIT Mode */ +#define SMC_MODE_EXNW_MODE_SHIFT 4 +#define SMC_MODE_EXNW_MODE_MASK (0x03 << SMC_MODE_EXNW_MODE_SHIFT) + +/* NWAIT Mode Values */ +#define SMC_MODE_EXNW_MODE_DISABLED (0x00 << SMC_MODE_EXNW_MODE_SHIFT) +#define SMC_MODE_EXNW_MODE_FROZEN (0x02 << SMC_MODE_EXNW_MODE_SHIFT) +#define SMC_MODE_EXNW_MODE_READY (0x03 << SMC_MODE_EXNW_MODE_SHIFT) + +/* Write Mode */ +#define SMC_MODE_WRITE_MODE (1 << 1) + +/* Read Mode */ +#define SMC_MODE_READ_MODE (1 << 0) + + +/* --- SMC OCMS Register (SMC_OCMS) ---------------------------------------- */ + +/* SRAM Scrambling Enable */ +#define SMC_OCMS_SRSE (1 << 1) + +/* Static Memory Controller Scrambling Enable */ +#define SMC_OCMS_SMSE (1 << 0) + + +/* --- SMC Write Protection Control (SMC_WPCR) ----------------------------- */ + +/* Write Protect Key */ +#define SMC_WPCR_WPKEY_SHIFT 8 +#define SMC_WPCR_WPKEY_KEY (0x534D43 << SMC_WPCR_WPKEY_SHIFT) + +/* Write Protect Enable */ +#define SMC_WPCR_WPEN (1 << 0) + + +/* --- SMC Write Protection Status (SMC_WPSR) ------------------------------ */ + +/* Write Protection Violation Source */ +#define SMC_WPSR_WP_VSRC_SHIFT 8 +#define SMC_WPSR_WP_VSRC_MASK (0xFFFF << SMC_WPSR_WP_VSRC_SHIFT) + +/* Write Protection Violation Status */ +#define SMC_WPSR_WP_VS_SHIFT 0 +#define SMC_WPSR_WP_VS_MASK (0x0F << SMC_WPSR_WP_VS_SHIFT) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/irq.json new file mode 100644 index 00000000..e9404825 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/irq.json @@ -0,0 +1,26 @@ +{ + "irqs": [ + "pm", + "sysctrl", + "wdt", + "rtc", + "eic", + "nvmctrl", + "dmac", + "reserved1", + "evsys", + "sercom0", + "sercom1", + "sercom2", + "tcc0", + "tc1", + "tc2", + "adc", + "ac", + "dac", + "ptc" + ], + "partname_humanreadable": "Atmel SAMD series", + "partname_doxygen": "SAMD", + "includeguard": "LIBOPENCM3_SAMD_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/memorymap.h new file mode 100644 index 00000000..5633a05d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/memorymap.h @@ -0,0 +1,51 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAMD_MEMORYMAP_H +#define SAMD_MEMORYMAP_H + +#include + +/* --- SAMD AHB-APB bridge A -------------------------------------------- */ +#define PM_BASE (0x40000400U) +#define SYSCTRL_BASE (0x40000800U) +#define GCLK_BASE (0x40000c00U) +#define WDT_BASE (0x40001000U) +#define RTC_BASE (0x40001400U) +#define EIC_BASE (0x40001800U) +/* --- SAMD AHB-APB bridge B -------------------------------------------- */ +#define DSU_BASE (0x41002000U) +#define NVMCTRL_BASE (0x41004000U) +#define PORT_BASE (0x41004400U) +#define DMAC_BASE (0x41004800U) +#define MTB_BASE (0x41006000U) +/* --- SAMD AHB-APB bridge C -------------------------------------------- */ +#define EVSYS_BASE (0x42000400U) +#define SERCOM0_BASE (0x42000800U) +#define SERCOM1_BASE (0x42000c00U) +#define SERCOM2_BASE (0x42001000U) +#define TCC0_BASE (0x42001400U) +#define TC1_BASE (0x42001800U) +#define TC2_BASE (0x42001c00U) +#define ADC_BASE (0x42002000U) +#define AC_BASE (0x42002400U) +#define DAC_BASE (0x42002800U) +#define PTC_BASE (0x42002c00U) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/port.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/port.h new file mode 100644 index 00000000..92ba7f17 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/d/port.h @@ -0,0 +1,68 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#pragma once + +#include + +/* --- Convenience macros ------------------------------------------------ */ + +#define PORTA (PORT_BASE + 0) +#define PORTB (PORT_BASE + 0x80) + +/* --- PORT registers ----------------------------------------------------- */ + +/* Direction register */ +#define PORT_DIR(port) MMIO32((port) + 0x0000) + +/* Direction clear register */ +#define PORT_DIRCLR(port) MMIO32((port) + 0x0004) + +/* Direction set register */ +#define PORT_DIRSET(port) MMIO32((port) + 0x0008) + +/* Direction toggle register */ +#define PORT_DIRTGL(port) MMIO32((port) + 0x000c) + +/* output register */ +#define PORT_OUT(port) MMIO32((port) + 0x0010) + +/* output clear register */ +#define PORT_OUTCLR(port) MMIO32((port) + 0x0014) + +/* output set register */ +#define PORT_OUTSET(port) MMIO32((port) + 0x0018) + +/* output toggle register */ +#define PORT_OUTTGL(port) MMIO32((port) + 0x001c) + +/* input register */ +#define PORT_IN(port) MMIO32((port) + 0x0020) + +/* Control register */ +#define PORT_CTRL(port) MMIO32((port) + 0x0024) + +/* Write configuration register */ +#define PORT_WRCONFIG(port) MMIO32((port) + 0x0028) + +/* Peripheral multiplexing registers */ +#define PORT_PMUX(port, n) MMIO8((port) + 0x0030 + (n)) + +/* Pin configuration registers */ +#define PORT_PINCFG(port, n) MMIO8((port) + 0x0040 + (n)) diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/eefc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/eefc.h new file mode 100644 index 00000000..eb6d4d0b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/eefc.h @@ -0,0 +1,83 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3X_EEFC_H +#define SAM3X_EEFC_H + +#include +#include + +/* --- Convenience macros ------------------------------------------------ */ +#define EEFC EEFC_BASE +#define EEFC0 EEFC0_BASE +#define EEFC1 EEFC1_BASE + +/* --- Enhanced Embedded Flash Controller (EEFC) registers --------------- */ +#define EEFC_FMR(port) MMIO32((port) + 0x00) +#define EEFC_FCR(port) MMIO32((port) + 0x04) +#define EEFC_FSR(port) MMIO32((port) + 0x08) +#define EEFC_FRR(port) MMIO32((port) + 0x0C) +/* 0x0010 - Reserved */ + + +/* EEFC Flash Mode Register (EEFC_FMR) */ +/* Bit [31:25] - Reserved */ +#define EEFC_FMR_FAM (0x01 << 24) +/* Bit [23:12] - Reserved */ +#define EEFC_FMR_FWS_MASK (0x0F << 8) +/* Bit [7:1] - Reserved */ +#define EEFC_FMR_FRDY (0x01 << 0) + +/* EEFC Flash Command Register (EEFC_FCR) */ +#define EEFC_FCR_FKEY (0x5A << 24) +#define EEFC_FCR_FARG_MASK (0xFFFF << 8) +#define EEFC_FCR_FCMD_MASK (0xFF << 0) +#define EEFC_FCR_FCMD_GETD (0x00 << 0) +#define EEFC_FCR_FCMD_WP (0x01 << 0) +#define EEFC_FCR_FCMD_WPL (0x02 << 0) +#define EEFC_FCR_FCMD_EWP (0x03 << 0) +#define EEFC_FCR_FCMD_EWPL (0x04 << 0) +#define EEFC_FCR_FCMD_EA (0x05 << 0) +#define EEFC_FCR_FCMD_SLB (0x08 << 0) +#define EEFC_FCR_FCMD_CLB (0x09 << 0) +#define EEFC_FCR_FCMD_GLB (0x0A << 0) +#define EEFC_FCR_FCMD_SGPB (0x0B << 0) +#define EEFC_FCR_FCMD_CGPB (0x0C << 0) +#define EEFC_FCR_FCMD_GGPB (0x0D << 0) +#define EEFC_FCR_FCMD_STUI (0x0E << 0) +#define EEFC_FCR_FCMD_SPUI (0x0F << 0) + +/* EEFC Flash Status Register (EEFC_FSR) */ +/* Bit [31:3] - Reserved */ +#define EEFC_FSR_FLOCKE (0x01 << 2) +#define EEFC_FSR_FCMDE (0x01 << 1) +#define EEFC_FSR_FRDY (0x01 << 0) + +static inline void eefc_set_latency(uint8_t wait) +{ +#if defined(SAM3A) || defined(SAM3U) || defined(SAM3X) + EEFC_FMR(EEFC0) = (EEFC_FMR(EEFC0) & ~EEFC_FMR_FWS_MASK) | (wait << 8); + EEFC_FMR(EEFC1) = (EEFC_FMR(EEFC1) & ~EEFC_FMR_FWS_MASK) | (wait << 8); +#elif defined(SAM3N) || defined(SAM3S) + EEFC_FMR(EEFC) = (EEFC_FMR(EEFC) & ~EEFC_FMR_FWS_MASK) | (wait << 8); +#endif +} + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/gpio.h new file mode 100644 index 00000000..79128987 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/gpio.h @@ -0,0 +1,34 @@ +/* This provides unification of code over SAM subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(SAM3A) +# include +#elif defined(SAM3N) +# include +#elif defined(SAM3S) +# include +#elif defined(SAM3U) +# include +#elif defined(SAM3X) +# include +#else +# error "sam family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/memorymap.h new file mode 100644 index 00000000..67f1def3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/memorymap.h @@ -0,0 +1,41 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM_MEMORYMAP_H +#define SAM_MEMORYMAP_H + +#if defined(SAM3A) +# include +#elif defined(SAM3N) +# include +#elif defined(SAM3S) +# include +#elif defined(SAM3U) +# include +#elif defined(SAM3X) +# include +#elif defined(SAMD) +# include +#else +# error "Processor family not defined." +#endif + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/periph.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/periph.h new file mode 100644 index 00000000..e1ae621d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/periph.h @@ -0,0 +1,32 @@ +/* This provides unification of code over SAM subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(SAM3A) +# include +#elif defined(SAM3N) +# include +#elif defined(SAM3S) +# include +#elif defined(SAM3U) +# include +#elif defined(SAM3X) +# include +#else +# error "sam family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pio.h new file mode 100644 index 00000000..ac0ca3ae --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pio.h @@ -0,0 +1,34 @@ +/* This provides unification of code over SAM subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(SAM3A) +# include +#elif defined(SAM3N) +# include +#elif defined(SAM3S) +# include +#elif defined(SAM3U) +# include +#elif defined(SAM3X) +# include +#else +# error "sam family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pmc.h new file mode 100644 index 00000000..4856f27c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pmc.h @@ -0,0 +1,32 @@ +/* This provides unification of code over SAM subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(SAM3A) +# include +#elif defined(SAM3N) +# include +#elif defined(SAM3S) +# include +#elif defined(SAM3U) +# include +#elif defined(SAM3X) +# include +#else +# error "sam family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pwm.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pwm.h new file mode 100644 index 00000000..fabb8b19 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/pwm.h @@ -0,0 +1,109 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3X_PWM_H +#define SAM3X_PWM_H + +#include +#include + +/* --- Pulse Width Modulation (PWM) registers ----------------------- */ + +#define PWM_CLK MMIO32(PWM_BASE + 0x0000) +#define PWM_ENA MMIO32(PWM_BASE + 0x0004) +#define PWM_DIS MMIO32(PWM_BASE + 0x0008) +#define PWM_SR MMIO32(PWM_BASE + 0x000C) +#define PWM_IER1 MMIO32(PWM_BASE + 0x0010) +#define PWM_IDR1 MMIO32(PWM_BASE + 0x0014) +#define PWM_IMR1 MMIO32(PWM_BASE + 0x0018) +#define PWM_ISR1 MMIO32(PWM_BASE + 0x001C) +#define PWM_SCM MMIO32(PWM_BASE + 0x0020) +/* 0x0024 - Reserved */ +#define PWM_SCUC MMIO32(PWM_BASE + 0x0028) +#define PWM_SCUP MMIO32(PWM_BASE + 0x002C) +#define PWM_SCUPUPD MMIO32(PWM_BASE + 0x0030) +#define PWM_IER2 MMIO32(PWM_BASE + 0x0034) +#define PWM_IDR2 MMIO32(PWM_BASE + 0x0038) +#define PWM_IMR2 MMIO32(PWM_BASE + 0x003C) +#define PWM_ISR2 MMIO32(PWM_BASE + 0x0040) +#define PWM_OOV MMIO32(PWM_BASE + 0x0044) +#define PWM_OS MMIO32(PWM_BASE + 0x0048) +#define PWM_OSS MMIO32(PWM_BASE + 0x004C) +#define PWM_OSC MMIO32(PWM_BASE + 0x0050) +#define PWM_OSSUPD MMIO32(PWM_BASE + 0x0054) +#define PWM_OSCUPD MMIO32(PWM_BASE + 0x0058) +#define PWM_FMR MMIO32(PWM_BASE + 0x005C) +#define PWM_FSR MMIO32(PWM_BASE + 0x0060) +#define PWM_FCR MMIO32(PWM_BASE + 0x0064) +#define PWM_FPV MMIO32(PWM_BASE + 0x0068) +#define PWM_FPE1 MMIO32(PWM_BASE + 0x006C) +#define PWM_FPE2 MMIO32(PWM_BASE + 0x0070) +/* 0x0074:0x0078 - Reserved */ +#define PWM_ELMR0 MMIO32(PWM_BASE + 0x007C) +#define PWM_ELMR1 MMIO32(PWM_BASE + 0x0080) +/* 0x0084:0x00AC - Reserved */ +#define PWM_SMMR MMIO32(PWM_BASE + 0x00B0) +/* 0x00B4:0x00E0 - Reserved */ +#define PWM_WPCR MMIO32(PWM_BASE + 0x00E4) +#define PWM_WPSR MMIO32(PWM_BASE + 0x00E8) +/* 0x00EC:0x00FC - Reserved */ +/* 0x0100:0x012C - Reserved */ +#define PWM_CMPV(x) MMIO32(PWM_BASE + 0x0130 + 0x10*(x)) +#define PWM_CMPVUPD(x) MMIO32(PWM_BASE + 0x0134 + 0x10*(x)) +#define PWM_CMMV(x) MMIO32(PWM_BASE + 0x0138 + 0x10*(x)) +#define PWM_CMMVUPD(x) MMIO32(PWM_BASE + 0x013C + 0x10*(x)) +/* 0x01B0:0x01FC - Reserved */ +#define PWM_CMR(x) MMIO32(PWM_BASE + 0x0200 + 0x20*(x)) +#define PWM_CDTY(x) MMIO32(PWM_BASE + 0x0204 + 0x20*(x)) +#if defined(SAM3X) +# define PWM_CDTYUPD(x) MMIO32(PWM_BASE + 0x0208 + 0x20*(x)) +# define PWM_CPRD(x) MMIO32(PWM_BASE + 0x020C + 0x20*(x)) +# define PWM_CPRDUPD(x) MMIO32(PWM_BASE + 0x0210 + 0x20*(x)) +# define PWM_CCNT(x) MMIO32(PWM_BASE + 0x0214 + 0x20*(x)) +# define PWM_DT(x) MMIO32(PWM_BASE + 0x0218 + 0x20*(x)) +# define PWM_DTUPD(x) MMIO32(PWM_BASE + 0x021C + 0x20*(x)) +#elif defined(SAM3N) +# define PWM_CPRD(x) MMIO32(PWM_BASE + 0x0208 + 0x20*(x)) +# define PWM_CCNT(x) MMIO32(PWM_BASE + 0x020C + 0x20*(x)) +# define PWM_CUPD(x) MMIO32(PWM_BASE + 0x0210 + 0x20*(x)) +#else +# error "Processor family not defined." +#endif + +static inline void pwm_set_period(int ch, uint32_t period) +{ + PWM_CPRD(ch) = period; +} + +static inline void pwm_set_duty(int ch, uint32_t duty) +{ + PWM_CDTY(ch) = duty; +} + +static inline void pwm_enable(int ch) +{ + PWM_ENA = 1 << ch; +} + +static inline void pwm_disable(int ch) +{ + PWM_DIS = 1 << ch; +} + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/smc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/smc.h new file mode 100644 index 00000000..8f2ab021 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/smc.h @@ -0,0 +1,32 @@ +/* This provides unification of code over SAM subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(SAM3A) +# include +#elif defined(SAM3N) +# error "sam3n doesn't have a static memory controller." +#elif defined(SAM3S) +# include +#elif defined(SAM3U) +# include +#elif defined(SAM3X) +# include +#else +# error "sam family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/tc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/tc.h new file mode 100644 index 00000000..864cc4ad --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/tc.h @@ -0,0 +1,52 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3X_TC_H +#define SAM3X_TC_H + +#include +#include + +/* --- Timer Counter (TC) registers -------------------------------------- */ + +#define TC_CCR(x) MMIO32(TC_BASE + 0x00 + 0x40*(x)) +#define TC_CMR(x) MMIO32(TC_BASE + 0x04 + 0x40*(x)) +#define TC_SMMR(x) MMIO32(TC_BASE + 0x08 + 0x40*(x)) +/* 0x0C + 0x40*channel - Reserved */ +#define TC_CV(x) MMIO32(TC_BASE + 0x10 + 0x40*(x)) +#define TC_RA(x) MMIO32(TC_BASE + 0x14 + 0x40*(x)) +#define TC_RB(x) MMIO32(TC_BASE + 0x18 + 0x40*(x)) +#define TC_RC(x) MMIO32(TC_BASE + 0x1C + 0x40*(x)) +#define TC_SR(x) MMIO32(TC_BASE + 0x20 + 0x40*(x)) +#define TC_IER(x) MMIO32(TC_BASE + 0x24 + 0x40*(x)) +#define TC_IDR(x) MMIO32(TC_BASE + 0x28 + 0x40*(x)) +#define TC_IMR(x) MMIO32(TC_BASE + 0x2C + 0x40*(x)) +#define TC_BCR MMIO32(TC_BASE + 0xC0) +#define TC_BMR MMIO32(TC_BASE + 0xC4) +#define TC_QIER MMIO32(TC_BASE + 0xC8) +#define TC_QIDR MMIO32(TC_BASE + 0xCC) +#define TC_QIMR MMIO32(TC_BASE + 0xD0) +#define TC_QISR MMIO32(TC_BASE + 0xD4) +#define TC_FMR MMIO32(TC_BASE + 0xD8) +/* 0x00DC:0x00E0 - Undocumented */ +#define TC_WPMR MMIO32(TC_BASE + 0xE4) +/* 0x00E8:0x00F8 - Undocumented */ +/* 0x00FC - Reserved */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/uart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/uart.h new file mode 100644 index 00000000..becfcb55 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/uart.h @@ -0,0 +1,85 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3X_UART_H +#define SAM3X_UART_H + +#include +#include + +/* --- Universal Asynchronous Receiver Transmitter (UART) registers ------- */ +#define UART_CR MMIO32(UART_BASE + 0x0000) +#define UART_MR MMIO32(UART_BASE + 0x0004) +#define UART_IER MMIO32(UART_BASE + 0x0008) +#define UART_IDR MMIO32(UART_BASE + 0x000C) +#define UART_IMR MMIO32(UART_BASE + 0x0010) +#define UART_SR MMIO32(UART_BASE + 0x0014) +#define UART_RHR MMIO32(UART_BASE + 0x0018) +#define UART_THR MMIO32(UART_BASE + 0x001C) +#define UART_BRGR MMIO32(UART_BASE + 0x0020) +/* 0x0024:0x003C - Reserved */ +/* 0x004C:0x00FC - Reserved */ +/* 0x0100:0x0124 - PDC Area */ + + +/* UART Control Register (UART_CR) */ +/* Bits [31:9] - Reserved */ +#define UART_CR_RSTSTA (0x01 << 8) +#define UART_CR_TXDIS (0x01 << 7) +#define UART_CR_TXEN (0x01 << 6) +#define UART_CR_RXDIS (0x01 << 5) +#define UART_CR_RXEN (0x01 << 4) +#define UART_CR_RSTTX (0x01 << 3) +#define UART_CR_RSTRX (0x01 << 2) +/* Bit [1:0] - Reserved */ + +/* UART Mode Register (UART_MR) */ +/* Bits [31:16] - Reserved */ +#define UART_MR_CHMODE_MASK (0x03 << 14) +#define UART_MR_CHMODE_NORMAL (0x00 << 14) +#define UART_MR_CHMODE_AUTOMATIC (0x01 << 14) +#define UART_MR_CHMODE_LOCAL_LOOPBACK (0x02 << 14) +#define UART_MR_CHMODE_REMOTE_LOOPBACK (0x03 << 14) +/* Bits [13:12] - Reserved */ +#define UART_MR_PAR_MASK (0x07 << 9) +#define UART_MR_PAR_EVEN (0x00 << 9) +#define UART_MR_PAR_ODD (0x01 << 9) +#define UART_MR_PAR_SPACE (0x02 << 9) +#define UART_MR_PAR_MARK (0x03 << 9) +#define UART_MR_PAR_NO (0x04 << 9) +/* Bits [8:0] - Reserved */ + +/* UART Status Register (UART_SR) */ +/* Bits [31:13] - Reserved */ +#define UART_SR_RXBUFF (0x01 << 12) +#define UART_SR_TXBUFF (0x01 << 11) +/* Bit [10] - Reserved */ +#define UART_SR_TXEMPTY (0x01 << 9) +/* Bit [8] - Reserved */ +#define UART_SR_PARE (0x01 << 7) +#define UART_SR_FRAME (0x01 << 6) +#define UART_SR_OVRE (0x01 << 5) +#define UART_SR_ENDTX (0x01 << 4) +#define UART_SR_ENDRX (0x01 << 3) +/* Bit [2] - Reserved */ +#define UART_SR_TXRDY (0x01 << 1) +#define UART_SR_RXRDY (0x01 << 0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/usart.h new file mode 100644 index 00000000..757e93dd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/usart.h @@ -0,0 +1,217 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3X_USART_H +#define SAM3X_USART_H + +#include +#include + +#define USART0 USART0_BASE +#define USART1 USART1_BASE +#define USART2 USART2_BASE +#define USART3 USART3_BASE + +/* --- Universal Synchronous Asynchronous Receiver Transmitter (USART) */ +#define USART_CR(x) MMIO32((x) + 0x0000) +#define USART_MR(x) MMIO32((x) + 0x0004) +#define USART_IER(x) MMIO32((x) + 0x0008) +#define USART_IDR(x) MMIO32((x) + 0x000C) +#define USART_IMR(x) MMIO32((x) + 0x0010) +#define USART_CSR(x) MMIO32((x) + 0x0014) +#define USART_RHR(x) MMIO32((x) + 0x0018) +#define USART_THR(x) MMIO32((x) + 0x001C) +#define USART_BRGR(x) MMIO32((x) + 0x0020) +#define USART_RTOR(x) MMIO32((x) + 0x0024) +#define USART_TTGR(x) MMIO32((x) + 0x0028) +/* 0x002C:0x003C - Reserved */ +#define USART_FIDI(x) MMIO32((x) + 0x0040) +#define USART_NER(x) MMIO32((x) + 0x0044) +#define USART_NER(x) MMIO32((x) + 0x0044) +/* 0x0048 - Reserved */ +#define USART_IF(x) MMIO32((x) + 0x004C) +#define USART_MAN(x) MMIO32((x) + 0x0050) +#define USART_LINMR(x) MMIO32((x) + 0x0054) +#define USART_LINIR(x) MMIO32((x) + 0x0058) +/* 0x005C:0x00E0 - Reserved */ +#define USART_WPMR(x) MMIO32((x) + 0x00E4) +#define USART_WPSR(x) MMIO32((x) + 0x00E8) +/* 0x00EC:0x00F8 - Reserved */ +#define USART_VERSION(x) MMIO32((x) + 0x00FC) +/* 0x0100:0x0124 - PDC Area */ + + +/* USART Control Register (USART_CR) */ +/* Bits [31:22] - Reserved */ +#define USART_CR_LINWKUP (0x01 << 21) +#define USART_CR_LINABT (0x01 << 20) +#define USART_CR_RTSDIS (0x01 << 19) +#define USART_CR_RCS (0x01 << 19) +#define USART_CR_RTSEN (0x01 << 18) +#define USART_CR_FCS (0x01 << 18) +/* Bits [17:16] - Reserved */ +#define USART_CR_RETTO (0x01 << 15) +#define USART_CR_RSTNACK (0x01 << 14) +#define USART_CR_RSTIT (0x01 << 13) +#define USART_CR_SENDA (0x01 << 12) +#define USART_CR_STTTO (0x01 << 11) +#define USART_CR_STPBRK (0x01 << 10) +#define USART_CR_STTBRK (0x01 << 9) +#define USART_CR_RSTSTA (0x01 << 8) +#define USART_CR_TXDIS (0x01 << 7) +#define USART_CR_TXEN (0x01 << 6) +#define USART_CR_RXDIS (0x01 << 5) +#define USART_CR_RXEN (0x01 << 4) +#define USART_CR_RSTTX (0x01 << 3) +#define USART_CR_RSTRX (0x01 << 2) +/* Bits [1:0] - Reserved */ + +/* USART Mode Register (USART_MR) */ +#define USART_MR_ONEBIT (0x01 << 31) +#define USART_MR_MODSYNC (0x01 << 30) +#define USART_MR_MAN (0x01 << 29) +#define USART_MR_FILTER (0x01 << 28) +/* Bit [27] - Reserved */ +#define USART_MR_MAX_ITERATION_MASK (0x07 << 24) +#define USART_MR_INVDATA (0x01 << 23) +#define USART_MR_VAR_SYNC (0x01 << 22) +#define USART_MR_DSNACK (0x01 << 21) +#define USART_MR_INACK (0x01 << 20) +#define USART_MR_OVER (0x01 << 19) +#define USART_MR_CLKO (0x01 << 18) +#define USART_MR_MODE9 (0x01 << 17) +#define USART_MR_MSBF (0x01 << 16) +#define USART_MR_CPOL (0x01 << 16) +#define USART_MR_CHMODE_MASK (0x03 << 14) +#define USART_MR_CHMODE_NORMAL (0x00 << 14) +#define USART_MR_CHMODE_AUTOMATIC (0x01 << 14) +#define USART_MR_CHMODE_LOCAL_LOOPBACK (0x02 << 14) +#define USART_MR_CHMODE_REMOTE_LOOPBACK (0x03 << 14) +#define USART_MR_NBSTOP_MASK (0x03 << 12) +#define USART_MR_NBSTOP_1_BIT (0x00 << 12) +#define USART_MR_NBSTOP_1_5_BIT (0x01 << 12) +#define USART_MR_NBSTOP_2_BIT (0x02 << 12) +/* Bits [13:12] - Reserved */ +#define USART_MR_PAR_MASK (0x07 << 9) +#define USART_MR_PAR_EVEN (0x00 << 9) +#define USART_MR_PAR_ODD (0x01 << 9) +#define USART_MR_PAR_SPACE (0x02 << 9) +#define USART_MR_PAR_MARK (0x03 << 9) +#define USART_MR_PAR_NO (0x04 << 9) +/* Bits [8:0] - Reserved */ +#define USART_MR_SYNC (0x01 << 8) +#define USART_MR_CPHA (0x01 << 8) +#define USART_MR_CHRL_MASK (0x03 << 6) +#define USART_MR_CHRL_5BIT (0x00 << 6) +#define USART_MR_CHRL_6BIT (0x01 << 6) +#define USART_MR_CHRL_7BIT (0x02 << 6) +#define USART_MR_CHRL_8BIT (0x03 << 6) +#define USART_MR_USCLKS_MASK (0x03 << 4) +#define USART_MR_USCLKS_MCK (0x00 << 4) +#define USART_MR_USCLKS_DIV (0x01 << 4) +#define USART_MR_USCLKS_SCK (0x03 << 4) +#define USART_MR_MODE_MASK (0x0F << 0) +#define USART_MR_MODE_NORMAL (0x00 << 0) +#define USART_MR_MODE_RS485 (0x01 << 0) +#define USART_MR_MODE_HW_HANDSHAKING (0x02 << 0) +#define USART_MR_MODE_ISO7816_T_0 (0x03 << 0) +#define USART_MR_MODE_ISO7816_T_1 (0x04 << 0) +#define USART_MR_MODE_IRDA (0x06 << 0) +#define USART_MR_MODE_LIN_MASTER (0x0A << 0) +#define USART_MR_MODE_LIN_SLAVE (0x0B << 0) +#define USART_MR_MODE_SPI_MASTER (0x0E << 0) +#define USART_MR_MODE_SPI_SLAVE (0x0F << 0) + +/* USART Status Register (USART_CSR) */ +/* Bits [31:30] - Reserved */ +#define USART_CSR_LINSNRE (0x01 << 29) +#define USART_CSR_LINCE (0x01 << 28) +#define USART_CSR_LINIPE (0x01 << 27) +#define USART_CSR_LINSFE (0x01 << 26) +#define USART_CSR_LINBE (0x01 << 25) +#define USART_CSR_MANERR (0x01 << 24) +#define USART_CSR_CTS (0x01 << 23) +#define USART_CSR_LINBLS (0x01 << 23) +/* Bits [22:20] - Reserved */ +#define USART_CSR_CTSIC (0x01 << 19) +/* Bits [18:16] - Reserved */ +#define USART_CSR_LINTC (0x01 << 15) +#define USART_CSR_LINID (0x01 << 14) +#define USART_CSR_NACK (0x01 << 13) +#define USART_CSR_LINBK (0x01 << 13) +#define USART_CSR_RXBUFF (0x01 << 12) +#define USART_CSR_TXBUFE (0x01 << 11) +/* Bit [10] - Reserved */ +#define USART_CSR_TXEMPTY (0x01 << 9) +/* Bit [8] - Reserved */ +#define USART_CSR_PARE (0x01 << 7) +#define USART_CSR_FRAME (0x01 << 6) +#define USART_CSR_OVRE (0x01 << 5) +#define USART_CSR_ENDTX (0x01 << 4) +#define USART_CSR_ENDRX (0x01 << 3) +/* Bit [2] - Reserved */ +#define USART_CSR_TXRDY (0x01 << 1) +#define USART_CSR_RXRDY (0x01 << 0) + +enum usart_stopbits { + USART_STOPBITS_1, + USART_STOPBITS_1_5, + USART_STOPBITS_2, +}; + +enum usart_parity { + USART_PARITY_EVEN, + USART_PARITY_ODD, + USART_PARITY_SPACE, + USART_PARITY_MARK, + USART_PARITY_NONE, + USART_PARITY_MULTIDROP, +}; + +enum usart_mode { + USART_MODE_DISABLED, + USART_MODE_RX, + USART_MODE_TX, + USART_MODE_TX_RX, +}; + +enum usart_flowcontrol { + USART_FLOWCONTROL_NONE, + USART_FLOWCONTROL_RTS_CTS, +}; + +void usart_set_baudrate(uint32_t usart, uint32_t baud); +void usart_set_databits(uint32_t usart, int bits); +void usart_set_stopbits(uint32_t usart, enum usart_stopbits); +void usart_set_parity(uint32_t usart, enum usart_parity); +void usart_set_mode(uint32_t usart, enum usart_mode); +void usart_set_flow_control(uint32_t usart, enum usart_flowcontrol); +void usart_enable(uint32_t usart); +void usart_disable(uint32_t usart); +void usart_send(uint32_t usart, uint16_t data); +uint16_t usart_recv(uint32_t usart); +void usart_wait_send_ready(uint32_t usart); +void usart_wait_recv_ready(uint32_t usart); +void usart_send_blocking(uint32_t usart, uint16_t data); +uint16_t usart_recv_blocking(uint32_t usart); +void usart_enable_rx_interrupt(uint32_t usart); +void usart_disable_rx_interrupt(uint32_t usart); + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/wdt.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/wdt.h new file mode 100644 index 00000000..566ac958 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/sam/wdt.h @@ -0,0 +1,57 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAM3X_WDT_H +#define SAM3X_WDT_H + +#include +#include + + +/* --- WDT registers ----------------------------------------------------- */ + +#define WDT_CR MMIO32(WDT_BASE + 0x00) +#define WDT_MR MMIO32(WDT_BASE + 0x04) +#define WDT_SR MMIO32(WDT_BASE + 0x08) + +/* --- WDT_CR values ------------------------------------------------------ */ + +#define WDT_CR_KEY (0xA5 << 24) +/* Bits [23:1]: Reserved. */ +#define WDT_CR_WDRSTT (1 << 0) + +/* --- WDT_MR values ------------------------------------------------------ */ + +/* Bits [31:32]: Reserved. */ +#define WDT_MR_WDIDLEHLT (1 << 29) +#define WDT_MR_WDDBGHLT (1 << 28) +#define WDT_MR_WDD_MASK (0xFFF << 16) +#define WDT_MR_WDDIS (1 << 15) +#define WDT_MR_WDRPROC (1 << 14) +#define WDT_MR_WDRSTEN (1 << 13) +#define WDT_MR_WDFIEN (1 << 12) +#define WDT_MR_WDV_MASK (0xFFF << 0) + +/* --- WDT_SR values ------------------------------------------------------ */ + +/* Bits [31:2]: Reserved. */ +#define WDT_SR_WDERR (1 << 1) +#define WDT_SR_WDUNF (1 << 0) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/adc.h new file mode 100644 index 00000000..2663a4ab --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/adc.h @@ -0,0 +1,40 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/can.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/can.h new file mode 100644 index 00000000..1b482888 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/can.h @@ -0,0 +1,679 @@ +/** @defgroup can_defines CAN defines + +@ingroup STM32F_defines + +@brief libopencm3 Defined Constants and Types for STM32 CAN + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski + +@date 12 November 2012 + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CAN_H +#define LIBOPENCM3_CAN_H + +#include +#include + +/**@{*/ + +/* --- Convenience macros -------------------------------------------------- */ + +/* CAN register base addresses (for convenience) */ +/*****************************************************************************/ +/** @defgroup can_reg_base CAN register base address +@ingroup can_defines + +@{*/ +#define CAN1 BX_CAN1_BASE +#define CAN2 BX_CAN2_BASE +/**@}*/ + +/* --- CAN registers ------------------------------------------------------- */ + +/* CAN master control register (CAN_MCR) */ +#define CAN_MCR(can_base) MMIO32((can_base) + 0x000) +/* CAN master status register (CAN_MSR) */ +#define CAN_MSR(can_base) MMIO32((can_base) + 0x004) +/* CAN transmit status register (CAN_TSR) */ +#define CAN_TSR(can_base) MMIO32((can_base) + 0x008) + +/* CAN receive FIFO 0 register (CAN_RF0R) */ +#define CAN_RF0R(can_base) MMIO32((can_base) + 0x00C) +/* CAN receive FIFO 1 register (CAN_RF1R) */ +#define CAN_RF1R(can_base) MMIO32((can_base) + 0x010) + +/* CAN interrupt enable register (CAN_IER) */ +#define CAN_IER(can_base) MMIO32((can_base) + 0x014) +/* CAN error status register (CAN_ESR) */ +#define CAN_ESR(can_base) MMIO32((can_base) + 0x018) +/* CAN bit timing register (CAN_BTR) */ +#define CAN_BTR(can_base) MMIO32((can_base) + 0x01C) + +/* Registers in the offset range 0x020 to 0x17F are reserved. */ + +/* --- CAN mailbox registers ----------------------------------------------- */ + +/* CAN mailbox / FIFO register offsets */ +#define CAN_MBOX0 0x180 +#define CAN_MBOX1 0x190 +#define CAN_MBOX2 0x1A0 +#define CAN_FIFO0 0x1B0 +#define CAN_FIFO1 0x1C0 + +/* CAN TX mailbox identifier register (CAN_TIxR) */ +#define CAN_TIxR(can_base, mbox) MMIO32((can_base) + (mbox) + 0x0) +#define CAN_TI0R(can_base) CAN_TIxR(can_base, CAN_MBOX0) +#define CAN_TI1R(can_base) CAN_TIxR(can_base, CAN_MBOX1) +#define CAN_TI2R(can_base) CAN_TIxR(can_base, CAN_MBOX2) + +/* CAN mailbox data length control and time stamp register (CAN_TDTxR) */ +#define CAN_TDTxR(can_base, mbox) MMIO32((can_base) + (mbox) + 0x4) +#define CAN_TDT0R(can_base) CAN_TDTxR((can_base), CAN_MBOX0) +#define CAN_TDT1R(can_base) CAN_TDTxR((can_base), CAN_MBOX1) +#define CAN_TDT2R(can_base) CAN_TDTxR((can_base), CAN_MBOX2) + +/* CAN mailbox data low register (CAN_TDLxR) */ +#define CAN_TDLxR(can_base, mbox) MMIO32((can_base) + (mbox) + 0x8) +#define CAN_TDL0R(can_base) CAN_TDLxR((can_base), CAN_MBOX0) +#define CAN_TDL1R(can_base) CAN_TDLxR((can_base), CAN_MBOX1) +#define CAN_TDL2R(can_base) CAN_TDLxR((can_base), CAN_MBOX2) + +/* CAN mailbox data high register (CAN_TDHxR) */ +#define CAN_TDHxR(can_base, mbox) MMIO32((can_base) + (mbox) + 0xC) +#define CAN_TDH0R(can_base) CAN_TDHxR((can_base), CAN_MBOX0) +#define CAN_TDH1R(can_base) CAN_TDHxR((can_base), CAN_MBOX1) +#define CAN_TDH2R(can_base) CAN_TDHxR((can_base), CAN_MBOX2) + +/* CAN RX FIFO identifier register (CAN_RIxR) */ +#define CAN_RIxR(can_base, fifo) MMIO32((can_base) + (fifo) + 0x0) +#define CAN_RI0R(can_base) CAN_RIxR((can_base), CAN_FIFO0) +#define CAN_RI1R(can_base) CAN_RIxR((can_base), CAN_FIFO1) + +/* CAN RX FIFO mailbox data length control & time stamp register (CAN_RDTxR) */ +#define CAN_RDTxR(can_base, fifo) MMIO32((can_base) + (fifo) + 0x4) +#define CAN_RDT0R(can_base) CAN_RDTxR((can_base), CAN_FIFO0) +#define CAN_RDT1R(can_base) CAN_RDTxR((can_base), CAN_FIFO1) + +/* CAN RX FIFO mailbox data low register (CAN_RDLxR) */ +#define CAN_RDLxR(can_base, fifo) MMIO32((can_base) + (fifo) + 0x8) +#define CAN_RDL0R(can_base) CAN_RDLxR((can_base), CAN_FIFO0) +#define CAN_RDL1R(can_base) CAN_RDLxR((can_base), CAN_FIFO1) + +/* CAN RX FIFO mailbox data high register (CAN_RDHxR) */ +#define CAN_RDHxR(can_base, fifo) MMIO32((can_base) + (fifo) + 0xC) +#define CAN_RDH0R(can_base) CAN_RDHxR((can_base), CAN_FIFO0) +#define CAN_RDH1R(can_base) CAN_RDHxR((can_base), CAN_FIFO1) + +/* --- CAN filter registers ------------------------------------------------ */ + +/* CAN filter master register (CAN_FMR) */ +#define CAN_FMR(can_base) MMIO32((can_base) + 0x200) + +/* CAN filter mode register (CAN_FM1R) */ +#define CAN_FM1R(can_base) MMIO32((can_base) + 0x204) + +/* Register offset 0x208 is reserved. */ + +/* CAN filter scale register (CAN_FS1R) */ +#define CAN_FS1R(can_base) MMIO32((can_base) + 0x20C) + +/* Register offset 0x210 is reserved. */ + +/* CAN filter FIFO assignement register (CAN_FFA1R) */ +#define CAN_FFA1R(can_base) MMIO32((can_base) + 0x214) + +/* Register offset 0x218 is reserved. */ + +/* CAN filter activation register (CAN_FA1R) */ +#define CAN_FA1R(can_base) MMIO32((can_base) + 0x21C) + +/* Register offset 0x220 is reserved. */ + +/* Registers with offset 0x224 to 0x23F are reserved. */ + +/* CAN filter bank registers (CAN_FiRx) */ +/* + * Connectivity line devices have 28 banks so the bank ID spans 0..27 + * all other devices have 14 banks so the bank ID spans 0..13. + */ +#define CAN_FiR1(can_base, bank) MMIO32((can_base) + 0x240 + \ + ((bank) * 0x8) + 0x0) +#define CAN_FiR2(can_base, bank) MMIO32((can_base) + 0x240 + \ + ((bank) * 0x8) + 0x4) + +/* --- CAN_MCR values ------------------------------------------------------ */ + +/* 31:17 Reserved, forced by hardware to 0 */ + +/* DBF: Debug freeze */ +#define CAN_MCR_DBF (1 << 16) + +/* RESET: bxCAN software master reset */ +#define CAN_MCR_RESET (1 << 15) + +/* 14:8 Reserved, forced by hardware to 0 */ + +/* TTCM: Time triggered communication mode */ +#define CAN_MCR_TTCM (1 << 7) + +/* ABOM: Automatic bus-off management */ +#define CAN_MCR_ABOM (1 << 6) + +/* AWUM: Automatic wakeup mode */ +#define CAN_MCR_AWUM (1 << 5) + +/* NART: No automatic retransmission */ +#define CAN_MCR_NART (1 << 4) + +/* RFLM: Receive FIFO locked mode */ +#define CAN_MCR_RFLM (1 << 3) + +/* TXFP: Transmit FIFO priority */ +#define CAN_MCR_TXFP (1 << 2) + +/* SLEEP: Sleep mode request */ +#define CAN_MCR_SLEEP (1 << 1) + +/* INRQ: Initialization request */ +#define CAN_MCR_INRQ (1 << 0) + +/* --- CAN_MSR values ------------------------------------------------------ */ + +/* 31:12 Reserved, forced by hardware to 0 */ + +/* RX: CAN Rx signal */ +#define CAN_MSR_RX (1 << 11) + +/* SAMP: Last sample point */ +#define CAN_MSR_SAMP (1 << 10) + +/* RXM: Receive mode */ +#define CAN_MSR_RXM (1 << 9) + +/* TXM: Transmit mode */ +#define CAN_MSR_TXM (1 << 8) + +/* 7:5 Reserved, forced by hardware to 0 */ + +/* SLAKI: Sleep acknowledge interrupt */ +#define CAN_MSR_SLAKI (1 << 4) + +/* WKUI: Wakeup interrupt */ +#define CAN_MSR_WKUI (1 << 3) + +/* ERRI: Error interrupt */ +#define CAN_MSR_ERRI (1 << 2) + +/* SLAK: Sleep acknowledge */ +#define CAN_MSR_SLAK (1 << 1) + +/* INAK: Initialization acknowledge */ +#define CAN_MSR_INAK (1 << 0) + +/* --- CAN_TSR values ------------------------------------------------------ */ + +/* LOW2: Lowest priority flag for mailbox 2 */ +#define CAN_TSR_LOW2 (1 << 31) + +/* LOW1: Lowest priority flag for mailbox 1 */ +#define CAN_TSR_LOW1 (1 << 30) + +/* LOW0: Lowest priority flag for mailbox 0 */ +#define CAN_TSR_LOW0 (1 << 29) + +/* TME2: Transmit mailbox 2 empty */ +#define CAN_TSR_TME2 (1 << 28) + +/* TME1: Transmit mailbox 1 empty */ +#define CAN_TSR_TME1 (1 << 27) + +/* TME0: Transmit mailbox 0 empty */ +#define CAN_TSR_TME0 (1 << 26) + +/* CODE[1:0]: Mailbox code */ +#define CAN_TSR_CODE_MASK (0x3 << 24) + +/* ABRQ2: Abort request for mailbox 2 */ +#define CAN_TSR_ABRQ2 (1 << 23) + +/* 22:20 Reserved, forced by hardware to 0 */ + +/* TERR2: Transmission error for mailbox 2 */ +#define CAN_TSR_TERR2 (1 << 19) + +/* ALST2: Arbitration lost for mailbox 2 */ +#define CAN_TSR_ALST2 (1 << 18) + +/* TXOK2: Transmission OK for mailbox 2 */ +#define CAN_TSR_TXOK2 (1 << 17) + +/* RQCP2: Request completed mailbox 2 */ +#define CAN_TSR_RQCP2 (1 << 16) + +/* ABRQ1: Abort request for mailbox 1 */ +#define CAN_TSR_ABRQ1 (1 << 15) + +/* 14:12 Reserved, forced by hardware to 0 */ + +/* TERR1: Transmission error for mailbox 1 */ +#define CAN_TSR_TERR1 (1 << 11) + +/* ALST1: Arbitration lost for mailbox 1 */ +#define CAN_TSR_ALST1 (1 << 10) + +/* TXOK1: Transmission OK for mailbox 1 */ +#define CAN_TSR_TXOK1 (1 << 9) + +/* RQCP1: Request completed mailbox 1 */ +#define CAN_TSR_RQCP1 (1 << 8) + +/* ABRQ0: Abort request for mailbox 0 */ +#define CAN_TSR_ABRQ0 (1 << 7) + +/* 6:4 Reserved, forced by hardware to 0 */ + +/* TERR0: Transmission error for mailbox 0 */ +#define CAN_TSR_TERR0 (1 << 3) + +/* ALST0: Arbitration lost for mailbox 0 */ +#define CAN_TSR_ALST0 (1 << 2) + +/* TXOK0: Transmission OK for mailbox 0 */ +#define CAN_TSR_TXOK0 (1 << 1) + +/* RQCP0: Request completed mailbox 0 */ +#define CAN_TSR_RQCP0 (1 << 0) + +/* --- CAN_RF0R values ----------------------------------------------------- */ + +/* 31:6 Reserved, forced by hardware to 0 */ + +/* RFOM0: Release FIFO 0 output mailbox */ +#define CAN_RF0R_RFOM0 (1 << 5) + +/* FOVR0: FIFO 0 overrun */ +#define CAN_RF0R_FOVR0 (1 << 4) + +/* FULL0: FIFO 0 full */ +#define CAN_RF0R_FULL0 (1 << 3) + +/* 2 Reserved, forced by hardware to 0 */ + +/* FMP0[1:0]: FIFO 0 message pending */ +#define CAN_RF0R_FMP0_MASK (0x3 << 0) + +/* --- CAN_RF1R values ----------------------------------------------------- */ + +/* 31:6 Reserved, forced by hardware to 0 */ + +/* RFOM1: Release FIFO 1 output mailbox */ +#define CAN_RF1R_RFOM1 (1 << 5) + +/* FOVR1: FIFO 1 overrun */ +#define CAN_RF1R_FOVR1 (1 << 4) + +/* FULL1: FIFO 1 full */ +#define CAN_RF1R_FULL1 (1 << 3) + +/* 2 Reserved, forced by hardware to 0 */ + +/* FMP1[1:0]: FIFO 1 message pending */ +#define CAN_RF1R_FMP1_MASK (0x3 << 0) + +/* --- CAN_IER values ------------------------------------------------------ */ + +/* 32:18 Reserved, forced by hardware to 0 */ + +/* SLKIE: Sleep interrupt enable */ +#define CAN_IER_SLKIE (1 << 17) + +/* WKUIE: Wakeup interrupt enable */ +#define CAN_IER_WKUIE (1 << 16) + +/* ERRIE: Error interrupt enable */ +#define CAN_IER_ERRIE (1 << 15) + +/* 14:12 Reserved, forced by hardware to 0 */ + +/* LECIE: Last error code interrupt enable */ +#define CAN_IER_LECIE (1 << 11) + +/* BOFIE: Bus-off interrupt enable */ +#define CAN_IER_BOFIE (1 << 10) + +/* EPVIE: Error passive interrupt enable */ +#define CAN_IER_EPVIE (1 << 9) + +/* EWGIE: Error warning interrupt enable */ +#define CAN_IER_EWGIE (1 << 8) + +/* 7 Reserved, forced by hardware to 0 */ + +/* FOVIE1: FIFO overrun interrupt enable */ +#define CAN_IER_FOVIE1 (1 << 6) + +/* FFIE1: FIFO full interrupt enable */ +#define CAN_IER_FFIE1 (1 << 5) + +/* FMPIE1: FIFO message pending interrupt enable */ +#define CAN_IER_FMPIE1 (1 << 4) + +/* FOVIE0: FIFO overrun interrupt enable */ +#define CAN_IER_FOVIE0 (1 << 3) + +/* FFIE0: FIFO full interrupt enable */ +#define CAN_IER_FFIE0 (1 << 2) + +/* FMPIE0: FIFO message pending interrupt enable */ +#define CAN_IER_FMPIE0 (1 << 1) + +/* TMEIE: Transmit mailbox empty interrupt enable */ +#define CAN_IER_TMEIE (1 << 0) + +/* --- CAN_ESR values ------------------------------------------------------ */ + +/* REC[7:0]: Receive error counter */ +#define CAN_ESR_REC_MASK (0xF << 24) + +/* TEC[7:0]: Least significant byte of the 9-bit transmit error counter */ +#define CAN_ESR_TEC_MASK (0xF << 16) + +/* 15:7 Reserved, forced by hardware to 0 */ + +/* LEC[2:0]: Last error code */ +#define CAN_ESR_LEC_NO_ERROR (0x0 << 4) +#define CAN_ESR_LEC_STUFF_ERROR (0x1 << 4) +#define CAN_ESR_LEC_FORM_ERROR (0x2 << 4) +#define CAN_ESR_LEC_ACK_ERROR (0x3 << 4) +#define CAN_ESR_LEC_REC_ERROR (0x4 << 4) +#define CAN_ESR_LEC_DOM_ERROR (0x5 << 4) +#define CAN_ESR_LEC_CRC_ERROR (0x6 << 4) +#define CAN_ESR_LEC_SOFT_ERROR (0x7 << 4) +#define CAN_ESR_LEC_MASK (0x7 << 4) + +/* 3 Reserved, forced by hardware to 0 */ + +/* BOFF: Bus-off flag */ +#define CAN_ESR_BOFF (1 << 2) + +/* EPVF: Error passive flag */ +#define CAN_ESR_EPVF (1 << 1) + +/* EWGF: Error warning flag */ +#define CAN_ESR_EWGF (1 << 0) + +/* --- CAN_BTR values ------------------------------------------------------ */ + +/* SILM: Silent mode (debug) */ +#define CAN_BTR_SILM (1 << 31) + +/* LBKM: Loop back mode (debug) */ +#define CAN_BTR_LBKM (1 << 30) + +/* 29:26 Reserved, forced by hardware to 0 */ + +/* SJW[1:0]: Resynchronization jump width */ +#define CAN_BTR_SJW_1TQ (0x0 << 24) +#define CAN_BTR_SJW_2TQ (0x1 << 24) +#define CAN_BTR_SJW_3TQ (0x2 << 24) +#define CAN_BTR_SJW_4TQ (0x3 << 24) +#define CAN_BTR_SJW_MASK (0x3 << 24) +#define CAN_BTR_SJW_SHIFT 24 + +/* 23 Reserved, forced by hardware to 0 */ + +/* TS2[2:0]: Time segment 2 */ +#define CAN_BTR_TS2_1TQ (0x0 << 20) +#define CAN_BTR_TS2_2TQ (0x1 << 20) +#define CAN_BTR_TS2_3TQ (0x2 << 20) +#define CAN_BTR_TS2_4TQ (0x3 << 20) +#define CAN_BTR_TS2_5TQ (0x4 << 20) +#define CAN_BTR_TS2_6TQ (0x5 << 20) +#define CAN_BTR_TS2_7TQ (0x6 << 20) +#define CAN_BTR_TS2_8TQ (0x7 << 20) +#define CAN_BTR_TS2_MASK (0x7 << 20) +#define CAN_BTR_TS2_SHIFT 20 + +/* TS1[3:0]: Time segment 1 */ +#define CAN_BTR_TS1_1TQ (0x0 << 16) +#define CAN_BTR_TS1_2TQ (0x1 << 16) +#define CAN_BTR_TS1_3TQ (0x2 << 16) +#define CAN_BTR_TS1_4TQ (0x3 << 16) +#define CAN_BTR_TS1_5TQ (0x4 << 16) +#define CAN_BTR_TS1_6TQ (0x5 << 16) +#define CAN_BTR_TS1_7TQ (0x6 << 16) +#define CAN_BTR_TS1_8TQ (0x7 << 16) +#define CAN_BTR_TS1_9TQ (0x8 << 16) +#define CAN_BTR_TS1_10TQ (0x9 << 16) +#define CAN_BTR_TS1_11TQ (0xA << 16) +#define CAN_BTR_TS1_12TQ (0xB << 16) +#define CAN_BTR_TS1_13TQ (0xC << 16) +#define CAN_BTR_TS1_14TQ (0xD << 16) +#define CAN_BTR_TS1_15TQ (0xE << 16) +#define CAN_BTR_TS1_16TQ (0xF << 16) +#define CAN_BTR_TS1_MASK (0xF << 16) +#define CAN_BTR_TS1_SHIFT 16 + +/* 15:10 Reserved, forced by hardware to 0 */ + +/* BRP[9:0]: Baud rate prescaler */ +#define CAN_BTR_BRP_MASK (0x3FFUL << 0) + +/* --- CAN_TIxR values ------------------------------------------------------ */ + +/* STID[10:0]: Standard identifier */ +#define CAN_TIxR_STID_MASK (0x7FF << 21) +#define CAN_TIxR_STID_SHIFT 21 + +/* EXID[15:0]: Extended identifier */ +#define CAN_TIxR_EXID_MASK (0x1FFFFFF << 3) +#define CAN_TIxR_EXID_SHIFT 3 + +/* IDE: Identifier extension */ +#define CAN_TIxR_IDE (1 << 2) + +/* RTR: Remote transmission request */ +#define CAN_TIxR_RTR (1 << 1) + +/* TXRQ: Transmit mailbox request */ +#define CAN_TIxR_TXRQ (1 << 0) + +/* --- CAN_TDTxR values ----------------------------------------------------- */ + +/* TIME[15:0]: Message time stamp */ +#define CAN_TDTxR_TIME_MASK (0xFFFF << 15) +#define CAN_TDTxR_TIME_SHIFT 15 + +/* 15:6 Reserved, forced by hardware to 0 */ + +/* TGT: Transmit global time */ +#define CAN_TDTxR_TGT (1 << 5) + +/* 7:4 Reserved, forced by hardware to 0 */ + +/* DLC[3:0]: Data length code */ +#define CAN_TDTxR_DLC_MASK (0xF << 0) +#define CAN_TDTxR_DLC_SHIFT 0 + +/* --- CAN_TDLxR values ----------------------------------------------------- */ + +/* DATA3[7:0]: Data byte 3 */ +/* DATA2[7:0]: Data byte 2 */ +/* DATA1[7:0]: Data byte 1 */ +/* DATA0[7:0]: Data byte 0 */ + +/* --- CAN_TDHxR values ----------------------------------------------------- */ + +/* DATA7[7:0]: Data byte 7 */ +/* DATA6[7:0]: Data byte 6 */ +/* DATA5[7:0]: Data byte 5 */ +/* DATA4[7:0]: Data byte 4 */ + +/* --- CAN_RIxR values ------------------------------------------------------ */ + +/* STID[10:0]: Standard identifier */ +#define CAN_RIxR_STID_MASK (0x7FF) +#define CAN_RIxR_STID_SHIFT 21 + +/* EXID[15:0]: Extended identifier */ +#define CAN_RIxR_EXID_MASK (0x1FFFFFFF) +#define CAN_RIxR_EXID_SHIFT 3 + +/* IDE: Identifier extension */ +#define CAN_RIxR_IDE (1 << 2) + +/* RTR: Remote transmission request */ +#define CAN_RIxR_RTR (1 << 1) + +/* 0 Reserved */ + +/* --- CAN_RDTxR values ----------------------------------------------------- */ + +/* TIME[15:0]: Message time stamp */ +#define CAN_RDTxR_TIME_MASK (0xFFFF << 16) +#define CAN_RDTxR_TIME_SHIFT 16 + +/* FMI[7:0]: Filter match index */ +#define CAN_RDTxR_FMI_MASK (0xFF << 8) +#define CAN_RDTxR_FMI_SHIFT 8 + +/* 7:4 Reserved, forced by hardware to 0 */ + +/* DLC[3:0]: Data length code */ +#define CAN_RDTxR_DLC_MASK (0xF << 0) +#define CAN_RDTxR_DLC_SHIFT 0 + +/* --- CAN_RDLxR values ----------------------------------------------------- */ + +/* DATA3[7:0]: Data byte 3 */ +/* DATA2[7:0]: Data byte 2 */ +/* DATA1[7:0]: Data byte 1 */ +/* DATA0[7:0]: Data byte 0 */ + +/* --- CAN_RDHxR values ----------------------------------------------------- */ + +/* DATA7[7:0]: Data byte 7 */ +/* DATA6[7:0]: Data byte 6 */ +/* DATA5[7:0]: Data byte 5 */ +/* DATA4[7:0]: Data byte 4 */ + +/* --- CAN_FMR values ------------------------------------------------------- */ + +/* 31:14 Reserved, forced to reset value */ + +/* + * CAN2SB[5:0]: CAN2 start bank + * (only on connectivity line devices otherwise reserved) + */ +#define CAN_FMR_CAN2SB_MASK (0x3F << 8) +#define CAN_FMR_CAN2SB_SHIFT 15 + +/* 7:1 Reserved, forced to reset value */ + +/* FINIT: Filter init mode */ +#define CAN_FMR_FINIT (1 << 0) + +/* --- CAN_FM1R values ------------------------------------------------------ */ + +/* 31:28 Reserved, forced by hardware to 0 */ + +/* + * FBMx: Filter mode + * x is 0..27 should be calculated by a helper function making so many macros + * seems like an overkill? + */ + +/* --- CAN_FS1R values ------------------------------------------------------ */ + +/* 31:28 Reserved, forced by hardware to 0 */ + +/* + * FSCx: Filter scale configuration + * x is 0..27 should be calculated by a helper function making so many macros + * seems like an overkill? + */ + +/* --- CAN_FFA1R values ----------------------------------------------------- */ + +/* 31:28 Reserved, forced by hardware to 0 */ + +/* + * FFAx: Filter scale configuration + * x is 0..27 should be calculated by a helper function making so many macros + * seems like an overkill? + */ + +/* --- CAN_FA1R values ------------------------------------------------------ */ + +/* 31:28 Reserved, forced by hardware to 0 */ + +/* + * FACTx: Filter active + * x is 0..27 should be calculated by a helper function making so many macros + * seems like an overkill? + */ + +/* --- CAN_FiRx values ------------------------------------------------------ */ + +/* FB[31:0]: Filter bits */ + +/* --- CAN functions -------------------------------------------------------- */ + +BEGIN_DECLS + +void can_reset(uint32_t canport); +int can_init(uint32_t canport, bool ttcm, bool abom, bool awum, bool nart, + bool rflm, bool txfp, uint32_t sjw, uint32_t ts1, uint32_t ts2, + uint32_t brp, bool loopback, bool silent); + +void can_filter_init(uint32_t canport, uint32_t nr, bool scale_32bit, + bool id_list_mode, uint32_t fr1, uint32_t fr2, + uint32_t fifo, bool enable); +void can_filter_id_mask_16bit_init(uint32_t canport, uint32_t nr, uint16_t id1, + uint16_t mask1, uint16_t id2, + uint16_t mask2, uint32_t fifo, bool enable); +void can_filter_id_mask_32bit_init(uint32_t canport, uint32_t nr, uint32_t id, + uint32_t mask, uint32_t fifo, bool enable); +void can_filter_id_list_16bit_init(uint32_t canport, uint32_t nr, uint16_t id1, + uint16_t id2, uint16_t id3, uint16_t id4, + uint32_t fifo, bool enable); +void can_filter_id_list_32bit_init(uint32_t canport, uint32_t nr, uint32_t id1, + uint32_t id2, uint32_t fifo, bool enable); + +void can_enable_irq(uint32_t canport, uint32_t irq); +void can_disable_irq(uint32_t canport, uint32_t irq); + +int can_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr, + uint8_t length, uint8_t *data); +void can_receive(uint32_t canport, uint8_t fifo, bool release, uint32_t *id, + bool *ext, bool *rtr, uint8_t *fmi, uint8_t *length, + uint8_t *data, uint16_t *timestamp); + +void can_fifo_release(uint32_t canport, uint8_t fifo); +bool can_available_mailbox(uint32_t canport); +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/cec.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/cec.h new file mode 100644 index 00000000..51f860e9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/cec.h @@ -0,0 +1,28 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v1.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v1.h new file mode 100644 index 00000000..4b817b83 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v1.h @@ -0,0 +1,412 @@ +/** @addtogroup adc_defines + +@author @htmlonly © @endhtmlonly 2014 Karl Palsson + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA ADC.H +The order of header inclusion is important. adc.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_ADC_H +/** @endcond */ +#ifndef LIBOPENCM3_ADC_COMMON_V1_H +#define LIBOPENCM3_ADC_COMMON_V1_H + +/* --- Convenience macros -------------------------------------------------- */ + +/* ADC port base addresses (for convenience) */ +/****************************************************************************/ +/** @defgroup adc_reg_base ADC register base addresses +@ingroup STM32xx_adc_defines + +@{*/ +#define ADC1 ADC1_BASE +/**@}*/ + +/* --- ADC registers ------------------------------------------------------- */ + +/* ADC status register (ADC_SR) */ +#define ADC_SR(block) MMIO32((block) + 0x00) + +/* ADC control register 1 (ADC_CR1) */ +#define ADC_CR1(block) MMIO32((block) + 0x04) + +/* ADC control register 2 (ADC_CR2) */ +#define ADC_CR2(block) MMIO32((block) + 0x08) + +/* ADC sample time register 1 (ADC_SMPR1) */ +#define ADC_SMPR1(block) MMIO32((block) + 0x0c) + +/* ADC sample time register 2 (ADC_SMPR2) */ +#define ADC_SMPR2(block) MMIO32((block) + 0x10) + +#define ADC1_SR ADC_SR(ADC1) +#define ADC1_CR1 ADC_CR1(ADC1) +#define ADC1_CR2 ADC_CR2(ADC1) +#define ADC1_SMPR1 ADC_SMPR1(ADC1) +#define ADC1_SMPR2 ADC_SMPR2(ADC1) + +#define ADC1_JOFR1 ADC_JOFR1(ADC1) +#define ADC1_JOFR2 ADC_JOFR2(ADC1) +#define ADC1_JOFR3 ADC_JOFR3(ADC1) +#define ADC1_JOFR4 ADC_JOFR4(ADC1) + +#define ADC1_HTR ADC_HTR(ADC1) +#define ADC1_LTR ADC_LTR(ADC1) + +#define ADC1_SQR1 ADC_SQR1(ADC1) +#define ADC1_SQR2 ADC_SQR2(ADC1) +#define ADC1_SQR3 ADC_SQR3(ADC1) +#define ADC1_JSQR ADC_JSQR(ADC1) + +#define ADC1_JDR1 ADC_JDR1(ADC1) +#define ADC1_JDR2 ADC_JDR2(ADC1) +#define ADC1_JDR3 ADC_JDR3(ADC1) +#define ADC1_JDR4 ADC_JDR4(ADC1) +#define ADC1_DR ADC_DR(ADC1) + +#if defined(ADC2_BASE) +#define ADC2 ADC2_BASE +#define ADC2_SR ADC_SR(ADC2) +#define ADC2_CR1 ADC_CR1(ADC2) +#define ADC2_CR2 ADC_CR2(ADC2) +#define ADC2_SMPR1 ADC_SMPR1(ADC2) +#define ADC2_SMPR2 ADC_SMPR2(ADC2) + +#define ADC2_JOFR1 ADC_JOFR1(ADC2) +#define ADC2_JOFR2 ADC_JOFR2(ADC2) +#define ADC2_JOFR3 ADC_JOFR3(ADC2) +#define ADC2_JOFR4 ADC_JOFR4(ADC2) + +/* ADC watchdog high threshold register (ADC_HTR) */ +#define ADC2_HTR ADC_HTR(ADC2) +/* ADC watchdog low threshold register (ADC_LTR) */ +#define ADC2_LTR ADC_LTR(ADC2) + +/* ADC regular sequence register 1 (ADC_SQR1) */ +#define ADC2_SQR1 ADC_SQR1(ADC2) +/* ADC regular sequence register 2 (ADC_SQR2) */ +#define ADC2_SQR2 ADC_SQR2(ADC2) +/* ADC regular sequence register 3 (ADC_SQR3) */ +#define ADC2_SQR3 ADC_SQR3(ADC2) +/* ADC injected sequence register (ADC_JSQR) */ +#define ADC2_JSQR ADC_JSQR(ADC2) + +/* ADC injected data register x (ADC_JDRx) (x=1..4) */ +#define ADC2_JDR1 ADC_JDR1(ADC2) +#define ADC2_JDR2 ADC_JDR2(ADC2) +#define ADC2_JDR3 ADC_JDR3(ADC2) +#define ADC2_JDR4 ADC_JDR4(ADC2) +/* ADC regular data register (ADC_DR) */ +#define ADC2_DR ADC_DR(ADC2) +#endif + +#if defined(ADC3_BASE) +#define ADC3 ADC3_BASE +#define ADC3_SR ADC_SR(ADC3) +#define ADC3_CR1 ADC_CR1(ADC3) +#define ADC3_CR2 ADC_CR2(ADC3) +#define ADC3_SMPR1 ADC_SMPR1(ADC3) +#define ADC3_SMPR2 ADC_SMPR2(ADC3) + +#define ADC3_JOFR1 ADC_JOFR1(ADC3) +#define ADC3_JOFR2 ADC_JOFR2(ADC3) +#define ADC3_JOFR3 ADC_JOFR3(ADC3) +#define ADC3_JOFR4 ADC_JOFR4(ADC3) + +#define ADC3_HTR ADC_HTR(ADC3) +#define ADC3_LTR ADC_LTR(ADC3) + +#define ADC3_SQR1 ADC_SQR1(ADC3) +#define ADC3_SQR2 ADC_SQR2(ADC3) +#define ADC3_SQR3 ADC_SQR3(ADC3) +#define ADC3_JSQR ADC_JSQR(ADC3) + +#define ADC3_JDR1 ADC_JDR1(ADC3) +#define ADC3_JDR2 ADC_JDR2(ADC3) +#define ADC3_JDR3 ADC_JDR3(ADC3) +#define ADC3_JDR4 ADC_JDR4(ADC3) +#define ADC3_DR ADC_DR(ADC3) +#endif + + + +/* --- ADC Channels ------------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup adc_channel ADC Channel Numbers +@ingroup STM32xx_adc_defines + +@{*/ +#define ADC_CHANNEL0 0x00 +#define ADC_CHANNEL1 0x01 +#define ADC_CHANNEL2 0x02 +#define ADC_CHANNEL3 0x03 +#define ADC_CHANNEL4 0x04 +#define ADC_CHANNEL5 0x05 +#define ADC_CHANNEL6 0x06 +#define ADC_CHANNEL7 0x07 +#define ADC_CHANNEL8 0x08 +#define ADC_CHANNEL9 0x09 +#define ADC_CHANNEL10 0x0A +#define ADC_CHANNEL11 0x0B +#define ADC_CHANNEL12 0x0C +#define ADC_CHANNEL13 0x0D +#define ADC_CHANNEL14 0x0E +#define ADC_CHANNEL15 0x0F +#define ADC_CHANNEL16 0x10 +#define ADC_CHANNEL17 0x11 +#define ADC_CHANNEL18 0x12 +/**@}*/ +#define ADC_CHANNEL_MASK 0x1F + + +/* --- ADC_SR values ------------------------------------------------------- */ + +#define ADC_SR_STRT (1 << 4) +#define ADC_SR_JSTRT (1 << 3) +#define ADC_SR_JEOC (1 << 2) +#define ADC_SR_EOC (1 << 1) +#define ADC_SR_AWD (1 << 0) + +/* --- ADC_CR1 values ------------------------------------------------------ */ + +/* AWDEN: Analog watchdog enable on regular channels */ +#define ADC_CR1_AWDEN (1 << 23) + +/* JAWDEN: Analog watchdog enable on injected channels */ +#define ADC_CR1_JAWDEN (1 << 22) + +/* Note: Bits [21:20] are reserved, and must be kept at reset value. */ + + +/* DISCNUM[2:0]: Discontinuous mode channel count. */ +/****************************************************************************/ +/** @defgroup adc_cr1_discnum ADC Number of channels in discontinuous mode. +@ingroup STM32_adc_defines + +@{*/ +#define ADC_CR1_DISCNUM_1CHANNELS (0x0 << 13) +#define ADC_CR1_DISCNUM_2CHANNELS (0x1 << 13) +#define ADC_CR1_DISCNUM_3CHANNELS (0x2 << 13) +#define ADC_CR1_DISCNUM_4CHANNELS (0x3 << 13) +#define ADC_CR1_DISCNUM_5CHANNELS (0x4 << 13) +#define ADC_CR1_DISCNUM_6CHANNELS (0x5 << 13) +#define ADC_CR1_DISCNUM_7CHANNELS (0x6 << 13) +#define ADC_CR1_DISCNUM_8CHANNELS (0x7 << 13) +/**@}*/ +#define ADC_CR1_DISCNUM_MASK (0x7 << 13) +#define ADC_CR1_DISCNUM_SHIFT 13 + +/* JDISCEN: */ /** Discontinuous mode on injected channels. */ +#define ADC_CR1_JDISCEN (1 << 12) + +/* DISCEN: */ /** Discontinuous mode on regular channels. */ +#define ADC_CR1_DISCEN (1 << 11) + +/* JAUTO: */ /** Automatic Injection Group conversion. */ +#define ADC_CR1_JAUTO (1 << 10) + +/* AWDSGL: */ /** Enable the watchdog on a single channel in scan mode. */ +#define ADC_CR1_AWDSGL (1 << 9) + +/* SCAN: */ /** Scan mode. */ +#define ADC_CR1_SCAN (1 << 8) + +/* JEOCIE: */ /** Interrupt enable for injected channels. */ +#define ADC_CR1_JEOCIE (1 << 7) + +/* AWDIE: */ /** Analog watchdog interrupt enable. */ +#define ADC_CR1_AWDIE (1 << 6) + +/* EOCIE: */ /** Interrupt enable EOC. */ +#define ADC_CR1_EOCIE (1 << 5) + +/* AWDCH[4:0]: Analog watchdog channel bits. (Up to 17 other values reserved) */ +/* Notes: Depending on part, and ADC peripheral, some channels are connected + * to V_SS, or to temperature/reference/battery inputs + */ +/****************************************************************************/ +/* ADC_CR1 AWDCH[4:0] ADC watchdog channel */ +/** @defgroup adc_watchdog_channel ADC watchdog channel +@ingroup STM32xx_adc_defines + +@{*/ +#define ADC_CR1_AWDCH_CHANNEL0 (0x00 << 0) +#define ADC_CR1_AWDCH_CHANNEL1 (0x01 << 0) +#define ADC_CR1_AWDCH_CHANNEL2 (0x02 << 0) +#define ADC_CR1_AWDCH_CHANNEL3 (0x03 << 0) +#define ADC_CR1_AWDCH_CHANNEL4 (0x04 << 0) +#define ADC_CR1_AWDCH_CHANNEL5 (0x05 << 0) +#define ADC_CR1_AWDCH_CHANNEL6 (0x06 << 0) +#define ADC_CR1_AWDCH_CHANNEL7 (0x07 << 0) +#define ADC_CR1_AWDCH_CHANNEL8 (0x08 << 0) +#define ADC_CR1_AWDCH_CHANNEL9 (0x09 << 0) +#define ADC_CR1_AWDCH_CHANNEL10 (0x0A << 0) +#define ADC_CR1_AWDCH_CHANNEL11 (0x0B << 0) +#define ADC_CR1_AWDCH_CHANNEL12 (0x0C << 0) +#define ADC_CR1_AWDCH_CHANNEL13 (0x0D << 0) +#define ADC_CR1_AWDCH_CHANNEL14 (0x0E << 0) +#define ADC_CR1_AWDCH_CHANNEL15 (0x0F << 0) +#define ADC_CR1_AWDCH_CHANNEL16 (0x10 << 0) +#define ADC_CR1_AWDCH_CHANNEL17 (0x11 << 0) +/**@}*/ +#define ADC_CR1_AWDCH_MASK (0x1F << 0) +#define ADC_CR1_AWDCH_SHIFT 0 + +/* --- ADC_CR2 values ------------------------------------------------------ */ + +/* ALIGN: Data alignement. */ +#define ADC_CR2_ALIGN_RIGHT (0 << 11) +#define ADC_CR2_ALIGN_LEFT (1 << 11) +#define ADC_CR2_ALIGN (1 << 11) + +/* DMA: Direct memory access mode. (ADC1 and ADC3 only!) */ +#define ADC_CR2_DMA (1 << 8) + +/* CONT: Continuous conversion. */ +#define ADC_CR2_CONT (1 << 1) + +/* ADON: A/D converter On/Off. */ +/* Note: If any other bit in this register apart from ADON is changed at the + * same time, then conversion is not triggered. This is to prevent triggering + * an erroneous conversion. + * Conclusion: Must be separately written. + */ +#define ADC_CR2_ADON (1 << 0) + +/* --- ADC_JOFRx, ADC_HTR, ADC_LTR values ---------------------------------- */ + +#define ADC_JOFFSET_LSB 0 +#define ADC_JOFFSET_MSK 0xfff +#define ADC_HT_LSB 0 +#define ADC_HT_MSK 0xfff +#define ADC_LT_LSB 0 +#define ADC_LT_MSK 0xfff + +/* --- ADC_SQR1 values ----------------------------------------------------- */ +/* The sequence length field is always in the same place, but sized + * differently on various parts */ +#define ADC_SQR1_L_LSB 20 + +/* --- ADC_JSQR values ----------------------------------------------------- */ +#define ADC_JSQR_JL_LSB 20 +#define ADC_JSQR_JSQ4_LSB 15 +#define ADC_JSQR_JSQ3_LSB 10 +#define ADC_JSQR_JSQ2_LSB 5 +#define ADC_JSQR_JSQ1_LSB 0 + +/* JL[2:0]: Discontinous mode channel count injected channels. */ +/****************************************************************************/ +/** @defgroup adc_jsqr_jl ADC Number of channels in discontinuous injected mode +@ingroup STM32xx_adc_defines + +@{*/ +#define ADC_JSQR_JL_1CHANNELS (0x0 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_2CHANNELS (0x1 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_3CHANNELS (0x2 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_4CHANNELS (0x3 << ADC_JSQR_JL_LSB) +/**@}*/ +#define ADC_JSQR_JL_MSK (0x2 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JSQ4_MSK (0x1f << ADC_JSQR_JSQ4_LSB) +#define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQR_JSQ3_LSB) +#define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQR_JSQ2_LSB) +#define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQR_JSQ1_LSB) + +#define ADC_JSQR_JSQ_VAL(n, val) ((val) << (((n) - 1) * 5)) +#define ADC_JSQR_JL_VAL(val) (((val) - 1) << ADC_JSQR_JL_LSB) + +#if (defined(THESE_HAVE_BAD_NAMES_PROBABLY) && (THESE_HAVE_BAD_NAMES_PROBABLY)) +/* --- ADC_JDRx, ADC_DR values --------------------------------------------- */ + +#define ADC_JDATA_LSB 0 +#define ADC_DATA_LSB 0 +#define ADC_ADC2DATA_LSB 16 /* ADC1 only (dual mode) */ +#define ADC_JDATA_MSK (0xffff << ADC_JDATA_LSB) +#define ADC_DATA_MSK (0xffff << ADC_DA) +#define ADC_ADC2DATA_MSK (0xffff << ADC_ADC2DATA_LSB) +/* ADC1 only (dual mode) */ +#endif + + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void adc_power_on(uint32_t adc); +void adc_power_off(uint32_t adc); +void adc_enable_analog_watchdog_regular(uint32_t adc); +void adc_disable_analog_watchdog_regular(uint32_t adc); +void adc_enable_analog_watchdog_injected(uint32_t adc); +void adc_disable_analog_watchdog_injected(uint32_t adc); +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length); +void adc_disable_discontinuous_mode_regular(uint32_t adc); +void adc_enable_discontinuous_mode_injected(uint32_t adc); +void adc_disable_discontinuous_mode_injected(uint32_t adc); +void adc_enable_automatic_injected_group_conversion(uint32_t adc); +void adc_disable_automatic_injected_group_conversion(uint32_t adc); +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc); +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel); +void adc_enable_scan_mode(uint32_t adc); +void adc_disable_scan_mode(uint32_t adc); +void adc_enable_eoc_interrupt_injected(uint32_t adc); +void adc_disable_eoc_interrupt_injected(uint32_t adc); +void adc_enable_awd_interrupt(uint32_t adc); +void adc_disable_awd_interrupt(uint32_t adc); +void adc_enable_eoc_interrupt(uint32_t adc); +void adc_disable_eoc_interrupt(uint32_t adc); +void adc_set_left_aligned(uint32_t adc); +void adc_set_right_aligned(uint32_t adc); +bool adc_eoc(uint32_t adc); +bool adc_eoc_injected(uint32_t adc); +uint32_t adc_read_regular(uint32_t adc); +uint32_t adc_read_injected(uint32_t adc, uint8_t reg); +void adc_set_continuous_conversion_mode(uint32_t adc); +void adc_set_single_conversion_mode(uint32_t adc); +void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[]); +void adc_set_injected_sequence(uint32_t adc, uint8_t length, uint8_t channel[]); +void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset); +void adc_set_watchdog_high_threshold(uint32_t adc, uint16_t threshold); +void adc_set_watchdog_low_threshold(uint32_t adc, uint16_t threshold); +void adc_start_conversion_regular(uint32_t adc); +void adc_start_conversion_injected(uint32_t adc); +void adc_enable_dma(uint32_t adc); +void adc_disable_dma(uint32_t adc); + +/* common methods that have slight differences */ +void adc_set_sample_time(uint32_t adc, uint8_t channel, uint8_t time); +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time); +void adc_disable_external_trigger_regular(uint32_t adc); +void adc_disable_external_trigger_injected(uint32_t adc); + +END_DECLS + +#endif +/** @cond */ +#endif +/** @endcond */ +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2.h new file mode 100644 index 00000000..afe23c39 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2.h @@ -0,0 +1,215 @@ +/** @addtogroup adc_defines + +@author @htmlonly © @endhtmlonly 2015 Karl Palsson + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA ADC.H +The order of header inclusion is important. adc.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_ADC_H +/** @endcond */ +#ifndef LIBOPENCM3_ADC_COMMON_V2_H +#define LIBOPENCM3_ADC_COMMON_V2_H + +/* ----- ADC registers -----------------------------------------------------*/ +/* ADC interrupt and status register */ +#define ADC_ISR(adc) MMIO32((adc) + 0x00) +/* Interrupt Enable Register */ +#define ADC_IER(adc) MMIO32((adc) + 0x04) +/* Control Register */ +#define ADC_CR(adc) MMIO32((adc) + 0x08) +/* Configuration Register 1 */ +#define ADC_CFGR1(adc) MMIO32((adc) + 0x0C) +/* Configuration Register 2 */ +#define ADC_CFGR2(adc) MMIO32((adc) + 0x10) +/* Sample Time Register 1 */ +#define ADC_SMPR1(adc) MMIO32((adc) + 0x14) +/* Watchdog Threshold Register 1*/ +#define ADC_TR1(adc) MMIO32((adc) + 0x20) +/* Regular Data Register */ +#define ADC_DR(adc) MMIO32((adc) + 0x40) +/* CALFACT for all but f0 :(*/ + +/* ADC common (shared) registers */ +#define ADC_CCR(adc) MMIO32((adc) + 0x300 + 0x8) + +/* --- Register values -------------------------------------------------------*/ + +/* ADC_ISR Values -----------------------------------------------------------*/ + +/* AWD1: Analog watchdog 1 flag */ +#define ADC_ISR_AWD1 (1 << 7) +#define ADC_ISR_OVR (1 << 4) +#define ADC_ISR_EOS (1 << 3) // FIXME - move to single/multi here. +#define ADC_ISR_EOSEQ ADC_ISR_EOS /* TODO - keep only one? */ +#define ADC_ISR_EOC (1 << 2) +#define ADC_ISR_EOSMP (1 << 1) +#define ADC_ISR_ADRDY (1 << 0) + +/* ADC_IER Values -----------------------------------------------------------*/ + +/* AWD1IE: Analog watchdog 1 interrupt enable */ +#define ADC_IER_AWD1IE (1 << 7) +/* OVRIE: Overrun interrupt enable */ +#define ADC_IER_OVRIE (1 << 4) +/* EOSIE: End of regular sequence of conversions interrupt enable */ +#define ADC_IER_EOSIE (1 << 3) +#define ADC_IER_EOSEQIE ADC_IER_EOSIE /* TODO - keep only one? */ +/* EOCIE: End of regular conversion interrupt enable */ +#define ADC_IER_EOCIE (1 << 2) +/* EOSMPIE: End of sampling flag interrupt enable for regular conversions */ +#define ADC_IER_EOSMPIE (1 << 1) +/* ADRDYIE : ADC ready interrupt enable */ +#define ADC_IER_ADRDYIE (1 << 0) + +/* ADC_CR Values -----------------------------------------------------------*/ + +/* ADCAL: ADC calibration */ +#define ADC_CR_ADCAL (1 << 31) +/* ADSTP: ADC stop of regular conversion command */ +#define ADC_CR_ADSTP (1 << 4) +/* ADSTART: ADC start of regular conversion */ +#define ADC_CR_ADSTART (1 << 2) +/* ADDIS: ADC disable command */ +#define ADC_CR_ADDIS (1 << 1) +/* ADEN: ADC enable control */ +#define ADC_CR_ADEN (1 << 0) + +/* ADC_CFGR1 Values -----------------------------------------------------------*/ + +/* AWD1CH[4:0]: Analog watchdog 1 channel selection */ +#define ADC_CFGR1_AWD1CH_SHIFT 26 +#define ADC_CFGR1_AWD1CH (0x1F << ADC_CFGR1_AWD1CH_SHIFT) +#define ADC_CFGR1_AWD1CH_VAL(x) ((x) << ADC_CFGR1_AWD1CH_SHIFT) + +/* AWD1EN: Analog watchdog 1 enable on regular channels */ +#define ADC_CFGR1_AWD1EN (1 << 23) + +/* AWD1SGL: Enable the watchdog 1 on a single channel or on all channels */ +#define ADC_CFGR1_AWD1SGL (1 << 22) + +/* DISCEN: Discontinuous mode for regular channels */ +#define ADC_CFGR1_DISCEN (1 << 16) + +/* AUTDLY: Delayed conversion mode */ +#define ADC_CFGR1_AUTDLY (1 << 14) + +/* CONT: Single / continuous conversion mode for regular conversions */ +#define ADC_CFGR1_CONT (1 << 13) + +/* OVRMOD: Overrun Mode */ +#define ADC_CFGR1_OVRMOD (1 << 12) + +/* + * EXTEN[1:0]: External trigger enable and polarity selection for regular + * channels + */ +#define ADC_CFGR1_EXTEN_DISABLED (0x0 << 10) +#define ADC_CFGR1_EXTEN_RISING_EDGE (0x1 << 10) +#define ADC_CFGR1_EXTEN_FALLING_EDGE (0x2 << 10) +#define ADC_CFGR1_EXTEN_BOTH_EDGES (0x3 << 10) + +#define ADC_CFGR1_EXTEN_MASK (0x3 << 10) + +/* ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 5) + +/* RES[1:0]: Data resolution */ +#define ADC_CFGR1_RES_12_BIT (0x0 << 3) +#define ADC_CFGR1_RES_10_BIT (0x1 << 3) +#define ADC_CFGR1_RES_8_BIT (0x2 << 3) +#define ADC_CFGR1_RES_6_BIT (0x3 << 3) +#define ADC_CFGR1_RES_MASK (0x3 << 3) + +/* DMACFG: Direct memory access configuration */ +#define ADC_CFGR1_DMACFG (1 << 1) + +/* DMAEN: Direct memory access enable */ +#define ADC_CFGR1_DMAEN (1 << 0) + +/* ADC_TR1 Values ------------------------------------------------------------*/ + +#define ADC_TR1_LT_SHIFT 0 +#define ADC_TR1_LT (0xFFF << ADC_TR1_LT_SHIFT) +#define ADC_TR1_LT_VAL(x) ((x) << ADC_TR1_LT_SHIFT) + +#define ADC_TR1_HT_SHIFT 16 +#define ADC_TR1_HT (0xFFF << ADC_TR1_HT_SHIFT) +#define ADC_TR1_HT_VAL(x) ((x) << ADC_TR1_HT_SHIFT) + + + +/* ADC_CCR Values -----------------------------------------------------------*/ +#define ADC_CCR_VBATEN (1 << 24) +#define ADC_CCR_TSEN (1 << 23) +#define ADC_CCR_VREFEN (1 << 22) + + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void adc_power_on_async(uint32_t adc); +void adc_power_on(uint32_t adc); +bool adc_is_power_on(uint32_t adc); +void adc_power_off_async(uint32_t adc); +void adc_power_off(uint32_t adc); +bool adc_is_power_off(uint32_t adc); +void adc_calibrate_async(uint32_t adc); +bool adc_is_calibrating(uint32_t adc); +void adc_calibrate(uint32_t adc); +void adc_set_continuous_conversion_mode(uint32_t adc); +void adc_set_single_conversion_mode(uint32_t adc); +void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[]); +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time); +void adc_enable_temperature_sensor(void); +void adc_disable_temperature_sensor(void); +void adc_enable_vrefint(void); +void adc_disable_vrefint(void); +void adc_set_resolution(uint32_t adc, uint16_t resolution); +void adc_set_left_aligned(uint32_t adc); +void adc_set_right_aligned(uint32_t adc); +void adc_enable_dma(uint32_t adc); +void adc_disable_dma(uint32_t adc); +bool adc_eoc(uint32_t adc); +bool adc_eos(uint32_t adc); +void adc_enable_eoc_interrupt(uint32_t adc); +void adc_disable_eoc_interrupt(uint32_t adc); +void adc_enable_overrun_interrupt(uint32_t adc); +void adc_disable_overrun_interrupt(uint32_t adc); +bool adc_get_overrun_flag(uint32_t adc); +void adc_clear_overrun_flag(uint32_t adc); +uint32_t adc_read_regular(uint32_t adc); +void adc_start_conversion_regular(uint32_t adc); + +END_DECLS + +#endif +/** @cond */ +#endif +/** @endcond */ +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_multi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_multi.h new file mode 100644 index 00000000..fdf2d293 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_multi.h @@ -0,0 +1,184 @@ +/** @addtogroup adc_defines + +@author @htmlonly © @endhtmlonly 2015 Karl Palsson + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA ADC.H +The order of header inclusion is important. adc.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_ADC_H +/** @endcond */ +#ifndef LIBOPENCM3_ADC_COMMON_V2_MULTI_H +#define LIBOPENCM3_ADC_COMMON_V2_MULTI_H + +/* + * The adc v2 peripheral optionally supports per channel sampling, injected + * sequences, watchdogs, offsets and other "advanced" features, and is + * found on the (so far) F3 and L4, + * or only a much "simpler" version as found on (so far) f0 and l0. + */ + +/* ----- ADC registers -----------------------------------------------------*/ +/* Sample Time Register 2 */ +#define ADC_SMPR2(adc) MMIO32((adc) + 0x18) +/* Watchdog Threshold Register 2 */ +#define ADC_TR2(adc) MMIO32((adc) + 0x24) +/* Watchdog Threshold Register 3 */ +#define ADC_TR3(adc) MMIO32((adc) + 0x28) +/* Regular Sequence Register x (ADCx_SQRy, x=1..4, y=1..4) SQRy */ +#define ADC_SQR1(adc) MMIO32((adc) + 0x30) +#define ADC_SQR2(adc) MMIO32((adc) + 0x34) +#define ADC_SQR3(adc) MMIO32((adc) + 0x38) +#define ADC_SQR4(adc) MMIO32((adc) + 0x3C) + +/* Injected Sequence Register (ADCx_JSQR, x=1..4) JSQR */ +#define ADC_JSQR(adc) MMIO32((adc) + 0x30) + +/* Offset Register x (ADCx_OFRy, x=1..4) (y=1..4) OFRy */ +#define ADC_OFR1(adc) MMIO32((adc) + 0x60) +#define ADC_OFR2(adc) MMIO32((adc) + 0x64) +#define ADC_OFR3(adc) MMIO32((adc) + 0x68) +#define ADC_OFR4(adc) MMIO32((adc) + 0x6C) + +/* Injected Data Register y (ADCx_JDRy, x=1..4, y= 1..4) JDRy */ +#define ADC_JDR1(adc) MMIO32((adc) + 0x80) +#define ADC_JDR2(adc) MMIO32((adc) + 0x84) +#define ADC_JDR3(adc) MMIO32((adc) + 0x88) +#define ADC_JDR4(adc) MMIO32((adc) + 0x8C) + +/* Analog Watchdog 2 Configuration Register (ADCx_AWD2CR, x=1..4) AWD2CR */ +#define ADC_AWD2CR(adc) MMIO32((adc) + 0xA0) +/* Analog Watchdog 3 Configuration Register (ADCx_AWD3CR, x=1..4) AWD3CR */ +#define ADC_AWD3CR(adc) MMIO32((adc) + 0xA4) + +/* Differential Mode Selection Register 2 (ADCx_DIFSEL, x=1..4) DIFSEL */ +#define ADC_DIFSEL(adc) MMIO32((adc) + 0xB0) + +/* Calibration Factors (ADCx_CALFACT, x=1..4) CALFACT */ +#define ADC_CALFACT(adc) MMIO32((adc) + 0xB4) + +/* ADC common (shared) registers */ +#define ADC_CSR(adc) MMIO32((adc) + 0x300 + 0x0) +#define ADC_CDR(adc) MMIO32((adc) + 0x300 + 0xa) + +/* --- Register values ------------------------------------------------------*/ +/* ADC_ISR Values -----------------------------------------------------------*/ + +/* QOVF: Injected context queue overflow */ +#define ADC_ISR_JQOVF (1 << 10) +/* AWD3: Analog watchdog 3 flag */ +#define ADC_ISR_AWD3 (1 << 9) +/* AWD2: Analog watchdog 2 flag */ +#define ADC_ISR_AWD2 (1 << 8) +/* JEOS: Injected channel end of sequence flag */ +#define ADC_ISR_JEOS (1 << 6) +/* JEOC: Injected channel end of conversion flag */ +#define ADC_ISR_JEOC (1 << 5) + +/* ADC_IER Values -----------------------------------------------------------*/ + +/* JQOVFIE: Injected context queue overflow interrupt enable */ +#define ADC_IER_JQOVFIE (1 << 10) +/* AWD3IE: Analog watchdog 3 interrupt enable */ +#define ADC_IER_AWD3IE (1 << 9) +/* AWD2IE: Analog watchdog 2 interrupt enable */ +#define ADC_IER_AWD2IE (1 << 8) +/* JEOSIE: End of injected sequence of conversions interrupt enable */ +#define ADC_IER_JEOSIE (1 << 6) +/* JEOCIE: End of injected conversion interrupt enable */ +#define ADC_IER_JEOCIE (1 << 5) + +/* ADC_CR Values ------------------------------------------------------------*/ + +/* ADCALDIF: Differential mode for calibration */ +#define ADC_CR_ADCALDIF (1 << 30) +/* JADSTP: ADC stop of injected conversion command */ +#define ADC_CR_JADSTP (1 << 5) +/* JADSTART: ADC start of injected conversion */ +#define ADC_CR_JADSTART (1 << 3) + +/* ADC_CFGR1 Values ---------------------------------------------------------*/ + +/* JAUTO: Autoamtic injected group conversion */ +#define ADC_CFGR1_JAUTO (1 << 25) + +/* JAWD1EN: Analog watchdog 1 enable on injected channels */ +#define ADC_CFGR1_JAWD1EN (1 << 24) + +/* JQM: JSQR queue mode */ +#define ADC_CFGR1_JQM (1 << 21) + +/* JDISCEN: Discontinuous mode on injected channels */ +#define ADC_CFGR1_JDISCEN (1 << 20) + +/* DISCNUM[2:0]: Discontinuous mode channel count */ +#define ADC_CFGR1_DISCNUM_SHIFT 17 +#define ADC_CFGR1_DISCNUM_MASK (0x7 << ADC_CFGR1_DISCNUM_SHIFT) +#define ADC_CFGR1_DISCNUM_VAL(x) (((x) - 1) << ADC_CFGR1_DISCNUM_SHIFT) + +/* EXTSEL[3:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 6 +#define ADC_CFGR1_EXTSEL_MASK (0xf << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + +/* ADC_SQRx Values: Regular Sequence ordering------------------------------- */ + +#define ADC_SQR1_L_SHIFT 0 +#define ADC_SQR1_L_MASK 0xf +#define ADC_SQRx_SQx_MASK 0x1f +#define ADC_SQR1_SQ1_SHIFT 6 +#define ADC_SQR1_SQ2_SHIFT 12 +#define ADC_SQR1_SQ3_SHIFT 18 +#define ADC_SQR1_SQ4_SHIFT 24 +#define ADC_SQR2_SQ5_SHIFT 0 +#define ADC_SQR2_SQ6_SHIFT 6 +#define ADC_SQR2_SQ7_SHIFT 12 +#define ADC_SQR2_SQ8_SHIFT 18 +#define ADC_SQR2_SQ9_SHIFT 24 +#define ADC_SQR3_SQ10_SHIFT 0 +#define ADC_SQR3_SQ11_SHIFT 6 +#define ADC_SQR3_SQ12_SHIFT 12 +#define ADC_SQR3_SQ13_SHIFT 18 +#define ADC_SQR3_SQ14_SHIFT 24 +#define ADC_SQR4_SQ15_SHIFT 0 +#define ADC_SQR4_SQ16_SHIFT 6 + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void adc_set_sample_time(uint32_t adc, uint8_t channel, uint8_t time); +void adc_enable_regulator(uint32_t adc); +void adc_disable_regulator(uint32_t adc); + +END_DECLS + +#endif +/** @cond */ +#endif +/** @endcond */ +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_single.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_single.h new file mode 100644 index 00000000..6d8ae65f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/adc_common_v2_single.h @@ -0,0 +1,74 @@ +/** @addtogroup adc_defines + +@author @htmlonly © @endhtmlonly 2015 Karl Palsson + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA ADC.H +The order of header inclusion is important. adc.h includes the device +specific memorymap.h header before including this header file.*/ + +/* + * The adc v2 peripheral optionally supports per channel sampling, injected + * sequences, watchdogs, offsets and other "advanced" features, and is + * found on the (so far) F3 and L4, + * or only a much "simpler" version as found on (so far) f0 and l0. + */ + +/** @cond */ +#ifdef LIBOPENCM3_ADC_H +/** @endcond */ +#ifndef LIBOPENCM3_ADC_COMMON_V2_SINGLE_H +#define LIBOPENCM3_ADC_COMMON_V2_SINGLE_H + +/* ----- ADC registers -----------------------------------------------------*/ +/* Channel Select Register */ +#define ADC_CHSELR(adc) MMIO32((adc) + 0x28) + +/* ----- ADC registers values -----------------------------------------------*/ +/* ADC_CFGR1 values */ +#define ADC_CFGR1_WAIT (1<<14) +/* EXTSEL[2:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 6 +#define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + +#define ADC_CFGR1_SCANDIR (1 << 2) + +/* ADC_CHSELR Values --------------------------------------------------------*/ + +#define ADC_CHSELR_CHSEL(x) (1 << (x)) + + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +END_DECLS + +#endif +/** @cond */ +#endif +/** @endcond */ +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crc_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crc_common_all.h new file mode 100644 index 00000000..4d16c203 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crc_common_all.h @@ -0,0 +1,118 @@ +/** @addtogroup crc_defines + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA CRC.H +The order of header inclusion is important. crc.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_CRC_H +/** @endcond */ +#ifndef LIBOPENCM3_CRC_COMMON_ALL_H +#define LIBOPENCM3_CRC_COMMON_ALL_H + +/**@{*/ + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +/* Data register (CRC_DR) */ +#define CRC_DR MMIO32(CRC_BASE + 0x00) + +/* Independent data register (CRC_IDR) */ +#define CRC_IDR MMIO32(CRC_BASE + 0x04) + +/* Control register (CRC_CR) */ +#define CRC_CR MMIO32(CRC_BASE + 0x08) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- CRC_DR values ------------------------------------------------------- */ + +/* Bits [31:0]: Data register */ + +/* --- CRC_IDR values ------------------------------------------------------ */ + +/* Bits [31:8]: Reserved */ + +/* Bits [7:0]: General-purpose 8-bit data register bits */ + +/* --- CRC_CR values ------------------------------------------------------- */ + +/* Bits [31:1]: Reserved */ + +/* RESET bit */ +#define CRC_CR_RESET (1 << 0) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +/* TODO */ + +/** + * Reset the CRC calculator to initial values. + */ +void crc_reset(void); + +/** + * Add a word to the CRC calculator and return the result. + * @param data new word to add to the CRC calculator + * @return final CRC calculator value + */ +uint32_t crc_calculate(uint32_t data); + +/** + * Add a block of data to the CRC calculator and return the final result + * @param datap pointer to the start of a block of 32bit data words + * @param size length of data, in 32bit increments + * @return final CRC calculator value + */ +uint32_t crc_calculate_block(uint32_t *datap, int size); + +END_DECLS + +/**@}*/ + +#endif +/** @cond */ +#else +#warning "crc_common_all.h should not be included explicitly, only via crc.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crs_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crs_common_all.h new file mode 100644 index 00000000..2ce29f36 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crs_common_all.h @@ -0,0 +1,133 @@ +/** @defgroup CRS_defines CRS Defines + * + * @brief STM32 Clock Recovery System: Defined Constants and Types + * + * @ingroup STM32_defines + * + * @version 1.0.0 + * + * @date 5 Feb 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRS_H +#define LIBOPENCM3_CRS_H +/**@{*/ + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define CRS CRS_BASE + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define CRS_CR MMIO32(CRS_BASE + 0x00) +#define CRS_CFGR MMIO32(CRS_BASE + 0x04) +#define CRS_ISR MMIO32(CRS_BASE + 0x08) +#define CRS_ICR MMIO32(CRS_BASE + 0x0c) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* CEC_CR Values ------------------------------------------------------------*/ + +#define CRS_CR_TRIM_SHIFT 8 +#define CRS_CR_TRIM (0x3F << CRS_CR_TRIM_SHIFT) + +#define CRS_CR_SWSYNC (1 << 7) +#define CRS_CR_AUTOTRIMEN (1 << 6) +#define CRS_CR_CEN (1 << 5) +#define CRS_CR_ESYNCIE (1 << 3) +#define CRS_CR_ERRIE (1 << 2) +#define CRS_CR_SYNCWARNIE (1 << 1) +#define CRS_CR_SYNCOKIE (1 << 0) + +/* CEC_CFGR Values ----------------------------------------------------------*/ + +#define CRS_CFGR_SYNCPOL (1 << 31) + +#define CRS_CFGR_SYNCSRC_SHIFT 28 +#define CRS_CFGR_SYNCSRC (3 << CRS_CFGR_SYNCSRC_SHIFT) +#define CRS_CFGR_SYNCSRC_GPIO (0 << CRS_CFGR_SYNCSRC_SHIFT) +#define CRS_CFGR_SYNCSRC_LSE (1 << CRS_CFGR_SYNCSRC_SHIFT) +#define CRS_CFGR_SYNCSRC_USB_SOF (2 << CRS_CFGR_SYNCSRC_SHIFT) + +#define CRS_CFGR_SYNCDIV_SHIFT 24 +#define CRS_CFGR_SYNCDIV (7 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_NODIV (0 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_DIV2 (1 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_DIV4 (2 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_DIV8 (3 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_DIV16 (4 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_DIV32 (5 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_DIV64 (6 << CRS_CFGR_SYNCDIV_SHIFT) +#define CRS_CFGR_SYNCDIV_DIV128 (7 << CRS_CFGR_SYNCDIV_SHIFT) + +#define CRS_CFGR_FELIM_SHIFT 16 +#define CRS_CFGR_FELIM (0xFF << CRS_CFGR_FELIM_SHIFT) +#define CRS_CFGR_FELIM_VAL(x) ((x) << CRS_CFGR_FELIM_SHIFT) + +#define CRS_CFGR_RELOAD_SHIFT 0 +#define CRS_CFGR_RELOAD (0xFFFF << CRS_CFGR_RELOAD_SHIFT) +#define CRS_CFGR_RELOAD_VAL(x) ((x) << CRS_CFGR_RELOAD_SHIFT) + +/* CEC_ISR Values -----------------------------------------------------------*/ + +#define CRS_ISR_FECAP_SHIFT 16 +#define CRS_ISR_FECAP (0xFFFF << CRS_ISR_FECAP_SHIFT) + +#define CRS_ISR_FEDIR (1 << 15) +#define CRS_ISR_TRIMOVF (1 << 10) +#define CRS_ISR_SYNCMISS (1 << 9) +#define CRS_ISR_SYNCERR (1 << 8) +#define CRS_ISR_ESYNCF (1 << 3) +#define CRS_ISR_ERRF (1 << 2) +#define CRS_ISR_SYNCWARNF (1 << 1) +#define CRS_ISR_SYNCOOKF (1 << 0) + +/* CEC_ICR Values -----------------------------------------------------------*/ + +#define CRS_ICR_ESYNCC (1 << 3) +#define CRS_ICR_ERRC (1 << 2) +#define CRS_ICR_SYNCWARNC (1 << 1) +#define CRS_ICR_SYNCOKC (1 << 0) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +void crs_autotrim_usb_enable(void); + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crypto_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crypto_common_f24.h new file mode 100644 index 00000000..eb885c8f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/crypto_common_f24.h @@ -0,0 +1,290 @@ +/** @addtogroup crypto_defines + * + * @warning The CRYP subsystem is present only in a limited set of devices, + * see next section for list of supported devices. + * + * @section crypto_api_supported Supported devices + * + * - STM32F205 + * - STM32F207 + * - STM32F215 + * - STM32F217 + * - STM32F405 + * - STM32F407 + * - STM32F415 + * - STM32F417 (tested) + * - STM32F427 + * - STM32F437 + * + * @section crypto_api_theory Theory of operation + * + * + * + * @section crypto_api_basic Basic handling API + * + * + * @b Example @b 1: Blocking mode + * + * @code + * //[enable-clocks] + * crypto_set_key(CRYPTO_KEY_128BIT,key); + * crypto_set_iv(iv); // only in CBC or CTR mode + * crypto_set_datatype(CRYPTO_DATA_16BIT); + * crypto_set_algorithm(ENCRYPT_AES_ECB); + * crypto_start(); + * foreach(block in blocks) + * crypto_process_block(plaintext,ciphertext,blocksize); + * crypto_stop(); + * @endcode + * + * @section crypto_api_interrupt Interrupt supported handling API + * + * @warning This operation mode is currently not supported. + * + * @b Example @b 2: Interrupt mode + * + * @code + * //[enable-clocks] + * crypto_set_key(CRYPTO_KEY_128BIT,key); + * crypto_set_iv(iv); // only in CBC or CTR mode + * crypto_set_datatype(CRYPTO_DATA_16BIT); + * crypto_set_algorithm(ENCRYPT_AES_ECB); + * crypto_start(); + * [... API to be described later ...] + * crypto_stop(); + * @endcode + * + * @section crypto_api_dma DMA handling API + * + * @warning This operation mode is currently not supported. + * + * @b Example @b 3: DMA mode + * + * @code + * //[enable-clocks] + * crypto_set_key(CRYPTO_KEY_128BIT,key); + * crypto_set_iv(iv); // only in CBC or CTR mode + * crypto_set_datatype(CRYPTO_DATA_16BIT); + * crypto_set_algorithm(ENCRYPT_AES_ECB); + * crypto_start(); + * [... API to be described later ...] + * crypto_stop(); + * @endcode + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA CRYP.H +The order of header inclusion is important. cryp.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_CRYPTO_H +/** @endcond */ + +#ifndef LIBOPENCM3_CRYPTO_COMMON_F24_H +#define LIBOPENCM3_CRYPTO_COMMON_F24_H + +/**@{*/ + +/* --- CRYP registers ------------------------------------------------------ */ +/** @defgroup crypto_registers_gen Registers (Generic) + * + * @brief Register access to the CRYP controller. (All chips) + * + * @ingroup crypto_defines + */ +/**@{*/ + +#define CRYP CRYP_BASE + +/* CRYP Control Register (CRYP_CR) */ +#define CRYP_CR MMIO32(CRYP_BASE + 0x00) + +/* CRYP Status Register (CRYP_SR) */ +#define CRYP_SR MMIO32(CRYP_BASE + 0x04) + +/* CRYP Data Input Register (CRYP_DIN) */ +#define CRYP_DIN MMIO32(CRYP_BASE + 0x08) + +/** CRYP Data Output Register (CRYP_DOUT) @see blablabla */ +#define CRYP_DOUT MMIO32(CRYP_BASE + 0x0C) + +/* CRYP DMA Control Register (CRYP_DMACR) */ +#define CRYP_DMACR MMIO32(CRYP_BASE + 0x10) + +/* CRYP Interrupt mask set/clear register (CRYP_IMSCR) */ +#define CRYP_IMSCR MMIO32(CRYP_BASE + 0x14) + +/* CRYP Raw Interrupt status register (CRYP_RISR) */ +#define CRYP_RISR MMIO32(CRYP_BASE + 0x18) + +/* CRYP Masked Interrupt status register (CRYP_MISR) */ +#define CRYP_MISR MMIO32(CRYP_BASE + 0x1C) + +/* CRYP Key registers (CRYP_KxLR) x=0..3 */ +#define CRYP_KR(i) MMIO64(CRYP_BASE + 0x20 + (i) * 8) + +/* CRYP Initialization Vector Registers (CRYP_IVxLR) x=0..1 */ +#define CRYP_IVR(i) MMIO32(CRYP_BASE + 0x40 + (i) * 8) + +/* --- CRYP_CR values ------------------------------------------------------ */ + +/* ALGODIR: Algorithm direction */ +#define CRYP_CR_ALGODIR (1 << 2) + +/* ALGOMODE: Algorithm mode */ +#define CRYP_CR_ALGOMODE_SHIFT 3 +#define CRYP_CR_ALGOMODE (7 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_TDES_ECB (0 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_TDES_CBC (1 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_DES_ECB (2 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_DES_CBC (3 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_AES_ECB (4 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_AES_CBC (5 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_AES_CTR (6 << CRYP_CR_ALGOMODE_SHIFT) +#define CRYP_CR_ALGOMODE_AES_PREP (7 << CRYP_CR_ALGOMODE_SHIFT) + +/* DATATYPE: Data type selection */ +#define CRYP_CR_DATATYPE_SHIFT 6 +#define CRYP_CR_DATATYPE (3 << CRYP_CR_DATATYPE_SHIFT) +#define CRYP_CR_DATATYPE_32 (0 << CRYP_CR_DATATYPE_SHIFT) +#define CRYP_CR_DATATYPE_16 (1 << CRYP_CR_DATATYPE_SHIFT) +#define CRYP_CR_DATATYPE_8 (2 << CRYP_CR_DATATYPE_SHIFT) +#define CRYP_CR_DATATYPE_BIT (3 << CRYP_CR_DATATYPE_SHIFT) + +/* KEYSIZE: Key size selection (AES mode only)*/ +#define CRYP_CR_KEYSIZE_SHIFT 8 +#define CRYP_CR_KEYSIZE (3 << CRYP_CR_KEYSIZE_SHIFT) +#define CRYP_CR_KEYSIZE_128 (0 << CRYP_CR_KEYSIZE_SHIFT) +#define CRYP_CR_KEYSIZE_192 (1 << CRYP_CR_KEYSIZE_SHIFT) +#define CRYP_CR_KEYSIZE_256 (2 << CRYP_CR_KEYSIZE_SHIFT) + +/* FFLUSH: FIFO Flush */ +#define CRYP_CR_FFLUSH (1 << 14) + +/* CRYPEN: Cryptographic processor enable*/ +#define CRYP_CR_CRYPEN (1 << 15) + +/* --- CRYP_SR values ------------------------------------------------------ */ + +/* IFEM: Input FIFO empty */ +#define CRYP_SR_IFEM (1 << 0) + +/* IFNF: Input FIFO not full */ +#define CRYP_SR_IFNF (1 << 1) + +/* OFNE: Output FIFO not empty */ +#define CRYP_SR_OFNE (1 << 2) + +/* OFFU: Output FIFO full */ +#define CRYP_SR_OFFU (1 << 3) + +/* BUSY: Busy bit */ +#define CRYP_SR_BUSY (1 << 4) + +/* --- CRYP_DMACR values --------------------------------------------------- */ + +/* DIEN: DMA input enable */ +#define CRYP_DMACR_DIEN (1 << 0) + +/* DOEN: DMA output enable */ +#define CRYP_DMACR_DOEN (1 << 1) + +/* --- CRYP_IMSCR values --------------------------------------------------- */ + +/* INIM: Input FIFO service interrupt mask */ +#define CRYP_IMSCR_INIM (1 << 0) + +/* OUTIM: Output FIFO service interrupt mask */ +#define CRYP_IMSCR_OUTIM (1 << 1) + +/* --- CRYP_RISR values ---------------------------------------------------- */ + +/* INRIS: Input FIFO service raw interrupt status */ +#define CRYP_RISR_INRIS (1 << 0) + +/* OUTRIS: Output FIFO service raw data */ +#define CRYP_RISR_OUTRIS (1 << 0) + +/* --- CRYP_MISR values ---------------------------------------------------- */ + +/* INMIS: Input FIFO service masked interrupt status */ +#define CRYP_MISR_INMIS (1 << 0) + +/* OUTMIS: Output FIFO service masked interrupt status */ +#define CRYP_MISR_OUTMIS (1 << 0) + +/**@}*/ + +/** @defgroup crypto_api_gen API (Generic) + * + * @brief API for the CRYP controller + * + * @ingroup crypto_defines + */ +/**@{*/ + +enum crypto_mode { + ENCRYPT_TDES_ECB = CRYP_CR_ALGOMODE_TDES_ECB, + ENCRYPT_TDES_CBC = CRYP_CR_ALGOMODE_TDES_CBC, + ENCRYPT_DES_ECB = CRYP_CR_ALGOMODE_DES_ECB, + ENCRYPT_DES_CBC = CRYP_CR_ALGOMODE_DES_CBC, + ENCRYPT_AES_ECB = CRYP_CR_ALGOMODE_AES_ECB, + ENCRYPT_AES_CBC = CRYP_CR_ALGOMODE_AES_CBC, + ENCRYPT_AES_CTR = CRYP_CR_ALGOMODE_AES_CTR, + DECRYPT_TDES_ECB = CRYP_CR_ALGOMODE_TDES_ECB | CRYP_CR_ALGODIR, + DECRYPT_TDES_CBC = CRYP_CR_ALGOMODE_TDES_CBC | CRYP_CR_ALGODIR, + DECRYPT_DES_ECB = CRYP_CR_ALGOMODE_DES_ECB | CRYP_CR_ALGODIR, + DECRYPT_DES_CBC = CRYP_CR_ALGOMODE_DES_CBC | CRYP_CR_ALGODIR, + DECRYPT_AES_ECB = CRYP_CR_ALGOMODE_AES_ECB | CRYP_CR_ALGODIR, + DECRYPT_AES_CBC = CRYP_CR_ALGOMODE_AES_CBC | CRYP_CR_ALGODIR, + DECRYPT_AES_CTR = CRYP_CR_ALGOMODE_AES_CTR,/* XOR is same ENC as DEC */ +}; +enum crypto_keysize { + CRYPTO_KEY_128BIT = 0, + CRYPTO_KEY_192BIT, + CRYPTO_KEY_256BIT, +}; +enum crypto_datatype { + + CRYPTO_DATA_32BIT = 0, + CRYPTO_DATA_16BIT, + CRYPTO_DATA_8BIT, + CRYPTO_DATA_BIT, +}; + +BEGIN_DECLS +void crypto_wait_busy(void); +void crypto_set_key(enum crypto_keysize keysize, uint64_t key[]); +void crypto_set_iv(uint64_t iv[]); +void crypto_set_datatype(enum crypto_datatype datatype); +void crypto_set_algorithm(enum crypto_mode mode); +void crypto_start(void); +void crypto_stop(void); +uint32_t crypto_process_block(uint32_t *inp, uint32_t *outp, uint32_t length); +END_DECLS +/**@}*/ +/**@}*/ +#endif +/** @cond */ +#else +#warning "crypto_common_f24.h should not be included explicitly, " + "only via crypto.h" +#endif +/** @endcond */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dac_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dac_common_all.h new file mode 100644 index 00000000..7a241ab8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dac_common_all.h @@ -0,0 +1,422 @@ +/** @addtogroup dac_defines + +@author @htmlonly © @endhtmlonly 2012 +Felix Held + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA DAC.H +The order of header inclusion is important. dac.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_DAC_H +/** @endcond */ +#ifndef LIBOPENCM3_DAC_COMMON_ALL_H +#define LIBOPENCM3_DAC_COMMON_ALL_H + +/* --- DAC registers ------------------------------------------------------- */ + +/* DAC control register (DAC_CR) */ +#define DAC_CR MMIO32(DAC_BASE + 0x00) + +/* DAC software trigger register (DAC_SWTRIGR) */ +#define DAC_SWTRIGR MMIO32(DAC_BASE + 0x04) + +/* DAC channel1 12-bit right-aligned data holding register (DAC_DHR12R1) */ +#define DAC_DHR12R1 MMIO32(DAC_BASE + 0x08) + +/* DAC channel1 12-bit left aligned data holding register (DAC_DHR12L1) */ +#define DAC_DHR12L1 MMIO32(DAC_BASE + 0x0C) + +/* DAC channel1 8-bit right aligned data holding register (DAC_DHR8R1) */ +#define DAC_DHR8R1 MMIO32(DAC_BASE + 0x10) + +/* DAC channel2 12-bit right aligned data holding register (DAC_DHR12R2) */ +#define DAC_DHR12R2 MMIO32(DAC_BASE + 0x14) + +/* DAC channel2 12-bit left aligned data holding register (DAC_DHR12L2) */ +#define DAC_DHR12L2 MMIO32(DAC_BASE + 0x18) + +/* DAC channel2 8-bit right-aligned data holding register (DAC_DHR8R2) */ +#define DAC_DHR8R2 MMIO32(DAC_BASE + 0x1C) + +/* Dual DAC 12-bit right-aligned data holding register (DAC_DHR12RD) */ +#define DAC_DHR12RD MMIO32(DAC_BASE + 0x20) + +/* DUAL DAC 12-bit left aligned data holding register (DAC_DHR12LD) */ +#define DAC_DHR12LD MMIO32(DAC_BASE + 0x24) + +/* DUAL DAC 8-bit right aligned data holding register (DAC_DHR8RD) */ +#define DAC_DHR8RD MMIO32(DAC_BASE + 0x28) + +/* DAC channel1 data output register (DAC_DOR1) */ +#define DAC_DOR1 MMIO32(DAC_BASE + 0x2C) + +/* DAC channel2 data output register (DAC_DOR2) */ +#define DAC_DOR2 MMIO32(DAC_BASE + 0x30) + + +/* --- DAC_CR values ------------------------------------------------------- */ + +/* DMAUDRIE2: DAC channel2 DMA underrun interrupt enable */ +/* doesn't exist in most members of the STM32F1 family */ +#define DAC_CR_DMAUDRIE2 (1 << 29) + +/* DMAEN2: DAC channel2 DMA enable */ +#define DAC_CR_DMAEN2 (1 << 28) + +/* MAMP2[3:0]: DAC channel2 mask/amplitude selector */ +/* DAC_CR_MAMP2_n: + * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 + */ +#define DAC_CR_MAMP2_SHIFT 24 +/** @defgroup dac_mamp2 DAC Channel 2 LFSR Mask and Triangle Wave Amplitude +values +@ingroup dac_defines + +Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 +@{*/ +#define DAC_CR_MAMP2_1 (0x0 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_2 (0x1 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_3 (0x2 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_4 (0x3 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_5 (0x4 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_6 (0x5 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_7 (0x6 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_8 (0x7 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_9 (0x8 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_10 (0x9 << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_11 (0xA << DAC_CR_MAMP2_SHIFT) +#define DAC_CR_MAMP2_12 (0xB << DAC_CR_MAMP2_SHIFT) +/**@}*/ + +/* WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ +/* Legend: + * DIS: wave generation disabled + * NOISE: Noise wave generation enabled + * TRI: Triangle wave generation enabled + * + * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) + */ +#define DAC_CR_WAVE2_SHIFT 22 +#define DAC_CR_WAVE2_DIS (0x3 << DAC_CR_WAVE2_SHIFT) +/** @defgroup dac_wave2_en DAC Channel 2 Waveform Generation Enable +@ingroup dac_defines + +@li NOISE: Noise wave generation enabled +@li TRI: Triangle wave generation enabled + +@note: only used if bit TEN2 is set (DAC channel2 trigger enabled) +@{*/ +#define DAC_CR_WAVE2_NOISE (0x1 << DAC_CR_WAVE2_SHIFT) +#define DAC_CR_WAVE2_TRI (0x2 << DAC_CR_WAVE2_SHIFT) +/**@}*/ + +/* TSEL2[2:0]: DAC channel2 trigger selection */ +/* Legend: + * + * T6: Timer 6 TRGO event + * T3: Timer 3 TRGO event + * T8: Timer 8 TRGO event + * T7: Timer 7 TRGO event + * T5: Timer 5 TRGO event + * T15: Timer 15 TRGO event + * T2: Timer 2 TRGO event + * T4: Timer 4 TRGO event + * E9: External line9 + * SW: Software trigger + * + * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) + * Note: T3 == T8; T5 == T15; not both present on one device + * Note: this is *not* valid for the STM32L1 family + */ +#define DAC_CR_TSEL2_SHIFT 19 +/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection +@ingroup dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) +@{*/ +#define DAC_CR_TSEL2_T6 (0x0 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T3 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T7 (0x2 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T5 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T15 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T2 (0x4 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_SW (0x7 << DAC_CR_TSEL2_SHIFT) +/**@}*/ + +/* TEN2: DAC channel2 trigger enable */ +#define DAC_CR_TEN2 (1 << 18) + +/* BOFF2: DAC channel2 output buffer disable */ +#define DAC_CR_BOFF2 (1 << 17) + +/* EN2: DAC channel2 enable */ +#define DAC_CR_EN2 (1 << 16) + +/* DMAUDRIE1: DAC channel1 DMA underrun interrupt enable */ +/* doesn't exist in most members of the STM32F1 family */ +#define DAC_CR_DMAUDRIE1 (1 << 13) + +/* DMAEN1: DAC channel1 DMA enable */ +#define DAC_CR_DMAEN1 (1 << 12) + +/* MAMP1[3:0]: DAC channel1 mask/amplitude selector */ +/* DAC_CR_MAMP1_n: + * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 + */ +#define DAC_CR_MAMP1_SHIFT 8 +/** @defgroup dac_mamp1 DAC Channel 1 LFSR Mask and Triangle Wave Amplitude +values +@ingroup dac_defines + +Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 +@{*/ +#define DAC_CR_MAMP1_1 (0x0 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_2 (0x1 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_3 (0x2 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_4 (0x3 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_5 (0x4 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_6 (0x5 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_7 (0x6 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_8 (0x7 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_9 (0x8 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_10 (0x9 << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_11 (0xA << DAC_CR_MAMP1_SHIFT) +#define DAC_CR_MAMP1_12 (0xB << DAC_CR_MAMP1_SHIFT) +/**@}*/ + +/* WAVE1[1:0]: DAC channel1 noise/triangle wave generation enable */ +/* Legend: + * DIS: wave generation disabled + * NOISE: Noise wave generation enabled + * TRI: Triangle wave generation enabled + * + * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) + */ +#define DAC_CR_WAVE1_SHIFT 6 +#define DAC_CR_WAVE1_DIS (0x3 << DAC_CR_WAVE1_SHIFT) +/** @defgroup dac_wave1_en DAC Channel 1 Waveform Generation Enable +@ingroup dac_defines + +@li DIS: wave generation disabled +@li NOISE: Noise wave generation enabled +@li TRI: Triangle wave generation enabled + +@note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) +@{*/ +#define DAC_CR_WAVE1_NOISE (0x1 << DAC_CR_WAVE1_SHIFT) +#define DAC_CR_WAVE1_TRI (0x2 << DAC_CR_WAVE1_SHIFT) +/**@}*/ + +/* TSEL1[2:0]: DAC channel1 trigger selection */ +/* Legend: + * + * T6: Timer 6 TRGO event + * T3: Timer 3 TRGO event in connectivity line devices + * T8: Timer 8 TRGO event in high-density and XL-density devices + * T7: Timer 7 TRGO event + * T5: Timer 5 TRGO event + * T15: Timer 15 TRGO event + * T2: Timer 2 TRGO event + * T4: Timer 4 TRGO event + * E9: External line9 + * SW: Software trigger + * + * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) + * Note: T3 == T8; T5 == T15; not both present on one device + * Note: this is *not* valid for the STM32L1 family + */ +#define DAC_CR_TSEL1_SHIFT 3 +/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection +@ingroup dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line 9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 1 trigger enabled). +@{*/ +#define DAC_CR_TSEL1_T6 (0x0 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T3 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T7 (0x2 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T5 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T15 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T2 (0x4 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_SW (0x7 << DAC_CR_TSEL1_SHIFT) +/**@}*/ + +/* TEN1: DAC channel1 trigger enable */ +#define DAC_CR_TEN1 (1 << 2) + +/* BOFF1: DAC channel1 output buffer disable */ +#define DAC_CR_BOFF1 (1 << 1) + +/* EN1: DAC channel1 enable */ +#define DAC_CR_EN1 (1 << 0) + + +/* --- DAC_SWTRIGR values -------------------------------------------------- */ + +/* SWTRIG2: DAC channel2 software trigger */ +#define DAC_SWTRIGR_SWTRIG2 (1 << 1) + +/* SWTRIG1: DAC channel1 software trigger */ +#define DAC_SWTRIGR_SWTRIG1 (1 << 0) + + +/* --- DAC_DHR12R1 values -------------------------------------------------- */ +#define DAC_DHR12R1_DACC1DHR_LSB (1 << 0) +#define DAC_DHR12R1_DACC1DHR_MSK (0x0FFF << 0) + + +/* --- DAC_DHR12L1 values -------------------------------------------------- */ +#define DAC_DHR12L1_DACC1DHR_LSB (1 << 4) +#define DAC_DHR12L1_DACC1DHR_MSK (0x0FFF << 4) + + +/* --- DAC_DHR8R1 values --------------------------------------------------- */ +#define DAC_DHR8R1_DACC1DHR_LSB (1 << 0) +#define DAC_DHR8R1_DACC1DHR_MSK (0x00FF << 0) + + +/* --- DAC_DHR12R2 values -------------------------------------------------- */ +#define DAC_DHR12R2_DACC2DHR_LSB (1 << 0) +#define DAC_DHR12R2_DACC2DHR_MSK (0x00FFF << 0) + + +/* --- DAC_DHR12L2 values -------------------------------------------------- */ +#define DAC_DHR12L2_DACC2DHR_LSB (1 << 4) +#define DAC_DHR12L2_DACC2DHR_MSK (0x0FFF << 4) + + +/* --- DAC_DHR8R2 values --------------------------------------------------- */ +#define DAC_DHR8R2_DACC2DHR_LSB (1 << 0) +#define DAC_DHR8R2_DACC2DHR_MSK (0x00FF << 0) + + +/* --- DAC_DHR12RD values -------------------------------------------------- */ +#define DAC_DHR12RD_DACC2DHR_LSB (1 << 16) +#define DAC_DHR12RD_DACC2DHR_MSK (0x0FFF << 16) +#define DAC_DHR12RD_DACC1DHR_LSB (1 << 0) +#define DAC_DHR12RD_DACC1DHR_MSK (0x0FFF << 0) + + +/* --- DAC_DHR12LD values -------------------------------------------------- */ +#define DAC_DHR12LD_DACC2DHR_LSB (1 << 16) +#define DAC_DHR12LD_DACC2DHR_MSK (0x0FFF << 20) +#define DAC_DHR12LD_DACC1DHR_LSB (1 << 0) +#define DAC_DHR12LD_DACC1DHR_MSK (0x0FFF << 4) + + +/* --- DAC_DHR8RD values --------------------------------------------------- */ +#define DAC_DHR8RD_DACC2DHR_LSB (1 << 8) +#define DAC_DHR8RD_DACC2DHR_MSK (0x00FF << 8) +#define DAC_DHR8RD_DACC1DHR_LSB (1 << 0) +#define DAC_DHR8RD_DACC1DHR_MSK (0x00FF << 0) + + +/* --- DAC_DOR1 values ----------------------------------------------------- */ +#define DAC_DOR1_DACC1DOR_LSB (1 << 0) +#define DAC_DOR1_DACC1DOR_MSK (0x0FFF << 0) + + +/* --- DAC_DOR2 values ----------------------------------------------------- */ +#define DAC_DOR2_DACC2DOR_LSB (1 << 0) +#define DAC_DOR2_DACC2DOR_MSK (0x0FFF << 0) + +/** DAC channel identifier */ +typedef enum { + CHANNEL_1, CHANNEL_2, CHANNEL_D +} data_channel; + +/** DAC data size (8/12 bits), alignment (right/left) */ +typedef enum { + RIGHT8, RIGHT12, LEFT12 +} data_align; + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void dac_enable(data_channel dac_channel); +void dac_disable(data_channel dac_channel); +void dac_buffer_enable(data_channel dac_channel); +void dac_buffer_disable(data_channel dac_channel); +void dac_dma_enable(data_channel dac_channel); +void dac_dma_disable(data_channel dac_channel); +void dac_trigger_enable(data_channel dac_channel); +void dac_trigger_disable(data_channel dac_channel); +void dac_set_trigger_source(uint32_t dac_trig_src); +void dac_set_waveform_generation(uint32_t dac_wave_ens); +void dac_disable_waveform_generation(data_channel dac_channel); +void dac_set_waveform_characteristics(uint32_t dac_mamp); +void dac_load_data_buffer_single(uint16_t dac_data, data_align dac_data_format, + data_channel dac_channel); +void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, + data_align dac_data_format); +void dac_software_trigger(data_channel dac_channel); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "dac_common_all.h should not be included explicitly, only via dac.h" +#endif +/** @endcond */ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_f24.h new file mode 100644 index 00000000..e32114b1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_f24.h @@ -0,0 +1,626 @@ +/** @addtogroup dma_defines + +@author @htmlonly © @endhtmlonly 2011 +Fergus Noble +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA DMA.H +The order of header inclusion is important. dma.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_DMA_H +/** @endcond */ +#ifndef LIBOPENCM3_DMA_COMMON_F24_H +#define LIBOPENCM3_DMA_COMMON_F24_H + +/**@{*/ + +/* --- Convenience macros -------------------------------------------------- */ + +/* DMA controller base addresses (for convenience) */ +#define DMA1 DMA1_BASE +#define DMA2 DMA2_BASE + +/* DMA stream base addresses (for API parameters) */ +/** @defgroup dma_st_number DMA Stream Number +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_STREAM0 0 +#define DMA_STREAM1 1 +#define DMA_STREAM2 2 +#define DMA_STREAM3 3 +#define DMA_STREAM4 4 +#define DMA_STREAM5 5 +#define DMA_STREAM6 6 +#define DMA_STREAM7 7 +/**@}*/ + +#define DMA_STREAM(port, n) ((port) + 0x10 + (24 * (n))) +#define DMA1_STREAM(n) DMA_STREAM(DMA1, (n)) +#define DMA2_STREAM(n) DMA_STREAM(DMA2, (n)) + +#define DMA1_STREAM0 DMA1_STREAM(0) +#define DMA1_STREAM1 DMA1_STREAM(1) +#define DMA1_STREAM2 DMA1_STREAM(2) +#define DMA1_STREAM3 DMA1_STREAM(3) +#define DMA1_STREAM4 DMA1_STREAM(4) +#define DMA1_STREAM5 DMA1_STREAM(5) +#define DMA1_STREAM6 DMA1_STREAM(6) +#define DMA1_STREAM7 DMA1_STREAM(7) + +#define DMA2_STREAM0 DMA2_STREAM(0) +#define DMA2_STREAM1 DMA2_STREAM(1) +#define DMA2_STREAM2 DMA2_STREAM(2) +#define DMA2_STREAM3 DMA2_STREAM(3) +#define DMA2_STREAM4 DMA2_STREAM(4) +#define DMA2_STREAM5 DMA2_STREAM(5) +#define DMA2_STREAM6 DMA2_STREAM(6) +#define DMA2_STREAM7 DMA2_STREAM(7) + +/* --- DMA controller registers -------------------------------------------- */ + +/* DMA low interrupt status register (DMAx_LISR) */ +#define DMA_LISR(port) MMIO32((port) + 0x00) +#define DMA1_LISR DMA_LISR(DMA1) +#define DMA2_LISR DMA_LISR(DMA2) + +/* DMA high interrupt status register (DMAx_HISR) */ +#define DMA_HISR(port) MMIO32((port) + 0x04) +#define DMA1_HISR DMA_HISR(DMA1) +#define DMA2_HISR DMA_HISR(DMA2) + +/* DMA low interrupt flag clear register (DMAx_LIFCR) */ +#define DMA_LIFCR(port) MMIO32((port) + 0x08) +#define DMA1_LIFCR DMA_LIFCR(DMA1) +#define DMA2_LIFCR DMA_LIFCR(DMA2) + +/* DMA high interrupt flag clear register (DMAx_HIFCR) */ +#define DMA_HIFCR(port) MMIO32((port) + 0x0C) +#define DMA1_HIFCR DMA_HIFCR(DMA1) +#define DMA2_HIFCR DMA_HIFCR(DMA2) + +/* --- DMA stream registers ------------------------------------------------ */ + +/* DMA Stream x configuration register (DMA_SxCR) */ +#define DMA_SCR(port, n) MMIO32(DMA_STREAM((port), (n)) + 0x00) +#define DMA1_SCR(n) DMA_SCR(DMA1, (n)) +#define DMA2_SCR(n) DMA_SCR(DMA2, (n)) + +#define DMA1_S0CR DMA1_SCR(0) +#define DMA1_S1CR DMA1_SCR(1) +#define DMA1_S2CR DMA1_SCR(2) +#define DMA1_S3CR DMA1_SCR(3) +#define DMA1_S4CR DMA1_SCR(4) +#define DMA1_S5CR DMA1_SCR(5) +#define DMA1_S6CR DMA1_SCR(6) +#define DMA1_S7CR DMA1_SCR(7) + +#define DMA2_S0CR DMA2_SCR(0) +#define DMA2_S1CR DMA2_SCR(1) +#define DMA2_S2CR DMA2_SCR(2) +#define DMA2_S3CR DMA2_SCR(3) +#define DMA2_S4CR DMA2_SCR(4) +#define DMA2_S5CR DMA2_SCR(5) +#define DMA2_S6CR DMA2_SCR(6) +#define DMA2_S7CR DMA2_SCR(7) + +/* DMA Stream x number of data register (DMA_SxNDTR) */ +#define DMA_SNDTR(port, n) MMIO32(DMA_STREAM((port), (n)) + 0x04) +#define DMA1_SNDTR(n) DMA_SNDTR(DMA1, (n)) +#define DMA2_SNDTR(n) DMA_SNDTR(DMA2, (n)) + +#define DMA1_S0NDTR DMA1_SNDTR(0) +#define DMA1_S1NDTR DMA1_SNDTR(1) +#define DMA1_S2NDTR DMA1_SNDTR(2) +#define DMA1_S3NDTR DMA1_SNDTR(3) +#define DMA1_S4NDTR DMA1_SNDTR(4) +#define DMA1_S5NDTR DMA1_SNDTR(5) +#define DMA1_S6NDTR DMA1_SNDTR(6) +#define DMA1_S7NDTR DMA1_SNDTR(7) + +#define DMA2_S0NDTR DMA2_SNDTR(0) +#define DMA2_S1NDTR DMA2_SNDTR(1) +#define DMA2_S2NDTR DMA2_SNDTR(2) +#define DMA2_S3NDTR DMA2_SNDTR(3) +#define DMA2_S4NDTR DMA2_SNDTR(4) +#define DMA2_S5NDTR DMA2_SNDTR(5) +#define DMA2_S6NDTR DMA2_SNDTR(6) +#define DMA2_S7NDTR DMA2_SNDTR(7) + +/* DMA Stream x peripheral address register (DMA_SxPAR) */ +#define DMA_SPAR(port, n) (*(volatile void **)\ + (DMA_STREAM((port), (n)) + 0x08)) +#define DMA1_SPAR(n) DMA_SPAR(DMA1, (n)) +#define DMA2_SPAR(n) DMA_SPAR(DMA2, (n)) + +#define DMA1_S0PAR DMA1_SPAR(0) +#define DMA1_S1PAR DMA1_SPAR(1) +#define DMA1_S2PAR DMA1_SPAR(2) +#define DMA1_S3PAR DMA1_SPAR(3) +#define DMA1_S4PAR DMA1_SPAR(4) +#define DMA1_S5PAR DMA1_SPAR(5) +#define DMA1_S6PAR DMA1_SPAR(6) +#define DMA1_S7PAR DMA1_SPAR(7) + +#define DMA2_S0PAR DMA2_SPAR(0) +#define DMA2_S1PAR DMA2_SPAR(1) +#define DMA2_S2PAR DMA2_SPAR(2) +#define DMA2_S3PAR DMA2_SPAR(3) +#define DMA2_S4PAR DMA2_SPAR(4) +#define DMA2_S5PAR DMA2_SPAR(5) +#define DMA2_S6PAR DMA2_SPAR(6) +#define DMA2_S7PAR DMA2_SPAR(7) + +/* DMA Stream x memory address 0 register (DMA_SxM0AR) */ +#define DMA_SM0AR(port, n) (*(volatile void **) \ + (DMA_STREAM((port), (n)) + 0x0c)) +#define DMA1_SM0AR(n) DMA_SM0AR(DMA1, (n)) +#define DMA2_SM0AR(n) DMA_SM0AR(DMA2, (n)) + +#define DMA1_S0M0AR DMA1_SM0AR(0) +#define DMA1_S1M0AR DMA1_SM0AR(1) +#define DMA1_S2M0AR DMA1_SM0AR(2) +#define DMA1_S3M0AR DMA1_SM0AR(3) +#define DMA1_S4M0AR DMA1_SM0AR(4) +#define DMA1_S5M0AR DMA1_SM0AR(5) +#define DMA1_S6M0AR DMA1_SM0AR(6) +#define DMA1_S7M0AR DMA1_SM0AR(7) + +#define DMA2_S0M0AR DMA2_SM0AR(0) +#define DMA2_S1M0AR DMA2_SM0AR(1) +#define DMA2_S2M0AR DMA2_SM0AR(2) +#define DMA2_S3M0AR DMA2_SM0AR(3) +#define DMA2_S4M0AR DMA2_SM0AR(4) +#define DMA2_S5M0AR DMA2_SM0AR(5) +#define DMA2_S6M0AR DMA2_SM0AR(6) +#define DMA2_S7M0AR DMA2_SM0AR(7) + +/* DMA Stream x memory address 1 register (DMA_SxM1AR) */ +#define DMA_SM1AR(port, n) (*(volatile void **)\ + (DMA_STREAM((port), (n)) + 0x10)) +#define DMA1_SM1AR(n) DMA_SM1AR(DMA1, (n)) +#define DMA2_SM1AR(n) DMA_SM1AR(DMA2, (n)) + +#define DMA1_S0M1AR DMA1_SM1AR(0) +#define DMA1_S1M1AR DMA1_SM1AR(1) +#define DMA1_S2M1AR DMA1_SM1AR(2) +#define DMA1_S3M1AR DMA1_SM1AR(3) +#define DMA1_S4M1AR DMA1_SM1AR(4) +#define DMA1_S5M1AR DMA1_SM1AR(5) +#define DMA1_S6M1AR DMA1_SM1AR(6) +#define DMA1_S7M1AR DMA1_SM1AR(7) + +#define DMA2_S0M1AR DMA2_SM1AR(0) +#define DMA2_S1M1AR DMA2_SM1AR(1) +#define DMA2_S2M1AR DMA2_SM1AR(2) +#define DMA2_S3M1AR DMA2_SM1AR(3) +#define DMA2_S4M1AR DMA2_SM1AR(4) +#define DMA2_S5M1AR DMA2_SM1AR(5) +#define DMA2_S6M1AR DMA2_SM1AR(6) +#define DMA2_S7M1AR DMA2_SM1AR(7) + +/* DMA Stream x FIFO control register (DMA_SxFCR) */ +#define DMA_SFCR(port, n) MMIO32(DMA_STREAM((port), (n)) + 0x14) +#define DMA1_SFCR(n) DMA_SFCR(DMA1, (n)) +#define DMA2_SFCR(n) DMA_SFCR(DMA2, (n)) + +#define DMA1_S0FCR DMA1_SFCR(0) +#define DMA1_S1FCR DMA1_SFCR(1) +#define DMA1_S2FCR DMA1_SFCR(2) +#define DMA1_S3FCR DMA1_SFCR(3) +#define DMA1_S4FCR DMA1_SFCR(4) +#define DMA1_S5FCR DMA1_SFCR(5) +#define DMA1_S6FCR DMA1_SFCR(6) +#define DMA1_S7FCR DMA1_SFCR(7) + +#define DMA2_S0FCR DMA2_SFCR(0) +#define DMA2_S1FCR DMA2_SFCR(1) +#define DMA2_S2FCR DMA2_SFCR(2) +#define DMA2_S3FCR DMA2_SFCR(3) +#define DMA2_S4FCR DMA2_SFCR(4) +#define DMA2_S5FCR DMA2_SFCR(5) +#define DMA2_S6FCR DMA2_SFCR(6) +#define DMA2_S7FCR DMA2_SFCR(7) + +/* --- DMA Interrupt Flag offset values ------------------------------------- */ + +/* For API parameters. These are based on every interrupt flag and flag clear +being at the same relative location */ +/** @defgroup dma_if_offset DMA Interrupt Flag Offsets within stream flag group. +@ingroup dma_defines + +@{*/ +/** Transfer Complete Interrupt Flag */ +#define DMA_TCIF (1 << 5) +/** Half Transfer Interrupt Flag */ +#define DMA_HTIF (1 << 4) +/** Transfer Error Interrupt Flag */ +#define DMA_TEIF (1 << 3) +/** Direct Mode Error Interrupt Flag */ +#define DMA_DMEIF (1 << 2) +/** FIFO Error Interrupt Flag */ +#define DMA_FEIF (1 << 0) +/**@}*/ + +/* Offset within interrupt status register to start of stream interrupt flag + * field + */ +#define DMA_ISR_OFFSET(stream) (6*((stream) & 0x01)+16*(((stream) & 0x02) >> 1)) +#define DMA_ISR_FLAGS (DMA_TCIF | DMA_HTIF | DMA_TEIF | DMA_DMEIF | \ + DMA_FEIF) +#define DMA_ISR_MASK(stream) (DMA_ISR_FLAGS << DMA_ISR_OFFSET(stream)) + +/* --- DMA_LISR values ----------------------------------------------------- */ + +#define DMA_LISR_FEIF0 (1 << 0) +#define DMA_LISR_DMEIF0 (1 << 2) +#define DMA_LISR_TEIF0 (1 << 3) +#define DMA_LISR_HTIF0 (1 << 4) +#define DMA_LISR_TCIF0 (1 << 5) + +#define DMA_LISR_FEIF1 (1 << 6) +#define DMA_LISR_DMEIF1 (1 << 8) +#define DMA_LISR_TEIF1 (1 << 9) +#define DMA_LISR_HTIF1 (1 << 10) +#define DMA_LISR_TCIF1 (1 << 11) + +#define DMA_LISR_FEIF2 (1 << 16) +#define DMA_LISR_DMEIF2 (1 << 18) +#define DMA_LISR_TEIF2 (1 << 19) +#define DMA_LISR_HTIF2 (1 << 20) +#define DMA_LISR_TCIF2 (1 << 21) + +#define DMA_LISR_FEIF3 (1 << 22) +#define DMA_LISR_DMEIF3 (1 << 24) +#define DMA_LISR_TEIF3 (1 << 25) +#define DMA_LISR_HTIF3 (1 << 26) +#define DMA_LISR_TCIF3 (1 << 27) + +/* --- DMA_HISR values ----------------------------------------------------- */ + +#define DMA_HISR_FEIF4 (1 << 0) +#define DMA_HISR_DMEIF4 (1 << 2) +#define DMA_HISR_TEIF4 (1 << 3) +#define DMA_HISR_HTIF4 (1 << 4) +#define DMA_HISR_TCIF4 (1 << 5) + +#define DMA_HISR_FEIF5 (1 << 6) +#define DMA_HISR_DMEIF5 (1 << 8) +#define DMA_HISR_TEIF5 (1 << 9) +#define DMA_HISR_HTIF5 (1 << 10) +#define DMA_HISR_TCIF5 (1 << 11) + +#define DMA_HISR_FEIF6 (1 << 16) +#define DMA_HISR_DMEIF6 (1 << 18) +#define DMA_HISR_TEIF6 (1 << 19) +#define DMA_HISR_HTIF6 (1 << 20) +#define DMA_HISR_TCIF6 (1 << 21) + +#define DMA_HISR_FEIF7 (1 << 22) +#define DMA_HISR_DMEIF7 (1 << 24) +#define DMA_HISR_TEIF7 (1 << 25) +#define DMA_HISR_HTIF7 (1 << 26) +#define DMA_HISR_TCIF7 (1 << 27) + +/* --- DMA_LIFCR values ----------------------------------------------------- */ + +#define DMA_LIFCR_CFEIF0 (1 << 0) +#define DMA_LIFCR_CDMEIF0 (1 << 2) +#define DMA_LIFCR_CTEIF0 (1 << 3) +#define DMA_LIFCR_CHTIF0 (1 << 4) +#define DMA_LIFCR_CTCIF0 (1 << 5) + +#define DMA_LIFCR_CFEIF1 (1 << 6) +#define DMA_LIFCR_CDMEIF1 (1 << 8) +#define DMA_LIFCR_CTEIF1 (1 << 9) +#define DMA_LIFCR_CHTIF1 (1 << 10) +#define DMA_LIFCR_CTCIF1 (1 << 11) + +#define DMA_LIFCR_CFEIF2 (1 << 16) +#define DMA_LIFCR_CDMEIF2 (1 << 18) +#define DMA_LIFCR_CTEIF2 (1 << 19) +#define DMA_LIFCR_CHTIF2 (1 << 20) +#define DMA_LIFCR_CTCIF2 (1 << 21) + +#define DMA_LIFCR_CFEIF3 (1 << 22) +#define DMA_LIFCR_CDMEIF3 (1 << 24) +#define DMA_LIFCR_CTEIF3 (1 << 25) +#define DMA_LIFCR_CHTIF3 (1 << 26) +#define DMA_LIFCR_CTCIF3 (1 << 27) + +/* --- DMA_HIFCR values ----------------------------------------------------- */ + +#define DMA_HIFCR_CFEIF4 (1 << 0) +#define DMA_HIFCR_CDMEIF4 (1 << 2) +#define DMA_HIFCR_CTEIF4 (1 << 3) +#define DMA_HIFCR_CHTIF4 (1 << 4) +#define DMA_HIFCR_CTCIF4 (1 << 5) + +#define DMA_HIFCR_CFEIF5 (1 << 6) +#define DMA_HIFCR_CDMEIF5 (1 << 8) +#define DMA_HIFCR_CTEIF5 (1 << 9) +#define DMA_HIFCR_CHTIF5 (1 << 10) +#define DMA_HIFCR_CTCIF5 (1 << 11) + +#define DMA_HIFCR_CFEIF6 (1 << 16) +#define DMA_HIFCR_CDMEIF6 (1 << 18) +#define DMA_HIFCR_CTEIF6 (1 << 19) +#define DMA_HIFCR_CHTIF6 (1 << 20) +#define DMA_HIFCR_CTCIF6 (1 << 21) + +#define DMA_HIFCR_CFEIF7 (1 << 22) +#define DMA_HIFCR_CDMEIF7 (1 << 24) +#define DMA_HIFCR_CTEIF7 (1 << 25) +#define DMA_HIFCR_CHTIF7 (1 << 26) +#define DMA_HIFCR_CTCIF7 (1 << 27) + +/* --- DMA_SxCR values ----------------------------------------------------- */ + +/* EN: Stream enable */ +#define DMA_SxCR_EN (1 << 0) +/* DMEIE: Direct Mode error interrupt enable */ +#define DMA_SxCR_DMEIE (1 << 1) +/* TEIE: Transfer error interrupt enable */ +#define DMA_SxCR_TEIE (1 << 2) +/* HTIE: Half transfer interrupt enable */ +#define DMA_SxCR_HTIE (1 << 3) +/* TCIE: Transfer complete interrupt enable */ +#define DMA_SxCR_TCIE (1 << 4) +/* PFCTRL: Peripheral Flow Controller */ +#define DMA_SxCR_PFCTRL (1 << 5) + +/* DIR[7:6]: Data transfer direction */ +/** @defgroup dma_st_dir DMA Stream Data transfer direction +@ingroup dma_defines + +@{*/ +#define DMA_SxCR_DIR_PERIPHERAL_TO_MEM (0 << 6) +#define DMA_SxCR_DIR_MEM_TO_PERIPHERAL (1 << 6) +#define DMA_SxCR_DIR_MEM_TO_MEM (2 << 6) +/**@}*/ +#define DMA_SxCR_DIR_SHIFT 6 +#define DMA_SxCR_DIR_MASK (3 << 6) + +/* CIRC: Circular mode */ +#define DMA_SxCR_CIRC (1 << 8) +/* PINC: Peripheral increment mode */ +#define DMA_SxCR_PINC (1 << 9) +/* MINC: Memory increment mode */ +#define DMA_SxCR_MINC (1 << 10) + +/* PSIZE[12:11]: Peripheral size */ +/** @defgroup dma_st_perwidth DMA Stream Peripheral Word Width +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SxCR_PSIZE_8BIT (0 << 11) +#define DMA_SxCR_PSIZE_16BIT (1 << 11) +#define DMA_SxCR_PSIZE_32BIT (2 << 11) +/**@}*/ +#define DMA_SxCR_PSIZE_SHIFT 11 +#define DMA_SxCR_PSIZE_MASK (3 << 11) + +/* MSIZE[14:13]: Memory size */ +/** @defgroup dma_st_memwidth DMA Stream Memory Word Width +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SxCR_MSIZE_8BIT (0 << 13) +#define DMA_SxCR_MSIZE_16BIT (1 << 13) +#define DMA_SxCR_MSIZE_32BIT (2 << 13) +/**@}*/ +#define DMA_SxCR_MSIZE_SHIFT 13 +#define DMA_SxCR_MSIZE_MASK (3 << 13) + +/* PINCOS: Peripheral increment offset size */ +#define DMA_SxCR_PINCOS (1 << 15) + +/* PL[17:16]: Stream priority level */ +/** @defgroup dma_st_pri DMA Stream Priority Levels +@ingroup dma_defines + +@{*/ +#define DMA_SxCR_PL_LOW (0 << 16) +#define DMA_SxCR_PL_MEDIUM (1 << 16) +#define DMA_SxCR_PL_HIGH (2 << 16) +#define DMA_SxCR_PL_VERY_HIGH (3 << 16) +/**@}*/ +#define DMA_SxCR_PL_SHIFT 16 +#define DMA_SxCR_PL_MASK (3 << 16) + +/* DBM: Double buffered mode */ +#define DMA_SxCR_DBM (1 << 18) +/* CT: Current target (in double buffered mode) */ +#define DMA_SxCR_CT (1 << 19) + +/* Bit 20 reserved */ + +/* PBURST[13:12]: Peripheral Burst Configuration */ +/** @defgroup dma_pburst DMA Peripheral Burst Length +@ingroup dma_defines + +@{*/ +#define DMA_SxCR_PBURST_SINGLE (0 << 21) +#define DMA_SxCR_PBURST_INCR4 (1 << 21) +#define DMA_SxCR_PBURST_INCR8 (2 << 21) +#define DMA_SxCR_PBURST_INCR16 (3 << 21) +/**@}*/ +#define DMA_SxCR_PBURST_SHIFT 21 +#define DMA_SxCR_PBURST_MASK (3 << 21) + +/* MBURST[13:12]: Memory Burst Configuration */ +/** @defgroup dma_mburst DMA Memory Burst Length +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SxCR_MBURST_SINGLE (0 << 23) +#define DMA_SxCR_MBURST_INCR4 (1 << 23) +#define DMA_SxCR_MBURST_INCR8 (2 << 23) +#define DMA_SxCR_MBURST_INCR16 (3 << 23) +/**@}*/ +#define DMA_SxCR_MBURST_SHIFT 23 +#define DMA_SxCR_MBURST_MASK (3 << 23) + +/* CHSEL[25:27]: Channel Select */ +/** @defgroup dma_ch_sel DMA Channel Select +@ingroup dma_defines + +@{*/ +#define DMA_SxCR_CHSEL_0 (0 << DMA_SxCR_CHSEL_SHIFT) +#define DMA_SxCR_CHSEL_1 (1 << DMA_SxCR_CHSEL_SHIFT) +#define DMA_SxCR_CHSEL_2 (2 << DMA_SxCR_CHSEL_SHIFT) +#define DMA_SxCR_CHSEL_3 (3 << DMA_SxCR_CHSEL_SHIFT) +#define DMA_SxCR_CHSEL_4 (4 << DMA_SxCR_CHSEL_SHIFT) +#define DMA_SxCR_CHSEL_5 (5 << DMA_SxCR_CHSEL_SHIFT) +#define DMA_SxCR_CHSEL_6 (6 << DMA_SxCR_CHSEL_SHIFT) +#define DMA_SxCR_CHSEL_7 (7 << DMA_SxCR_CHSEL_SHIFT) +/**@}*/ +#define DMA_SxCR_CHSEL_SHIFT 25 +#define DMA_SxCR_CHSEL_MASK (7 << 25) +#define DMA_SxCR_CHSEL(n) ((n) << DMA_SxCR_CHSEL_SHIFT) + +/* Reserved [31:28] */ + +/* --- DMA_SxNDTR values --------------------------------------------------- */ + +/* DMA_SxNDTR[15:0]: Number of data register. */ + +/* --- DMA_SxPAR values ---------------------------------------------------- */ + +/* DMA_SxPAR[31:0]: Peripheral address register. */ + +/* --- DMA_SxM0AR values --------------------------------------------------- */ + +/* DMA_SxM0AR[31:0]: Memory 0 address register. */ + +/* --- DMA_SxM1AR values --------------------------------------------------- */ + +/* DMA_SxM1AR[31:0]: Memory 1 address register. */ + +/* --- DMA_SxFCR values ---------------------------------------------------- */ + +/* FTH[1:0]: FIFO Threshold selection */ +/** @defgroup dma_fifo_thresh FIFO Threshold selection +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SxFCR_FTH_1_4_FULL (0 << 0) +#define DMA_SxFCR_FTH_2_4_FULL (1 << 0) +#define DMA_SxFCR_FTH_3_4_FULL (2 << 0) +#define DMA_SxFCR_FTH_4_4_FULL (3 << 0) +/**@}*/ +#define DMA_SxFCR_FTH_SHIFT 0 +#define DMA_SxFCR_FTH_MASK (3 << 0) + +/* DMDIS: Direct Mode disable */ +#define DMA_SxFCR_DMDIS (1 << 2) + +/* FS[5:3]: FIFO Status */ +/** @defgroup dma_fifo_status FIFO Status +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SxFCR_FS_LT_1_4_FULL (0 << 0) +#define DMA_SxFCR_FS_LT_2_4_FULL (1 << 0) +#define DMA_SxFCR_FS_LT_3_4_FULL (2 << 0) +#define DMA_SxFCR_FS_LT_4_4_FULL (3 << 0) +#define DMA_SxFCR_FS_FULL (4 << 3) +#define DMA_SxFCR_FS_EMPTY (5 << 3) +/**@}*/ +#define DMA_SxFCR_FS_SHIFT 3 +#define DMA_SxFCR_FS_MASK (7 << 3) + +/* [6]: reserved */ + +/* FEIE[7]: FIFO error interrupt enable */ +#define DMA_SxFCR_FEIE (1 << 7) + +/* [31:8]: Reserved */ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +/* + * Note: The F2 and F4 series have a completely new DMA peripheral with + * different configuration options. + */ + +void dma_stream_reset(uint32_t dma, uint8_t stream); +void dma_clear_interrupt_flags(uint32_t dma, uint8_t stream, + uint32_t interrupts); +bool dma_get_interrupt_flag(uint32_t dma, uint8_t stream, uint32_t interrupt); +void dma_set_transfer_mode(uint32_t dma, uint8_t stream, uint32_t direction); +void dma_set_priority(uint32_t dma, uint8_t stream, uint32_t prio); +void dma_set_memory_size(uint32_t dma, uint8_t stream, uint32_t mem_size); +void dma_set_peripheral_size(uint32_t dma, uint8_t stream, + uint32_t peripheral_size); +void dma_enable_memory_increment_mode(uint32_t dma, uint8_t stream); +void dma_disable_memory_increment_mode(uint32_t dma, uint8_t channel); +void dma_enable_peripheral_increment_mode(uint32_t dma, uint8_t stream); +void dma_disable_peripheral_increment_mode(uint32_t dma, uint8_t channel); +void dma_enable_fixed_peripheral_increment_mode(uint32_t dma, uint8_t stream); +void dma_enable_circular_mode(uint32_t dma, uint8_t stream); +void dma_channel_select(uint32_t dma, uint8_t stream, uint32_t channel); +void dma_set_memory_burst(uint32_t dma, uint8_t stream, uint32_t burst); +void dma_set_peripheral_burst(uint32_t dma, uint8_t stream, uint32_t burst); +void dma_set_initial_target(uint32_t dma, uint8_t stream, uint8_t memory); +uint8_t dma_get_target(uint32_t dma, uint8_t stream); +void dma_enable_double_buffer_mode(uint32_t dma, uint8_t stream); +void dma_disable_double_buffer_mode(uint32_t dma, uint8_t stream); +void dma_set_peripheral_flow_control(uint32_t dma, uint8_t stream); +void dma_set_dma_flow_control(uint32_t dma, uint8_t stream); +void dma_enable_transfer_error_interrupt(uint32_t dma, uint8_t stream); +void dma_disable_transfer_error_interrupt(uint32_t dma, uint8_t stream); +void dma_enable_half_transfer_interrupt(uint32_t dma, uint8_t stream); +void dma_disable_half_transfer_interrupt(uint32_t dma, uint8_t stream); +void dma_enable_transfer_complete_interrupt(uint32_t dma, uint8_t stream); +void dma_disable_transfer_complete_interrupt(uint32_t dma, uint8_t stream); +uint32_t dma_fifo_status(uint32_t dma, uint8_t stream); +void dma_enable_direct_mode_error_interrupt(uint32_t dma, uint8_t stream); +void dma_disable_direct_mode_error_interrupt(uint32_t dma, uint8_t stream); +void dma_enable_fifo_error_interrupt(uint32_t dma, uint8_t stream); +void dma_disable_fifo_error_interrupt(uint32_t dma, uint8_t stream); +void dma_enable_direct_mode(uint32_t dma, uint8_t stream); +void dma_enable_fifo_mode(uint32_t dma, uint8_t stream); +void dma_set_fifo_threshold(uint32_t dma, uint8_t stream, uint32_t threshold); +void dma_enable_stream(uint32_t dma, uint8_t stream); +void dma_disable_stream(uint32_t dma, uint8_t stream); +void dma_set_peripheral_address(uint32_t dma, uint8_t stream, uint32_t address); +void dma_set_memory_address(uint32_t dma, uint8_t stream, uint32_t address); +void dma_set_memory_address_1(uint32_t dma, uint8_t stream, uint32_t address); +void dma_set_number_of_data(uint32_t dma, uint8_t stream, uint16_t number); + +END_DECLS +/**@}*/ +#endif +/** @cond */ +#else +#warning "dma_common_f24.h should not be included explicitly, only via dma.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_l1f013.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_l1f013.h new file mode 100644 index 00000000..a00834ab --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/dma_common_l1f013.h @@ -0,0 +1,425 @@ +/** @addtogroup dma_defines + +@author @htmlonly © @endhtmlonly 2010 +Thomas Otto +@author @htmlonly © @endhtmlonly 2012 +Piotr Esden-Tempski + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA DMA.H +The order of header inclusion is important. dma.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_DMA_H +/** @endcond */ +#ifndef LIBOPENCM3_DMA_COMMON_F13_H +#define LIBOPENCM3_DMA_COMMON_F13_H + +/* --- Convenience macros -------------------------------------------------- */ + +/* DMA register base adresses (for convenience) */ +#define DMA1 DMA1_BASE +#define DMA2 DMA2_BASE + +/* --- DMA registers ------------------------------------------------------- */ + +/* DMA interrupt status register (DMAx_ISR) */ +#define DMA_ISR(dma_base) MMIO32((dma_base) + 0x00) +#define DMA1_ISR DMA_ISR(DMA1) +#define DMA2_ISR DMA_ISR(DMA2) + +/* DMA interrupt flag clear register (DMAx_IFCR) */ +#define DMA_IFCR(dma_base) MMIO32((dma_base) + 0x04) +#define DMA1_IFCR DMA_IFCR(DMA1) +#define DMA2_IFCR DMA_IFCR(DMA2) + +/* DMA channel configuration register (DMAx_CCRy) */ +#define DMA_CCR(dma_base, channel) MMIO32((dma_base) + 0x08 + \ + (0x14 * ((channel) - 1))) + +#define DMA1_CCR(channel) DMA_CCR(DMA1, channel) +#define DMA1_CCR1 DMA1_CCR(DMA_CHANNEL1) +#define DMA1_CCR2 DMA1_CCR(DMA_CHANNEL2) +#define DMA1_CCR3 DMA1_CCR(DMA_CHANNEL3) +#define DMA1_CCR4 DMA1_CCR(DMA_CHANNEL4) +#define DMA1_CCR5 DMA1_CCR(DMA_CHANNEL5) +#define DMA1_CCR6 DMA1_CCR(DMA_CHANNEL6) +#define DMA1_CCR7 DMA1_CCR(DMA_CHANNEL7) + +#define DMA2_CCR(channel) DMA_CCR(DMA2, channel) +#define DMA2_CCR1 DMA2_CCR(DMA_CHANNEL1) +#define DMA2_CCR2 DMA2_CCR(DMA_CHANNEL2) +#define DMA2_CCR3 DMA2_CCR(DMA_CHANNEL3) +#define DMA2_CCR4 DMA2_CCR(DMA_CHANNEL4) +#define DMA2_CCR5 DMA2_CCR(DMA_CHANNEL5) + +/* DMA number of data register (DMAx_CNDTRy) */ +#define DMA_CNDTR(dma_base, channel) MMIO32((dma_base) + 0x0C + \ + (0x14 * ((channel) - 1))) + +#define DMA1_CNDTR(channel) DMA_CNDTR(DMA1, channel) +#define DMA1_CNDTR1 DMA1_CNDTR(DMA_CHANNEL1) +#define DMA1_CNDTR2 DMA1_CNDTR(DMA_CHANNEL2) +#define DMA1_CNDTR3 DMA1_CNDTR(DMA_CHANNEL3) +#define DMA1_CNDTR4 DMA1_CNDTR(DMA_CHANNEL4) +#define DMA1_CNDTR5 DMA1_CNDTR(DMA_CHANNEL5) +#define DMA1_CNDTR6 DMA1_CNDTR(DMA_CHANNEL6) +#define DMA1_CNDTR7 DMA1_CNDTR(DMA_CHANNEL7) + +#define DMA2_CNDTR(channel) DMA_CNDTR(DMA2, channel) +#define DMA2_CNDTR1 DMA2_CNDTR(DMA_CHANNEL1) +#define DMA2_CNDTR2 DMA2_CNDTR(DMA_CHANNEL2) +#define DMA2_CNDTR3 DMA2_CNDTR(DMA_CHANNEL3) +#define DMA2_CNDTR4 DMA2_CNDTR(DMA_CHANNEL4) +#define DMA2_CNDTR5 DMA2_CNDTR(DMA_CHANNEL5) + +/* DMA peripheral address register (DMAx_CPARy) */ +#define DMA_CPAR(dma_base, channel) MMIO32((dma_base) + 0x10 + \ + (0x14 * ((channel) - 1))) + +#define DMA1_CPAR(channel) DMA_CPAR(DMA1, channel) +#define DMA1_CPAR1 DMA1_CPAR(DMA_CHANNEL1) +#define DMA1_CPAR2 DMA1_CPAR(DMA_CHANNEL2) +#define DMA1_CPAR3 DMA1_CPAR(DMA_CHANNEL3) +#define DMA1_CPAR4 DMA1_CPAR(DMA_CHANNEL4) +#define DMA1_CPAR5 DMA1_CPAR(DMA_CHANNEL5) +#define DMA1_CPAR6 DMA1_CPAR(DMA_CHANNEL6) +#define DMA1_CPAR7 DMA1_CPAR(DMA_CHANNEL7) + +#define DMA2_CPAR(channel) DMA_CPAR(DMA2, channel) +#define DMA2_CPAR1 DMA2_CPAR(DMA_CHANNEL1) +#define DMA2_CPAR2 DMA2_CPAR(DMA_CHANNEL2) +#define DMA2_CPAR3 DMA2_CPAR(DMA_CHANNEL3) +#define DMA2_CPAR4 DMA2_CPAR(DMA_CHANNEL4) +#define DMA2_CPAR5 DMA2_CPAR(DMA_CHANNEL5) + +/* DMA memory address register (DMAx_CMARy) */ + +#define DMA_CMAR(dma_base, channel) MMIO32((dma_base) + 0x14 + \ + (0x14 * ((channel) - 1))) + +#define DMA1_CMAR(channel) DMA_CMAR(DMA1, channel) +#define DMA1_CMAR1 DMA1_CMAR(DMA_CHANNEL1) +#define DMA1_CMAR2 DMA1_CMAR(DMA_CHANNEL2) +#define DMA1_CMAR3 DMA1_CMAR(DMA_CHANNEL3) +#define DMA1_CMAR4 DMA1_CMAR(DMA_CHANNEL4) +#define DMA1_CMAR5 DMA1_CMAR(DMA_CHANNEL5) +#define DMA1_CMAR6 DMA1_CMAR(DMA_CHANNEL6) +#define DMA1_CMAR7 DMA1_CMAR(DMA_CHANNEL7) + +#define DMA2_CMAR(channel) DMA_CMAR(DMA2, channel) +#define DMA2_CMAR1 DMA2_CMAR(DMA_CHANNEL1) +#define DMA2_CMAR2 DMA2_CMAR(DMA_CHANNEL2) +#define DMA2_CMAR3 DMA2_CMAR(DMA_CHANNEL3) +#define DMA2_CMAR4 DMA2_CMAR(DMA_CHANNEL4) +#define DMA2_CMAR5 DMA2_CMAR(DMA_CHANNEL5) + +/* --- DMA_ISR values ------------------------------------------------------ */ + +/* --- DMA Interrupt Flag offset values ------------------------------------- */ +/* These are based on every interrupt flag and flag clear being at the same + * relative location + */ +/** @defgroup dma_if_offset DMA Interrupt Flag Offsets within channel flag +group. +@ingroup dma_defines + +@{*/ +/** Transfer Error Interrupt Flag */ +#define DMA_TEIF (1 << 3) +/** Half Transfer Interrupt Flag */ +#define DMA_HTIF (1 << 2) +/** Transfer Complete Interrupt Flag */ +#define DMA_TCIF (1 << 1) +/** Global Interrupt Flag */ +#define DMA_GIF (1 << 0) +/**@}*/ + +/* Offset within interrupt status register to start of channel interrupt flag + * field + */ +#define DMA_FLAG_OFFSET(channel) (4*((channel) - 1)) +#define DMA_FLAGS (DMA_TEIF | DMA_TCIF | DMA_HTIF | \ + DMA_GIF) +#define DMA_ISR_MASK(channel) (DMA_FLAGS << DMA_FLAG_OFFSET(channel)) + +/* TEIF: Transfer error interrupt flag */ +#define DMA_ISR_TEIF_BIT DMA_TEIF +#define DMA_ISR_TEIF(channel) (DMA_ISR_TEIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_ISR_TEIF1 DMA_ISR_TEIF(DMA_CHANNEL1) +#define DMA_ISR_TEIF2 DMA_ISR_TEIF(DMA_CHANNEL2) +#define DMA_ISR_TEIF3 DMA_ISR_TEIF(DMA_CHANNEL3) +#define DMA_ISR_TEIF4 DMA_ISR_TEIF(DMA_CHANNEL4) +#define DMA_ISR_TEIF5 DMA_ISR_TEIF(DMA_CHANNEL5) +#define DMA_ISR_TEIF6 DMA_ISR_TEIF(DMA_CHANNEL6) +#define DMA_ISR_TEIF7 DMA_ISR_TEIF(DMA_CHANNEL7) + +/* HTIF: Half transfer interrupt flag */ +#define DMA_ISR_HTIF_BIT DMA_HTIF +#define DMA_ISR_HTIF(channel) (DMA_ISR_HTIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_ISR_HTIF1 DMA_ISR_HTIF(DMA_CHANNEL1) +#define DMA_ISR_HTIF2 DMA_ISR_HTIF(DMA_CHANNEL2) +#define DMA_ISR_HTIF3 DMA_ISR_HTIF(DMA_CHANNEL3) +#define DMA_ISR_HTIF4 DMA_ISR_HTIF(DMA_CHANNEL4) +#define DMA_ISR_HTIF5 DMA_ISR_HTIF(DMA_CHANNEL5) +#define DMA_ISR_HTIF6 DMA_ISR_HTIF(DMA_CHANNEL6) +#define DMA_ISR_HTIF7 DMA_ISR_HTIF(DMA_CHANNEL7) + +/* TCIF: Transfer complete interrupt flag */ +#define DMA_ISR_TCIF_BIT DMA_TCIF +#define DMA_ISR_TCIF(channel) (DMA_ISR_TCIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_ISR_TCIF1 DMA_ISR_TCIF(DMA_CHANNEL1) +#define DMA_ISR_TCIF2 DMA_ISR_TCIF(DMA_CHANNEL2) +#define DMA_ISR_TCIF3 DMA_ISR_TCIF(DMA_CHANNEL3) +#define DMA_ISR_TCIF4 DMA_ISR_TCIF(DMA_CHANNEL4) +#define DMA_ISR_TCIF5 DMA_ISR_TCIF(DMA_CHANNEL5) +#define DMA_ISR_TCIF6 DMA_ISR_TCIF(DMA_CHANNEL6) +#define DMA_ISR_TCIF7 DMA_ISR_TCIF(DMA_CHANNEL7) + +/* GIF: Global interrupt flag */ +#define DMA_ISR_GIF_BIT DMA_GIF +#define DMA_ISR_GIF(channel) (DMA_ISR_GIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_ISR_GIF1 DMA_ISR_GIF(DMA_CHANNEL1) +#define DMA_ISR_GIF2 DMA_ISR_GIF(DMA_CHANNEL2) +#define DMA_ISR_GIF3 DMA_ISR_GIF(DMA_CHANNEL3) +#define DMA_ISR_GIF4 DMA_ISR_GIF(DMA_CHANNEL4) +#define DMA_ISR_GIF5 DMA_ISR_GIF(DMA_CHANNEL5) +#define DMA_ISR_GIF6 DMA_ISR_GIF(DMA_CHANNEL6) +#define DMA_ISR_GIF7 DMA_ISR_GIF(DMA_CHANNEL7) + +/* --- DMA_IFCR values ----------------------------------------------------- */ + +/* CTEIF: Transfer error clear */ +#define DMA_IFCR_CTEIF_BIT DMA_TEIF +#define DMA_IFCR_CTEIF(channel) (DMA_IFCR_CTEIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_IFCR_CTEIF1 DMA_IFCR_CTEIF(DMA_CHANNEL1) +#define DMA_IFCR_CTEIF2 DMA_IFCR_CTEIF(DMA_CHANNEL2) +#define DMA_IFCR_CTEIF3 DMA_IFCR_CTEIF(DMA_CHANNEL3) +#define DMA_IFCR_CTEIF4 DMA_IFCR_CTEIF(DMA_CHANNEL4) +#define DMA_IFCR_CTEIF5 DMA_IFCR_CTEIF(DMA_CHANNEL5) +#define DMA_IFCR_CTEIF6 DMA_IFCR_CTEIF(DMA_CHANNEL6) +#define DMA_IFCR_CTEIF7 DMA_IFCR_CTEIF(DMA_CHANNEL7) + +/* CHTIF: Half transfer clear */ +#define DMA_IFCR_CHTIF_BIT DMA_HTIF +#define DMA_IFCR_CHTIF(channel) (DMA_IFCR_CHTIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_IFCR_CHTIF1 DMA_IFCR_CHTIF(DMA_CHANNEL1) +#define DMA_IFCR_CHTIF2 DMA_IFCR_CHTIF(DMA_CHANNEL2) +#define DMA_IFCR_CHTIF3 DMA_IFCR_CHTIF(DMA_CHANNEL3) +#define DMA_IFCR_CHTIF4 DMA_IFCR_CHTIF(DMA_CHANNEL4) +#define DMA_IFCR_CHTIF5 DMA_IFCR_CHTIF(DMA_CHANNEL5) +#define DMA_IFCR_CHTIF6 DMA_IFCR_CHTIF(DMA_CHANNEL6) +#define DMA_IFCR_CHTIF7 DMA_IFCR_CHTIF(DMA_CHANNEL7) + +/* CTCIF: Transfer complete clear */ +#define DMA_IFCR_CTCIF_BIT DMA_TCIF +#define DMA_IFCR_CTCIF(channel) (DMA_IFCR_CTCIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_IFCR_CTCIF1 DMA_IFCR_CTCIF(DMA_CHANNEL1) +#define DMA_IFCR_CTCIF2 DMA_IFCR_CTCIF(DMA_CHANNEL2) +#define DMA_IFCR_CTCIF3 DMA_IFCR_CTCIF(DMA_CHANNEL3) +#define DMA_IFCR_CTCIF4 DMA_IFCR_CTCIF(DMA_CHANNEL4) +#define DMA_IFCR_CTCIF5 DMA_IFCR_CTCIF(DMA_CHANNEL5) +#define DMA_IFCR_CTCIF6 DMA_IFCR_CTCIF(DMA_CHANNEL6) +#define DMA_IFCR_CTCIF7 DMA_IFCR_CTCIF(DMA_CHANNEL7) + +/* CGIF: Global interrupt clear */ +#define DMA_IFCR_CGIF_BIT DMA_GIF +#define DMA_IFCR_CGIF(channel) (DMA_IFCR_CGIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_IFCR_CGIF1 DMA_IFCR_CGIF(DMA_CHANNEL1) +#define DMA_IFCR_CGIF2 DMA_IFCR_CGIF(DMA_CHANNEL2) +#define DMA_IFCR_CGIF3 DMA_IFCR_CGIF(DMA_CHANNEL3) +#define DMA_IFCR_CGIF4 DMA_IFCR_CGIF(DMA_CHANNEL4) +#define DMA_IFCR_CGIF5 DMA_IFCR_CGIF(DMA_CHANNEL5) +#define DMA_IFCR_CGIF6 DMA_IFCR_CGIF(DMA_CHANNEL6) +#define DMA_IFCR_CGIF7 DMA_IFCR_CGIF(DMA_CHANNEL7) + +/* Clear interrupts mask */ +#define DMA_IFCR_CIF_BIT 0xF +#define DMA_IFCR_CIF(channel) (DMA_IFCR_CIF_BIT << \ + (DMA_FLAG_OFFSET(channel))) + +#define DMA_IFCR_CIF1 DMA_IFCR_CIF(DMA_CHANNEL1) +#define DMA_IFCR_CIF2 DMA_IFCR_CIF(DMA_CHANNEL2) +#define DMA_IFCR_CIF3 DMA_IFCR_CIF(DMA_CHANNEL3) +#define DMA_IFCR_CIF4 DMA_IFCR_CIF(DMA_CHANNEL4) +#define DMA_IFCR_CIF5 DMA_IFCR_CIF(DMA_CHANNEL5) +#define DMA_IFCR_CIF6 DMA_IFCR_CIF(DMA_CHANNEL6) +#define DMA_IFCR_CIF7 DMA_IFCR_CIF(DMA_CHANNEL7) + +/* --- DMA_CCRx generic values --------------------------------------------- */ + +/* MEM2MEM: Memory to memory mode */ +#define DMA_CCR_MEM2MEM (1 << 14) + +/* PL[13:12]: Channel priority level */ +/** @defgroup dma_ch_pri DMA Channel Priority Levels +@ingroup dma_defines + +@{*/ +#define DMA_CCR_PL_LOW (0x0 << 12) +#define DMA_CCR_PL_MEDIUM (0x1 << 12) +#define DMA_CCR_PL_HIGH (0x2 << 12) +#define DMA_CCR_PL_VERY_HIGH (0x3 << 12) +/**@}*/ +#define DMA_CCR_PL_MASK (0x3 << 12) +#define DMA_CCR_PL_SHIFT 12 + +/* MSIZE[11:10]: Memory size */ +/** @defgroup dma_ch_memwidth DMA Channel Memory Word Width +@ingroup dma_defines + +@{*/ +#define DMA_CCR_MSIZE_8BIT (0x0 << 10) +#define DMA_CCR_MSIZE_16BIT (0x1 << 10) +#define DMA_CCR_MSIZE_32BIT (0x2 << 10) +/**@}*/ +#define DMA_CCR_MSIZE_MASK (0x3 << 10) +#define DMA_CCR_MSIZE_SHIFT 10 + +/* PSIZE[9:8]: Peripheral size */ +/** @defgroup dma_ch_perwidth DMA Channel Peripheral Word Width +@ingroup dma_defines + +@{*/ +#define DMA_CCR_PSIZE_8BIT (0x0 << 8) +#define DMA_CCR_PSIZE_16BIT (0x1 << 8) +#define DMA_CCR_PSIZE_32BIT (0x2 << 8) +/**@}*/ +#define DMA_CCR_PSIZE_MASK (0x3 << 8) +#define DMA_CCR_PSIZE_SHIFT 8 + +/* MINC: Memory increment mode */ +#define DMA_CCR_MINC (1 << 7) + +/* PINC: Peripheral increment mode */ +#define DMA_CCR_PINC (1 << 6) + +/* CIRC: Circular mode */ +#define DMA_CCR_CIRC (1 << 5) + +/* DIR: Data transfer direction */ +#define DMA_CCR_DIR (1 << 4) + +/* TEIE: Transfer error interrupt enable */ +#define DMA_CCR_TEIE (1 << 3) + +/* HTIE: Half transfer interrupt enable */ +#define DMA_CCR_HTIE (1 << 2) + +/* TCIE: Transfer complete interrupt enable */ +#define DMA_CCR_TCIE (1 << 1) + +/* EN: Channel enable */ +#define DMA_CCR_EN (1 << 0) + +/* --- DMA_CNDTRx values --------------------------------------------------- */ + +/* NDT[15:0]: Number of data to transfer */ + +/* --- DMA_CPARx values ---------------------------------------------------- */ + +/* PA[31:0]: Peripheral address */ + +/* --- DMA_CMARx values ---------------------------------------------------- */ + +/* MA[31:0]: Memory address */ + +/* --- Generic values ------------------------------------------------------ */ + +/** @defgroup dma_ch DMA Channel Number +@ingroup dma_defines + +@{*/ +#define DMA_CHANNEL1 1 +#define DMA_CHANNEL2 2 +#define DMA_CHANNEL3 3 +#define DMA_CHANNEL4 4 +#define DMA_CHANNEL5 5 +#define DMA_CHANNEL6 6 +#define DMA_CHANNEL7 7 +/**@}*/ + +/* --- function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void dma_channel_reset(uint32_t dma, uint8_t channel); +void dma_clear_interrupt_flags(uint32_t dma, uint8_t channel, + uint32_t interrupts); +bool dma_get_interrupt_flag(uint32_t dma, uint8_t channel, uint32_t interrupts); +void dma_enable_mem2mem_mode(uint32_t dma, uint8_t channel); +void dma_set_priority(uint32_t dma, uint8_t channel, uint32_t prio); +void dma_set_memory_size(uint32_t dma, uint8_t channel, uint32_t mem_size); +void dma_set_peripheral_size(uint32_t dma, uint8_t channel, + uint32_t peripheral_size); +void dma_enable_memory_increment_mode(uint32_t dma, uint8_t channel); +void dma_disable_memory_increment_mode(uint32_t dma, uint8_t channel); +void dma_enable_peripheral_increment_mode(uint32_t dma, uint8_t channel); +void dma_disable_peripheral_increment_mode(uint32_t dma, uint8_t channel); +void dma_enable_circular_mode(uint32_t dma, uint8_t channel); +void dma_set_read_from_peripheral(uint32_t dma, uint8_t channel); +void dma_set_read_from_memory(uint32_t dma, uint8_t channel); +void dma_enable_transfer_error_interrupt(uint32_t dma, uint8_t channel); +void dma_disable_transfer_error_interrupt(uint32_t dma, uint8_t channel); +void dma_enable_half_transfer_interrupt(uint32_t dma, uint8_t channel); +void dma_disable_half_transfer_interrupt(uint32_t dma, uint8_t channel); +void dma_enable_transfer_complete_interrupt(uint32_t dma, uint8_t channel); +void dma_disable_transfer_complete_interrupt(uint32_t dma, uint8_t channel); +void dma_enable_channel(uint32_t dma, uint8_t channel); +void dma_disable_channel(uint32_t dma, uint8_t channel); +void dma_set_peripheral_address(uint32_t dma, uint8_t channel, + uint32_t address); +void dma_set_memory_address(uint32_t dma, uint8_t channel, uint32_t address); +void dma_set_number_of_data(uint32_t dma, uint8_t channel, uint16_t number); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "dma_common_f13.h should not be included explicitly, only via dma.h" +#endif +/** @endcond */ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/exti_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/exti_common_all.h new file mode 100644 index 00000000..18596ad4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/exti_common_all.h @@ -0,0 +1,106 @@ +/** @addtogroup exti_defines + * + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @cond */ +#if defined(LIBOPENCM3_EXTI_H) +/** @endcond */ +#ifndef LIBOPENCM3_EXTI_COMMON_ALL_H +#define LIBOPENCM3_EXTI_COMMON_ALL_H +/**@{*/ + +/* --- EXTI registers ------------------------------------------------------ */ + +#define EXTI_IMR MMIO32(EXTI_BASE + 0x00) +#define EXTI_EMR MMIO32(EXTI_BASE + 0x04) +#define EXTI_RTSR MMIO32(EXTI_BASE + 0x08) +#define EXTI_FTSR MMIO32(EXTI_BASE + 0x0c) +#define EXTI_SWIER MMIO32(EXTI_BASE + 0x10) +#define EXTI_PR MMIO32(EXTI_BASE + 0x14) + +/* EXTI number definitions */ +#define EXTI0 (1 << 0) +#define EXTI1 (1 << 1) +#define EXTI2 (1 << 2) +#define EXTI3 (1 << 3) +#define EXTI4 (1 << 4) +#define EXTI5 (1 << 5) +#define EXTI6 (1 << 6) +#define EXTI7 (1 << 7) +#define EXTI8 (1 << 8) +#define EXTI9 (1 << 9) +#define EXTI10 (1 << 10) +#define EXTI11 (1 << 11) +#define EXTI12 (1 << 12) +#define EXTI13 (1 << 13) +#define EXTI14 (1 << 14) +#define EXTI15 (1 << 15) +#define EXTI16 (1 << 16) +#define EXTI17 (1 << 17) +#define EXTI18 (1 << 18) +#define EXTI19 (1 << 19) +#define EXTI20 (1 << 20) +#define EXTI21 (1 << 21) +#define EXTI22 (1 << 22) +#define EXTI23 (1 << 23) +#define EXTI24 (1 << 24) +#define EXTI25 (1 << 25) +#define EXTI26 (1 << 26) +#define EXTI27 (1 << 27) +#define EXTI28 (1 << 28) +#define EXTI29 (1 << 29) +#define EXTI30 (1 << 30) +#define EXTI31 (1 << 31) + +#define EXTI32 (1 << 0) +#define EXTI33 (1 << 1) +#define EXTI34 (1 << 2) +#define EXTI35 (1 << 3) +#define EXTI36 (1 << 4) +#define EXTI37 (1 << 5) + +/* Trigger types */ +enum exti_trigger_type { + EXTI_TRIGGER_RISING, + EXTI_TRIGGER_FALLING, + EXTI_TRIGGER_BOTH, +}; + +BEGIN_DECLS + +void exti_set_trigger(uint32_t extis, enum exti_trigger_type trig); +void exti_enable_request(uint32_t extis); +void exti_disable_request(uint32_t extis); +void exti_reset_request(uint32_t extis); +void exti_select_source(uint32_t exti, uint32_t gpioport); +uint32_t exti_get_flag_status(uint32_t exti); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "exti_common_all.h should not be included directly, only via exti.h" +#endif +/** @endcond */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f01.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f01.h new file mode 100644 index 00000000..e765c3bd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f01.h @@ -0,0 +1,130 @@ +/** @addtogroup flash_defines + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * For details see: + * PM0081 Programming manual: STM32F40xxx and STM32F41xxx Flash programming + * September 2011, Doc ID 018520 Rev 1 + * https://github.com/libopencm3/libopencm3-archive/blob/master/st_micro/DM00023388.pdf + */ + +/** @cond */ +#ifdef LIBOPENCM3_FLASH_H +/** @endcond */ +#ifndef LIBOPENCM3_FLASH_COMMON_F01_H +#define LIBOPENCM3_FLASH_COMMON_F01_H +/**@{*/ + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) +#define FLASH_KEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) +#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) +#define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) +#define FLASH_CR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) +#define FLASH_AR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_OBR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x1C) +#define FLASH_WRPR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x20) +/* Only present in STM32F10x XL series */ +#define FLASH_KEYR2 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x44) +#define FLASH_SR2 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x4C) +#define FLASH_CR2 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x50) +#define FLASH_AR2 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x54) + +/* --- FLASH_OPTION bytes ------------------------------------------------- */ + +#define FLASH_OPTION_BYTE(i) MMIO16(INFO_BASE+0x0800 + (i)*2) + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +#define FLASH_ACR_LATENCY_SHIFT 0 +#define FLASH_ACR_LATENCY 7 + +#define FLASH_ACR_PRFTBS (1 << 5) +#define FLASH_ACR_PRFTBE (1 << 4) + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_EOP (1 << 5) +#define FLASH_SR_WRPRTERR (1 << 4) +#define FLASH_SR_PGERR (1 << 2) +#define FLASH_SR_BSY (1 << 0) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +#define FLASH_CR_EOPIE (1 << 12) +#define FLASH_CR_ERRIE (1 << 10) +#define FLASH_CR_OPTWRE (1 << 9) +#define FLASH_CR_LOCK (1 << 7) +#define FLASH_CR_STRT (1 << 6) +#define FLASH_CR_OPTER (1 << 5) +#define FLASH_CR_OPTPG (1 << 4) +#define FLASH_CR_MER (1 << 2) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_PG (1 << 0) + +/* --- FLASH_OBR values ---------------------------------------------------- */ + +#define FLASH_OBR_RDPRT_SHIFT 1 +#define FLASH_OBR_OPTERR (1 << 0) + +/* --- FLASH Keys -----------------------------------------------------------*/ + +#define FLASH_KEYR_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEYR_KEY2 ((uint32_t)0xcdef89ab) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_set_ws(uint32_t ws); +void flash_prefetch_buffer_enable(void); +void flash_prefetch_buffer_disable(void); +void flash_unlock(void); +void flash_lock(void); +void flash_clear_pgerr_flag(void); +void flash_clear_eop_flag(void); +void flash_clear_wrprterr_flag(void); +void flash_clear_bsy_flag(void); +void flash_clear_status_flags(void); +uint32_t flash_get_status_flags(void); +void flash_wait_for_last_operation(void); +void flash_program_word(uint32_t address, uint32_t data); +void flash_program_half_word(uint32_t address, uint16_t data); +void flash_erase_page(uint32_t page_address); +void flash_erase_all_pages(void); +void flash_unlock_option_bytes(void); +void flash_erase_option_bytes(void); +void flash_program_option_bytes(uint32_t address, uint16_t data); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "flash_common_f01.h should not be included directly," +#warning "only via flash.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f234.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f234.h new file mode 100644 index 00000000..19247c4e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f234.h @@ -0,0 +1,94 @@ +/** @addtogroup flash_defines + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * For details see: + * PM0081 Programming manual: STM32F40xxx and STM32F41xxx Flash programming + * September 2011, Doc ID 018520 Rev 1 + * https://github.com/libopencm3/libopencm3-archive/blob/master/st_micro/DM00023388.pdf + */ + +/** @cond */ +#ifdef LIBOPENCM3_FLASH_H +/** @endcond */ +#ifndef LIBOPENCM3_FLASH_COMMON_F234_H +#define LIBOPENCM3_FLASH_COMMON_F234_H +/**@{*/ + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) +#define FLASH_KEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) +#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) +#define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) +#define FLASH_CR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +#define FLASH_ACR_LATENCY_MASK 0x07 +#define FLASH_ACR_LATENCY_0WS 0x00 +#define FLASH_ACR_LATENCY_1WS 0x01 +#define FLASH_ACR_LATENCY_2WS 0x02 +#define FLASH_ACR_LATENCY_3WS 0x03 +#define FLASH_ACR_LATENCY_4WS 0x04 +#define FLASH_ACR_LATENCY_5WS 0x05 +#define FLASH_ACR_LATENCY_6WS 0x06 +#define FLASH_ACR_LATENCY_7WS 0x07 + +/* --- FLASH_SR values ----------------------------------------------------- */ + +/* --- FLASH_CR values ----------------------------------------------------- */ + +/* --- FLASH Keys -----------------------------------------------------------*/ + +#define FLASH_KEYR_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEYR_KEY2 ((uint32_t)0xcdef89ab) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_set_ws(uint32_t ws); +void flash_unlock(void); +void flash_lock(void); +void flash_clear_pgperr_flag(void); +void flash_clear_eop_flag(void); +void flash_clear_bsy_flag(void); +void flash_clear_status_flags(void); +void flash_wait_for_last_operation(void); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "flash_common_f234.h should not be included direcitly," +#warning "only via flash.h" +#endif +/** @endcond */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f24.h new file mode 100644 index 00000000..e75f1445 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_f24.h @@ -0,0 +1,149 @@ +/** @addtogroup flash_defines + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * For details see: + * PM0081 Programming manual: STM32F40xxx and STM32F41xxx Flash programming + * September 2011, Doc ID 018520 Rev 1 + * https://github.com/libopencm3/libopencm3-archive/blob/master/st_micro/DM00023388.pdf + */ + +/** @cond */ +#ifdef LIBOPENCM3_FLASH_H +/** @endcond */ +#ifndef LIBOPENCM3_FLASH_COMMON_F24_H +#define LIBOPENCM3_FLASH_COMMON_F24_H +/**@{*/ + +#include + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_OPTCR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_OPTCR1 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x18) + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +#define FLASH_ACR_DCRST (1 << 12) +#define FLASH_ACR_ICRST (1 << 11) +#define FLASH_ACR_DCEN (1 << 10) +#define FLASH_ACR_ICEN (1 << 9) +#define FLASH_ACR_PRFTEN (1 << 8) + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_BSY (1 << 16) +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_SR_PGPERR (1 << 6) +#define FLASH_SR_PGAERR (1 << 5) +#define FLASH_SR_WRPERR (1 << 4) +#define FLASH_SR_OPERR (1 << 1) +#define FLASH_SR_EOP (1 << 0) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +#define FLASH_CR_LOCK (1 << 31) +#define FLASH_CR_ERRIE (1 << 25) +#define FLASH_CR_EOPIE (1 << 24) +#define FLASH_CR_STRT (1 << 16) +#define FLASH_CR_MER (1 << 2) +#define FLASH_CR_SER (1 << 1) +#define FLASH_CR_PG (1 << 0) +#define FLASH_CR_SNB_SHIFT 3 +#define FLASH_CR_SNB_MASK 0x1f +#define FLASH_CR_PROGRAM_MASK 0x3 +#define FLASH_CR_PROGRAM_SHIFT 8 +/** @defgroup flash_cr_program_width Flash programming width +@ingroup flash_group + +@{*/ +#define FLASH_CR_PROGRAM_X8 0 +#define FLASH_CR_PROGRAM_X16 1 +#define FLASH_CR_PROGRAM_X32 2 +#define FLASH_CR_PROGRAM_X64 3 +/**@}*/ + +/* --- FLASH_OPTCR values -------------------------------------------------- */ + +/* FLASH_OPTCR[27:16]: nWRP */ +/* FLASH_OBR[15:8]: RDP */ +#define FLASH_OPTCR_NRST_STDBY (1 << 7) +#define FLASH_OPTCR_NRST_STOP (1 << 6) +#define FLASH_OPTCR_WDG_SW (1 << 5) +#define FLASH_OPTCR_OPTSTRT (1 << 1) +#define FLASH_OPTCR_OPTLOCK (1 << 0) +#define FLASH_OPTCR_BOR_LEVEL_3 (0x00 << 2) +#define FLASH_OPTCR_BOR_LEVEL_2 (0x01 << 2) +#define FLASH_OPTCR_BOR_LEVEL_1 (0x02 << 2) +#define FLASH_OPTCR_BOR_OFF (0x03 << 2) + +/* --- FLASH_OPTCR1 values ------------------------------------------------- */ +/* Only on some devices */ +/* FLASH_OPTCR1[27:16]: nWRP bank 2 */ + +/* --- FLASH Keys -----------------------------------------------------------*/ + +#define FLASH_OPTKEYR_KEY1 ((uint32_t)0x08192a3b) +#define FLASH_OPTKEYR_KEY2 ((uint32_t)0x4c5d6e7f) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_unlock_option_bytes(void); +void flash_lock_option_bytes(void); +void flash_clear_pgserr_flag(void); +void flash_clear_wrperr_flag(void); +void flash_clear_pgaerr_flag(void); +void flash_dcache_enable(void); +void flash_dcache_disable(void); +void flash_icache_enable(void); +void flash_icache_disable(void); +void flash_prefetch_enable(void); +void flash_prefetch_disable(void); +void flash_dcache_reset(void); +void flash_icache_reset(void); +void flash_erase_all_sectors(uint32_t program_size); +void flash_erase_sector(uint8_t sector, uint32_t program_size); +void flash_program_double_word(uint32_t address, uint64_t data); +void flash_program_word(uint32_t address, uint32_t data); +void flash_program_half_word(uint32_t address, uint16_t data); +void flash_program_byte(uint32_t address, uint8_t data); +void flash_program(uint32_t address, uint8_t *data, uint32_t len); +void flash_program_option_bytes(uint32_t data); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "flash_common_f24.h should not be included direcitly," +#warning "only via flash.h" +#endif +/** @endcond */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_l01.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_l01.h new file mode 100644 index 00000000..8827873e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/flash_common_l01.h @@ -0,0 +1,137 @@ +/** @addtogroup flash_defines + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @cond */ +#ifdef LIBOPENCM3_FLASH_H +/** @endcond */ +#ifndef LIBOPENCM3_FLASH_COMMON_L01_H +#define LIBOPENCM3_FLASH_COMMON_L01_H +/**@{*/ + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) +#define FLASH_PECR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) +#define FLASH_PDKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) +#define FLASH_PEKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) +#define FLASH_PRGKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) +#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x18) +#define FLASH_OBR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x1c) +#define FLASH_WRPR1 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x20) +#define FLASH_WRPR2 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x80) + +/* --- FLASH_ACR values ---------------------------------------------------- */ +#define FLASH_ACR_RUNPD (1 << 4) +#define FLASH_ACR_SLEEPPD (1 << 3) +#define FLASH_ACR_PRFTEN (1 << 1) +/** @defgroup flash_latency FLASH Wait States +@ingroup flash_defines +@{*/ +#define FLASH_ACR_LATENCY_0WS 0x00 +#define FLASH_ACR_LATENCY_1WS 0x01 +/**@}*/ + +/* --- FLASH_PECR values. Program/erase control register */ +#define FLASH_PECR_OBL_LAUNCH (1 << 18) +#define FLASH_PECR_ERRIE (1 << 17) +#define FLASH_PECR_EOPIE (1 << 16) +#define FLASH_PECR_PARALLBANK (1 << 15) +#define FLASH_PECR_FPRG (1 << 10) +#define FLASH_PECR_ERASE (1 << 9) +#define FLASH_PECR_FTDW (1 << 8) +#define FLASH_PECR_DATA (1 << 4) +#define FLASH_PECR_PROG (1 << 3) +#define FLASH_PECR_OPTLOCK (1 << 2) +#define FLASH_PECR_PRGLOCK (1 << 1) +#define FLASH_PECR_PELOCK (1 << 0) + +/* Power down key register (FLASH_PDKEYR) */ +#define FLASH_PDKEYR_PDKEY1 ((uint32_t)0x04152637) +#define FLASH_PDKEYR_PDKEY2 ((uint32_t)0xFAFBFCFD) + +/* Program/erase key register (FLASH_PEKEYR) */ +#define FLASH_PEKEYR_PEKEY1 ((uint32_t)0x89ABCDEF) +#define FLASH_PEKEYR_PEKEY2 ((uint32_t)0x02030405) + +/* Program memory key register (FLASH_PRGKEYR) */ +#define FLASH_PRGKEYR_PRGKEY1 ((uint32_t)0x8C9DAEBF) +#define FLASH_PRGKEYR_PRGKEY2 ((uint32_t)0x13141516) + +/* Option byte key register (FLASH_OPTKEYR) */ +#define FLASH_OPTKEYR_OPTKEY1 ((uint32_t)0xFBEAD9C8) +#define FLASH_OPTKEYR_OPTKEY2 ((uint32_t)0x24252627) + +/* --- FLASH_SR values ----------------------------------------------------- */ +#define FLASH_SR_OPTVERR (1 << 11) +#define FLASH_SR_SIZEERR (1 << 10) +#define FLASH_SR_PGAERR (1 << 9) +#define FLASH_SR_WRPERR (1 << 8) +#define FLASH_SR_READY (1 << 3) +#define FLASH_SR_ENDHV (1 << 2) +#define FLASH_SR_EOP (1 << 1) +#define FLASH_SR_BSY (1 << 0) + +/* --- FLASH_OBR values ----------------------------------------------------- */ +#define FLASH_OBR_BFB2 (1 << 23) +#define FLASH_OBR_NRST_STDBY (1 << 22) +#define FLASH_OBR_NRST_STOP (1 << 21) +#define FLASH_OBR_IWDG_SW (1 << 20) +#define FLASH_OBR_BOR_OFF (0x0 << 16) +#define FLASH_OBR_BOR_LEVEL_1 (0x8 << 16) +#define FLASH_OBR_BOR_LEVEL_2 (0x9 << 16) +#define FLASH_OBR_BOR_LEVEL_3 (0xa << 16) +#define FLASH_OBR_BOR_LEVEL_4 (0xb << 16) +#define FLASH_OBR_BOR_LEVEL_5 (0xc << 16) +#define FLASH_OBR_RDPRT_LEVEL_0 (0xaa) +#define FLASH_OBR_RDPRT_LEVEL_1 (0x00) +#define FLASH_OBR_RDPRT_LEVEL_2 (0xcc) + +BEGIN_DECLS + +void flash_prefetch_enable(void); +void flash_prefetch_disable(void); +void flash_set_ws(uint32_t ws); +void flash_unlock_pecr(void); +void flash_lock_pecr(void); +void flash_unlock_progmem(void); +void flash_lock_progmem(void); +void flash_unlock_option_bytes(void); +void flash_lock_option_bytes(void); +void flash_unlock(void); +void flash_lock(void); + +void eeprom_program_word(uint32_t address, uint32_t data); +void eeprom_program_words(uint32_t address, uint32_t *data, int length_in_words); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#error "flash_common_l01.h should not be included directly, only via flash.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_all.h new file mode 100644 index 00000000..fcfd31e1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_all.h @@ -0,0 +1,91 @@ +/** @addtogroup gpio_defines + * + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * @author @htmlonly © @endhtmlonly 2012 + * Ken Sarkies + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA GPIO.H +The order of header inclusion is important. gpio.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#if defined(LIBOPENCM3_GPIO_H) +/** @endcond */ +#ifndef LIBOPENCM3_GPIO_COMMON_ALL_H +#define LIBOPENCM3_GPIO_COMMON_ALL_H + +/**@{*/ + +/* --- Convenience macros -------------------------------------------------- */ + +/* --- GPIO_LCKR values ---------------------------------------------------- */ + +#define GPIO_LCKK (1 << 16) +/* GPIO_LCKR[15:0]: LCKy: Port x lock bit y (y = 0..15) */ + +/* GPIO number definitions (for convenience) */ +/** @defgroup gpio_pin_id GPIO Pin Identifiers +@ingroup gpio_defines + +@{*/ +#define GPIO0 (1 << 0) +#define GPIO1 (1 << 1) +#define GPIO2 (1 << 2) +#define GPIO3 (1 << 3) +#define GPIO4 (1 << 4) +#define GPIO5 (1 << 5) +#define GPIO6 (1 << 6) +#define GPIO7 (1 << 7) +#define GPIO8 (1 << 8) +#define GPIO9 (1 << 9) +#define GPIO10 (1 << 10) +#define GPIO11 (1 << 11) +#define GPIO12 (1 << 12) +#define GPIO13 (1 << 13) +#define GPIO14 (1 << 14) +#define GPIO15 (1 << 15) +#define GPIO_ALL 0xffff +/**@}*/ + +BEGIN_DECLS + +void gpio_set(uint32_t gpioport, uint16_t gpios); +void gpio_clear(uint32_t gpioport, uint16_t gpios); +uint16_t gpio_get(uint32_t gpioport, uint16_t gpios); +void gpio_toggle(uint32_t gpioport, uint16_t gpios); +uint16_t gpio_port_read(uint32_t gpioport); +void gpio_port_write(uint32_t gpioport, uint16_t data); +void gpio_port_config_lock(uint32_t gpioport, uint16_t gpios); + +END_DECLS + +/**@}*/ +#endif +/** @cond */ +#else +#warning "gpio_common_all.h should not be included explicitly, only via gpio.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f234.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f234.h new file mode 100644 index 00000000..5fb03ae8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f234.h @@ -0,0 +1,272 @@ +/** @addtogroup gpio_defines + * + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * @author @htmlonly © @endhtmlonly 2012 + * Ken Sarkies + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA GPIO.H +The order of header inclusion is important. gpio.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_GPIO_H +/** @endcond */ +#ifndef LIBOPENCM3_GPIO_COMMON_F234_H +#define LIBOPENCM3_GPIO_COMMON_F234_H + +/**@{*/ + +#include + +/* GPIO port base addresses (for convenience) */ +/** @defgroup gpio_port_id GPIO Port IDs +@ingroup gpio_defines + +@{*/ +#define GPIOA GPIO_PORT_A_BASE +#define GPIOB GPIO_PORT_B_BASE +#define GPIOC GPIO_PORT_C_BASE +#define GPIOD GPIO_PORT_D_BASE +#define GPIOE GPIO_PORT_E_BASE +#define GPIOF GPIO_PORT_F_BASE + +/**@}*/ + +/* --- GPIO registers for STM32F2, STM32F3 and STM32F4 --------------------- */ + +/* Port mode register (GPIOx_MODER) */ +#define GPIO_MODER(port) MMIO32((port) + 0x00) +#define GPIOA_MODER GPIO_MODER(GPIOA) +#define GPIOB_MODER GPIO_MODER(GPIOB) +#define GPIOC_MODER GPIO_MODER(GPIOC) +#define GPIOD_MODER GPIO_MODER(GPIOD) +#define GPIOE_MODER GPIO_MODER(GPIOE) +#define GPIOF_MODER GPIO_MODER(GPIOF) + +/* Port output type register (GPIOx_OTYPER) */ +#define GPIO_OTYPER(port) MMIO32((port) + 0x04) +#define GPIOA_OTYPER GPIO_OTYPER(GPIOA) +#define GPIOB_OTYPER GPIO_OTYPER(GPIOB) +#define GPIOC_OTYPER GPIO_OTYPER(GPIOC) +#define GPIOD_OTYPER GPIO_OTYPER(GPIOD) +#define GPIOE_OTYPER GPIO_OTYPER(GPIOE) +#define GPIOF_OTYPER GPIO_OTYPER(GPIOF) + +/* Port output speed register (GPIOx_OSPEEDR) */ +#define GPIO_OSPEEDR(port) MMIO32((port) + 0x08) +#define GPIOA_OSPEEDR GPIO_OSPEEDR(GPIOA) +#define GPIOB_OSPEEDR GPIO_OSPEEDR(GPIOB) +#define GPIOC_OSPEEDR GPIO_OSPEEDR(GPIOC) +#define GPIOD_OSPEEDR GPIO_OSPEEDR(GPIOD) +#define GPIOE_OSPEEDR GPIO_OSPEEDR(GPIOE) +#define GPIOF_OSPEEDR GPIO_OSPEEDR(GPIOF) + +/* Port pull-up/pull-down register (GPIOx_PUPDR) */ +#define GPIO_PUPDR(port) MMIO32((port) + 0x0c) +#define GPIOA_PUPDR GPIO_PUPDR(GPIOA) +#define GPIOB_PUPDR GPIO_PUPDR(GPIOB) +#define GPIOC_PUPDR GPIO_PUPDR(GPIOC) +#define GPIOD_PUPDR GPIO_PUPDR(GPIOD) +#define GPIOE_PUPDR GPIO_PUPDR(GPIOE) +#define GPIOF_PUPDR GPIO_PUPDR(GPIOF) + +/* Port input data register (GPIOx_IDR) */ +#define GPIO_IDR(port) MMIO32((port) + 0x10) +#define GPIOA_IDR GPIO_IDR(GPIOA) +#define GPIOB_IDR GPIO_IDR(GPIOB) +#define GPIOC_IDR GPIO_IDR(GPIOC) +#define GPIOD_IDR GPIO_IDR(GPIOD) +#define GPIOE_IDR GPIO_IDR(GPIOE) +#define GPIOF_IDR GPIO_IDR(GPIOF) + +/* Port output data register (GPIOx_ODR) */ +#define GPIO_ODR(port) MMIO32((port) + 0x14) +#define GPIOA_ODR GPIO_ODR(GPIOA) +#define GPIOB_ODR GPIO_ODR(GPIOB) +#define GPIOC_ODR GPIO_ODR(GPIOC) +#define GPIOD_ODR GPIO_ODR(GPIOD) +#define GPIOE_ODR GPIO_ODR(GPIOE) +#define GPIOF_ODR GPIO_ODR(GPIOF) + +/* Port bit set/reset register (GPIOx_BSRR) */ +#define GPIO_BSRR(port) MMIO32((port) + 0x18) +#define GPIOA_BSRR GPIO_BSRR(GPIOA) +#define GPIOB_BSRR GPIO_BSRR(GPIOB) +#define GPIOC_BSRR GPIO_BSRR(GPIOC) +#define GPIOD_BSRR GPIO_BSRR(GPIOD) +#define GPIOE_BSRR GPIO_BSRR(GPIOE) +#define GPIOF_BSRR GPIO_BSRR(GPIOF) + +/* Port configuration lock register (GPIOx_LCKR) */ +#define GPIO_LCKR(port) MMIO32((port) + 0x1c) +#define GPIOA_LCKR GPIO_LCKR(GPIOA) +#define GPIOB_LCKR GPIO_LCKR(GPIOB) +#define GPIOC_LCKR GPIO_LCKR(GPIOC) +#define GPIOD_LCKR GPIO_LCKR(GPIOD) +#define GPIOE_LCKR GPIO_LCKR(GPIOE) +#define GPIOF_LCKR GPIO_LCKR(GPIOF) + +/* Alternate function low register (GPIOx_AFRL) */ +#define GPIO_AFRL(port) MMIO32((port) + 0x20) +#define GPIOA_AFRL GPIO_AFRL(GPIOA) +#define GPIOB_AFRL GPIO_AFRL(GPIOB) +#define GPIOC_AFRL GPIO_AFRL(GPIOC) +#define GPIOD_AFRL GPIO_AFRL(GPIOD) +#define GPIOE_AFRL GPIO_AFRL(GPIOE) +#define GPIOF_AFRL GPIO_AFRL(GPIOF) + +/* Alternate function high register (GPIOx_AFRH) */ +#define GPIO_AFRH(port) MMIO32((port) + 0x24) +#define GPIOA_AFRH GPIO_AFRH(GPIOA) +#define GPIOB_AFRH GPIO_AFRH(GPIOB) +#define GPIOC_AFRH GPIO_AFRH(GPIOC) +#define GPIOD_AFRH GPIO_AFRH(GPIOD) +#define GPIOE_AFRH GPIO_AFRH(GPIOE) +#define GPIOF_AFRH GPIO_AFRH(GPIOF) + +/* --- GPIOx_MODER values -------------------------------------------------- */ + +#define GPIO_MODE(n, mode) ((mode) << (2 * (n))) +#define GPIO_MODE_MASK(n) (0x3 << (2 * (n))) +/** @defgroup gpio_mode GPIO Pin Direction and Analog/Digital Mode +@ingroup gpio_defines +@{*/ +#define GPIO_MODE_INPUT 0x0 +#define GPIO_MODE_OUTPUT 0x1 +#define GPIO_MODE_AF 0x2 +#define GPIO_MODE_ANALOG 0x3 +/**@}*/ + +/* --- GPIOx_OTYPER values ------------------------------------------------- */ + +/** @defgroup gpio_output_type GPIO Output Pin Driver Type +@ingroup gpio_defines +@list Push Pull +@list Open Drain +@{*/ +#define GPIO_OTYPE_PP 0x0 +#define GPIO_OTYPE_OD 0x1 +/**@}*/ + +/* --- GPIOx_OSPEEDR values ------------------------------------------------ */ + +#define GPIO_OSPEED(n, speed) ((speed) << (2 * (n))) +#define GPIO_OSPEED_MASK(n) (0x3 << (2 * (n))) +/** @defgroup gpio_speed GPIO Output Pin Speed +@ingroup gpio_defines +@{*/ +#define GPIO_OSPEED_2MHZ 0x0 +#define GPIO_OSPEED_25MHZ 0x1 +#define GPIO_OSPEED_50MHZ 0x2 +#define GPIO_OSPEED_100MHZ 0x3 +/**@}*/ + +/* --- GPIOx_PUPDR values -------------------------------------------------- */ + +#define GPIO_PUPD(n, pupd) ((pupd) << (2 * (n))) +#define GPIO_PUPD_MASK(n) (0x3 << (2 * (n))) +/** @defgroup gpio_pup GPIO Output Pin Pullup +@ingroup gpio_defines +@{*/ +#define GPIO_PUPD_NONE 0x0 +#define GPIO_PUPD_PULLUP 0x1 +#define GPIO_PUPD_PULLDOWN 0x2 +/**@}*/ + +/* --- GPIOx_IDR values ---------------------------------------------------- */ + +/* GPIOx_IDR[15:0]: IDRy[15:0]: Port input data (y = 0..15) */ + +/* --- GPIOx_ODR values ---------------------------------------------------- */ + +/* GPIOx_ODR[15:0]: ODRy[15:0]: Port output data (y = 0..15) */ + +/* --- GPIOx_BSRR values --------------------------------------------------- */ + +/* GPIOx_BSRR[31:16]: BRy: Port x reset bit y (y = 0..15) */ +/* GPIOx_BSRR[15:0]: BSy: Port x set bit y (y = 0..15) */ + +/* --- GPIOx_LCKR values --------------------------------------------------- */ + +#define GPIO_LCKK (1 << 16) +/* GPIOx_LCKR[15:0]: LCKy: Port x lock bit y (y = 0..15) */ + +/* --- GPIOx_AFRL/H values ------------------------------------------------- */ + +/* Note: AFRL is used for bits 0..7, AFRH is used for 8..15 */ +/* See datasheet table 6 (pg. 48) for alternate function mappings. */ + +#define GPIO_AFR(n, af) ((af) << ((n) * 4)) +#define GPIO_AFR_MASK(n) (0xf << ((n) * 4)) +/** @defgroup gpio_af_num Alternate Function Pin Selection +@ingroup gpio_defines +@{*/ +#define GPIO_AF0 0x0 +#define GPIO_AF1 0x1 +#define GPIO_AF2 0x2 +#define GPIO_AF3 0x3 +#define GPIO_AF4 0x4 +#define GPIO_AF5 0x5 +#define GPIO_AF6 0x6 +#define GPIO_AF7 0x7 +#define GPIO_AF8 0x8 +#define GPIO_AF9 0x9 +#define GPIO_AF10 0xa +#define GPIO_AF11 0xb +#define GPIO_AF12 0xc +#define GPIO_AF13 0xd +#define GPIO_AF14 0xe +#define GPIO_AF15 0xf +/**@}*/ + +/* Note: EXTI source selection is now in the SYSCFG peripheral. */ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +/* + * Note: The F2 and F4 series have a completely new GPIO peripheral with + * different configuration options. Here we implement a different API partly to + * more closely match the peripheral capabilities and also to deliberately + * break compatibility with old F1 code so there is no confusion with similar + * sounding functions that have very different functionality. + */ + +void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t pull_up_down, + uint16_t gpios); +void gpio_set_output_options(uint32_t gpioport, uint8_t otype, uint8_t speed, + uint16_t gpios); +void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint16_t gpios); + +END_DECLS +/**@}*/ +#endif +/** @cond */ +#else +#warning "gpio_common_f234.h should not be included explicitly, only via gpio.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f24.h new file mode 100644 index 00000000..99758d0c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/gpio_common_f24.h @@ -0,0 +1,133 @@ +/** @addtogroup gpio_defines + * + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * @author @htmlonly © @endhtmlonly 2012 + * Ken Sarkies + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA GPIO.H +The order of header inclusion is important. gpio.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_GPIO_H +/** @endcond */ +#ifndef LIBOPENCM3_GPIO_COMMON_F24_H +#define LIBOPENCM3_GPIO_COMMON_F24_H + +/**@{*/ + +#include + +/* GPIO port base addresses (for convenience) */ +/** @defgroup gpio_port_id GPIO Port IDs +@ingroup gpio_defines + +@{*/ +#define GPIOG GPIO_PORT_G_BASE +#define GPIOH GPIO_PORT_H_BASE +#define GPIOI GPIO_PORT_I_BASE +#define GPIOJ GPIO_PORT_J_BASE +#define GPIOK GPIO_PORT_K_BASE +/**@}*/ + +/* --- GPIO registers for STM32F2, STM32F3 and STM32F4 --------------------- */ + +/* Port mode register (GPIOx_MODER) */ +#define GPIOG_MODER GPIO_MODER(GPIOG) +#define GPIOH_MODER GPIO_MODER(GPIOH) +#define GPIOI_MODER GPIO_MODER(GPIOI) +#define GPIOJ_MODER GPIO_MODER(GPIOJ) +#define GPIOK_MODER GPIO_MODER(GPIOK) + +/* Port output type register (GPIOx_OTYPER) */ +#define GPIOG_OTYPER GPIO_OTYPER(GPIOG) +#define GPIOH_OTYPER GPIO_OTYPER(GPIOH) +#define GPIOI_OTYPER GPIO_OTYPER(GPIOI) +#define GPIOJ_OTYPER GPIO_OTYPER(GPIOJ) +#define GPIOK_OTYPER GPIO_OTYPER(GPIOK) + +/* Port output speed register (GPIOx_OSPEEDR) */ +#define GPIOG_OSPEEDR GPIO_OSPEEDR(GPIOG) +#define GPIOH_OSPEEDR GPIO_OSPEEDR(GPIOH) +#define GPIOI_OSPEEDR GPIO_OSPEEDR(GPIOI) +#define GPIOJ_OSPEEDR GPIO_OSPEEDR(GPIOJ) +#define GPIOK_OSPEEDR GPIO_OSPEEDR(GPIOK) + +/* Port pull-up/pull-down register (GPIOx_PUPDR) */ +#define GPIOG_PUPDR GPIO_PUPDR(GPIOG) +#define GPIOH_PUPDR GPIO_PUPDR(GPIOH) +#define GPIOI_PUPDR GPIO_PUPDR(GPIOI) +#define GPIOJ_PUPDR GPIO_PUPDR(GPIOJ) +#define GPIOK_PUPDR GPIO_PUPDR(GPIOK) + +/* Port input data register (GPIOx_IDR) */ +#define GPIOG_IDR GPIO_IDR(GPIOG) +#define GPIOH_IDR GPIO_IDR(GPIOH) +#define GPIOI_IDR GPIO_IDR(GPIOI) +#define GPIOJ_IDR GPIO_IDR(GPIOJ) +#define GPIOK_IDR GPIO_IDR(GPIOK) + +/* Port output data register (GPIOx_ODR) */ +#define GPIOG_ODR GPIO_ODR(GPIOG) +#define GPIOH_ODR GPIO_ODR(GPIOH) +#define GPIOI_ODR GPIO_ODR(GPIOI) +#define GPIOJ_ODR GPIO_ODR(GPIOJ) +#define GPIOK_ODR GPIO_ODR(GPIOK) + +/* Port bit set/reset register (GPIOx_BSRR) */ +#define GPIOG_BSRR GPIO_BSRR(GPIOG) +#define GPIOH_BSRR GPIO_BSRR(GPIOH) +#define GPIOI_BSRR GPIO_BSRR(GPIOI) +#define GPIOJ_BSRR GPIO_BSRR(GPIOJ) +#define GPIOK_BSRR GPIO_BSRR(GPIOK) + +/* Port configuration lock register (GPIOx_LCKR) */ +#define GPIOG_LCKR GPIO_LCKR(GPIOG) +#define GPIOH_LCKR GPIO_LCKR(GPIOH) +#define GPIOI_LCKR GPIO_LCKR(GPIOI) +#define GPIOJ_LCKR GPIO_LCKR(GPIOJ) +#define GPIOK_LCKR GPIO_LCKR(GPIOK) + +/* Alternate function low register (GPIOx_AFRL) */ +#define GPIOG_AFRL GPIO_AFRL(GPIOG) +#define GPIOH_AFRL GPIO_AFRL(GPIOH) +#define GPIOI_AFRL GPIO_AFRL(GPIOI) +#define GPIOJ_AFRL GPIO_AFRL(GPIOJ) +#define GPIOK_AFRL GPIO_AFRL(GPIOK) + +/* Alternate function high register (GPIOx_AFRH) */ +#define GPIOG_AFRH GPIO_AFRH(GPIOG) +#define GPIOH_AFRH GPIO_AFRH(GPIOH) +#define GPIOI_AFRH GPIO_AFRH(GPIOI) +#define GPIOJ_AFRH GPIO_AFRH(GPIOJ) +#define GPIOK_AFRH GPIO_AFRH(GPIOK) + +/**@}*/ +#endif +/** @cond */ +#else +#warning "gpio_common_f24.h should not be included explicitly, only via gpio.h" +#endif +/** @endcond */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/hash_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/hash_common_f24.h new file mode 100644 index 00000000..6c433028 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/hash_common_f24.h @@ -0,0 +1,181 @@ +/** @addtogroup hash_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Mikhail Avkhimenia + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Mikhail Avkhimenia + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/** @cond */ +#ifdef LIBOPENCM3_HASH_H +/** @endcond */ +#ifndef LIBOPENCM3_HASH_COMMON_F24_H +#define LIBOPENCM3_HASH_COMMON_F24_H + +/* --- Convenience macros -------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup hash_reg_base HASH register base addresses +@ingroup STM32F_hash_defines + +@{*/ +#define HASH_BASE (PERIPH_BASE_AHB2 + 0x60400) +#define HASH HASH_BASE +/**@}*/ + +/* --- HASH registers ------------------------------------------------------ */ + +/* HASH control register (HASH_CR) */ +#define HASH_CR MMIO32(HASH + 0x00) + +/* HASH data input register (HASH_DIR) */ +#define HASH_DIN MMIO32(HASH + 0x04) + +/* HASH start register (HASH_STR) */ +#define HASH_STR MMIO32(HASH + 0x08) + +/* HASH digest registers (HASH_HR[5]) */ +#define HASH_HR (&MMIO32(HASH + 0x0C)) /* x5 */ + +/* HASH interrupt enable register (HASH_IMR) */ +#define HASH_IMR MMIO32(HASH + 0x20) + +/* HASH status register (HASH_SR) */ +#define HASH_SR MMIO32(HASH + 0x28) + +/* HASH context swap registers (HASH_CSR[51]) */ +#define HASH_CSR (&MMIO32(HASH + 0xF8)) /* x51 */ + +/* --- HASH_CR values ------------------------------------------------------ */ + +/* INIT: Initialize message digest calculation */ +#define HASH_CR_INIT (1 << 2) + +/* DMAE: DMA enable */ +#define HASH_CR_DMAE (1 << 3) + +/* DATATYPE: Data type selection */ +/****************************************************************************/ +/** @defgroup hash_data_type HASH Data Type +@ingroup hash_defines + +@{*/ +#define HASH_DATA_32BIT (0 << 4) +#define HASH_DATA_16BIT (1 << 4) +#define HASH_DATA_8BIT (2 << 4) +#define HASH_DATA_BITSTRING (3 << 4) +/**@}*/ +#define HASH_CR_DATATYPE (3 << 4) + +/* MODE: Mode selection */ +/****************************************************************************/ +/** @defgroup hash_mode HASH Mode +@ingroup hash_defines + +@{*/ +#define HASH_MODE_HASH (0 << 6) +#define HASH_MODE_HMAC (1 << 6) +/**@}*/ +#define HASH_CR_MODE (1 << 6) + +/* ALGO: Algorithm selection */ +/****************************************************************************/ +/** @defgroup hash_algorithm HASH Algorithm +@ingroup hash_defines + +@{*/ +#define HASH_ALGO_SHA1 (0 << 7) +#define HASH_ALGO_MD5 (1 << 7) +/**@}*/ +#define HASH_CR_ALGO (1 << 7) + +/* NBW: Number of words already pushed */ +#define HASH_CR_NBW (15 << 8) + +/* DINNE: DIN(Data input register) not empty */ +#define HASH_CR_DINNE (1 << 12) + +/* LKEY: Long key selection */ +/****************************************************************************/ +/** @defgroup hash_key_length HASH Key length +@ingroup hash_defines + +@{*/ +#define HASH_KEY_SHORT (0 << 16) +#define HASH_KEY_LONG (1 << 16) +/**@}*/ +#define HASH_CR_LKEY (1 << 16) + +/* --- HASH_STR values ----------------------------------------------------- */ + +/* NBLW: Number of valid bits in the last word of the message in the bit string + */ +#define HASH_STR_NBW (31 << 0) + +/* DCAL: Digest calculation */ +#define HASH_STR_DCAL (1 << 8) + +/* --- HASH_IMR values ----------------------------------------------------- */ + +/* DINIE: Data input interrupt enable */ +#define HASH_IMR_DINIE (1 << 0) + +/* DCIE: Digest calculation completion interrupt enable */ +#define HASH_IMR_DCIE (1 << 1) + +/* --- HASH_SR values ------------------------------------------------------ */ + +/* DINIS: Data input interrupt status */ +#define HASH_SR_DINIS (1 << 0) + +/* DCIS: Digest calculation completion interrupt status */ +#define HASH_SR_DCIS (1 << 1) + +/* DMAS: DMA Status */ +#define HASH_SR_DMAS (1 << 2) + +/* BUSY: Busy bit */ +#define HASH_SR_BUSY (1 << 3) + +/* --- HASH function prototypes -------------------------------------------- */ + +BEGIN_DECLS + +void hash_set_mode(uint8_t mode); +void hash_set_algorithm(uint8_t algorithm); +void hash_set_data_type(uint8_t datatype); +void hash_set_key_length(uint8_t keylength); +void hash_set_last_word_valid_bits(uint8_t validbits); +void hash_init(void); +void hash_add_data(uint32_t data); +void hash_digest(void); +void hash_get_result(uint32_t *data); + +END_DECLS +/**@}*/ +#endif +/** @cond */ +#else +#warning "hash_common_f24.h should not be included explicitly, only via hash.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v1.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v1.h new file mode 100644 index 00000000..e4998c61 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v1.h @@ -0,0 +1,419 @@ +/** @addtogroup i2c_defines + * + * @author @htmlonly © @endhtmlonly 2010 Thomas Otto + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA I2C.H +The order of header inclusion is important. i2c.h includes the device +specific memorymap.h header before including this header file.*/ + +/**@{*/ + +/** @cond */ +#ifdef LIBOPENCM3_I2C_H +/** @endcond */ +#ifndef LIBOPENCM3_I2C_COMMON_V1_H +#define LIBOPENCM3_I2C_COMMON_V1_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* I2C register base addresses (for convenience) */ +/****************************************************************************/ +/** @defgroup i2c_reg_base I2C register base address +@ingroup i2c_defines + +@{*/ +#define I2C1 I2C1_BASE +#define I2C2 I2C2_BASE +/**@}*/ + +/* --- I2C registers ------------------------------------------------------- */ + +/* Control register 1 (I2Cx_CR1) */ +#define I2C_CR1(i2c_base) MMIO32((i2c_base) + 0x00) +#define I2C1_CR1 I2C_CR1(I2C1) +#define I2C2_CR1 I2C_CR1(I2C2) + +/* Control register 2 (I2Cx_CR2) */ +#define I2C_CR2(i2c_base) MMIO32((i2c_base) + 0x04) +#define I2C1_CR2 I2C_CR2(I2C1) +#define I2C2_CR2 I2C_CR2(I2C2) + +/* Own address register 1 (I2Cx_OAR1) */ +#define I2C_OAR1(i2c_base) MMIO32((i2c_base) + 0x08) +#define I2C1_OAR1 I2C_OAR1(I2C1) +#define I2C2_OAR1 I2C_OAR1(I2C2) + +/* Own address register 2 (I2Cx_OAR2) */ +#define I2C_OAR2(i2c_base) MMIO32((i2c_base) + 0x0c) +#define I2C1_OAR2 I2C_OAR2(I2C1) +#define I2C2_OAR2 I2C_OAR2(I2C2) + +/* Data register (I2Cx_DR) */ +#define I2C_DR(i2c_base) MMIO32((i2c_base) + 0x10) +#define I2C1_DR I2C_DR(I2C1) +#define I2C2_DR I2C_DR(I2C2) + +/* Status register 1 (I2Cx_SR1) */ +#define I2C_SR1(i2c_base) MMIO32((i2c_base) + 0x14) +#define I2C1_SR1 I2C_SR1(I2C1) +#define I2C2_SR1 I2C_SR1(I2C2) + +/* Status register 2 (I2Cx_SR2) */ +#define I2C_SR2(i2c_base) MMIO32((i2c_base) + 0x18) +#define I2C1_SR2 I2C_SR2(I2C1) +#define I2C2_SR2 I2C_SR2(I2C2) + +/* Clock control register (I2Cx_CCR) */ +#define I2C_CCR(i2c_base) MMIO32((i2c_base) + 0x1c) +#define I2C1_CCR I2C_CCR(I2C1) +#define I2C2_CCR I2C_CCR(I2C2) + +/* TRISE register (I2Cx_CCR) */ +#define I2C_TRISE(i2c_base) MMIO32((i2c_base) + 0x20) +#define I2C1_TRISE I2C_TRISE(I2C1) +#define I2C2_TRISE I2C_TRISE(I2C2) + +/* --- I2Cx_CR1 values ----------------------------------------------------- */ + +/* SWRST: Software reset */ +#define I2C_CR1_SWRST (1 << 15) + +/* Note: Bit 14 is reserved, and forced to 0 by hardware. */ + +/* ALERT: SMBus alert */ +#define I2C_CR1_ALERT (1 << 13) + +/* PEC: Packet error checking */ +#define I2C_CR1_PEC (1 << 12) + +/* POS: Acknowledge / PEC position */ +#define I2C_CR1_POS (1 << 11) + +/* ACK: Acknowledge enable */ +#define I2C_CR1_ACK (1 << 10) + +/* STOP: STOP generation */ +#define I2C_CR1_STOP (1 << 9) + +/* START: START generation */ +#define I2C_CR1_START (1 << 8) + +/* NOSTRETCH: Clock stretching disable (slave mode) */ +#define I2C_CR1_NOSTRETCH (1 << 7) + +/* ENGC: General call enable */ +#define I2C_CR1_ENGC (1 << 6) + +/* ENPEC: Enable PEC */ +#define I2C_CR1_ENPEC (1 << 5) + +/* ENARP: ARP enable */ +#define I2C_CR1_ENARP (1 << 4) + +/* SMBTYPE: SMBus type */ +#define I2C_CR1_SMBTYPE (1 << 3) + +/* Note: Bit 2 is reserved, and forced to 0 by hardware. */ + +/* SMBUS: SMBus mode */ +#define I2C_CR1_SMBUS (1 << 1) + +/* PE: Peripheral enable */ +#define I2C_CR1_PE (1 << 0) + +/* --- I2Cx_CR2 values ----------------------------------------------------- */ + +/* Note: Bits [15:13] are reserved, and forced to 0 by hardware. */ + +/* LAST: DMA last transfer */ +#define I2C_CR2_LAST (1 << 12) + +/* DMAEN: DMA requests enable */ +#define I2C_CR2_DMAEN (1 << 11) + +/* ITBUFEN: Buffer interrupt enable */ +#define I2C_CR2_ITBUFEN (1 << 10) + +/* ITEVTEN: Event interrupt enable */ +#define I2C_CR2_ITEVTEN (1 << 9) + +/* ITERREN: Error interrupt enable */ +#define I2C_CR2_ITERREN (1 << 8) + +/* Note: Bits [7:6] are reserved, and forced to 0 by hardware. */ + +/* FREQ[5:0]: Peripheral clock frequency (valid values: 2-36 MHz, 2-42 MHz for + * STM32F4 respectively) */ +/****************************************************************************/ +/** @defgroup i2c_clock I2C clock frequency settings +@ingroup i2c_defines + +@{*/ +#define I2C_CR2_FREQ_2MHZ 0x02 +#define I2C_CR2_FREQ_3MHZ 0x03 +#define I2C_CR2_FREQ_4MHZ 0x04 +#define I2C_CR2_FREQ_5MHZ 0x05 +#define I2C_CR2_FREQ_6MHZ 0x06 +#define I2C_CR2_FREQ_7MHZ 0x07 +#define I2C_CR2_FREQ_8MHZ 0x08 +#define I2C_CR2_FREQ_9MHZ 0x09 +#define I2C_CR2_FREQ_10MHZ 0x0a +#define I2C_CR2_FREQ_11MHZ 0x0b +#define I2C_CR2_FREQ_12MHZ 0x0c +#define I2C_CR2_FREQ_13MHZ 0x0d +#define I2C_CR2_FREQ_14MHZ 0x0e +#define I2C_CR2_FREQ_15MHZ 0x0f +#define I2C_CR2_FREQ_16MHZ 0x10 +#define I2C_CR2_FREQ_17MHZ 0x11 +#define I2C_CR2_FREQ_18MHZ 0x12 +#define I2C_CR2_FREQ_19MHZ 0x13 +#define I2C_CR2_FREQ_20MHZ 0x14 +#define I2C_CR2_FREQ_21MHZ 0x15 +#define I2C_CR2_FREQ_22MHZ 0x16 +#define I2C_CR2_FREQ_23MHZ 0x17 +#define I2C_CR2_FREQ_24MHZ 0x18 +#define I2C_CR2_FREQ_25MHZ 0x19 +#define I2C_CR2_FREQ_26MHZ 0x1a +#define I2C_CR2_FREQ_27MHZ 0x1b +#define I2C_CR2_FREQ_28MHZ 0x1c +#define I2C_CR2_FREQ_29MHZ 0x1d +#define I2C_CR2_FREQ_30MHZ 0x1e +#define I2C_CR2_FREQ_31MHZ 0x1f +#define I2C_CR2_FREQ_32MHZ 0x20 +#define I2C_CR2_FREQ_33MHZ 0x21 +#define I2C_CR2_FREQ_34MHZ 0x22 +#define I2C_CR2_FREQ_35MHZ 0x23 +#define I2C_CR2_FREQ_36MHZ 0x24 +#define I2C_CR2_FREQ_37MHZ 0x25 +#define I2C_CR2_FREQ_38MHZ 0x26 +#define I2C_CR2_FREQ_39MHZ 0x27 +#define I2C_CR2_FREQ_40MHZ 0x28 +#define I2C_CR2_FREQ_41MHZ 0x29 +#define I2C_CR2_FREQ_42MHZ 0x2a +/**@}*/ + +/* --- I2Cx_OAR1 values ---------------------------------------------------- */ + +/* ADDMODE: Addressing mode (slave mode) */ +#define I2C_OAR1_ADDMODE (1 << 15) +#define I2C_OAR1_ADDMODE_7BIT 0 +#define I2C_OAR1_ADDMODE_10BIT 1 + +/* Note: Bit 14 should always be kept at 1 by software! */ + +/* Note: Bits [13:10] are reserved, and forced to 0 by hardware. */ + +/* ADD: Address bits: [7:1] in 7-bit mode, bits [9:0] in 10-bit mode */ + +/* --- I2Cx_OAR2 values ---------------------------------------------------- */ + +/* Note: Bits [15:8] are reserved, and forced to 0 by hardware. */ + +/* ADD2[7:1]: Interface address (bits [7:1] in dual addressing mode) */ + +/* ENDUAL: Dual addressing mode enable */ +#define I2C_OAR2_ENDUAL (1 << 0) + +/* --- I2Cx_DR values ------------------------------------------------------ */ + +/* Note: Bits [15:8] are reserved, and forced to 0 by hardware. */ + +/* DR[7:0] 8-bit data register */ + +/* --- I2Cx_SR1 values ----------------------------------------------------- */ + +/* SMBALERT: SMBus alert */ +#define I2C_SR1_SMBALERT (1 << 15) + +/* TIMEOUT: Timeout or Tlow Error */ +#define I2C_SR1_TIMEOUT (1 << 14) + +/* Note: Bit 13 is reserved, and forced to 0 by hardware. */ + +/* PECERR: PEC Error in reception */ +#define I2C_SR1_PECERR (1 << 12) + +/* OVR: Overrun/Underrun */ +#define I2C_SR1_OVR (1 << 11) + +/* AF: Acknowledge failure */ +#define I2C_SR1_AF (1 << 10) + +/* ARLO: Arbitration lost (master mode) */ +#define I2C_SR1_ARLO (1 << 9) + +/* BERR: Bus error */ +#define I2C_SR1_BERR (1 << 8) + +/* TxE: Data register empty (transmitters) */ +#define I2C_SR1_TxE (1 << 7) + +/* RxNE: Data register not empty (receivers) */ +#define I2C_SR1_RxNE (1 << 6) + +/* Note: Bit 5 is reserved, and forced to 0 by hardware. */ + +/* STOPF: STOP detection (slave mode) */ +#define I2C_SR1_STOPF (1 << 4) + +/* ADD10: 10-bit header sent (master mode) */ +#define I2C_SR1_ADD10 (1 << 3) + +/* BTF: Byte transfer finished */ +#define I2C_SR1_BTF (1 << 2) + +/* ADDR: Address sent (master mode) / address matched (slave mode) */ +#define I2C_SR1_ADDR (1 << 1) + +/* SB: Start bit (master mode) */ +#define I2C_SR1_SB (1 << 0) + +/* --- I2Cx_SR2 values ----------------------------------------------------- */ + +/* Bits [15:8]: PEC[7:0]: Packet error checking register */ + +/* DUALF: Dual flag (slave mode) */ +#define I2C_SR2_DUALF (1 << 7) + +/* SMBHOST: SMBus host header (slave mode) */ +#define I2C_SR2_SMBHOST (1 << 6) + +/* SMBDEFAULT: SMBus device default address (slave mode) */ +#define I2C_SR2_SMBDEFAULT (1 << 5) + +/* GENCALL: General call address (slave mode) */ +#define I2C_SR2_GENCALL (1 << 4) + +/* Note: Bit 3 is reserved, and forced to 0 by hardware. */ + +/* TRA: Transmitter / receiver */ +#define I2C_SR2_TRA (1 << 2) + +/* BUSY: Bus busy */ +#define I2C_SR2_BUSY (1 << 1) + +/* MSL: Master / slave */ +#define I2C_SR2_MSL (1 << 0) + +/* --- I2Cx_CCR values ----------------------------------------------------- */ + +/* F/S: I2C Master mode selection (fast / standard) */ +#define I2C_CCR_FS (1 << 15) + +/* DUTY: Fast Mode Duty Cycle */ +/** @defgroup i2c_duty_cycle I2C peripheral clock duty cycles +@ingroup i2c_defines + +@{*/ +#define I2C_CCR_DUTY (1 << 14) +#define I2C_CCR_DUTY_DIV2 0 +#define I2C_CCR_DUTY_16_DIV_9 1 +/**@}*/ + +/* Note: Bits [13:12] are reserved, and forced to 0 by hardware. */ + +/* + * Bits [11:0]: + * CCR[11:0]: Clock control register in Fast/Standard mode (master mode) + */ + +/* --- I2Cx_TRISE values --------------------------------------------------- */ + +/* Note: Bits [15:6] are reserved, and forced to 0 by hardware. */ + +/* + * Bits [5:0]: + * TRISE[5:0]: Maximum rise time in Fast/Standard mode (master mode) + */ + +/* --- I2C constant definitions -------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup i2c_rw I2C Read/Write bit +@ingroup i2c_defines + +@{*/ +#define I2C_WRITE 0 +#define I2C_READ 1 +/**@}*/ + +/* --- I2C function prototypes---------------------------------------------- */ + +/** + * I2C speed modes. + */ +enum i2c_speeds { + i2c_speed_sm_100k, + i2c_speed_fm_400k, + i2c_speed_fmp_1m, + i2c_speed_unknown +}; + +BEGIN_DECLS + +void i2c_reset(uint32_t i2c); +void i2c_peripheral_enable(uint32_t i2c); +void i2c_peripheral_disable(uint32_t i2c); +void i2c_send_start(uint32_t i2c); +void i2c_send_stop(uint32_t i2c); +void i2c_clear_stop(uint32_t i2c); +void i2c_set_own_7bit_slave_address(uint32_t i2c, uint8_t slave); +void i2c_set_own_10bit_slave_address(uint32_t i2c, uint16_t slave); +void i2c_set_own_7bit_slave_address_two(uint32_t i2c, uint8_t slave); +void i2c_enable_dual_addressing_mode(uint32_t i2c); +void i2c_disable_dual_addressing_mode(uint32_t i2c); +void i2c_set_clock_frequency(uint32_t i2c, uint8_t freq); +void i2c_send_data(uint32_t i2c, uint8_t data); +void i2c_set_fast_mode(uint32_t i2c); +void i2c_set_standard_mode(uint32_t i2c); +void i2c_set_ccr(uint32_t i2c, uint16_t freq); +void i2c_set_trise(uint32_t i2c, uint16_t trise); +void i2c_send_7bit_address(uint32_t i2c, uint8_t slave, uint8_t readwrite); +uint8_t i2c_get_data(uint32_t i2c); +void i2c_enable_interrupt(uint32_t i2c, uint32_t interrupt); +void i2c_disable_interrupt(uint32_t i2c, uint32_t interrupt); +void i2c_enable_ack(uint32_t i2c); +void i2c_disable_ack(uint32_t i2c); +void i2c_nack_next(uint32_t i2c); +void i2c_nack_current(uint32_t i2c); +void i2c_set_dutycycle(uint32_t i2c, uint32_t dutycycle); +void i2c_enable_dma(uint32_t i2c); +void i2c_disable_dma(uint32_t i2c); +void i2c_set_dma_last_transfer(uint32_t i2c); +void i2c_clear_dma_last_transfer(uint32_t i2c); +void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn); +void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "i2c_common_v1.h should not be included explicitly, only via i2c.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v2.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v2.h new file mode 100644 index 00000000..1a9df080 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/i2c_common_v2.h @@ -0,0 +1,455 @@ +/** @addtogroup i2c_defines + * + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA I2C.H +The order of header inclusion is important. i2c.h includes the device +specific memorymap.h header before including this header file.*/ + +/**@{*/ + +/** @cond */ +#ifdef LIBOPENCM3_I2C_H +/** @endcond */ +#ifndef LIBOPENCM3_I2C_COMMON_V2_H +#define LIBOPENCM3_I2C_COMMON_V2_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* I2C register base addresses (for convenience) */ +/*****************************************************************************/ +/** @defgroup i2c_reg_base I2C register base address + * @ingroup i2c_defines + * @{*/ +#define I2C1 I2C1_BASE +#define I2C2 I2C2_BASE +/**@}*/ + +/* --- I2C registers ------------------------------------------------------- */ + +/* Control register 1 (I2Cx_CR1) */ +#define I2C_CR1(i2c_base) MMIO32((i2c_base) + 0x00) +#define I2C1_CR1 I2C_CR1(I2C1) +#define I2C2_CR1 I2C_CR1(I2C2) + +/* Control register 2 (I2Cx_CR2) */ +#define I2C_CR2(i2c_base) MMIO32((i2c_base) + 0x04) +#define I2C1_CR2 I2C_CR2(I2C1) +#define I2C2_CR2 I2C_CR2(I2C2) + +/* Own address register 1 (I2Cx_OAR1) */ +#define I2C_OAR1(i2c_base) MMIO32((i2c_base) + 0x08) +#define I2C1_OAR1 I2C_OAR1(I2C1) +#define I2C2_OAR1 I2C_OAR1(I2C2) + +/* Own address register 2 (I2Cx_OAR2) */ +#define I2C_OAR2(i2c_base) MMIO32((i2c_base) + 0x0c) +#define I2C1_OAR2 I2C_OAR2(I2C1) +#define I2C2_OAR2 I2C_OAR2(I2C2) + +/* Timing register (I2Cx_TIMINGR) */ +#define I2C_TIMINGR(i2c_base) MMIO32((i2c_base) + 0x10) +#define I2C1_TIMINGR I2C_TIMINGR(I2C1) +#define I2C2_TIMINGR I2C_TIMINGR(I2C2) + +/* Timeout register (I2Cx_TIMEOUTR) */ +#define I2C_TIMEOUTR(i2c_base) MMIO32((i2c_base) + 0x14) +#define I2C1_TIMEOUTR I2C_TIMEOUTR(I2C1) +#define I2C2_TIMEOUTR I2C_TIMEOUTR(I2C2) + +/* Interrupt and Status register (I2Cx_ISR) */ +#define I2C_ISR(i2c_base) MMIO32((i2c_base) + 0x18) +#define I2C1_ISR I2C_ISR(I2C1) +#define I2C2_ISR I2C_ISR(I2C2) + +/* Interrupt clear register (I2Cx_ICR) */ +#define I2C_ICR(i2c_base) MMIO32((i2c_base) + 0x1C) +#define I2C1_ICR I2C_ICR(I2C1) +#define I2C2_ICR I2C_ICR(I2C2) + +/* PEC register (I2Cx_PECR) */ +#define I2C_PECR(i2c_base) MMIO32((i2c_base) + 0x20) +#define I2C1_PECR I2C_PECR(I2C1) +#define I2C2_PECR I2C_PECR(I2C2) + +/* Receive data register (I2Cx_RXDR) */ +#define I2C_RXDR(i2c_base) MMIO32((i2c_base) + 0x24) +#define I2C1_RXDR I2C_RXDR(I2C1) +#define I2C2_RXDR I2C_RXDR(I2C2) + +/* Transmit data register (I2Cx_TXDR) */ +#define I2C_TXDR(i2c_base) MMIO32((i2c_base) + 0x28) +#define I2C1_TXDR I2C_TXDR(I2C1) +#define I2C2_TXDR I2C_TXDR(I2C2) + +/* --- I2Cx_CR1 values ----------------------------------------------------- */ + +/* PECEN: PEC enable */ +#define I2C_CR1_PECEN (1 << 23) + +/* ALERTEN: SMBus alert enable */ +#define I2C_CR1_ALERTEN (1 << 22) + +/* SMBDEN: SMBus Device Default address enable */ +#define I2C_CR1_SMBDEN (1 << 21) + +/* SMBHEN: SMBus Host address enable */ +#define I2C_CR1_SMBHEN (1 << 20) + +/* GCEN: General call enable */ +#define I2C_CR1_GCEN (1 << 19) + +/* WUPEN: Wakeup from STOP enable */ +#define I2C_CR1_WUPEN (1 << 18) + +/* NOSTRETCH: Clock stretching disable */ +#define I2C_CR1_NOSTRETCH (1 << 17) + +/* SBC: Slave byte control */ +#define I2C_CR1_SBC (1 << 16) + +/* RXDMAEN: DMA reception requests enable */ +#define I2C_CR1_RXDMAEN (1 << 15) + +/* TXDMAEN: DMA transmission requests enable */ +#define I2C_CR1_TXDMAEN (1 << 14) + +/* ANFOFF: Analog noise filter OFF */ +#define I2C_CR1_ANFOFF (1 << 12) + +/* DNF[3:0]: Digital noise filter */ +#define I2C_CR1_DNF_DISABLED (0x0 << 8) +#define I2C_CR1_DNF_UP_1_TI2CCLK (0x1 << 8) +#define I2C_CR1_DNF_UP_2_TI2CCLK (0x2 << 8) +#define I2C_CR1_DNF_UP_3_TI2CCLK (0x3 << 8) +#define I2C_CR1_DNF_UP_4_TI2CCLK (0x4 << 8) +#define I2C_CR1_DNF_UP_5_TI2CCLK (0x5 << 8) +#define I2C_CR1_DNF_UP_6_TI2CCLK (0x6 << 8) +#define I2C_CR1_DNF_UP_7_TI2CCLK (0x7 << 8) +#define I2C_CR1_DNF_UP_8_TI2CCLK (0x8 << 8) +#define I2C_CR1_DNF_UP_9_TI2CCLK (0x9 << 8) +#define I2C_CR1_DNF_UP_10_TI2CCLK (0xA << 8) +#define I2C_CR1_DNF_UP_11_TI2CCLK (0xB << 8) +#define I2C_CR1_DNF_UP_12_TI2CCLK (0xC << 8) +#define I2C_CR1_DNF_UP_13_TI2CCLK (0xD << 8) +#define I2C_CR1_DNF_UP_14_TI2CCLK (0xE << 8) +#define I2C_CR1_DNF_UP_15_TI2CCLK (0xF << 8) +#define I2C_CR1_DNF_MASK (0xF << 8) + +/* ERRIE: Error interrupts enable */ +#define I2C_CR1_ERRIE (1 << 7) + +/* TCIE: Transfer Complete interrupt enable */ +#define I2C_CR1_TCIE (1 << 6) + +/* STOPIE: STOP detection Interrupt enable */ +#define I2C_CR1_STOPIE (1 << 5) + +/* NACKIE: Not acknowledge received Interrupt enable */ +#define I2C_CR1_NACKIE (1 << 4) + +/* ADDRIE: Address match Interrupt enable (slave only) */ +#define I2C_CR1_DDRIE (1 << 3) + +/* RXIE: RX Interrupt enable */ +#define I2C_CR1_RXIE (1 << 2) + +/* TXIE: TX Interrupt enable */ +#define I2C_CR1_TXIE (1 << 1) + +/* PE: Peripheral enable */ +#define I2C_CR1_PE (1 << 0) + +/* --- I2Cx_CR2 values ----------------------------------------------------- */ + +/* PECBYTE: Packet error checking byte */ +#define I2C_CR2_PECBYTE (1 << 26) + +/* AUTOEND: Automatic end mode (master mode) */ +#define I2C_CR2_AUTOEND (1 << 25) + +/* RELOAD: NBYTES reload mode */ +#define I2C_CR2_RELOAD (1 << 24) + +/* NBYTES[7:0]: Number of bytes (23,16) */ +#define I2C_CR2_NBYTES_SHIFT 16 +#define I2C_CR2_NBYTES_MASK (0xFF << I2C_CR2_NBYTES_SHIFT) + +/* NACK: NACK generation (slave mode) */ +#define I2C_CR2_NACK (1 << 15) + +/* STOP: Stop generation (master mode) */ +#define I2C_CR2_STOP (1 << 14) + +/* START: Start generation */ +#define I2C_CR2_START (1 << 13) + +/* HEAD10R: 10-bit address header only read direction (master receiver mode) */ +#define I2C_CR2_HEAD10R (1 << 12) + +/* ADD10: 10-bit addressing mode (master mode) */ +#define I2C_CR2_ADD10 (1 << 11) + +/* RD_WRN: Transfer direction (master mode) */ +#define I2C_CR2_RD_WRN (1 << 10) + +#define I2C_CR2_SADD_7BIT_SHIFT 1 +#define I2C_CR2_SADD_10BIT_SHIFT 0 +#define I2C_CR2_SADD_7BIT_MASK (0x7F << I2C_CR2_SADD_7BIT_SHIFT) +#define I2C_CR2_SADD_10BIT_MASK 0x3FF + +/* --- I2Cx_OAR1 values ---------------------------------------------------- */ + +/* OA1EN: Own Address 1 enable */ +#define I2C_OAR1_OA1EN_DISABLE (0x0 << 15) +#define I2C_OAR1_OA1EN_ENABLE (0x1 << 15) + +/* OA1MODE Own Address 1 10-bit mode */ +#define I2C_OAR1_OA1MODE (1 << 10) +#define I2C_OAR1_OA1MODE_7BIT 0 +#define I2C_OAR1_OA1MODE_10BIT 1 + +/* OA1[9:8]: Interface address */ + +/* OA1[7:1]: Interface address */ + +/* OA1[0]: Interface address */ +#define I2C_OAR1_OA1 (1 << 10) +#define I2C_OAR1_OA1_7BIT 0 +#define I2C_OAR1_OA1_10BIT 1 + +/* --- I2Cx_OAR2 values ---------------------------------------------------- */ + +/* OA2EN: Own Address 2 enable */ +#define I2C_OAR2_OA2EN (1 << 15) + +/* OA2MSK[2:0]: Own Address 2 masks */ +#define I2C_OAR2_OA2MSK_NO_MASK (0x0 << 8) +#define I2C_OAR2_OA2MSK_OA2_7_OA2_2 (0x1 << 8) +#define I2C_OAR2_OA2MSK_OA2_7_OA2_3 (0x2 << 8) +#define I2C_OAR2_OA2MSK_OA2_7_OA2_4 (0x3 << 8) +#define I2C_OAR2_OA2MSK_OA2_7_OA2_5 (0x4 << 8) +#define I2C_OAR2_OA2MSK_OA2_7_OA2_6 (0x5 << 8) +#define I2C_OAR2_OA2MSK_OA2_7 (0x6 << 8) +#define I2C_OAR2_OA2MSK_NO_CMP (0x7 << 8) + +/* OA2[7:1]: Interface address */ + +/* --- I2Cx_TIMINGR values ------------------------------------------------- */ + +/* PRESC[3:0]: Timing prescaler (31,28) */ +#define I2C_TIMINGR_PRESC_SHIFT 28 +#define I2C_TIMINGR_PRESC_MASK (0xF << 28) + +/* SCLDEL[3:0]: Data setup time (23,20) */ +#define I2C_TIMINGR_SCLDEL_SHIFT 20 +#define I2C_TIMINGR_SCLDEL_MASK (0xF << I2C_TIMINGR_SCLDEL_SHIFT) + +/* SDADEL[3:0]: Data hold time (19,16) */ +#define I2C_TIMINGR_SDADEL_SHIFT 16 +#define I2C_TIMINGR_SDADEL_MASK (0xF << I2C_TIMINGR_SDADEL_SHIFT) + +/* SCLH[7:0]: SCL high period (master mode) (15,8) */ +#define I2C_TIMINGR_SCLH_SHIFT 8 +#define I2C_TIMINGR_SCLH_MASK (0xFF << I2C_TIMINGR_SCLH_SHIFT) + +/* SCLL[7:0]: SCL low period (master mode) (7,0) */ +#define I2C_TIMINGR_SCLL_SHIFT 0 +#define I2C_TIMINGR_SCLL_MASK (0xFF << I2C_TIMINGR_SCLL_SHIFT) + +/* --- I2Cx_TIEMOUTR values ------------------------------------------------ */ + +/* TEXTEN: Extended clock timeout enable */ +#define I2C_TIEMOUTR_TEXTEN (1 << 31) + +/* XXX: Not clear yet. */ +/* TIMEOUTB[11:0]: Bus timeout B */ + +/* TIMOUTEN: Clock timeout enable */ +#define I2C_TIEMOUTR_TIMOUTEN (1 << 15) + +/* TIDLE: Idle clock timeout detection */ +#define I2C_TIEMOUTR_TIDLE_SCL_LOW (0x0 << 12) +#define I2C_TIEMOUTR_TIDLE_SCL_SDA_HIGH (0x1 << 12) + +/* XXX: Not clear yet. */ +/* TIMEOUTA[11:0]: Bus Timeout A */ + +/* --- I2Cx_ISR values ----------------------------------------------------- */ + +/* Bits 31:24 Reserved, must be kept at reset value */ + +/* XXX: Not clear yet. */ +/* ADDCODE[6:0]: Address match code (Slave mode) */ + +/* DIR: Transfer direction (Slave mode) */ +#define I2C_ISR_DIR_READ (0x1 << 16) +#define I2C_ISR_DIR_WRITE (0x0 << 16) + +/* BUSY: Bus busy */ +#define I2C_ISR_BUSY (1 << 15) + +/* ALERT: SMBus alert */ +#define I2C_ISR_ALERT (1 << 13) + +/* TIMEOUT: Timeout or tLOW detection flag */ +#define I2C_ISR_TIMEOUT (1 << 12) + +/* PECERR: PEC Error in reception */ +#define I2C_ISR_PECERR (1 << 11) + +/* OVR: Overrun/Underrun (slave mode) */ +#define I2C_ISR_OVR (1 << 10) + +/* ARLO: Arbitration lost */ +#define I2C_ISR_ARLO (1 << 9) + +/* BERR: Bus error */ +#define I2C_ISR_BERR (1 << 8) + +/* TCR: Transfer Complete Reload */ +#define I2C_ISR_TCR (1 << 7) + +/* TC: Transfer Complete (master mode) */ +#define I2C_ISR_TC (1 << 6) + +/* STOPF: Stop detection flag */ +#define I2C_ISR_STOPF (1 << 5) + +/* NACKF: Not Acknowledge received flag */ +#define I2C_ISR_NACKF (1 << 4) + +/* ADDR: Address matched (slave mode) */ +#define I2C_ISR_ADDR (1 << 3) + +/* RXNE: Receive data register not empty (receivers) */ +#define I2C_ISR_RXNE (1 << 2) + +/* TXIS: Transmit interrupt status (transmitters) */ +#define I2C_ISR_TXIS (1 << 1) + +/* TXE: Transmit data register empty (transmitters) */ +#define I2C_ISR_TXE (1 << 0) + +/* --- I2Cx_ICR values ----------------------------------------------------- */ + +/* ALERTCF: Alert flag clear */ +#define I2C_ICR_ALERTCF (1 << 13) + +/* TIMOUTCF: Timeout detection flag clear */ +#define I2C_ICR_TIMOUTCF (1 << 12) + +/* PECCF: PEC Error flag clear */ +#define I2C_ICR_PECCF (1 << 11) + +/* OVRCF: Overrun/Underrun flag clear */ +#define I2C_ICR_OVRCF (1 << 10) + +/* ARLOCF: Arbitration Lost flag clear */ +#define I2C_ICR_ARLOCF (1 << 9) + +/* BERRCF: Bus error flag clear */ +#define I2C_ICR_BERRCF (1 << 8) + +/* STOPCF: Stop detection flag clear */ +#define I2C_ICR_STOPCF (1 << 5) + +/* NACKCF: Not Acknowledge flag clear */ +#define I2C_ICR_NACKCF (1 << 4) + +/* ADDRCF: Address Matched flag clear */ +#define I2C_ICR_ADDRCF (1 << 3) + +/* --- I2Cx_PECR values ---------------------------------------------------- */ + +/* PEC[7:0] Packet error checking register */ + +/* --- I2C function prototypes---------------------------------------------- */ + +/** + * I2C speed modes. + */ +enum i2c_speeds { + i2c_speed_sm_100k, + i2c_speed_fm_400k, + i2c_speed_fmp_1m, + i2c_speed_unknown +}; + +BEGIN_DECLS + +void i2c_reset(uint32_t i2c); +void i2c_peripheral_enable(uint32_t i2c); +void i2c_peripheral_disable(uint32_t i2c); +void i2c_send_start(uint32_t i2c); +void i2c_send_stop(uint32_t i2c); +void i2c_clear_stop(uint32_t i2c); +void i2c_set_own_7bit_slave_address(uint32_t i2c, uint8_t slave); +void i2c_set_own_10bit_slave_address(uint32_t i2c, uint16_t slave); +void i2c_send_data(uint32_t i2c, uint8_t data); +uint8_t i2c_get_data(uint32_t i2c); + +void i2c_enable_analog_filter(uint32_t i2c); +void i2c_disable_analog_filter(uint32_t i2c); +void i2c_set_digital_filter(uint32_t i2c, uint8_t dnf_setting); +void i2c_set_prescaler(uint32_t i2c, uint8_t presc); +void i2c_set_data_setup_time(uint32_t i2c, uint8_t s_time); +void i2c_set_data_hold_time(uint32_t i2c, uint8_t h_time); +void i2c_set_scl_high_period(uint32_t i2c, uint8_t period); +void i2c_set_scl_low_period(uint32_t i2c, uint8_t period); +void i2c_enable_stretching(uint32_t i2c); +void i2c_disable_stretching(uint32_t i2c); +void i2c_set_7bit_addr_mode(uint32_t i2c); +void i2c_set_10bit_addr_mode(uint32_t i2c); +void i2c_set_7bit_address(uint32_t i2c, uint8_t addr); +void i2c_set_10bit_address(uint32_t i2c, uint16_t addr); +void i2c_set_write_transfer_dir(uint32_t i2c); +void i2c_set_read_transfer_dir(uint32_t i2c); +void i2c_set_bytes_to_transfer(uint32_t i2c, uint32_t n_bytes); +bool i2c_is_start(uint32_t i2c); +void i2c_enable_autoend(uint32_t i2c); +void i2c_disable_autoend(uint32_t i2c); +bool i2c_nack(uint32_t i2c); +bool i2c_busy(uint32_t i2c); +bool i2c_transmit_int_status(uint32_t i2c); +bool i2c_transfer_complete(uint32_t i2c); +bool i2c_received_data(uint32_t i2c); +void i2c_enable_interrupt(uint32_t i2c, uint32_t interrupt); +void i2c_disable_interrupt(uint32_t i2c, uint32_t interrupt); +void i2c_enable_rxdma(uint32_t i2c); +void i2c_disable_rxdma(uint32_t i2c); +void i2c_enable_txdma(uint32_t i2c); +void i2c_disable_txdma(uint32_t i2c); +void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn); +void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "i2c_common_v2.h should not be included explicitly, only via i2c.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/iwdg_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/iwdg_common_all.h new file mode 100644 index 00000000..7d915d69 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/iwdg_common_all.h @@ -0,0 +1,121 @@ +/** @addtogroup iwdg_defines + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA IWDG.H +The order of header inclusion is important. iwdg.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_IWDG_H +/** @endcond */ +#ifndef LIBOPENCM3_IWDG_COMMON_ALL_H +#define LIBOPENCM3_IWDG_COMMON_ALL_H + +/**@{*/ + +/* --- IWDG registers ------------------------------------------------------ */ + +/* Key Register (IWDG_KR) */ +#define IWDG_KR MMIO32(IWDG_BASE + 0x00) + +/* Prescaler register (IWDG_PR) */ +#define IWDG_PR MMIO32(IWDG_BASE + 0x04) + +/* Reload register (IWDG_RLR) */ +#define IWDG_RLR MMIO32(IWDG_BASE + 0x08) + +/* Status register (IWDG_SR) */ +#define IWDG_SR MMIO32(IWDG_BASE + 0x0c) + +/* --- IWDG_KR values ------------------------------------------------------ */ + +/* Bits [31:16]: Reserved. */ + +/* KEY[15:0]: Key value (write-only, reads as 0x0000) */ +/** @defgroup iwdg_key IWDG Key Values +@ingroup STM32F_iwdg_defines + +@{*/ +#define IWDG_KR_RESET 0xaaaa +#define IWDG_KR_UNLOCK 0x5555 +#define IWDG_KR_START 0xcccc +/**@}*/ + +/* --- IWDG_PR values ------------------------------------------------------ */ + +/* Bits [31:3]: Reserved. */ + +/* PR[2:0]: Prescaler divider */ +#define IWDG_PR_LSB 0 +/** @defgroup iwdg_prediv IWDG prescaler divider +@ingroup STM32F_iwdg_defines + +@{*/ +#define IWDG_PR_DIV4 0x0 +#define IWDG_PR_DIV8 0x1 +#define IWDG_PR_DIV16 0x2 +#define IWDG_PR_DIV32 0x3 +#define IWDG_PR_DIV64 0x4 +#define IWDG_PR_DIV128 0x5 +#define IWDG_PR_DIV256 0x6 +/**@}*/ +/* Double definition: 0x06 and 0x07 both mean DIV256 as per datasheet. */ +/* #define IWDG_PR_DIV256 0x7 */ + +/* --- IWDG_RLR values ----------------------------------------------------- */ + +/* Bits [31:12]: Reserved. */ + +/* RL[11:0]: Watchdog counter reload value */ + +/* --- IWDG_SR values ------------------------------------------------------ */ + +/* Bits [31:2]: Reserved. */ + +/* RVU: Watchdog counter reload value update */ +#define IWDG_SR_RVU (1 << 1) + +/* PVU: Watchdog prescaler value update */ +#define IWDG_SR_PVU (1 << 0) + +/* --- IWDG function prototypes---------------------------------------------- */ + +BEGIN_DECLS + +void iwdg_start(void); +void iwdg_set_period_ms(uint32_t period); +bool iwdg_reload_busy(void); +bool iwdg_prescaler_busy(void); +void iwdg_reset(void); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "iwdg_common_all.h should not be included explicitly, only via iwdg.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v1.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v1.h new file mode 100644 index 00000000..273c5dee --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v1.h @@ -0,0 +1,132 @@ +/** @addtogroup pwr_defines + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA PWR.H +The order of header inclusion is important. pwr.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_PWR_H +/** @endcond */ +#ifndef LIBOPENCM3_PWR_COMMON_V1_H +#define LIBOPENCM3_PWR_COMMON_V1_H + +/**@{*/ + +/* --- PWR registers ------------------------------------------------------- */ + +/* Power control register (PWR_CR) */ +#define PWR_CR MMIO32(POWER_CONTROL_BASE + 0x00) + +/* Power control/status register (PWR_CSR) */ +#define PWR_CSR MMIO32(POWER_CONTROL_BASE + 0x04) + +/* --- PWR_CR values ------------------------------------------------------- */ + +/* Bits [31:9]: Reserved, must be kept at reset value. */ + +/* DBP: Disable backup domain write protection */ +#define PWR_CR_DBP (1 << 8) + +/* PLS[7:5]: PVD level selection */ +#define PWR_CR_PLS_LSB 5 +/** @defgroup pwr_pls PVD level selection +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CR_PLS_2V2 (0x0 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V3 (0x1 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V4 (0x2 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V5 (0x3 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V6 (0x4 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V7 (0x5 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V8 (0x6 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V9 (0x7 << PWR_CR_PLS_LSB) +/**@}*/ +#define PWR_CR_PLS_MASK (0x7 << PWR_CR_PLS_LSB) + +/* PVDE: Power voltage detector enable */ +#define PWR_CR_PVDE (1 << 4) + +/* CSBF: Clear standby flag */ +#define PWR_CR_CSBF (1 << 3) + +/* CWUF: Clear wakeup flag */ +#define PWR_CR_CWUF (1 << 2) + +/* PDDS: Power down deepsleep */ +#define PWR_CR_PDDS (1 << 1) + +/* LPDS: Low-power deepsleep */ +#define PWR_CR_LPDS (1 << 0) + +/* --- PWR_CSR values ------------------------------------------------------ */ + +/* Bits [31:9]: Reserved, must be kept at reset value. */ + +/* EWUP: Enable WKUP pin */ +#define PWR_CSR_EWUP (1 << 8) + +/* Bits [7:3]: Reserved, must be kept at reset value. */ + +/* PVDO: PVD output */ +#define PWR_CSR_PVDO (1 << 2) + +/* SBF: Standby flag */ +#define PWR_CSR_SBF (1 << 1) + +/* WUF: Wakeup flag */ +#define PWR_CSR_WUF (1 << 0) + +/* --- PWR function prototypes ------------------------------------------- */ + +BEGIN_DECLS + +void pwr_disable_backup_domain_write_protect(void); +void pwr_enable_backup_domain_write_protect(void); +void pwr_enable_power_voltage_detect(uint32_t pvd_level); +void pwr_disable_power_voltage_detect(void); +void pwr_clear_standby_flag(void); +void pwr_clear_wakeup_flag(void); +void pwr_set_standby_mode(void); +void pwr_set_stop_mode(void); +void pwr_voltage_regulator_on_in_stop(void); +void pwr_voltage_regulator_low_power_in_stop(void); +void pwr_enable_wakeup_pin(void); +void pwr_disable_wakeup_pin(void); +bool pwr_voltage_high(void); +bool pwr_get_standby_flag(void); +bool pwr_get_wakeup_flag(void); + +END_DECLS + +/**@}*/ +#endif +/** @cond */ +#else +#warning "pwr_common_v1.h should not be included explicitly, only via pwr.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v2.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v2.h new file mode 100644 index 00000000..cd797fa1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/pwr_common_v2.h @@ -0,0 +1,98 @@ +/** @addtogroup pwr_defines + +@author @htmlonly © @endhtmlonly 2011 Stephen Caudle +@author @htmlonly © @endhtmlonly 2012 Karl Palsson + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_COMMON_V2_H +#define LIBOPENCM3_PWR_COMMON_V2_H + +#include + +/* --- PWR_CR values ------------------------------------------------------- */ + +/* Bits [31:15]: Reserved */ + +/* LPRUN: Low power run mode */ +#define PWR_CR_LPRUN (1 << 14) + +/* VOS[12:11]: Regulator voltage scaling output selection */ +#define PWR_CR_VOS_LSB 11 +/** @defgroup pwr_vos Voltage Scaling Output level selection +@ingroup pwr_defines + +@{*/ +#define PWR_CR_VOS_RANGE1 (0x1 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE2 (0x2 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE3 (0x3 << PWR_CR_VOS_LSB) +/**@}*/ +#define PWR_CR_VOS_MASK (0x3 << PWR_CR_VOS_LSB) + +/* FWU: Fast wakeup */ +#define PWR_CR_FWU (1 << 10) + +/* ULP: Ultralow power mode */ +#define PWR_CR_ULP (1 << 9) + +/* LPSDSR: Low-power deepsleep/sleep/low power run */ +#define PWR_CR_LPSDSR (1 << 0) /* masks common PWR_CR_LPDS */ + +/* --- PWR_CSR values ------------------------------------------------------- */ + +/* EWUP2: Enable WKUP2 pin */ +#define PWR_CSR_EWUP2 (1 << 9) + +/* EWUP1: Enable WKUP1 pin */ +#define PWR_CSR_EWUP1 PWR_CSR_EWUP + +/* REGLPF : Regulator LP flag */ +#define PWR_CSR_REGLPF (1 << 5) + +/* VOSF: Voltage Scaling select flag */ +#define PWR_CSR_VOSF (1 << 4) + +/* VREFINTRDYF: Internal voltage reference (VREFINT) ready flag */ +#define PWR_CSR_VREFINTRDYF (1 << 3) + + + +/* --- Function prototypes ------------------------------------------------- */ + +/** Voltage scales for internal regulator + */ +enum pwr_vos_scale { + /** high performance, highest voltage */ + PWR_SCALE1, + /** medium performance, flash operational but slow */ + PWR_SCALE2, + /** low performance, no flash erase/program */ + PWR_SCALE3, +}; + +BEGIN_DECLS + +void pwr_set_vos_scale(enum pwr_vos_scale scale); + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rcc_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rcc_common_all.h new file mode 100644 index 00000000..49837137 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rcc_common_all.h @@ -0,0 +1,79 @@ +/** @addtogroup rcc_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA RCC.H + * The order of header inclusion is important. rcc.h defines the device + * specific enumerations before including this header file. + */ + +/** @cond */ +#ifdef LIBOPENCM3_RCC_H +/** @endcond */ + +#ifndef LIBOPENCM3_RCC_COMMON_ALL_H +#define LIBOPENCM3_RCC_COMMON_ALL_H + +/**@{*/ + +BEGIN_DECLS + +void rcc_peripheral_enable_clock(volatile uint32_t *reg, uint32_t en); +void rcc_peripheral_disable_clock(volatile uint32_t *reg, uint32_t en); +void rcc_peripheral_reset(volatile uint32_t *reg, uint32_t reset); +void rcc_peripheral_clear_reset(volatile uint32_t *reg, uint32_t clear_reset); + +void rcc_periph_clock_enable(enum rcc_periph_clken clken); +void rcc_periph_clock_disable(enum rcc_periph_clken clken); +void rcc_periph_reset_pulse(enum rcc_periph_rst rst); +void rcc_periph_reset_hold(enum rcc_periph_rst rst); +void rcc_periph_reset_release(enum rcc_periph_rst rst); + +void rcc_set_mco(uint32_t mcosrc); +void rcc_osc_bypass_enable(enum rcc_osc osc); +void rcc_osc_bypass_disable(enum rcc_osc osc); + +/** + * Is the given oscillator ready? + * @param osc Oscillator ID + * @return true if the hardware indicates the oscillator is ready. + */ +bool rcc_is_osc_ready(enum rcc_osc osc); + +/** + * Wait for Oscillator Ready. + * Block until the hardware indicates that the Oscillator is ready. + * @param osc Oscillator ID + */ +void rcc_wait_for_osc_ready(enum rcc_osc osc); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "rcc_common_all.h should not be included explicitly, only via rcc.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rng_common_v1.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rng_common_v1.h new file mode 100644 index 00000000..1f226d77 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rng_common_v1.h @@ -0,0 +1,91 @@ +/** @addtogroup rng_file + */ +/* + * This file is part of the libopencm3 project. + * + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA RNG.H +The order of header inclusion is important. rng.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_RNG_H +/** @endcond */ +#ifndef LIBOPENCM3_RNG_V1_H +#define LIBOPENCM3_RNG_V1_H + +#include +#include + +/**@{*/ + +/* --- Random number generator registers ----------------------------------- */ + +/* Control register */ +#define RNG_CR MMIO32(RNG_BASE + 0x00) + +/* Status register */ +#define RNG_SR MMIO32(RNG_BASE + 0x04) + +/* Data register */ +#define RNG_DR MMIO32(RNG_BASE + 0x08) + +/* --- RNG_CR values ------------------------------------------------------- */ + +/* RNG ENABLE */ +#define RNG_CR_RNGEN (1 << 2) + +/* RNG interrupt enable */ +#define RNG_CR_IE (1 << 3) + +/* --- RNG_SR values ------------------------------------------------------- */ + +/* Data ready */ +#define RNG_SR_DRDY (1 << 0) + +/* Clock error current status */ +#define RNG_SR_CECS (1 << 1) + +/* Seed error current status */ +#define RNG_SR_SECS (1 << 2) + +/* Clock error interrupt status */ +#define RNG_SR_CEIS (1 << 5) + +/* Seed error interrupt status */ +#define RNG_SR_SEIS (1 << 6) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void rng_enable(void); +void rng_disable(void); +bool rng_get_random(uint32_t *rand_nr); +uint32_t rng_get_random_blocking(void); + +END_DECLS + +/**@}*/ + +#endif +/** @cond */ +#else +#warning "rng_common_v1.h should not be included explicitly, only via rng.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rtc_common_l1f024.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rtc_common_l1f024.h new file mode 100644 index 00000000..154652e3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/rtc_common_l1f024.h @@ -0,0 +1,347 @@ +/** @addtogroup rtc_defines + +@author @htmlonly © @endhtmlonly 2012 Karl Palsson + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * This covers the "version 2" RTC peripheral. This is completely different + * to the v1 RTC periph on the F1 series devices. It has BCD counters, with + * automatic leapyear corrections and daylight savings support. + * This peripheral is used on the F0, F2, F3, F4 and L1 devices, though some + * only support a subset. + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA RTC.H +The order of header inclusion is important. rtc.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_RTC_H +/** @endcond */ +#ifndef LIBOPENCM3_RTC2_H +#define LIBOPENCM3_RTC2_H + +/**@{*/ + +/* RTC time register (RTC_TR) */ +#define RTC_TR MMIO32(RTC_BASE + 0x00) + +/* RTC date register (RTC_DR) */ +#define RTC_DR MMIO32(RTC_BASE + 0x04) + +/* RTC control register (RTC_CR) */ +#define RTC_CR MMIO32(RTC_BASE + 0x08) + +/* RTC initialization and status register (RTC_ISR) */ +#define RTC_ISR MMIO32(RTC_BASE + 0x0c) + +/* RTC prescaler register (RTC_PRER) */ +#define RTC_PRER MMIO32(RTC_BASE + 0x10) + +/* RTC wakeup timer register (RTC_WUTR) */ +#define RTC_WUTR MMIO32(RTC_BASE + 0x14) + +/* RTC calibration register (RTC_CALIBR) NB: see also RTC_CALR */ +#define RTC_CALIBR MMIO32(RTC_BASE + 0x18) + +/* RTC alarm X register (RTC_ALRMxR) */ +#define RTC_ALRMAR MMIO32(RTC_BASE + 0x1c) +#define RTC_ALRMBR MMIO32(RTC_BASE + 0x20) + +/* RTC write protection register (RTC_WPR)*/ +#define RTC_WPR MMIO32(RTC_BASE + 0x24) + +/* RTC sub second register (RTC_SSR) (high and med+ only) */ +#define RTC_SSR MMIO32(RTC_BASE + 0x28) + +/* RTC shift control register (RTC_SHIFTR) (high and med+ only) */ +#define RTC_SHIFTR MMIO32(RTC_BASE + 0x2c) + +/* RTC time stamp time register (RTC_TSTR) */ +#define RTC_TSTR MMIO32(RTC_BASE + 0x30) +/* RTC time stamp date register (RTC_TSDR) */ +#define RTC_TSDR MMIO32(RTC_BASE + 0x34) +/* RTC timestamp sub second register (RTC_TSSSR) (high and med+ only) */ +#define RTC_TSSSR MMIO32(RTC_BASE + 0x38) + +/* RTC calibration register (RTC_CALR) (high and med+ only) */ +#define RTC_CALR MMIO32(RTC_BASE + 0x3c) + +/* RTC tamper and alternate function configuration register (RTC_TAFCR) */ +#define RTC_TAFCR MMIO32(RTC_BASE + 0x40) + +/* RTC alarm X sub second register (RTC_ALRMxSSR) (high and med+ only) */ +#define RTC_ALRMASSR MMIO32(RTC_BASE + 0x44) +#define RTC_ALRMBSSR MMIO32(RTC_BASE + 0x48) + +/* RTC backup registers (RTC_BKPxR) */ +#define RTC_BKP_BASE (RTC_BASE + 0x50) +#define RTC_BKPXR(reg) MMIO32(RTC_BKP_BASE + (4 * (reg))) + + +/* RTC time register (RTC_TR) ----------------------------------- */ +/* Note: Bits [31:23], 15, and 7 are reserved, and must be kept at reset value. + */ +#define RTC_TR_PM (1 << 22) /* AM/PM notation */ +#define RTC_TR_HT_SHIFT (20) /* Hour tens in BCD format shift */ +#define RTC_TR_HT_MASK (0x3) /* Hour tens in BCD format mask */ +#define RTC_TR_HU_SHIFT (16) /* Hour units in BCD format shift */ +#define RTC_TR_HU_MASK (0xf) /* Hour units in BCD format mask */ +#define RTC_TR_MNT_SHIFT (12) /* Minute tens in BCD format shift */ +#define RTC_TR_MNT_MASK (0x7) /* Minute tens in BCD format mask */ +#define RTC_TR_MNU_SHIFT (8) /* Minute units in BCD format shift */ +#define RTC_TR_MNU_MASK (0xf) /* Minute units in BCD format mask */ +#define RTC_TR_ST_SHIFT (4) /* Second tens in BCD format shift */ +#define RTC_TR_ST_MASK (0x7) /* Second tens in BCD format mask */ +#define RTC_TR_SU_SHIFT (0) /* Second units in BCD format shift */ +#define RTC_TR_SU_MASK (0xf) /* Second units in BCD format mask */ + +/* RTC date register (RTC_DR) ----------------------------------- */ +/* Note: Bits [31:24] and [7:6] are reserved, and must be kept at reset value. + */ +#define RTC_DR_YT_SHIFT (20) /* Year tens in BCD format shift */ +#define RTC_DR_YT_MASK (0xf) /* Year tens in BCD format mask */ +#define RTC_DR_YU_SHIFT (16) /* Year units in BCD format shift */ +#define RTC_DR_YU_MASK (0xf) /* Year units in BCD format mask */ +#define RTC_DR_WDU_SHIFT (13) /* Weekday units shift */ +#define RTC_DR_WDU_MASK (0x7) /* Weekday units mask */ +#define RTC_DR_MT (1<<12) /* Month tens in BCD format shift */ +#define RTC_DR_MT_SHIFT (12) /* Month tens in BCD format mask */ +#define RTC_DR_MU_SHIFT (8) /* Month units in BCD format shift */ +#define RTC_DR_MU_MASK (0xf) /* Month units in BCD format mask */ +#define RTC_DR_DT_SHIFT (4) /* Date tens in BCD format shift */ +#define RTC_DR_DT_MASK (0x3) /* Date tens in BCD format mask */ +#define RTC_DR_DU_SHIFT (0) /* Date units in BCD format shift */ +#define RTC_DR_DU_MASK (0xf) /* Date units in BCD format mask */ + +/* RTC control register (RTC_CR) -------------------------------- */ +/* Note: Bits [31:24] are reserved, and must be kept at reset value. */ +/* Note: Bits 7, 6 and 4 of this register can be written in initialization mode + * only (RTC_ISR/INITF = 1). + */ +/* Note: Bits 2 to 0 of this register can be written only when RTC_CR WUTE bit + * = 0 and RTC_ISR WUTWF bit = 1. + */ +#define RTC_CR_COE (1<<23) /* RTC_CR_COE: Calibration output enable */ + +/* RTC_CR_OSEL: Output selection values */ +/* Note: These bits are used to select the flag to be routed to AFO_ALARM RTC + * output + */ +#define RTC_CR_OSEL_SHIFT 21 +#define RTC_CR_OSEL_MASK (0x3) +#define RTC_CR_OSEL_DISABLED (0x0) +#define RTC_CR_OSEL_ALARMA (0x1) +#define RTC_CR_OSEL_ALARMB (0x2) +#define RTC_CR_OSEL_WAKEUP (0x3) + +#define RTC_CR_POL (1<<20) /* RTC_CR_POL: Output polarity */ +#define RTC_CR_COSEL (1<<19) /* RTC_CR_COSEL: Calibration output + selection */ +#define RTC_CR_BKP (1<<18) /* RTC_CR_BKP: Backup */ +#define RTC_CR_SUB1H (1<<17) /* RTC_CR_SUB1H: Subtract 1 hour + (winter time change) */ +#define RTC_CR_ADD1H (1<<16) /* RTC_CR_ADD1H: Add 1 hour (summer + time change) */ +#define RTC_CR_TSIE (1<<15) /* RTC_CR_TSIE: Timestamp interrupt + enable */ +#define RTC_CR_WUTIE (1<<14) /* RTC_CR_WUTIE: Wakeup timer + interrupt enable */ +#define RTC_CR_ALRBIE (1<<13) /* RTC_CR_ALRBIE: Alarm B interrupt + enable */ +#define RTC_CR_ALRAIE (1<<12) /* RTC_CR_ALRAIE: Alarm A interrupt + enable */ +#define RTC_CR_TSE (1<<11) /* RTC_CR_TSE: Time stamp enable */ +#define RTC_CR_WUTE (1<<10) /* RTC_CR_WUTE: Wakeup timer enable */ +#define RTC_CR_ALRBE (1<<9) /* RTC_CR_ALRBIE: Alarm B enable */ +#define RTC_CR_ALRAE (1<<8) /* RTC_CR_ALRAE: Alarm A enable */ +#define RTC_CR_DCE (1<<7) /* RTC_CR_DCE: Course digital + calibration enable */ +#define RTC_CR_FMT (1<<6) /* RTC_CR_FMT: Hour format */ +#define RTC_CR_BYPSHAD (1<<5) /* RTC_CR_BYPSHAD: Bypass the shadow + registers */ +#define RTC_CR_REFCKON (1<<4) /* RTC_CR_REFCKON: Reference clock + detection enable */ +#define RTC_CR_TSEDGE (1<<3) /* RTC_CR_TSEDGE: Timestamp event + active edge */ + +/* RTC_CR_WUCKSEL: Wakeup clock selection */ +#define RTC_CR_WUCLKSEL_SHIFT (0) +#define RTC_CR_WUCLKSEL_MASK (0x7) +#define RTC_CR_WUCLKSEL_RTC_DIV16 (0x0) +#define RTC_CR_WUCLKSEL_RTC_DIV8 (0x1) +#define RTC_CR_WUCLKSEL_RTC_DIV4 (0x2) +#define RTC_CR_WUCLKSEL_RTC_DIV2 (0x3) +#define RTC_CR_WUCLKSEL_SPRE (0x4) +#define RTC_CR_WUCLKSEL_SPRE_216 (0x6) + +/* RTC initialization and status register (RTC_ISR) ------------- */ +/* Note: Bits [31:17] and [15] are reserved, and must be kept at reset value. */ +/* Note: This register is write protected (except for RTC_ISR[13:8] bits). */ +#define RTC_ISR_RECALPF (1<<16) /* RECALPF: Recalib pending flag */ +#define RTC_ISR_TAMP3F (1<<15) /* TAMP3F: TAMPER3 detection flag + (not on F4)*/ +#define RTC_ISR_TAMP2F (1<<14) /* TAMP2F: TAMPER2 detection flag */ +#define RTC_ISR_TAMP1F (1<<13) /* TAMP1F: TAMPER detection flag */ +#define RTC_ISR_TSOVF (1<<12) /* TSOVF: Timestamp overflow flag */ +#define RTC_ISR_TSF (1<<11) /* TSF: Timestamp flag */ +#define RTC_ISR_WUTF (1<<10) /* WUTF: Wakeup timer flag */ +#define RTC_ISR_ALRBF (1<<9) /* ALRBF: Alarm B flag */ +#define RTC_ISR_ALRAF (1<<8) /* ALRAF: Alarm A flag */ +#define RTC_ISR_INIT (1<<7) /* INIT: Initialization mode */ +#define RTC_ISR_INITF (1<<6) /* INITF: Initialization flag */ +#define RTC_ISR_RSF (1<<5) /* RSF: Registers sync flag */ +#define RTC_ISR_INITS (1<<4) /* INITS: Init status flag */ +#define RTC_ISR_SHPF (1<<3) /* SHPF: Shift operation pending */ +#define RTC_ISR_WUTWF (1<<2) /* WUTWF: Wakeup timer write flag */ +#define RTC_ISR_ALRBWF (1<<1) /* ALRBWF: Alarm B write flag */ +#define RTC_ISR_ALRAWF (1<<0) /* ALRAWF: Alarm A write flag */ + +/* RTC prescaler register (RTC_PRER) ---------------------------- */ +#define RTC_PRER_PREDIV_A_SHIFT (16) /* Async prescaler factor shift */ +#define RTC_PRER_PREDIV_A_MASK (0x7f) /* Async prescaler factor mask */ +#define RTC_PRER_PREDIV_S_SHIFT (0) /* Sync prescaler factor shift */ +#define RTC_PRER_PREDIV_S_MASK (0x7fff) /* Sync prescaler factor mask */ + +/* RTC calibration register (RTC_CALIBR) ------------------------ */ +/* FIXME - TODO */ + +/* RTC Alarm register ------------------------------------------- */ +/* Note: Applies to RTC_ALRMAR and RTC_ALRMBR */ +#define RTC_ALRMXR_MSK4 (1<<31) +#define RTC_ALRMXR_WDSEL (1<<30) +#define RTC_ALRMXR_DT_SHIFT (28) +#define RTC_ALRMXR_DT_MASK (0x3) +#define RTC_ALRMXR_DU_SHIFT (24) +#define RTC_ALRMXR_DU_MASK (0xf) +#define RTC_ALRMXR_MSK3 (1<<23) +#define RTC_ALRMXR_PM (1<<22) +#define RTC_ALRMXR_HT_SHIFT (20) +#define RTC_ALRMXR_HT_MASK (0x3) +#define RTC_ALRMXR_HU_SHIFT (16) +#define RTC_ALRMXR_HU_MASK (0xf) +#define RTC_ALRMXR_MSK2 (1<<15) +#define RTC_ALRMXR_MNT_SHIFT (12) +#define RTC_ALRMXR_MNT_MASK (0x7) +#define RTC_ALRMXR_MNU_SHIFT (8) +#define RTC_ALRMXR_MNU_MASK (0xf) +#define RTC_ALRMXR_MSK1 (1<<7) +#define RTC_ALRMXR_ST_SHIFT (4) +#define RTC_ALRMXR_ST_MASK (0x7) +#define RTC_ALRMXR_SU_SHIFT (0) +#define RTC_ALRMXR_SU_MASK (0xf) + +/* RTC shift control register (RTC_SHIFTR) */ +/* FIXME - TODO */ + +/* RTC time stamp time register (RTC_TSTR) ---------------------- */ +#define RTC_TSTR_PM (1<<22) +#define RTC_TSTR_HT_SHIFT (20) +#define RTC_TSTR_HT_MASK (0x3) +#define RTC_TSTR_HU_SHIFT (16) +#define RTC_TSTR_HU_MASK (0xf) +#define RTC_TSTR_MNT_SHIFT (12) +#define RTC_TSTR_MNT_MASK (0x7) +#define RTC_TSTR_MNU_SHIFT (8) +#define RTC_TSTR_MNU_MASK (0xf) +#define RTC_TSTR_ST_SHIFT (4) +#define RTC_TSTR_ST_MASK (0x7) +#define RTC_TSTR_SU_SHIFT (0) +#define RTC_TSTR_SU_MASK (0xf) + +/* RTC time stamp date register (RTC_TSDR) ---------------------- */ +#define RTC_TSDR_WDU_SHIFT (13) +#define RTC_TSDR_WDU_MASK (0x7) +#define RTC_TSDR_MT (1<<12) +#define RTC_TSDR_MU_SHIFT (8) +#define RTC_TSDR_MU_MASK (0xf) +#define RTC_TSDR_DT_SHIFT (4) +#define RTC_TSDR_DT_MASK (0x3) +#define RTC_TSDR_DU_SHIFT (0) +#define RTC_TSDR_DU_MASK (0xf) + +/* RTC calibration register (RTC_CALR) -------------------------- */ +/* FIXME - TODO */ + +/* RTC tamper and alternate function configuration register (RTC_TAFCR) --- */ +#define RTC_TAFCR_ALARMOUTTYPE (1<<18) +#define RTC_TAFCR_TAMPPUDIS (1<<15) + +#define RTC_TAFCR_TAMPPRCH_SHIFT (13) +#define RTC_TAFCR_TAMPPRCH_MASK (0x3) +#define RTC_TAFCR_TAMPPRCH_1RTC (0x0) +#define RTC_TAFCR_TAMPPRCH_2RTC (0x1) +#define RTC_TAFCR_TAMPPRCH_4RTC (0x2) +#define RTC_TAFCR_TAMPPRCH_8RTC (0x3) + +#define RTC_TAFCR_TAMPFLT_SHIFT (11) +#define RTC_TAFCR_TAMPFLT_MASK (0x3) +#define RTC_TAFCR_TAMPFLT_EDGE1 (0x0) +#define RTC_TAFCR_TAMPFLT_EDGE2 (0x1) +#define RTC_TAFCR_TAMPFLT_EDGE4 (0x2) +#define RTC_TAFCR_TAMPFLT_EDGE8 (0x3) + +#define RTC_TAFCR_TAMPFREQ_SHIFT (8) +#define RTC_TAFCR_TAMPFREQ_MASK (0x7) +#define RTC_TAFCR_TAMPFREQ_RTCDIV32K (0x0) +#define RTC_TAFCR_TAMPFREQ_RTCDIV16K (0x1) +#define RTC_TAFCR_TAMPFREQ_RTCDIV8K (0x2) +#define RTC_TAFCR_TAMPFREQ_RTCDIV4K (0x3) +#define RTC_TAFCR_TAMPFREQ_RTCDIV2K (0x4) +#define RTC_TAFCR_TAMPFREQ_RTCDIV1K (0x5) +#define RTC_TAFCR_TAMPFREQ_RTCDIV512 (0x6) +#define RTC_TAFCR_TAMPFREQ_RTCDIV256 (0x7) + +#define RTC_TAFCR_TAMPTS (1<<7) +#define RTC_TAFCR_TAMP3TRG (1<<6) +#define RTC_TAFCR_TAMP3E (1<<5) +#define RTC_TAFCR_TAMP2TRG (1<<4) +#define RTC_TAFCR_TAMP2E (1<<3) +#define RTC_TAFCR_TAMPIE (1<<2) +#define RTC_TAFCR_TAMP1TRG (1<<1) +#define RTC_TAFCR_TAMP1E (1<<0) + +/* RTC alarm X sub second register */ +/* FIXME - TODO */ + + + +BEGIN_DECLS + +void rtc_set_prescaler(uint32_t sync, uint32_t async); +void rtc_wait_for_synchro(void); +void rtc_lock(void); +void rtc_unlock(void); +void rtc_set_wakeup_time(uint16_t wkup_time, uint8_t rtc_cr_wucksel); +void rtc_clear_wakeup_flag(void); + +END_DECLS +/**@}*/ + +#endif /* RTC2_H */ +/** @cond */ +#else +#warning "rtc_common_bcd.h should not be included explicitly, only via rtc.h" +#endif +/** @endcond */ + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_all.h new file mode 100644 index 00000000..7997e587 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_all.h @@ -0,0 +1,406 @@ +/** @addtogroup spi_defines + * + * @author @htmlonly © @endhtmlonly 2009 Uwe Hermann + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA SPI.H +The order of header inclusion is important. spi.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#if defined(LIBOPENCM3_SPI_H) +/** @endcond */ +#ifndef LIBOPENCM3_SPI_COMMON_ALL_H +#define LIBOPENCM3_SPI_COMMON_ALL_H + +/**@{*/ + +/* Registers can be accessed as 16bit or 32bit values. */ + +/* --- Convenience macros -------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup spi_reg_base SPI Register base address +@ingroup spi_defines + +@{*/ +#define SPI1 SPI1_BASE +#define SPI2 SPI2_BASE +#define SPI3 SPI3_BASE +#define SPI4 SPI4_BASE +#define SPI5 SPI5_BASE +#define SPI6 SPI6_BASE +/**@}*/ + +/* --- SPI registers ------------------------------------------------------- */ + +/* Control register 1 (SPIx_CR1) */ +/* Note: Not used in I2S mode. */ +#define SPI_CR1(spi_base) MMIO32((spi_base) + 0x00) +#define SPI1_CR1 SPI_CR1(SPI1_BASE) +#define SPI2_CR1 SPI_CR1(SPI2_BASE) +#define SPI3_CR1 SPI_CR1(SPI3_BASE) + +/* Control register 2 (SPIx_CR2) */ +#define SPI_CR2(spi_base) MMIO32((spi_base) + 0x04) +#define SPI1_CR2 SPI_CR2(SPI1_BASE) +#define SPI2_CR2 SPI_CR2(SPI2_BASE) +#define SPI3_CR2 SPI_CR2(SPI3_BASE) + +/* Status register (SPIx_SR) */ +#define SPI_SR(spi_base) MMIO32((spi_base) + 0x08) +#define SPI1_SR SPI_SR(SPI1_BASE) +#define SPI2_SR SPI_SR(SPI2_BASE) +#define SPI3_SR SPI_SR(SPI3_BASE) + +/* Data register (SPIx_DR) */ +#define SPI_DR(spi_base) MMIO32((spi_base) + 0x0c) +#define SPI1_DR SPI_DR(SPI1_BASE) +#define SPI2_DR SPI_DR(SPI2_BASE) +#define SPI3_DR SPI_DR(SPI3_BASE) + +/* CRC polynomial register (SPIx_CRCPR) */ +/* Note: Not used in I2S mode. */ +#define SPI_CRCPR(spi_base) MMIO32((spi_base) + 0x10) +#define SPI1_CRCPR SPI_CRCPR(SPI1_BASE) +#define SPI2_CRCPR SPI_CRCPR(SPI2_BASE) +#define SPI3_CRCPR SPI_CRCPR(SPI3_BASE) + +/* RX CRC register (SPIx_RXCRCR) */ +/* Note: Not used in I2S mode. */ +#define SPI_RXCRCR(spi_base) MMIO32((spi_base) + 0x14) +#define SPI1_RXCRCR SPI_RXCRCR(SPI1_BASE) +#define SPI2_RXCRCR SPI_RXCRCR(SPI2_BASE) +#define SPI3_RXCRCR SPI_RXCRCR(SPI3_BASE) + +/* TX CRC register (SPIx_RXCRCR) */ +/* Note: Not used in I2S mode. */ +#define SPI_TXCRCR(spi_base) MMIO32((spi_base) + 0x18) +#define SPI1_TXCRCR SPI_TXCRCR(SPI1_BASE) +#define SPI2_TXCRCR SPI_TXCRCR(SPI2_BASE) +#define SPI3_TXCRCR SPI_TXCRCR(SPI3_BASE) + +/* I2S configuration register (SPIx_I2SCFGR) */ +#define SPI_I2SCFGR(spi_base) MMIO32((spi_base) + 0x1c) +#define SPI1_I2SCFGR SPI_I2SCFGR(SPI1_BASE) +#define SPI2_I2SCFGR SPI_I2SCFGR(SPI2_BASE) +#define SPI3_I2SCFGR SPI_I2SCFGR(SPI3_BASE) + +/* I2S prescaler register (SPIx_I2SPR) */ +#define SPI_I2SPR(spi_base) MMIO32((spi_base) + 0x20) +#define SPI1_I2SPR SPI_I2SPR(SPI1_BASE) +#define SPI2_I2SPR SPI_I2SPR(SPI2_BASE) +#define SPI3_I2SPR SPI_I2SPR(SPI3_BASE) + +/* --- SPI_CR1 values ------------------------------------------------------ */ + +/* Note: None of the CR1 bits are used in I2S mode. */ + +/* BIDIMODE: Bidirectional data mode enable */ +#define SPI_CR1_BIDIMODE_2LINE_UNIDIR (0 << 15) +#define SPI_CR1_BIDIMODE_1LINE_BIDIR (1 << 15) +#define SPI_CR1_BIDIMODE (1 << 15) + +/* BIDIOE: Output enable in bidirectional mode */ +#define SPI_CR1_BIDIOE (1 << 14) + +/* CRCEN: Hardware CRC calculation enable */ +#define SPI_CR1_CRCEN (1 << 13) + +/* CRCNEXT: Transmit CRC next */ +#define SPI_CR1_CRCNEXT (1 << 12) + +/* RXONLY: Receive only */ +#define SPI_CR1_RXONLY (1 << 10) + +/* SSM: Software slave management */ +#define SPI_CR1_SSM (1 << 9) + +/* SSI: Internal slave select */ +#define SPI_CR1_SSI (1 << 8) + +/* LSBFIRST: Frame format */ +/****************************************************************************/ +/** @defgroup spi_lsbfirst SPI lsb/msb first +@ingroup spi_defines + +@{*/ +#define SPI_CR1_MSBFIRST (0 << 7) +#define SPI_CR1_LSBFIRST (1 << 7) +/**@}*/ + +/* SPE: SPI enable */ +#define SPI_CR1_SPE (1 << 6) + +/* BR[2:0]: Baud rate control */ +/****************************************************************************/ +/** @defgroup spi_baudrate SPI peripheral baud rates +@ingroup spi_defines + +@{*/ +#define SPI_CR1_BAUDRATE_FPCLK_DIV_2 (0x00 << 3) +#define SPI_CR1_BAUDRATE_FPCLK_DIV_4 (0x01 << 3) +#define SPI_CR1_BAUDRATE_FPCLK_DIV_8 (0x02 << 3) +#define SPI_CR1_BAUDRATE_FPCLK_DIV_16 (0x03 << 3) +#define SPI_CR1_BAUDRATE_FPCLK_DIV_32 (0x04 << 3) +#define SPI_CR1_BAUDRATE_FPCLK_DIV_64 (0x05 << 3) +#define SPI_CR1_BAUDRATE_FPCLK_DIV_128 (0x06 << 3) +#define SPI_CR1_BAUDRATE_FPCLK_DIV_256 (0x07 << 3) +/**@}*/ +/****************************************************************************/ +/** @defgroup spi_br_pre SPI peripheral baud rate prescale values +@ingroup spi_defines + +@{*/ +#define SPI_CR1_BR_FPCLK_DIV_2 0x0 +#define SPI_CR1_BR_FPCLK_DIV_4 0x1 +#define SPI_CR1_BR_FPCLK_DIV_8 0x2 +#define SPI_CR1_BR_FPCLK_DIV_16 0x3 +#define SPI_CR1_BR_FPCLK_DIV_32 0x4 +#define SPI_CR1_BR_FPCLK_DIV_64 0x5 +#define SPI_CR1_BR_FPCLK_DIV_128 0x6 +#define SPI_CR1_BR_FPCLK_DIV_256 0x7 +/**@}*/ + +/* MSTR: Master selection */ +#define SPI_CR1_MSTR (1 << 2) + +/* CPOL: Clock polarity */ +/****************************************************************************/ +/** @defgroup spi_cpol SPI clock polarity +@ingroup spi_defines + +@{*/ +#define SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE (0 << 1) +#define SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE (1 << 1) +/**@}*/ +#define SPI_CR1_CPOL (1 << 1) + +/* CPHA: Clock phase */ +/****************************************************************************/ +/** @defgroup spi_cpha SPI clock phase +@ingroup spi_defines + +@{*/ +#define SPI_CR1_CPHA_CLK_TRANSITION_1 (0 << 0) +#define SPI_CR1_CPHA_CLK_TRANSITION_2 (1 << 0) +/**@}*/ +#define SPI_CR1_CPHA (1 << 0) + +/* --- SPI_CR2 values ------------------------------------------------------ */ + +/* Bits [15:8]: Reserved. Forced to 0 by hardware. Used on F3. */ + +/* TXEIE: Tx buffer empty interrupt enable */ +#define SPI_CR2_TXEIE (1 << 7) + +/* RXNEIE: Rx buffer not empty interrupt enable */ +#define SPI_CR2_RXNEIE (1 << 6) + +/* ERRIE: Error interrupt enable */ +#define SPI_CR2_ERRIE (1 << 5) + +/* Bits [4:3]: Reserved. Forced to 0 by hardware. */ + +/* SSOE: SS output enable */ +/* Note: Not used in I2S mode. */ +#define SPI_CR2_SSOE (1 << 2) + +/* TXDMAEN: Tx buffer DMA enable */ +#define SPI_CR2_TXDMAEN (1 << 1) + +/* RXDMAEN: Rx buffer DMA enable */ +#define SPI_CR2_RXDMAEN (1 << 0) + +/* --- SPI_SR values ------------------------------------------------------- */ + +/* Bits [15:8]: Reserved. Forced to 0 by hardware. Used on F3. */ + +/* BSY: Busy flag */ +#define SPI_SR_BSY (1 << 7) + +/* OVR: Overrun flag */ +#define SPI_SR_OVR (1 << 6) + +/* MODF: Mode fault */ +/* Note: Not used in I2S mode. */ +#define SPI_SR_MODF (1 << 5) + +/* CRCERR: CRC error flag */ +/* Note: Not used in I2S mode. */ +#define SPI_SR_CRCERR (1 << 4) + +/* UDR: Underrun flag */ +/* Note: Not used in SPI mode. */ +#define SPI_SR_UDR (1 << 3) + +/* CHSIDE: Channel side */ +/* Note: Not used in SPI mode. No meaning in PCM mode. */ +#define SPI_SR_CHSIDE (1 << 2) + +/* TXE: Transmit buffer empty */ +#define SPI_SR_TXE (1 << 1) + +/* RXNE: Receive buffer not empty */ +#define SPI_SR_RXNE (1 << 0) + +/* --- SPI_DR values ------------------------------------------------------- */ + +/* SPI_DR[15:0]: Data Register. */ + +/* --- SPI_CRCPR values ---------------------------------------------------- */ + +/* Note: Not used in I2S mode. */ +/* SPI_CRCPR [15:0]: CRC Polynomial Register. */ + +/* --- SPI_RXCRCR values --------------------------------------------------- */ + +/* Note: Not used in I2S mode. */ +/* SPI_RXCRCR [15:0]: RX CRC Register. */ + +/* --- SPI_TXCRCR values --------------------------------------------------- */ + +/* Note: Not used in I2S mode. */ +/* SPI_TXCRCR [15:0]: TX CRC Register. */ + +/* --- SPI_I2SCFGR values -------------------------------------------------- */ + +/* Note: None of these bits are used in SPI mode. */ + +/* Bits [15:12]: Reserved. Forced to 0 by hardware. */ + +/* I2SMOD: I2S mode selection */ +#define SPI_I2SCFGR_I2SMOD (1 << 11) + +/* I2SE: I2S enable */ +#define SPI_I2SCFGR_I2SE (1 << 10) + +/* I2SCFG[9:8]: I2S configuration mode */ +#define SPI_I2SCFGR_I2SCFG_LSB 8 +#define SPI_I2SCFGR_I2SCFG_SLAVE_TRANSMIT 0x0 +#define SPI_I2SCFGR_I2SCFG_SLAVE_RECEIVE 0x1 +#define SPI_I2SCFGR_I2SCFG_MASTER_TRANSMIT 0x2 +#define SPI_I2SCFGR_I2SCFG_MASTER_RECEIVE 0x3 + +/* PCMSYNC: PCM frame synchronization */ +#define SPI_I2SCFGR_PCMSYNC (1 << 7) + +/* Bit 6: Reserved. Forced to 0 by hardware. */ + +/* I2SSTD[5:4]: I2S standard selection */ +#define SPI_I2SCFGR_I2SSTD_LSB 4 +#define SPI_I2SCFGR_I2SSTD_I2S_PHILIPS 0x0 +#define SPI_I2SCFGR_I2SSTD_MSB_JUSTIFIED 0x1 +#define SPI_I2SCFGR_I2SSTD_LSB_JUSTIFIED 0x2 +#define SPI_I2SCFGR_I2SSTD_PCM 0x3 + +/* CKPOL: Steady state clock polarity */ +#define SPI_I2SCFGR_CKPOL (1 << 3) + +/* DATLEN[2:1]: Data length to be transferred */ +#define SPI_I2SCFGR_DATLEN_LSB 1 +#define SPI_I2SCFGR_DATLEN_16BIT 0x0 +#define SPI_I2SCFGR_DATLEN_24BIT 0x1 +#define SPI_I2SCFGR_DATLEN_32BIT 0x2 + +/* CHLEN: Channel length */ +#define SPI_I2SCFGR_CHLEN (1 << 0) + +/* --- SPI_I2SPR values ---------------------------------------------------- */ + +/* Note: None of these bits are used in SPI mode. */ + +/* Bits [15:10]: Reserved. Forced to 0 by hardware. */ + +/* MCKOE: Master clock output enable */ +#define SPI_I2SPR_MCKOE (1 << 9) + +/* ODD: Odd factor for the prescaler */ +#define SPI_I2SPR_ODD (1 << 8) + +/* I2SDIV[7:0]: I2S linear prescaler */ +/* 0 and 1 are forbidden values */ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void spi_reset(uint32_t spi_peripheral); +int spi_init_master(uint32_t spi, uint32_t br, uint32_t cpol, uint32_t cpha, + uint32_t dff, uint32_t lsbfirst); +void spi_enable(uint32_t spi); +void spi_disable(uint32_t spi); +uint16_t spi_clean_disable(uint32_t spi); +void spi_write(uint32_t spi, uint16_t data); +void spi_send(uint32_t spi, uint16_t data); +uint16_t spi_read(uint32_t spi); +uint16_t spi_xfer(uint32_t spi, uint16_t data); +void spi_set_bidirectional_mode(uint32_t spi); +void spi_set_unidirectional_mode(uint32_t spi); +void spi_set_bidirectional_receive_only_mode(uint32_t spi); +void spi_set_bidirectional_transmit_only_mode(uint32_t spi); +void spi_enable_crc(uint32_t spi); +void spi_disable_crc(uint32_t spi); +void spi_set_next_tx_from_buffer(uint32_t spi); +void spi_set_next_tx_from_crc(uint32_t spi); +void spi_set_dff_8bit(uint32_t spi); +void spi_set_dff_16bit(uint32_t spi); +void spi_set_full_duplex_mode(uint32_t spi); +void spi_set_receive_only_mode(uint32_t spi); +void spi_disable_software_slave_management(uint32_t spi); +void spi_enable_software_slave_management(uint32_t spi); +void spi_set_nss_high(uint32_t spi); +void spi_set_nss_low(uint32_t spi); +void spi_send_lsb_first(uint32_t spi); +void spi_send_msb_first(uint32_t spi); +void spi_set_baudrate_prescaler(uint32_t spi, uint8_t baudrate); +void spi_set_master_mode(uint32_t spi); +void spi_set_slave_mode(uint32_t spi); +void spi_set_clock_polarity_1(uint32_t spi); +void spi_set_clock_polarity_0(uint32_t spi); +void spi_set_clock_phase_1(uint32_t spi); +void spi_set_clock_phase_0(uint32_t spi); +void spi_enable_tx_buffer_empty_interrupt(uint32_t spi); +void spi_disable_tx_buffer_empty_interrupt(uint32_t spi); +void spi_enable_rx_buffer_not_empty_interrupt(uint32_t spi); +void spi_disable_rx_buffer_not_empty_interrupt(uint32_t spi); +void spi_enable_error_interrupt(uint32_t spi); +void spi_disable_error_interrupt(uint32_t spi); +void spi_enable_ss_output(uint32_t spi); +void spi_disable_ss_output(uint32_t spi); +void spi_enable_tx_dma(uint32_t spi); +void spi_disable_tx_dma(uint32_t spi); +void spi_enable_rx_dma(uint32_t spi); +void spi_disable_rx_dma(uint32_t spi); +void spi_set_standard_mode(uint32_t spi, uint8_t mode); + +END_DECLS + +/**@}*/ + +#endif +/** @cond */ +#else +#warning "spi_common_all.h should not be included explicitly, only via spi.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f03.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f03.h new file mode 100644 index 00000000..ac0f27d7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f03.h @@ -0,0 +1,124 @@ +/** @addtogroup spi_defines + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA SPI.H + * The order of header inclusion is important. spi.h includes the device + * specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_SPI_H +/** @endcond */ +#ifndef LIBOPENCM3_SPI_COMMON_F03_H +#define LIBOPENCM3_SPI_COMMON_F03_H + +/**@{*/ + +#include + +/* + * This file extends the common stm32 version with defintions only + * applicable to the STM32F0/F3 series of devices + */ + +#define SPI_DR8(spi_base) MMIO8((spi_base) + 0x0c) +#define SPI1_DR8 SPI_DR8(SPI1_BASE) +#define SPI2_DR8 SPI_DR8(SPI2_BASE) +#define SPI3_DR8 SPI_DR8(SPI3_BASE) + +/* DFF: Data frame format */ +/****************************************************************************/ +/** @defgroup spi_dff SPI data frame format + * @ingroup spi_defines + * + * @{*/ + +#define SPI_CR1_CRCL_8BIT (0 << 11) +#define SPI_CR1_CRCL_16BIT (1 << 11) +/**@}*/ +#define SPI_CR1_CRCL (1 << 11) + +/* --- SPI_CR2 values ------------------------------------------------------ */ + +/* LDMA_TX: Last DMA transfer for transmission */ +#define SPI_CR2_LDMA_TX (1 << 14) + +/* LDMA_RX: Last DMA transfer for reception */ +#define SPI_CR2_LDMA_RX (1 << 13) + +/* FRXTH: FIFO reception threshold */ +#define SPI_CR2_FRXTH (1 << 12) + +/* DS [3:0]: Data size */ +/* 0x0 - 0x2 NOT USED */ +#define SPI_CR2_DS_4BIT (0x3 << 8) +#define SPI_CR2_DS_5BIT (0x4 << 8) +#define SPI_CR2_DS_6BIT (0x5 << 8) +#define SPI_CR2_DS_7BIT (0x6 << 8) +#define SPI_CR2_DS_8BIT (0x7 << 8) +#define SPI_CR2_DS_9BIT (0x8 << 8) +#define SPI_CR2_DS_10BIT (0x9 << 8) +#define SPI_CR2_DS_11BIT (0xA << 8) +#define SPI_CR2_DS_12BIT (0xB << 8) +#define SPI_CR2_DS_13BIT (0xC << 8) +#define SPI_CR2_DS_14BIT (0xD << 8) +#define SPI_CR2_DS_15BIT (0xE << 8) +#define SPI_CR2_DS_16BIT (0xF << 8) +#define SPI_CR2_DS_MASK (0xF << 8) + +/* NSSP: NSS pulse management */ +#define SPI_CR2_NSSP (1 << 3) + +/* --- SPI_SR values ------------------------------------------------------- */ + +/* FTLVL[1:0]: FIFO Transmission Level */ +#define SPI_SR_FTLVL_FIFO_EMPTY (0x0 << 11) +#define SPI_SR_FTLVL_QUARTER_FIFO (0x1 << 11) +#define SPI_SR_FTLVL_HALF_FIFO (0x2 << 11) +#define SPI_SR_FTLVL_FIFO_FULL (0x3 << 11) + +/* FRLVL[1:0]: FIFO Reception Level */ +#define SPI_SR_FRLVL_FIFO_EMPTY (0x0 << 9) +#define SPI_SR_FRLVL_QUARTER_FIFO (0x1 << 9) +#define SPI_SR_FRLVL_HALF_FIFO (0x2 << 9) +#define SPI_SR_FRLVL_FIFO_FULL (0x3 << 9) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void spi_set_crcl_8bit(uint32_t spi); +void spi_set_crcl_16bit(uint32_t spi); +void spi_set_data_size(uint32_t spi, uint16_t data_s); +void spi_fifo_reception_threshold_8bit(uint32_t spi); +void spi_fifo_reception_threshold_16bit(uint32_t spi); +void spi_i2s_mode_spi_mode(uint32_t spi); +void spi_send8(uint32_t spi, uint8_t data); +uint8_t spi_read8(uint32_t spi); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "spi_common_f03.h should not be included explicitly, only via spi.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f24.h new file mode 100644 index 00000000..f8946261 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_f24.h @@ -0,0 +1,66 @@ +/** @addtogroup spi_defines + +@author @htmlonly © @endhtmlonly 2011 Fergus Noble + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA SPI.H +The order of header inclusion is important. spi.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_SPI_H +/** @endcond */ +#ifndef LIBOPENCM3_SPI_COMMON_F24_H +#define LIBOPENCM3_SPI_COMMON_F24_H + +/**@{*/ + +#include + +/* + * This file extends the common STM32 version with definitions only + * applicable to the STM32F2/4 series of devices. + */ + +/* Note, these values are also on the F0, but other parts are _not_ */ + +/* --- SPI_CR2 values ------------------------------------------------------ */ + +/* FRF: Frame format */ +/* Note: Not used in I2S mode. */ +#define SPI_CR2_FRF (1 << 4) +#define SPI_CR2_FRF_MOTOROLA_MODE (0 << 4) +#define SPI_CR2_FRF_TI_MODE (1 << 4) + +/* --- SPI_SR values ------------------------------------------------------- */ + +/* TIFRFE: TI frame format error */ +#define SPI_SR_TIFRFE (1 << 8) + +#endif +/** @cond */ +#else +#warning "spi_common_f24.h should not be included explicitly, only via spi.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_l1f124.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_l1f124.h new file mode 100644 index 00000000..ddfe6128 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/spi_common_l1f124.h @@ -0,0 +1,65 @@ +/** @addtogroup spi_defines + +@author @htmlonly © @endhtmlonly 2011 Fergus Noble + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA SPI.H +The order of header inclusion is important. spi.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_SPI_H +/** @endcond */ +#ifndef LIBOPENCM3_SPI_COMMON_L1F124_H +#define LIBOPENCM3_SPI_COMMON_L1F124_H + +/**@{*/ + +#include + +/* + * This file extends the common STM32 version with definitions only + * applicable to the STM32L1/F1/2/4 series of devices. + */ + +/* DFF: Data frame format */ +/****************************************************************************/ +/** @defgroup spi_dff SPI data frame format +@ingroup spi_defines + +@{*/ + +#define SPI_CR1_DFF_8BIT (0 << 11) +#define SPI_CR1_DFF_16BIT (1 << 11) + +/**@}*/ + +#define SPI_CR1_DFF (1 << 11) + +#endif +/** @cond */ +#else +#warning "spi_common_l1f124.h should not be included explicitly, only via spi.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_common.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_common.h new file mode 100644 index 00000000..874aa503 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_common.h @@ -0,0 +1,302 @@ +/** @defgroup usb_defines USB Defines + +@brief Defined Constants and Types for the STM32F* USB drivers + +@ingroup STM32Fx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 +Piotr Esden-Tempski + +@date 11 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +/**@{*/ + +/** @cond */ +#ifdef LIBOPENCM3_ST_USBFS_H +/** @endcond */ +#ifndef LIBOPENCM3_ST_USBFS_COMMON_H +#define LIBOPENCM3_ST_USBFS_COMMON_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +/* --- USB general registers ----------------------------------------------- */ + +/* USB Control register */ +#define USB_CNTR_REG (&MMIO32(USB_DEV_FS_BASE + 0x40)) +/* USB Interrupt status register */ +#define USB_ISTR_REG (&MMIO32(USB_DEV_FS_BASE + 0x44)) +/* USB Frame number register */ +#define USB_FNR_REG (&MMIO32(USB_DEV_FS_BASE + 0x48)) +/* USB Device address register */ +#define USB_DADDR_REG (&MMIO32(USB_DEV_FS_BASE + 0x4C)) +/* USB Buffer table address register */ +#define USB_BTABLE_REG (&MMIO32(USB_DEV_FS_BASE + 0x50)) + +/* USB EP register */ +#define USB_EP_REG(EP) (&MMIO32(USB_DEV_FS_BASE) + (EP)) + + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- USB control register masks / bits ----------------------------------- */ + +/* Interrupt mask bits, set to 1 to enable interrupt generation */ +#define USB_CNTR_CTRM 0x8000 +#define USB_CNTR_PMAOVRM 0x4000 +#define USB_CNTR_ERRM 0x2000 +#define USB_CNTR_WKUPM 0x1000 +#define USB_CNTR_SUSPM 0x0800 +#define USB_CNTR_RESETM 0x0400 +#define USB_CNTR_SOFM 0x0200 +#define USB_CNTR_ESOFM 0x0100 + +/* Request/Force bits */ +#define USB_CNTR_RESUME 0x0010 /* Resume request */ +#define USB_CNTR_FSUSP 0x0008 /* Force suspend */ +#define USB_CNTR_LP_MODE 0x0004 /* Low-power mode */ +#define USB_CNTR_PWDN 0x0002 /* Power down */ +#define USB_CNTR_FRES 0x0001 /* Force reset */ + +/* --- USB interrupt status register masks / bits -------------------------- */ + +#define USB_ISTR_CTR 0x8000 /* Correct Transfer */ +#define USB_ISTR_PMAOVR 0x4000 /* Packet Memory Area Over / Underrun */ +#define USB_ISTR_ERR 0x2000 /* Error */ +#define USB_ISTR_WKUP 0x1000 /* Wake up */ +#define USB_ISTR_SUSP 0x0800 /* Suspend mode request */ +#define USB_ISTR_RESET 0x0400 /* USB RESET request */ +#define USB_ISTR_SOF 0x0200 /* Start Of Frame */ +#define USB_ISTR_ESOF 0x0100 /* Expected Start Of Frame */ +#define USB_ISTR_DIR 0x0010 /* Direction of transaction */ +#define USB_ISTR_EP_ID 0x000F /* Endpoint Identifier */ + +/* --- USB interrupt status register manipulators -------------------------- */ + +/* Note: CTR is read only! */ +#define USB_CLR_ISTR_PMAOVR() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_PMAOVR) +#define USB_CLR_ISTR_ERR() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_ERR) +#define USB_CLR_ISTR_WKUP() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_WKUP) +#define USB_CLR_ISTR_SUSP() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_SUSP) +#define USB_CLR_ISTR_RESET() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_RESET) +#define USB_CLR_ISTR_SOF() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_SOF) +#define USB_CLR_ISTR_ESOF() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_ESOF) + +/* --- USB Frame Number Register bits -------------------------------------- */ + +#define USB_FNR_RXDP (1 << 15) +#define USB_FNR_RXDM (1 << 14) +#define USB_FNR_LCK (1 << 13) + +#define USB_FNR_LSOF_SHIFT 11 +#define USB_FNR_LSOF (3 << USB_FNR_LSOF_SHIFT) + +#define USB_FNR_FN (0x7FF << 0) + +/* --- USB device address register masks / bits ---------------------------- */ + +#define USB_DADDR_EF (1 << 7) +#define USB_DADDR_ADDR 0x007F + +/* USB_BTABLE Values ------------------------------------------------------- */ + +#define USB_BTABLE_BTABLE 0xFFF8 + +/* --- USB device address register manipulators ---------------------------- */ + +/* --- USB endpoint register offsets --------------------------------------- */ + +#define USB_EP0 0 +#define USB_EP1 1 +#define USB_EP2 2 +#define USB_EP3 3 +#define USB_EP4 4 +#define USB_EP5 5 +#define USB_EP6 6 +#define USB_EP7 7 + +/* --- USB endpoint register masks / bits ---------------------------------- */ + +/* Masks and toggle bits */ +#define USB_EP_RX_CTR 0x8000 /* Correct transfer RX */ +#define USB_EP_RX_DTOG 0x4000 /* Data toggle RX */ +#define USB_EP_RX_STAT 0x3000 /* Endpoint status for RX */ + +#define USB_EP_SETUP 0x0800 /* Setup transaction completed */ +#define USB_EP_TYPE 0x0600 /* Endpoint type */ +#define USB_EP_KIND 0x0100 /* Endpoint kind. + * When set and type=bulk -> double buffer + * When set and type=control -> status out + */ + +#define USB_EP_TX_CTR 0x0080 /* Correct transfer TX */ +#define USB_EP_TX_DTOG 0x0040 /* Data toggle TX */ +#define USB_EP_TX_STAT 0x0030 /* Endpoint status for TX */ + +#define USB_EP_ADDR 0x000F /* Endpoint Address */ + +/* Masking all toggle bits */ +#define USB_EP_NTOGGLE_MSK (USB_EP_RX_CTR | \ + USB_EP_SETUP | \ + USB_EP_TYPE | \ + USB_EP_KIND | \ + USB_EP_TX_CTR | \ + USB_EP_ADDR) + +/* All non toggle bits plus EP_RX toggle bits */ +#define USB_EP_RX_STAT_TOG_MSK (USB_EP_RX_STAT | USB_EP_NTOGGLE_MSK) +/* All non toggle bits plus EP_TX toggle bits */ +#define USB_EP_TX_STAT_TOG_MSK (USB_EP_TX_STAT | USB_EP_NTOGGLE_MSK) + +/* Endpoint status bits for USB_EP_RX_STAT bit field */ +#define USB_EP_RX_STAT_DISABLED 0x0000 +#define USB_EP_RX_STAT_STALL 0x1000 +#define USB_EP_RX_STAT_NAK 0x2000 +#define USB_EP_RX_STAT_VALID 0x3000 + +/* Endpoint status bits for USB_EP_TX_STAT bit field */ +#define USB_EP_TX_STAT_DISABLED 0x0000 +#define USB_EP_TX_STAT_STALL 0x0010 +#define USB_EP_TX_STAT_NAK 0x0020 +#define USB_EP_TX_STAT_VALID 0x0030 + +/* Endpoint type bits for USB_EP_TYPE bit field */ +#define USB_EP_TYPE_BULK 0x0000 +#define USB_EP_TYPE_CONTROL 0x0200 +#define USB_EP_TYPE_ISO 0x0400 +#define USB_EP_TYPE_INTERRUPT 0x0600 + +/* --- USB endpoint register manipulators ---------------------------------- */ + +/* + * Set USB endpoint tx/rx status. + * + * USB status field is changed using an awkward toggle mechanism, that + * is why we use some helper macros for that. + */ +#define USB_SET_EP_RX_STAT(EP, STAT) \ + TOG_SET_REG_BIT_MSK_AND_SET(USB_EP_REG(EP), \ + USB_EP_RX_STAT_TOG_MSK, STAT, USB_EP_RX_CTR | USB_EP_TX_CTR) + +#define USB_SET_EP_TX_STAT(EP, STAT) \ + TOG_SET_REG_BIT_MSK_AND_SET(USB_EP_REG(EP), \ + USB_EP_TX_STAT_TOG_MSK, STAT, USB_EP_RX_CTR | USB_EP_TX_CTR) + +/* + * Macros for clearing and setting USB endpoint register bits that do + * not use the toggle mechanism. + * + * Because the register contains some bits that use the toggle + * mechanism we need a helper macro here. Otherwise the code gets really messy. + */ +#define USB_CLR_EP_NTOGGLE_BIT_AND_SET(EP, BIT, EXTRA_BITS) \ + CLR_REG_BIT_MSK_AND_SET(USB_EP_REG(EP), \ + USB_EP_NTOGGLE_MSK, BIT, EXTRA_BITS) + +#define USB_CLR_EP_RX_CTR(EP) \ + USB_CLR_EP_NTOGGLE_BIT_AND_SET(EP, USB_EP_RX_CTR, USB_EP_TX_CTR) + +#define USB_CLR_EP_TX_CTR(EP) \ + USB_CLR_EP_NTOGGLE_BIT_AND_SET(EP, USB_EP_TX_CTR, USB_EP_RX_CTR) + + +#define USB_SET_EP_TYPE(EP, TYPE) \ + SET_REG(USB_EP_REG(EP), \ + (GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & \ + (~USB_EP_TYPE))) | TYPE) + +#define USB_SET_EP_KIND(EP) \ + SET_REG(USB_EP_REG(EP), \ + (GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & \ + (~USB_EP_KIND))) | USB_EP_KIND) + +#define USB_CLR_EP_KIND(EP) \ + SET_REG(USB_EP_REG(EP), \ + (GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & (~USB_EP_KIND)))) + +#define USB_SET_EP_STAT_OUT(EP) USB_SET_EP_KIND(EP) +#define USB_CLR_EP_STAT_OUT(EP) USB_CLR_EP_KIND(EP) + +#define USB_SET_EP_ADDR(EP, ADDR) \ + SET_REG(USB_EP_REG(EP), \ + ((GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & \ + (~USB_EP_ADDR))) | ADDR)) + +/* Macros for clearing DTOG bits */ +#define USB_CLR_EP_TX_DTOG(EP) \ + SET_REG(USB_EP_REG(EP), \ + GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK | USB_EP_TX_DTOG)) + +#define USB_CLR_EP_RX_DTOG(EP) \ + SET_REG(USB_EP_REG(EP), \ + GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK | USB_EP_RX_DTOG)) + + +/* --- USB BTABLE registers ------------------------------------------------ */ + +#define USB_GET_BTABLE GET_REG(USB_BTABLE_REG) + +/* --- USB BTABLE manipulators --------------------------------------------- */ + +#define USB_GET_EP_TX_ADDR(EP) GET_REG(USB_EP_TX_ADDR(EP)) +#define USB_GET_EP_TX_COUNT(EP) GET_REG(USB_EP_TX_COUNT(EP)) +#define USB_GET_EP_RX_ADDR(EP) GET_REG(USB_EP_RX_ADDR(EP)) +#define USB_GET_EP_RX_COUNT(EP) GET_REG(USB_EP_RX_COUNT(EP)) +#define USB_SET_EP_TX_ADDR(EP, ADDR) SET_REG(USB_EP_TX_ADDR(EP), ADDR) +#define USB_SET_EP_TX_COUNT(EP, COUNT) SET_REG(USB_EP_TX_COUNT(EP), COUNT) +#define USB_SET_EP_RX_ADDR(EP, ADDR) SET_REG(USB_EP_RX_ADDR(EP), ADDR) +#define USB_SET_EP_RX_COUNT(EP, COUNT) SET_REG(USB_EP_RX_COUNT(EP), COUNT) + + + +/**@}*/ + +#endif +/** @cond */ +#else +#error "st_usbfs_common.h should not be included explicitly, only via st_usbfs.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v1.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v1.h new file mode 100644 index 00000000..7a5a0459 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v1.h @@ -0,0 +1,67 @@ +/** @addtogroup usb_defines + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + * + * Additional definitions for F1, F3, L1 devices: + * -F102, F103 (RM0008) + * -F302x{B,C}; *NOT* F302x{6,8,D,E} !! (USB_BTABLE access issues) (RM0365) + * -F303x{B,C}; *NOT* F303x{D,E} !! (USB_BTABLE access issues) (RM0316) + * -F37x (RM0313) + * -L1xx (RM0038) + */ + +/** @cond */ +#ifdef LIBOPENCM3_ST_USBFS_H +/** @endcond */ +#ifndef LIBOPENCM3_ST_USBFS_V1_H +#define LIBOPENCM3_ST_USBFS_V1_H + +#include + +/* --- USB BTABLE Registers ------------------------------------------------ */ + +#define USB_EP_TX_ADDR(EP) \ + ((uint32_t *)(USB_PMA_BASE + (USB_GET_BTABLE + EP * 8 + 0) * 2)) + +#define USB_EP_TX_COUNT(EP) \ + ((uint32_t *)(USB_PMA_BASE + (USB_GET_BTABLE + EP * 8 + 2) * 2)) + +#define USB_EP_RX_ADDR(EP) \ + ((uint32_t *)(USB_PMA_BASE + (USB_GET_BTABLE + EP * 8 + 4) * 2)) + +#define USB_EP_RX_COUNT(EP) \ + ((uint32_t *)(USB_PMA_BASE + (USB_GET_BTABLE + EP * 8 + 6) * 2)) + +/* --- USB BTABLE manipulators --------------------------------------------- */ + +#define USB_GET_EP_TX_BUFF(EP) \ + (USB_PMA_BASE + (uint8_t *)(USB_GET_EP_TX_ADDR(EP) * 2)) + +#define USB_GET_EP_RX_BUFF(EP) \ + (USB_PMA_BASE + (uint8_t *)(USB_GET_EP_RX_ADDR(EP) * 2)) + +#endif +/** @cond */ +#else +#error "st_usbfs_v1.h should not be included directly, only via st_usbfs.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v2.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v2.h new file mode 100644 index 00000000..d85f4427 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/st_usbfs_v2.h @@ -0,0 +1,109 @@ +/** @addtogroup usb_defines + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + * + * Additional definitions for F0 devices : + * -F0x0 (RM0360), + * -F04x, F0x2, F0x8 (RM0091) + */ + +/** @cond */ +#ifdef LIBOPENCM3_ST_USBFS_H +/** @endcond */ +#ifndef LIBOPENCM3_ST_USBFS_V2_H +#define LIBOPENCM3_ST_USBFS_V2_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define USB_LPMCSR_REG (&MMIO32(USB_DEV_FS_BASE + 0x54)) +#define USB_BCDR_REG (&MMIO32(USB_DEV_FS_BASE + 0x58)) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- USB control register masks / bits ----------------------------------- */ + +#define USB_CNTR_L1REQM (1 << 7) +#define USB_CNTR_L1RESUME (1 << 5) + +/* --- USB interrupt status register masks / bits -------------------------- */ + +#define USB_ISTR_L1REQ (1 << 7) + +/* --- LPM control and status register USB_LPMCSR Values --------------------*/ + +#define USB_LPMCSR_BESL_SHIFT 4 +#define USB_LPMCSR_BESL (15 << USB_LPMCSR_BESL_SHIFT) + +#define USB_LPMCSR_REMWAKE (1 << 3) +#define USB_LPMCSR_LPMACK (1 << 1) +#define USB_LPMCSR_LPMEN (1 << 0) + +/* --- Battery Charging Detector Values ----------------------------------------------------------*/ + +#define USB_BCDR_DPPU (1 << 15) +#define USB_BCDR_PS2DET (1 << 7) +#define USB_BCDR_SDET (1 << 6) +#define USB_BCDR_PDET (1 << 5) +#define USB_BCDR_DCDET (1 << 4) +#define USB_BCDR_SDEN (1 << 3) +#define USB_BCDR_PDEN (1 << 2) +#define USB_BCDR_DCDEN (1 << 1) +#define USB_BCDR_BCDEN (1 << 0) + +/* --- USB BTABLE registers ------------------------------------------------ */ + +#define USB_EP_TX_ADDR(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 0) * 1)) + +#define USB_EP_TX_COUNT(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 2) * 1)) + +#define USB_EP_RX_ADDR(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 4) * 1)) + +#define USB_EP_RX_COUNT(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 6) * 1)) + +/* --- USB BTABLE manipulators --------------------------------------------- */ + +#define USB_GET_EP_TX_BUFF(ep) \ + (USB_PMA_BASE + (uint8_t *)(USB_GET_EP_TX_ADDR(ep) * 1)) + +#define USB_GET_EP_RX_BUFF(ep) \ + (USB_PMA_BASE + (uint8_t *)(USB_GET_EP_RX_ADDR(ep) * 1)) + +#endif +/** @cond */ +#else +#error "st_usbfs_v2.h should not be included directly, only via st_usbfs.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/syscfg_common_l1f234.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/syscfg_common_l1f234.h new file mode 100644 index 00000000..776e12da --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/syscfg_common_l1f234.h @@ -0,0 +1,61 @@ +/** @addtogroup syscfg_defines + * + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA SYSCFG.H +The order of header inclusion is important. syscfg.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#if defined(LIBOPENCM3_SYSCFG_H) +/** @endcond */ +#ifndef LIBOPENCM3_SYSCFG_COMMON_L1F234_H +#define LIBOPENCM3_SYSCFG_COMMON_L1F234_H + +/**@{*/ + +/* --- SYSCFG registers ---------------------------------------------------- */ + +#define SYSCFG_MEMRM MMIO32(SYSCFG_BASE + 0x00) + +#define SYSCFG_PMC MMIO32(SYSCFG_BASE + 0x04) + +/* External interrupt configuration registers [0..3] (SYSCFG_EXTICR[1..4]) */ +#define SYSCFG_EXTICR(i) MMIO32(SYSCFG_BASE + 0x08 + (i)*4) +#define SYSCFG_EXTICR1 SYSCFG_EXTICR(0) +#define SYSCFG_EXTICR2 SYSCFG_EXTICR(1) +#define SYSCFG_EXTICR3 SYSCFG_EXTICR(2) +#define SYSCFG_EXTICR4 SYSCFG_EXTICR(3) + +#define SYSCFG_CMPCR MMIO32(SYSCFG_BASE + 0x20) + +#endif +/**@}*/ + +/** @cond */ +#else +#warning "syscfg_common_l1f234.h should not be included explicitly," +#warning "only via syscfg.h" +#endif +/** @endcond */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_all.h new file mode 100644 index 00000000..46ada5fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_all.h @@ -0,0 +1,1269 @@ +/** @addtogroup timer_defines + * + * @author @htmlonly © @endhtmlonly 2009 Piotr Esden-Tempski + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA TIMER.H +The order of header inclusion is important. timer.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#if defined(LIBOPENCM3_TIMER_H) +/** @endcond */ +#ifndef LIBOPENCM3_TIMER_COMMON_H +#define LIBOPENCM3_TIMER_COMMON_H + +/* --- Convenience macros -------------------------------------------------- */ + +/* Timer register base addresses (for convenience) */ +/****************************************************************************/ +/** @defgroup tim_reg_base Timer register base addresses +@ingroup timer_defines + +@{*/ +#define TIM1 TIM1_BASE +#define TIM2 TIM2_BASE +#define TIM3 TIM3_BASE +#if defined(TIM4_BASE) +#define TIM4 TIM4_BASE +#endif +#define TIM5 TIM5_BASE +#define TIM6 TIM6_BASE +#define TIM7 TIM7_BASE +#if defined(TIM8_BASE) +# define TIM8 TIM8_BASE +#endif +#if defined(TIM9_BASE) +# define TIM9 TIM9_BASE +#endif +#if defined(TIM10_BASE) +# define TIM10 TIM10_BASE +#endif +#if defined(TIM11_BASE) +# define TIM11 TIM11_BASE +#endif +#if defined(TIM12_BASE) +# define TIM12 TIM12_BASE +#endif +#if defined(TIM13_BASE) +# define TIM13 TIM13_BASE +#endif +#if defined(TIM14_BASE) +# define TIM14 TIM14_BASE +#endif +#if defined(TIM15_BASE) +# define TIM15 TIM15_BASE +#endif +#if defined(TIM16_BASE) +# define TIM16 TIM16_BASE +#endif +#if defined(TIM17_BASE) +# define TIM17 TIM17_BASE +#endif +/**@}*/ + +/* --- Timer registers ----------------------------------------------------- */ + +/* Control register 1 (TIMx_CR1) */ +#define TIM_CR1(tim_base) MMIO32((tim_base) + 0x00) +#define TIM1_CR1 TIM_CR1(TIM1) +#define TIM2_CR1 TIM_CR1(TIM2) +#define TIM3_CR1 TIM_CR1(TIM3) +#define TIM4_CR1 TIM_CR1(TIM4) +#define TIM5_CR1 TIM_CR1(TIM5) +#define TIM6_CR1 TIM_CR1(TIM6) +#define TIM7_CR1 TIM_CR1(TIM7) +#define TIM8_CR1 TIM_CR1(TIM8) +#define TIM9_CR1 TIM_CR1(TIM9) +#define TIM10_CR1 TIM_CR1(TIM10) +#define TIM11_CR1 TIM_CR1(TIM11) +#define TIM12_CR1 TIM_CR1(TIM12) +#define TIM13_CR1 TIM_CR1(TIM13) +#define TIM14_CR1 TIM_CR1(TIM14) +#define TIM15_CR1 TIM_CR1(TIM15) +#define TIM16_CR1 TIM_CR1(TIM16) +#define TIM17_CR1 TIM_CR1(TIM17) + +/* Control register 2 (TIMx_CR2) */ +#define TIM_CR2(tim_base) MMIO32((tim_base) + 0x04) +#define TIM1_CR2 TIM_CR2(TIM1) +#define TIM2_CR2 TIM_CR2(TIM2) +#define TIM3_CR2 TIM_CR2(TIM3) +#define TIM4_CR2 TIM_CR2(TIM4) +#define TIM5_CR2 TIM_CR2(TIM5) +#define TIM6_CR2 TIM_CR2(TIM6) +#define TIM7_CR2 TIM_CR2(TIM7) +#define TIM8_CR2 TIM_CR2(TIM8) +#define TIM15_CR2 TIM_CR2(TIM15) +#define TIM16_CR2 TIM_CR2(TIM16) +#define TIM17_CR2 TIM_CR2(TIM17) + +/* Slave mode control register (TIMx_SMCR) */ +#define TIM_SMCR(tim_base) MMIO32((tim_base) + 0x08) +#define TIM1_SMCR TIM_SMCR(TIM1) +#define TIM2_SMCR TIM_SMCR(TIM2) +#define TIM3_SMCR TIM_SMCR(TIM3) +#define TIM4_SMCR TIM_SMCR(TIM4) +#define TIM5_SMCR TIM_SMCR(TIM5) +#define TIM8_SMCR TIM_SMCR(TIM8) +#define TIM9_SMCR TIM_SMCR(TIM9) +#define TIM12_SMCR TIM_SMCR(TIM12) +#define TIM15_SMCR TIM_SMCR(TIM15) + +/* DMA/Interrupt enable register (TIMx_DIER) */ +#define TIM_DIER(tim_base) MMIO32((tim_base) + 0x0C) +#define TIM1_DIER TIM_DIER(TIM1) +#define TIM2_DIER TIM_DIER(TIM2) +#define TIM3_DIER TIM_DIER(TIM3) +#define TIM4_DIER TIM_DIER(TIM4) +#define TIM5_DIER TIM_DIER(TIM5) +#define TIM6_DIER TIM_DIER(TIM6) +#define TIM7_DIER TIM_DIER(TIM7) +#define TIM8_DIER TIM_DIER(TIM8) +#define TIM9_DIER TIM_DIER(TIM9) +#define TIM10_DIER TIM_DIER(TIM10) +#define TIM11_DIER TIM_DIER(TIM11) +#define TIM12_DIER TIM_DIER(TIM12) +#define TIM13_DIER TIM_DIER(TIM13) +#define TIM14_DIER TIM_DIER(TIM14) +#define TIM15_DIER TIM_DIER(TIM15) +#define TIM16_DIER TIM_DIER(TIM16) +#define TIM17_DIER TIM_DIER(TIM17) + +/* Status register (TIMx_SR) */ +#define TIM_SR(tim_base) MMIO32((tim_base) + 0x10) +#define TIM1_SR TIM_SR(TIM1) +#define TIM2_SR TIM_SR(TIM2) +#define TIM3_SR TIM_SR(TIM3) +#define TIM4_SR TIM_SR(TIM4) +#define TIM5_SR TIM_SR(TIM5) +#define TIM6_SR TIM_SR(TIM6) +#define TIM7_SR TIM_SR(TIM7) +#define TIM8_SR TIM_SR(TIM8) +#define TIM9_SR TIM_SR(TIM9) +#define TIM10_SR TIM_SR(TIM10) +#define TIM11_SR TIM_SR(TIM11) +#define TIM12_SR TIM_SR(TIM12) +#define TIM13_SR TIM_SR(TIM13) +#define TIM14_SR TIM_SR(TIM14) +#define TIM15_SR TIM_SR(TIM15) +#define TIM16_SR TIM_SR(TIM16) +#define TIM17_SR TIM_SR(TIM17) + +/* Event generation register (TIMx_EGR) */ +#define TIM_EGR(tim_base) MMIO32((tim_base) + 0x14) +#define TIM1_EGR TIM_EGR(TIM1) +#define TIM2_EGR TIM_EGR(TIM2) +#define TIM3_EGR TIM_EGR(TIM3) +#define TIM4_EGR TIM_EGR(TIM4) +#define TIM5_EGR TIM_EGR(TIM5) +#define TIM6_EGR TIM_EGR(TIM6) +#define TIM7_EGR TIM_EGR(TIM7) +#define TIM8_EGR TIM_EGR(TIM8) +#define TIM9_EGR TIM_EGR(TIM9) +#define TIM10_EGR TIM_EGR(TIM10) +#define TIM11_EGR TIM_EGR(TIM11) +#define TIM12_EGR TIM_EGR(TIM12) +#define TIM13_EGR TIM_EGR(TIM13) +#define TIM14_EGR TIM_EGR(TIM14) +#define TIM15_EGR TIM_EGR(TIM15) +#define TIM16_EGR TIM_EGR(TIM16) +#define TIM17_EGR TIM_EGR(TIM17) + +/* Capture/compare mode register 1 (TIMx_CCMR1) */ +#define TIM_CCMR1(tim_base) MMIO32((tim_base) + 0x18) +#define TIM1_CCMR1 TIM_CCMR1(TIM1) +#define TIM2_CCMR1 TIM_CCMR1(TIM2) +#define TIM3_CCMR1 TIM_CCMR1(TIM3) +#define TIM4_CCMR1 TIM_CCMR1(TIM4) +#define TIM5_CCMR1 TIM_CCMR1(TIM5) +#define TIM8_CCMR1 TIM_CCMR1(TIM8) +#define TIM9_CCMR1 TIM_CCMR1(TIM9) +#define TIM10_CCMR1 TIM_CCMR1(TIM10) +#define TIM11_CCMR1 TIM_CCMR1(TIM11) +#define TIM12_CCMR1 TIM_CCMR1(TIM12) +#define TIM13_CCMR1 TIM_CCMR1(TIM13) +#define TIM14_CCMR1 TIM_CCMR1(TIM14) +#define TIM15_CCMR1 TIM_CCMR1(TIM15) +#define TIM16_CCMR1 TIM_CCMR1(TIM16) +#define TIM17_CCMR1 TIM_CCMR1(TIM17) + +/* Capture/compare mode register 2 (TIMx_CCMR2) */ +#define TIM_CCMR2(tim_base) MMIO32((tim_base) + 0x1C) +#define TIM1_CCMR2 TIM_CCMR2(TIM1) +#define TIM2_CCMR2 TIM_CCMR2(TIM2) +#define TIM3_CCMR2 TIM_CCMR2(TIM3) +#define TIM4_CCMR2 TIM_CCMR2(TIM4) +#define TIM5_CCMR2 TIM_CCMR2(TIM5) +#define TIM8_CCMR2 TIM_CCMR2(TIM8) + +/* Capture/compare enable register (TIMx_CCER) */ +#define TIM_CCER(tim_base) MMIO32((tim_base) + 0x20) +#define TIM1_CCER TIM_CCER(TIM1) +#define TIM2_CCER TIM_CCER(TIM2) +#define TIM3_CCER TIM_CCER(TIM3) +#define TIM4_CCER TIM_CCER(TIM4) +#define TIM5_CCER TIM_CCER(TIM5) +#define TIM8_CCER TIM_CCER(TIM8) +#define TIM9_CCER TIM_CCER(TIM9) +#define TIM10_CCER TIM_CCER(TIM10) +#define TIM11_CCER TIM_CCER(TIM11) +#define TIM12_CCER TIM_CCER(TIM12) +#define TIM13_CCER TIM_CCER(TIM13) +#define TIM14_CCER TIM_CCER(TIM14) +#define TIM15_CCER TIM_CCER(TIM15) +#define TIM16_CCER TIM_CCER(TIM16) +#define TIM17_CCER TIM_CCER(TIM17) + +/* Counter (TIMx_CNT) */ +#define TIM_CNT(tim_base) MMIO32((tim_base) + 0x24) +#define TIM1_CNT TIM_CNT(TIM1) +#define TIM2_CNT TIM_CNT(TIM2) +#define TIM3_CNT TIM_CNT(TIM3) +#define TIM4_CNT TIM_CNT(TIM4) +#define TIM5_CNT TIM_CNT(TIM5) +#define TIM6_CNT TIM_CNT(TIM6) +#define TIM7_CNT TIM_CNT(TIM7) +#define TIM8_CNT TIM_CNT(TIM8) +#define TIM9_CNT TIM_CNT(TIM9) +#define TIM10_CNT TIM_CNT(TIM10) +#define TIM11_CNT TIM_CNT(TIM11) +#define TIM12_CNT TIM_CNT(TIM12) +#define TIM13_CNT TIM_CNT(TIM13) +#define TIM14_CNT TIM_CNT(TIM14) +#define TIM15_CNT TIM_CNT(TIM15) +#define TIM16_CNT TIM_CNT(TIM16) +#define TIM17_CNT TIM_CNT(TIM17) + +/* Prescaler (TIMx_PSC) */ +#define TIM_PSC(tim_base) MMIO32((tim_base) + 0x28) +#define TIM1_PSC TIM_PSC(TIM1) +#define TIM2_PSC TIM_PSC(TIM2) +#define TIM3_PSC TIM_PSC(TIM3) +#define TIM4_PSC TIM_PSC(TIM4) +#define TIM5_PSC TIM_PSC(TIM5) +#define TIM6_PSC TIM_PSC(TIM6) +#define TIM7_PSC TIM_PSC(TIM7) +#define TIM8_PSC TIM_PSC(TIM8) +#define TIM9_PSC TIM_PSC(TIM9) +#define TIM10_PSC TIM_PSC(TIM10) +#define TIM11_PSC TIM_PSC(TIM11) +#define TIM12_PSC TIM_PSC(TIM12) +#define TIM13_PSC TIM_PSC(TIM13) +#define TIM14_PSC TIM_PSC(TIM14) +#define TIM15_PSC TIM_PSC(TIM15) +#define TIM16_PSC TIM_PSC(TIM16) +#define TIM17_PSC TIM_PSC(TIM17) + +/* Auto-reload register (TIMx_ARR) */ +#define TIM_ARR(tim_base) MMIO32((tim_base) + 0x2C) +#define TIM1_ARR TIM_ARR(TIM1) +#define TIM2_ARR TIM_ARR(TIM2) +#define TIM3_ARR TIM_ARR(TIM3) +#define TIM4_ARR TIM_ARR(TIM4) +#define TIM5_ARR TIM_ARR(TIM5) +#define TIM6_ARR TIM_ARR(TIM6) +#define TIM7_ARR TIM_ARR(TIM7) +#define TIM8_ARR TIM_ARR(TIM8) +#define TIM9_ARR TIM_ARR(TIM9) +#define TIM10_ARR TIM_ARR(TIM10) +#define TIM11_ARR TIM_ARR(TIM11) +#define TIM12_ARR TIM_ARR(TIM12) +#define TIM13_ARR TIM_ARR(TIM13) +#define TIM14_ARR TIM_ARR(TIM14) +#define TIM15_ARR TIM_ARR(TIM15) +#define TIM16_ARR TIM_ARR(TIM16) +#define TIM17_ARR TIM_ARR(TIM17) + +/* Repetition counter register (TIMx_RCR) */ +#define TIM_RCR(tim_base) MMIO32((tim_base) + 0x30) +#define TIM1_RCR TIM_RCR(TIM1) +#define TIM8_RCR TIM_RCR(TIM8) +#define TIM15_RCR TIM_RCR(TIM15) +#define TIM16_RCR TIM_RCR(TIM16) +#define TIM17_RCR TIM_RCR(TIM17) + +/* Capture/compare register 1 (TIMx_CCR1) */ +#define TIM_CCR1(tim_base) MMIO32((tim_base) + 0x34) +#define TIM1_CCR1 TIM_CCR1(TIM1) +#define TIM2_CCR1 TIM_CCR1(TIM2) +#define TIM3_CCR1 TIM_CCR1(TIM3) +#define TIM4_CCR1 TIM_CCR1(TIM4) +#define TIM5_CCR1 TIM_CCR1(TIM5) +#define TIM8_CCR1 TIM_CCR1(TIM8) +#define TIM9_CCR1 TIM_CCR1(TIM9) +#define TIM10_CCR1 TIM_CCR1(TIM10) +#define TIM11_CCR1 TIM_CCR1(TIM11) +#define TIM12_CCR1 TIM_CCR1(TIM12) +#define TIM13_CCR1 TIM_CCR1(TIM13) +#define TIM14_CCR1 TIM_CCR1(TIM14) +#define TIM15_CCR1 TIM_CCR1(TIM15) +#define TIM16_CCR1 TIM_CCR1(TIM16) +#define TIM17_CCR1 TIM_CCR1(TIM17) + +/* Capture/compare register 2 (TIMx_CCR2) */ +#define TIM_CCR2(tim_base) MMIO32((tim_base) + 0x38) +#define TIM1_CCR2 TIM_CCR2(TIM1) +#define TIM2_CCR2 TIM_CCR2(TIM2) +#define TIM3_CCR2 TIM_CCR2(TIM3) +#define TIM4_CCR2 TIM_CCR2(TIM4) +#define TIM5_CCR2 TIM_CCR2(TIM5) +#define TIM8_CCR2 TIM_CCR2(TIM8) +#define TIM9_CCR2 TIM_CCR2(TIM9) +#define TIM12_CCR2 TIM_CCR2(TIM12) +#define TIM15_CCR2 TIM_CCR2(TIM15) + +/* Capture/compare register 3 (TIMx_CCR3) */ +#define TIM_CCR3(tim_base) MMIO32((tim_base) + 0x3C) +#define TIM1_CCR3 TIM_CCR3(TIM1) +#define TIM2_CCR3 TIM_CCR3(TIM2) +#define TIM3_CCR3 TIM_CCR3(TIM3) +#define TIM4_CCR3 TIM_CCR3(TIM4) +#define TIM5_CCR3 TIM_CCR3(TIM5) +#define TIM8_CCR3 TIM_CCR3(TIM8) + +/* Capture/compare register 4 (TIMx_CCR4) */ +#define TIM_CCR4(tim_base) MMIO32((tim_base) + 0x40) +#define TIM1_CCR4 TIM_CCR4(TIM1) +#define TIM2_CCR4 TIM_CCR4(TIM2) +#define TIM3_CCR4 TIM_CCR4(TIM3) +#define TIM4_CCR4 TIM_CCR4(TIM4) +#define TIM5_CCR4 TIM_CCR4(TIM5) +#define TIM8_CCR4 TIM_CCR4(TIM8) + +/* Break and dead-time register (TIMx_BDTR) */ +#define TIM_BDTR(tim_base) MMIO32((tim_base) + 0x44) +#define TIM1_BDTR TIM_BDTR(TIM1) +#define TIM8_BDTR TIM_BDTR(TIM8) +#define TIM15_BDTR TIM_BDTR(TIM15) +#define TIM16_BDTR TIM_BDTR(TIM16) +#define TIM17_BDTR TIM_BDTR(TIM17) + +/* DMA control register (TIMx_DCR) */ +#define TIM_DCR(tim_base) MMIO32((tim_base) + 0x48) +#define TIM1_DCR TIM_DCR(TIM1) +#define TIM2_DCR TIM_DCR(TIM2) +#define TIM3_DCR TIM_DCR(TIM3) +#define TIM4_DCR TIM_DCR(TIM4) +#define TIM5_DCR TIM_DCR(TIM5) +#define TIM8_DCR TIM_DCR(TIM8) +#define TIM15_DCR TIM_DCR(TIM15) +#define TIM16_DCR TIM_DCR(TIM16) +#define TIM17_DCR TIM_DCR(TIM17) + +/* DMA address for full transfer (TIMx_DMAR) */ +#define TIM_DMAR(tim_base) MMIO32((tim_base) + 0x4C) +#define TIM1_DMAR TIM_DMAR(TIM1) +#define TIM2_DMAR TIM_DMAR(TIM2) +#define TIM3_DMAR TIM_DMAR(TIM3) +#define TIM4_DMAR TIM_DMAR(TIM4) +#define TIM5_DMAR TIM_DMAR(TIM5) +#define TIM8_DMAR TIM_DMAR(TIM8) +#define TIM15_DMAR TIM_DMAR(TIM15) +#define TIM16_DMAR TIM_DMAR(TIM16) +#define TIM17_DMAR TIM_DMAR(TIM17) + +/* --- TIMx_CR1 values ----------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup tim_x_cr1_cdr TIMx_CR1 CKD[1:0] Clock Division Ratio +@ingroup timer_defines + +@{*/ +/* CKD[1:0]: Clock division */ +#define TIM_CR1_CKD_CK_INT (0x0 << 8) +#define TIM_CR1_CKD_CK_INT_MUL_2 (0x1 << 8) +#define TIM_CR1_CKD_CK_INT_MUL_4 (0x2 << 8) +#define TIM_CR1_CKD_CK_INT_MASK (0x3 << 8) +/**@}*/ + +/* ARPE: Auto-reload preload enable */ +#define TIM_CR1_ARPE (1 << 7) + +/* CMS[1:0]: Center-aligned mode selection */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_cms TIMx_CR1 CMS[1:0]: Center-aligned Mode Selection +@ingroup timer_defines + +@{*/ +#define TIM_CR1_CMS_EDGE (0x0 << 5) +#define TIM_CR1_CMS_CENTER_1 (0x1 << 5) +#define TIM_CR1_CMS_CENTER_2 (0x2 << 5) +#define TIM_CR1_CMS_CENTER_3 (0x3 << 5) +#define TIM_CR1_CMS_MASK (0x3 << 5) +/**@}*/ + +/* DIR: Direction */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_dir TIMx_CR1 DIR: Direction +@ingroup timer_defines + +@{*/ +#define TIM_CR1_DIR_UP (0 << 4) +#define TIM_CR1_DIR_DOWN (1 << 4) +/**@}*/ + +/* OPM: One pulse mode */ +#define TIM_CR1_OPM (1 << 3) + +/* URS: Update request source */ +#define TIM_CR1_URS (1 << 2) + +/* UDIS: Update disable */ +#define TIM_CR1_UDIS (1 << 1) + +/* CEN: Counter enable */ +#define TIM_CR1_CEN (1 << 0) + +/* --- TIMx_CR2 values ----------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup tim_x_cr2_ois TIMx_CR2_OIS: Force Output Idle State Control Values +@ingroup timer_defines + +@{*/ +/* OIS4:*//** Output idle state 4 (OC4 output) */ +#define TIM_CR2_OIS4 (1 << 14) + +/* OIS3N:*//** Output idle state 3 (OC3N output) */ +#define TIM_CR2_OIS3N (1 << 13) + +/* OIS3:*//** Output idle state 3 (OC3 output) */ +#define TIM_CR2_OIS3 (1 << 12) + +/* OIS2N:*//** Output idle state 2 (OC2N output) */ +#define TIM_CR2_OIS2N (1 << 11) + +/* OIS2:*//** Output idle state 2 (OC2 output) */ +#define TIM_CR2_OIS2 (1 << 10) + +/* OIS1N:*//** Output idle state 1 (OC1N output) */ +#define TIM_CR2_OIS1N (1 << 9) + +/* OIS1:*//** Output idle state 1 (OC1 output) */ +#define TIM_CR2_OIS1 (1 << 8) +#define TIM_CR2_OIS_MASK (0x7f << 8) +/**@}*/ + +/* TI1S: TI1 selection */ +#define TIM_CR2_TI1S (1 << 7) + +/* MMS[2:0]: Master mode selection */ +/****************************************************************************/ +/** @defgroup tim_mastermode TIMx_CR2 MMS[6:4]: Master Mode Selection +@ingroup timer_defines + +@{*/ +#define TIM_CR2_MMS_RESET (0x0 << 4) +#define TIM_CR2_MMS_ENABLE (0x1 << 4) +#define TIM_CR2_MMS_UPDATE (0x2 << 4) +#define TIM_CR2_MMS_COMPARE_PULSE (0x3 << 4) +#define TIM_CR2_MMS_COMPARE_OC1REF (0x4 << 4) +#define TIM_CR2_MMS_COMPARE_OC2REF (0x5 << 4) +#define TIM_CR2_MMS_COMPARE_OC3REF (0x6 << 4) +#define TIM_CR2_MMS_COMPARE_OC4REF (0x7 << 4) +#define TIM_CR2_MMS_MASK (0x7 << 4) +/**@}*/ + +/* CCDS: Capture/compare DMA selection */ +#define TIM_CR2_CCDS (1 << 3) + +/* CCUS: Capture/compare control update selection */ +#define TIM_CR2_CCUS (1 << 2) + +/* CCPC: Capture/compare preload control */ +#define TIM_CR2_CCPC (1 << 0) + +/* --- TIMx_SMCR values ---------------------------------------------------- */ + +/* ETP: External trigger polarity */ +#define TIM_SMCR_ETP (1 << 15) + +/* ECE: External clock enable */ +#define TIM_SMCR_ECE (1 << 14) + +/* ETPS[1:0]: External trigger prescaler */ +#define TIM_SMCR_ETPS_OFF (0x0 << 12) +#define TIM_SMCR_ETPS_ETRP_DIV_2 (0x1 << 12) +#define TIM_SMCR_ETPS_ETRP_DIV_4 (0x2 << 12) +#define TIM_SMCR_ETPS_ETRP_DIV_8 (0x3 << 12) +#define TIM_SMCR_ETPS_MASK (0X3 << 12) + +/* ETF[3:0]: External trigger filter */ +#define TIM_SMCR_ETF_OFF (0x0 << 8) +#define TIM_SMCR_ETF_CK_INT_N_2 (0x1 << 8) +#define TIM_SMCR_ETF_CK_INT_N_4 (0x2 << 8) +#define TIM_SMCR_ETF_CK_INT_N_8 (0x3 << 8) +#define TIM_SMCR_ETF_DTS_DIV_2_N_6 (0x4 << 8) +#define TIM_SMCR_ETF_DTS_DIV_2_N_8 (0x5 << 8) +#define TIM_SMCR_ETF_DTS_DIV_4_N_6 (0x6 << 8) +#define TIM_SMCR_ETF_DTS_DIV_4_N_8 (0x7 << 8) +#define TIM_SMCR_ETF_DTS_DIV_8_N_6 (0x8 << 8) +#define TIM_SMCR_ETF_DTS_DIV_8_N_8 (0x9 << 8) +#define TIM_SMCR_ETF_DTS_DIV_16_N_5 (0xA << 8) +#define TIM_SMCR_ETF_DTS_DIV_16_N_6 (0xB << 8) +#define TIM_SMCR_ETF_DTS_DIV_16_N_8 (0xC << 8) +#define TIM_SMCR_ETF_DTS_DIV_32_N_5 (0xD << 8) +#define TIM_SMCR_ETF_DTS_DIV_32_N_6 (0xE << 8) +#define TIM_SMCR_ETF_DTS_DIV_32_N_8 (0xF << 8) +#define TIM_SMCR_ETF_MASK (0xF << 8) + +/* MSM: Master/slave mode */ +#define TIM_SMCR_MSM (1 << 7) + +/* TS[2:0]: Trigger selection */ +/** @defgroup tim_ts TS Trigger selection +@ingroup timer_defines + +@{*/ +/** Internal Trigger 0 (ITR0) */ +#define TIM_SMCR_TS_ITR0 (0x0 << 4) +/** Internal Trigger 1 (ITR1) */ +#define TIM_SMCR_TS_ITR1 (0x1 << 4) +/** Internal Trigger 2 (ITR2) */ +#define TIM_SMCR_TS_ITR2 (0x2 << 4) +/** Internal Trigger 3 (ITR3) */ +#define TIM_SMCR_TS_ITR3 (0x3 << 4) +/** TI1 Edge Detector (TI1F_ED) */ +#define TIM_SMCR_TS_TI1F_ED (0x4 << 4) +/** Filtered Timer Input 1 (TI1FP1) */ +#define TIM_SMCR_TS_TI1FP1 (0x5 << 4) +/** Filtered Timer Input 2 (TI2FP2) */ +#define TIM_SMCR_TS_TI2FP2 (0x6 << 4) +/** External Trigger input (ETRF) */ +#define TIM_SMCR_TS_ETRF (0x7 << 4) +#define TIM_SMCR_TS_MASK (0x7 << 4) +/**@}*/ + +/* SMS[2:0]: Slave mode selection */ +/** @defgroup tim_sms SMS Slave mode selection +@ingroup timer_defines + +@{*/ +/** Slave mode disabled */ +#define TIM_SMCR_SMS_OFF (0x0 << 0) +/** Encoder mode 1 - Counter counts up/down on TI2FP2 edge depending on TI1FP1 +level. */ +#define TIM_SMCR_SMS_EM1 (0x1 << 0) +/** Encoder mode 2 - Counter counts up/down on TI1FP1 edge depending on TI2FP2 +level. */ +#define TIM_SMCR_SMS_EM2 (0x2 << 0) +/** Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges +depending on the level of the complementary input. */ +#define TIM_SMCR_SMS_EM3 (0x3 << 0) +/** Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes + * the counter and generates an update of the registers. + */ +#define TIM_SMCR_SMS_RM (0x4 << 0) +/** Gated Mode - The counter clock is enabled when the trigger input (TRGI) is + * high. + */ +#define TIM_SMCR_SMS_GM (0x5 << 0) +/** Trigger Mode - The counter starts at a rising edge of the trigger TRGI. */ +#define TIM_SMCR_SMS_TM (0x6 << 0) +/** External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock + * the counter. + */ +#define TIM_SMCR_SMS_ECM1 (0x7 << 0) +#define TIM_SMCR_SMS_MASK (0x7 << 0) +/**@}*/ + +/* --- TIMx_DIER values ---------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup tim_irq_enable TIMx_DIER Timer DMA and Interrupt Enable Values +@ingroup timer_defines + +@{*/ +/* TDE:*//** Trigger DMA request enable */ +#define TIM_DIER_TDE (1 << 14) + +/* COMDE:*//** COM DMA request enable */ +#define TIM_DIER_COMDE (1 << 13) + +/* CC4DE:*//** Capture/Compare 4 DMA request enable */ +#define TIM_DIER_CC4DE (1 << 12) + +/* CC3DE:*//** Capture/Compare 3 DMA request enable */ +#define TIM_DIER_CC3DE (1 << 11) + +/* CC2DE:*//** Capture/Compare 2 DMA request enable */ +#define TIM_DIER_CC2DE (1 << 10) + +/* CC1DE:*//** Capture/Compare 1 DMA request enable */ +#define TIM_DIER_CC1DE (1 << 9) + +/* UDE*//**: Update DMA request enable */ +#define TIM_DIER_UDE (1 << 8) + +/* BIE:*//** Break interrupt enable */ +#define TIM_DIER_BIE (1 << 7) + +/* TIE:*//** Trigger interrupt enable */ +#define TIM_DIER_TIE (1 << 6) + +/* COMIE:*//** COM interrupt enable */ +#define TIM_DIER_COMIE (1 << 5) + +/* CC4IE:*//** Capture/compare 4 interrupt enable */ +#define TIM_DIER_CC4IE (1 << 4) + +/* CC3IE:*//** Capture/compare 3 interrupt enable */ +#define TIM_DIER_CC3IE (1 << 3) + +/* CC2IE:*//** Capture/compare 2 interrupt enable */ +#define TIM_DIER_CC2IE (1 << 2) + +/* CC1IE:*//** Capture/compare 1 interrupt enable */ +#define TIM_DIER_CC1IE (1 << 1) + +/* UIE:*//** Update interrupt enable */ +#define TIM_DIER_UIE (1 << 0) +/**@}*/ + +/* --- TIMx_SR values ------------------------------------------------------ */ +/****************************************************************************/ +/** @defgroup tim_sr_values TIMx_SR Timer Status Register Flags +@ingroup timer_defines + +@{*/ + +/* CC4OF:*//** Capture/compare 4 overcapture flag */ +#define TIM_SR_CC4OF (1 << 12) + +/* CC3OF:*//** Capture/compare 3 overcapture flag */ +#define TIM_SR_CC3OF (1 << 11) + +/* CC2OF:*//** Capture/compare 2 overcapture flag */ +#define TIM_SR_CC2OF (1 << 10) + +/* CC1OF:*//** Capture/compare 1 overcapture flag */ +#define TIM_SR_CC1OF (1 << 9) + +/* BIF:*//** Break interrupt flag */ +#define TIM_SR_BIF (1 << 7) + +/* TIF:*//** Trigger interrupt flag */ +#define TIM_SR_TIF (1 << 6) + +/* COMIF:*//** COM interrupt flag */ +#define TIM_SR_COMIF (1 << 5) + +/* CC4IF:*//** Capture/compare 4 interrupt flag */ +#define TIM_SR_CC4IF (1 << 4) + +/* CC3IF:*//** Capture/compare 3 interrupt flag */ +#define TIM_SR_CC3IF (1 << 3) + +/* CC2IF:*//** Capture/compare 2 interrupt flag */ +#define TIM_SR_CC2IF (1 << 2) + +/* CC1IF:*//** Capture/compare 1 interrupt flag */ +#define TIM_SR_CC1IF (1 << 1) + +/* UIF:*//** Update interrupt flag */ +#define TIM_SR_UIF (1 << 0) +/**@}*/ + +/* --- TIMx_EGR values ----------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup tim_event_gen TIMx_EGR Timer Event Generator Values +@ingroup timer_defines + +@{*/ + +/* BG:*//** Break generation */ +#define TIM_EGR_BG (1 << 7) + +/* TG:*//** Trigger generation */ +#define TIM_EGR_TG (1 << 6) + +/* COMG:*//** Capture/compare control update generation */ +#define TIM_EGR_COMG (1 << 5) + +/* CC4G:*//** Capture/compare 4 generation */ +#define TIM_EGR_CC4G (1 << 4) + +/* CC3G:*//** Capture/compare 3 generation */ +#define TIM_EGR_CC3G (1 << 3) + +/* CC2G:*//** Capture/compare 2 generation */ +#define TIM_EGR_CC2G (1 << 2) + +/* CC1G:*//** Capture/compare 1 generation */ +#define TIM_EGR_CC1G (1 << 1) + +/* UG:*//** Update generation */ +#define TIM_EGR_UG (1 << 0) +/**@}*/ + +/* --- TIMx_CCMR1 values --------------------------------------------------- */ + +/* --- Output compare mode --- */ + +/* OC2CE: Output compare 2 clear enable */ +#define TIM_CCMR1_OC2CE (1 << 15) + +/* OC2M[2:0]: Output compare 2 mode */ +#define TIM_CCMR1_OC2M_FROZEN (0x0 << 12) +#define TIM_CCMR1_OC2M_ACTIVE (0x1 << 12) +#define TIM_CCMR1_OC2M_INACTIVE (0x2 << 12) +#define TIM_CCMR1_OC2M_TOGGLE (0x3 << 12) +#define TIM_CCMR1_OC2M_FORCE_LOW (0x4 << 12) +#define TIM_CCMR1_OC2M_FORCE_HIGH (0x5 << 12) +#define TIM_CCMR1_OC2M_PWM1 (0x6 << 12) +#define TIM_CCMR1_OC2M_PWM2 (0x7 << 12) +#define TIM_CCMR1_OC2M_MASK (0x7 << 12) + +/* OC2PE: Output compare 2 preload enable */ +#define TIM_CCMR1_OC2PE (1 << 11) + +/* OC2FE: Output compare 2 fast enable */ +#define TIM_CCMR1_OC2FE (1 << 10) + +/* CC2S[1:0]: Capture/compare 2 selection */ +/* Note: CC2S bits are writable only when the channel is OFF (CC2E = 0 in + * TIMx_CCER). */ +#define TIM_CCMR1_CC2S_OUT (0x0 << 8) +#define TIM_CCMR1_CC2S_IN_TI2 (0x1 << 8) +#define TIM_CCMR1_CC2S_IN_TI1 (0x2 << 8) +#define TIM_CCMR1_CC2S_IN_TRC (0x3 << 8) +#define TIM_CCMR1_CC2S_MASK (0x3 << 8) + +/* OC1CE: Output compare 1 clear enable */ +#define TIM_CCMR1_OC1CE (1 << 7) + +/* OC1M[2:0]: Output compare 1 mode */ +#define TIM_CCMR1_OC1M_FROZEN (0x0 << 4) +#define TIM_CCMR1_OC1M_ACTIVE (0x1 << 4) +#define TIM_CCMR1_OC1M_INACTIVE (0x2 << 4) +#define TIM_CCMR1_OC1M_TOGGLE (0x3 << 4) +#define TIM_CCMR1_OC1M_FORCE_LOW (0x4 << 4) +#define TIM_CCMR1_OC1M_FORCE_HIGH (0x5 << 4) +#define TIM_CCMR1_OC1M_PWM1 (0x6 << 4) +#define TIM_CCMR1_OC1M_PWM2 (0x7 << 4) +#define TIM_CCMR1_OC1M_MASK (0x7 << 4) + +/* OC1PE: Output compare 1 preload enable */ +#define TIM_CCMR1_OC1PE (1 << 3) + +/* OC1FE: Output compare 1 fast enable */ +#define TIM_CCMR1_OC1FE (1 << 2) + +/* CC1S[1:0]: Capture/compare 1 selection */ +/* Note: CC2S bits are writable only when the channel is OFF (CC2E = 0 in + * TIMx_CCER). */ +#define TIM_CCMR1_CC1S_OUT (0x0 << 0) +#define TIM_CCMR1_CC1S_IN_TI2 (0x2 << 0) +#define TIM_CCMR1_CC1S_IN_TI1 (0x1 << 0) +#define TIM_CCMR1_CC1S_IN_TRC (0x3 << 0) +#define TIM_CCMR1_CC1S_MASK (0x3 << 0) + +/* --- Input capture mode --- */ + +/* IC2F[3:0]: Input capture 2 filter */ +#define TIM_CCMR1_IC2F_OFF (0x0 << 12) +#define TIM_CCMR1_IC2F_CK_INT_N_2 (0x1 << 12) +#define TIM_CCMR1_IC2F_CK_INT_N_4 (0x2 << 12) +#define TIM_CCMR1_IC2F_CK_INT_N_8 (0x3 << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_2_N_6 (0x4 << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_2_N_8 (0x5 << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_4_N_6 (0x6 << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_4_N_8 (0x7 << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_8_N_6 (0x8 << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_8_N_8 (0x9 << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_16_N_5 (0xA << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_16_N_6 (0xB << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_16_N_8 (0xC << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_32_N_5 (0xD << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_32_N_6 (0xE << 12) +#define TIM_CCMR1_IC2F_DTF_DIV_32_N_8 (0xF << 12) +#define TIM_CCMR1_IC2F_MASK (0xF << 12) + +/* IC2PSC[1:0]: Input capture 2 prescaler */ +#define TIM_CCMR1_IC2PSC_OFF (0x0 << 10) +#define TIM_CCMR1_IC2PSC_2 (0x1 << 10) +#define TIM_CCMR1_IC2PSC_4 (0x2 << 10) +#define TIM_CCMR1_IC2PSC_8 (0x3 << 10) +#define TIM_CCMR1_IC2PSC_MASK (0x3 << 10) + +/* IC1F[3:0]: Input capture 1 filter */ +#define TIM_CCMR1_IC1F_OFF (0x0 << 4) +#define TIM_CCMR1_IC1F_CK_INT_N_2 (0x1 << 4) +#define TIM_CCMR1_IC1F_CK_INT_N_4 (0x2 << 4) +#define TIM_CCMR1_IC1F_CK_INT_N_8 (0x3 << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_2_N_6 (0x4 << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_2_N_8 (0x5 << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_4_N_6 (0x6 << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_4_N_8 (0x7 << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_8_N_6 (0x8 << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_8_N_8 (0x9 << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_16_N_5 (0xA << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_16_N_6 (0xB << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_16_N_8 (0xC << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_32_N_5 (0xD << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_32_N_6 (0xE << 4) +#define TIM_CCMR1_IC1F_DTF_DIV_32_N_8 (0xF << 4) +#define TIM_CCMR1_IC1F_MASK (0xF << 4) + +/* IC1PSC[1:0]: Input capture 1 prescaler */ +#define TIM_CCMR1_IC1PSC_OFF (0x0 << 2) +#define TIM_CCMR1_IC1PSC_2 (0x1 << 2) +#define TIM_CCMR1_IC1PSC_4 (0x2 << 2) +#define TIM_CCMR1_IC1PSC_8 (0x3 << 2) +#define TIM_CCMR1_IC1PSC_MASK (0x3 << 2) + +/* --- TIMx_CCMR2 values --------------------------------------------------- */ + +/* --- Output compare mode --- */ + +/* OC4CE: Output compare 4 clear enable */ +#define TIM_CCMR2_OC4CE (1 << 15) + +/* OC4M[2:0]: Output compare 4 mode */ +#define TIM_CCMR2_OC4M_FROZEN (0x0 << 12) +#define TIM_CCMR2_OC4M_ACTIVE (0x1 << 12) +#define TIM_CCMR2_OC4M_INACTIVE (0x2 << 12) +#define TIM_CCMR2_OC4M_TOGGLE (0x3 << 12) +#define TIM_CCMR2_OC4M_FORCE_LOW (0x4 << 12) +#define TIM_CCMR2_OC4M_FORCE_HIGH (0x5 << 12) +#define TIM_CCMR2_OC4M_PWM1 (0x6 << 12) +#define TIM_CCMR2_OC4M_PWM2 (0x7 << 12) +#define TIM_CCMR2_OC4M_MASK (0x7 << 12) + +/* OC4PE: Output compare 4 preload enable */ +#define TIM_CCMR2_OC4PE (1 << 11) + +/* OC4FE: Output compare 4 fast enable */ +#define TIM_CCMR2_OC4FE (1 << 10) + +/* CC4S[1:0]: Capture/compare 4 selection */ +/* Note: CC2S bits are writable only when the channel is OFF (CC2E = 0 in + * TIMx_CCER). */ +#define TIM_CCMR2_CC4S_OUT (0x0 << 8) +#define TIM_CCMR2_CC4S_IN_TI4 (0x1 << 8) +#define TIM_CCMR2_CC4S_IN_TI3 (0x2 << 8) +#define TIM_CCMR2_CC4S_IN_TRC (0x3 << 8) +#define TIM_CCMR2_CC4S_MASK (0x3 << 8) + +/* OC3CE: Output compare 3 clear enable */ +#define TIM_CCMR2_OC3CE (1 << 7) + +/* OC3M[2:0]: Output compare 3 mode */ +#define TIM_CCMR2_OC3M_FROZEN (0x0 << 4) +#define TIM_CCMR2_OC3M_ACTIVE (0x1 << 4) +#define TIM_CCMR2_OC3M_INACTIVE (0x2 << 4) +#define TIM_CCMR2_OC3M_TOGGLE (0x3 << 4) +#define TIM_CCMR2_OC3M_FORCE_LOW (0x4 << 4) +#define TIM_CCMR2_OC3M_FORCE_HIGH (0x5 << 4) +#define TIM_CCMR2_OC3M_PWM1 (0x6 << 4) +#define TIM_CCMR2_OC3M_PWM2 (0x7 << 4) +#define TIM_CCMR2_OC3M_MASK (0x7 << 4) + +/* OC3PE: Output compare 3 preload enable */ +#define TIM_CCMR2_OC3PE (1 << 3) + +/* OC3FE: Output compare 3 fast enable */ +#define TIM_CCMR2_OC3FE (1 << 2) + +/* CC3S[1:0]: Capture/compare 3 selection */ +/* Note: CC2S bits are writable only when the channel is OFF (CC2E = 0 in + * TIMx_CCER). */ +#define TIM_CCMR2_CC3S_OUT (0x0 << 0) +#define TIM_CCMR2_CC3S_IN_TI3 (0x1 << 0) +#define TIM_CCMR2_CC3S_IN_TI4 (0x2 << 0) +#define TIM_CCMR2_CC3S_IN_TRC (0x3 << 0) +#define TIM_CCMR2_CC3S_MASK (0x3 << 0) + +/* --- Input capture mode --- */ + +/* IC4F[3:0]: Input capture 4 filter */ +#define TIM_CCMR2_IC4F_OFF (0x0 << 12) +#define TIM_CCMR2_IC4F_CK_INT_N_2 (0x1 << 12) +#define TIM_CCMR2_IC4F_CK_INT_N_4 (0x2 << 12) +#define TIM_CCMR2_IC4F_CK_INT_N_8 (0x3 << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_2_N_6 (0x4 << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_2_N_8 (0x5 << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_4_N_6 (0x6 << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_4_N_8 (0x7 << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_8_N_6 (0x8 << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_8_N_8 (0x9 << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_16_N_5 (0xA << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_16_N_6 (0xB << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_16_N_8 (0xC << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_32_N_5 (0xD << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_32_N_6 (0xE << 12) +#define TIM_CCMR2_IC4F_DTF_DIV_32_N_8 (0xF << 12) +#define TIM_CCMR2_IC4F_MASK (0xF << 12) + +/* IC4PSC[1:0]: Input capture 4 prescaler */ +#define TIM_CCMR2_IC4PSC_OFF (0x0 << 10) +#define TIM_CCMR2_IC4PSC_2 (0x1 << 10) +#define TIM_CCMR2_IC4PSC_4 (0x2 << 10) +#define TIM_CCMR2_IC4PSC_8 (0x3 << 10) +#define TIM_CCMR2_IC4PSC_MASK (0x3 << 10) + +/* IC3F[3:0]: Input capture 3 filter */ +#define TIM_CCMR2_IC3F_OFF (0x0 << 4) +#define TIM_CCMR2_IC3F_CK_INT_N_2 (0x1 << 4) +#define TIM_CCMR2_IC3F_CK_INT_N_4 (0x2 << 4) +#define TIM_CCMR2_IC3F_CK_INT_N_8 (0x3 << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_2_N_6 (0x4 << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_2_N_8 (0x5 << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_4_N_6 (0x6 << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_4_N_8 (0x7 << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_8_N_6 (0x8 << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_8_N_8 (0x9 << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_16_N_5 (0xA << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_16_N_6 (0xB << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_16_N_8 (0xC << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_32_N_5 (0xD << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_32_N_6 (0xE << 4) +#define TIM_CCMR2_IC3F_DTF_DIV_32_N_8 (0xF << 4) +#define TIM_CCMR2_IC3F_MASK (0xF << 4) + +/* IC3PSC[1:0]: Input capture 3 prescaler */ +#define TIM_CCMR2_IC3PSC_OFF (0x0 << 2) +#define TIM_CCMR2_IC3PSC_2 (0x1 << 2) +#define TIM_CCMR2_IC3PSC_4 (0x2 << 2) +#define TIM_CCMR2_IC3PSC_8 (0x3 << 2) +#define TIM_CCMR2_IC3PSC_MASK (0x3 << 2) + +/* --- TIMx_CCER values ---------------------------------------------------- */ + +/* CC4NP: Capture/compare 4 complementary output polarity */ +#define TIM_CCER_CC4NP (1 << 15) + +/* CC4P: Capture/compare 4 output polarity */ +#define TIM_CCER_CC4P (1 << 13) + +/* CC4E: Capture/compare 4 output enable */ +#define TIM_CCER_CC4E (1 << 12) + +/* CC3NP: Capture/compare 3 complementary output polarity */ +#define TIM_CCER_CC3NP (1 << 11) + +/* CC3NE: Capture/compare 3 complementary output enable */ +#define TIM_CCER_CC3NE (1 << 10) + +/* CC3P: Capture/compare 3 output polarity */ +#define TIM_CCER_CC3P (1 << 9) + +/* CC3E: Capture/compare 3 output enable */ +#define TIM_CCER_CC3E (1 << 8) + +/* CC2NP: Capture/compare 2 complementary output polarity */ +#define TIM_CCER_CC2NP (1 << 7) + +/* CC2NE: Capture/compare 2 complementary output enable */ +#define TIM_CCER_CC2NE (1 << 6) + +/* CC2P: Capture/compare 2 output polarity */ +#define TIM_CCER_CC2P (1 << 5) + +/* CC2E: Capture/compare 2 output enable */ +#define TIM_CCER_CC2E (1 << 4) + +/* CC1NP: Capture/compare 1 complementary output polarity */ +#define TIM_CCER_CC1NP (1 << 3) + +/* CC1NE: Capture/compare 1 complementary output enable */ +#define TIM_CCER_CC1NE (1 << 2) + +/* CC1P: Capture/compare 1 output polarity */ +#define TIM_CCER_CC1P (1 << 1) + +/* CC1E: Capture/compare 1 output enable */ +#define TIM_CCER_CC1E (1 << 0) + +/* --- TIMx_CNT values ----------------------------------------------------- */ + +/* CNT[15:0]: Counter value */ + +/* --- TIMx_PSC values ----------------------------------------------------- */ + +/* PSC[15:0]: Prescaler value */ + +/* --- TIMx_ARR values ----------------------------------------------------- */ + +/* ARR[15:0]: Prescaler value */ + +/* --- TIMx_RCR values ----------------------------------------------------- */ + +/* REP[15:0]: Repetition counter value */ + +/* --- TIMx_CCR1 values ---------------------------------------------------- */ + +/* CCR1[15:0]: Capture/compare 1 value */ + +/* --- TIMx_CCR2 values ---------------------------------------------------- */ + +/* CCR2[15:0]: Capture/compare 2 value */ + +/* --- TIMx_CCR3 values ---------------------------------------------------- */ + +/* CCR3[15:0]: Capture/compare 3 value */ + +/* --- TIMx_CCR4 values ---------------------------------------------------- */ + +/* CCR4[15:0]: Capture/compare 4 value */ + +/* --- TIMx_BDTR values ---------------------------------------------------- */ + +/* MOE: Main output enable */ +#define TIM_BDTR_MOE (1 << 15) + +/* AOE: Automatic output enable */ +#define TIM_BDTR_AOE (1 << 14) + +/* BKP: Break polarity */ +#define TIM_BDTR_BKP (1 << 13) + +/* BKE: Break enable */ +#define TIM_BDTR_BKE (1 << 12) + +/* OSSR: Off-state selection of run mode */ +#define TIM_BDTR_OSSR (1 << 11) + +/* OSSI: Off-state selection of idle mode */ +#define TIM_BDTR_OSSI (1 << 10) + +/* LOCK[1:0]: Lock configuration */ +/****************************************************************************/ +/** @defgroup tim_lock TIM_BDTR_LOCK Timer Lock Values +@ingroup timer_defines + +@{*/ +#define TIM_BDTR_LOCK_OFF (0x0 << 8) +#define TIM_BDTR_LOCK_LEVEL_1 (0x1 << 8) +#define TIM_BDTR_LOCK_LEVEL_2 (0x2 << 8) +#define TIM_BDTR_LOCK_LEVEL_3 (0x3 << 8) +#define TIM_BDTR_LOCK_MASK (0x3 << 8) +/**@}*/ + +/* DTG[7:0]: Dead-time generator set-up */ +#define TIM_BDTR_DTG_MASK 0x00FF + +/* --- TIMx_DCR values ----------------------------------------------------- */ + +/* DBL[4:0]: DMA burst length */ +#define TIM_BDTR_DBL_MASK (0x1F << 8) + +/* DBA[4:0]: DMA base address */ +#define TIM_BDTR_DBA_MASK (0x1F << 0) + +/* --- TIMx_DMAR values ---------------------------------------------------- */ + +/* DMAB[15:0]: DMA register for burst accesses */ + +/* --- TIMx convenience defines -------------------------------------------- */ + +/** Output Compare channel designators */ +enum tim_oc_id { + TIM_OC1 = 0, + TIM_OC1N, + TIM_OC2, + TIM_OC2N, + TIM_OC3, + TIM_OC3N, + TIM_OC4, +}; + +/** Output Compare mode designators */ +enum tim_oc_mode { + TIM_OCM_FROZEN, + TIM_OCM_ACTIVE, + TIM_OCM_INACTIVE, + TIM_OCM_TOGGLE, + TIM_OCM_FORCE_LOW, + TIM_OCM_FORCE_HIGH, + TIM_OCM_PWM1, + TIM_OCM_PWM2, +}; + +/** Input Capture channel designators */ +enum tim_ic_id { + TIM_IC1, + TIM_IC2, + TIM_IC3, + TIM_IC4, +}; + +/** Input Capture input filter. The frequency used to sample the +input and the number of events needed to validate an output transition. + +TIM_IC_CK_INT_N_x No division from the Deadtime and Sampling Clock frequency +(DTF), filter length x +TIM_IC_DTF_DIV_y_N_x Division by y from the DTF, filter length x + */ +enum tim_ic_filter { + TIM_IC_OFF, + TIM_IC_CK_INT_N_2, + TIM_IC_CK_INT_N_4, + TIM_IC_CK_INT_N_8, + TIM_IC_DTF_DIV_2_N_6, + TIM_IC_DTF_DIV_2_N_8, + TIM_IC_DTF_DIV_4_N_6, + TIM_IC_DTF_DIV_4_N_8, + TIM_IC_DTF_DIV_8_N_6, + TIM_IC_DTF_DIV_8_N_8, + TIM_IC_DTF_DIV_16_N_5, + TIM_IC_DTF_DIV_16_N_6, + TIM_IC_DTF_DIV_16_N_8, + TIM_IC_DTF_DIV_32_N_5, + TIM_IC_DTF_DIV_32_N_6, + TIM_IC_DTF_DIV_32_N_8, +}; + +/** Input Capture input prescaler. + +TIM_IC_PSC_x Input capture is done every x events*/ +enum tim_ic_psc { + TIM_IC_PSC_OFF, + TIM_IC_PSC_2, + TIM_IC_PSC_4, + TIM_IC_PSC_8, +}; + +/** Input Capture input source. + +The direction of the channel (input/output) as well as the input used. + */ +enum tim_ic_input { + TIM_IC_OUT = 0, + TIM_IC_IN_TI1 = 1, + TIM_IC_IN_TI2 = 2, + TIM_IC_IN_TRC = 3, + TIM_IC_IN_TI3 = 5, + TIM_IC_IN_TI4 = 6, +}; + +/** Slave external trigger polarity */ +enum tim_et_pol { + TIM_ET_RISING, + TIM_ET_FALLING, +}; + +/* --- TIM function prototypes --------------------------------------------- */ + +BEGIN_DECLS + +void timer_reset(uint32_t timer_peripheral); +void timer_enable_irq(uint32_t timer_peripheral, uint32_t irq); +void timer_disable_irq(uint32_t timer_peripheral, uint32_t irq); +bool timer_interrupt_source(uint32_t timer_peripheral, uint32_t flag); +bool timer_get_flag(uint32_t timer_peripheral, uint32_t flag); +void timer_clear_flag(uint32_t timer_peripheral, uint32_t flag); +void timer_set_mode(uint32_t timer_peripheral, uint32_t clock_div, + uint32_t alignment, uint32_t direction); +void timer_set_clock_division(uint32_t timer_peripheral, uint32_t clock_div); +void timer_enable_preload(uint32_t timer_peripheral); +void timer_disable_preload(uint32_t timer_peripheral); +void timer_set_alignment(uint32_t timer_peripheral, uint32_t alignment); +void timer_direction_up(uint32_t timer_peripheral); +void timer_direction_down(uint32_t timer_peripheral); +void timer_one_shot_mode(uint32_t timer_peripheral); +void timer_continuous_mode(uint32_t timer_peripheral); +void timer_update_on_any(uint32_t timer_peripheral); +void timer_update_on_overflow(uint32_t timer_peripheral); +void timer_enable_update_event(uint32_t timer_peripheral); +void timer_disable_update_event(uint32_t timer_peripheral); +void timer_enable_counter(uint32_t timer_peripheral); +void timer_disable_counter(uint32_t timer_peripheral); +void timer_set_output_idle_state(uint32_t timer_peripheral, uint32_t outputs); +void timer_reset_output_idle_state(uint32_t timer_peripheral, uint32_t outputs); +void timer_set_ti1_ch123_xor(uint32_t timer_peripheral); +void timer_set_ti1_ch1(uint32_t timer_peripheral); +void timer_set_master_mode(uint32_t timer_peripheral, uint32_t mode); +void timer_set_dma_on_compare_event(uint32_t timer_peripheral); +void timer_set_dma_on_update_event(uint32_t timer_peripheral); +void timer_enable_compare_control_update_on_trigger(uint32_t timer_peripheral); +void timer_disable_compare_control_update_on_trigger(uint32_t timer_peripheral); +void timer_enable_preload_complementry_enable_bits(uint32_t timer_peripheral); +void timer_disable_preload_complementry_enable_bits(uint32_t timer_peripheral); +void timer_set_prescaler(uint32_t timer_peripheral, uint32_t value); +void timer_set_repetition_counter(uint32_t timer_peripheral, uint32_t value); +void timer_set_period(uint32_t timer_peripheral, uint32_t period); +void timer_enable_oc_clear(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_disable_oc_clear(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_fast_mode(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_slow_mode(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_mode(uint32_t timer_peripheral, enum tim_oc_id oc_id, + enum tim_oc_mode oc_mode); +void timer_enable_oc_preload(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_disable_oc_preload(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_polarity_high(uint32_t timer_peripheral, + enum tim_oc_id oc_id); +void timer_set_oc_polarity_low(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_enable_oc_output(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_disable_oc_output(uint32_t timer_peripheral, enum tim_oc_id oc_id); +void timer_set_oc_idle_state_set(uint32_t timer_peripheral, + enum tim_oc_id oc_id); +void timer_set_oc_idle_state_unset(uint32_t timer_peripheral, + enum tim_oc_id oc_id); +void timer_set_oc_value(uint32_t timer_peripheral, enum tim_oc_id oc_id, + uint32_t value); +void timer_enable_break_main_output(uint32_t timer_peripheral); +void timer_disable_break_main_output(uint32_t timer_peripheral); +void timer_enable_break_automatic_output(uint32_t timer_peripheral); +void timer_disable_break_automatic_output(uint32_t timer_peripheral); +void timer_set_break_polarity_high(uint32_t timer_peripheral); +void timer_set_break_polarity_low(uint32_t timer_peripheral); +void timer_enable_break(uint32_t timer_peripheral); +void timer_disable_break(uint32_t timer_peripheral); +void timer_set_enabled_off_state_in_run_mode(uint32_t timer_peripheral); +void timer_set_disabled_off_state_in_run_mode(uint32_t timer_peripheral); +void timer_set_enabled_off_state_in_idle_mode(uint32_t timer_peripheral); +void timer_set_disabled_off_state_in_idle_mode(uint32_t timer_peripheral); +void timer_set_break_lock(uint32_t timer_peripheral, uint32_t lock); +void timer_set_deadtime(uint32_t timer_peripheral, uint32_t deadtime); +void timer_generate_event(uint32_t timer_peripheral, uint32_t event); +uint32_t timer_get_counter(uint32_t timer_peripheral); +void timer_set_counter(uint32_t timer_peripheral, uint32_t count); + +void timer_ic_set_filter(uint32_t timer, enum tim_ic_id ic, + enum tim_ic_filter flt); +void timer_ic_set_prescaler(uint32_t timer, enum tim_ic_id ic, + enum tim_ic_psc psc); +void timer_ic_set_input(uint32_t timer, enum tim_ic_id ic, + enum tim_ic_input in); +void timer_ic_enable(uint32_t timer, enum tim_ic_id ic); +void timer_ic_disable(uint32_t timer, enum tim_ic_id ic); + +void timer_slave_set_filter(uint32_t timer, enum tim_ic_filter flt); +void timer_slave_set_prescaler(uint32_t timer, enum tim_ic_psc psc); +void timer_slave_set_polarity(uint32_t timer, enum tim_et_pol pol); +void timer_slave_set_mode(uint32_t timer, uint8_t mode); +void timer_slave_set_trigger(uint32_t timer, uint8_t trigger); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "timer_common_all.h should not be included directly, only via timer.h" +#endif +/** @endcond */ +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_f24.h new file mode 100644 index 00000000..6f483d86 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/timer_common_f24.h @@ -0,0 +1,114 @@ +/** @addtogroup timer_defines + +@author @htmlonly © @endhtmlonly 2011 Fergus Noble + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA TIMER.H +The order of header inclusion is important. timer.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_TIMER_H +/** @endcond */ +#ifndef LIBOPENCM3_TIMER_COMMON_F24_H +#define LIBOPENCM3_TIMER_COMMON_F24_H + +#include + +/* + * TIM2 and TIM5 are now 32bit and the following registers are now 32-bit wide: + * CNT, ARR, CCR1, CCR2, CCR3, CCR4 + */ + +/* Timer 2/5 option register (TIMx_OR) */ +#define TIM_OR(tim_base) MMIO32((tim_base) + 0x50) +#define TIM2_OR TIM_OR(TIM2) +#define TIM5_OR TIM_OR(TIM5) + +/* --- TIM2_OR values ---------------------------------------------------- */ + +/* ITR1_RMP */ +/****************************************************************************/ +/** @defgroup tim2_opt_trigger_remap TIM2_OR Timer 2 Option Register Internal +Trigger 1 Remap + +Only available in F2 and F4 series. +@ingroup timer_defines + +@{*/ +/** Internal Trigger 1 remapped to timer 8 trigger out */ +#define TIM2_OR_ITR1_RMP_TIM8_TRGOU (0x0 << 10) +/** Internal Trigger 1 remapped to PTP trigger out */ +#define TIM2_OR_ITR1_RMP_PTP (0x1 << 10) +/** Internal Trigger 1 remapped to USB OTG FS SOF */ +#define TIM2_OR_ITR1_RMP_OTG_FS_SOF (0x2 << 10) +/** Internal Trigger 1 remapped to USB OTG HS SOF */ +#define TIM2_OR_ITR1_RMP_OTG_HS_SOF (0x3 << 10) +/**@}*/ +#define TIM2_OR_ITR1_RMP_MASK (0x3 << 10) + +/* --- TIM5_OR values ---------------------------------------------------- */ + +/* ITR4_RMP */ +/****************************************************************************/ +/** @defgroup tim5_opt_trigger_remap TIM5_OR Timer 5 Option Register Internal Trigger 4 Remap + +Only available in F2 and F4 series. +@ingroup timer_defines + +@{*/ +/** Internal Trigger 4 remapped to GPIO (see reference manual) */ +#define TIM5_OR_TI4_RMP_GPIO (0x0 << 6) +/** Internal Trigger 4 remapped to LSI internal clock */ +#define TIM5_OR_TI4_RMP_LSI (0x1 << 6) +/** Internal Trigger 4 remapped to LSE internal clock */ +#define TIM5_OR_TI4_RMP_LSE (0x2 << 6) +/** Internal Trigger 4 remapped to RTC output event */ +#define TIM5_OR_TI4_RMP_RTC (0x3 << 6) +/**@}*/ +#define TIM5_OR_TI4_RMP_MASK (0x3 << 6) + +/** Input Capture input polarity */ +enum tim_ic_pol { + TIM_IC_RISING, + TIM_IC_FALLING, + TIM_IC_BOTH, +}; + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void timer_set_option(uint32_t timer_peripheral, uint32_t option); +void timer_ic_set_polarity(uint32_t timer, enum tim_ic_id ic, + enum tim_ic_pol pol); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "timer_common_f24.h should not be included directly, only via timer.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_all.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_all.h new file mode 100644 index 00000000..f838dfea --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_all.h @@ -0,0 +1,140 @@ +/** @addtogroup usart_defines + * + * @author @htmlonly © @endhtmlonly 2009 Uwe Hermann + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA USART.H +The order of header inclusion is important. usart.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#if defined(LIBOPENCM3_USART_H) +/** @endcond */ +#ifndef LIBOPENCM3_USART_COMMON_ALL_H +#define LIBOPENCM3_USART_COMMON_ALL_H + +/* --- Convenience macros -------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup usart_reg_base USART register base addresses +@ingroup STM32F_usart_defines + +@{*/ +#define USART1 USART1_BASE +#define USART2 USART2_BASE +#define USART3 USART3_BASE +/**@}*/ +#define UART4 UART4_BASE +#define UART5 UART5_BASE + +/* --- Convenience defines ------------------------------------------------- */ + +/* CR1_PCE / CR1_PS combined values */ +/****************************************************************************/ +/** @defgroup usart_cr1_parity USART Parity Selection +@ingroup STM32F_usart_defines + +@{*/ +#define USART_PARITY_NONE 0x00 +#define USART_PARITY_EVEN USART_CR1_PCE +#define USART_PARITY_ODD (USART_CR1_PS | USART_CR1_PCE) +/**@}*/ +#define USART_PARITY_MASK (USART_CR1_PS | USART_CR1_PCE) + +/* CR1_TE/CR1_RE combined values */ +/****************************************************************************/ +/** @defgroup usart_cr1_mode USART Tx/Rx Mode Selection +@ingroup STM32F_usart_defines + +@{*/ +#define USART_MODE_RX USART_CR1_RE +#define USART_MODE_TX USART_CR1_TE +#define USART_MODE_TX_RX (USART_CR1_RE | USART_CR1_TE) +/**@}*/ +#define USART_MODE_MASK (USART_CR1_RE | USART_CR1_TE) + +/****************************************************************************/ +/** @defgroup usart_cr2_stopbits USART Stop Bit Selection +@ingroup STM32F_usart_defines + +@{*/ +#define USART_STOPBITS_1 USART_CR2_STOPBITS_1 /* 1 stop bit */ +#define USART_STOPBITS_0_5 USART_CR2_STOPBITS_0_5 /* .5 stop bit */ +#define USART_STOPBITS_2 USART_CR2_STOPBITS_2 /* 2 stop bits */ +#define USART_STOPBITS_1_5 USART_CR2_STOPBITS_1_5 /* 1.5 stop bit*/ +/**@}*/ + +/* CR3_CTSE/CR3_RTSE combined values */ +/****************************************************************************/ +/** @defgroup usart_cr3_flowcontrol USART Hardware Flow Control Selection +@ingroup STM32F_usart_defines + +@{*/ +#define USART_FLOWCONTROL_NONE 0x00 +#define USART_FLOWCONTROL_RTS USART_CR3_RTSE +#define USART_FLOWCONTROL_CTS USART_CR3_CTSE +#define USART_FLOWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) +/**@}*/ +#define USART_FLOWCONTROL_MASK (USART_CR3_RTSE | USART_CR3_CTSE) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void usart_set_baudrate(uint32_t usart, uint32_t baud); +void usart_set_databits(uint32_t usart, uint32_t bits); +void usart_set_stopbits(uint32_t usart, uint32_t stopbits); +void usart_set_parity(uint32_t usart, uint32_t parity); +void usart_set_mode(uint32_t usart, uint32_t mode); +void usart_set_flow_control(uint32_t usart, uint32_t flowcontrol); +void usart_enable(uint32_t usart); +void usart_disable(uint32_t usart); +void usart_send(uint32_t usart, uint16_t data); +uint16_t usart_recv(uint32_t usart); +void usart_wait_send_ready(uint32_t usart); +void usart_wait_recv_ready(uint32_t usart); +void usart_send_blocking(uint32_t usart, uint16_t data); +uint16_t usart_recv_blocking(uint32_t usart); +void usart_enable_rx_dma(uint32_t usart); +void usart_disable_rx_dma(uint32_t usart); +void usart_enable_tx_dma(uint32_t usart); +void usart_disable_tx_dma(uint32_t usart); +void usart_enable_rx_interrupt(uint32_t usart); +void usart_disable_rx_interrupt(uint32_t usart); +void usart_enable_tx_interrupt(uint32_t usart); +void usart_disable_tx_interrupt(uint32_t usart); +void usart_enable_error_interrupt(uint32_t usart); +void usart_disable_error_interrupt(uint32_t usart); +bool usart_get_flag(uint32_t usart, uint32_t flag); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "usart_common_all.h should not be included directly, only via usart.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f124.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f124.h new file mode 100644 index 00000000..cd6f56ff --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f124.h @@ -0,0 +1,288 @@ +/** @addtogroup usart_defines + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA USART.H +The order of header inclusion is important. usart.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#if defined(LIBOPENCM3_USART_H) +/** @endcond */ +#ifndef LIBOPENCM3_USART_COMMON_F124_H +#define LIBOPENCM3_USART_COMMON_F124_H + +#include + +/* --- USART registers ----------------------------------------------------- */ + +/* Status register (USARTx_SR) */ +#define USART_SR(usart_base) MMIO32((usart_base) + 0x00) +#define USART1_SR USART_SR(USART1_BASE) +#define USART2_SR USART_SR(USART2_BASE) +#define USART3_SR USART_SR(USART3_BASE) +#define UART4_SR USART_SR(UART4_BASE) +#define UART5_SR USART_SR(UART5_BASE) + +/* Data register (USARTx_DR) */ +#define USART_DR(usart_base) MMIO32((usart_base) + 0x04) +#define USART1_DR USART_DR(USART1_BASE) +#define USART2_DR USART_DR(USART2_BASE) +#define USART3_DR USART_DR(USART3_BASE) +#define UART4_DR USART_DR(UART4_BASE) +#define UART5_DR USART_DR(UART5_BASE) + +/* Baud rate register (USARTx_BRR) */ +#define USART_BRR(usart_base) MMIO32((usart_base) + 0x08) +#define USART1_BRR USART_BRR(USART1_BASE) +#define USART2_BRR USART_BRR(USART2_BASE) +#define USART3_BRR USART_BRR(USART3_BASE) +#define UART4_BRR USART_BRR(UART4_BASE) +#define UART5_BRR USART_BRR(UART5_BASE) + +/* Control register 1 (USARTx_CR1) */ +#define USART_CR1(usart_base) MMIO32((usart_base) + 0x0c) +#define USART1_CR1 USART_CR1(USART1_BASE) +#define USART2_CR1 USART_CR1(USART2_BASE) +#define USART3_CR1 USART_CR1(USART3_BASE) +#define UART4_CR1 USART_CR1(UART4_BASE) +#define UART5_CR1 USART_CR1(UART5_BASE) + +/* Control register 2 (USARTx_CR2) */ +#define USART_CR2(usart_base) MMIO32((usart_base) + 0x10) +#define USART1_CR2 USART_CR2(USART1_BASE) +#define USART2_CR2 USART_CR2(USART2_BASE) +#define USART3_CR2 USART_CR2(USART3_BASE) +#define UART4_CR2 USART_CR2(UART4_BASE) +#define UART5_CR2 USART_CR2(UART5_BASE) + +/* Control register 3 (USARTx_CR3) */ +#define USART_CR3(usart_base) MMIO32((usart_base) + 0x14) +#define USART1_CR3 USART_CR3(USART1_BASE) +#define USART2_CR3 USART_CR3(USART2_BASE) +#define USART3_CR3 USART_CR3(USART3_BASE) +#define UART4_CR3 USART_CR3(UART4_BASE) +#define UART5_CR3 USART_CR3(UART5_BASE) + +/* Guard time and prescaler register (USARTx_GTPR) */ +#define USART_GTPR(usart_base) MMIO32((usart_base) + 0x18) +#define USART1_GTPR USART_GTPR(USART1_BASE) +#define USART2_GTPR USART_GTPR(USART2_BASE) +#define USART3_GTPR USART_GTPR(USART3_BASE) +#define UART4_GTPR USART_GTPR(UART4_BASE) +#define UART5_GTPR USART_GTPR(UART5_BASE) + +/* --- USART_SR values ----------------------------------------------------- */ +/****************************************************************************/ +/** @defgroup usart_sr_flags USART Status register Flags +@ingroup STM32F_usart_defines + +@{*/ + +/** CTS: CTS flag */ +/** @note: undefined on UART4 and UART5 */ +#define USART_SR_CTS (1 << 9) + +/** LBD: LIN break detection flag */ +#define USART_SR_LBD (1 << 8) + +/** TXE: Transmit data buffer empty */ +#define USART_SR_TXE (1 << 7) + +/** TC: Transmission complete */ +#define USART_SR_TC (1 << 6) + +/** RXNE: Read data register not empty */ +#define USART_SR_RXNE (1 << 5) + +/** IDLE: Idle line detected */ +#define USART_SR_IDLE (1 << 4) + +/** ORE: Overrun error */ +#define USART_SR_ORE (1 << 3) + +/** NE: Noise error flag */ +#define USART_SR_NE (1 << 2) + +/** FE: Framing error */ +#define USART_SR_FE (1 << 1) + +/** PE: Parity error */ +#define USART_SR_PE (1 << 0) +/**@}*/ + +/* --- USART_DR values ----------------------------------------------------- */ + +/* USART_DR[8:0]: DR[8:0]: Data value */ +#define USART_DR_MASK 0x1FF + +/* --- USART_BRR values ---------------------------------------------------- */ + +/* DIV_Mantissa[11:0]: mantissa of USARTDIV */ +#define USART_BRR_DIV_MANTISSA_MASK (0xFFF << 4) +/* DIV_Fraction[3:0]: fraction of USARTDIV */ +#define USART_BRR_DIV_FRACTION_MASK 0xF + +/* --- USART_CR1 values ---------------------------------------------------- */ + +/* UE: USART enable */ +#define USART_CR1_UE (1 << 13) + +/* M: Word length */ +#define USART_CR1_M (1 << 12) + +/* WAKE: Wakeup method */ +#define USART_CR1_WAKE (1 << 11) + +/* PCE: Parity control enable */ +#define USART_CR1_PCE (1 << 10) + +/* PS: Parity selection */ +#define USART_CR1_PS (1 << 9) + +/* PEIE: PE interrupt enable */ +#define USART_CR1_PEIE (1 << 8) + +/* TXEIE: TXE interrupt enable */ +#define USART_CR1_TXEIE (1 << 7) + +/* TCIE: Transmission complete interrupt enable */ +#define USART_CR1_TCIE (1 << 6) + +/* RXNEIE: RXNE interrupt enable */ +#define USART_CR1_RXNEIE (1 << 5) + +/* IDLEIE: IDLE interrupt enable */ +#define USART_CR1_IDLEIE (1 << 4) + +/* TE: Transmitter enable */ +#define USART_CR1_TE (1 << 3) + +/* RE: Receiver enable */ +#define USART_CR1_RE (1 << 2) + +/* RWU: Receiver wakeup */ +#define USART_CR1_RWU (1 << 1) + +/* SBK: Send break */ +#define USART_CR1_SBK (1 << 0) + +/* --- USART_CR2 values ---------------------------------------------------- */ + +/* LINEN: LIN mode enable */ +#define USART_CR2_LINEN (1 << 14) + +/* STOP[13:12]: STOP bits */ +#define USART_CR2_STOPBITS_1 (0x00 << 12) /* 1 stop bit */ +#define USART_CR2_STOPBITS_0_5 (0x01 << 12) /* 0.5 stop bits */ +#define USART_CR2_STOPBITS_2 (0x02 << 12) /* 2 stop bits */ +#define USART_CR2_STOPBITS_1_5 (0x03 << 12) /* 1.5 stop bits */ +#define USART_CR2_STOPBITS_MASK (0x03 << 12) +#define USART_CR2_STOPBITS_SHIFT 12 + +/* CLKEN: Clock enable */ +#define USART_CR2_CLKEN (1 << 11) + +/* CPOL: Clock polarity */ +#define USART_CR2_CPOL (1 << 10) + +/* CPHA: Clock phase */ +#define USART_CR2_CPHA (1 << 9) + +/* LBCL: Last bit clock pulse */ +#define USART_CR2_LBCL (1 << 8) + +/* LBDIE: LIN break detection interrupt enable */ +#define USART_CR2_LBDIE (1 << 6) + +/* LBDL: LIN break detection length */ +#define USART_CR2_LBDL (1 << 5) + +/* ADD[3:0]: Address of the usart node */ +#define USART_CR2_ADD_MASK 0xF + +/* --- USART_CR3 values ---------------------------------------------------- */ + +/* CTSIE: CTS interrupt enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_CTSIE (1 << 10) + +/* CTSE: CTS enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_CTSE (1 << 9) + +/* RTSE: RTS enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_RTSE (1 << 8) + +/* DMAT: DMA enable transmitter */ +/* Note: N/A on UART5 */ +#define USART_CR3_DMAT (1 << 7) + +/* DMAR: DMA enable receiver */ +/* Note: N/A on UART5 */ +#define USART_CR3_DMAR (1 << 6) + +/* SCEN: Smartcard mode enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_SCEN (1 << 5) + +/* NACK: Smartcard NACK enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_NACK (1 << 4) + +/* HDSEL: Half-duplex selection */ +#define USART_CR3_HDSEL (1 << 3) + +/* IRLP: IrDA low-power */ +#define USART_CR3_IRLP (1 << 2) + +/* IREN: IrDA mode enable */ +#define USART_CR3_IREN (1 << 1) + +/* EIE: Error interrupt enable */ +#define USART_CR3_EIE (1 << 0) + +/* --- USART_GTPR values --------------------------------------------------- */ + +/* GT[7:0]: Guard time value */ +/* Note: N/A on UART4 & UART5 */ +#define USART_GTPR_GT_MASK (0xFF << 8) + +/* PSC[7:0]: Prescaler value */ +/* Note: N/A on UART4/5 */ +#define USART_GTPR_PSC_MASK 0xFF + +/* TODO */ /* Note to Uwe: what needs to be done here? */ + +#endif +/** @cond */ +#else +#warning "usart_common_all.h should not be included directly, only via usart.h" +#endif +/** @endcond */ +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f24.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f24.h new file mode 100644 index 00000000..e8d9f7f0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_f24.h @@ -0,0 +1,98 @@ +/** @addtogroup usart_defines + +@author @htmlonly © @endhtmlonly 2011 Uwe Hermann +@author @htmlonly © @endhtmlonly 2011 Stephen Caudle + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA USART.H +The order of header inclusion is important. usart.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_USART_H +/** @endcond */ +#ifndef LIBOPENCM3_USART_COMMON_F24_H +#define LIBOPENCM3_USART_COMMON_F24_H + +#include + +/* --- Convenience macros -------------------------------------------------- */ + +#define USART6 USART6_BASE +#define UART7 UART7_BASE +#define UART8 UART8_BASE + +/* --- USART registers ----------------------------------------------------- */ + +/* Status register (USARTx_SR) */ +#define USART6_SR USART_SR(USART6_BASE) +#define UART7_SR USART_SR(UART7) +#define UART8_SR USART_SR(UART8) + +/* Data register (USARTx_DR) */ +#define USART6_DR USART_DR(USART6_BASE) +#define UART7_DR USART_DR(UART7) +#define UART8_DR USART_DR(UART8) + +/* Baud rate register (USARTx_BRR) */ +#define USART6_BRR USART_BRR(USART6_BASE) +#define UART7_BRR USART_BRR(UART7) +#define UART8_BRR USART_BRR(UART8) + +/* Control register 1 (USARTx_CR1) */ +#define USART6_CR1 USART_CR1(USART6_BASE) +#define UART7_CR1 USART_CR1(UART7) +#define UART8_CR1 USART_CR1(UART8) + +/* Control register 2 (USARTx_CR2) */ +#define USART6_CR2 USART_CR2(USART6_BASE) +#define UART7_CR2 USART_CR2(UART7) +#define UART8_CR2 USART_CR2(UART8) + +/* Control register 3 (USARTx_CR3) */ +#define USART6_CR3 USART_CR3(USART6_BASE) +#define UART7_CR3 USART_CR3(UART7) +#define UART8_CR3 USART_CR3(UART8) + +/* Guard time and prescaler register (USARTx_GTPR) */ +#define USART6_GTPR USART_GTPR(USART6_BASE) +#define UART7_GTPR USART_GTPR(UART7) +#define UART8_GTPR USART_GTPR(UART8) + +/* --- USART_CR1 values ---------------------------------------------------- */ + +/* OVER8: Oversampling mode */ +#define USART_CR1_OVER8 (1 << 15) + +/* --- USART_CR3 values ---------------------------------------------------- */ + +/* ONEBIT: One sample bit method enable */ +#define USART_CR3_ONEBIT (1 << 11) + +#endif +/** @cond */ +#else +#warning "usart_common_f24.h should not be included directly, only via usart.h" +#endif +/** @endcond */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_v2.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_v2.h new file mode 100644 index 00000000..0df94be9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/common/usart_common_v2.h @@ -0,0 +1,73 @@ +/** @addtogroup usart_defines + + @author @htmlonly © @endhtmlonly 2016 Cem Basoglu + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Cem Basoglu + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/** @cond */ +#if defined(LIBOPENCM3_USART_H) +/** @endcond */ +#ifndef LIBOPENCM3_USART_COMMON_V2_H +#define LIBOPENCM3_USART_COMMON_V2_H + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- USART_RTOR values --------------------------------------------------- */ + +/* BLEN[7:0]: Block Length */ +#define USART_RTOR_BLEN_SHIFT 24 +#define USART_RTOR_BLEN_MASK (0xFF << USART_RTOR_BLEN_SHIFT) +#define USART_RTOR_BLEN_VAL(x) ((x) << USART_RTOR_BLEN_SHIFT) + +/* RTO[23:0]: Receiver timeout value */ +#define USART_RTOR_RTO_SHIFT 0 +#define USART_RTOR_RTO_MASK (0xFFFFF << USART_RTOR_RTO_SHIFT) +#define USART_RTOR_RTO_VAL(x) ((x) << USART_RTOR_RTO_SHIFT) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void usart_enable_data_inversion(uint32_t usart); +void usart_disable_data_inversion(uint32_t usart); +void usart_enable_tx_inversion(uint32_t usart); +void usart_disable_tx_inversion(uint32_t usart); +void usart_enable_rx_inversion(uint32_t usart); +void usart_disable_rx_inversion(uint32_t usart); +void usart_enable_halfduplex(uint32_t usart); +void usart_disable_halfduplex(uint32_t usart); + +void usart_set_rx_timeout_value(uint32_t usart, uint32_t value); +void usart_enable_rx_timeout(uint32_t usart); +void usart_disable_rx_timeout(uint32_t usart); +void usart_enable_rx_timeout_interrupt(uint32_t usart); +void usart_disable_rx_timeout_interrupt(uint32_t usart); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "usart_common_v2.h should not be included directly, only via usart.h" +#endif +/** @endcond */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/comparator.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/comparator.h new file mode 100644 index 00000000..2fdb2902 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/comparator.h @@ -0,0 +1,28 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crc.h new file mode 100644 index 00000000..de6f4482 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crc.h @@ -0,0 +1,38 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crs.h new file mode 100644 index 00000000..50c94b5b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crs.h @@ -0,0 +1,30 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32L0) +# include +#else +# error "stm32 family not defined or not supported for this peripheral" +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crypto.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crypto.h new file mode 100644 index 00000000..edce6a10 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/crypto.h @@ -0,0 +1,30 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F2) +# include +#elif defined(STM32F4) +# include +#else +# error "CRYPTO processor is supported only" \ + "in stm32f2xx, stm32f41xx, stm32f42xx and stm32f43xx family." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dac.h new file mode 100644 index 00000000..0f348bb4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dac.h @@ -0,0 +1,38 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dbgmcu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dbgmcu.h new file mode 100644 index 00000000..cb4c5f69 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dbgmcu.h @@ -0,0 +1,72 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_STM32_DBGMCU_H +#define LIBOPENCM3_STM32_DBGMCU_H + +#include +#include + +/* --- DBGMCU registers ---------------------------------------------------- */ + +/* Debug MCU IDCODE register (DBGMCU_IDCODE) */ +#define DBGMCU_IDCODE MMIO32(DBGMCU_BASE + 0x00) + +/* Debug MCU configuration register (DBGMCU_CR) */ +/* Note: Only 32bit access supported. */ +#define DBGMCU_CR MMIO32(DBGMCU_BASE + 0x04) + +/* --- DBGMCU_IDCODE values ------------------------------------------------ */ + +#define DBGMCU_IDCODE_DEV_ID_MASK 0x00000fff +#define DBGMCU_IDCODE_REV_ID_MASK 0xffff0000 + +/* --- DBGMCU_CR values ---------------------------------------------------- */ + +/* Bit 31: Reserved. */ + +/* Bits [24:22]: Reserved, must be kept cleared. */ + +/* Bits [4:3]: Reserved. */ + +#define DBGMCU_CR_SLEEP 0x00000001 +#define DBGMCU_CR_STOP 0x00000002 +#define DBGMCU_CR_STANDBY 0x00000004 +#define DBGMCU_CR_TRACE_IOEN 0x00000020 +#define DBGMCU_CR_TRACE_MODE_MASK 0x000000C0 +#define DBGMCU_CR_TRACE_MODE_ASYNC 0x00000000 +#define DBGMCU_CR_TRACE_MODE_SYNC_1 0x00000040 +#define DBGMCU_CR_TRACE_MODE_SYNC_2 0x00000080 +#define DBGMCU_CR_TRACE_MODE_SYNC_4 0x000000C0 +#define DBGMCU_CR_IWDG_STOP 0x00000100 +#define DBGMCU_CR_WWDG_STOP 0x00000200 +#define DBGMCU_CR_TIM1_STOP 0x00000400 +#define DBGMCU_CR_TIM2_STOP 0x00000800 +#define DBGMCU_CR_TIM3_STOP 0x00001000 +#define DBGMCU_CR_TIM4_STOP 0x00002000 +#define DBGMCU_CR_CAN1_STOP 0x00004000 +#define DBGMCU_CR_I2C1_SMBUS_TIMEOUT 0x00008000 +#define DBGMCU_CR_I2C2_SMBUS_TIMEOUT 0x00010000 +#define DBGMCU_CR_TIM8_STOP 0x00020000 +#define DBGMCU_CR_TIM5_STOP 0x00040000 +#define DBGMCU_CR_TIM6_STOP 0x00080000 +#define DBGMCU_CR_TIM7_STOP 0x00100000 +#define DBGMCU_CR_CAN2_STOP 0x00200000 + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/desig.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/desig.h new file mode 100644 index 00000000..f181cbc6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/desig.h @@ -0,0 +1,65 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DESIG_H +#define LIBOPENCM3_DESIG_H + +#include +#include + +/* --- Device Electronic Signature -------------------------------- */ + +/* Flash size register */ +#define DESIG_FLASH_SIZE MMIO16(DESIG_FLASH_SIZE_BASE + 0x00) + +BEGIN_DECLS + +/** + * Read the on board flash size + * @return flash size in KB + */ +uint16_t desig_get_flash_size(void); + +/** + * Read the full 96 bit unique identifier + * Note: ST specifies that bits 31..16 are _also_ reserved for future use + * @param result pointer to at least 3xuint32_ts (96 bits) + */ +void desig_get_unique_id(uint32_t *result); + +/** + * Read the full 96 bit unique identifier and return it as a + * zero-terminated string + * @param string memory region to write the result to + * @param string_len the size of string in bytes + */ +void desig_get_unique_id_as_string(char *string, + unsigned int string_len); + +/** + * Returns the same serial number that the factory DFU + * bootloader reports (via USB descriptors). + * @param string memory region to write the result to. This is + * expected to be a 13-byte buffer. + */ +void desig_get_unique_id_as_dfu(char *string); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma.h new file mode 100644 index 00000000..658b7a60 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma.h @@ -0,0 +1,38 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma2d.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma2d.h new file mode 100644 index 00000000..178c1b07 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dma2d.h @@ -0,0 +1,28 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F4) +# include +#else +# error "dma2d.h not available for this family." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dsi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dsi.h new file mode 100644 index 00000000..a6074781 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/dsi.h @@ -0,0 +1,25 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(STM32F4) +# include +#else +# error "dsi.h not available for this family." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/exti.h new file mode 100644 index 00000000..a9f17ff6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/exti.h @@ -0,0 +1,42 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/adc.h new file mode 100644 index 00000000..eaf52fe8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/adc.h @@ -0,0 +1,196 @@ +/** @defgroup adc_defines ADC Defines + * + * @brief Defined Constants and Types for the STM32F0xx Analog to Digital + * Converter + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/** @defgroup adc_reg_base ADC register base addresses + * @ingroup adc_defines + * + *@{*/ +#define ADC ADC_BASE +#define ADC1 ADC_BASE/* for API compatibility */ +/**@}*/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define ADC1_ISR ADC_ISR(ADC) +#define ADC1_IER ADC_IER(ADC) +#define ADC1_CR ADC_CR(ADC) +#define ADC1_CFGR1 ADC_CFGR1(ADC) +#define ADC1_CFGR2 ADC_CFGR2(ADC) +#define ADC1_SMPR1 ADC_SMPR1(ADC) +#define ADC_SMPR(adc) ADC_SMPR1(adc) /* Compatibility */ +#define ADC1_SMPR ADC_SMPR1(ADC) /* Compatibility */ +#define ADC1_TR1 ADC_TR1(ADC) +#define ADC_TR(adc) ADC_TR1(adc) /* Compatibility */ +#define ADC1_TR ADC1_TR(ADC) /* Compatibility */ +#define ADC1_CHSELR ADC_CHSELR(ADC) +#define ADC1_DR ADC_DR(ADC) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* ADC_CFGR2 Values ---------------------------------------------------------*/ + +#define ADC_CFGR2_CKMODE_SHIFT 30 +#define ADC_CFGR2_CKMODE (3 << ADC_CFGR2_CKMODE_SHIFT) +#define ADC_CFGR2_CKMODE_CK_ADC (0 << ADC_CFGR2_CKMODE_SHIFT) +#define ADC_CFGR2_CKMODE_PCLK_DIV2 (1 << ADC_CFGR2_CKMODE_SHIFT) +#define ADC_CFGR2_CKMODE_PCLK_DIV4 (2 << ADC_CFGR2_CKMODE_SHIFT) + +/* ADC_SMPR Values ----------------------------------------------------------*/ + +#define ADC_SMPR_SMP_SHIFT 0 +#define ADC_SMPR_SMP (7 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_001DOT5 (0 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_007DOT5 (1 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_013DOT5 (2 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_028DOT5 (3 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_041DOT5 (4 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_055DOT5 (5 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_071DOT5 (6 << ADC_SMPR_SMP_SHIFT) +#define ADC_SMPR_SMP_239DOT5 (7 << ADC_SMPR_SMP_SHIFT) + + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/** @defgroup adc_api_res ADC resolutions + * @ingroup adc_defines + * + *@{*/ +#define ADC_RESOLUTION_12BIT ADC_CFGR1_RES_12_BIT +#define ADC_RESOLUTION_10BIT ADC_CFGR1_RES_10_BIT +#define ADC_RESOLUTION_8BIT ADC_CFGR1_RES_8_BIT +#define ADC_RESOLUTION_6BIT ADC_CFGR1_RES_6_BIT +/**@}*/ + +/** @defgroup adc_api_smptime ADC sampling time + * @ingroup adc_defines + * + *@{*/ +#define ADC_SMPTIME_001DOT5 ADC_SMPR_SMP_001DOT5 +#define ADC_SMPTIME_007DOT5 ADC_SMPR_SMP_007DOT5 +#define ADC_SMPTIME_013DOT5 ADC_SMPR_SMP_013DOT5 +#define ADC_SMPTIME_028DOT5 ADC_SMPR_SMP_028DOT5 +#define ADC_SMPTIME_041DOT5 ADC_SMPR_SMP_041DOT5 +#define ADC_SMPTIME_055DOT5 ADC_SMPR_SMP_055DOT5 +#define ADC_SMPTIME_071DOT5 ADC_SMPR_SMP_071DOT5 +#define ADC_SMPTIME_239DOT5 ADC_SMPR_SMP_239DOT5 +/**@}*/ + +/** @defgroup adc_api_clksource ADC clock source + * @ingroup adc_defines + * + *@{*/ +#define ADC_CLKSOURCE_ADC ADC_CFGR2_CKMODE_CK_ADC +#define ADC_CLKSOURCE_PCLK_DIV2 ADC_CFGR2_CKMODE_PCLK_DIV2 +#define ADC_CLKSOURCE_PCLK_DIV4 ADC_CFGR2_CKMODE_PCLK_DIV4 +/**@}*/ + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_TEMP 16 +#define ADC_CHANNEL_VREF 17 +#define ADC_CHANNEL_VBAT 18 +/**@}*/ + +/** @defgroup adc_api_opmode ADC Operation Modes + * @ingroup adc_defines + * + *@{*/ +enum adc_opmode { + ADC_MODE_SEQUENTIAL, + ADC_MODE_SCAN, + ADC_MODE_SCAN_INFINITE, +}; +/**@}*/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + + +BEGIN_DECLS + +/* Operation mode API */ +void adc_enable_discontinuous_mode(uint32_t adc); +void adc_disable_discontinuous_mode(uint32_t adc); +void adc_set_operation_mode(uint32_t adc, enum adc_opmode opmode); + +/* Trigger API */ +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity); +void adc_disable_external_trigger_regular(uint32_t adc); + +/* Interrupt configuration */ +void adc_enable_watchdog_interrupt(uint32_t adc); +void adc_disable_watchdog_interrupt(uint32_t adc); +bool adc_get_watchdog_flag(uint32_t adc); +void adc_clear_watchdog_flag(uint32_t adc); +void adc_enable_eoc_sequence_interrupt(uint32_t adc); +void adc_disable_eoc_sequence_interrupt(uint32_t adc); +bool adc_get_eoc_sequence_flag(uint32_t adc); + +/* Basic configuration */ +void adc_set_clk_source(uint32_t adc, uint32_t source); +void adc_enable_vbat_sensor(void); +void adc_disable_vbat_sensor(void); +void adc_calibrate_start(uint32_t adc) + LIBOPENCM3_DEPRECATED("see adc_calibrate/_async"); +void adc_calibrate_wait_finish(uint32_t adc) + LIBOPENCM3_DEPRECATED("see adc_is_calibrating"); + +/* Analog Watchdog */ +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc); +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, uint8_t chan); +void adc_disable_analog_watchdog(uint32_t adc); +void adc_set_watchdog_high_threshold(uint32_t adc, uint8_t threshold); +void adc_set_watchdog_low_threshold(uint32_t adc, uint8_t threshold); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/cec.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/cec.h new file mode 100644 index 00000000..2193a97e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/cec.h @@ -0,0 +1,125 @@ +/** @defgroup CEC_defines CEC Defines + * + * @brief Defined Constants and Types for the STM32F0xx HDMI-CEC + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CEC_H +#define LIBOPENCM3_CEC_H +/**@{*/ + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define CEC CEC_BASE + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define CEC_CR MMIO32(CEC_BASE + 0x00) +#define CEC_CFGR MMIO32(CEC_BASE + 0x04) +#define CEC_TXDR MMIO32(CEC_BASE + 0x08) +#define CEC_RXDR MMIO32(CEC_BASE + 0x0c) +#define CEC_ISR MMIO32(CEC_BASE + 0x10) +#define CEC_IER MMIO32(CEC_BASE + 0x14) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* CEC_CR Values ------------------------------------------------------------*/ + +#define CEC_CR_TXEOM (1 << 2) +#define CEC_CR_TXSOM (1 << 1) +#define CEC_CR_CECEN (1 << 0) + +/* CEC_CFGR Values ----------------------------------------------------------*/ + +#define CEC_CFGR_LSTN (1 << 31) + +#define CEC_CFGR_OAR_SHIFT 16 +#define CEC_CFGR_OAR (0x3FFF << CEC_CFGR_OAR_SHIFT) + +#define CEC_CFGR_SFTOPT (1 << 8) +#define CEC_CFGR_BRDNOGEN (1 << 7) +#define CEC_CFGR_LBPEGEN (1 << 6) +#define CEC_CFGR_BREGEN (1 << 5) +#define CEC_CFGR_BRESTP (1 << 4) +#define CEC_CFGR_RXTOL (1 << 3) + +#define CEC_CFGR_SFT_SHIFT 0 +#define CEC_CFGR_SFT (7 >> CEC_CFGR_SFT_SHIFT) + +/* CEC_ISR Values -----------------------------------------------------------*/ + +#define CEC_ISR_TXACKE (1 << 12) +#define CEC_ISR_TXERR (1 << 11) +#define CEC_ISR_TXUDR (1 << 10) +#define CEC_ISR_TXEND (1 << 9) +#define CEC_ISR_TXBR (1 << 8) +#define CEC_ISR_ARBLST (1 << 7) +#define CEC_ISR_RXACKE (1 << 6) +#define CEC_ISR_LBPE (1 << 5) +#define CEC_ISR_SBPE (1 << 4) +#define CEC_ISR_BRE (1 << 3) +#define CEC_ISR_RXOVR (1 << 2) +#define CEC_ISR_RXEND (1 << 1) +#define CEC_ISR_RXBR (1 << 0) + +/* CEC_IER Values -----------------------------------------------------------*/ + +#define CEC_IER_TXACKIE (1 << 12) +#define CEC_IER_TXERRIE (1 << 11) +#define CEC_IER_TXUDRIE (1 << 10) +#define CEC_IER_TXENDIE (1 << 9) +#define CEC_IER_TXBRIE (1 << 8) +#define CEC_IER_ARBLSTIE (1 << 7) +#define CEC_IER_RXACKIE (1 << 6) +#define CEC_IER_LBPEIE (1 << 5) +#define CEC_IER_SBPEIE (1 << 4) +#define CEC_IER_BREIE (1 << 3) +#define CEC_IER_RXOVRIE (1 << 2) +#define CEC_IER_RXENDIE (1 << 1) +#define CEC_IER_RXBRIE (1 << 0) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/comparator.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/comparator.h new file mode 100644 index 00000000..78db9cf9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/comparator.h @@ -0,0 +1,124 @@ +/** @defgroup comp_defines COMP Defines + * + * @brief libopencm3 Defined Constants and Types for the STM32F0xx + * Comparator module + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 29 Jun 2013 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_COMP_H +#define LIBOPENCM3_COMP_H +/**@{*/ + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define COMP1 0 +#define COMP2 1 + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define COMP_CSR(i) MMIO16(SYSCFG_COMP_BASE + 0x1c + (i)*2) +#define COMP_CSR1 COMP_CSR(COMP1) +#define COMP_CSR2 COMP_CSR(COMP2) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* COMP_CSR Values ----------------------------------------------------------*/ + +#define COMP_CSR_LOCK (1 << 15) +#define COMP_CSR_OUT (1 << 14) + +#define COMP_CSR_HYST_SHIFT 12 +#define COMP_CSR_HYST (3 << COMP_CSR_HYST_SHIFT) +#define COMP_CSR_HYST_NO (0 << COMP_CSR_HYST_SHIFT) +#define COMP_CSR_HYST_LOW (1 << COMP_CSR_HYST_SHIFT) +#define COMP_CSR_HYST_MED (2 << COMP_CSR_HYST_SHIFT) +#define COMP_CSR_HYST_HIGH (3 << COMP_CSR_HYST_SHIFT) + +#define COMP_CSR_POL (1 << 11) + +#define COMP_CSR_OUTSEL_SHIFT 8 +#define COMP_CSR_OUTSEL (7 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_NONE (0 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_TIM1_BRK (1 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_TIM1_IC1 (2 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_TIM1_OCRCLR (3 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_TIM2_IC4 (4 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_TIM2_OCRCLR (5 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_TIM3_IC1 (6 << COMP_CSR_OUTSEL_SHIFT) +#define COMP_CSR_OUTSEL_TIM3_OCRCLR (7 << COMP_CSR_OUTSEL_SHIFT) + +#define COMP_CSR_WINDWEN (1 << 23) + +#define COMP_CSR_INSEL_SHIFT 4 +#define COMP_CSR_INSEL (7 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_1_4_VREFINT (0 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_2_4_VREFINT (1 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_3_4_VREFINT (2 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_4_4_VREFINT (3 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_VREFINT (3 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_INM4 (4 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_INM5 (5 << COMP_CSR_INSEL_SHIFT) +#define COMP_CSR_INSEL_INM6 (6 << COMP_CSR_INSEL_SHIFT) + +#define COMP_CSR_SPEED_SHIFT 2 +#define COMP_CSR_SPEED (3 << COMP_CSR_SPEED_SHIFT) +#define COMP_CSR_SPEED_HIGH (0 << COMP_CSR_SPEED_SHIFT) +#define COMP_CSR_SPEED_MED (1 << COMP_CSR_SPEED_SHIFT) +#define COMP_CSR_SPEED_LOW (2 << COMP_CSR_SPEED_SHIFT) +#define COMP_CSR_SPEED_VERYLOW (3 << COMP_CSR_SPEED_SHIFT) + +#define COMP_CSR_SW1 (1 << 1) +#define COMP_CSR_EN (1 << 0) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +void comp_enable(uint8_t id); +void comp_disable(uint8_t id); +void comp_select_input(uint8_t id, uint32_t input); +void comp_select_output(uint8_t id, uint32_t output); +void comp_select_hyst(uint8_t id, uint32_t hyst); +void comp_select_speed(uint8_t id, uint32_t speed); + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/crc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/crc.h new file mode 100644 index 00000000..34d8a897 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/crc.h @@ -0,0 +1,89 @@ +/** @defgroup crc_defines CRC Defines + * + * @brief libopencm3 Defined Constants and Types for the STM32F1xx CRC + * Generator + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 29 Jun 2013 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H +/**@{*/ + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +/* Initial CRC Value */ +#define CRC_INIT MMIO32(CRC_BASE + 0x10) + +/* CRC Polynomial */ +#define CRC_POL MMIO32(CRC_BASE + 0x14) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +#define CRC_CR_REV_OUT (1 << 7) + +#define CRC_CR_REV_IN_SHIFT 5 +#define CRC_CR_REV_IN (3 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_NONE (0 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_BYTE (1 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_HALF (2 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_WORD (3 << CRC_CR_REV_IN_SHIFT) + +#define CRC_CR_POLYSIZE_SHIFT 3 +#define CRC_CR_POLYSIZE (3 << CRC_CR_POLYSIZE_SHIFT) +#define CRC_CR_POLYSIZE_32BIT (0 << CRC_CR_POLYSIZE_SHIFT) +#define CRC_CR_POLYSIZE_16BIT (1 << CRC_CR_POLYSIZE_SHIFT) +#define CRC_CR_POLYSIZE_8BIT (2 << CRC_CR_POLYSIZE_SHIFT) +#define CRC_CR_POLYSIZE_7BIT (3 << CRC_CR_POLYSIZE_SHIFT) + +/* Default polynomial */ +#define CRC_POL_DEFAULT 0x04C11DB7 + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dac.h new file mode 100644 index 00000000..7f544843 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dac.h @@ -0,0 +1,117 @@ +/** @defgroup dac_defines DAC Defines + * + * @brief Defined Constants and Types for the STM32F0xx Digital to Analog + * Converter + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC DAC_BASE + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define DAC_CR MMIO32(DAC_BASE + 0x00) +#define DAC_SWTRIGR MMIO32(DAC_BASE + 0x04) +#define DAC_DHR12R1 MMIO32(DAC_BASE + 0x08) +#define DAC_DHR12L1 MMIO32(DAC_BASE + 0x0C) +#define DAC_DHR8R1 MMIO32(DAC_BASE + 0x10) +#define DAC_DOR1 MMIO32(DAC_BASE + 0x2C) +#define DAC_SR MMIO32(DAC_BASE + 0x34) + + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* DAC_CR Values ------------------------------------------------------------*/ + +#define DAC_CR_DMAUDRIE1 (1 << 13) +#define DAC_CR_DMAEN1 (1 << 12) + +#define DAC_CR_TSEL1_SHIFT 3 +#define DAC_CR_TSEL1 (7 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_TIM6_TRGO (0 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_TIM8_TRGO (1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_TIM7_TRGO (2 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_TIM5_TRGO (3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_TIM2_TRGO (4 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_TIM4_TRGO (5 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_EXT_9 (6 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_SWTRG (7 << DAC_CR_TSEL1_SHIFT) + +#define DAC_CR_TEN1 (1 << 2) +#define DAC_CR_BOFF1 (1 << 1) +#define DAC_CR_EN1 (1 << 0) + +/* DAC_SWTRIGR Values -------------------------------------------------------*/ + +#define DAC_SWTRIGR_SWTRIG1 (1 << 0) + +/* DAC_DHR12R1 Values -------------------------------------------------------*/ + +#define DAC_DHR12R1_DACC1DHR 0xFFF + +/* DAC_DHR12L1 Values -------------------------------------------------------*/ + +#define DAC_DHR12L1_DACC1DHR (0xFFF << 4) + +/* DAC_DHR8R1 Values --------------------------------------------------------*/ + +#define DAC_DHR8R1_DACC1DHR 0xFF + +/* DAC_DOR1 Values ----------------------------------------------------------*/ + +#define DAC_DOR1_DACC1DOR 0xFFF + +/* DAC_SR Values ------------------------------------------------------------*/ + +#define DAC_SR_DMAUDR1 (1 << 13) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dma.h new file mode 100644 index 00000000..42b4687d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/dma.h @@ -0,0 +1,37 @@ +/** @defgroup dma_defines DMA Defines + * + * @ingroup STM32F0xx_defines + * + * @brief Defined Constants and Types for the STM32F0xx DMA Controller + * + * @version 1.0.0 + * + * @date 10 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/doc-stm32f0.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/doc-stm32f0.h new file mode 100644 index 00000000..fc26c508 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/doc-stm32f0.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32F0 + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * API documentation for ST Microelectronics STM32F0 Cortex M0 series. + * + * LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F0xx STM32F0xx + * Libraries for ST Microelectronics STM32F0xx series. + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/** @defgroup STM32F0xx_defines STM32F0xx Defines + * + * @brief Defined Constants and Types for the STM32F0xx series + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/exti.h new file mode 100644 index 00000000..3a99f5bb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/exti.h @@ -0,0 +1,40 @@ +/** @defgroup exti_defines EXTI Defines + * + * @brief Defined Constants and Types for the STM32F0xx External Interrupts + * + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EXTI_H +#define LIBOPENCM3_EXTI_H +/**@{*/ + +#include +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/flash.h new file mode 100644 index 00000000..e27acc6d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/flash.h @@ -0,0 +1,118 @@ +/** @defgroup flash_defines FLASH Defines + * + * @brief Defined Constants and Types for the STM32F0xx Flash memory + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H +/**@{*/ + +#include + +/* --- FLASH_OPTION values ------------------------------------------------- */ + +/** @defgroup flash_options Option Byte Addresses +@ingroup flash_defines +@{*/ +#define FLASH_OPTION_BYTE_0 FLASH_OPTION_BYTE(0) +#define FLASH_OPTION_BYTE_1 FLASH_OPTION_BYTE(1) +#define FLASH_OPTION_BYTE_2 FLASH_OPTION_BYTE(2) +#define FLASH_OPTION_BYTE_3 FLASH_OPTION_BYTE(3) +#define FLASH_OPTION_BYTE_4 FLASH_OPTION_BYTE(4) +#define FLASH_OPTION_BYTE_5 FLASH_OPTION_BYTE(5) +/**@}*/ + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +/** @defgroup flash_latency FLASH Wait States +@ingroup flash_defines +@{*/ +#define FLASH_ACR_LATENCY_000_024MHZ 0 +#define FLASH_ACR_LATENCY_024_048MHZ 1 +#define FLASH_ACR_LATENCY_0WS 0 +#define FLASH_ACR_LATENCY_1WS 1 +/**@}*/ + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_EOP (1 << 5) +#define FLASH_SR_WRPRTERR (1 << 4) +#define FLASH_SR_PGERR (1 << 2) +#define FLASH_SR_BSY (1 << 0) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +#define FLASH_CR_OBL_LAUNCH (1 << 13) + +/* --- FLASH_OBR values ---------------------------------------------------- */ + +#define FLASH_OBR_DATA1_SHIFT 24 +#define FLASH_OBR_DATA1 (0xFF << FLASH_OBR_DATA1_SHIFT) +#define FLASH_OBR_DATA0_SHIFT 16 +#define FLASH_OBR_DATA0 (0xFF << FLASH_OBR_DATA0_SHIFT) + +#define FLASH_OBR_BOOT_SEL (1 << 15) +#define FLASH_OBR_RAM_PARITY_CHECK (1 << 14) +#define FLASH_OBR_VDDA_MONITOR (1 << 13) +#define FLASH_OBR_NBOOT1 (1 << 12) +#define FLASH_OBR_NBOOT0 (1 << 11) +#define FLASH_OBR_NRST_STDBY (1 << 10) +#define FLASH_OBR_NRST_STOP (1 << 9) +#define FLASH_OBR_WDG_SW (1 << 8) +#define FLASH_OBR_RDPRT (3 << FLASH_OBR_RDPRT_SHIFT) +#define FLASH_OBR_RDPRT_L0 (0 << FLASH_OBR_RDPRT_SHIFT) +#define FLASH_OBR_RDPRT_L1 (1 << FLASH_OBR_RDPRT_SHIFT) +#define FLASH_OBR_RDPRT_L2 (3 << FLASH_OBR_RDPRT_SHIFT) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/* Read protection option byte protection level setting */ +#define FLASH_RDP_L0 ((uint8_t)0xaa) +#define FLASH_RDP_L1 ((uint8_t)0xf0) /* any value */ +#define FLASH_RDP_L2 ((uint8_t)0xcc) + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/gpio.h new file mode 100644 index 00000000..a5a22364 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/gpio.h @@ -0,0 +1,75 @@ +/** @defgroup gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the STM32F0xx General Purpose I/O + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 1 July 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define GPIO_BRR(port) MMIO32((port) + 0x28) +#define GPIOA_BRR GPIO_BRR(GPIOA) +#define GPIOB_BRR GPIO_BRR(GPIOB) +#define GPIOC_BRR GPIO_BRR(GPIOC) +#define GPIOD_BRR GPIO_BRR(GPIOD) +#define GPIOF_BRR GPIO_BRR(GPIOF) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/** @defgroup gpio_speed GPIO Output Pin Speed +@ingroup gpio_defines +@{*/ +#define GPIO_OSPEED_LOW 0x0 +#define GPIO_OSPEED_MED 0x1 +#define GPIO_OSPEED_HIGH 0x3 +/**@}*/ + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/i2c.h new file mode 100644 index 00000000..d105a2fc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/i2c.h @@ -0,0 +1,38 @@ +/** @defgroup i2c_defines I2C Defines + * + * @brief Defined Constants and Types for the STM32F0xx I2C + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/irq.json new file mode 100644 index 00000000..8a407dc2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/irq.json @@ -0,0 +1,39 @@ +{ + "irqs": [ + "wwdg", + "pvd", + "rtc", + "flash", + "rcc", + "exti0_1", + "exti2_3", + "exti4_15", + "tsc", + "dma1_channel1", + "dma1_channel2_3", + "dma1_channel4_5", + "adc_comp", + "tim1_brk_up_trg_com", + "tim1_cc", + "tim2", + "tim3", + "tim6_dac", + "tim7", + "tim14", + "tim15", + "tim16", + "tim17", + "i2c1", + "i2c2", + "spi1", + "spi2", + "usart1", + "usart2", + "usart3_4", + "cec_can", + "usb" + ], + "partname_humanreadable": "STM32 F0 series", + "partname_doxygen": "STM32F0", + "includeguard": "LIBOPENCM3_STM32_F0_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/iwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/iwdg.h new file mode 100644 index 00000000..be9dc5ab --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/iwdg.h @@ -0,0 +1,70 @@ +/** @defgroup iwdg_defines IWDG Defines + * + * @brief Defined Constants and Types for the STM32F0xx Independent Watchdog + * Timer + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_IWDG_H +#define LIBOPENCM3_IWDG_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +/* Key Register (IWDG_WINR) */ +#define IWDG_WINR MMIO32(IWDG_BASE + 0x10) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- IWDG_SR values ------------------------------------------------------ */ + +/* WVU: Watchdog counter window value update */ +#define IWDG_SR_WVU (1 << 2) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/memorymap.h new file mode 100644 index 00000000..ccb26ae8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/memorymap.h @@ -0,0 +1,116 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * .. based on file from F4. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32 specific peripheral definitions ------------------------------- */ + +/* Memory map for all buses */ +#define FLASH_BASE (0x08000000U) +#define PERIPH_BASE (0x40000000U) +#define INFO_BASE (0x1ffff000U) +#define PERIPH_BASE_APB (PERIPH_BASE + 0x00000000) +#define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x00020000) +#define PERIPH_BASE_AHB2 (PERIPH_BASE + 0x08000000) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB + 0x0400) + +#define TIM6_BASE (PERIPH_BASE_APB + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB + 0x1400) + +#define TIM14_BASE (PERIPH_BASE_APB + 0x2000) +/* PERIPH_BASE_APB1 + 0x2400 (0x4000 2400 - 0x4000 27FF): Reserved */ +#define RTC_BASE (PERIPH_BASE_APB + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB + 0x3000) +/* PERIPH_BASE_APB + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define SPI2_BASE (PERIPH_BASE_APB + 0x3800) +/* PERIPH_BASE_APB + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ +#define USART2_BASE (PERIPH_BASE_APB + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB + 0x4800) +#define USART4_BASE (PERIPH_BASE_APB + 0x4C00) + +#define I2C1_BASE (PERIPH_BASE_APB + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB + 0x5800) +#define USB_DEV_FS_BASE (PERIPH_BASE_APB + 0x5C00) +#define USB_PMA_BASE (PERIPH_BASE_APB + 0x6000) +#define BX_CAN1_BASE (PERIPH_BASE_APB + 0x6400) + +#define CRS_BASE (PERIPH_BASE_APB + 0x6C00) +#define POWER_CONTROL_BASE (PERIPH_BASE_APB + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB + 0x7400) +#define CEC_BASE (PERIPH_BASE_APB + 0x7800) + +#define SYSCFG_COMP_BASE (PERIPH_BASE_APB + 0x10000) +#define EXTI_BASE (PERIPH_BASE_APB + 0x10400) + +#define ADC_BASE (PERIPH_BASE_APB + 0x12400) +#define TIM1_BASE (PERIPH_BASE_APB + 0x12C00) +#define SPI1_BASE (PERIPH_BASE_APB + 0x13000) + +#define USART1_BASE (PERIPH_BASE_APB + 0x13800) +#define TIM15_BASE (PERIPH_BASE_APB + 0x14000) +#define TIM16_BASE (PERIPH_BASE_APB + 0x14400) +#define TIM17_BASE (PERIPH_BASE_APB + 0x14800) + +#define DBGMCU_BASE (PERIPH_BASE_APB + 0x15800) + +/* AHB1 */ +#define DMA_BASE (PERIPH_BASE_AHB1 + 0x0000) +/* DMA is the name in the F0 refman, but all other stm32's use DMA1 */ +#define DMA1_BASE DMA_BASE + +#define RCC_BASE (PERIPH_BASE_AHB1 + 0x1000) + +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x2000) + +#define CRC_BASE (PERIPH_BASE_AHB1 + 0x3000) + +#define TSC_BASE (PERIPH_BASE_AHB1 + 0x4000) + +/* AHB2 */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB2 + 0x0000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB2 + 0x0400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB2 + 0x0800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB2 + 0x0C00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB2 + 0x1000) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB2 + 0x1400) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (0x1FFFF7CCU) +#define DESIG_UNIQUE_ID_BASE (0x1FFFF7ACU) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 8) + +/* ST provided factory calibration values @ 3.3V */ +#define ST_VREFINT_CAL MMIO16(0x1FFFF7BA) +#define ST_TSENSE_CAL1_30C MMIO16(0x1FFFF7B8) +#define ST_TSENSE_CAL2_110C MMIO16(0x1FFFF7C2) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/pwr.h new file mode 100644 index 00000000..c01c7d38 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/pwr.h @@ -0,0 +1,67 @@ +/** @defgroup pwr_defines PWR Defines + * + * @brief Defined Constants and Types for the STM32F0xx PWR Control + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 5 December 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* EWUP: Enable WKUP2 pin */ +#define PWR_CSR_EWUP2 (1 << 9) + +/* EWUP: Enable WKUP1 pin */ +#define PWR_CSR_EWUP1 (1 << 8) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rcc.h new file mode 100644 index 00000000..bb1dd981 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rcc.h @@ -0,0 +1,539 @@ +/** @defgroup rcc_defines RCC Defines + * + * @brief Defined Constants and Types for the STM32F0xx Reset and Clock +Control + * + * @ingroup STM32F0xx_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @version 1.0.0 + * + * @date 29 Jun 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_CFGR MMIO32(RCC_BASE + 0x04) +#define RCC_CIR MMIO32(RCC_BASE + 0x08) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x0c) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x10) +#define RCC_AHBENR MMIO32(RCC_BASE + 0x14) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x18) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x1c) +#define RCC_BDCR MMIO32(RCC_BASE + 0x20) +#define RCC_CSR MMIO32(RCC_BASE + 0x24) +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x28) +#define RCC_CFGR2 MMIO32(RCC_BASE + 0x2c) +#define RCC_CFGR3 MMIO32(RCC_BASE + 0x30) +#define RCC_CR2 MMIO32(RCC_BASE + 0x34) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSICAL_SHIFT 8 +#define RCC_CR_HSICAL (0xFF << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSITRIM_SHIFT 3 +#define RCC_CR_HSITRIM (0x1F << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +#define RCC_CFGR_PLLNODIV (1 << 31) + +#define RCC_CFGR_MCOPRE_SHIFT 28 +#define RCC_CFGR_MCOPRE (7 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV1 (0 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV32 (5 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV64 (6 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV128 (7 << RCC_CFGR_MCOPRE_SHIFT) + +#define RCC_CFGR_MCO_SHIFT 24 +#define RCC_CFGR_MCO_MASK 0xf +#define RCC_CFGR_MCO_NOCLK 0 +#define RCC_CFGR_MCO_HSI14 1 +#define RCC_CFGR_MCO_LSI 2 +#define RCC_CFGR_MCO_LSE 3 +#define RCC_CFGR_MCO_SYSCLK 4 +#define RCC_CFGR_MCO_HSI 5 +#define RCC_CFGR_MCO_HSE 6 +#define RCC_CFGR_MCO_PLL 7 +#define RCC_CFGR_MCO_HSI48 8 + +#define RCC_CFGR_PLLMUL_SHIFT 18 +#define RCC_CFGR_PLLMUL (0x0F << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL2 (0x00 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL3 (0x01 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL4 (0x02 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL5 (0x03 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL6 (0x04 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL7 (0x05 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL8 (0x06 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL9 (0x07 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL10 (0x08 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL11 (0x09 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL12 (0x0A << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL13 (0x0B << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL14 (0x0C << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL15 (0x0D << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL16 (0x0E << RCC_CFGR_PLLMUL_SHIFT) + +#define RCC_CFGR_PLLXTPRE (1<<17) +#define RCC_CFGR_PLLXTPRE_HSE_CLK 0x0 +#define RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2 0x1 + +#define RCC_CFGR_PLLSRC (1<<16) +#define RCC_CFGR_PLLSRC_HSI_CLK_DIV2 0x0 +#define RCC_CFGR_PLLSRC_HSE_CLK 0x1 + +#define RCC_CFGR_PLLSRC0 (1<<15) +#define RCC_CFGR_ADCPRE (1<<14) + +#define RCC_CFGR_PPRE_SHIFT 8 +#define RCC_CFGR_PPRE (7 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_NODIV (0 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV2 (4 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV4 (5 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV8 (6 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV16 (7 << RCC_CFGR_PPRE_SHIFT) + +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE (0xf << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_NODIV (0x0 << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV2 (0x8 << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV4 (0x9 << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV8 (0xa << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV16 (0xb << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV64 (0xc << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV128 (0xd << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV256 (0xe << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV512 (0xf << RCC_CFGR_HPRE_SHIFT) + +#define RCC_CFGR_SWS_SHIFT 2 +#define RCC_CFGR_SWS (3 << RCC_CFGR_SWS_SHIFT) +#define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) +#define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) +#define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) +#define RCC_CFGR_SWS_HSI48 (3 << RCC_CFGR_SWS_SHIFT) + +#define RCC_CFGR_SW_SHIFT 0 +#define RCC_CFGR_SW (3 << RCC_CFGR_SW_SHIFT) +#define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) +#define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) +#define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) +#define RCC_CFGR_SW_HSI48 (3 << RCC_CFGR_SW_SHIFT) + +/* --- RCC_CIR values ------------------------------------------------------ */ + +#define RCC_CIR_CSSC (1 << 23) +#define RCC_CIR_HSI48RDYC (1 << 22) +#define RCC_CIR_HSI14RDYC (1 << 21) +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) +#define RCC_CIR_HSI48RDYIE (1 << 14) +#define RCC_CIR_HSI14RDYIE (1 << 13) +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) +#define RCC_CIR_CSSF (1 << 7) +#define RCC_CIR_HSI48RDYF (1 << 6) +#define RCC_CIR_HSI14RDYF (1 << 5) +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_DBGMCURST (1 << 22) +#define RCC_APB2RSTR_TIM17RST (1 << 18) +#define RCC_APB2RSTR_TIM16RST (1 << 17) +#define RCC_APB2RSTR_TIM15RST (1 << 16) +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_TIM1RST (1 << 11) +#define RCC_APB2RSTR_ADCRST (1 << 9) +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_CECRST (1 << 30) +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_CRSRST (1 << 27) +#define RCC_APB1RSTR_CANRST (1 << 25) +#define RCC_APB1RSTR_USBRST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_USART4RST (1 << 19) +#define RCC_APB1RSTR_USART3RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_TIM14RST (1 << 8) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_AHBENR values --------------------------------------------------- */ + +#define RCC_AHBENR_TSCEN (1 << 24) +#define RCC_AHBENR_GPIOFEN (1 << 22) +#define RCC_AHBENR_GPIOEEN (1 << 21) +#define RCC_AHBENR_GPIODEN (1 << 20) +#define RCC_AHBENR_GPIOCEN (1 << 19) +#define RCC_AHBENR_GPIOBEN (1 << 18) +#define RCC_AHBENR_GPIOAEN (1 << 17) +#define RCC_AHBENR_CRCEN (1 << 6) +#define RCC_AHBENR_FLTFEN (1 << 4) +#define RCC_AHBENR_SRAMEN (1 << 2) +#define RCC_AHBENR_DMAEN (1 << 0) + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +#define RCC_APB2ENR_DBGMCUEN (1 << 22) +#define RCC_APB2ENR_TIM17EN (1 << 18) +#define RCC_APB2ENR_TIM16EN (1 << 17) +#define RCC_APB2ENR_TIM15EN (1 << 16) +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_TIM1EN (1 << 11) +#define RCC_APB2ENR_ADCEN (1 << 9) +#define RCC_APB2ENR_SYSCFGCOMPEN (1 << 0) + +/* --- RCC_APB1ENR values -------------------------------------------------- */ + +#define RCC_APB1ENR_CECEN (1 << 30) +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_CRSEN (1 << 27) +#define RCC_APB1ENR_CANEN (1 << 25) +#define RCC_APB1ENR_USBEN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_USART4EN (1 << 19) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_TIM14EN (1 << 8) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) + +/* --- RCC_BDCR values ----------------------------------------------------- */ + +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) +#define RCC_BDCR_RTCSEL_SHIFT 8 +#define RCC_BDCR_RTCSEL (3 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_LSEDRV_SHIFT 3 +#define RCC_BDCR_LSEDRV (3 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_LOW (0 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_MEDLO (1 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_MEDHI (2 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_HIGH (3 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_OBLRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\ + RCC_CSR_PINRSTF | RCC_CSR_OBLRSTF) +#define RCC_CSR_V18PWRRSTF (1 << 23) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- RCC_AHBRSTR values -------------------------------------------------- */ + +#define RCC_AHBRSTR_TSCRST (1 << 24) +#define RCC_AHBRSTR_IOPFRST (1 << 22) +#define RCC_AHBRSTR_IOPERST (1 << 21) +#define RCC_AHBRSTR_IOPDRST (1 << 20) +#define RCC_AHBRSTR_IOPCRST (1 << 19) +#define RCC_AHBRSTR_IOPBRST (1 << 18) +#define RCC_AHBRSTR_IOPARST (1 << 17) + + +/* --- RCC_CFGR2 values ---------------------------------------------------- */ + +#define RCC_CFGR2_PREDIV 0xf +/** @defgroup rcc_cfgr2_prediv PLL source predividers +@ingroup rcc_defines +@{*/ +#define RCC_CFGR2_PREDIV_NODIV 0x0 +#define RCC_CFGR2_PREDIV_DIV2 0x1 +#define RCC_CFGR2_PREDIV_DIV3 0x2 +#define RCC_CFGR2_PREDIV_DIV4 0x3 +#define RCC_CFGR2_PREDIV_DIV5 0x4 +#define RCC_CFGR2_PREDIV_DIV6 0x5 +#define RCC_CFGR2_PREDIV_DIV7 0x6 +#define RCC_CFGR2_PREDIV_DIV8 0x7 +#define RCC_CFGR2_PREDIV_DIV9 0x8 +#define RCC_CFGR2_PREDIV_DIV10 0x9 +#define RCC_CFGR2_PREDIV_DIV11 0xa +#define RCC_CFGR2_PREDIV_DIV12 0xb +#define RCC_CFGR2_PREDIV_DIV13 0xc +#define RCC_CFGR2_PREDIV_DIV14 0xd +#define RCC_CFGR2_PREDIV_DIV15 0xe +#define RCC_CFGR2_PREDIV_DIV16 0xf +/**@}*/ + +/* --- RCC_CFGR3 values ---------------------------------------------------- */ + +#define RCC_CFGR3_USART2SW_SHIFT 16 +#define RCC_CFGR3_USART2SW (3 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART2SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART2SW_SYSCLK (1 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART2SW_LSE (2 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART2SW_HSI (3 << RCC_CFGR3_USART2SW_SHIFT) + +#define RCC_CFGR3_ADCSW (1 << 8) +#define RCC_CFGR3_USBSW (1 << 7) +#define RCC_CFGR3_CECSW (1 << 6) +#define RCC_CFGR3_I2C1SW (1 << 4) + +#define RCC_CFGR3_USART1SW_SHIFT 0 +#define RCC_CFGR3_USART1SW (3 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_PCLK (0 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_SYSCLK (1 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_LSE (2 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_HSI (3 << RCC_CFGR3_USART1SW_SHIFT) + +/* --- RCC_CFGR3 values ---------------------------------------------------- */ + +#define RCC_CR2_HSI48CAL_SHIFT 24 +#define RCC_CR2_HSI48CAL (0xFF << RCC_CR2_HSI48CAL_SHIFT) +#define RCC_CR2_HSI48RDY (1 << 17) +#define RCC_CR2_HSI48ON (1 << 16) +#define RCC_CR2_HSI14CAL_SHIFT 8 +#define RCC_CR2_HSI14CAL (0xFF << RCC_CR2_HSI14CAL_SHIFT) +#define RCC_CR2_HSI14TRIM_SHIFT 3 +#define RCC_CR2_HSI14TRIM (31 << RCC_CR2_HSI14TRIM_SHIFT) +#define RCC_CR2_HSI14DIS (1 << 2) +#define RCC_CR2_HSI14RDY (1 << 1) +#define RCC_CR2_HSI14ON (1 << 0) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; + +enum rcc_osc { + RCC_HSI14, RCC_HSI, RCC_HSE, RCC_PLL, RCC_LSI, RCC_LSE, RCC_HSI48 +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + /* AHB peripherals */ + RCC_DMA = _REG_BIT(0x14, 0), + RCC_SRAM = _REG_BIT(0x14, 2), + RCC_FLTIF = _REG_BIT(0x14, 4), + RCC_CRC = _REG_BIT(0x14, 6), + RCC_GPIOA = _REG_BIT(0x14, 17), + RCC_GPIOB = _REG_BIT(0x14, 18), + RCC_GPIOC = _REG_BIT(0x14, 19), + RCC_GPIOD = _REG_BIT(0x14, 20), + RCC_GPIOE = _REG_BIT(0x14, 21), + RCC_GPIOF = _REG_BIT(0x14, 22), + RCC_TSC = _REG_BIT(0x14, 24), + + /* APB2 peripherals */ + RCC_SYSCFG_COMP = _REG_BIT(0x18, 0), + RCC_ADC = _REG_BIT(0x18, 9), + RCC_ADC1 = _REG_BIT(0x18, 9), /* Compatibility alias */ + RCC_TIM1 = _REG_BIT(0x18, 11), + RCC_SPI1 = _REG_BIT(0x18, 12), + RCC_USART1 = _REG_BIT(0x18, 14), + RCC_TIM15 = _REG_BIT(0x18, 16), + RCC_TIM16 = _REG_BIT(0x18, 17), + RCC_TIM17 = _REG_BIT(0x18, 18), + RCC_DBGMCU = _REG_BIT(0x18, 22), + + /* APB1 peripherals */ + RCC_TIM2 = _REG_BIT(0x1C, 0), + RCC_TIM3 = _REG_BIT(0x1C, 1), + RCC_TIM6 = _REG_BIT(0x1C, 4), + RCC_TIM7 = _REG_BIT(0x1C, 5), + RCC_TIM14 = _REG_BIT(0x1C, 8), + RCC_WWDG = _REG_BIT(0x1C, 11), + RCC_SPI2 = _REG_BIT(0x1C, 14), + RCC_USART2 = _REG_BIT(0x1C, 17), + RCC_USART3 = _REG_BIT(0x1C, 18), + RCC_USART4 = _REG_BIT(0x1C, 19), + RCC_I2C1 = _REG_BIT(0x1C, 21), + RCC_I2C2 = _REG_BIT(0x1C, 22), + RCC_USB = _REG_BIT(0x1C, 23), + RCC_CAN = _REG_BIT(0x1C, 25), + RCC_CAN1 = _REG_BIT(0x1C, 25), /* Compatibility alias */ + RCC_CRS = _REG_BIT(0x1C, 27), + RCC_PWR = _REG_BIT(0x1C, 28), + RCC_DAC = _REG_BIT(0x1C, 29), + RCC_DAC1 = _REG_BIT(0x1C, 29), /* Compatibility alias */ + RCC_CEC = _REG_BIT(0x1C, 30), + + /* Advanced peripherals */ + RCC_RTC = _REG_BIT(0x20, 15),/* BDCR[15] */ +}; + +enum rcc_periph_rst { + /* APB2 peripherals */ + RST_SYSCFG = _REG_BIT(0x0C, 0), + RST_ADC = _REG_BIT(0x0C, 9), + RST_ADC1 = _REG_BIT(0x0C, 9), /* Compatibility alias */ + RST_TIM1 = _REG_BIT(0x0C, 11), + RST_SPI1 = _REG_BIT(0x0C, 12), + RST_USART1 = _REG_BIT(0x0C, 14), + RST_TIM15 = _REG_BIT(0x0C, 16), + RST_TIM16 = _REG_BIT(0x0C, 17), + RST_TIM17 = _REG_BIT(0x0C, 18), + RST_DBGMCU = _REG_BIT(0x0C, 22), + + /* APB1 peripherals */ + RST_TIM2 = _REG_BIT(0x10, 0), + RST_TIM3 = _REG_BIT(0x10, 1), + RST_TIM6 = _REG_BIT(0x10, 4), + RST_TIM7 = _REG_BIT(0x10, 5), + RST_TIM14 = _REG_BIT(0x10, 8), + RST_WWDG = _REG_BIT(0x10, 11), + RST_SPI2 = _REG_BIT(0x10, 14), + RST_USART2 = _REG_BIT(0x10, 17), + RST_USART3 = _REG_BIT(0x10, 18), + RST_USART4 = _REG_BIT(0x10, 19), + RST_I2C1 = _REG_BIT(0x10, 21), + RST_I2C2 = _REG_BIT(0x10, 22), + RST_USB = _REG_BIT(0x10, 23), + RST_CAN = _REG_BIT(0x10, 25), + RST_CAN1 = _REG_BIT(0x10, 25), /* Compatibility alias */ + RST_CRS = _REG_BIT(0x10, 27), + RST_PWR = _REG_BIT(0x10, 28), + RST_DAC = _REG_BIT(0x10, 29), + RST_DAC1 = _REG_BIT(0x10, 29), /* Compatibility alias */ + RST_CEC = _REG_BIT(0x10, 30), + + /* Advanced peripherals */ + RST_BACKUPDOMAIN = _REG_BIT(0x20, 16),/* BDCR[16] */ + + /* AHB peripherals */ + RST_GPIOA = _REG_BIT(0x28, 17), + RST_GPIOB = _REG_BIT(0x28, 18), + RST_GPIOC = _REG_BIT(0x28, 19), + RST_GPIOD = _REG_BIT(0x28, 20), + RST_GPIOE = _REG_BIT(0x28, 21), + RST_GPIOF = _REG_BIT(0x28, 22), + RST_TSC = _REG_BIT(0x28, 24), +}; +#undef _REG_BIT + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +#include + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_set_sysclk_source(enum rcc_osc clk); +void rcc_set_usbclk_source(enum rcc_osc clk); +void rcc_set_rtc_clock_source(enum rcc_osc clk); +void rcc_enable_rtc_clock(void); +void rcc_disable_rtc_clock(void); +void rcc_set_pll_multiplication_factor(uint32_t mul); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_pllxtpre(uint32_t pllxtpre); +void rcc_set_ppre(uint32_t ppre); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_prediv(uint32_t prediv); +enum rcc_osc rcc_system_clock_source(void); +enum rcc_osc rcc_usb_clock_source(void); +void rcc_clock_setup_in_hse_8mhz_out_48mhz(void); +void rcc_clock_setup_in_hsi_out_48mhz(void); +void rcc_clock_setup_in_hsi48_out_48mhz(void); + +END_DECLS + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rtc.h new file mode 100644 index 00000000..8a99c241 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/rtc.h @@ -0,0 +1,36 @@ +/** @defgroup rtc_defines RTC Defines + * + * @brief Defined Constants and Types for the STM32F0xx RTC + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 5 December 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/spi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/spi.h new file mode 100644 index 00000000..773743eb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/spi.h @@ -0,0 +1,36 @@ +/** @defgroup spi_defines SPI Defines + * + * @brief Defined Constants and Types for the STM32F0xx SPI + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SPI_H +#define LIBOPENCM3_SPI_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/st_usbfs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/st_usbfs.h new file mode 100644 index 00000000..7b65d2b8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/st_usbfs.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +# error Do not include directly ! +#else + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/syscfg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/syscfg.h new file mode 100644 index 00000000..7e796a05 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/syscfg.h @@ -0,0 +1,121 @@ +/** @defgroup syscfg_defines SYSCFG Defines + * + * @brief Defined Constants and Types for the STM32F0xx System Config + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SYSCFG_H +#define LIBOPENCM3_SYSCFG_H +/**@{*/ + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define SYSCFG_CFGR1 MMIO32(SYSCFG_COMP_BASE + 0x00) +#define SYSCFG_EXTICR(i) MMIO32(SYSCFG_COMP_BASE + 0x08 + (i)*4) +#define SYSCFG_EXTICR1 SYSCFG_EXTICR(0) +#define SYSCFG_EXTICR2 SYSCFG_EXTICR(1) +#define SYSCFG_EXTICR3 SYSCFG_EXTICR(2) +#define SYSCFG_EXTICR4 SYSCFG_EXTICR(3) +#define SYSCFG_CFGR2 MMIO32(SYSCFG_COMP_BASE + 0x18) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* SYSCFG_CFGR1 Values -- ---------------------------------------------------*/ + +#define SYSCFG_CFGR1_MEM_MODE_SHIFT 0 +#define SYSCFG_CFGR1_MEM_MODE (3 << SYSCFG_CFGR1_MEM_MODE_SHIFT) +#define SYSCFG_CFGR1_MEM_MODE_FLASH (0 << SYSCFG_CFGR1_MEM_MODE_SHIFT) +#define SYSCFG_CFGR1_MEM_MODE_SYSTEM (1 << SYSCFG_CFGR1_MEM_MODE_SHIFT) +#define SYSCFG_CFGR1_MEM_MODE_SRAM (3 << SYSCFG_CFGR1_MEM_MODE_SHIFT) + +#define SYSCFG_CFGR1_PA11_PA12_RMP (1 << 4) +#define SYSCFG_CFGR1_ADC_DMA_RMP (1 << 8) +#define SYSCFG_CFGR1_USART1_TX_DMA_RMP (1 << 9) +#define SYSCFG_CFGR1_USART1_RX_DMA_RMP (1 << 10) +#define SYSCFG_CFGR1_TIM16_DMA_RMP (1 << 11) +#define SYSCFG_CFGR1_TIM17_DMA_RMP (1 << 12) +#define SYSCFG_CFGR1_TIM16_DMA_RMP2 (1 << 13) +#define SYSCFG_CFGR1_TIM17_DMA_RMP2 (1 << 14) + +#define SYSCFG_CFGR1_I2C_PB6_FMP (1 << 16) +#define SYSCFG_CFGR1_I2C_PB7_FMP (1 << 17) +#define SYSCFG_CFGR1_I2C_PB8_FMP (1 << 18) +#define SYSCFG_CFGR1_I2C_PB9_FMP (1 << 19) +#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) +#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) +#define SYSCFG_CFGR1_I2C_PA9_FMP (1 << 22) +#define SYSCFG_CFGR1_I2C_PA10_FMP (1 << 23) +#define SYSCFG_CFGR1_SPI2_DMA_RMP (1 << 24) +#define SYSCFG_CFGR1_USART2_DMA_RMP (1 << 25) +#define SYSCFG_CFGR1_USART3_DMA_RMP (1 << 26) +#define SYSCFG_CFGR1_I2C1_DMA_RMP (1 << 27) +#define SYSCFG_CFGR1_TIM1_DMA_RMP (1 << 28) +#define SYSCFG_CFGR1_TIM2_DMA_RMP (1 << 29) +#define SYSCFG_CFGR1_TIM3_DMA_RMP (1 << 30) + +/* SYSCFG_EXTICR Values -- --------------------------------------------------*/ + +#define SYSCFG_EXTICR_SKIP 4 +#define SYSCFG_EXTICR_GPIOA 0 +#define SYSCFG_EXTICR_GPIOB 1 +#define SYSCFG_EXTICR_GPIOC 2 +#define SYSCFG_EXTICR_GPIOD 3 +#define SYSCFG_EXTICR_GPIOF 5 + +/* SYSCFG_CFGR2 Values -- ---------------------------------------------------*/ + +#define SYSCFG_CFGR2_LOCKUP_LOCK (1 << 0) +#define SYSCFG_CFGR2_SRAM_PARITY_LOCK (1 << 1) +#define SYSCFG_CFGR2_PVD_LOCK (1 << 2) +#define SYSCFG_CFGR2_SRAM_PEF (1 << 8) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/timer.h new file mode 100644 index 00000000..5f59816c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/timer.h @@ -0,0 +1,37 @@ +/** @defgroup timer_defines Timers Defines + * + * @brief Defined Constants and Types for the STM32F0xx Timers + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/tsc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/tsc.h new file mode 100644 index 00000000..989451f4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/tsc.h @@ -0,0 +1,159 @@ +/** @defgroup tsc_defines TSC Defines + * + * @brief Defined Constants and Types for the STM32F0xx Touch Sensor + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TSC_H +#define LIBOPENCM3_TSC_H +/**@{*/ + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define TSC TSC_BASE + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define TSC_CR MMIO32(TSC_BASE + 0x00) +#define TSC_IER MMIO32(TSC_BASE + 0x04) +#define TSC_ICR MMIO32(TSC_BASE + 0x08) +#define TSC_ISR MMIO32(TSC_BASE + 0x0c) +#define TSC_IOHCR MMIO32(TSC_BASE + 0x10) +#define TSC_IOASCR MMIO32(TSC_BASE + 0x18) +#define TSC_IOSCR MMIO32(TSC_BASE + 0x20) +#define TSC_IOCCR MMIO32(TSC_BASE + 0x28) +#define TSC_IOGCSR MMIO32(TSC_BASE + 0x30) +#define TSC_IOGxCR(x) MMIO32(TSC_BASE + 0x34 + ((x)-1)*4) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* TSC_CR Values ------------------------------------------------------------*/ + +#define TSC_CR_CTPH_SHIFT 28 +#define TSC_CR_CTPH (0xF << TSC_CR_CTPH_SHIFT) + +#define TSC_CR_CTPL_SHIFT 24 +#define TSC_CR_CTPL (0x0F << TSC_CR_CTPL_SHIFT) + +#define TSC_CR_SSD_SHIFT 17 +#define TSC_CR_SSD (0x7F << TSC_CR_SSD_SHIFT) + +#define TSC_CR_SSE (1 << 16) +#define TSC_CR_SSPSC (1 << 15) + +#define TSC_CR_PGPSC_SHIFT 12 +#define TSC_CR_PGPSC (7 << TSC_CR_PGPSC_SHIFT) + +#define TSC_CR_MCV_SHIFT 5 +#define TSC_CR_MCV (7 << TSC_CR_MCV_SHIFT) + +#define TSC_CR_IODEF (1 << 4) +#define TSC_CR_SYNCPOL (1 << 3) +#define TSC_CR_AM (1 << 2) +#define TSC_CR_START (1 << 1) +#define TSC_CR_TSCE (1 << 0) + +/* TSC_IER Values -----------------------------------------------------------*/ + +#define TSC_IER_MCEIE (1 << 1) +#define TSC_IER_EOAIE (1 << 0) + +/* TSC_ICR Values -----------------------------------------------------------*/ + +#define TSC_ICR_MCEIC (1 << 1) +#define TSC_ICR_EOAIC (1 << 0) + +/* TSC_ISR Values -----------------------------------------------------------*/ + +#define TSC_ISR_MCEF (1 << 1) +#define TSC_ISR_EOAF (1 << 0) + +/* TSC_IOHCR Values ---------------------------------------------------------*/ + +/* Bit helper g = [1..6] io = [1..4] */ +#define TSC_IOBIT_VAL(g, io) ((1 << ((io)-1)) << (((g)-1)*4)) + +#define TSC_IOHCR_G1(io) TSC_IOBIT_VAL(1, io) +#define TSC_IOHCR_G2(io) TSC_IOBIT_VAL(2, io) +#define TSC_IOHCR_G3(io) TSC_IOBIT_VAL(3, io) +#define TSC_IOHCR_G4(io) TSC_IOBIT_VAL(4, io) +#define TSC_IOHCR_G5(io) TSC_IOBIT_VAL(5, io) +#define TSC_IOHCR_G6(io) TSC_IOBIT_VAL(6, io) + +/* TSC_IOASCR Values --------------------------------------------------------*/ + +#define TSC_IOASCR_G1(io) TSC_IOBIT_VAL(1, io) +#define TSC_IOASCR_G2(io) TSC_IOBIT_VAL(2, io) +#define TSC_IOASCR_G3(io) TSC_IOBIT_VAL(3, io) +#define TSC_IOASCR_G4(io) TSC_IOBIT_VAL(4, io) +#define TSC_IOASCR_G5(io) TSC_IOBIT_VAL(5, io) +#define TSC_IOASCR_G6(io) TSC_IOBIT_VAL(6, io) + +/* TSC_IOSCR Values ---------------------------------------------------------*/ + +#define TSC_IOSCR_G1(io) TSC_IOBIT_VAL(1, io) +#define TSC_IOSCR_G2(io) TSC_IOBIT_VAL(2, io) +#define TSC_IOSCR_G3(io) TSC_IOBIT_VAL(3, io) +#define TSC_IOSCR_G4(io) TSC_IOBIT_VAL(4, io) +#define TSC_IOSCR_G5(io) TSC_IOBIT_VAL(5, io) +#define TSC_IOSCR_G6(io) TSC_IOBIT_VAL(6, io) + +/* TSC_IOCCR Values ---------------------------------------------------------*/ + +#define TSC_IOCCR_G1(io) TSC_IOBIT_VAL(1, io) +#define TSC_IOCCR_G2(io) TSC_IOBIT_VAL(2, io) +#define TSC_IOCCR_G3(io) TSC_IOBIT_VAL(3, io) +#define TSC_IOCCR_G4(io) TSC_IOBIT_VAL(4, io) +#define TSC_IOCCR_G5(io) TSC_IOBIT_VAL(5, io) +#define TSC_IOCCR_G6(io) TSC_IOBIT_VAL(6, io) + +/* TSC_IOGCSR Values --------------------------------------------------------*/ + +#define TSC_IOGCSR_GxE(x) (1 << ((x)-1)) +#define TSC_IOGCSR_GxS(x) (1 << ((x)+15)) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/usart.h new file mode 100644 index 00000000..4ddefc14 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f0/usart.h @@ -0,0 +1,333 @@ +/** @defgroup usart_defines USART Defines + * + * @brief Defined Constants and Types for the STM32F0xx USART + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 2 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_USART_H +#define LIBOPENCM3_USART_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define USART1 USART1_BASE +#define USART2 USART2_BASE +#define USART3 USART3_BASE +#define USART4 USART4_BASE + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define USART_CR1(usart_base) MMIO32((usart_base) + 0x00) +#define USART1_CR1 USART_CR1(USART1_BASE) +#define USART2_CR1 USART_CR1(USART2_BASE) +#define USART3_CR1 USART_CR1(USART3_BASE) +#define USART4_CR1 USART_CR1(USART4_BASE) + +#define USART_CR2(usart_base) MMIO32((usart_base) + 0x04) +#define USART1_CR2 USART_CR2(USART1_BASE) +#define USART2_CR2 USART_CR2(USART2_BASE) +#define USART3_CR2 USART_CR2(USART3_BASE) +#define USART4_CR2 USART_CR2(USART4_BASE) + +#define USART_CR3(usart_base) MMIO32((usart_base) + 0x08) +#define USART1_CR3 USART_CR3(USART1_BASE) +#define USART2_CR3 USART_CR3(USART2_BASE) +#define USART3_CR3 USART_CR3(USART3_BASE) +#define USART4_CR3 USART_CR3(USART4_BASE) + +#define USART_BRR(usart_base) MMIO32((usart_base) + 0x0c) +#define USART1_BRR USART_BRR(USART1_BASE) +#define USART2_BRR USART_BRR(USART2_BASE) +#define USART3_BRR USART_BRR(USART3_BASE) +#define USART4_BRR USART_BRR(USART4_BASE) + +#define USART_GTPR(usart_base) MMIO32((usart_base) + 0x10) +#define USART1_GTPR USART_GTPR(USART1_BASE) +#define USART2_GTPR USART_GTPR(USART2_BASE) +#define USART3_GTPR USART_GTPR(USART3_BASE) +#define USART4_GTPR USART_GTPR(USART4_BASE) + +#define USART_RTOR(usart_base) MMIO32((usart_base) + 0x14) +#define USART1_RTOR USART_RTOR(USART1_BASE) +#define USART2_RTOR USART_RTOR(USART2_BASE) +#define USART3_RTOR USART_RTOR(USART3_BASE) +#define USART4_RTOR USART_RTOR(USART4_BASE) + +#define USART_RQR(usart_base) MMIO32((usart_base) + 0x18) +#define USART1_RQR USART_RQR(USART1_BASE) +#define USART2_RQR USART_RQR(USART2_BASE) +#define USART3_RQR USART_RQR(USART3_BASE) +#define USART4_RQR USART_RQR(USART4_BASE) + +#define USART_ISR(usart_base) MMIO32((usart_base) + 0x1c) +#define USART1_ISR USART_ISR(USART1_BASE) +#define USART2_ISR USART_ISR(USART2_BASE) +#define USART3_ISR USART_ISR(USART3_BASE) +#define USART4_ISR USART_ISR(USART4_BASE) + +#define USART_ICR(usart_base) MMIO32((usart_base) + 0x20) +#define USART1_ICR USART_ICR(USART1_BASE) +#define USART2_ICR USART_ICR(USART2_BASE) +#define USART3_ICR USART_ICR(USART3_BASE) +#define USART4_ICR USART_ICR(USART4_BASE) + +#define USART_RDR(usart_base) MMIO16((usart_base) + 0x24) +#define USART1_RDR USART_RDR(USART1_BASE) +#define USART2_RDR USART_RDR(USART2_BASE) +#define USART3_RDR USART_RDR(USART3_BASE) +#define USART4_RDR USART_RDR(USART4_BASE) + +#define USART_TDR(usart_base) MMIO16((usart_base) + 0x28) +#define USART1_TDR USART_TDR(USART1_BASE) +#define USART2_TDR USART_TDR(USART2_BASE) +#define USART3_TDR USART_TDR(USART3_BASE) +#define USART4_TDR USART_TDR(USART4_BASE) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* USART_CR1 Values ---------------------------------------------------------*/ + +#define USART_CR1_M1 (1 << 28) /* F07x */ +#define USART_CR1_EOBIE (1 << 27) +#define USART_CR1_RTOIE (1 << 26) + +#define USART_CR1_DEAT_SHIFT 21 +#define USART_CR1_DEAT (0x1F << USART_CR1_DEAT_SHIFT) +#define USART_CR1_DEAT_VAL(x) ((x) << USART_CR1_DEAT_SHIFT) + +#define USART_CR1_DEDT_SHIFT 16 +#define USART_CR1_DEDT (0x1F << USART_CR1_DEDT_SHIFT) +#define USART_CR1_DEDT_VAL(x) ((x) << USART_CR1_DEDT_SHIFT) + +#define USART_CR1_OVER8 (1 << 15) +#define USART_CR1_CMIE (1 << 14) +#define USART_CR1_MME (1 << 13) +#define USART_CR1_M (1 << 12) /* Obsolete, please use M0 */ +#define USART_CR1_M0 (1 << 12) +#define USART_CR1_WAKE (1 << 11) +#define USART_CR1_PCE (1 << 10) +#define USART_CR1_PS (1 << 9) +#define USART_CR1_PEIE (1 << 8) +#define USART_CR1_TXEIE (1 << 7) +#define USART_CR1_TCIE (1 << 6) +#define USART_CR1_RXNEIE (1 << 5) +#define USART_CR1_IDLEIE (1 << 4) +#define USART_CR1_TE (1 << 3) +#define USART_CR1_RE (1 << 2) +#define USART_CR1_UESM (1 << 1) +#define USART_CR1_UE (1 << 0) + +/* USART_CR2 Values ---------------------------------------------------------*/ + +#define USART_CR2_ADD_SHIFT 24 +#define USART_CR2_ADD (0xFF << USART_CR2_ADD_SHIFT) +#define USART_CR2_ADD_VAL(x) ((x) << USART_CR2_ADD_SHIFT) + +#define USART_CR2_RTOEN (1 << 23) + +#define USART_CR2_ABRMOD_SHIFT 21 +#define USART_CR2_ABRMOD (3 << USART_CR2_ABRMOD_SHIFT) +#define USART_CR2_ABRMOD_STARTBIT (0 << USART_CR2_ABRMOD_SHIFT) +#define USART_CR2_ABRMOD_FALLTOFALL (1 << USART_CR2_ABRMOD_SHIFT) + +#define USART_CR2_ABREN (1 << 20) +#define USART_CR2_MSBFIRST (1 << 19) +#define USART_CR2_DATAINV (1 << 18) +#define USART_CR2_TXINV (1 << 17) +#define USART_CR2_RXINV (1 << 16) +#define USART_CR2_SWAP (1 << 15) +#define USART_CR2_LINEN (1 << 14) + +#define USART_CR2_STOP_SHIFT 12 +#define USART_CR2_STOP (3 << USART_CR2_STOP_SHIFT) +#define USART_CR2_STOP_1_0BIT (0 << USART_CR2_STOP_SHIFT) +#define USART_CR2_STOP_2_0BIT (2 << USART_CR2_STOP_SHIFT) +#define USART_CR2_STOP_1_5BIT (3 << USART_CR2_STOP_SHIFT) + +#define USART_CR2_CLKEN (1 << 11) +#define USART_CR2_CPOL (1 << 10) +#define USART_CR2_CPHA (1 << 9) +#define USART_CR2_LBCL (1 << 8) +#define USART_CR2_LBIDE (1 << 6) +#define USART_CR2_LBDL (1 << 5) +#define USART_CR2_ADDM (1 << 4) /* Obsolete, use ADDM7 */ +#define USART_CR2_ADDM7 (1 << 4) + +/* USART_CR3 Values ---------------------------------------------------------*/ + +#define USART_CR3_WUFIE (1 << 22) + +#define USART_CR3_WUS_SHIFT 20 +#define USART_CR3_WUS (3 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_ADDRMATCH (0 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_STARTBIT (2 << USART_CR3_WUS_SHIFT) +#define USART_CR3_WUS_RXNE (3 << USART_CR3_WUS_SHIFT) + +#define USART_CR3_SCARCNT_SHIFT 17 +#define USART_CR3_SCARCNT (7 << USART_CR3_SCARCNT_SHIFT) +#define USART_CR3_SCARCNT_DISABLE (0 << USART_CR3_SCARCNT_SHIFT) +#define USART_CR3_SCARCNT_VAL(x) ((x) << USART_CR3_SCARCNT_SHIFT) + +#define USART_CR3_DEP (1 << 15) +#define USART_CR3_DEM (1 << 14) +#define USART_CR3_DDRE (1 << 13) +#define USART_CR3_OVRDIS (1 << 12) +#define USART_CR3_ONEBIT (1 << 11) +#define USART_CR3_CTSIE (1 << 10) +#define USART_CR3_CTSE (1 << 9) +#define USART_CR3_RTSE (1 << 8) +#define USART_CR3_DMAT (1 << 7) +#define USART_CR3_DMAR (1 << 6) +#define USART_CR3_SCEN (1 << 5) +#define USART_CR3_NACK (1 << 4) +#define USART_CR3_HDSEL (1 << 3) +#define USART_CR3_IRLP (1 << 2) +#define USART_CR3_IREN (1 << 1) +#define USART_CR3_EIE (1 << 0) + +/* USART_GTPR Values --------------------------------------------------------*/ + +#define USART_GTPR_GT_SHIFT 8 +#define USART_GTPR_GT (0xFF << USART_GTPR_GT_SHIFT) +#define USART_GTPR_GT_VAL(x) ((x) << USART_GTPR_GT_SHIFT) + +#define USART_GTPR_PSC_SHIFT 0 +#define USART_GTPR_PSC (0xFF << USART_GTPR_PSC_SHIFT) +#define USART_GTPR_PSC_VAL(x) ((x) << USART_GTPR_PSC_SHIFT) + +/* USART_RQR Values ---------------------------------------------------------*/ + +#define USART_RQR_TXFRQ (1 << 4) +#define USART_RQR_RXFRQ (1 << 3) +#define USART_RQR_MMRQ (1 << 2) +#define USART_RQR_SBKRQ (1 << 1) +#define USART_RQR_ABRRQ (1 << 0) + +/* USART_ISR Values ---------------------------------------------------------*/ + +#define USART_ISR_REACK (1 << 22) +#define USART_ISR_TEACK (1 << 21) +#define USART_ISR_WUF (1 << 20) +#define USART_ISR_RWU (1 << 19) +#define USART_ISR_SBKF (1 << 18) +#define USART_ISR_CMF (1 << 17) +#define USART_ISR_BUSY (1 << 16) +#define USART_ISR_ABRF (1 << 15) +#define USART_ISR_ABRE (1 << 14) +#define USART_ISR_EOBF (1 << 12) +#define USART_ISR_RTOF (1 << 11) +#define USART_ISR_CTS (1 << 10) +#define USART_ISR_CTSIF (1 << 9) +#define USART_ISR_LBDF (1 << 8) +#define USART_ISR_TXE (1 << 7) +#define USART_ISR_TC (1 << 6) +#define USART_ISR_RXNE (1 << 5) +#define USART_ISR_IDLE (1 << 4) +#define USART_ISR_ORE (1 << 3) +#define USART_ISR_NF (1 << 2) +#define USART_ISR_FE (1 << 1) +#define USART_ISR_PE (1 << 0) + +/* USART_ICR Values ---------------------------------------------------------*/ + +#define USART_ICR_WUCF (1 << 20) +#define USART_ICR_CMCF (1 << 17) +#define USART_ICR_EOBCF (1 << 12) +#define USART_ICR_RTOCF (1 << 11) +#define USART_ICR_CTSCF (1 << 9) +#define USART_ICR_LBDCF (1 << 8) +#define USART_ICR_TCCF (1 << 6) +#define USART_ICR_IDLECF (1 << 4) +#define USART_ICR_ORECF (1 << 3) +#define USART_ICR_NCF (1 << 2) +#define USART_ICR_FECF (1 << 1) +#define USART_ICR_PECF (1 << 0) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +#define USART_PARITY (USART_CR1_PCE | USART_CR1_PS) +#define USART_PARITY_NONE (0) +#define USART_PARITY_EVEN (USART_CR1_PCE) +#define USART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) + +#define USART_MODE (USART_CR1_TE | USART_CR1_RE) +#define USART_MODE_NONE (0) +#define USART_MODE_RX (USART_CR1_RE) +#define USART_MODE_TX (USART_CR1_TE) +#define USART_MODE_TX_RX (USART_CR1_TE | USART_CR1_RE) + +#define USART_FLOWCONTROL (USART_CR3_RTSE | USART_CR3_CTSE) +#define USART_FLOWCONTROL_NONE (0) +#define USART_FLOWCONTROL_RTS (USART_CR3_RTSE) +#define USART_FLOWCONTROL_CTS (USART_CR3_CTSE) +#define USART_FLOWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +void usart_set_baudrate(uint32_t usart, uint32_t baud); +void usart_set_databits(uint32_t usart, uint32_t bits); +void usart_set_stopbits(uint32_t usart, uint32_t stopbits); +void usart_set_parity(uint32_t usart, uint32_t parity); +void usart_set_mode(uint32_t usart, uint32_t mode); +void usart_set_flow_control(uint32_t usart, uint32_t flowcontrol); +void usart_enable(uint32_t usart); +void usart_disable(uint32_t usart); +void usart_send(uint32_t usart, uint16_t data); +uint16_t usart_recv(uint32_t usart); +void usart_wait_send_ready(uint32_t usart); +void usart_wait_recv_ready(uint32_t usart); +void usart_send_blocking(uint32_t usart, uint16_t data); +uint16_t usart_recv_blocking(uint32_t usart); +void usart_enable_rx_dma(uint32_t usart); +void usart_disable_rx_dma(uint32_t usart); +void usart_enable_tx_dma(uint32_t usart); +void usart_disable_tx_dma(uint32_t usart); +void usart_enable_rx_interrupt(uint32_t usart); +void usart_disable_rx_interrupt(uint32_t usart); +void usart_enable_tx_interrupt(uint32_t usart); +void usart_disable_tx_interrupt(uint32_t usart); +void usart_enable_error_interrupt(uint32_t usart); +void usart_disable_error_interrupt(uint32_t usart); +bool usart_get_flag(uint32_t usart, uint32_t flag); + +END_DECLS + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/adc.h new file mode 100644 index 00000000..39410363 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/adc.h @@ -0,0 +1,425 @@ +/** @defgroup adc_defines ADC Defines + +@brief Defined Constants and Types for the STM32F1xx Analog to Digital +Converters + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 +Edward Cheeseman + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Edward Cheeseman + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* ADC injected channel data offset register x (ADC_JOFRx) (x=1..4) */ +#define ADC_JOFR1(block) MMIO32((block) + 0x14) +#define ADC_JOFR2(block) MMIO32((block) + 0x18) +#define ADC_JOFR3(block) MMIO32((block) + 0x1c) +#define ADC_JOFR4(block) MMIO32((block) + 0x20) + +/* ADC watchdog high threshold register (ADC_HTR) */ +#define ADC_HTR(block) MMIO32((block) + 0x24) + +/* ADC watchdog low threshold register (ADC_LTR) */ +#define ADC_LTR(block) MMIO32((block) + 0x28) + +/* ADC regular sequence register 1 (ADC_SQR1) */ +#define ADC_SQR1(block) MMIO32((block) + 0x2c) + +/* ADC regular sequence register 2 (ADC_SQR2) */ +#define ADC_SQR2(block) MMIO32((block) + 0x30) + +/* ADC regular sequence register 3 (ADC_SQR3) */ +#define ADC_SQR3(block) MMIO32((block) + 0x34) + +/* ADC injected sequence register (ADC_JSQR) */ +#define ADC_JSQR(block) MMIO32((block) + 0x38) + +/* ADC injected data register x (ADC_JDRx) (x=1..4) */ +#define ADC_JDR1(block) MMIO32((block) + 0x3c) +#define ADC_JDR2(block) MMIO32((block) + 0x40) +#define ADC_JDR3(block) MMIO32((block) + 0x44) +#define ADC_JDR4(block) MMIO32((block) + 0x48) + +/* ADC regular data register (ADC_DR) */ +#define ADC_DR(block) MMIO32((block) + 0x4c) + + +/* --- ADC_CR1 values ------------------------------------------------------ */ + +/* Note: Bits [21:20] are reserved, and must be kept at reset value. */ + +/* DUALMOD[3:0]: Dual mode selection. (ADC1 only) */ +/* Legend: + * IND: Independent mode. + * CRSISM: Combined regular simultaneous + injected simultaneous mode. + * CRSATM: Combined regular simultaneous + alternate trigger mode. + * CISFIM: Combined injected simultaneous + fast interleaved mode. + * CISSIM: Combined injected simultaneous + slow interleaved mode. + * ISM: Injected simultaneous mode only. + * RSM: Regular simultaneous mode only. + * FIM: Fast interleaved mode only. + * SIM: Slow interleaved mode only. + * ATM: Alternate trigger mode only. + */ +/****************************************************************************/ +/* ADC_CR1 DUALMOD[3:0] ADC Mode Selection */ +/** @defgroup adc_cr1_dualmod ADC Mode Selection +@ingroup adc_defines + +@{*/ +/** Independent (non-dual) mode */ +#define ADC_CR1_DUALMOD_IND (0x0 << 16) +/** Combined regular simultaneous + injected simultaneous mode. */ +#define ADC_CR1_DUALMOD_CRSISM (0x1 << 16) +/** Combined regular simultaneous + alternate trigger mode. */ +#define ADC_CR1_DUALMOD_CRSATM (0x2 << 16) +/** Combined injected simultaneous + fast interleaved mode. */ +#define ADC_CR1_DUALMOD_CISFIM (0x3 << 16) +/** Combined injected simultaneous + slow interleaved mode. */ +#define ADC_CR1_DUALMOD_CISSIM (0x4 << 16) +/** Injected simultaneous mode only. */ +#define ADC_CR1_DUALMOD_ISM (0x5 << 16) +/** Regular simultaneous mode only. */ +#define ADC_CR1_DUALMOD_RSM (0x6 << 16) +/** Fast interleaved mode only. */ +#define ADC_CR1_DUALMOD_FIM (0x7 << 16) +/** Slow interleaved mode only. */ +#define ADC_CR1_DUALMOD_SIM (0x8 << 16) +/** Alternate trigger mode only. */ +#define ADC_CR1_DUALMOD_ATM (0x9 << 16) +/**@}*/ +#define ADC_CR1_DUALMOD_MASK (0xF << 16) +#define ADC_CR1_DUALMOD_SHIFT 16 + +#define ADC_CR1_AWDCH_MAX 17 + +/* --- ADC_CR2 values ------------------------------------------------------ */ + +/* TSVREFE: */ /** Temperature sensor and V_REFINT enable. (ADC1 only!) */ +#define ADC_CR2_TSVREFE (1 << 23) + +/* SWSTART: */ /** Start conversion of regular channels. */ +#define ADC_CR2_SWSTART (1 << 22) + +/* JSWSTART: */ /** Start conversion of injected channels. */ +#define ADC_CR2_JSWSTART (1 << 21) + +/* EXTTRIG: */ /** External trigger conversion mode for regular channels. */ +#define ADC_CR2_EXTTRIG (1 << 20) + +/* EXTSEL[2:0]: External event select for regular group. */ +/* The following are only valid for ADC1 and ADC2. */ +/****************************************************************************/ +/* ADC_CR2 EXTSEL[2:0] ADC Trigger Identifier for ADC1 and ADC2 */ +/** @defgroup adc_trigger_regular_12 ADC Trigger Identifier for ADC1 and ADC2 +@ingroup adc_defines + +@{*/ +/** Timer 1 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 17) +/** Timer 1 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 17) +/** Timer 1 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 17) +/** Timer 2 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 17) +/** Timer 3 Trigger Output */ +#define ADC_CR2_EXTSEL_TIM3_TRGO (0x4 << 17) +/** Timer 4 Compare Output 4 */ +#define ADC_CR2_EXTSEL_TIM4_CC4 (0x5 << 17) +/** External Interrupt 11 */ +#define ADC_CR2_EXTSEL_EXTI11 (0x6 << 17) +/** Software Trigger */ +#define ADC_CR2_EXTSEL_SWSTART (0x7 << 17) +/**@}*/ + +/* The following are only valid for ADC3 */ +/****************************************************************************/ +/* ADC_CR2 EXTSEL[2:0] ADC Trigger Identifier for ADC3 */ +/** @defgroup adc_trigger_regular_3 ADC Trigger Identifier for ADC3 +@ingroup adc_defines + +@{*/ +/** Timer 2 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM3_CC1 (0x0 << 17) +/** Timer 2 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM2_CC3 (0x1 << 17) +/** Timer 1 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 17) +/** Timer 8 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM8_CC1 (0x3 << 17) +/** Timer 8 Trigger Output */ +#define ADC_CR2_EXTSEL_TIM8_TRGO (0x4 << 17) +/** Timer 5 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM5_CC1 (0x5 << 17) +/** Timer 5 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM5_CC3 (0x6 << 17) +/**@}*/ + +#define ADC_CR2_EXTSEL_MASK (0x7 << 17) +#define ADC_CR2_EXTSEL_SHIFT 17 + +/* Note: Bit 16 is reserved, must be kept at reset value. */ + +/* JEXTTRIG: External trigger conversion mode for injected channels. */ +#define ADC_CR2_JEXTTRIG (1 << 15) + +/* JEXTSEL[2:0]: External event selection for injected group. */ +/* The following are only valid for ADC1 and ADC2. */ +/****************************************************************************/ +/* ADC_CR2 JEXTSEL[2:0] ADC Injected Trigger Identifier for ADC1 and ADC2 */ +/** @defgroup adc_trigger_injected_12 ADC Injected Trigger Identifier for ADC1 +and ADC2 +@ingroup adc_defines + +@{*/ +/** Timer 1 Trigger Output */ +#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x0 << 12) +/** Timer 1 Compare Output 4 */ +#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x1 << 12) +/** Timer 2 Trigger Output */ +#define ADC_CR2_JEXTSEL_TIM2_TRGO (0x2 << 12) +/** Timer 2 Compare Output 1 */ +#define ADC_CR2_JEXTSEL_TIM2_CC1 (0x3 << 12) +/** Timer 3 Compare Output 4 */ +#define ADC_CR2_JEXTSEL_TIM3_CC4 (0x4 << 12) +/** Timer 4 Trigger Output */ +#define ADC_CR2_JEXTSEL_TIM4_TRGO (0x5 << 12) +/** External Interrupt 15 */ +#define ADC_CR2_JEXTSEL_EXTI15 (0x6 << 12) +/** Injected Software Trigger */ +#define ADC_CR2_JEXTSEL_JSWSTART (0x7 << 12) /* Software start. */ +/**@}*/ + +/* The following are the different meanings for ADC3 only. */ +/****************************************************************************/ +/* ADC_CR2 JEXTSEL[2:0] ADC Injected Trigger Identifier for ADC3 */ +/** @defgroup adc_trigger_injected_3 ADC Injected Trigger Identifier for ADC3 +@ingroup adc_defines + +@{*/ +/** Timer 1 Trigger Output */ +#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x0 << 12) +/** Timer 1 Compare Output 4 */ +#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x1 << 12) +/** Timer 4 Compare Output 3 */ +#define ADC_CR2_JEXTSEL_TIM4_CC3 (0x2 << 12) +/** Timer 8 Compare Output 2 */ +#define ADC_CR2_JEXTSEL_TIM8_CC2 (0x3 << 12) +/** Timer 8 Compare Output 4 */ +#define ADC_CR2_JEXTSEL_TIM8_CC4 (0x4 << 12) +/** Timer 5 Trigger Output */ +#define ADC_CR2_JEXTSEL_TIM5_TRGO (0x5 << 12) +/** Timer 5 Compare Output 4 */ +#define ADC_CR2_JEXTSEL_TIM5_CC4 (0x6 << 12) +/** Injected Software Trigger */ +#define ADC_CR2_JEXTSEL_JSWSTART (0x7 << 12) /* Software start. */ +/**@}*/ + +#define ADC_CR2_JEXTSEL_MASK (0x7 << 12) +#define ADC_CR2_JEXTSEL_SHIFT 12 + +/* ALIGN: Data alignment. */ +#define ADC_CR2_ALIGN_RIGHT (0 << 11) +#define ADC_CR2_ALIGN_LEFT (1 << 11) +#define ADC_CR2_ALIGN (1 << 11) + +/* Note: Bits [10:9] are reserved and must be kept at reset value. */ + +/* DMA: Direct memory access mode. (ADC1 and ADC3 only!) */ +#define ADC_CR2_DMA (1 << 8) + +/* Note: Bits [7:4] are reserved and must be kept at reset value. */ + +/* RSTCAL: Reset calibration. */ +#define ADC_CR2_RSTCAL (1 << 3) + +/* CAL: A/D Calibration. */ +#define ADC_CR2_CAL (1 << 2) + +/* CONT: Continuous conversion. */ +#define ADC_CR2_CONT (1 << 1) + +/* ADON: A/D converter On/Off. */ +/* Note: If any other bit in this register apart from ADON is changed at the + * same time, then conversion is not triggered. This is to prevent triggering + * an erroneous conversion. + * Conclusion: Must be separately written. + */ +#define ADC_CR2_ADON (1 << 0) + +/* --- ADC_SMPR1 values ---------------------------------------------------- */ +#define ADC_SMPR1_SMP17_LSB 21 +#define ADC_SMPR1_SMP16_LSB 18 +#define ADC_SMPR1_SMP15_LSB 15 +#define ADC_SMPR1_SMP14_LSB 12 +#define ADC_SMPR1_SMP13_LSB 9 +#define ADC_SMPR1_SMP12_LSB 6 +#define ADC_SMPR1_SMP11_LSB 3 +#define ADC_SMPR1_SMP10_LSB 0 +#define ADC_SMPR1_SMP17_MSK (0x7 << ADC_SMPR1_SMP17_LSB) +#define ADC_SMPR1_SMP16_MSK (0x7 << ADC_SMPR1_SMP16_LSB) +#define ADC_SMPR1_SMP15_MSK (0x7 << ADC_SMPR1_SMP15_LSB) +#define ADC_SMPR1_SMP14_MSK (0x7 << ADC_SMPR1_SMP14_LSB) +#define ADC_SMPR1_SMP13_MSK (0x7 << ADC_SMPR1_SMP13_LSB) +#define ADC_SMPR1_SMP12_MSK (0x7 << ADC_SMPR1_SMP12_LSB) +#define ADC_SMPR1_SMP11_MSK (0x7 << ADC_SMPR1_SMP11_LSB) +#define ADC_SMPR1_SMP10_MSK (0x7 << ADC_SMPR1_SMP10_LSB) + +/* --- ADC_SMPR2 values ---------------------------------------------------- */ + +#define ADC_SMPR2_SMP9_LSB 27 +#define ADC_SMPR2_SMP8_LSB 24 +#define ADC_SMPR2_SMP7_LSB 21 +#define ADC_SMPR2_SMP6_LSB 18 +#define ADC_SMPR2_SMP5_LSB 15 +#define ADC_SMPR2_SMP4_LSB 12 +#define ADC_SMPR2_SMP3_LSB 9 +#define ADC_SMPR2_SMP2_LSB 6 +#define ADC_SMPR2_SMP1_LSB 3 +#define ADC_SMPR2_SMP0_LSB 0 +#define ADC_SMPR2_SMP9_MSK (0x7 << ADC_SMPR2_SMP9_LSB) +#define ADC_SMPR2_SMP8_MSK (0x7 << ADC_SMPR2_SMP8_LSB) +#define ADC_SMPR2_SMP7_MSK (0x7 << ADC_SMPR2_SMP7_LSB) +#define ADC_SMPR2_SMP6_MSK (0x7 << ADC_SMPR2_SMP6_LSB) +#define ADC_SMPR2_SMP5_MSK (0x7 << ADC_SMPR2_SMP5_LSB) +#define ADC_SMPR2_SMP4_MSK (0x7 << ADC_SMPR2_SMP4_LSB) +#define ADC_SMPR2_SMP3_MSK (0x7 << ADC_SMPR2_SMP3_LSB) +#define ADC_SMPR2_SMP2_MSK (0x7 << ADC_SMPR2_SMP2_LSB) +#define ADC_SMPR2_SMP1_MSK (0x7 << ADC_SMPR2_SMP1_LSB) +#define ADC_SMPR2_SMP0_MSK (0x7 << ADC_SMPR2_SMP0_LSB) + +/* --- ADC_SMPRx values --------------------------------------------------- */ +/****************************************************************************/ +/* ADC_SMPRG ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_rg ADC Sample Time Selection for All Channels +@ingroup adc_defines + +@{*/ +#define ADC_SMPR_SMP_1DOT5CYC 0x0 +#define ADC_SMPR_SMP_7DOT5CYC 0x1 +#define ADC_SMPR_SMP_13DOT5CYC 0x2 +#define ADC_SMPR_SMP_28DOT5CYC 0x3 +#define ADC_SMPR_SMP_41DOT5CYC 0x4 +#define ADC_SMPR_SMP_55DOT5CYC 0x5 +#define ADC_SMPR_SMP_71DOT5CYC 0x6 +#define ADC_SMPR_SMP_239DOT5CYC 0x7 +/**@}*/ + + +/* --- ADC_SQR1 values ----------------------------------------------------- */ + +#define ADC_SQR_MAX_CHANNELS_REGULAR 16 + +#define ADC_SQR1_SQ16_LSB 15 +#define ADC_SQR1_SQ15_LSB 10 +#define ADC_SQR1_SQ14_LSB 5 +#define ADC_SQR1_SQ13_LSB 0 +#define ADC_SQR1_L_MSK (0xf << ADC_SQR1_L_LSB) +#define ADC_SQR1_SQ16_MSK (0x1f << ADC_SQR1_SQ16_LSB) +#define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQR1_SQ15_LSB) +#define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQR1_SQ14_LSB) +#define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQR1_SQ13_LSB) + +/* --- ADC_SQR2 values ----------------------------------------------------- */ + +#define ADC_SQR2_SQ12_LSB 25 +#define ADC_SQR2_SQ11_LSB 20 +#define ADC_SQR2_SQ10_LSB 15 +#define ADC_SQR2_SQ9_LSB 10 +#define ADC_SQR2_SQ8_LSB 5 +#define ADC_SQR2_SQ7_LSB 0 +#define ADC_SQR2_SQ12_MSK (0x1f << ADC_SQR2_SQ12_LSB) +#define ADC_SQR2_SQ11_MSK (0x1f << ADC_SQR2_SQ11_LSB) +#define ADC_SQR2_SQ10_MSK (0x1f << ADC_SQR2_SQ10_LSB) +#define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQR2_SQ9_LSB) +#define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQR2_SQ8_LSB) +#define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQR2_SQ7_LSB) + +/* --- ADC_SQR3 values ----------------------------------------------------- */ + +#define ADC_SQR3_SQ6_LSB 25 +#define ADC_SQR3_SQ5_LSB 20 +#define ADC_SQR3_SQ4_LSB 15 +#define ADC_SQR3_SQ3_LSB 10 +#define ADC_SQR3_SQ2_LSB 5 +#define ADC_SQR3_SQ1_LSB 0 +#define ADC_SQR3_SQ6_MSK (0x1f << ADC_SQR3_SQ6_LSB) +#define ADC_SQR3_SQ5_MSK (0x1f << ADC_SQR3_SQ5_LSB) +#define ADC_SQR3_SQ4_MSK (0x1f << ADC_SQR3_SQ4_LSB) +#define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQR3_SQ3_LSB) +#define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQR3_SQ2_LSB) +#define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQR3_SQ1_LSB) + +/* --- ADC_JDRx, ADC_DR values --------------------------------------------- */ + +#define ADC_JDATA_LSB 0 +#define ADC_DATA_LSB 0 +#define ADC_ADC2DATA_LSB 16 /* ADC1 only (dual mode) */ +#define ADC_JDATA_MSK (0xffff << ADC_JDATA_LSB) +#define ADC_DATA_MSK (0xffff << ADC_DA) +#define ADC_ADC2DATA_MSK (0xffff << ADC_ADC2DATA_LSB) + /* ADC1 only (dual mode) */ + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_TEMP 16 +#define ADC_CHANNEL_VREF 17 +/**@}*/ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void adc_start_conversion_direct(uint32_t adc); +void adc_set_dual_mode(uint32_t mode); +void adc_enable_temperature_sensor(void); +void adc_disable_temperature_sensor(void); +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger); +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger); +void adc_reset_calibration(uint32_t adc); +void adc_calibration(uint32_t adc) + LIBOPENCM3_DEPRECATED("see adc_calibrate/_async"); +void adc_calibrate_async(uint32_t adc); +bool adc_is_calibrating(uint32_t adc); +void adc_calibrate(uint32_t adc); + +END_DECLS + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/bkp.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/bkp.h new file mode 100644 index 00000000..3d36a1f4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/bkp.h @@ -0,0 +1,205 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_BKP_H +#define LIBOPENCM3_BKP_H + +/* --- BKP registers ------------------------------------------------------- */ + +/* Backup data register 1 (BKP_DR1) */ +#define BKP_DR1 MMIO32(BACKUP_REGS_BASE + 0x04) + +/* Backup data register 2 (BKP_DR2) */ +#define BKP_DR2 MMIO32(BACKUP_REGS_BASE + 0x08) + +/* Backup data register 3 (BKP_DR3) */ +#define BKP_DR3 MMIO32(BACKUP_REGS_BASE + 0x0C) + +/* Backup data register 4 (BKP_DR4) */ +#define BKP_DR4 MMIO32(BACKUP_REGS_BASE + 0x10) + +/* Backup data register 5 (BKP_DR5) */ +#define BKP_DR5 MMIO32(BACKUP_REGS_BASE + 0x14) + +/* Backup data register 6 (BKP_DR6) */ +#define BKP_DR6 MMIO32(BACKUP_REGS_BASE + 0x18) + +/* Backup data register 7 (BKP_DR7) */ +#define BKP_DR7 MMIO32(BACKUP_REGS_BASE + 0x1C) + +/* Backup data register 8 (BKP_DR8) */ +#define BKP_DR8 MMIO32(BACKUP_REGS_BASE + 0x20) + +/* Backup data register 9 (BKP_DR9) */ +#define BKP_DR9 MMIO32(BACKUP_REGS_BASE + 0x24) + +/* Backup data register 10 (BKP_DR10) */ +#define BKP_DR10 MMIO32(BACKUP_REGS_BASE + 0x28) + +/* RTC clock calibration register (BKP_RTCCR) */ +#define BKP_RTCCR MMIO32(BACKUP_REGS_BASE + 0x2C) + +/* Backup control register (BKP_CR) */ +#define BKP_CR MMIO32(BACKUP_REGS_BASE + 0x30) + +/* Backup control/status register (BKP_CSR) */ +#define BKP_CSR MMIO32(BACKUP_REGS_BASE + 0x34) + +/* Backup data register 11 (BKP_DR11) */ +#define BKP_DR11 MMIO32(BACKUP_REGS_BASE + 0x40) + +/* Backup data register 12 (BKP_DR12) */ +#define BKP_DR12 MMIO32(BACKUP_REGS_BASE + 0x44) + +/* Backup data register 13 (BKP_DR13) */ +#define BKP_DR13 MMIO32(BACKUP_REGS_BASE + 0x48) + +/* Backup data register 14 (BKP_DR14) */ +#define BKP_DR14 MMIO32(BACKUP_REGS_BASE + 0x4C) + +/* Backup data register 15 (BKP_DR15) */ +#define BKP_DR15 MMIO32(BACKUP_REGS_BASE + 0x50) + +/* Backup data register 16 (BKP_DR16) */ +#define BKP_DR16 MMIO32(BACKUP_REGS_BASE + 0x54) + +/* Backup data register 17 (BKP_DR17) */ +#define BKP_DR17 MMIO32(BACKUP_REGS_BASE + 0x58) + +/* Backup data register 18 (BKP_DR18) */ +#define BKP_DR18 MMIO32(BACKUP_REGS_BASE + 0x5C) + +/* Backup data register 19 (BKP_DR19) */ +#define BKP_DR19 MMIO32(BACKUP_REGS_BASE + 0x60) + +/* Backup data register 20 (BKP_DR20) */ +#define BKP_DR20 MMIO32(BACKUP_REGS_BASE + 0x64) + +/* Backup data register 21 (BKP_DR21) */ +#define BKP_DR21 MMIO32(BACKUP_REGS_BASE + 0x68) + +/* Backup data register 22 (BKP_DR22) */ +#define BKP_DR22 MMIO32(BACKUP_REGS_BASE + 0x6C) + +/* Backup data register 23 (BKP_DR23) */ +#define BKP_DR23 MMIO32(BACKUP_REGS_BASE + 0x70) + +/* Backup data register 24 (BKP_DR24) */ +#define BKP_DR24 MMIO32(BACKUP_REGS_BASE + 0x74) + +/* Backup data register 25 (BKP_DR25) */ +#define BKP_DR25 MMIO32(BACKUP_REGS_BASE + 0x78) + +/* Backup data register 26 (BKP_DR26) */ +#define BKP_DR26 MMIO32(BACKUP_REGS_BASE + 0x7C) + +/* Backup data register 27 (BKP_DR27) */ +#define BKP_DR27 MMIO32(BACKUP_REGS_BASE + 0x80) + +/* Backup data register 28 (BKP_DR28) */ +#define BKP_DR28 MMIO32(BACKUP_REGS_BASE + 0x84) + +/* Backup data register 29 (BKP_DR29) */ +#define BKP_DR29 MMIO32(BACKUP_REGS_BASE + 0x88) + +/* Backup data register 30 (BKP_DR30) */ +#define BKP_DR30 MMIO32(BACKUP_REGS_BASE + 0x8C) + +/* Backup data register 31 (BKP_DR31) */ +#define BKP_DR31 MMIO32(BACKUP_REGS_BASE + 0x90) + +/* Backup data register 32 (BKP_DR32) */ +#define BKP_DR32 MMIO32(BACKUP_REGS_BASE + 0x94) + +/* Backup data register 33 (BKP_DR33) */ +#define BKP_DR33 MMIO32(BACKUP_REGS_BASE + 0x98) + +/* Backup data register 34 (BKP_DR34) */ +#define BKP_DR34 MMIO32(BACKUP_REGS_BASE + 0x9C) + +/* Backup data register 35 (BKP_DR35) */ +#define BKP_DR35 MMIO32(BACKUP_REGS_BASE + 0xA0) + +/* Backup data register 36 (BKP_DR36) */ +#define BKP_DR36 MMIO32(BACKUP_REGS_BASE + 0xA4) + +/* Backup data register 37 (BKP_DR37) */ +#define BKP_DR37 MMIO32(BACKUP_REGS_BASE + 0xA8) + +/* Backup data register 38 (BKP_DR38) */ +#define BKP_DR38 MMIO32(BACKUP_REGS_BASE + 0xAC) + +/* Backup data register 39 (BKP_DR39) */ +#define BKP_DR39 MMIO32(BACKUP_REGS_BASE + 0xB0) + +/* Backup data register 40 (BKP_DR40) */ +#define BKP_DR40 MMIO32(BACKUP_REGS_BASE + 0xB4) + +/* Backup data register 41 (BKP_DR41) */ +#define BKP_DR41 MMIO32(BACKUP_REGS_BASE + 0xB8) + +/* Backup data register 42 (BKP_DR42) */ +#define BKP_DR42 MMIO32(BACKUP_REGS_BASE + 0xBC) + +/* --- BKP_RTCCR values ---------------------------------------------------- */ + +/* ASOS: Alarm or second output selection */ +#define BKP_RTCCR_ASOS (1 << 9) + +/* ASOE: Alarm or second output enable */ +#define BKP_RTCCR_ASOE (1 << 8) + +/* CCO: Calibration clock output */ +#define BKP_RTCCR_CCO (1 << 7) + +/* CAL[6:0]: Calibration value */ +#define BKP_RTCCR_CAL_LSB 0 + +/* --- BKP_CR values ------------------------------------------------------- */ + +/* TPAL: TAMPER pin active level */ +#define BKP_CR_TAL (1 << 1) + +/* TPE: TAMPER pin enable */ +#define BKP_CR_TPE (1 << 0) + +/* --- BKP_CSR values ------------------------------------------------------ */ + +/* TIF: Tamper interrupt flag */ +#define BKP_CSR_TIF (1 << 9) + +/* TEF: Tamper event flag */ +#define BKP_CSR_TEF (1 << 8) + +/* TPIE: TAMPER pin interrupt enable */ +#define BKP_CSR_TPIE (1 << 2) + +/* CTI: Clear tamper interrupt */ +#define BKP_CSR_CTI (1 << 1) + +/* CTE: Clear tamper event */ +#define BKP_CSR_CTE (1 << 0) + +/* --- BKP_DRx values ------------------------------------------------------ */ + +/* Bits[15:0]: Backup data */ + +/* --- BKP function prototypes --------------------------------------------- */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/crc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/crc.h new file mode 100644 index 00000000..a35bf490 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/crc.h @@ -0,0 +1,38 @@ +/** @defgroup crc_defines CRC Defines + +@brief libopencm3 Defined Constants and Types for the STM32F1xx CRC +Generator + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dac.h new file mode 100644 index 00000000..145df731 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dac.h @@ -0,0 +1,37 @@ +/** @defgroup dac_defines DAC Defines + +@brief Defined Constants and Types for the STM32F1xx DAC + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dma.h new file mode 100644 index 00000000..ac730904 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/dma.h @@ -0,0 +1,37 @@ +/** @defgroup dma_defines DMA Defines + +@ingroup STM32F1xx_defines + +@brief Defined Constants and Types for the STM32F1xx DMA Controller + +@version 1.0.0 + +@date 30 November 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/doc-stm32f1.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/doc-stm32f1.h new file mode 100644 index 00000000..4e1407e2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/doc-stm32f1.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32F1 + +@version 1.0.0 + +@date 7 September 2012 + +API documentation for ST Microelectronics STM32F1 Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F1xx STM32F1xx +Libraries for ST Microelectronics STM32F1xx series. + +@version 1.0.0 + +@date 7 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F1xx_defines STM32F1xx Defines + +@brief Defined Constants and Types for the STM32F1xx series + +@version 1.0.0 + +@date 7 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/exti.h new file mode 100644 index 00000000..10882107 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/exti.h @@ -0,0 +1,41 @@ +/** @defgroup exti_defines EXTI Defines + * + * @brief Defined Constants and Types for the STM32F1xx External Interrupts + * + * + * @ingroup STM32F1xx_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Piotr Esden-Tempski + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EXTI_H +#define LIBOPENCM3_EXTI_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/flash.h new file mode 100644 index 00000000..f7ba402b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/flash.h @@ -0,0 +1,120 @@ +/** @defgroup flash_defines FLASH Defines + * + * @ingroup STM32F1xx_defines + * + * @brief Defined Constants and Types for the STM32F1xx FLASH Memory + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * For details see: + * PM0075 programming manual: STM32F10xxx Flash programming + * August 2010, Doc ID 17863 Rev 1 + * https://github.com/libopencm3/libopencm3-archive/blob/master/st_micro/CD00283419.pdf + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H + +/**@{*/ + +#include + +/* --- FLASH_OPTION bytes ------------------------------------------------- */ + +/** @defgroup flash_options Option Byte Addresses +@ingroup flash_defines +@{*/ +#define FLASH_OPTION_BYTE_0 FLASH_OPTION_BYTE(0) +#define FLASH_OPTION_BYTE_1 FLASH_OPTION_BYTE(1) +#define FLASH_OPTION_BYTE_2 FLASH_OPTION_BYTE(2) +#define FLASH_OPTION_BYTE_3 FLASH_OPTION_BYTE(3) +#define FLASH_OPTION_BYTE_4 FLASH_OPTION_BYTE(4) +#define FLASH_OPTION_BYTE_5 FLASH_OPTION_BYTE(5) +#define FLASH_OPTION_BYTE_6 FLASH_OPTION_BYTE(6) +#define FLASH_OPTION_BYTE_7 FLASH_OPTION_BYTE(7) +/**@}*/ + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +/** @defgroup flash_latency FLASH Wait States +@ingroup flash_defines +@{*/ +#define FLASH_ACR_LATENCY_0WS 0x00 +#define FLASH_ACR_LATENCY_1WS 0x01 +#define FLASH_ACR_LATENCY_2WS 0x02 +/**@}*/ +#define FLASH_ACR_HLFCYA (1 << 3) + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_EOP (1 << 5) +#define FLASH_SR_WRPRTERR (1 << 4) +#define FLASH_SR_PGERR (1 << 2) +#define FLASH_SR_BSY (1 << 0) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +/* --- FLASH_OBR values ---------------------------------------------------- */ + +/* FLASH_OBR[25:18]: Data1 */ +/* FLASH_OBR[17:10]: Data0 */ +#define FLASH_OBR_NRST_STDBY (1 << 4) +#define FLASH_OBR_NRST_STOP (1 << 3) +#define FLASH_OBR_WDG_SW (1 << 2) +#define FLASH_OBR_RDPRT_EN (1 << FLASH_OBR_RDPRT_SHIFT) + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/* Read protection option byte protection enable key */ +#define FLASH_RDP_KEY ((uint16_t)0x00a5) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_halfcycle_enable(void); +void flash_halfcycle_disable(void); +void flash_unlock_upper(void); +void flash_lock_upper(void); +void flash_clear_pgerr_flag_upper(void); +void flash_clear_eop_flag_upper(void); +void flash_clear_wrprterr_flag_upper(void); +void flash_clear_bsy_flag_upper(void); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/gpio.h new file mode 100644 index 00000000..2de19ce9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/gpio.h @@ -0,0 +1,979 @@ +/** @defgroup gpio_defines GPIO Defines + +@brief Defined Constants and Types for the STM32F1xx General Purpose I/O + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Piotr Esden-Tempski + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +/** @defgroup gpio_port_id GPIO Port IDs +@ingroup gpio_defines + +@{*/ +/* GPIO port base addresses (for convenience) */ +#define GPIOA GPIO_PORT_A_BASE +#define GPIOB GPIO_PORT_B_BASE +#define GPIOC GPIO_PORT_C_BASE +#define GPIOD GPIO_PORT_D_BASE +#define GPIOE GPIO_PORT_E_BASE +#define GPIOF GPIO_PORT_F_BASE +#define GPIOG GPIO_PORT_G_BASE +/**@}*/ + +/* --- Alternate function GPIOs -------------------------------------------- */ + +/* Default alternate functions of some pins (with and without remapping) */ + +/* CAN1 / CAN GPIO */ +#define GPIO_CAN1_RX GPIO11 /* PA11 */ +#define GPIO_CAN1_TX GPIO12 /* PA12 */ +#define GPIO_CAN_RX GPIO_CAN1_RX /* Alias */ +#define GPIO_CAN_TX GPIO_CAN1_TX /* Alias */ + +#define GPIO_CAN_PB_RX GPIO8 /* PB8 */ +#define GPIO_CAN_PB_TX GPIO9 /* PB9 */ +#define GPIO_CAN1_PB_RX GPIO_CAN_PB_RX /* Alias */ +#define GPIO_CAN1_PB_TX GPIO_CAN_PB_TX /* Alias */ + +#define GPIO_CAN_PD_RX GPIO0 /* PD0 */ +#define GPIO_CAN_PD_TX GPIO1 /* PD1 */ +#define GPIO_CAN1_PD_RX GPIO_CAN_PD_RX /* Alias */ +#define GPIO_CAN1_PD_TX GPIO_CAN_PD_TX /* Alias */ + +/* CAN1 / CAN BANK */ +#define GPIO_BANK_CAN1_RX GPIOA /* PA11 */ +#define GPIO_BANK_CAN1_TX GPIOA /* PA12 */ +#define GPIO_BANK_CAN_RX GPIO_BANK_CAN1_RX /* Alias */ +#define GPIO_BANK_CAN_TX GPIO_BANK_CAN1_TX /* Alias */ + +#define GPIO_BANK_CAN_PB_RX GPIOB /* PB8 */ +#define GPIO_BANK_CAN_PB_TX GPIOB /* PB9 */ +#define GPIO_BANK_CAN1_PB_RX GPIO_BANK_CAN_PB_RX /* Alias */ +#define GPIO_BANK_CAN1_PB_TX GPIO_BANK_CAN_PB_TX /* Alias */ + +#define GPIO_BANK_CAN_PD_RX GPIOD /* PD0 */ +#define GPIO_BANK_CAN_PD_TX GPIOD /* PD1 */ +#define GPIO_BANK_CAN1_PD_RX GPIO_BANK_CAN_PD_RX /* Alias */ +#define GPIO_BANK_CAN1_PD_TX GPIO_BANK_CAN_PD_TX /* Alias */ + +/* CAN2 GPIO */ +#define GPIO_CAN2_RX GPIO12 /* PB12 */ +#define GPIO_CAN2_TX GPIO13 /* PB13 */ + +#define GPIO_CAN2_RE_RX GPIO5 /* PB5 */ +#define GPIO_CAN2_RE_TX GPIO6 /* PB6 */ + +/* CAN2 BANK */ +#define GPIO_BANK_CAN2_RX GPIOB /* PB12 */ +#define GPIO_BANK_CAN2_TX GPIOB /* PB13 */ + +#define GPIO_BANK_CAN2_RE_RX GPIOB /* PB5 */ +#define GPIO_BANK_CAN2_RE_TX GPIOB /* PB6 */ + +/* JTAG/SWD GPIO */ +#define GPIO_JTMS_SWDIO GPIO13 /* PA13 */ +#define GPIO_JTCK_SWCLK GPIO14 /* PA14 */ +#define GPIO_JTDI GPIO15 /* PA15 */ +#define GPIO_JTDO_TRACESWO GPIO3 /* PB3 */ +#define GPIO_JNTRST GPIO4 /* PB4 */ +#define GPIO_TRACECK GPIO2 /* PE2 */ +#define GPIO_TRACED0 GPIO3 /* PE3 */ +#define GPIO_TRACED1 GPIO4 /* PE4 */ +#define GPIO_TRACED2 GPIO5 /* PE5 */ +#define GPIO_TRACED3 GPIO6 /* PE6 */ + +/* JTAG/SWD BANK */ +#define GPIO_BANK_JTMS_SWDIO GPIOA /* PA13 */ +#define GPIO_BANK_JTCK_SWCLK GPIOA /* PA14 */ +#define GPIO_BANK_JTDI GPIOA /* PA15 */ +#define GPIO_BANK_JTDO_TRACESWO GPIOB /* PB3 */ +#define GPIO_BANK_JNTRST GPIOB /* PB4 */ +#define GPIO_BANK_TRACECK GPIOE /* PE2 */ +#define GPIO_BANK_TRACED0 GPIOE /* PE3 */ +#define GPIO_BANK_TRACED1 GPIOE /* PE4 */ +#define GPIO_BANK_TRACED2 GPIOE /* PE5 */ +#define GPIO_BANK_TRACED3 GPIOE /* PE6 */ + +/* Timer5 GPIO */ +#define GPIO_TIM5_CH1 GPIO0 /* PA0 */ +#define GPIO_TIM5_CH2 GPIO1 /* PA1 */ +#define GPIO_TIM5_CH3 GPIO2 /* PA2 */ +#define GPIO_TIM5_CH4 GPIO3 /* PA3 */ + +/* Timer5 BANK */ +#define GPIO_BANK_TIM5_CH1 GPIOA /* PA0 */ +#define GPIO_BANK_TIM5_CH2 GPIOA /* PA1 */ +#define GPIO_BANK_TIM5_CH3 GPIOA /* PA2 */ +#define GPIO_BANK_TIM5_CH4 GPIOA /* PA3 */ +#define GPIO_BANK_TIM5 GPIOA + +/* Timer4 GPIO */ +#define GPIO_TIM4_CH1 GPIO6 /* PB6 */ +#define GPIO_TIM4_CH2 GPIO7 /* PB7 */ +#define GPIO_TIM4_CH3 GPIO8 /* PB8 */ +#define GPIO_TIM4_CH4 GPIO9 /* PB9 */ + +#define GPIO_TIM4_RE_CH1 GPIO12 /* PD12 */ +#define GPIO_TIM4_RE_CH2 GPIO13 /* PD13 */ +#define GPIO_TIM4_RE_CH3 GPIO14 /* PD14 */ +#define GPIO_TIM4_RE_CH4 GPIO15 /* PD15 */ + +/* Timer4 BANK */ +#define GPIO_BANK_TIM4_CH1 GPIOB /* PB6 */ +#define GPIO_BANK_TIM4_CH2 GPIOB /* PB7 */ +#define GPIO_BANK_TIM4_CH3 GPIOB /* PB8 */ +#define GPIO_BANK_TIM4_CH4 GPIOB /* PB9 */ +#define GPIO_BANK_TIM4 GPIOB + +#define GPIO_BANK_TIM4_RE_CH1 GPIOD /* PD12 */ +#define GPIO_BANK_TIM4_RE_CH2 GPIOD /* PD13 */ +#define GPIO_BANK_TIM4_RE_CH3 GPIOD /* PD14 */ +#define GPIO_BANK_TIM4_RE_CH4 GPIOD /* PD15 */ +#define GPIO_BANK_TIM4_RE GPIOD + +/* Timer3 GPIO */ +#define GPIO_TIM3_CH1 GPIO6 /* PA6 */ +#define GPIO_TIM3_CH2 GPIO7 /* PA7 */ +#define GPIO_TIM3_CH3 GPIO0 /* PB0 */ +#define GPIO_TIM3_CH4 GPIO1 /* PB1 */ + +#define GPIO_TIM3_PR_CH1 GPIO4 /* PB4 */ +#define GPIO_TIM3_PR_CH2 GPIO5 /* PB5 */ +#define GPIO_TIM3_PR_CH3 GPIO0 /* PB0 */ +#define GPIO_TIM3_PR_CH4 GPIO1 /* PB1 */ + +#define GPIO_TIM3_FR_CH1 GPIO6 /* PC6 */ +#define GPIO_TIM3_FR_CH2 GPIO7 /* PC7 */ +#define GPIO_TIM3_FR_CH3 GPIO8 /* PC8 */ +#define GPIO_TIM3_FR_CH4 GPIO9 /* PC9 */ + +/* Timer3 BANK */ +#define GPIO_BANK_TIM3_CH1 GPIOA /* PA6 */ +#define GPIO_BANK_TIM3_CH2 GPIOA /* PA7 */ +#define GPIO_BANK_TIM3_CH3 GPIOB /* PB0 */ +#define GPIO_BANK_TIM3_CH4 GPIOB /* PB1 */ +#define GPIO_BANK_TIM3_CH12 GPIOA +#define GPIO_BANK_TIM3_CH34 GPIOB + +#define GPIO_BANK_TIM3_PR_CH1 GPIOB /* PB4 */ +#define GPIO_BANK_TIM3_PR_CH2 GPIOB /* PB5 */ +#define GPIO_BANK_TIM3_PR_CH3 GPIOB /* PB0 */ +#define GPIO_BANK_TIM3_PR_CH4 GPIOB /* PB1 */ +#define GPIO_BANK_TIM3_PR GPIOB + +#define GPIO_BANK_TIM3_FR_CH1 GPIOC /* PC6 */ +#define GPIO_BANK_TIM3_FR_CH2 GPIOC /* PC7 */ +#define GPIO_BANK_TIM3_FR_CH3 GPIOC /* PC8 */ +#define GPIO_BANK_TIM3_FR_CH4 GPIOC /* PC9 */ +#define GPIO_BANK_TIM3_FR GPIOC + +/* Timer2 GPIO */ +#define GPIO_TIM2_CH1_ETR GPIO0 /* PA0 */ +#define GPIO_TIM2_CH2 GPIO1 /* PA1 */ +#define GPIO_TIM2_CH3 GPIO2 /* PA2 */ +#define GPIO_TIM2_CH4 GPIO3 /* PA3 */ + +#define GPIO_TIM2_PR1_CH1_ETR GPIO15 /* PA15 */ +#define GPIO_TIM2_PR1_CH2 GPIO3 /* PB3 */ +#define GPIO_TIM2_PR1_CH3 GPIO2 /* PA2 */ +#define GPIO_TIM2_PR1_CH4 GPIO3 /* PA3 */ + +#define GPIO_TIM2_PR2_CH1_ETR GPIO0 /* PA0 */ +#define GPIO_TIM2_PR2_CH2 GPIO1 /* PA1 */ +#define GPIO_TIM2_PR2_CH3 GPIO10 /* PB10 */ +#define GPIO_TIM2_PR2_CH4 GPIO11 /* PB11 */ + +#define GPIO_TIM2_FR_CH1_ETR GPIO15 /* PA15 */ +#define GPIO_TIM2_FR_CH2 GPIO3 /* PB3 */ +#define GPIO_TIM2_FR_CH3 GPIO10 /* PB10 */ +#define GPIO_TIM2_FR_CH4 GPIO11 /* PB11 */ + +/* Timer2 BANK */ +#define GPIO_BANK_TIM2_CH1_ETR GPIOA /* PA0 */ +#define GPIO_BANK_TIM2_CH2 GPIOA /* PA1 */ +#define GPIO_BANK_TIM2_CH3 GPIOA /* PA2 */ +#define GPIO_BANK_TIM2_CH4 GPIOA /* PA3 */ +#define GPIO_BANK_TIM2 GPIOA + +#define GPIO_BANK_TIM2_PR1_CH1_ETR GPIOA /* PA15 */ +#define GPIO_BANK_TIM2_PR1_CH2 GPIOB /* PB3 */ +#define GPIO_BANK_TIM2_PR1_CH3 GPIOA /* PA2 */ +#define GPIO_BANK_TIM2_PR1_CH4 GPIOA /* PA3 */ +#define GPIO_BANK_TIM2_PR1_CH134 GPIOA + +#define GPIO_BANK_TIM2_PR2_CH1_ETR GPIOA /* PA0 */ +#define GPIO_BANK_TIM2_PR2_CH2 GPIOA /* PA1 */ +#define GPIO_BANK_TIM2_PR2_CH3 GPIOB /* PB10 */ +#define GPIO_BANK_TIM2_PR2_CH4 GPIOB /* PB11 */ +#define GPIO_BANK_TIM2_PR2_CH12 GPIOA +#define GPIO_BANK_TIM2_PR2_CH34 GPIOB + +#define GPIO_BANK_TIM2_FR_CH1_ETR GPIOA /* PA15 */ +#define GPIO_BANK_TIM2_FR_CH2 GPIOB /* PB3 */ +#define GPIO_BANK_TIM2_FR_CH3 GPIOB /* PB10 */ +#define GPIO_BANK_TIM2_FR_CH4 GPIOB /* PB11 */ +#define GPIO_BANK_TIM2_FR_CH234 GPIOB + +/* Timer1 GPIO */ +#define GPIO_TIM1_ETR GPIO12 /* PA12 */ +#define GPIO_TIM1_CH1 GPIO8 /* PA8 */ +#define GPIO_TIM1_CH2 GPIO9 /* PA9 */ +#define GPIO_TIM1_CH3 GPIO10 /* PA10 */ +#define GPIO_TIM1_CH4 GPIO11 /* PA11 */ +#define GPIO_TIM1_BKIN GPIO12 /* PB12 */ +#define GPIO_TIM1_CH1N GPIO13 /* PB13 */ +#define GPIO_TIM1_CH2N GPIO14 /* PB14 */ +#define GPIO_TIM1_CH3N GPIO15 /* PB15 */ + +#define GPIO_TIM1_PR_ETR GPIO12 /* PA12 */ +#define GPIO_TIM1_PR_CH1 GPIO8 /* PA8 */ +#define GPIO_TIM1_PR_CH2 GPIO9 /* PA9 */ +#define GPIO_TIM1_PR_CH3 GPIO10 /* PA10 */ +#define GPIO_TIM1_PR_CH4 GPIO11 /* PA11 */ +#define GPIO_TIM1_PR_BKIN GPIO6 /* PA6 */ +#define GPIO_TIM1_PR_CH1N GPIO7 /* PA7 */ +#define GPIO_TIM1_PR_CH2N GPIO0 /* PB0 */ +#define GPIO_TIM1_PR_CH3N GPIO1 /* PB1 */ + +#define GPIO_TIM1_FR_ETR GPIO7 /* PE7 */ +#define GPIO_TIM1_FR_CH1 GPIO9 /* PE9 */ +#define GPIO_TIM1_FR_CH2 GPIO11 /* PE11 */ +#define GPIO_TIM1_FR_CH3 GPIO13 /* PE13 */ +#define GPIO_TIM1_FR_CH4 GPIO14 /* PE14 */ +#define GPIO_TIM1_FR_BKIN GPIO15 /* PE15 */ +#define GPIO_TIM1_FR_CH1N GPIO8 /* PE8 */ +#define GPIO_TIM1_FR_CH2N GPIO10 /* PE10 */ +#define GPIO_TIM1_FR_CH3N GPIO12 /* PE12 */ + +/* Timer1 BANK */ +#define GPIO_BANK_TIM1_ETR GPIOA /* PA12 */ +#define GPIO_BANK_TIM1_CH1 GPIOA /* PA8 */ +#define GPIO_BANK_TIM1_CH2 GPIOA /* PA9 */ +#define GPIO_BANK_TIM1_CH3 GPIOA /* PA10 */ +#define GPIO_BANK_TIM1_CH4 GPIOA /* PA11 */ +#define GPIO_BANK_TIM1_BKIN GPIOB /* PB12 */ +#define GPIO_BANK_TIM1_CH1N GPIOB /* PB13 */ +#define GPIO_BANK_TIM1_CH2N GPIOB /* PB14 */ +#define GPIO_BANK_TIM1_CH3N GPIOB /* PB15 */ +#define GPIO_BANK_TIM1_ETR_CH1234 GPIOA +#define GPIO_BANK_TIM1_BKIN_CH123N GPIOB + +#define GPIO_BANK_TIM1_PR_ETR GPIOA /* PA12 */ +#define GPIO_BANK_TIM1_PR_CH1 GPIOA /* PA8 */ +#define GPIO_BANK_TIM1_PR_CH2 GPIOA /* PA9 */ +#define GPIO_BANK_TIM1_PR_CH3 GPIOA /* PA10 */ +#define GPIO_BANK_TIM1_PR_CH4 GPIOA /* PA11 */ +#define GPIO_BANK_TIM1_PR_BKIN GPIOA /* PA6 */ +#define GPIO_BANK_TIM1_PR_CH1N GPIOA /* PA7 */ +#define GPIO_BANK_TIM1_PR_CH2N GPIOB /* PB0 */ +#define GPIO_BANK_TIM1_PR_CH3N GPIOB /* PB1 */ +#define GPIO_BANK_TIM1_PR_ETR_CH1234_BKIN_CH1N GPIOA +#define GPIO_BANK_TIM1_PR_CH23N GPIOB + +#define GPIO_BANK_TIM1_FR_ETR GPIOE /* PE7 */ +#define GPIO_BANK_TIM1_FR_CH1 GPIOE /* PE9 */ +#define GPIO_BANK_TIM1_FR_CH2 GPIOE /* PE11 */ +#define GPIO_BANK_TIM1_FR_CH3 GPIOE /* PE13 */ +#define GPIO_BANK_TIM1_FR_CH4 GPIOE /* PE14 */ +#define GPIO_BANK_TIM1_FR_BKIN GPIOE /* PE15 */ +#define GPIO_BANK_TIM1_FR_CH1N GPIOE /* PE8 */ +#define GPIO_BANK_TIM1_FR_CH2N GPIOE /* PE10 */ +#define GPIO_BANK_TIM1_FR_CH3N GPIOE /* PE12 */ +#define GPIO_BANK_TIM1_FR GPIOE + +/* UART5 GPIO */ +#define GPIO_UART5_TX GPIO12 /* PC12 */ +#define GPIO_UART5_RX GPIO2 /* PD2 */ + +/* UART5 BANK */ +#define GPIO_BANK_UART5_TX GPIOC /* PC12 */ +#define GPIO_BANK_UART5_RX GPIOD /* PD2 */ + +/* UART4 GPIO */ +#define GPIO_UART4_TX GPIO10 /* PC10 */ +#define GPIO_UART4_RX GPIO11 /* PC11 */ + +/* UART4 BANK */ +#define GPIO_BANK_UART4_TX GPIOC /* PC10 */ +#define GPIO_BANK_UART4_RX GPIOC /* PC11 */ + +/* USART3 GPIO */ +#define GPIO_USART3_TX GPIO10 /* PB10 */ +#define GPIO_USART3_RX GPIO11 /* PB11 */ +#define GPIO_USART3_CK GPIO12 /* PB12 */ +#define GPIO_USART3_CTS GPIO13 /* PB13 */ +#define GPIO_USART3_RTS GPIO14 /* PB14 */ + +#define GPIO_USART3_PR_TX GPIO10 /* PC10 */ +#define GPIO_USART3_PR_RX GPIO11 /* PC11 */ +#define GPIO_USART3_PR_CK GPIO12 /* PC12 */ +#define GPIO_USART3_PR_CTS GPIO13 /* PB13 */ +#define GPIO_USART3_PR_RTS GPIO14 /* PB14 */ + +#define GPIO_USART3_FR_TX GPIO8 /* PD8 */ +#define GPIO_USART3_FR_RX GPIO9 /* PD9 */ +#define GPIO_USART3_FR_CK GPIO10 /* PD10 */ +#define GPIO_USART3_FR_CTS GPIO11 /* PD11 */ +#define GPIO_USART3_FR_RTS GPIO12 /* PD12 */ + +/* USART3 BANK */ +#define GPIO_BANK_USART3_TX GPIOB /* PB10 */ +#define GPIO_BANK_USART3_RX GPIOB /* PB11 */ +#define GPIO_BANK_USART3_CK GPIOB /* PB12 */ +#define GPIO_BANK_USART3_CTS GPIOB /* PB13 */ +#define GPIO_BANK_USART3_RTS GPIOB /* PB14 */ + +#define GPIO_BANK_USART3_PR_TX GPIOC /* PC10 */ +#define GPIO_BANK_USART3_PR_RX GPIOC /* PC11 */ +#define GPIO_BANK_USART3_PR_CK GPIOC /* PC12 */ +#define GPIO_BANK_USART3_PR_CTS GPIOB /* PB13 */ +#define GPIO_BANK_USART3_PR_RTS GPIOB /* PB14 */ + +#define GPIO_BANK_USART3_FR_TX GPIOD /* PD8 */ +#define GPIO_BANK_USART3_FR_RX GPIOD /* PD9 */ +#define GPIO_BANK_USART3_FR_CK GPIOD /* PD10 */ +#define GPIO_BANK_USART3_FR_CTS GPIOD /* PD11 */ +#define GPIO_BANK_USART3_FR_RTS GPIOD /* PD12 */ + +/* USART2 GPIO */ +#define GPIO_USART2_CTS GPIO0 /* PA0 */ +#define GPIO_USART2_RTS GPIO1 /* PA1 */ +#define GPIO_USART2_TX GPIO2 /* PA2 */ +#define GPIO_USART2_RX GPIO3 /* PA3 */ +#define GPIO_USART2_CK GPIO4 /* PA4 */ + +#define GPIO_USART2_RE_CTS GPIO3 /* PD3 */ +#define GPIO_USART2_RE_RTS GPIO4 /* PD4 */ +#define GPIO_USART2_RE_TX GPIO5 /* PD5 */ +#define GPIO_USART2_RE_RX GPIO6 /* PD6 */ +#define GPIO_USART2_RE_CK GPIO7 /* PD7 */ + +/* USART2 BANK */ +#define GPIO_BANK_USART2_CTS GPIOA /* PA0 */ +#define GPIO_BANK_USART2_RTS GPIOA /* PA1 */ +#define GPIO_BANK_USART2_TX GPIOA /* PA2 */ +#define GPIO_BANK_USART2_RX GPIOA /* PA3 */ +#define GPIO_BANK_USART2_CK GPIOA /* PA4 */ + +#define GPIO_BANK_USART2_RE_CTS GPIOD /* PD3 */ +#define GPIO_BANK_USART2_RE_RTS GPIOD /* PD4 */ +#define GPIO_BANK_USART2_RE_TX GPIOD /* PD5 */ +#define GPIO_BANK_USART2_RE_RX GPIOD /* PD6 */ +#define GPIO_BANK_USART2_RE_CK GPIOD /* PD7 */ + +/* USART1 GPIO */ +#define GPIO_USART1_TX GPIO9 /* PA9 */ +#define GPIO_USART1_RX GPIO10 /* PA10 */ + +#define GPIO_USART1_RE_TX GPIO6 /* PB6 */ +#define GPIO_USART1_RE_RX GPIO7 /* PB7 */ + +/* USART1 BANK */ +#define GPIO_BANK_USART1_TX GPIOA /* PA9 */ +#define GPIO_BANK_USART1_RX GPIOA /* PA10 */ + +#define GPIO_BANK_USART1_RE_TX GPIOB /* PB6 */ +#define GPIO_BANK_USART1_RE_RX GPIOB /* PB7 */ + +/* I2C1 GPIO */ +#define GPIO_I2C1_SMBAI GPIO5 /* PB5 */ +#define GPIO_I2C1_SCL GPIO6 /* PB6 */ +#define GPIO_I2C1_SDA GPIO7 /* PB7 */ + +#define GPIO_I2C1_RE_SMBAI GPIO5 /* PB5 */ +#define GPIO_I2C1_RE_SCL GPIO8 /* PB8 */ +#define GPIO_I2C1_RE_SDA GPIO9 /* PB9 */ + +/* I2C1 BANK */ +#define GPIO_BANK_I2C1_SMBAI GPIOB /* PB5 */ +#define GPIO_BANK_I2C1_SCL GPIOB /* PB6 */ +#define GPIO_BANK_I2C1_SDA GPIOB /* PB7 */ + +#define GPIO_BANK_I2C1_RE_SMBAI GPIOB /* PB5 */ +#define GPIO_BANK_I2C1_RE_SCL GPIOB /* PB8 */ +#define GPIO_BANK_I2C1_RE_SDA GPIOB /* PB9 */ + +/* I2C2 GPIO */ +#define GPIO_I2C2_SCL GPIO10 /* PB10 */ +#define GPIO_I2C2_SDA GPIO11 /* PB11 */ +#define GPIO_I2C2_SMBAI GPIO12 /* PB12 */ + +/* I2C2 BANK */ +#define GPIO_BANK_I2C2_SCL GPIOB /* PB10 */ +#define GPIO_BANK_I2C2_SDA GPIOB /* PB11 */ +#define GPIO_BANK_I2C2_SMBAI GPIOB /* PB12 */ + +/* SPI1 GPIO */ +#define GPIO_SPI1_NSS GPIO4 /* PA4 */ +#define GPIO_SPI1_SCK GPIO5 /* PA5 */ +#define GPIO_SPI1_MISO GPIO6 /* PA6 */ +#define GPIO_SPI1_MOSI GPIO7 /* PA7 */ + +#define GPIO_SPI1_RE_NSS GPIO15 /* PA15 */ +#define GPIO_SPI1_RE_SCK GPIO3 /* PB3 */ +#define GPIO_SPI1_RE_MISO GPIO4 /* PB4 */ +#define GPIO_SPI1_RE_MOSI GPIO5 /* PB5 */ + +/* SPI1 BANK */ +#define GPIO_BANK_SPI1_NSS GPIOA /* PA4 */ +#define GPIO_BANK_SPI1_SCK GPIOA /* PA5 */ +#define GPIO_BANK_SPI1_MISO GPIOA /* PA6 */ +#define GPIO_BANK_SPI1_MOSI GPIOA /* PA7 */ + +#define GPIO_BANK_SPI1_RE_NSS GPIOA /* PA15 */ +#define GPIO_BANK_SPI1_RE_SCK GPIOB /* PB3 */ +#define GPIO_BANK_SPI1_RE_MISO GPIOB /* PB4 */ +#define GPIO_BANK_SPI1_RE_MOSI GPIOB /* PB5 */ + +/* SPI2 GPIO */ +#define GPIO_SPI2_NSS GPIO12 /* PB12 */ +#define GPIO_SPI2_SCK GPIO13 /* PB13 */ +#define GPIO_SPI2_MISO GPIO14 /* PB14 */ +#define GPIO_SPI2_MOSI GPIO15 /* PB15 */ + +/* SPI2 BANK */ +#define GPIO_BANK_SPI2_NSS GPIOB /* PB12 */ +#define GPIO_BANK_SPI2_SCK GPIOB /* PB13 */ +#define GPIO_BANK_SPI2_MISO GPIOB /* PB14 */ +#define GPIO_BANK_SPI2_MOSI GPIOB /* PB15 */ + +/* SPI3 GPIO */ +#define GPIO_SPI3_NSS GPIO15 /* PA15 */ +#define GPIO_SPI3_SCK GPIO3 /* PB3 */ +#define GPIO_SPI3_MISO GPIO4 /* PB4 */ +#define GPIO_SPI3_MOSI GPIO5 /* PB5 */ + +#define GPIO_SPI3_RE_NSS GPIO4 /* PA4 */ +#define GPIO_SPI3_RE_SCK GPIO10 /* PC10 */ +#define GPIO_SPI3_RE_MISO GPIO11 /* PC11 */ +#define GPIO_SPI3_RE_MOSI GPIO12 /* PC12 */ + +/* SPI3 BANK */ +#define GPIO_BANK_SPI3_NSS GPIOA /* PA15 */ +#define GPIO_BANK_SPI3_SCK GPIOB /* PB3 */ +#define GPIO_BANK_SPI3_MISO GPIOB /* PB4 */ +#define GPIO_BANK_SPI3_MOSI GPIOB /* PB5 */ + +#define GPIO_BANK_SPI3_RE_NSS GPIOA /* PA4 */ +#define GPIO_BANK_SPI3_RE_SCK GPIOC /* PC10 */ +#define GPIO_BANK_SPI3_RE_MISO GPIOC /* PC11 */ +#define GPIO_BANK_SPI3_RE_MOSI GPIOC /* PC12 */ + +/* ETH GPIO */ +#define GPIO_ETH_RX_DV_CRS_DV GPIO7 /* PA7 */ +#define GPIO_ETH_RXD0 GPIO4 /* PC4 */ +#define GPIO_ETH_RXD1 GPIO5 /* PC5 */ +#define GPIO_ETH_RXD2 GPIO0 /* PB0 */ +#define GPIO_ETH_RXD3 GPIO1 /* PB1 */ + +#define GPIO_ETH_RE_RX_DV_CRS_DV GPIO8 /* PD8 */ +#define GPIO_ETH_RE_RXD0 GPIO9 /* PD9 */ +#define GPIO_ETH_RE_RXD1 GPIO10 /* PD10 */ +#define GPIO_ETH_RE_RXD2 GPIO11 /* PD11 */ +#define GPIO_ETH_RE_RXD3 GPIO12 /* PD12 */ + +/* ETH BANK */ +#define GPIO_BANK_ETH_RX_DV_CRS_DV GPIOA /* PA7 */ +#define GPIO_BANK_ETH_RXD0 GPIOC /* PC4 */ +#define GPIO_BANK_ETH_RXD1 GPIOC /* PC5 */ +#define GPIO_BANK_ETH_RXD2 GPIOB /* PB0 */ +#define GPIO_BANK_ETH_RXD3 GPIOB /* PB1 */ + +#define GPIO_BANK_ETH_RE_RX_DV_CRS_DV GPIOD /* PD8 */ +#define GPIO_BANK_ETH_RE_RXD0 GPIOD /* PD9 */ +#define GPIO_BANK_ETH_RE_RXD1 GPIOD /* PD10 */ +#define GPIO_BANK_ETH_RE_RXD2 GPIOD /* PD11 */ +#define GPIO_BANK_ETH_RE_RXD3 GPIOD /* PD12 */ + +/* --- GPIO registers ------------------------------------------------------ */ + +/* Port configuration register low (GPIOx_CRL) */ +#define GPIO_CRL(port) MMIO32((port) + 0x00) +#define GPIOA_CRL GPIO_CRL(GPIOA) +#define GPIOB_CRL GPIO_CRL(GPIOB) +#define GPIOC_CRL GPIO_CRL(GPIOC) +#define GPIOD_CRL GPIO_CRL(GPIOD) +#define GPIOE_CRL GPIO_CRL(GPIOE) +#define GPIOF_CRL GPIO_CRL(GPIOF) +#define GPIOG_CRL GPIO_CRL(GPIOG) + +/* Port configuration register low (GPIOx_CRH) */ +#define GPIO_CRH(port) MMIO32((port) + 0x04) +#define GPIOA_CRH GPIO_CRH(GPIOA) +#define GPIOB_CRH GPIO_CRH(GPIOB) +#define GPIOC_CRH GPIO_CRH(GPIOC) +#define GPIOD_CRH GPIO_CRH(GPIOD) +#define GPIOE_CRH GPIO_CRH(GPIOE) +#define GPIOF_CRH GPIO_CRH(GPIOF) +#define GPIOG_CRH GPIO_CRH(GPIOG) + +/* Port input data register (GPIOx_IDR) */ +#define GPIO_IDR(port) MMIO32((port) + 0x08) +#define GPIOA_IDR GPIO_IDR(GPIOA) +#define GPIOB_IDR GPIO_IDR(GPIOB) +#define GPIOC_IDR GPIO_IDR(GPIOC) +#define GPIOD_IDR GPIO_IDR(GPIOD) +#define GPIOE_IDR GPIO_IDR(GPIOE) +#define GPIOF_IDR GPIO_IDR(GPIOF) +#define GPIOG_IDR GPIO_IDR(GPIOG) + +/* Port output data register (GPIOx_ODR) */ +#define GPIO_ODR(port) MMIO32((port) + 0x0c) +#define GPIOA_ODR GPIO_ODR(GPIOA) +#define GPIOB_ODR GPIO_ODR(GPIOB) +#define GPIOC_ODR GPIO_ODR(GPIOC) +#define GPIOD_ODR GPIO_ODR(GPIOD) +#define GPIOE_ODR GPIO_ODR(GPIOE) +#define GPIOF_ODR GPIO_ODR(GPIOF) +#define GPIOG_ODR GPIO_ODR(GPIOG) + +/* Port bit set/reset register (GPIOx_BSRR) */ +#define GPIO_BSRR(port) MMIO32((port) + 0x10) +#define GPIOA_BSRR GPIO_BSRR(GPIOA) +#define GPIOB_BSRR GPIO_BSRR(GPIOB) +#define GPIOC_BSRR GPIO_BSRR(GPIOC) +#define GPIOD_BSRR GPIO_BSRR(GPIOD) +#define GPIOE_BSRR GPIO_BSRR(GPIOE) +#define GPIOF_BSRR GPIO_BSRR(GPIOF) +#define GPIOG_BSRR GPIO_BSRR(GPIOG) + +/* Port bit reset register (GPIOx_BRR) */ +#define GPIO_BRR(port) MMIO16((port) + 0x14) +#define GPIOA_BRR GPIO_BRR(GPIOA) +#define GPIOB_BRR GPIO_BRR(GPIOB) +#define GPIOC_BRR GPIO_BRR(GPIOC) +#define GPIOD_BRR GPIO_BRR(GPIOD) +#define GPIOE_BRR GPIO_BRR(GPIOE) +#define GPIOF_BRR GPIO_BRR(GPIOF) +#define GPIOG_BRR GPIO_BRR(GPIOG) + +/* Port configuration lock register (GPIOx_LCKR) */ +#define GPIO_LCKR(port) MMIO32((port) + 0x18) +#define GPIOA_LCKR GPIO_LCKR(GPIOA) +#define GPIOB_LCKR GPIO_LCKR(GPIOB) +#define GPIOC_LCKR GPIO_LCKR(GPIOC) +#define GPIOD_LCKR GPIO_LCKR(GPIOD) +#define GPIOE_LCKR GPIO_LCKR(GPIOE) +#define GPIOF_LCKR GPIO_LCKR(GPIOF) +#define GPIOG_LCKR GPIO_LCKR(GPIOG) + +/* --- GPIO_CRL/GPIO_CRH values -------------------------------------------- */ + +/** @defgroup gpio_cnf GPIO Pin Configuration +@ingroup gpio_defines +If mode specifies input, configuration can be +@li Analog input +@li Floating input +@li Pull up/down input + +If mode specifies output, configuration can be +@li Digital push-pull +@li Digital open drain +@li Alternate function push-pull or analog output +@li Alternate function open drain or analog output +@{*/ +/* CNF[1:0] values when MODE[1:0] is 00 (input mode) */ +/** Analog Input */ +#define GPIO_CNF_INPUT_ANALOG 0x00 +/** Digital Input Floating */ +#define GPIO_CNF_INPUT_FLOAT 0x01 /* Default */ +/** Digital Input Pull Up and Down */ +#define GPIO_CNF_INPUT_PULL_UPDOWN 0x02 +/* CNF[1:0] values when MODE[1:0] is != 00 (one of the output modes) */ +/** Digital Output Pushpull */ +#define GPIO_CNF_OUTPUT_PUSHPULL 0x00 +/** Digital Output Open Drain */ +#define GPIO_CNF_OUTPUT_OPENDRAIN 0x01 +/** Alternate Function Output Pushpull */ +#define GPIO_CNF_OUTPUT_ALTFN_PUSHPULL 0x02 +/** Alternate Function Output Open Drain */ +#define GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN 0x03 +/**@}*/ + +/* Pin mode (MODE[1:0]) values */ +/** @defgroup gpio_mode GPIO Pin Mode +@ingroup gpio_defines +@li Input (default after reset) +@li Output mode at 10 MHz maximum speed +@li Output mode at 2 MHz maximum speed +@li Output mode at 50 MHz maximum speed +@{*/ +#define GPIO_MODE_INPUT 0x00 /* Default */ +#define GPIO_MODE_OUTPUT_10_MHZ 0x01 +#define GPIO_MODE_OUTPUT_2_MHZ 0x02 +#define GPIO_MODE_OUTPUT_50_MHZ 0x03 +/**@}*/ + +/* --- GPIO_IDR values ----------------------------------------------------- */ + +/* GPIO_IDR[15:0]: IDRy[15:0]: Port input data (y = 0..15) */ + +/* --- GPIO_ODR values ----------------------------------------------------- */ + +/* GPIO_ODR[15:0]: ODRy[15:0]: Port output data (y = 0..15) */ + +/* --- GPIO_BSRR values ---------------------------------------------------- */ + +/* GPIO_BSRR[31:16]: BRy: Port x reset bit y (y = 0..15) */ +/* GPIO_BSRR[15:0]: BSy: Port x set bit y (y = 0..15) */ + +/* --- GPIO_BRR values ----------------------------------------------------- */ + +/* GPIO_BRR[15:0]: BRy: Port x reset bit y (y = 0..15) */ + +/* --- AFIO registers ------------------------------------------------------ */ + +/* Event control register (AFIO_EVCR) */ +#define AFIO_EVCR MMIO32(AFIO_BASE + 0x00) + +/* AF remap and debug I/O configuration register (AFIO_MAPR) */ +#define AFIO_MAPR MMIO32(AFIO_BASE + 0x04) + +/* External interrupt configuration register [0..3] (AFIO_EXTICR[1..4])*/ +#define AFIO_EXTICR(i) MMIO32(AFIO_BASE + 0x08 + (i)*4) +#define AFIO_EXTICR1 AFIO_EXTICR(0) +#define AFIO_EXTICR2 AFIO_EXTICR(1) +#define AFIO_EXTICR3 AFIO_EXTICR(2) +#define AFIO_EXTICR4 AFIO_EXTICR(3) + +/* AF remap and debug I/O configuration register (AFIO_MAPR) */ +#define AFIO_MAPR2 MMIO32(AFIO_BASE + 0x1C) + +/* --- AFIO_EVCR values ---------------------------------------------------- */ + +/* EVOE: Event output enable */ +#define AFIO_EVCR_EVOE (1 << 7) + +/* PORT[2:0]: Port selection */ +/** @defgroup afio_evcr_port EVENTOUT Port selection +@ingroup gpio_defines + +@{*/ +#define AFIO_EVCR_PORT_PA (0x0 << 4) +#define AFIO_EVCR_PORT_PB (0x1 << 4) +#define AFIO_EVCR_PORT_PC (0x2 << 4) +#define AFIO_EVCR_PORT_PD (0x3 << 4) +#define AFIO_EVCR_PORT_PE (0x4 << 4) +/**@}*/ + +/* PIN[3:0]: Pin selection */ +/** @defgroup afio_evcr_pin EVENTOUT Pin selection +@ingroup gpio_defines + +@{*/ +#define AFIO_EVCR_PIN_Px0 (0x0 << 0) +#define AFIO_EVCR_PIN_Px1 (0x1 << 0) +#define AFIO_EVCR_PIN_Px2 (0x2 << 0) +#define AFIO_EVCR_PIN_Px3 (0x3 << 0) +#define AFIO_EVCR_PIN_Px4 (0x4 << 0) +#define AFIO_EVCR_PIN_Px5 (0x5 << 0) +#define AFIO_EVCR_PIN_Px6 (0x6 << 0) +#define AFIO_EVCR_PIN_Px7 (0x7 << 0) +#define AFIO_EVCR_PIN_Px8 (0x8 << 0) +#define AFIO_EVCR_PIN_Px9 (0x9 << 0) +#define AFIO_EVCR_PIN_Px10 (0xA << 0) +#define AFIO_EVCR_PIN_Px11 (0xB << 0) +#define AFIO_EVCR_PIN_Px12 (0xC << 0) +#define AFIO_EVCR_PIN_Px13 (0xD << 0) +#define AFIO_EVCR_PIN_Px14 (0xE << 0) +#define AFIO_EVCR_PIN_Px15 (0xF << 0) +/**@}*/ + +/* --- AFIO_MAPR values ---------------------------------------------------- */ + +/* 31 reserved */ + +/** @defgroup afio_remap_cld Alternate Function Remap Controls for Connectivity +Line Devices only +@ingroup gpio_defines + +@{*/ +/* PTP_PPS_REMAP: */ +/** Ethernet PTP PPS remapping (only connectivity line devices) */ +#define AFIO_MAPR_PTP_PPS_REMAP (1 << 30) + +/* TIM2ITR1_IREMAP: */ +/** TIM2 internal trigger 1 remapping (only connectivity line devices) */ +#define AFIO_MAPR_TIM2ITR1_IREMAP (1 << 29) + +/* SPI3_REMAP: */ +/** SPI3/I2S3 remapping (only connectivity line devices) */ +#define AFIO_MAPR_SPI3_REMAP (1 << 28) + +/* MII_REMAP: */ +/** MII or RMII selection (only connectivity line devices) */ +#define AFIO_MAPR_MII_RMII_SEL (1 << 23) + +/* CAN2_REMAP: */ +/** CAN2 I/O remapping (only connectivity line devices) */ +#define AFIO_MAPR_CAN2_REMAP (1 << 22) + +/* ETH_REMAP: */ +/** Ethernet MAC I/O remapping (only connectivity line devices) */ +#define AFIO_MAPR_ETH_REMAP (1 << 21) + +/**@}*/ + +/* 27 reserved */ + +/* SWJ_CFG[2:0]: Serial wire JTAG configuration */ +/** @defgroup afio_swj_disable Serial Wire JTAG disables +@ingroup gpio_defines + +@{*/ +#define AFIO_MAPR_SWJ_MASK (0x7 << 24) +/** Full Serial Wire JTAG capability */ +#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) +/** Full Serial Wire JTAG capability without JNTRST */ +#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST (0x1 << 24) +/** JTAG-DP disabled with SW-DP enabled */ +#define AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON (0x2 << 24) +/** JTAG-DP disabled and SW-DP disabled */ +#define AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF (0x4 << 24) +/**@}*/ + +/** @defgroup afio_remap Alternate Function Remap Controls +@ingroup gpio_defines + +@{*/ +/* ADC2_ETRGREG_REMAP: */ +/** + * ADC2 external trigger regulator conversion remapping + * (only low-, medium-, high- and XL-density devices) + */ +#define AFIO_MAPR_ADC2_ETRGREG_REMAP (1 << 20) + +/* ADC2_ETRGINJ_REMAP: */ +/** + * ADC2 external trigger injected conversion remapping + * (only low-, medium-, high- and XL-density devices) + */ +#define AFIO_MAPR_ADC2_ETRGINJ_REMAP (1 << 19) + +/* ADC1_ETRGREG_REMAP: */ +/** + * ADC1 external trigger regulator conversion remapping + * (only low-, medium-, high- and XL-density devices) + */ +#define AFIO_MAPR_ADC1_ETRGREG_REMAP (1 << 18) + +/* ADC1_ETRGINJ_REMAP: */ +/** + * ADC1 external trigger injected conversion remapping + * (only low-, medium-, high- and XL-density devices) + */ +#define AFIO_MAPR_ADC1_ETRGINJ_REMAP (1 << 17) + +/* TIM5CH4_IREMAP: */ +/** TIM5 channel 4 internal remap */ +#define AFIO_MAPR_TIM5CH4_IREMAP (1 << 16) + +/* PD01_REMAP: */ +/** Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ +#define AFIO_MAPR_PD01_REMAP (1 << 15) + +/* TIM4_REMAP: */ +/** TIM4 remapping */ +#define AFIO_MAPR_TIM4_REMAP (1 << 12) + +/* USART2_REMAP[1:0]: */ +/** USART2 remapping */ +#define AFIO_MAPR_USART2_REMAP (1 << 3) + +/* USART1_REMAP[1:0]: */ +/** USART1 remapping */ +#define AFIO_MAPR_USART1_REMAP (1 << 2) + +/* I2C1_REMAP[1:0]: */ +/** I2C1 remapping */ +#define AFIO_MAPR_I2C1_REMAP (1 << 1) + +/* SPI1_REMAP[1:0]: */ +/** SPI1 remapping */ +#define AFIO_MAPR_SPI1_REMAP (1 << 0) +/**@}*/ + +/* CAN_REMAP[1:0]: CAN1 alternate function remapping */ +/** @defgroup afio_remap_can1 Alternate Function Remap Controls for CAN 1 +@ingroup gpio_defines + +@{*/ +#define AFIO_MAPR_CAN1_REMAP_PORTA (0x0 << 13) +#define AFIO_MAPR_CAN1_REMAP_PORTB (0x2 << 13) /* Not 36pin pkg */ +#define AFIO_MAPR_CAN1_REMAP_PORTD (0x3 << 13) +/**@}*/ + +/* TIM3_REMAP[1:0]: TIM3 remapping */ +/** @defgroup afio_remap_tim3 Alternate Function Remap Controls for Timer 3 +@ingroup gpio_defines + +@{*/ +#define AFIO_MAPR_TIM3_REMAP_NO_REMAP (0x0 << 10) +#define AFIO_MAPR_TIM3_REMAP_PARTIAL_REMAP (0x2 << 10) +#define AFIO_MAPR_TIM3_REMAP_FULL_REMAP (0x3 << 10) +/**@}*/ + +/* TIM2_REMAP[1:0]: TIM2 remapping */ +/** @defgroup afio_remap_tim2 Alternate Function Remap Controls for Timer 2 +@ingroup gpio_defines + +@{*/ +#define AFIO_MAPR_TIM2_REMAP_NO_REMAP (0x0 << 8) +#define AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP1 (0x1 << 8) +#define AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP2 (0x2 << 8) +#define AFIO_MAPR_TIM2_REMAP_FULL_REMAP (0x3 << 8) +/**@}*/ + +/* TIM1_REMAP[1:0]: TIM1 remapping */ +/** @defgroup afio_remap_tim1 Alternate Function Remap Controls for Timer 1 +@ingroup gpio_defines + +@{*/ +#define AFIO_MAPR_TIM1_REMAP_NO_REMAP (0x0 << 6) +#define AFIO_MAPR_TIM1_REMAP_PARTIAL_REMAP (0x1 << 6) +#define AFIO_MAPR_TIM1_REMAP_FULL_REMAP (0x3 << 6) +/**@}*/ + +/* USART3_REMAP[1:0]: USART3 remapping */ +/** @defgroup afio_remap_usart3 Alternate Function Remap Controls for USART 3 +@ingroup gpio_defines + +@{*/ +#define AFIO_MAPR_USART3_REMAP_NO_REMAP (0x0 << 4) +#define AFIO_MAPR_USART3_REMAP_PARTIAL_REMAP (0x1 << 4) +#define AFIO_MAPR_USART3_REMAP_FULL_REMAP (0x3 << 4) +/**@}*/ + +/** @defgroup afio_remap2 Alternate Function Remap Controls Secondary Set +@ingroup gpio_defines + +@{*/ +/** various remaps, dma/dac/timer triggers (HD only) */ +#define AFIO_MAPR2_MISC_REMAP (1 << 13) + +/** TIM12_CH1 and TIM12_CH2 remapping (HD only) */ +#define AFIO_MAPR2_TIM12_REMAP (1 << 12) + +/** TIM76_DAC_DMA remap to DMA1/DMA2 */ +#define AFIO_MAPR2_TIM76_DAC_DMA_REMAPE (1 << 11) + +/* FSMC_NADV_DISCONNECT: */ +/** The NADV is disconnected from its allocated pin */ +#define AFIO_MAPR2_FSMC_NADV_DISCONNECT (1 << 10) + +/* TIM14_REMAP: */ +/** TIM14 remapping */ +#define AFIO_MAPR2_TIM14_REMAP (1 << 9) + +/* TIM13_REMAP: */ +/** TIM13 remapping */ +#define AFIO_MAPR2_TIM13_REMAP (1 << 8) + +/* TIM11_REMAP: */ +/** TIM11 remapping */ +#define AFIO_MAPR2_TIM11_REMAP (1 << 7) + +/* TIM10_REMAP: */ +/** TIM10 remapping */ +#define AFIO_MAPR2_TIM10_REMAP (1 << 6) + +/* TIM9_REMAP: */ +/** TIM9 remapping */ +#define AFIO_MAPR2_TIM9_REMAP (1 << 5) + +/** TIM1_DMA channel 1/2 remapping */ +#define AFIO_MAPR2_TIM1_DMA_REMAP (1 << 4) + +/** CEC remapping (PB8 vs PB10) */ +#define AFIO_MAPR2_CEC_REMAP (1 << 3) + +/** TIM17 remapping (PB9 vs PB7) */ +#define AFIO_MAPR2_TIM17_REMAP (1 << 2) + +/** TIM16 remapping (PB8 vs PB6) */ +#define AFIO_MAPR2_TIM16_REMAP (1 << 1) + +/** TIM15 remapping channels 1/2 */ +#define AFIO_MAPR1_TIM16_REMAP (1 << 0) + +/**@}*/ + +/* --- AFIO_EXTICR1 values ------------------------------------------------- */ +/* --- AFIO_EXTICR2 values ------------------------------------------------- */ +/* --- AFIO_EXTICR3 values ------------------------------------------------- */ +/* --- AFIO_EXTICR4 values ------------------------------------------------- */ + +/** @defgroup afio_exti Alternate Function EXTI pin number +@ingroup gpio_defines + +@{*/ + +#define AFIO_EXTI0 0 +#define AFIO_EXTI1 1 +#define AFIO_EXTI2 2 +#define AFIO_EXTI3 3 +#define AFIO_EXTI4 4 +#define AFIO_EXTI5 5 +#define AFIO_EXTI6 6 +#define AFIO_EXTI7 7 +#define AFIO_EXTI8 8 +#define AFIO_EXTI9 9 +#define AFIO_EXTI10 10 +#define AFIO_EXTI11 11 +#define AFIO_EXTI12 12 +#define AFIO_EXTI13 13 +#define AFIO_EXTI14 14 +#define AFIO_EXTI15 15 + +/**@}*/ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void gpio_set_mode(uint32_t gpioport, uint8_t mode, uint8_t cnf, + uint16_t gpios); +void gpio_set_eventout(uint8_t evoutport, uint8_t evoutpin); +void gpio_primary_remap(uint32_t swjenable, uint32_t maps); +void gpio_secondary_remap(uint32_t maps); + +END_DECLS + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/i2c.h new file mode 100644 index 00000000..f7e25f79 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/i2c.h @@ -0,0 +1,37 @@ +/** @defgroup i2c_defines I2C Defines + +@brief Defined Constants and Types for the STM32F1xx I2C + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 12 October 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/irq.json new file mode 100644 index 00000000..20bf00ca --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/irq.json @@ -0,0 +1,75 @@ +{ + "irqs": [ + "wwdg", + "pvd", + "tamper", + "rtc", + "flash", + "rcc", + "exti0", + "exti1", + "exti2", + "exti3", + "exti4", + "dma1_channel1", + "dma1_channel2", + "dma1_channel3", + "dma1_channel4", + "dma1_channel5", + "dma1_channel6", + "dma1_channel7", + "adc1_2", + "usb_hp_can_tx", + "usb_lp_can_rx0", + "can_rx1", + "can_sce", + "exti9_5", + "tim1_brk", + "tim1_up", + "tim1_trg_com", + "tim1_cc", + "tim2", + "tim3", + "tim4", + "i2c1_ev", + "i2c1_er", + "i2c2_ev", + "i2c2_er", + "spi1", + "spi2", + "usart1", + "usart2", + "usart3", + "exti15_10", + "rtc_alarm", + "usb_wakeup", + "tim8_brk", + "tim8_up", + "tim8_trg_com", + "tim8_cc", + "adc3", + "fsmc", + "sdio", + "tim5", + "spi3", + "uart4", + "uart5", + "tim6", + "tim7", + "dma2_channel1", + "dma2_channel2", + "dma2_channel3", + "dma2_channel4_5", + "dma2_channel5", + "eth", + "eth_wkup", + "can2_tx", + "can2_rx0", + "can2_rx1", + "can2_sce", + "otg_fs" + ], + "partname_humanreadable": "STM32 F1 series", + "partname_doxygen": "STM32F1", + "includeguard": "LIBOPENCM3_STM32_F1_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/iwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/iwdg.h new file mode 100644 index 00000000..cdb51154 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/iwdg.h @@ -0,0 +1,39 @@ +/** @defgroup iwdg_defines IWDG Defines + +@brief Defined Constants and Types for the STM32F1xx Independent Watchdog +Timer + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_IWDG_H +#define LIBOPENCM3_IWDG_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/memorymap.h new file mode 100644 index 00000000..cbc04f4e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/memorymap.h @@ -0,0 +1,128 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32 specific peripheral definitions ------------------------------- */ + +/* Memory map for all buses */ +#define FLASH_BASE (0x08000000U) +#define PERIPH_BASE (0x40000000U) +#define INFO_BASE (0x1ffff000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB (PERIPH_BASE + 0x18000) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define TIM12_BASE (PERIPH_BASE_APB1 + 0x1800) +#define TIM13_BASE (PERIPH_BASE_APB1 + 0x1c00) +#define TIM14_BASE (PERIPH_BASE_APB1 + 0x2000) +/* PERIPH_BASE_APB1 + 0x2400 (0x4000 2400 - 0x4000 27FF): Reserved */ +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +/* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +/* PERIPH_BASE_APB1 + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define UART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define UART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define USB_DEV_FS_BASE (PERIPH_BASE_APB1 + 0x5c00) +#define USB_PMA_BASE (PERIPH_BASE_APB1 + 0x6000) +#define USB_CAN_SRAM_BASE (PERIPH_BASE_APB1 + 0x6000) +#define BX_CAN1_BASE (PERIPH_BASE_APB1 + 0x6400) +#define BX_CAN2_BASE (PERIPH_BASE_APB1 + 0x6800) +/* PERIPH_BASE_APB1 + 0x6800 (0x4000 6800 - 0x4000 6BFF): Reserved? Typo? */ +#define BACKUP_REGS_BASE (PERIPH_BASE_APB1 + 0x6c00) +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define CEC_BASE (PERIPH_BASE_APB1 + 0x7800) +/* PERIPH_BASE_APB1 + 0x7c00 (0x4000 7c00 - 0x4000 FFFF): Reserved */ + +/* APB2 */ +#define AFIO_BASE (PERIPH_BASE_APB2 + 0x0000) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x0400) +#define GPIO_PORT_A_BASE (PERIPH_BASE_APB2 + 0x0800) +#define GPIO_PORT_B_BASE (PERIPH_BASE_APB2 + 0x0c00) +#define GPIO_PORT_C_BASE (PERIPH_BASE_APB2 + 0x1000) +#define GPIO_PORT_D_BASE (PERIPH_BASE_APB2 + 0x1400) +#define GPIO_PORT_E_BASE (PERIPH_BASE_APB2 + 0x1800) +#define GPIO_PORT_F_BASE (PERIPH_BASE_APB2 + 0x1c00) +#define GPIO_PORT_G_BASE (PERIPH_BASE_APB2 + 0x2000) +#define ADC1_BASE (PERIPH_BASE_APB2 + 0x2400) +#define ADC2_BASE (PERIPH_BASE_APB2 + 0x2800) +#define TIM1_BASE (PERIPH_BASE_APB2 + 0x2c00) +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +#define TIM8_BASE (PERIPH_BASE_APB2 + 0x3400) +#define USART1_BASE (PERIPH_BASE_APB2 + 0x3800) +#define ADC3_BASE (PERIPH_BASE_APB2 + 0x3c00) +#define TIM15_BASE (PERIPH_BASE_APB2 + 0x4000) +#define TIM16_BASE (PERIPH_BASE_APB2 + 0x4400) +#define TIM17_BASE (PERIPH_BASE_APB2 + 0x4800) +#define TIM9_BASE (PERIPH_BASE_APB2 + 0x4c00) +#define TIM10_BASE (PERIPH_BASE_APB2 + 0x5000) +#define TIM11_BASE (PERIPH_BASE_APB2 + 0x5400) +/* PERIPH_BASE_APB2 + 0x5800 (0x4001 5800 - 0x4001 7FFF): Reserved */ + +/* AHB */ +#define SDIO_BASE (PERIPH_BASE_AHB + 0x00000) +/* PERIPH_BASE_AHB + 0x0400 (0x4001 8400 - 0x4001 7FFF): Reserved */ +#define DMA1_BASE (PERIPH_BASE_AHB + 0x08000) +#define DMA2_BASE (PERIPH_BASE_AHB + 0x08400) +/* PERIPH_BASE_AHB + 0x8800 (0x4002 0800 - 0x4002 0FFF): Reserved */ +#define RCC_BASE (PERIPH_BASE_AHB + 0x09000) +/* PERIPH_BASE_AHB + 0x9400 (0x4002 1400 - 0x4002 1FFF): Reserved */ +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB + 0x0a000) +#define CRC_BASE (PERIPH_BASE_AHB + 0x0b000) +/* PERIPH_BASE_AHB + 0xb400 (0x4002 3400 - 0x4002 7FFF): Reserved */ +#define ETHERNET_BASE (PERIPH_BASE_AHB + 0x10000) +/* PERIPH_BASE_AHB + 0x18000 (0x4003 0000 - 0x4FFF FFFF): Reserved */ +#define USB_OTG_FS_BASE (PERIPH_BASE_AHB + 0xffe8000) + +/* PPIB */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* FSMC */ +#define FSMC_BASE (PERIPH_BASE + 0x60000000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x7e0) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x7e8) +/* Ignore the "reserved for future use" half of the first word */ +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 8) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/pwr.h new file mode 100644 index 00000000..27e899b6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/pwr.h @@ -0,0 +1,37 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32F1xx PWR Control + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rcc.h new file mode 100644 index 00000000..bbb23fcf --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rcc.h @@ -0,0 +1,726 @@ +/** @defgroup rcc_defines RCC Defines + * + * @brief Defined Constants and Types for the STM32F1xx Reset and Clock + * Control + * + * @ingroup STM32F1xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2009 + * Federico Ruiz-Ugalde \ + * @author @htmlonly © @endhtmlonly 2009 + * Uwe Hermann + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2009 Federico Ruiz-Ugalde + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +/* Note: Regs/bits marked (**) only exist in "connectivity line" STM32s. */ +/* Note: Regs/bits marked (XX) do NOT exist in "connectivity line" STM32s. */ + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_CFGR MMIO32(RCC_BASE + 0x04) +#define RCC_CIR MMIO32(RCC_BASE + 0x08) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x0c) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x10) +#define RCC_AHBENR MMIO32(RCC_BASE + 0x14) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x18) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x1c) +#define RCC_BDCR MMIO32(RCC_BASE + 0x20) +#define RCC_CSR MMIO32(RCC_BASE + 0x24) +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x28) /*(**)*/ +#define RCC_CFGR2 MMIO32(RCC_BASE + 0x2c) /*(**)*/ + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLL3RDY (1 << 29) /* (**) */ +#define RCC_CR_PLL3ON (1 << 28) /* (**) */ +#define RCC_CR_PLL2RDY (1 << 27) /* (**) */ +#define RCC_CR_PLL2ON (1 << 26) /* (**) */ +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +/* HSICAL: [15:8] */ +/* HSITRIM: [7:3] */ +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +#define RCC_CFGR_OTGFSPRE (1 << 22) /* Connectivity line */ +#define RCC_CFGR_USBPRE (1 << 22) /* LD,MD, HD, XL */ + +#define RCC_CFGR_PLLMUL_SHIFT 18 +#define RCC_CFGR_PLLMUL (0xF << RCC_CFGR_PLLMUL_SHIFT) + +#define RCC_CFGR_PLLXTPRE (1 << 17) +#define RCC_CFGR_PLLSRC (1 << 16) + +#define RCC_CFGR_ADCPRE_SHIFT 14 +#define RCC_CFGR_ADCPRE (3 << RCC_CFGR_ADCPRE_SHIFT) + +#define RCC_CFGR_PPRE2_SHIFT 11 +#define RCC_CFGR_PPRE2 (7 << RCC_CFGR_PPRE2_SHIFT) + +#define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE1 (7 << RCC_CFGR_PPRE1_SHIFT) + +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE (0xF << RCC_CFGR_HPRE_SHIFT) + +#define RCC_CFGR_SWS_SHIFT 2 +#define RCC_CFGR_SWS (3 << RCC_CFGR_SWS_SHIFT) + +#define RCC_CFGR_SW_SHIFT 0 +#define RCC_CFGR_SW (3 << RCC_CFGR_SW_SHIFT) + +/* MCO: Microcontroller clock output */ +/** @defgroup rcc_cfgr_co RCC_CFGR Microcontroller Clock Output Source +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_MCO_SHIFT 24 +#define RCC_CFGR_MCO_MASK 0xf +#define RCC_CFGR_MCO_NOCLK 0x0 +#define RCC_CFGR_MCO_SYSCLK 0x4 +#define RCC_CFGR_MCO_HSI 0x5 +#define RCC_CFGR_MCO_HSE 0x6 +#define RCC_CFGR_MCO_PLL_DIV2 0x7 +#define RCC_CFGR_MCO_PLL2 0x8 /* (**) */ +#define RCC_CFGR_MCO_PLL3_DIV2 0x9 /* (**) */ +#define RCC_CFGR_MCO_XT1 0xa /* (**) */ +#define RCC_CFGR_MCO_PLL3 0xb /* (**) */ +/**@}*/ + +/* USBPRE: USB prescaler (RCC_CFGR[22]) */ +/** @defgroup rcc_cfgr_usbpre RCC_CFGR USB prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_USBPRE_PLL_CLK_DIV1_5 0x0 +#define RCC_CFGR_USBPRE_PLL_CLK_NODIV 0x1 +/**@}*/ + +/* OTGFSPRE: USB OTG FS prescaler (RCC_CFGR[22]; only in conn. line STM32s) */ +#define RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3 0x0 +#define RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV2 0x1 + +/* PLLMUL: PLL multiplication factor */ +/** @defgroup rcc_cfgr_pmf RCC_CFGR PLL Multiplication Factor +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL2 0x0 /* (XX) */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL3 0x1 /* (XX) */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL4 0x2 +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL5 0x3 +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL6 0x4 +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL7 0x5 +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL8 0x6 +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL9 0x7 +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL10 0x8 /* (XX) */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL11 0x9 /* (XX) */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL12 0xa /* (XX) */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL13 0xb /* (XX) */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL14 0xc /* (XX) */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL15 0xd /* 0xd: PLL x 15 */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL6_5 0xd /* 0xd: PLL x 6.5 for conn. + line */ +#define RCC_CFGR_PLLMUL_PLL_CLK_MUL16 0xe /* (XX) */ +/* #define PLLMUL_PLL_CLK_MUL16 0xf */ /* (XX) */ /* Errata? 17? */ +/**@}*/ + +/* TODO: conn. line differs. */ +/* PLLXTPRE: HSE divider for PLL entry */ +/** @defgroup rcc_cfgr_hsepre RCC_CFGR HSE Divider for PLL +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_PLLXTPRE_HSE_CLK 0x0 +#define RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2 0x1 +/**@}*/ + +/* PLLSRC: PLL entry clock source */ +/** @defgroup rcc_cfgr_pcs RCC_CFGR PLL Clock Source +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_PLLSRC_HSI_CLK_DIV2 0x0 +#define RCC_CFGR_PLLSRC_HSE_CLK 0x1 +#define RCC_CFGR_PLLSRC_PREDIV1_CLK 0x1 /* On conn. line */ +/**@}*/ + +/* ADCPRE: ADC prescaler */ +/****************************************************************************/ +/** @defgroup rcc_cfgr_adcpre RCC ADC clock prescaler enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_ADCPRE_PCLK2_DIV2 0x0 +#define RCC_CFGR_ADCPRE_PCLK2_DIV4 0x1 +#define RCC_CFGR_ADCPRE_PCLK2_DIV6 0x2 +#define RCC_CFGR_ADCPRE_PCLK2_DIV8 0x3 +/**@}*/ + +/* PPRE2: APB high-speed prescaler (APB2) */ +/** @defgroup rcc_cfgr_apb2pre RCC_CFGR APB2 prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_PPRE2_HCLK_NODIV 0x0 +#define RCC_CFGR_PPRE2_HCLK_DIV2 0x4 +#define RCC_CFGR_PPRE2_HCLK_DIV4 0x5 +#define RCC_CFGR_PPRE2_HCLK_DIV8 0x6 +#define RCC_CFGR_PPRE2_HCLK_DIV16 0x7 +/**@}*/ + +/* PPRE1: APB low-speed prescaler (APB1) */ +/** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB1 prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_PPRE1_HCLK_NODIV 0x0 +#define RCC_CFGR_PPRE1_HCLK_DIV2 0x4 +#define RCC_CFGR_PPRE1_HCLK_DIV4 0x5 +#define RCC_CFGR_PPRE1_HCLK_DIV8 0x6 +#define RCC_CFGR_PPRE1_HCLK_DIV16 0x7 +/**@}*/ + +/* HPRE: AHB prescaler */ +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_HPRE_SYSCLK_NODIV 0x0 +#define RCC_CFGR_HPRE_SYSCLK_DIV2 0x8 +#define RCC_CFGR_HPRE_SYSCLK_DIV4 0x9 +#define RCC_CFGR_HPRE_SYSCLK_DIV8 0xa +#define RCC_CFGR_HPRE_SYSCLK_DIV16 0xb +#define RCC_CFGR_HPRE_SYSCLK_DIV64 0xc +#define RCC_CFGR_HPRE_SYSCLK_DIV128 0xd +#define RCC_CFGR_HPRE_SYSCLK_DIV256 0xe +#define RCC_CFGR_HPRE_SYSCLK_DIV512 0xf +/**@}*/ + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_SYSCLKSEL_HSICLK 0x0 +#define RCC_CFGR_SWS_SYSCLKSEL_HSECLK 0x1 +#define RCC_CFGR_SWS_SYSCLKSEL_PLLCLK 0x2 + +/* SW: System clock switch */ +/** @defgroup rcc_cfgr_scs RCC_CFGR System Clock Selection +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_CFGR_SW_SYSCLKSEL_HSICLK 0x0 +#define RCC_CFGR_SW_SYSCLKSEL_HSECLK 0x1 +#define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x2 +/**@}*/ + +/* --- RCC_CIR values ------------------------------------------------------ */ + +/* Clock security system interrupt clear bit */ +#define RCC_CIR_CSSC (1 << 23) + +/* OSC ready interrupt clear bits */ +#define RCC_CIR_PLL3RDYC (1 << 22) /* (**) */ +#define RCC_CIR_PLL2RDYC (1 << 21) /* (**) */ +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) + +/* OSC ready interrupt enable bits */ +#define RCC_CIR_PLL3RDYIE (1 << 14) /* (**) */ +#define RCC_CIR_PLL2RDYIE (1 << 13) /* (**) */ +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) + +/* Clock security system interrupt flag bit */ +#define RCC_CIR_CSSF (1 << 7) + +/* OSC ready interrupt flag bits */ +#define RCC_CIR_PLL3RDYF (1 << 6) /* (**) */ +#define RCC_CIR_PLL2RDYF (1 << 5) /* (**) */ +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +/** @defgroup rcc_apb2rstr_rst RCC_APB2RSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_APB2RSTR_TIM17RST (1 << 18) +#define RCC_APB2RSTR_TIM16RST (1 << 17) +#define RCC_APB2RSTR_TIM15RST (1 << 16) +#define RCC_APB2RSTR_ADC3RST (1 << 15) /* (XX) */ +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_TIM8RST (1 << 13) /* (XX) */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_TIM1RST (1 << 11) +#define RCC_APB2RSTR_ADC2RST (1 << 10) +#define RCC_APB2RSTR_ADC1RST (1 << 9) +#define RCC_APB2RSTR_IOPGRST (1 << 8) /* (XX) */ +#define RCC_APB2RSTR_IOPFRST (1 << 7) /* (XX) */ +#define RCC_APB2RSTR_IOPERST (1 << 6) +#define RCC_APB2RSTR_IOPDRST (1 << 5) +#define RCC_APB2RSTR_IOPCRST (1 << 4) +#define RCC_APB2RSTR_IOPBRST (1 << 3) +#define RCC_APB2RSTR_IOPARST (1 << 2) +#define RCC_APB2RSTR_AFIORST (1 << 0) +/**@}*/ + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +/** @defgroup rcc_apb1rstr_rst RCC_APB1RSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_BKPRST (1 << 27) +#define RCC_APB1RSTR_CAN2RST (1 << 26) /* (**) */ +#define RCC_APB1RSTR_CAN1RST (1 << 25) /* (**) */ +#define RCC_APB1RSTR_CANRST (1 << 25) /* (XX) Alias for + CAN1RST */ +#define RCC_APB1RSTR_USBRST (1 << 23) /* (XX) */ +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_UART5RST (1 << 20) +#define RCC_APB1RSTR_UART4RST (1 << 19) +#define RCC_APB1RSTR_USART3RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI3RST (1 << 15) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM5RST (1 << 3) +#define RCC_APB1RSTR_TIM4RST (1 << 2) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) +/**@}*/ + +/* --- RCC_AHBENR values --------------------------------------------------- */ + +/** @defgroup rcc_ahbenr_en RCC_AHBENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_AHBENR_ETHMACENRX (1 << 16) +#define RCC_AHBENR_ETHMACENTX (1 << 15) +#define RCC_AHBENR_ETHMACEN (1 << 14) +#define RCC_AHBENR_OTGFSEN (1 << 12) +#define RCC_AHBENR_SDIOEN (1 << 10) +#define RCC_AHBENR_FSMCEN (1 << 8) +#define RCC_AHBENR_CRCEN (1 << 6) +#define RCC_AHBENR_FLITFEN (1 << 4) +#define RCC_AHBENR_SRAMEN (1 << 2) +#define RCC_AHBENR_DMA2EN (1 << 1) +#define RCC_AHBENR_DMA1EN (1 << 0) +/**@}*/ + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_APB2ENR_TIM17EN (1 << 18) +#define RCC_APB2ENR_TIM16EN (1 << 17) +#define RCC_APB2ENR_TIM15EN (1 << 16) +#define RCC_APB2ENR_ADC3EN (1 << 15) /* (XX) */ +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_TIM8EN (1 << 13) /* (XX) */ +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_TIM1EN (1 << 11) +#define RCC_APB2ENR_ADC2EN (1 << 10) +#define RCC_APB2ENR_ADC1EN (1 << 9) +#define RCC_APB2ENR_IOPGEN (1 << 8) /* (XX) */ +#define RCC_APB2ENR_IOPFEN (1 << 7) /* (XX) */ +#define RCC_APB2ENR_IOPEEN (1 << 6) +#define RCC_APB2ENR_IOPDEN (1 << 5) +#define RCC_APB2ENR_IOPCEN (1 << 4) +#define RCC_APB2ENR_IOPBEN (1 << 3) +#define RCC_APB2ENR_IOPAEN (1 << 2) +#define RCC_APB2ENR_AFIOEN (1 << 0) +/**@}*/ + +/* --- RCC_APB1ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_BKPEN (1 << 27) +#define RCC_APB1ENR_CAN2EN (1 << 26) /* (**) */ +#define RCC_APB1ENR_CAN1EN (1 << 25) /* (**) */ +#define RCC_APB1ENR_CANEN (1 << 25) /* (XX) Alias for + CAN1EN */ +#define RCC_APB1ENR_USBEN (1 << 23) /* (XX) */ +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_UART5EN (1 << 20) +#define RCC_APB1ENR_UART4EN (1 << 19) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI3EN (1 << 15) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM5EN (1 << 3) +#define RCC_APB1ENR_TIM4EN (1 << 2) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) +/**@}*/ + +/* --- RCC_BDCR values ----------------------------------------------------- */ + +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) +/* RCC_BDCR[9:8]: RTCSEL */ +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\ + RCC_CSR_PINRSTF) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- RCC_AHBRSTR values -------------------------------------------------- */ + +/** @defgroup rcc_ahbrstr_rst RCC_AHBRSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ +#define RCC_AHBRSTR_ETHMACRST (1 << 14) +#define RCC_AHBRSTR_OTGFSRST (1 << 12) +/**@}*/ + +/* --- RCC_CFGR2 values ---------------------------------------------------- */ + +/* I2S3SRC: I2S3 clock source */ +#define RCC_CFGR2_I2S3SRC_SYSCLK 0x0 +#define RCC_CFGR2_I2S3SRC_PLL3_VCO_CLK 0x1 + +/* I2S2SRC: I2S2 clock source */ +#define RCC_CFGR2_I2S2SRC_SYSCLK 0x0 +#define RCC_CFGR2_I2S2SRC_PLL3_VCO_CLK 0x1 +#define RCC_CFGR2_I2S2SRC (1 << 17) + +/* PREDIV1SRC: PREDIV1 entry clock source */ +#define RCC_CFGR2_PREDIV1SRC_HSE_CLK 0x0 +#define RCC_CFGR2_PREDIV1SRC_PLL2_CLK 0x1 +#define RCC_CFGR2_PREDIV1SRC (1 << 16) + +#define RCC_CFGR2_PLL3MUL_SHIFT 12 +#define RCC_CFGR2_PLL3MUL (0xF << RCC_CFGR2_PLL3MUL_SHIFT) + +#define RCC_CFGR2_PLL2MUL_SHIFT 8 +#define RCC_CFGR2_PLL2MUL (0xF << RCC_CFGR2_PLL2MUL_SHIFT) + +#define RCC_CFGR2_PREDIV2_SHIFT 4 +#define RCC_CFGR2_PREDIV2 (0xF << RCC_CFGR2_PREDIV2_SHIFT) + +#define RCC_CFGR2_PREDIV1_SHIFT 0 +#define RCC_CFGR2_PREDIV1 (0xF << RCC_CFGR2_PREDIV1_SHIFT) + +/* PLL3MUL: PLL3 multiplication factor */ +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL8 0x6 +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL9 0x7 +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL10 0x8 +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL11 0x9 +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL12 0xa +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL13 0xb +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL14 0xc +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL16 0xe +#define RCC_CFGR2_PLL3MUL_PLL3_CLK_MUL20 0xf + +/* PLL2MUL: PLL2 multiplication factor */ +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL8 0x6 +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL9 0x7 +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL10 0x8 +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL11 0x9 +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL12 0xa +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL13 0xb +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL14 0xc +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL16 0xe +#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL20 0xf + +/* PREDIV: PREDIV division factor */ +#define RCC_CFGR2_PREDIV_NODIV 0x0 +#define RCC_CFGR2_PREDIV_DIV2 0x1 +#define RCC_CFGR2_PREDIV_DIV3 0x2 +#define RCC_CFGR2_PREDIV_DIV4 0x3 +#define RCC_CFGR2_PREDIV_DIV5 0x4 +#define RCC_CFGR2_PREDIV_DIV6 0x5 +#define RCC_CFGR2_PREDIV_DIV7 0x6 +#define RCC_CFGR2_PREDIV_DIV8 0x7 +#define RCC_CFGR2_PREDIV_DIV9 0x8 +#define RCC_CFGR2_PREDIV_DIV10 0x9 +#define RCC_CFGR2_PREDIV_DIV11 0xa +#define RCC_CFGR2_PREDIV_DIV12 0xb +#define RCC_CFGR2_PREDIV_DIV13 0xc +#define RCC_CFGR2_PREDIV_DIV14 0xd +#define RCC_CFGR2_PREDIV_DIV15 0xe +#define RCC_CFGR2_PREDIV_DIV16 0xf + +/* PREDIV2: PREDIV2 division factor */ +#define RCC_CFGR2_PREDIV2_NODIV 0x0 +#define RCC_CFGR2_PREDIV2_DIV2 0x1 +#define RCC_CFGR2_PREDIV2_DIV3 0x2 +#define RCC_CFGR2_PREDIV2_DIV4 0x3 +#define RCC_CFGR2_PREDIV2_DIV5 0x4 +#define RCC_CFGR2_PREDIV2_DIV6 0x5 +#define RCC_CFGR2_PREDIV2_DIV7 0x6 +#define RCC_CFGR2_PREDIV2_DIV8 0x7 +#define RCC_CFGR2_PREDIV2_DIV9 0x8 +#define RCC_CFGR2_PREDIV2_DIV10 0x9 +#define RCC_CFGR2_PREDIV2_DIV11 0xa +#define RCC_CFGR2_PREDIV2_DIV12 0xb +#define RCC_CFGR2_PREDIV2_DIV13 0xc +#define RCC_CFGR2_PREDIV2_DIV14 0xd +#define RCC_CFGR2_PREDIV2_DIV15 0xe +#define RCC_CFGR2_PREDIV2_DIV16 0xf + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_osc { + RCC_PLL, RCC_PLL2, RCC_PLL3, RCC_HSE, RCC_HSI, RCC_LSE, RCC_LSI +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +/* V = value line F100 + * N = standard line F101, F102, F103 + * C = communication line F105, F107 + */ +enum rcc_periph_clken { + + /* AHB peripherals */ + RCC_DMA1 = _REG_BIT(0x14, 0),/*VNC*/ + RCC_DMA2 = _REG_BIT(0x14, 1),/*VNC*/ + RCC_SRAM = _REG_BIT(0x14, 2),/*VNC*/ + RCC_FLTF = _REG_BIT(0x14, 4),/*VNC*/ + RCC_CRC = _REG_BIT(0x14, 6),/*VNC*/ + RCC_FSMC = _REG_BIT(0x14, 8),/*VN-*/ + RCC_SDIO = _REG_BIT(0x14, 10),/*-N-*/ + RCC_OTGFS = _REG_BIT(0x14, 12),/*--C*/ + RCC_ETHMAC = _REG_BIT(0x14, 14),/*--C*/ + RCC_ETHMACTX = _REG_BIT(0x14, 15),/*--C*/ + RCC_ETHMACRX = _REG_BIT(0x14, 16),/*--C*/ + + /* APB2 peripherals */ + RCC_AFIO = _REG_BIT(0x18, 0),/*VNC*/ + RCC_GPIOA = _REG_BIT(0x18, 2),/*VNC*/ + RCC_GPIOB = _REG_BIT(0x18, 3),/*VNC*/ + RCC_GPIOC = _REG_BIT(0x18, 4),/*VNC*/ + RCC_GPIOD = _REG_BIT(0x18, 5),/*VNC*/ + RCC_GPIOE = _REG_BIT(0x18, 6),/*VNC*/ + RCC_GPIOF = _REG_BIT(0x18, 7),/*VN-*/ + RCC_GPIOG = _REG_BIT(0x18, 8),/*VN-*/ + RCC_ADC1 = _REG_BIT(0x18, 9),/*VNC*/ + RCC_ADC2 = _REG_BIT(0x18, 10),/*-NC*/ + RCC_TIM1 = _REG_BIT(0x18, 11),/*VNC*/ + RCC_SPI1 = _REG_BIT(0x18, 12),/*VNC*/ + RCC_TIM8 = _REG_BIT(0x18, 13),/*-N-*/ + RCC_USART1 = _REG_BIT(0x18, 14),/*VNC*/ + RCC_ADC3 = _REG_BIT(0x18, 15),/*-N-*/ + RCC_TIM15 = _REG_BIT(0x18, 16),/*V--*/ + RCC_TIM16 = _REG_BIT(0x18, 17),/*V--*/ + RCC_TIM17 = _REG_BIT(0x18, 18),/*V--*/ + RCC_TIM9 = _REG_BIT(0x18, 19),/*-N-*/ + RCC_TIM10 = _REG_BIT(0x18, 20),/*-N-*/ + RCC_TIM11 = _REG_BIT(0x18, 21),/*-N-*/ + + /* APB1 peripherals */ + RCC_TIM2 = _REG_BIT(0x1C, 0),/*VNC*/ + RCC_TIM3 = _REG_BIT(0x1C, 1),/*VNC*/ + RCC_TIM4 = _REG_BIT(0x1C, 2),/*VNC*/ + RCC_TIM5 = _REG_BIT(0x1C, 3),/*VNC*/ + RCC_TIM6 = _REG_BIT(0x1C, 4),/*VNC*/ + RCC_TIM7 = _REG_BIT(0x1C, 5),/*VNC*/ + RCC_TIM12 = _REG_BIT(0x1C, 6),/*VN-*/ + RCC_TIM13 = _REG_BIT(0x1C, 7),/*VN-*/ + RCC_TIM14 = _REG_BIT(0x1C, 8),/*VN-*/ + RCC_WWDG = _REG_BIT(0x1C, 11),/*VNC*/ + RCC_SPI2 = _REG_BIT(0x1C, 14),/*VNC*/ + RCC_SPI3 = _REG_BIT(0x1C, 15),/*VNC*/ + RCC_USART2 = _REG_BIT(0x1C, 17),/*VNC*/ + RCC_USART3 = _REG_BIT(0x1C, 18),/*VNC*/ + RCC_UART4 = _REG_BIT(0x1C, 19),/*VNC*/ + RCC_UART5 = _REG_BIT(0x1C, 20),/*VNC*/ + RCC_I2C1 = _REG_BIT(0x1C, 21),/*VNC*/ + RCC_I2C2 = _REG_BIT(0x1C, 22),/*VNC*/ + RCC_USB = _REG_BIT(0x1C, 23),/*-N-*/ + RCC_CAN = _REG_BIT(0x1C, 25),/*-N-*/ + RCC_CAN1 = _REG_BIT(0x1C, 25),/*--C*/ + RCC_CAN2 = _REG_BIT(0x1C, 26),/*--C*/ + RCC_BKP = _REG_BIT(0x1C, 27),/*VNC*/ + RCC_PWR = _REG_BIT(0x1C, 28),/*VNC*/ + RCC_DAC = _REG_BIT(0x1C, 29),/*VNC*/ + RCC_CEC = _REG_BIT(0x1C, 30),/*V--*/ +}; + +enum rcc_periph_rst { + + /* AHB peripherals */ + RST_OTGFS = _REG_BIT(0x28, 12),/*--C*/ + RST_ETHMAC = _REG_BIT(0x28, 14),/*--C*/ + + /* APB2 peripherals */ + RST_AFIO = _REG_BIT(0x0c, 0),/*VNC*/ + RST_GPIOA = _REG_BIT(0x0c, 2),/*VNC*/ + RST_GPIOB = _REG_BIT(0x0c, 3),/*VNC*/ + RST_GPIOC = _REG_BIT(0x0c, 4),/*VNC*/ + RST_GPIOD = _REG_BIT(0x0c, 5),/*VNC*/ + RST_GPIOE = _REG_BIT(0x0c, 6),/*VNC*/ + RST_GPIOF = _REG_BIT(0x0c, 7),/*VN-*/ + RST_GPIOG = _REG_BIT(0x0c, 8),/*VN-*/ + RST_ADC1 = _REG_BIT(0x0c, 9),/*VNC*/ + RST_ADC2 = _REG_BIT(0x0c, 10),/*-NC*/ + RST_TIM1 = _REG_BIT(0x0c, 11),/*VNC*/ + RST_SPI1 = _REG_BIT(0x0c, 12),/*VNC*/ + RST_TIM8 = _REG_BIT(0x0c, 13),/*-N-*/ + RST_USART1 = _REG_BIT(0x0c, 14),/*VNC*/ + RST_ADC3 = _REG_BIT(0x0c, 15),/*-N-*/ + RST_TIM15 = _REG_BIT(0x0c, 16),/*V--*/ + RST_TIM16 = _REG_BIT(0x0c, 17),/*V--*/ + RST_TIM17 = _REG_BIT(0x0c, 18),/*V--*/ + RST_TIM9 = _REG_BIT(0x0c, 19),/*-N-*/ + RST_TIM10 = _REG_BIT(0x0c, 20),/*-N-*/ + RST_TIM11 = _REG_BIT(0x0c, 21),/*-N-*/ + + /* APB1 peripherals */ + RST_TIM2 = _REG_BIT(0x10, 0),/*VNC*/ + RST_TIM3 = _REG_BIT(0x10, 1),/*VNC*/ + RST_TIM4 = _REG_BIT(0x10, 2),/*VNC*/ + RST_TIM5 = _REG_BIT(0x10, 3),/*VNC*/ + RST_TIM6 = _REG_BIT(0x10, 4),/*VNC*/ + RST_TIM7 = _REG_BIT(0x10, 5),/*VNC*/ + RST_TIM12 = _REG_BIT(0x10, 6),/*VN-*/ + RST_TIM13 = _REG_BIT(0x10, 7),/*VN-*/ + RST_TIM14 = _REG_BIT(0x10, 8),/*VN-*/ + RST_WWDG = _REG_BIT(0x10, 11),/*VNC*/ + RST_SPI2 = _REG_BIT(0x10, 14),/*VNC*/ + RST_SPI3 = _REG_BIT(0x10, 15),/*VNC*/ + RST_USART2 = _REG_BIT(0x10, 17),/*VNC*/ + RST_USART3 = _REG_BIT(0x10, 18),/*VNC*/ + RST_UART4 = _REG_BIT(0x10, 19),/*VNC*/ + RST_UART5 = _REG_BIT(0x10, 20),/*VNC*/ + RST_I2C1 = _REG_BIT(0x10, 21),/*VNC*/ + RST_I2C2 = _REG_BIT(0x10, 22),/*VNC*/ + RST_USB = _REG_BIT(0x10, 23),/*-N-*/ + RST_CAN = _REG_BIT(0x10, 24),/*-N-*/ + RST_CAN1 = _REG_BIT(0x10, 24),/*--C*/ + RST_CAN2 = _REG_BIT(0x10, 25),/*--C*/ + RST_BKP = _REG_BIT(0x10, 27),/*VNC*/ + RST_PWR = _REG_BIT(0x10, 28),/*VNC*/ + RST_DAC = _REG_BIT(0x10, 29),/*VNC*/ + RST_CEC = _REG_BIT(0x10, 30),/*V--*/ +}; + +#include + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_multiplication_factor(uint32_t mul); +void rcc_set_pll2_multiplication_factor(uint32_t mul); +void rcc_set_pll3_multiplication_factor(uint32_t mul); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_pllxtpre(uint32_t pllxtpre); +uint32_t rcc_rtc_clock_enabled_flag(void); +void rcc_enable_rtc_clock(void); +void rcc_set_rtc_clock_source(enum rcc_osc clock_source); +void rcc_set_adcpre(uint32_t adcpre); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_usbpre(uint32_t usbpre); +void rcc_set_prediv1(uint32_t prediv); +void rcc_set_prediv2(uint32_t prediv); +void rcc_set_prediv1_source(uint32_t rccsrc); +uint32_t rcc_system_clock_source(void); +void rcc_clock_setup_in_hsi_out_64mhz(void); +void rcc_clock_setup_in_hsi_out_48mhz(void); +void rcc_clock_setup_in_hsi_out_24mhz(void); +void rcc_clock_setup_in_hse_8mhz_out_24mhz(void); +void rcc_clock_setup_in_hse_8mhz_out_72mhz(void); +void rcc_clock_setup_in_hse_12mhz_out_72mhz(void); +void rcc_clock_setup_in_hse_16mhz_out_72mhz(void); +void rcc_clock_setup_in_hse_25mhz_out_72mhz(void); +void rcc_backupdomain_reset(void); + +END_DECLS + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rtc.h new file mode 100644 index 00000000..242efef1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/rtc.h @@ -0,0 +1,176 @@ +/** @defgroup rtc_defines RTC Defines + * + * @brief Defined Constants and Types for the STM32F1xx Real Time Clock + * + * @ingroup STM32F1xx_defines + * + * @author @htmlonly © @endhtmlonly 2010 Uwe Hermann + * + * @version 1.0.0 + * + * @date 4 March 2013 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * The F1 RTC is a straight time stamp, a completely different peripheral to + * that found in the F2, F3, F4, L1 and F0. + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H +/**@{*/ + +#include +#include + +/* --- RTC registers ------------------------------------------------------- */ + +/* RTC control register high (RTC_CRH) */ +#define RTC_CRH MMIO32(RTC_BASE + 0x00) + +/* RTC control register low (RTC_CRL) */ +#define RTC_CRL MMIO32(RTC_BASE + 0x04) + +/* RTC prescaler load register (RTC_PRLH / RTC_PRLL) */ +#define RTC_PRLH MMIO32(RTC_BASE + 0x08) +#define RTC_PRLL MMIO32(RTC_BASE + 0x0c) + +/* RTC prescaler divider register (RTC_DIVH / RTC_DIVL) */ +#define RTC_DIVH MMIO32(RTC_BASE + 0x10) +#define RTC_DIVL MMIO32(RTC_BASE + 0x14) + +/* RTC counter register (RTC_CNTH / RTC_CNTL) */ +#define RTC_CNTH MMIO32(RTC_BASE + 0x18) +#define RTC_CNTL MMIO32(RTC_BASE + 0x1c) + +/* RTC alarm register high (RTC_ALRH / RTC_ALRL) */ +#define RTC_ALRH MMIO32(RTC_BASE + 0x20) +#define RTC_ALRL MMIO32(RTC_BASE + 0x24) + +/* --- RTC_CRH values -------------------------------------------------------*/ + +/* Note: Bits [15:3] are reserved, and forced to 0 by hardware. */ + +/* OWIE: Overflow interrupt enable */ +#define RTC_CRH_OWIE (1 << 2) + +/* ALRIE: Alarm interrupt enable */ +#define RTC_CRH_ALRIE (1 << 1) + +/* SECIE: Second interrupt enable */ +#define RTC_CRH_SECIE (1 << 0) + +/* --- RTC_CRL values -------------------------------------------------------*/ + +/* Note: Bits [15:6] are reserved, and forced to 0 by hardware. */ + +/* RTOFF: RTC operation OFF */ +#define RTC_CRL_RTOFF (1 << 5) + +/* CNF: Configuration flag */ +#define RTC_CRL_CNF (1 << 4) + +/* RSF: Registers synchronized flag */ +#define RTC_CRL_RSF (1 << 3) + +/* OWF: Overflow flag */ +#define RTC_CRL_OWF (1 << 2) + +/* ALRF: Alarm flag */ +#define RTC_CRL_ALRF (1 << 1) + +/* SECF: Second flag */ +#define RTC_CRL_SECF (1 << 0) + +/* --- RTC_PRLH values ------------------------------------------------------*/ + +/* Note: Bits [15:4] are reserved, and forced to 0 by hardware. */ + +/* TODO */ + +/* --- RTC_PRLL values ------------------------------------------------------*/ + +/* TODO */ + +/* --- RTC_DIVH values ------------------------------------------------------*/ + +/* Bits [15:4] are reserved. */ + +/* TODO */ + +/* --- RTC_DIVL values ------------------------------------------------------*/ + +/* TODO */ + +/* --- RTC_CNTH values ------------------------------------------------------*/ + +/* TODO */ + +/* --- RTC_CNTL values ------------------------------------------------------*/ + +/* TODO */ + +/* --- RTC_ALRH values ------------------------------------------------------*/ + +/* TODO */ + +/* --- RTC_ALRL values ------------------------------------------------------*/ + +/* TODO */ + +/** RTC Interrupt Flags */ +typedef enum { + /** Counter Second Flag */ + RTC_SEC, + /** Alarm Event Flag */ + RTC_ALR, + /** Counter Overflow Flag */ + RTC_OW, +} rtcflag_t; + +/* --- Function prototypes --------------------------------------------------*/ + +BEGIN_DECLS + +void rtc_awake_from_off(enum rcc_osc clock_source); +void rtc_enter_config_mode(void); +void rtc_exit_config_mode(void); +void rtc_set_alarm_time(uint32_t alarm_time); +void rtc_enable_alarm(void); +void rtc_disable_alarm(void); +void rtc_set_prescale_val(uint32_t prescale_val); +uint32_t rtc_get_counter_val(void); +uint32_t rtc_get_prescale_div_val(void); +uint32_t rtc_get_alarm_val(void); +void rtc_set_counter_val(uint32_t counter_val); +void rtc_interrupt_enable(rtcflag_t flag_val); +void rtc_interrupt_disable(rtcflag_t flag_val); +void rtc_clear_flag(rtcflag_t flag_val); +uint32_t rtc_check_flag(rtcflag_t flag_val); +void rtc_awake_from_standby(void); +void rtc_auto_awake(enum rcc_osc clock_source, uint32_t prescale_val); + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/spi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/spi.h new file mode 100644 index 00000000..8513454d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/spi.h @@ -0,0 +1,37 @@ +/** @defgroup spi_defines SPI Defines + +@brief Defined Constants and Types for the STM32F1xx SPI + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SPI_H +#define LIBOPENCM3_SPI_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/st_usbfs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/st_usbfs.h new file mode 100644 index 00000000..7da73f2a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/st_usbfs.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +# error Do not include directly ! +#else + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/timer.h new file mode 100644 index 00000000..6046d792 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/timer.h @@ -0,0 +1,56 @@ +/** @defgroup timer_defines Timer Defines + +@brief libopencm3 Defined Constants and Types for the STM32F1xx Timers + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 8 March 2013 + +@author @htmlonly © @endhtmlonly 2011 Fergus Noble + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +/** Input Capture input polarity */ +enum tim_ic_pol { + TIM_IC_RISING, + TIM_IC_FALLING, +}; + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void timer_ic_set_polarity(uint32_t timer, + enum tim_ic_id ic, + enum tim_ic_pol pol); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/usart.h new file mode 100644 index 00000000..324d78eb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f1/usart.h @@ -0,0 +1,37 @@ +/** @defgroup usart_defines USART Defines + +@brief Defined Constants and Types for the STM32F1xx USART + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_USART_H +#define LIBOPENCM3_USART_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crc.h new file mode 100644 index 00000000..45c16ba6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crc.h @@ -0,0 +1,38 @@ +/** @defgroup crc_defines CRC Defines + +@brief libopencm3 Defined Constants and Types for the STM32F2xx CRC +Generator + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crypto.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crypto.h new file mode 100644 index 00000000..02ea8b58 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/crypto.h @@ -0,0 +1,36 @@ +/** @defgroup crypto_defines CRYPTO Defines + * + * @brief Defined Constants and Types for the STM32F2xx CRYP Controller + * + * @ingroup STM32F2xx_defines + * + * @version 1.0.0 + * + * @date 17 Jun 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRYPTO_H +#define LIBOPENCM3_CRYPTO_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dac.h new file mode 100644 index 00000000..5d148a6d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dac.h @@ -0,0 +1,37 @@ +/** @defgroup dac_defines DAC Defines + +@brief Defined Constants and Types for the STM32F2xx DAC + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dma.h new file mode 100644 index 00000000..8fe846df --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/dma.h @@ -0,0 +1,37 @@ +/** @defgroup dma_defines DMA Defines + +@ingroup STM32F2xx_defines + +@brief Defined Constants and Types for the STM32F2xx DMA Controller + +@version 1.0.0 + +@date 18 October 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/doc-stm32f2.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/doc-stm32f2.h new file mode 100644 index 00000000..faa7f291 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/doc-stm32f2.h @@ -0,0 +1,33 @@ +/** @mainpage libopencm3 STM32F2 + +@version 1.0.0 + +@date 14 September 2012 + +API documentation for ST Microelectronics STM32F2 Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + + +/** @defgroup STM32F2xx STM32F2xx +Libraries for ST Microelectronics STM32F2xx series. + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F2xx_defines STM32F2xx Defines + +@brief Defined Constants and Types for the STM32F2xx series + +@version 1.0.0 + +@date 14 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/exti.h new file mode 100644 index 00000000..d21a921a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/exti.h @@ -0,0 +1,41 @@ +/** @defgroup exti_defines EXTI Defines + * + * @brief Defined Constants and Types for the STM32F2xx External Interrupts + * + * + * @ingroup STM32F2xx_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Piotr Esden-Tempski + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EXTI_H +#define LIBOPENCM3_EXTI_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/flash.h new file mode 100644 index 00000000..70668028 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/flash.h @@ -0,0 +1,37 @@ +/** @defgroup flash_defines FLASH Defines + * + * @ingroup STM32F2xx_defines + * + * @brief Defined Constants and Types for the STM32F2xx FLASH Memory + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/gpio.h new file mode 100644 index 00000000..fed93532 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/gpio.h @@ -0,0 +1,37 @@ +/** @defgroup gpio_defines GPIO Defines + +@brief Defined Constants and Types for the STM32F2xx General Purpose I/O + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/hash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/hash.h new file mode 100644 index 00000000..9f9cea96 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/hash.h @@ -0,0 +1,36 @@ +/** @defgroup hash_defines HASH Defines + +@ingroup STM32F2xx_defines + +@brief Defined Constants and Types for the STM32F2xx HASH Controller + +@version 1.0.0 + +@date 31 May 2013 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_HASH_H +#define LIBOPENCM3_HASH_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/i2c.h new file mode 100644 index 00000000..9c8afc94 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/i2c.h @@ -0,0 +1,43 @@ +/** @defgroup i2c_defines I2C Defines + +@brief Defined Constants and Types for the STM32F2xx I2C + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 12 October 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +/**@{*/ + +#define I2C3 I2C3_BASE + +/**@}*/ + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/irq.json new file mode 100644 index 00000000..ec596748 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/irq.json @@ -0,0 +1,88 @@ +{ + "irqs": [ + "nvic_wwdg", + "pvd", + "tamp_stamp", + "rtc_wkup", + "flash", + "rcc", + "exti0", + "exti1", + "exti2", + "exti3", + "exti4", + "dma1_stream0", + "dma1_stream1", + "dma1_stream2", + "dma1_stream3", + "dma1_stream4", + "dma1_stream5", + "dma1_stream6", + "adc", + "can1_tx", + "can1_rx0", + "can1_rx1", + "can1_sce", + "exti9_5", + "tim1_brk_tim9", + "tim1_up_tim10", + "tim1_trg_com_tim11", + "tim1_cc", + "tim2", + "tim3", + "tim4", + "i2c1_ev", + "i2c1_er", + "i2c2_ev", + "i2c2_er", + "spi1", + "spi2", + "usart1", + "usart2", + "usart3", + "exti15_10", + "rtc_alarm", + "usb_fs_wkup", + "tim8_brk_tim12", + "tim8_up_tim13", + "tim8_trg_com_tim14", + "tim8_cc", + "dma1_stream7", + "fsmc", + "sdio", + "tim5", + "spi3", + "uart4", + "uart5", + "tim6_dac", + "tim7", + "dma2_stream0", + "dma2_stream1", + "dma2_stream2", + "dma2_stream3", + "dma2_stream4", + "eth", + "eth_wkup", + "can2_tx", + "can2_rx0", + "can2_rx1", + "can2_sce", + "otg_fs", + "dma2_stream5", + "dma2_stream6", + "dma2_stream7", + "usart6", + "i2c3_ev", + "i2c3_er", + "otg_hs_ep1_out", + "otg_hs_ep1_in", + "otg_hs_wkup", + "otg_hs", + "dcmi", + "cryp", + "hash_rng" + ], + "partname_humanreadable": "STM32 F2 series", + "partname_doxygen": "STM32F2", + "includeguard": "LIBOPENCM3_STM32_F2_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/iwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/iwdg.h new file mode 100644 index 00000000..23ccb101 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/iwdg.h @@ -0,0 +1,39 @@ +/** @defgroup iwdg_defines IWDG Defines + +@brief Defined Constants and Types for the STM32F2xx Independent Watchdog +Timer + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_IWDG_H +#define LIBOPENCM3_IWDG_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/memorymap.h new file mode 100644 index 00000000..4f47a32f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/memorymap.h @@ -0,0 +1,141 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32F20x specific peripheral definitions --------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x20000) +#define PERIPH_BASE_AHB2 (0x50000000U) +#define PERIPH_BASE_AHB3 (0x60000000U) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define TIM12_BASE (PERIPH_BASE_APB1 + 0x1800) +#define TIM13_BASE (PERIPH_BASE_APB1 + 0x1c00) +#define TIM14_BASE (PERIPH_BASE_APB1 + 0x2000) +/* PERIPH_BASE_APB1 + 0x2400 (0x4000 2400 - 0x4000 27FF): Reserved */ +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +/* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +/* PERIPH_BASE_APB1 + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define UART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define UART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define I2C3_BASE (PERIPH_BASE_APB1 + 0x5C00) +/* PERIPH_BASE_APB1 + 0x6000 (0x4000 6000 - 0x4000 63FF): Reserved */ +#define BX_CAN1_BASE (PERIPH_BASE_APB1 + 0x6400) +#define BX_CAN2_BASE (PERIPH_BASE_APB1 + 0x6800) +/* PERIPH_BASE_APB1 + 0x6C00 (0x4000 6C00 - 0x4000 6FFF): Reserved */ +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +/* PERIPH_BASE_APB1 + 0x7800 (0x4000 7800 - 0x4000 FFFF): Reserved */ + +/* APB2 */ +#define TIM1_BASE (PERIPH_BASE_APB2 + 0x0000) +#define TIM8_BASE (PERIPH_BASE_APB2 + 0x0400) +/* PERIPH_BASE_APB2 + 0x0800 (0x4001 0800 - 0x4001 0FFF): Reserved */ +#define USART1_BASE (PERIPH_BASE_APB2 + 0x1000) +#define USART6_BASE (PERIPH_BASE_APB2 + 0x1400) +/* PERIPH_BASE_APB2 + 0x1800 (0x4001 1800 - 0x4001 1FFF): Reserved */ +#define ADC1_BASE (PERIPH_BASE_APB2 + 0x2000) +#define ADC2_BASE (PERIPH_BASE_APB2 + 0x2000) +#define ADC3_BASE (PERIPH_BASE_APB2 + 0x2000) +/* PERIPH_BASE_APB2 + 0x2400 (0x4001 2400 - 0x4001 27FF): Reserved */ +#define SDIO_BASE (PERIPH_BASE_APB2 + 0x2C00) +/* PERIPH_BASE_APB2 + 0x2C00 (0x4001 2C00 - 0x4001 2FFF): Reserved */ +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +/* PERIPH_BASE_APB2 + 0x3400 (0x4001 3400 - 0x4001 37FF): Reserved */ +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x3800) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x3C00) +#define TIM9_BASE (PERIPH_BASE_APB2 + 0x4000) +#define TIM10_BASE (PERIPH_BASE_APB2 + 0x4400) +#define TIM11_BASE (PERIPH_BASE_APB2 + 0x4800) +/* PERIPH_BASE_APB2 + 0x4C00 (0x4001 4C00 - 0x4001 FFFF): Reserved */ + +/* AHB1 */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB1 + 0x0000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB1 + 0x0400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB1 + 0x0800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB1 + 0x0C00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB1 + 0x1000) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB1 + 0x1400) +#define GPIO_PORT_G_BASE (PERIPH_BASE_AHB1 + 0x1800) +#define GPIO_PORT_H_BASE (PERIPH_BASE_AHB1 + 0x1C00) +#define GPIO_PORT_I_BASE (PERIPH_BASE_AHB1 + 0x2000) +/* PERIPH_BASE_AHB1 + 0x2400 (0x4002 2400 - 0x4002 2FFF): Reserved */ +#define CRC_BASE (PERIPH_BASE_AHB1 + 0x3000) +/* PERIPH_BASE_AHB1 + 0x3400 (0x4002 3400 - 0x4002 37FF): Reserved */ +#define RCC_BASE (PERIPH_BASE_AHB1 + 0x3800) +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x3C00) +#define BKPSRAM_BASE (PERIPH_BASE_AHB1 + 0x4000) +/* PERIPH_BASE_AHB1 + 0x5000 (0x4002 5000 - 0x4002 5FFF): Reserved */ +#define DMA1_BASE (PERIPH_BASE_AHB1 + 0x6000) +#define DMA2_BASE (PERIPH_BASE_AHB1 + 0x6400) +/* PERIPH_BASE_AHB1 + 0x6800 (0x4002 6800 - 0x4002 7FFF): Reserved */ +#define ETHERNET_BASE (PERIPH_BASE_AHB1 + 0x8000) +/* PERIPH_BASE_AHB1 + 0x9400 (0x4002 9400 - 0x4003 FFFF): Reserved */ +#define USB_OTG_HS_BASE (PERIPH_BASE_AHB1 + 0x20000) +/* PERIPH_BASE_AHB1 + 0x60000 (0x4008 0000 - 0x4FFF FFFF): Reserved */ + +/* AHB2 */ +#define USB_OTG_FS_BASE (PERIPH_BASE_AHB2 + 0x0000) +/* PERIPH_BASE_AHB2 + 0x40000 (0x5004 0000 - 0x5004 FFFF): Reserved */ +#define DCMI_BASE (PERIPH_BASE_AHB2 + 0x50000) +/* PERIPH_BASE_AHB2 + 0x50400 (0x5005 0400 - 0x5005 FFFF): Reserved */ +#define CRYP_BASE (PERIPH_BASE_AHB2 + 0x60000) +#define HASH_BASE (PERIPH_BASE_AHB2 + 0x60400) +#define RNG_BASE (PERIPH_BASE_AHB2 + 0x60800) +/* PERIPH_BASE_AHB2 + 0x61000 (0x5006 1000 - 0x5FFF FFFF): Reserved */ + +/* AHB3 */ +#define FSMC_BASE (PERIPH_BASE_AHB3 + 0x40000000) + +/* PPIB */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (0x1FFF7A22U) +#define DESIG_UNIQUE_ID_BASE (0x1FFF7A10U) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 8) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/pwr.h new file mode 100644 index 00000000..5100eeeb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/pwr.h @@ -0,0 +1,59 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32F2xx PWR Control + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 4 March 2013 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include + +/* + * This file extends the common STM32 version with definitions only + * applicable to the STM32F2 series of devices. + */ + +/* --- PWR_CR values ------------------------------------------------------- */ + +/* Bits [31:10]: Reserved, always read as 0. */ + +/* FPDS: Flash power down in stop mode */ +#define PWR_CR_FPDS (1 << 9) + +/* --- PWR_CSR values ------------------------------------------------------ */ + +/* Bits [31:10]: Reserved, always read as 0. */ + +/* BRE: Backup regulator enable */ +#define PWR_CSR_BRE (1 << 9) + +/* Bits [7:4]: Reserved, always read as 0. */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rcc.h new file mode 100644 index 00000000..37345910 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rcc.h @@ -0,0 +1,766 @@ +/** @defgroup rcc_defines RCC Defines + * + * @brief Defined Constants and Types for the STM32F2xx Reset and Clock + * Control + * + * @ingroup STM32F2xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2009 + * Federico Ruiz-Ugalde \ + * @author @htmlonly © @endhtmlonly 2009 + * Uwe Hermann + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_PLLCFGR MMIO32(RCC_BASE + 0x04) +#define RCC_CFGR MMIO32(RCC_BASE + 0x08) +#define RCC_CIR MMIO32(RCC_BASE + 0x0c) +#define RCC_AHB1RSTR MMIO32(RCC_BASE + 0x10) +#define RCC_AHB2RSTR MMIO32(RCC_BASE + 0x14) +#define RCC_AHB3RSTR MMIO32(RCC_BASE + 0x18) +/* RCC_BASE + 0x1c Reserved */ +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x20) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x24) +/* RCC_BASE + 0x28 Reserved */ +/* RCC_BASE + 0x2c Reserved */ +#define RCC_AHB1ENR MMIO32(RCC_BASE + 0x30) +#define RCC_AHB2ENR MMIO32(RCC_BASE + 0x34) +#define RCC_AHB3ENR MMIO32(RCC_BASE + 0x38) +/* RCC_BASE + 0x3c Reserved */ +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x40) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x44) +/* RCC_BASE + 0x48 Reserved */ +/* RCC_BASE + 0x4c Reserved */ +#define RCC_AHB1LPENR MMIO32(RCC_BASE + 0x50) +#define RCC_AHB2LPENR MMIO32(RCC_BASE + 0x54) +#define RCC_AHB3LPENR MMIO32(RCC_BASE + 0x58) +/* RCC_BASE + 0x5c Reserved */ +#define RCC_APB1LPENR MMIO32(RCC_BASE + 0x60) +#define RCC_APB2LPENR MMIO32(RCC_BASE + 0x64) +/* RCC_BASE + 0x68 Reserved */ +/* RCC_BASE + 0x6c Reserved */ +#define RCC_BDCR MMIO32(RCC_BASE + 0x70) +#define RCC_CSR MMIO32(RCC_BASE + 0x74) +/* RCC_BASE + 0x78 Reserved */ +/* RCC_BASE + 0x7c Reserved */ +#define RCC_SSCGR MMIO32(RCC_BASE + 0x80) +#define RCC_PLLI2SCFGR MMIO32(RCC_BASE + 0x84) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLI2SRDY (1 << 27) +#define RCC_CR_PLLI2SON (1 << 26) +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +/* HSICAL: [15:8] */ +/* HSITRIM: [7:3] */ +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +/* --- RCC_PLLCFGR values -------------------------------------------------- */ + +/* PLLQ: [27:24] */ +#define RCC_PLLCFGR_PLLQ_SHIFT 24 +#define RCC_PLLCFGR_PLLSRC (1 << 22) +/* PLLP: [17:16] */ +#define RCC_PLLCFGR_PLLP_SHIFT 16 +/* PLLN: [14:6] */ +#define RCC_PLLCFGR_PLLN_SHIFT 6 +/* PLLM: [5:0] */ +#define RCC_PLLCFGR_PLLM_SHIFT 0 + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +/* MCO2: Microcontroller clock output 2 */ +#define RCC_CFGR_MCO2_SHIFT 30 +#define RCC_CFGR_MCO2_SYSCLK 0x0 +#define RCC_CFGR_MCO2_PLLI2S 0x1 +#define RCC_CFGR_MCO2_HSE 0x2 +#define RCC_CFGR_MCO2_PLL 0x3 + +/* MCO1/2PRE: MCO Prescalers */ +#define RCC_CFGR_MCO2PRE_SHIFT 27 +#define RCC_CFGR_MCO1PRE_SHIFT 24 +#define RCC_CFGR_MCOPRE_DIV_NONE 0x0 +#define RCC_CFGR_MCOPRE_DIV_2 0x4 +#define RCC_CFGR_MCOPRE_DIV_3 0x5 +#define RCC_CFGR_MCOPRE_DIV_4 0x6 +#define RCC_CFGR_MCOPRE_DIV_5 0x7 + +/* I2SSRC: I2S clock selection */ +#define RCC_CFGR_I2SSRC (1 << 23) + +/* MCO1: Microcontroller clock output 1 */ +#define RCC_CFGR_MCO1_SHIFT 21 +#define RCC_CFGR_MCO1_MASK 0x3 +#define RCC_CFGR_MCO1_HSI 0x0 +#define RCC_CFGR_MCO1_LSE 0x1 +#define RCC_CFGR_MCO1_HSE 0x2 +#define RCC_CFGR_MCO1_PLL 0x3 +#define RCC_CFGR_MCO_SHIFT RCC_CFGR_MCO1_SHIFT +#define RCC_CFGR_MCO_MASK RCC_CFGR_MCO1_MASK + +/* RTCPRE: HSE division factor for RTC clock */ +#define RCC_CFGR_RTCPRE_SHIFT 16 +#define RCC_CFGR_RTCPRE_MASK 0x1f + +/* PPRE1/2: APB high-speed prescalers */ +#define RCC_CFGR_PPRE2_SHIFT 13 +#define RCC_CFGR_PPRE1_SHIFT 10 +#define RCC_CFGR_PPRE_DIV_NONE 0x0 +#define RCC_CFGR_PPRE_DIV_2 0x4 +#define RCC_CFGR_PPRE_DIV_4 0x5 +#define RCC_CFGR_PPRE_DIV_8 0x6 +#define RCC_CFGR_PPRE_DIV_16 0x7 + +/* HPRE: AHB high-speed prescaler */ +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_SHIFT 2 +#define RCC_CFGR_SWS_MASK 0x3 +#define RCC_CFGR_SWS_HSI 0x0 +#define RCC_CFGR_SWS_HSE 0x1 +#define RCC_CFGR_SWS_PLL 0x2 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_SHIFT 0 +#define RCC_CFGR_SW_HSI 0x0 +#define RCC_CFGR_SW_HSE 0x1 +#define RCC_CFGR_SW_PLL 0x2 + +/* --- RCC_CIR values ------------------------------------------------------ */ + +/* Clock security system interrupt clear bit */ +#define RCC_CIR_CSSC (1 << 23) + +/* OSC ready interrupt clear bits */ +#define RCC_CIR_PLLI2SRDYC (1 << 21) +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) + +/* OSC ready interrupt enable bits */ +#define RCC_CIR_PLLI2SRDYIE (1 << 13) +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) + +/* Clock security system interrupt flag bit */ +#define RCC_CIR_CSSF (1 << 7) + +/* OSC ready interrupt flag bits */ +#define RCC_CIR_PLLI2SRDYF (1 << 5) +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_AHB1RSTR values ------------------------------------------------- */ + +#define RCC_AHB1RSTR_OTGHSRST (1 << 29) +#define RCC_AHB1RSTR_ETHMACRST (1 << 25) +#define RCC_AHB1RSTR_DMA2RST (1 << 22) +#define RCC_AHB1RSTR_DMA1RST (1 << 21) +#define RCC_AHB1RSTR_CRCRST (1 << 12) +#define RCC_AHB1RSTR_IOPIRST (1 << 8) +#define RCC_AHB1RSTR_IOPHRST (1 << 7) +#define RCC_AHB1RSTR_IOPGRST (1 << 6) +#define RCC_AHB1RSTR_IOPFRST (1 << 5) +#define RCC_AHB1RSTR_IOPERST (1 << 4) +#define RCC_AHB1RSTR_IOPDRST (1 << 3) +#define RCC_AHB1RSTR_IOPCRST (1 << 2) +#define RCC_AHB1RSTR_IOPBRST (1 << 1) +#define RCC_AHB1RSTR_IOPARST (1 << 0) + +/* --- RCC_AHB2RSTR values ------------------------------------------------- */ + +#define RCC_AHB2RSTR_OTGFSRST (1 << 7) +#define RCC_AHB2RSTR_RNGRST (1 << 6) +#define RCC_AHB2RSTR_HASHRST (1 << 5) +#define RCC_AHB2RSTR_CRYPRST (1 << 4) +#define RCC_AHB2RSTR_DCMIRST (1 << 0) + +/* --- RCC_AHB3RSTR values ------------------------------------------------- */ + +#define RCC_AHB3RSTR_FSMCRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_CAN2RST (1 << 26) +#define RCC_APB1RSTR_CAN1RST (1 << 25) +#define RCC_APB1RSTR_I2C3RST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_UART5RST (1 << 20) +#define RCC_APB1RSTR_UART4RST (1 << 19) +#define RCC_APB1RSTR_USART3RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI3RST (1 << 15) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_TIM14RST (1 << 8) +#define RCC_APB1RSTR_TIM13RST (1 << 7) +#define RCC_APB1RSTR_TIM12RST (1 << 6) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM5RST (1 << 3) +#define RCC_APB1RSTR_TIM4RST (1 << 2) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_TIM11RST (1 << 18) +#define RCC_APB2RSTR_TIM10RST (1 << 17) +#define RCC_APB2RSTR_TIM9RST (1 << 16) +#define RCC_APB2RSTR_SYSCFGRST (1 << 14) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_SDIORST (1 << 11) +#define RCC_APB2RSTR_ADCRST (1 << 8) +#define RCC_APB2RSTR_USART6RST (1 << 5) +#define RCC_APB2RSTR_USART1RST (1 << 4) +#define RCC_APB2RSTR_TIM8RST (1 << 1) +#define RCC_APB2RSTR_TIM1RST (1 << 0) + +/* --- RCC_AHB1ENR values ------------------------------------------------- */ + +#define RCC_AHB1ENR_OTGHSULPIEN (1 << 30) +#define RCC_AHB1ENR_OTGHSEN (1 << 29) +#define RCC_AHB1ENR_ETHMACPTPEN (1 << 28) +#define RCC_AHB1ENR_ETHMACRXEN (1 << 27) +#define RCC_AHB1ENR_ETHMACTXEN (1 << 26) +#define RCC_AHB1ENR_ETHMACEN (1 << 25) +#define RCC_AHB1ENR_DMA2EN (1 << 22) +#define RCC_AHB1ENR_DMA1EN (1 << 21) +#define RCC_AHB1ENR_BKPSRAMEN (1 << 18) +#define RCC_AHB1ENR_CRCEN (1 << 12) +#define RCC_AHB1ENR_IOPIEN (1 << 8) +#define RCC_AHB1ENR_IOPHEN (1 << 7) +#define RCC_AHB1ENR_IOPGEN (1 << 6) +#define RCC_AHB1ENR_IOPFEN (1 << 5) +#define RCC_AHB1ENR_IOPEEN (1 << 4) +#define RCC_AHB1ENR_IOPDEN (1 << 3) +#define RCC_AHB1ENR_IOPCEN (1 << 2) +#define RCC_AHB1ENR_IOPBEN (1 << 1) +#define RCC_AHB1ENR_IOPAEN (1 << 0) + +/* --- RCC_AHB2ENR values ------------------------------------------------- */ + +#define RCC_AHB2ENR_OTGFSEN (1 << 7) +#define RCC_AHB2ENR_RNGEN (1 << 6) +#define RCC_AHB2ENR_HASHEN (1 << 5) +#define RCC_AHB2ENR_CRYPEN (1 << 4) +#define RCC_AHB2ENR_DCMIEN (1 << 0) + +/* --- RCC_AHB3ENR values ------------------------------------------------- */ + +#define RCC_AHB3ENR_FSMCEN (1 << 0) + +/* --- RCC_APB1ENR values ------------------------------------------------- */ + +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_CAN2EN (1 << 26) +#define RCC_APB1ENR_CAN1EN (1 << 25) +#define RCC_APB1ENR_I2C3EN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_UART5EN (1 << 20) +#define RCC_APB1ENR_UART4EN (1 << 19) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI3EN (1 << 15) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_TIM14EN (1 << 8) +#define RCC_APB1ENR_TIM13EN (1 << 7) +#define RCC_APB1ENR_TIM12EN (1 << 6) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM5EN (1 << 3) +#define RCC_APB1ENR_TIM4EN (1 << 2) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) + +/* --- RCC_APB2ENR values ------------------------------------------------- */ + +#define RCC_APB2ENR_TIM11EN (1 << 18) +#define RCC_APB2ENR_TIM10EN (1 << 17) +#define RCC_APB2ENR_TIM9EN (1 << 16) +#define RCC_APB2ENR_SYSCFGEN (1 << 14) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_SDIOEN (1 << 11) +#define RCC_APB2ENR_ADC3EN (1 << 10) +#define RCC_APB2ENR_ADC2EN (1 << 9) +#define RCC_APB2ENR_ADC1EN (1 << 8) +#define RCC_APB2ENR_USART6EN (1 << 5) +#define RCC_APB2ENR_USART1EN (1 << 4) +#define RCC_APB2ENR_TIM8EN (1 << 1) +#define RCC_APB2ENR_TIM1EN (1 << 0) + +/* --- RCC_AHB1LPENR values ------------------------------------------------- */ + +#define RCC_AHB1LPENR_OTGHSULPILPEN (1 << 30) +#define RCC_AHB1LPENR_OTGHSLPEN (1 << 29) +#define RCC_AHB1LPENR_ETHMACPTPLPEN (1 << 28) +#define RCC_AHB1LPENR_ETHMACRXLPEN (1 << 27) +#define RCC_AHB1LPENR_ETHMACTXLPEN (1 << 26) +#define RCC_AHB1LPENR_ETHMACLPEN (1 << 25) +#define RCC_AHB1LPENR_DMA2LPEN (1 << 22) +#define RCC_AHB1LPENR_DMA1LPEN (1 << 21) +#define RCC_AHB1LPENR_BKPSRAMLPEN (1 << 18) +#define RCC_AHB1LPENR_SRAM2LPEN (1 << 17) +#define RCC_AHB1LPENR_SRAM1LPEN (1 << 16) +#define RCC_AHB1LPENR_FLITFLPEN (1 << 15) +#define RCC_AHB1LPENR_CRCLPEN (1 << 12) +#define RCC_AHB1LPENR_IOPILPEN (1 << 8) +#define RCC_AHB1LPENR_IOPHLPEN (1 << 7) +#define RCC_AHB1LPENR_IOPGLPEN (1 << 6) +#define RCC_AHB1LPENR_IOPFLPEN (1 << 5) +#define RCC_AHB1LPENR_IOPELPEN (1 << 4) +#define RCC_AHB1LPENR_IOPDLPEN (1 << 3) +#define RCC_AHB1LPENR_IOPCLPEN (1 << 2) +#define RCC_AHB1LPENR_IOPBLPEN (1 << 1) +#define RCC_AHB1LPENR_IOPALPEN (1 << 0) + +/* --- RCC_AHB2LPENR values ------------------------------------------------- */ + +#define RCC_AHB2LPENR_OTGFSLPEN (1 << 7) +#define RCC_AHB2LPENR_RNGLPEN (1 << 6) +#define RCC_AHB2LPENR_HASHLPEN (1 << 5) +#define RCC_AHB2LPENR_CRYPLPEN (1 << 4) +#define RCC_AHB2LPENR_DCMILPEN (1 << 0) + +/* --- RCC_AHB3LPENR values ------------------------------------------------- */ + +#define RCC_AHB3LPENR_FSMCLPEN (1 << 0) + +/* --- RCC_APB1LPENR values ------------------------------------------------- */ + +#define RCC_APB1LPENR_DACLPEN (1 << 29) +#define RCC_APB1LPENR_PWRLPEN (1 << 28) +#define RCC_APB1LPENR_CAN2LPEN (1 << 26) +#define RCC_APB1LPENR_CAN1LPEN (1 << 25) +#define RCC_APB1LPENR_I2C3LPEN (1 << 23) +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) +#define RCC_APB1LPENR_UART5LPEN (1 << 20) +#define RCC_APB1LPENR_UART4LPEN (1 << 19) +#define RCC_APB1LPENR_USART3LPEN (1 << 18) +#define RCC_APB1LPENR_USART2LPEN (1 << 17) +#define RCC_APB1LPENR_SPI3LPEN (1 << 15) +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) +#define RCC_APB1LPENR_TIM14LPEN (1 << 8) +#define RCC_APB1LPENR_TIM13LPEN (1 << 7) +#define RCC_APB1LPENR_TIM12LPEN (1 << 6) +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) +#define RCC_APB1LPENR_TIM5LPEN (1 << 3) +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) + +/* --- RCC_APB2LPENR values ------------------------------------------------- */ + +#define RCC_APB2LPENR_TIM11LPEN (1 << 18) +#define RCC_APB2LPENR_TIM10LPEN (1 << 17) +#define RCC_APB2LPENR_TIM9LPEN (1 << 16) +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 14) +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) +#define RCC_APB2LPENR_SDIOLPEN (1 << 11) +#define RCC_APB2LPENR_ADC3LPEN (1 << 10) +#define RCC_APB2LPENR_ADC2LPEN (1 << 9) +#define RCC_APB2LPENR_ADC1LPEN (1 << 8) +#define RCC_APB2LPENR_USART6LPEN (1 << 5) +#define RCC_APB2LPENR_USART1LPEN (1 << 4) +#define RCC_APB2LPENR_TIM8LPEN (1 << 1) +#define RCC_APB2LPENR_TIM1LPEN (1 << 0) + +/* --- RCC_BDCR values ----------------------------------------------------- */ + +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) +/* RCC_BDCR[9:8]: RTCSEL */ +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_BORRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\ + RCC_CSR_PINRSTF | RCC_CSR_BORRSTF) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- RCC_SSCGR values ---------------------------------------------------- */ + +/* PLL spread spectrum clock generation documented in Datasheet. */ + +#define RCC_SSCGR_SSCGEN (1 << 31) +#define RCC_SSCGR_SPREADSEL (1 << 30) +/* RCC_SSCGR[27:16]: INCSTEP */ +#define RCC_SSCGR_INCSTEP_SHIFT 16 +/* RCC_SSCGR[15:0]: MODPER */ +#define RCC_SSCGR_MODPER_SHIFT 15 + +/* --- RCC_PLLI2SCFGR values ----------------------------------------------- */ + +/* RCC_PLLI2SCFGR[30:28]: PLLI2SR */ +#define RCC_PLLI2SCFGR_PLLI2SR_SHIFT 28 +/* RCC_PLLI2SCFGR[14:6]: PLLI2SN */ +#define RCC_PLLI2SCFGR_PLLI2SN_SHIFT 6 + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_clock_3v3 { + RCC_CLOCK_3V3_120MHZ, + RCC_CLOCK_3V3_END +}; + +struct rcc_clock_scale { + uint8_t pllm; + uint16_t plln; + uint8_t pllp; + uint8_t pllq; + uint32_t flash_config; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + uint32_t apb1_frequency; + uint32_t apb2_frequency; +}; + +extern const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END]; + +enum rcc_osc { + RCC_PLL, + RCC_HSE, + RCC_HSI, + RCC_LSE, + RCC_LSI +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + /* AHB1 peripherals */ + RCC_GPIOA = _REG_BIT(0x30, 0), + RCC_GPIOB = _REG_BIT(0x30, 1), + RCC_GPIOC = _REG_BIT(0x30, 2), + RCC_GPIOD = _REG_BIT(0x30, 3), + RCC_GPIOE = _REG_BIT(0x30, 4), + RCC_GPIOF = _REG_BIT(0x30, 5), + RCC_GPIOG = _REG_BIT(0x30, 6), + RCC_GPIOH = _REG_BIT(0x30, 7), + RCC_GPIOI = _REG_BIT(0x30, 8), + RCC_CRC = _REG_BIT(0x30, 12), + RCC_BKPSRAM = _REG_BIT(0x30, 18), + RCC_DMA1 = _REG_BIT(0x30, 21), + RCC_DMA2 = _REG_BIT(0x30, 22), + RCC_ETHMAC = _REG_BIT(0x30, 25), + RCC_ETHMACTX = _REG_BIT(0x30, 26), + RCC_ETHMACRX = _REG_BIT(0x30, 27), + RCC_ETHMACPTP = _REG_BIT(0x30, 28), + RCC_OTGHS = _REG_BIT(0x30, 29), + RCC_OTGHSULPI = _REG_BIT(0x30, 30), + + /* AHB2 peripherals */ + RCC_DCMI = _REG_BIT(0x34, 0), + RCC_CRYP = _REG_BIT(0x34, 4), + RCC_HASH = _REG_BIT(0x34, 5), + RCC_RNG = _REG_BIT(0x34, 6), + RCC_OTGFS = _REG_BIT(0x34, 7), + + /* AHB3 peripherals */ + RCC_FSMC = _REG_BIT(0x38, 0), + + /* APB1 peripherals */ + RCC_TIM2 = _REG_BIT(0x40, 0), + RCC_TIM3 = _REG_BIT(0x40, 1), + RCC_TIM4 = _REG_BIT(0x40, 2), + RCC_TIM5 = _REG_BIT(0x40, 3), + RCC_TIM6 = _REG_BIT(0x40, 4), + RCC_TIM7 = _REG_BIT(0x40, 5), + RCC_TIM12 = _REG_BIT(0x40, 6), + RCC_TIM13 = _REG_BIT(0x40, 7), + RCC_TIM14 = _REG_BIT(0x40, 8), + RCC_WWDG = _REG_BIT(0x40, 11), + RCC_SPI2 = _REG_BIT(0x40, 14), + RCC_SPI3 = _REG_BIT(0x40, 15), + RCC_USART2 = _REG_BIT(0x40, 17), + RCC_USART3 = _REG_BIT(0x40, 18), + RCC_UART4 = _REG_BIT(0x40, 19), + RCC_UART5 = _REG_BIT(0x40, 20), + RCC_I2C1 = _REG_BIT(0x40, 21), + RCC_I2C2 = _REG_BIT(0x40, 22), + RCC_I2C3 = _REG_BIT(0x40, 23), + RCC_CAN1 = _REG_BIT(0x40, 25), + RCC_CAN2 = _REG_BIT(0x40, 26), + RCC_PWR = _REG_BIT(0x40, 28), + RCC_DAC = _REG_BIT(0x40, 29), + + /* APB2 peripherals */ + RCC_TIM1 = _REG_BIT(0x44, 0), + RCC_TIM8 = _REG_BIT(0x44, 1), + RCC_USART1 = _REG_BIT(0x44, 4), + RCC_USART6 = _REG_BIT(0x44, 5), + RCC_ADC1 = _REG_BIT(0x44, 8), + RCC_ADC2 = _REG_BIT(0x44, 9), + RCC_ADC3 = _REG_BIT(0x44, 10), + RCC_SDIO = _REG_BIT(0x44, 11), + RCC_SPI1 = _REG_BIT(0x44, 12), + RCC_SYSCFG = _REG_BIT(0x44, 14), + RCC_TIM9 = _REG_BIT(0x44, 16), + RCC_TIM10 = _REG_BIT(0x44, 17), + RCC_TIM11 = _REG_BIT(0x44, 18), + + /* Extended peripherals */ + RCC_RTC = _REG_BIT(0x70, 15),/* BDCR[15] */ + + /* AHB1 peripherals */ + SCC_GPIOA = _REG_BIT(0x50, 0), + SCC_GPIOB = _REG_BIT(0x50, 1), + SCC_GPIOC = _REG_BIT(0x50, 2), + SCC_GPIOD = _REG_BIT(0x50, 3), + SCC_GPIOE = _REG_BIT(0x50, 4), + SCC_GPIOF = _REG_BIT(0x50, 5), + SCC_GPIOG = _REG_BIT(0x50, 6), + SCC_GPIOH = _REG_BIT(0x50, 7), + SCC_GPIOI = _REG_BIT(0x50, 8), + SCC_CRC = _REG_BIT(0x50, 12), + SCC_FLTIF = _REG_BIT(0x50, 15), + SCC_SRAM1 = _REG_BIT(0x50, 16), + SCC_SRAM2 = _REG_BIT(0x50, 17), + SCC_BKPSRAM = _REG_BIT(0x50, 18), + SCC_DMA1 = _REG_BIT(0x50, 21), + SCC_DMA2 = _REG_BIT(0x50, 22), + SCC_ETHMAC = _REG_BIT(0x50, 25), + SCC_ETHMACTX = _REG_BIT(0x50, 26), + SCC_ETHMACRX = _REG_BIT(0x50, 27), + SCC_ETHMACPTP = _REG_BIT(0x50, 28), + SCC_OTGHS = _REG_BIT(0x50, 29), + SCC_OTGHSULPI = _REG_BIT(0x50, 30), + + /* AHB2 peripherals */ + SCC_DCMI = _REG_BIT(0x54, 0), + SCC_CRYP = _REG_BIT(0x54, 4), + SCC_HASH = _REG_BIT(0x54, 5), + SCC_RNG = _REG_BIT(0x54, 6), + SCC_OTGFS = _REG_BIT(0x54, 7), + + /* AHB3 peripherals */ + SCC_FSMC = _REG_BIT(0x58, 0), + + /* APB1 peripherals */ + SCC_TIM2 = _REG_BIT(0x60, 0), + SCC_TIM3 = _REG_BIT(0x60, 1), + SCC_TIM4 = _REG_BIT(0x60, 2), + SCC_TIM5 = _REG_BIT(0x60, 3), + SCC_TIM6 = _REG_BIT(0x60, 4), + SCC_TIM7 = _REG_BIT(0x60, 5), + SCC_TIM12 = _REG_BIT(0x60, 6), + SCC_TIM13 = _REG_BIT(0x60, 7), + SCC_TIM14 = _REG_BIT(0x60, 8), + SCC_WWDG = _REG_BIT(0x60, 11), + SCC_SPI2 = _REG_BIT(0x60, 14), + SCC_SPI3 = _REG_BIT(0x60, 15), + SCC_USART2 = _REG_BIT(0x60, 17), + SCC_USART3 = _REG_BIT(0x60, 18), + SCC_UART4 = _REG_BIT(0x60, 19), + SCC_UART5 = _REG_BIT(0x60, 20), + SCC_I2C1 = _REG_BIT(0x60, 21), + SCC_I2C2 = _REG_BIT(0x60, 22), + SCC_I2C3 = _REG_BIT(0x60, 23), + SCC_CAN1 = _REG_BIT(0x60, 25), + SCC_CAN2 = _REG_BIT(0x60, 26), + SCC_PWR = _REG_BIT(0x60, 28), + SCC_DAC = _REG_BIT(0x60, 29), + + /* APB2 peripherals */ + SCC_TIM1 = _REG_BIT(0x64, 0), + SCC_TIM8 = _REG_BIT(0x64, 1), + SCC_USART1 = _REG_BIT(0x64, 4), + SCC_USART6 = _REG_BIT(0x64, 5), + SCC_ADC1 = _REG_BIT(0x64, 8), + SCC_ADC2 = _REG_BIT(0x64, 9), + SCC_ADC3 = _REG_BIT(0x64, 10), + SCC_SDIO = _REG_BIT(0x64, 11), + SCC_SPI1 = _REG_BIT(0x64, 12), + SCC_SYSCFG = _REG_BIT(0x64, 14), + SCC_TIM9 = _REG_BIT(0x64, 16), + SCC_TIM10 = _REG_BIT(0x64, 17), + SCC_TIM11 = _REG_BIT(0x64, 18), +}; + +enum rcc_periph_rst { + /* AHB1 peripherals */ + RST_GPIOA = _REG_BIT(0x10, 0), + RST_GPIOB = _REG_BIT(0x10, 1), + RST_GPIOC = _REG_BIT(0x10, 2), + RST_GPIOD = _REG_BIT(0x10, 3), + RST_GPIOE = _REG_BIT(0x10, 4), + RST_GPIOF = _REG_BIT(0x10, 5), + RST_GPIOG = _REG_BIT(0x10, 6), + RST_GPIOH = _REG_BIT(0x10, 7), + RST_GPIOI = _REG_BIT(0x10, 8), + RST_CRC = _REG_BIT(0x10, 12), + RST_DMA1 = _REG_BIT(0x10, 21), + RST_DMA2 = _REG_BIT(0x10, 22), + RST_ETHMAC = _REG_BIT(0x10, 25), + RST_OTGHS = _REG_BIT(0x10, 29), + + /* AHB2 peripherals */ + RST_DCMI = _REG_BIT(0x14, 0), + RST_CRYP = _REG_BIT(0x14, 4), + RST_HASH = _REG_BIT(0x14, 5), + RST_RNG = _REG_BIT(0x14, 6), + RST_OTGFS = _REG_BIT(0x14, 7), + + /* AHB3 peripherals */ + RST_FSMC = _REG_BIT(0x18, 0), + + /* APB1 peripherals */ + RST_TIM2 = _REG_BIT(0x20, 0), + RST_TIM3 = _REG_BIT(0x20, 1), + RST_TIM4 = _REG_BIT(0x20, 2), + RST_TIM5 = _REG_BIT(0x20, 3), + RST_TIM6 = _REG_BIT(0x20, 4), + RST_TIM7 = _REG_BIT(0x20, 5), + RST_TIM12 = _REG_BIT(0x20, 6), + RST_TIM13 = _REG_BIT(0x20, 7), + RST_TIM14 = _REG_BIT(0x20, 8), + RST_WWDG = _REG_BIT(0x20, 11), + RST_SPI2 = _REG_BIT(0x20, 14), + RST_SPI3 = _REG_BIT(0x20, 15), + RST_USART2 = _REG_BIT(0x20, 17), + RST_USART3 = _REG_BIT(0x20, 18), + RST_UART4 = _REG_BIT(0x20, 19), + RST_UART5 = _REG_BIT(0x20, 20), + RST_I2C1 = _REG_BIT(0x20, 21), + RST_I2C2 = _REG_BIT(0x20, 22), + RST_I2C3 = _REG_BIT(0x20, 23), + RST_CAN1 = _REG_BIT(0x20, 25), + RST_CAN2 = _REG_BIT(0x20, 26), + RST_PWR = _REG_BIT(0x20, 28), + RST_DAC = _REG_BIT(0x20, 29), + + /* APB2 peripherals */ + RST_TIM1 = _REG_BIT(0x24, 0), + RST_TIM8 = _REG_BIT(0x24, 1), + RST_USART1 = _REG_BIT(0x24, 4), + RST_USART6 = _REG_BIT(0x24, 5), + RST_ADC = _REG_BIT(0x24, 8), + RST_SDIO = _REG_BIT(0x24, 11), + RST_SPI1 = _REG_BIT(0x24, 12), + RST_SYSCFG = _REG_BIT(0x24, 14), + RST_TIM9 = _REG_BIT(0x24, 16), + RST_TIM10 = _REG_BIT(0x24, 17), + RST_TIM11 = _REG_BIT(0x24, 18), +}; + +#undef _REG_BIT + +#include + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_sysclk_status(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_rtcpre(uint32_t rtcpre); +void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq); +void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq); +uint32_t rcc_system_clock_source(void); +void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock); +void rcc_backupdomain_reset(void); + +END_DECLS + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rng.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rng.h new file mode 100644 index 00000000..09d014d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rng.h @@ -0,0 +1,23 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RNG_H +#define LIBOPENCM3_RNG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rtc.h new file mode 100644 index 00000000..bae06aca --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/rtc.h @@ -0,0 +1,36 @@ +/** @defgroup rtc_defines RTC Defines + +@brief Defined Constants and Types for the STM32F2xx RTC + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/spi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/spi.h new file mode 100644 index 00000000..c503eab5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/spi.h @@ -0,0 +1,37 @@ +/** @defgroup spi_defines SPI Defines + +@brief Defined Constants and Types for the STM32F2xx SPI + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SPI_H +#define LIBOPENCM3_SPI_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/syscfg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/syscfg.h new file mode 100644 index 00000000..579e6d67 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/syscfg.h @@ -0,0 +1,44 @@ +/** @defgroup syscfg_defines SYSCFG Defines + * + * @ingroup STM32F2xx_defines + * + * @brief Defined Constants and Types for the STM32F2xx Sysconfig + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#ifndef LIBOPENCM3_SYSCFG_H +#define LIBOPENCM3_SYSCFG_H + +#include + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/timer.h new file mode 100644 index 00000000..7dc6d326 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/timer.h @@ -0,0 +1,39 @@ +/** @defgroup timer_defines Timer Defines + +@brief libopencm3 Defined Constants and Types for the STM32F2xx Timers + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 8 March 2013 + +@author @htmlonly © @endhtmlonly 2011 Fergus Noble + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/usart.h new file mode 100644 index 00000000..8d4485bf --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f2/usart.h @@ -0,0 +1,37 @@ +/** @defgroup usart_defines USART Defines + +@brief Defined Constants and Types for the STM32F2xx USART + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_USART_H +#define LIBOPENCM3_USART_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/adc.h new file mode 100644 index 00000000..0e8ef4e1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/adc.h @@ -0,0 +1,555 @@ +/** @defgroup adc_defines ADC Defines + * + * @brief Defined Constants and Types for the STM32F37x Analog to Digital + * converter + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 ARCOS-Lab UCR + * Copyright (C) 2013 Fernando Cortes + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include +#include + +/** @defgroup adc_reg_base ADC register base addresses +@ingroup STM32xx_adc_defines +@{*/ +#define ADC1 ADC1_BASE +#define ADC2 ADC2_BASE +#define ADC3 ADC3_BASE +#define ADC4 ADC4_BASE +/**@}*/ + +/* Master and slave ADCs common registers (ADC12 or ADC34) */ + + +/*----------- ADC registers -------------------------------------- */ + +#define ADC1_ISR ADC_ISR(ADC1_BASE) +#define ADC2_ISR ADC_ISR(ADC2_BASE) +#define ADC3_ISR ADC_ISR(ADC3_BASE) +#define ADC4_ISR ADC_ISR(ADC4_BASE) + +#define ADC1_IER ADC_IER(ADC1_BASE) +#define ADC2_IER ADC_IER(ADC2_BASE) +#define ADC3_IER ADC_IER(ADC3_BASE) +#define ADC4_IER ADC_IER(ADC4_BASE) + +#define ADC1_CR ADC_CR(ADC1_BASE) +#define ADC2_CR ADC_CR(ADC2_BASE) +#define ADC3_CR ADC_CR(ADC3_BASE) +#define ADC4_CR ADC_CR(ADC4_BASE) + +#define ADC1_CFGR1 ADC_CFGR1(ADC1_BASE) +#define ADC2_CFGR1 ADC_CFGR1(ADC2_BASE) +#define ADC3_CFGR1 ADC_CFGR1(ADC3_BASE) +#define ADC4_CFGR1 ADC_CFGR1(ADC4_BASE) +/* Compatibility with original ref man names */ +#define ADC_CFGR(adc) ADC_CFGR1(adc) +#define ADC1_CFGR ADC_CFGR1(ADC1_BASE) +#define ADC2_CFGR ADC_CFGR1(ADC2_BASE) +#define ADC3_CFGR ADC_CFGR1(ADC3_BASE) +#define ADC4_CFGR ADC_CFGR1(ADC4_BASE) + +#define ADC1_SMPR1 ADC_SMPR1(ADC1_BASE) +#define ADC2_SMPR1 ADC_SMPR1(ADC2_BASE) +#define ADC3_SMPR1 ADC_SMPR1(ADC3_BASE) +#define ADC4_SMPR1 ADC_SMPR1(ADC4_BASE) + +#define ADC1_SMPR2 ADC_SMPR2(ADC1_BASE) +#define ADC2_SMPR2 ADC_SMPR2(ADC2_BASE) +#define ADC3_SMPR2 ADC_SMPR2(ADC3_BASE) +#define ADC4_SMPR2 ADC_SMPR2(ADC4_BASE) + +#define ADC1_TR1 ADC_TR1(ADC1_BASE) +#define ADC2_TR1 ADC_TR1(ADC2_BASE) +#define ADC3_TR1 ADC_TR1(ADC3_BASE) +#define ADC4_TR1 ADC_TR1(ADC4_BASE) + +#define ADC1_TR2 ADC_TR2(ADC1_BASE) +#define ADC2_TR2 ADC_TR2(ADC2_BASE) +#define ADC3_TR2 ADC_TR2(ADC3_BASE) +#define ADC4_TR2 ADC_TR2(ADC4_BASE) + +#define ADC1_TR3 ADC_TR3(ADC1_BASE) +#define ADC2_TR3 ADC_TR3(ADC2_BASE) +#define ADC3_TR3 ADC_TR3(ADC3_BASE) +#define ADC4_TR3 ADC_TR3(ADC4_BASE) + +#define ADC1_SQR1 ADC_SQR1(ADC1_BASE) +#define ADC2_SQR1 ADC_SQR1(ADC2_BASE) +#define ADC3_SQR1 ADC_SQR1(ADC3_BASE) +#define ADC4_SQR1 ADC_SQR1(ADC4_BASE) + +#define ADC1_SQR2 ADC_SQR2(ADC1_BASE) +#define ADC2_SQR2 ADC_SQR2(ADC2_BASE) +#define ADC3_SQR2 ADC_SQR2(ADC3_BASE) +#define ADC4_SQR2 ADC_SQR2(ADC4_BASE) + +#define ADC1_SQR3 ADC_SQR3(ADC1_BASE) +#define ADC2_SQR3 ADC_SQR3(ADC2_BASE) +#define ADC3_SQR3 ADC_SQR3(ADC3_BASE) +#define ADC4_SQR3 ADC_SQR3(ADC4_BASE) + +#define ADC1_SQR4 ADC_SQR4(ADC1_BASE) +#define ADC2_SQR4 ADC_SQR4(ADC2_BASE) +#define ADC3_SQR4 ADC_SQR4(ADC3_BASE) +#define ADC4_SQR4 ADC_SQR4(ADC4_BASE) + +#define ADC1_DR ADC_DR(ADC1_BASE) +#define ADC2_DR ADC_DR(ADC2_BASE) +#define ADC3_DR ADC_DR(ADC3_BASE) +#define ADC4_DR ADC_DR(ADC4_BASE) + +#define ADC1_JSQR ADC_JSQR(ADC1_BASE) +#define ADC2_JSQR ADC_JSQR(ADC2_BASE) +#define ADC3_JSQR ADC_JSQR(ADC3_BASE) +#define ADC4_JSQR ADC_JSQR(ADC4_BASE) + +#define ADC1_OFR1 ADC_OFR1(ADC1_BASE) +#define ADC2_OFR1 ADC_OFR1(ADC2_BASE) +#define ADC3_OFR1 ADC_OFR1(ADC3_BASE) +#define ADC4_OFR1 ADC_OFR1(ADC4_BASE) + +#define ADC1_OFR2 ADC_OFR2(ADC1_BASE) +#define ADC2_OFR2 ADC_OFR2(ADC2_BASE) +#define ADC3_OFR2 ADC_OFR2(ADC3_BASE) +#define ADC4_OFR2 ADC_OFR2(ADC4_BASE) + +#define ADC1_OFR3 ADC_OFR3(ADC1_BASE) +#define ADC2_OFR3 ADC_OFR3(ADC2_BASE) +#define ADC3_OFR3 ADC_OFR3(ADC3_BASE) +#define ADC4_OFR3 ADC_OFR3(ADC4_BASE) + +#define ADC1_OFR4 ADC_OFR4(ADC1_BASE) +#define ADC2_OFR4 ADC_OFR4(ADC2_BASE) +#define ADC3_OFR4 ADC_OFR4(ADC3_BASE) +#define ADC4_OFR4 ADC_OFR4(ADC4_BASE) + +#define ADC1_JDR1 ADC_JDR1(ADC1_BASE) +#define ADC2_JDR1 ADC_JDR1(ADC2_BASE) +#define ADC3_JDR1 ADC_JDR1(ADC3_BASE) +#define ADC4_JDR1 ADC_JDR1(ADC4_BASE) + +#define ADC1_JDR2 ADC_JDR2(ADC1_BASE) +#define ADC2_JDR2 ADC_JDR2(ADC2_BASE) +#define ADC3_JDR2 ADC_JDR2(ADC3_BASE) +#define ADC4_JDR2 ADC_JDR2(ADC4_BASE) + +#define ADC1_JDR3 ADC_JDR3(ADC1_BASE) +#define ADC2_JDR3 ADC_JDR3(ADC2_BASE) +#define ADC3_JDR3 ADC_JDR3(ADC3_BASE) +#define ADC4_JDR3 ADC_JDR3(ADC4_BASE) + +#define ADC1_JDR4 ADC_JDR4(ADC1_BASE) +#define ADC2_JDR4 ADC_JDR4(ADC2_BASE) +#define ADC3_JDR4 ADC_JDR4(ADC3_BASE) +#define ADC4_JDR4 ADC_JDR4(ADC4_BASE) + +#define ADC1_AWD2CR ADC_AWD2CR(ADC1_BASE) +#define ADC2_AWD2CR ADC_AWD2CR(ADC2_BASE) +#define ADC3_AWD2CR ADC_AWD2CR(ADC3_BASE) +#define ADC4_AWD2CR ADC_AWD2CR(ADC4_BASE) + +#define ADC1_AWD3CR ADC_AWD3CR(ADC1_BASE) +#define ADC2_AWD3CR ADC_AWD3CR(ADC2_BASE) +#define ADC3_AWD3CR ADC_AWD3CR(ADC3_BASE) +#define ADC4_AWD3CR ADC_AWD3CR(ADC4_BASE) + +#define ADC1_DIFSEL ADC_DIFSEL(ADC1_BASE) +#define ADC2_DIFSEL ADC_DIFSEL(ADC2_BASE) +#define ADC3_DIFSEL ADC_DIFSEL(ADC3_BASE) +#define ADC4_DIFSEL ADC_DIFSEL(ADC4_BASE) + +#define ADC1_CALFACT ADC_CALFACT(ADC1_BASE) +#define ADC2_CALFACT ADC_CALFACT(ADC2_BASE) +#define ADC3_CALFACT ADC_CALFACT(ADC3_BASE) +#define ADC4_CALFACT ADC_CALFACT(ADC4_BASE) + +#define ADC12_CSR ADC_CSR(ADC1) +#define ADC12_CCR ADC_CCR(ADC1) +#define ADC12_CDR ADC_CDR(ADC1) +#define ADC34_CSR ADC_CSR(ADC3) +#define ADC34_CCR ADC_CCR(ADC3) +#define ADC34_CDR ADC_CDR(ADC3) + + +/*------- ADC_CR values ---------*/ + +/** ADVREGEN: ADC voltage regulator enable */ +#define ADC_CR_ADVREGEN_ENABLE (0x1 << 28) +#define ADC_CR_ADVREGEN_DISABLE (0x2 << 28) +#define ADC_CR_ADVREGEN_MASK (0x3 << 28) + +/****************************************************************************/ +/* ADC_SMPRx ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample ADC Sample Time Selection values +@ingroup adc_defines + +@{*/ +#define ADC_SMPR_SMP_1DOT5CYC 0x0 +#define ADC_SMPR_SMP_2DOT5CYC 0x1 +#define ADC_SMPR_SMP_4DOT5CYC 0x2 +#define ADC_SMPR_SMP_7DOT5CYC 0x3 +#define ADC_SMPR_SMP_19DOT5CYC 0x4 +#define ADC_SMPR_SMP_61DOT5CYC 0x5 +#define ADC_SMPR_SMP_181DOT5CYC 0x6 +#define ADC_SMPR_SMP_601DOT5CYC 0x7 +/**@}*/ + +/* SMPx[2:0]: Channel x sampling time selection */ + +/*------- ADC_T2 values ---------*/ + +/* Bits 23:16 HT2[7:0]: Analog watchdog 2 higher threshold */ + +/* Bit 7:0 LT2[7:0]: Analog watchdog 2 lower threshold */ + + +/*------- ADC_T3 values ---------*/ + +/* Bits 23:16 HT3[7:0]: Analog watchdog 3 higher threshold */ + +/* Bit 7:0 LT3[7:0]: Analog watchdog 3 lower threshold */ + + +/*------- ADC_DR values ---------*/ + +/* Bits 15:0 RDATA[15:0]: Regular Data converted */ + + +/*------- ADC_JSQR values ---------*/ + +#define ADC_JSQR_JL_LSB 0 +#define ADC_JSQR_JL_SHIFT 0 +#define ADC_JSQR_JSQ4_LSB 26 +#define ADC_JSQR_JSQ3_LSB 20 +#define ADC_JSQR_JSQ2_LSB 14 +#define ADC_JSQR_JSQ1_LSB 8 + +#define ADC_JSQR_JSQ_VAL(n, val) ((val) << (((n) - 1) * 6 + 8)) +#define ADC_JSQR_JL_VAL(val) (((val) - 1) << ADC_JSQR_JL_SHIFT) + +/* Bits 30:26 JSQ4[4:0]: 4th conversion in the injected sequence */ + +/* Bits 24:20 JSQ3[4:0]: 3rd conversion in the injected sequence */ + +/* Bits 18:14 JSQ2[4:0]: 2nd conversion in the injected sequence */ + +/* Bits 12:8 JSQ1[4:0]: 1st conversion in the injected sequence */ + +/* + * JEXTEN[1:0]: External Trigger Enable and Polarity Selection for injected + * channels + */ +#define ADC_JSQR_JEXTEN_DISABLED (0x0 << 6) +#define ADC_JSQR_JEXTEN_RISING_EDGE (0x1 << 6) +#define ADC_JSQR_JEXTEN_FALLING_EDGE (0x2 << 6) +#define ADC_JSQR_JEXTEN_BOTH_EDGES (0x3 << 6) + +#define ADC_JSQR_JEXTEN_MASK (0x3 << 6) + +/* JEXTSEL[3:0]: External Trigger Selection for injected group */ +#define ADC_JSQR_JEXTSEL_EVENT_0 (0x0 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_1 (0x1 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_2 (0x2 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_3 (0x3 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_4 (0x4 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_5 (0x5 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_6 (0x6 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_7 (0x7 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_8 (0x8 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_9 (0x9 << 2) +#define ADC_JSQR_JEXTSEL_EVENT_10 (0xA << 2) +#define ADC_JSQR_JEXTSEL_EVENT_11 (0xB << 2) +#define ADC_JSQR_JEXTSEL_EVENT_12 (0xC << 2) +#define ADC_JSQR_JEXTSEL_EVENT_13 (0xD << 2) +#define ADC_JSQR_JEXTSEL_EVENT_14 (0xE << 2) +#define ADC_JSQR_JEXTSEL_EVENT_15 (0xF << 2) + +#define ADC_JSQR_JEXTSEL_MASK (0xF << 2) + +/* JL[1:0]: Injected channel sequence length */ +#define ADC_JSQR_JL_1_CONVERSION (0x0 << 0) +#define ADC_JSQR_JL_2_CONVERSIONS (0x1 << 0) +#define ADC_JSQR_JL_3_CONVERSIONS (0x2 << 0) +#define ADC_JSQR_JL_4_CONVERSIONS (0x3 << 0) + + +/*------- ADC_OFR1 values ---------*/ + +/* OFFSET1_EN: Offset 1 Enable */ +#define ADC_OFR1_OFFSET1_EN (1 << 31) + +/* Bits 30:26 OFFSET1_CH[4:0]: Channel selection for the Data offset 1 */ + +/* + * Bits 11:0 OFFSET1[11:0]: Data offset y for the channel programmed into bits + * OFFSET1_CH[4:0] + */ + + +/*------- ADC_OFR2 values ---------*/ + +/* OFFSET2_EN: Offset 2 Enable */ +#define ADC_OFR2_OFFSET2_EN (1 << 31) + +/* Bits 30:26 OFFSET2_CH[4:0]: Channel selection for the Data offset 2 */ + +/* + * Bits 11:0 OFFSET2[11:0]: Data offset y for the channel programmed into bits + * OFFSET2_CH[4:0] + */ + + +/*------- ADC_OFR3 values ---------*/ + +/* OFFSET3_EN: Offset 3 Enable */ +#define ADC_OFR3_OFFSET3_EN (1 << 31) + +/* Bits 30:26 OFFSET3_CH[4:0]: Channel selection for the Data offset 3 */ + +/* + * Bits 11:0 OFFSET3[11:0]: Data offset y for the channel programmed into bits + * OFFSET3_CH[4:0] + */ + + +/*------- ADC_OFR4 values ---------*/ + +/* OFFSET4_EN: Offset 4 Enable */ +#define ADC_OFR4_OFFSET4_EN (1 << 31) + +/* Bits 30:26 OFFSET4_CH[4:0]: Channel selection for the Data offset 4 */ + +/* + * Bits 11:0 OFFSET4[11:0]: Data offset y for the channel programmed into bits + * OFFSET4_CH[4:0] + */ + + +/*------- ADC_JDRy, y= 1..4 values -------*/ + +/* Bits 15:0 JDATA[15:0]: Injected data */ + + +/*------- ADC_AWD2CR values ---------*/ + +/* Bits 18:1 AWD2CH[18:1]: Analog watchdog 2 channel selection */ + + +/*------- ADC_AWD3CR values ---------*/ + +/* Bits 18:1 AWD3CH[18:1]: Analog watchdog 3 channel selection */ + + +/*------- ADC_DIFSEL values ---------*/ + +/* DIFSEL[18:16]: Differential mode for channels 18 to 16. */ + +/* Bits 15:1 DIFSEL[15:1]: Differential mode for channels 15 to 1 */ + + +/*------- ADC_CALFACT values ---------*/ + +/* Bits 22:16 CALFACT_D[6:0]: Calibration Factors in differential mode */ + +/* Bits 6:0 CALFACT_S[6:0]: Calibration Factors In Single-Ended mode */ + + +/*--------------- ADC_CSR values ------------------------*/ + +/* Bit 26 JQOVF_SLV: Injected Context Queue Overflow flag of the slave ADC */ +#define ADC_CSR_JQOVF_SLV (1 << 26) + +/* Bit 25 AWD3_SLV: Analog watchdog 3 flag of the slave ADC */ +#define ADC_CSR_AWD3_SLV (1 << 25) + +/* Bit 24 AWD2_SLV: Analog watchdog 2 flag of the slave ADC */ +#define ADC_CSR_AWD2_SLV (1 << 24) + +/* Bit 23 AWD1_SLV: Analog watchdog 1 flag of the slave ADC */ +#define ADC_CSR_AWD1_SLV (1 << 23) + +/* Bit 22 JEOS_SLV: End of injected sequence flag of the slave ADC */ +#define ADC_CSR_JEOS_SLV (1 << 22) + +/* Bit 21 JEOC_SLV: End of injected conversion flag of the slave ADC */ +#define ADC_CSR_JEOC_SLV (1 << 21) + +/* Bit 20 OVR_SLV: Overrun flag of the slave ADC */ +#define ADC_CSR_OVR_SLV (1 << 20) + +/* Bit 19 EOS_SLV: End of regular sequence flag of the slave ADC */ +#define ADC_CSR_EOS_SLV (1 << 19) + +/* Bit 18 EOC_SLV: End of regular conversion of the slave ADC */ +#define ADC_CSR_EOC_SLV (1 << 18) + +/* Bit 17 EOSMP_SLV: End of Sampling phase flag of the slave ADC */ +#define ADC_CSR_EOSMP_SLV (1 << 17) + +/* Bit 16 ADRDY_SLV: Slave ADC ready */ +#define ADC_CSR_ADRDY_SLV (1 << 16) + +/* Bit 10 JQOVF_MST: Injected Context Queue Overflow flag of the master ADC */ +#define ADC_CSR_JQOVF_MST (1 << 10) + +/* Bit 9 AWD3_MST: Analog watchdog 3 flag of the master ADC */ +#define ADC_CSR_AWD3_MST (1 << 9) + +/* Bit 8 AWD2_MST: Analog watchdog 2 flag of the master ADC */ +#define ADC_CSR_AWD2_MST (1 << 8) + +/* Bit 7 AWD1_MST: Analog watchdog 1 flag of the master ADC */ +#define ADC_CSR_AWD1_MST (1 << 7) + +/* Bit 6 JEOS_MST: End of injected sequence flag of the master ADC */ +#define ADC_CSR_JEOS_MST (1 << 6) + +/* Bit 5 JEOC_MST: End of injected conversion flag of the master ADC */ +#define ADC_CSR_JEOC_MST (1 << 5) + +/* Bit 4 OVR_MST: Overrun flag of the master ADC */ +#define ADC_CSR_OVR_MST (1 << 4) + +/* Bit 3 EOS_MST: End of regular sequence flag of the master ADC */ +#define ADC_CSR_EOS_MST (1 << 3) + +/* Bit 2 EOC_MST: End of regular conversion of the master ADC */ +#define ADC_CSR_EOC_MST (1 << 2) + +/* Bit 1 EOSMP_MST: End of Sampling phase flag of the master ADC */ +#define ADC_CSR_EOSMP_MST (1 << 1) + +/* Bit 0 ADRDY_MST: Master ADC ready */ +#define ADC_CSR_ADRDY_MST (1 << 0) + + +/*-------- ADC_CCR values ------------*/ + +/* VBATEN: VBAT enable */ +#define ADC_CCR_VBATEN (1 << 24) + +/* TSEN: Temperature sensor enable */ +#define ADC_CCR_TSEN (1 << 23) + +/* VREFEN: VREFINT enable */ +#define ADC_CCR_VREFEN (1 << 22) + +/* CKMODE[1:0]: ADC clock mode */ +#define ADC_CCR_CKMODE_CKX (0x0 << 16) +#define ADC_CCR_CKMODE_DIV1 (0x1 << 16) +#define ADC_CCR_CKMODE_DIV2 (0x2 << 16) +#define ADC_CCR_CKMODE_DIV4 (0x3 << 16) + +#define ADC_CCR_CKMODE_MASK (0x3 << 16) + +/* MDMA[1:0]: Direct memory access mode for dual ADC mode */ +#define ADC_CCR_MDMA_DISABLE (0x0 << 14) +/*#define ADC_CCR_MDMA_RESERVED (0x1 << 14)*/ +#define ADC_CCR_MDMA_12_10_BIT (0x2 << 14) +#define ADC_CCR_MDMA_8_6_BIT (0x3 << 14) + +/* DMACFG: DMA configuration (for dual ADC mode) */ +#define ADC_CCR_DMACFG (1 << 13) + +/* DELAY: Delay between 2 sampling phases */ +#define ADC_CCR_DELAY_SHIFT 8 + +/* DUAL[4:0]: Dual ADC mode selection */ +#define ADC_CCR_DUAL_SHIFT 0 + + +/*---------------- ADC_CDR values -----------------*/ + +/* Bits 31:16 RDATA_SLV[15:0]: Regular data of the slave ADC */ + +/* Bits 15:0 RDATA_MST[15:0]: Regular data of the master ADC. */ + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_TEMP 16 +#define ADC_CHANNEL_VBAT 17 +#define ADC_CHANNEL_VREF 18 +/**@}*/ + + +BEGIN_DECLS + +void adc_enable_analog_watchdog_regular(uint32_t adc); +void adc_disable_analog_watchdog_regular(uint32_t adc); +void adc_enable_analog_watchdog_injected(uint32_t adc); +void adc_disable_analog_watchdog_injected(uint32_t adc); +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length); +void adc_disable_discontinuous_mode_regular(uint32_t adc); +void adc_enable_discontinuous_mode_injected(uint32_t adc); +void adc_disable_discontinuous_mode_injected(uint32_t adc); +void adc_enable_automatic_injected_group_conversion(uint32_t adc); +void adc_disable_automatic_injected_group_conversion(uint32_t adc); +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc); +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel); +/*void adc_enable_scan_mode(uint32_t adc);*/ +/*void adc_disable_scan_mode(uint32_t adc);*/ +void adc_enable_eoc_interrupt_injected(uint32_t adc); +void adc_disable_eoc_interrupt_injected(uint32_t adc); +void adc_enable_eos_interrupt_injected(uint32_t adc); +void adc_disable_eos_interrupt_injected(uint32_t adc); +void adc_enable_all_awd_interrupt(uint32_t adc); +void adc_disable_all_awd_interrupt(uint32_t adc); +void adc_enable_eos_interrupt(uint32_t adc); +void adc_disable_eos_interrupt(uint32_t adc); +void adc_start_conversion_injected(uint32_t adc); +void adc_disable_external_trigger_regular(uint32_t adc); +void adc_disable_external_trigger_injected(uint32_t adc); +void adc_set_watchdog_high_threshold(uint32_t adc, uint8_t threshold); +void adc_set_watchdog_low_threshold(uint32_t adc, uint8_t threshold); +void adc_set_injected_sequence(uint32_t adc, uint8_t length, uint8_t channel[]); +bool adc_eoc_injected(uint32_t adc); +bool adc_eos_injected(uint32_t adc); +uint32_t adc_read_injected(uint32_t adc, uint8_t reg); +void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset); + +void adc_set_clk_prescale(uint32_t adc, uint32_t prescaler); +void adc_set_multi_mode(uint32_t adc, uint32_t mode); +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity); +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity); +bool adc_awd(uint32_t adc); +/*void adc_set_dma_continue(uint32_t adc);*/ +/*void adc_set_dma_terminate(uint32_t adc);*/ + +END_DECLS + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/crc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/crc.h new file mode 100644 index 00000000..828832b0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/crc.h @@ -0,0 +1,70 @@ +/** @defgroup crc_defines CRC Defines + * + * @brief Defined Constants and Types for the STM32F3xx CRC Generator + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H + +#include + +/* --- CRC registers ------------------------------------------------------- */ + +/* Initial CRC value (CRC_INIT) */ +#define CRC_INIT MMIO32(CRC_BASE + 0x10) + +/* CRC polynomial (CRC_POL) */ +#define CRC_POL MMIO32(CRC_BASE + 0x14) + +/* --- CRC_CR values ------------------------------------------------------- */ + +/* REV_OUT: Reverse output data */ +#define CRC_CR_REV_OUT (1 << 7) + +/* REV_IN[1:0]: Reverse input data */ +#define CRC_CR_REV_IN_NOT_AFFECTED (0x0 << 5) +#define CRC_CR_REV_IN_BYTE (0x1 << 5) +#define CRC_CR_REV_IN_HALF_WORD (0x2 << 5) +#define CRC_CR_REV_IN_WORD (0x3 << 5) + +/* POLYSIZE[1:0]: Polynomial size */ +#define CRC_CR_POLYSIZE_32 (0x0 << 3) +#define CRC_CR_POLYSIZE_16 (0x1 << 3) +#define CRC_CR_POLYSIZE_8 (0x2 << 3) +#define CRC_CR_POLYSIZE_7 (0x3 << 3) + +/* --- CRC_INIT values ----------------------------------------------------- */ + +/* Bits 31:0 CRC_INIT: Programmable initial CRC value */ + +/* --- CRC_POL values ------------------------------------------------------ */ + +/* Bits 31:0 POL[31:0]: Programmable polynomial */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dac.h new file mode 100644 index 00000000..aceea8c5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dac.h @@ -0,0 +1,37 @@ +/** @defgroup dac_defines DAC Defines + * + * @brief Defined Constants and Types for the STM32F3xx DAC + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 5 December 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dma.h new file mode 100644 index 00000000..ae738ccc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/dma.h @@ -0,0 +1,37 @@ +/** @defgroup dma_defines DMA Defines + * + * @ingroup STM32F3xx_defines + * + * @brief Defined Constants and Types for the STM32F3xx DMA Controller + * + * @version 1.0.0 + * + * @date 30 November 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/doc-stm32f3.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/doc-stm32f3.h new file mode 100644 index 00000000..5adc4edb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/doc-stm32f3.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32F3 + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * API documentation for ST Microelectronics STM32F3 Cortex M3 series. + * + * LGPL License Terms @ref lgpl_license + */ + +/** @defgroup STM32F3xx STM32F3xx + * Libraries for ST Microelectronics STM32F3xx series. + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/** @defgroup STM32F3xx_defines STM32F3xx Defines + * + * @brief Defined Constants and Types for the STM32F3xx series + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/exti.h new file mode 100644 index 00000000..d94916db --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/exti.h @@ -0,0 +1,51 @@ +/** @defgroup exti_defines EXTI Defines + * + * @brief Defined Constants and Types for the STM32F3xx External Interrupts + * + * + * @ingroup STM32F3xx_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Piotr Esden-Tempski + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EXTI_H +#define LIBOPENCM3_EXTI_H +/**@{*/ + +#include + +/* --- EXTI registers ------------------------------------------------------ */ +#define EXTI_IMR2 MMIO32(EXTI_BASE + 0x18) +#define EXTI_EMR2 MMIO32(EXTI_BASE + 0x1C) +#define EXTI_RTSR2 MMIO32(EXTI_BASE + 0x20) +#define EXTI_FTSR2 MMIO32(EXTI_BASE + 0x24) +#define EXTI_SWIER2 MMIO32(EXTI_BASE + 0x28) +#define EXTI_PR2 MMIO32(EXTI_BASE + 0x2C) +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/flash.h new file mode 100644 index 00000000..58a8c9fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/flash.h @@ -0,0 +1,73 @@ +/** @defgroup flash_defines FLASH Defines + * + * @brief Defined Constants and Types for the STM32F3xx Flash + * controller + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H +/**@{*/ + +#include + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_AR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_OBR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x1C) +#define FLASH_WRPR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x20) + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +#define FLASH_ACR_PRFTBS (1 << 5) +#define FLASH_ACR_PRFTBE (1 << 4) +#define FLASH_ACR_HLFCYA (1 << 3) + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_BSY (1 << 0) +#define FLASH_SR_ERLYBSY (1 << 1) +#define FLASH_SR_PGPERR (1 << 2) +#define FLASH_SR_WRPRTERR (1 << 4) +#define FLASH_SR_EOP (1 << 5) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +#define FLASH_CR_OBL_LAUNCH (1 << 13) +#define FLASH_CR_EOPIE (1 << 12) +#define FLASH_CR_ERRIE (1 << 10) +#define FLASH_CR_OPTWRE (1 << 9) +#define FLASH_CR_LOCK (1 << 7) +#define FLASH_CR_STRT (1 << 6) +#define FLASH_CR_OPTER (1 << 5) +#define FLASH_CR_OPTPG (1 << 4) +#define FLASH_CR_MER (1 << 2) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_PG (1 << 0) +/**@}*/ + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/gpio.h new file mode 100644 index 00000000..82aad6b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/gpio.h @@ -0,0 +1,38 @@ +/** @defgroup gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the STM32F3xx General Purpose + * I/O + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 1 July 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/i2c.h new file mode 100644 index 00000000..ee16a86e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/i2c.h @@ -0,0 +1,37 @@ +/** @defgroup i2c_defines I2C Defines + * + * @brief Defined Constants and Types for the STM32F3xx I2C + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 12 October 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/irq.json new file mode 100644 index 00000000..ee8042e7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/irq.json @@ -0,0 +1,88 @@ +{ + "irqs": [ + "nvic_wwdg", + "pvd", + "tamp_stamp", + "rtc_wkup", + "flash", + "rcc", + "exti0", + "exti1", + "exti2_tsc", + "exti3", + "exti4", + "dma1_channel1", + "dma1_channel2", + "dma1_channel3", + "dma1_channel4", + "dma1_channel5", + "dma1_channel6", + "dma1_channel7", + "adc1_2", + "usb_hp_can1_tx", + "usb_lp_can1_rx0", + "can1_rx1", + "can1_sce", + "exti9_5", + "tim1_brk_tim15", + "tim1_up_tim16", + "tim1_trg_com_tim17", + "tim1_cc", + "tim2", + "tim3", + "tim4", + "i2c1_ev_exti23", + "i2c1_er", + "i2c2_ev_exti24", + "i2c2_er", + "spi1", + "spi2", + "usart1_exti25", + "usart2_exti26", + "usart3_exti28", + "exti15_10", + "rtc_alarm", + "usb_wkup_a", + "tim8_brk", + "tim8_up", + "tim8_trg_com", + "tim8_cc", + "adc3", + "reserved_1", + "reserved_2", + "reserved_3", + "spi3", + "uart4_exti34", + "uart5_exti35", + "tim6_dac", + "tim7", + "dma2_channel1", + "dma2_channel2", + "dma2_channel3", + "dma2_channel4", + "dma2_channel5", + "eth", + "reserved_4", + "reserved_5", + "comp123", + "comp456", + "comp7", + "reserved_6", + "reserved_7", + "reserved_8", + "reserved_9", + "reserved_10", + "reserved_11", + "reserved_12", + "usb_hp", + "usb_lp", + "usb_wkup", + "reserved_13", + "reserved_14", + "reserved_15", + "reserved_16" + ], + "partname_humanreadable": "STM32 F3 series", + "partname_doxygen": "STM32F3", + "includeguard": "LIBOPENCM3_STM32_F3_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/iwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/iwdg.h new file mode 100644 index 00000000..c7413a4e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/iwdg.h @@ -0,0 +1,53 @@ +/** @defgroup iwdg_defines IWDG Defines + * + * @brief Defined Constants and Types for the STM32F3xx Independent Watchdog + * Timer + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_IWDG_H +#define LIBOPENCM3_IWDG_H + +#include + +/* --- IWDG registers ------------------------------------------------------ */ + +/* Window register (IWDG_WINR) */ +#define IWDG_WINR MMIO32(IWDG_BASE + 0x10) + +/* --- IWDG_SR values ------------------------------------------------------ */ + +/* WVU: Watchdog counter window value update */ +#define IWGD_SR_WVU (1 << 2) + +/* --- IWDG_WIN values ----------------------------------------------------- */ + +/* Bits 11:0 WIN[11:0]: Watchdog counter window value */ + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/memorymap.h new file mode 100644 index 00000000..7ad3b0ac --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/memorymap.h @@ -0,0 +1,129 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * Modified by 2013 Fernando Cortes (stm32f3) + * Modified by 2013 Guillermo Rivera (stm32f3) + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32F3 specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x20000) +#define PERIPH_BASE_AHB2 (0x48000000U) +#define PERIPH_BASE_AHB3 (0x50000000U) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +/* PERIPH_BASE_APB1 + 0x0C00 (0x4000 0C00 - 0x4000 0FFF): Reserved */ +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +/* PERIPH_BASE_APB1 + 0x1800 (0x4000 1800 - 0x4000 27FF): Reserved */ +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +#define I2S2_EXT_BASE (PERIPH_BASE_APB1 + 0x3400) +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +#define I2S3_EXT_BASE (PERIPH_BASE_APB1 + 0x4000) +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define UART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define UART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define USB_DEV_FS_BASE (PERIPH_BASE_APB1 + 0x5C00) +#define USB_PMA_BASE (PERIPH_BASE_APB1 + 0x6000) +#define BX_CAN1_BASE (PERIPH_BASE_APB1 + 0x6400) +/* PERIPH_BASE_APB1 + 0x6800 (0x4000 6800 - 0x4000 6BFF): Reserved */ +/* PERIPH_BASE_APB1 + 0x6C00 (0x4000 6C00 - 0x4000 6FFF): Reserved */ +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +/* PERIPH_BASE_APB1 + 0x7800 (0x4000 7800 - 0x4000 7FFF): Reserved */ + + +/* APB2 */ +#define TIM17_BASE (PERIPH_BASE_APB2 + 0x4800) +#define TIM16_BASE (PERIPH_BASE_APB2 + 0x4400) +#define TIM15_BASE (PERIPH_BASE_APB2 + 0x4000) +/* PERIPH_BASE_APB2 + 0x3C00 (0x4001 3C00 - 0x4001 3FFF): Reserved */ +#define USART1_BASE (PERIPH_BASE_APB2 + 0x3800) +#define TIM8_BASE (PERIPH_BASE_APB2 + 0x3400) +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +#define TIM1_BASE (PERIPH_BASE_APB2 + 0x2C00) +/* PERIPH_BASE_APB2 + 0x0800 (0x4001 0800 - 0x4001 2BFF): Reserved */ +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x0400) +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x0000) +#define COMP_BASE (PERIPH_BASE_APB2 + 0x0000) +#define OPAMP_BASE (PERIPH_BASE_APB2 + 0x0000) + + +/* AHB2 */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB2 + 0x0000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB2 + 0x0400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB2 + 0x0800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB2 + 0x0C00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB2 + 0x1000) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB2 + 0x1400) + + +/* AHB1 */ +#define TSC_BASE (PERIPH_BASE_AHB1 + 0x4000) +/* PERIPH_BASE_AHB1 + 0x3400 (0x4002 3400 - 0x4002 37FF): Reserved */ +#define CRC_BASE (PERIPH_BASE_AHB1 + 0x3000) +/* PERIPH_BASE_AHB1 + 0x2400 (0x4002 2400 - 0x4002 2FFF): Reserved */ +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x2000) +/* PERIPH_BASE_AHB1 + 0x1400 (0x4002 1400 - 0x4002 1FFF): Reserved */ +#define RCC_BASE (PERIPH_BASE_AHB1 + 0x1000) +/* PERIPH_BASE_AHB1 + 0x0800 (0x4002 0800 - 0x4002 0FFF): Reserved */ +#define DMA1_BASE (PERIPH_BASE_AHB1 + 0x0000) +#define DMA2_BASE (PERIPH_BASE_AHB1 + 0x0400) + + +/* AHB3 */ +#define ADC3_BASE (PERIPH_BASE_AHB3 + 0x0400) +#define ADC4_BASE (PERIPH_BASE_AHB3 + 0x0500) +#define ADC1_BASE (PERIPH_BASE_AHB3 + 0x0000) +#define ADC2_BASE (PERIPH_BASE_AHB3 + 0x0100) + +/* PPIB */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (0x1FFFF7CCU) +#define DESIG_UNIQUE_ID_BASE (0x1FFFF7ACU) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 8) + +/* ST provided factory calibration values @ 3.3V */ +#define ST_VREFINT_CAL MMIO16(0x1FFFF7BA) +#define ST_TSENSE_CAL1_30C MMIO16(0x1FFFF7B8) +#define ST_TSENSE_CAL2_110C MMIO16(0x1FFFF7C2) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/pwr.h new file mode 100644 index 00000000..08bfbe2f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/pwr.h @@ -0,0 +1,69 @@ +/** @defgroup pwr_defines PWR Defines + * + * @brief Defined Constants and Types for the STM32F3xx Power control + * + * @ingroup STM32F3xx_defines + * + * @author @htmlonly © @endhtmlonly 2011 + * Stephen Caudle + * @author @htmlonly © @endhtmlonly 2013 + * Fernando Cortes + * @author @htmlonly © @endhtmlonly 2013 + * Guillermo Rivera + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * Modified by 2013 Fernando Cortes (stm32f3) + * Modified by 2013 Guillermo Rivera (stm32f3) + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include + +/* --- PWR_CR values ------------------------------------------------------- */ + +/* Bits [31:10]: Reserved */ +#define PWR_CR_DBP (1 << 8) +/* Bits [7:5]: Reserved PLS: PVD level selection. (Power Voltage Detector) */ +#define PWR_CR_PVDE (1 << 4) +#define PWR_CR_CSBF (1 << 3) +#define PWR_CR_CWUF (1 << 2) +#define PWR_CR_PDDS (1 << 1) +#define PWR_CR_LPDS (1 << 0) + + +/* --- PWR_CSR values ------------------------------------------------------ */ + +/* Bits [31:10]: Reserved */ +#define PWR_CSR_EWUP2 (1 << 9) +#define PWR_CSR_EWUP1 (1 << 8) +/* Bits [7:3]: Reserved */ +#define PWR_CSR_PVDO (1 << 2) +#define PWR_CSR_SBF (1 << 1) +#define PWR_CSR_WUF (1 << 0) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rcc.h new file mode 100644 index 00000000..9b5f5c1b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rcc.h @@ -0,0 +1,618 @@ +/** @defgroup rcc_defines RCC Defines + * + * @brief Defined Constants and Types for the STM32F3xx Reset and Clock + * Control + * + * @ingroup STM32F3xx_defines + * + * @author @htmlonly © @endhtmlonly 2009 + * Federico Ruiz-Ugalde \ + * @author @htmlonly © @endhtmlonly 2009 + * Uwe Hermann + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * @author @htmlonly © @endhtmlonly 2011 + * Stephen Caudle + * @author @htmlonly © @endhtmlonly 2013 + * Fernando Cortes + * @author @htmlonly © @endhtmlonly 2013 + * Guillermo Rivera + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2011 Fergus Noble + * Copyright (C) 2011 Stephen Caudle + * Modified by 2013 Fernando Cortes (stm32f3) + * Modified by 2013 Guillermo Rivera (stm32f3) + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_CFGR MMIO32(RCC_BASE + 0x04) +#define RCC_CIR MMIO32(RCC_BASE + 0x08) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x0C) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x10) +#define RCC_AHBENR MMIO32(RCC_BASE + 0x14) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x18) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x1C) +#define RCC_BDCR MMIO32(RCC_BASE + 0x20) +#define RCC_CSR MMIO32(RCC_BASE + 0x24) +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x28) +#define RCC_CFGR2 MMIO32(RCC_BASE + 0x2C) +#define RCC_CFGR3 MMIO32(RCC_BASE + 0x30) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +/* HSICAL: [15:8] */ +/* HSITRIM: [7:3] */ +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +/* --- RCC_CFGR values ----------------------------------------------------- */ +#define RCC_CFGR_MCOF (1 << 28) +#define RCC_CFGR_I2SSRC (1 << 23) +#define RCC_CFGR_USBPRES (1 << 22) +#define RCC_CFGR_PLLXTPRE (1 << 17) +#define RCC_CFGR_PLLSRC (1 << 16) + +/* MCO: Microcontroller clock output */ +#define RCC_CFGR_MCO_SHIFT 24 +#define RCC_CFGR_MCO_MASK 0x7 +#define RCC_CFGR_MCO_NOCLK 0x0 +/*Reserve RCC_CFGR_MCO 0x1*/ +#define RCC_CFGR_MCO_LSI 0x2 +#define RCC_CFGR_MCO_LSE 0x3 +#define RCC_CFGR_MCO_SYSCLK 0x4 +#define RCC_CFGR_MCO_HSI 0x5 +#define RCC_CFGR_MCO_HSE 0x6 +#define RCC_CFGR_MCO_PLL 0x7 + +/* PLLSRC: PLL source values */ +#define RCC_CFGR_PLLSRC_HSI_DIV2 0 +#define RCC_CFGR_PLLSRC_HSE_PREDIV 1 + +/* PLLMUL: PLL multiplication factor */ +#define RCC_CFGR_PLLMUL_SHIFT 18 +#define RCC_CFGR_PLLMUL_MASK 0xF +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X2 0x0 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X3 0x1 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X4 0x2 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X5 0x3 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X6 0x4 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X7 0x5 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X8 0x6 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X9 0x7 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X10 0x8 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X11 0x9 +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X12 0xA +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X13 0xB +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X14 0xC +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X15 0xD +#define RCC_CFGR_PLLMUL_PLL_IN_CLK_X16 0xE + +/* PPRE2: APB high-speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_SHIFT 11 +#define RCC_CFGR_PPRE2_MASK 0x7 +/* 0XX: HCLK not divided */ +#define RCC_CFGR_PPRE2_DIV_NONE 0x0 + +#define RCC_CFGR_PPRE2_DIV_2 0x4 +#define RCC_CFGR_PPRE2_DIV_4 0x5 +#define RCC_CFGR_PPRE2_DIV_8 0x6 +#define RCC_CFGR_PPRE2_DIV_16 0x7 + +/* PPRE1:APB Low-speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE1_MASK 0x7 +/* 0XX: HCLK not divided */ +#define RCC_CFGR_PPRE1_DIV_NONE 0x0 +#define RCC_CFGR_PPRE1_DIV_2 0x4 +#define RCC_CFGR_PPRE1_DIV_4 0x5 +#define RCC_CFGR_PPRE1_DIV_8 0x6 +#define RCC_CFGR_PPRE1_DIV_16 0x7 + +/* HPRE: HLCK prescaler */ +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE_MASK 0xf +/* 0XXX: SYSCLK not divided */ +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 0x8 +#define RCC_CFGR_HPRE_DIV_4 0x9 +#define RCC_CFGR_HPRE_DIV_8 0xA +#define RCC_CFGR_HPRE_DIV_16 0xB +#define RCC_CFGR_HPRE_DIV_64 0xC +#define RCC_CFGR_HPRE_DIV_128 0xD +#define RCC_CFGR_HPRE_DIV_256 0xE +#define RCC_CFGR_HPRE_DIV_512 0xF + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_SHIFT 2 +#define RCC_CFGR_SWS_MASK 0x3 +#define RCC_CFGR_SWS_HSI 0x0 +#define RCC_CFGR_SWS_HSE 0x1 +#define RCC_CFGR_SWS_PLL 0x2 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_SHIFT 0 +#define RCC_CFGR_SW_HSI 0x0 +#define RCC_CFGR_SW_HSE 0x1 +#define RCC_CFGR_SW_PLL 0x2 + +/* --- RCC_CIR values ------------------------------------------------------ */ + +/* Clock security system interrupt clear bit */ +#define RCC_CIR_CSSC (1 << 23) + +/* OSC ready interrupt clear bits */ +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) + +/* OSC ready interrupt enable bits */ +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) + +/* Clock security system interrupt flag bit */ +#define RCC_CIR_CSSF (1 << 7) + +/* OSC ready interrupt flag bits */ +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_TIM20RST (1 << 20) +#define RCC_APB2RSTR_TIM17RST (1 << 18) +#define RCC_APB2RSTR_TIM16RST (1 << 17) +#define RCC_APB2RSTR_TIM15RST (1 << 16) +#define RCC_APB2RSTR_SPI4RST (1 << 15) +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_TIM8RST (1 << 13) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_TIM1RST (1 << 11) +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_I2C3RST (1 << 30) +#define RCC_APB1RSTR_DAC1RST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_DAC2RST (1 << 26) +#define RCC_APB1RSTR_CAN1RST (1 << 25) +#define RCC_APB1RSTR_USBRST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_UART5RST (1 << 20) +#define RCC_APB1RSTR_UART4RST (1 << 19) +#define RCC_APB1RSTR_USART3RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI3RST (1 << 15) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM4RST (1 << 2) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_AHBENR values --------------------------------------------------- */ +#define RCC_AHBENR_ADC34EN (1 << 29) +#define RCC_AHBENR_ADC12EN (1 << 28) +#define RCC_AHBENR_TSCEN (1 << 24) +#define RCC_AHBENR_IOPGEN (1 << 23) +#define RCC_AHBENR_IOPFEN (1 << 22) +#define RCC_AHBENR_IOPEEN (1 << 21) +#define RCC_AHBENR_IOPDEN (1 << 20) +#define RCC_AHBENR_IOPCEN (1 << 19) +#define RCC_AHBENR_IOPBEN (1 << 18) +#define RCC_AHBENR_IOPAEN (1 << 17) +#define RCC_AHBENR_IOPHEN (1 << 16) +#define RCC_AHBENR_CRCEN (1 << 6) +#define RCC_AHBENR_FMCEN (1 << 5) +#define RCC_AHBENR_FLITFEN (1 << 4) +#define RCC_AHBENR_SRAMEN (1 << 2) +#define RCC_AHBENR_DMA2EN (1 << 1) +#define RCC_AHBENR_DMA1EN (1 << 0) + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +#define RCC_APB2ENR_TIM20EN (1 << 20) +#define RCC_APB2ENR_TIM17EN (1 << 18) +#define RCC_APB2ENR_TIM16EN (1 << 17) +#define RCC_APB2ENR_TIM15EN (1 << 16) +#define RCC_APB2ENR_SPI4EN (1 << 15) +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_TIM8EN (1 << 13) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_TIM1EN (1 << 11) +#define RCC_APB2ENR_SYSCFGEN (1 << 0) + +/* --- RCC_APB1ENR values -------------------------------------------------- */ + +#define RCC_APB1ENR_I2C3EN (1 << 30) +#define RCC_APB1ENR_DAC1EN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_DAC2EN (1 << 26) +#define RCC_APB1ENR_CANEN (1 << 25) +#define RCC_APB1ENR_USBEN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_USART5EN (1 << 20) +#define RCC_APB1ENR_USART4EN (1 << 19) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI3EN (1 << 15) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM4EN (1 << 2) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) + +/* --- RCC_BDCR values ----------------------------------------------------- */ + +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) +/* RCC_BDCR[9:8]: RTCSEL */ +/* RCC_BDCR[4:3]: LSEDRV */ +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_OBLRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- RCC_AHBRSTR values -------------------------------------------------- */ +#define RCC_AHBRSTR_ADC34RST (1 << 29) +#define RCC_AHBRSTR_ADC12RST (1 << 28) +#define RCC_AHBRSTR_TSCRST (1 << 24) +#define RCC_AHBRSTR_IOPGRST (1 << 23) +#define RCC_AHBRSTR_IOPFRST (1 << 22) +#define RCC_AHBRSTR_IOPERST (1 << 21) +#define RCC_AHBRSTR_IOPDRST (1 << 20) +#define RCC_AHBRSTR_IOPCRST (1 << 19) +#define RCC_AHBRSTR_IOPBRST (1 << 18) +#define RCC_AHBRSTR_IOPARST (1 << 17) +#define RCC_AHBRSTR_IOPHRST (1 << 16) +#define RCC_AHBRSTR_FMCRST (1 << 5) + +/* --- RCC_CFGR2 values ---------------------------------------------------- */ +/* ADCxxPRES: ADCxx prescaler */ +#define RCC_CFGR2_ADC34PRES_SHIFT 9 +#define RCC_CFGR2_ADC12PRES_SHIFT 4 +#define RCC_CFGR2_ADCxPRES_MASK 0x1f +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_1 0x10 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_2 0x11 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_4 0x12 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_6 0x13 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_8 0x14 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_10 0x15 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_12 0x16 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_16 0x17 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_32 0x18 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_64 0x19 +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_128 0x1A +#define RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_256 0x1B + +#define RCC_CFGR2_PREDIV 0xf +/** @defgroup rcc_cfgr2_prediv PLL source predividers +@ingroup rcc_defines +@{*/ +#define RCC_CFGR2_PREDIV_NODIV 0x0 +#define RCC_CFGR2_PREDIV_DIV2 0x1 +#define RCC_CFGR2_PREDIV_DIV3 0x2 +#define RCC_CFGR2_PREDIV_DIV4 0x3 +#define RCC_CFGR2_PREDIV_DIV5 0x4 +#define RCC_CFGR2_PREDIV_DIV6 0x5 +#define RCC_CFGR2_PREDIV_DIV7 0x6 +#define RCC_CFGR2_PREDIV_DIV8 0x7 +#define RCC_CFGR2_PREDIV_DIV9 0x8 +#define RCC_CFGR2_PREDIV_DIV10 0x9 +#define RCC_CFGR2_PREDIV_DIV11 0xa +#define RCC_CFGR2_PREDIV_DIV12 0xb +#define RCC_CFGR2_PREDIV_DIV13 0xc +#define RCC_CFGR2_PREDIV_DIV14 0xd +#define RCC_CFGR2_PREDIV_DIV15 0xe +#define RCC_CFGR2_PREDIV_DIV16 0xf +/**@}*/ + +/* --- RCC_CFGR3 values ---------------------------------------------------- */ +#define RCC_CFGR3_TIM8SW (1 << 9) +#define RCC_CFGR3_TIM1SW (1 << 8) +#define RCC_CFGR3_I2C2SW (1 << 5) +#define RCC_CFGR3_I2C1SW (1 << 4) +/* UART5SW: UART5 clock source selection */ +#define RCC_CFGR3_UART5SW_SHIFT 22 +#define RCC_CFGR3_UART5SW_PCLK 0x0 +#define RCC_CFGR3_UART5SW_SYSCLK 0x1 +#define RCC_CFGR3_UART5SW_LSE 0x2 +#define RCC_CFGR3_UART5SW_HSI 0x3 +/* UART4SW: UART4 clock source selection */ +#define RCC_CFGR3_UART4SW_SHIFT 20 +#define RCC_CFGR3_UART4SW_PCLK 0x0 +#define RCC_CFGR3_UART4SW_SYSCLK 0x1 +#define RCC_CFGR3_UART4SW_LSE 0x2 +#define RCC_CFGR3_UART4SW_HSI 0x3 +/* UART3SW: UART3 clock source selection */ +#define RCC_CFGR3_UART3SW_SHIFT 18 +#define RCC_CFGR3_UART3SW_PCLK 0x0 +#define RCC_CFGR3_UART3SW_SYSCLK 0x1 +#define RCC_CFGR3_UART3SW_LSE 0x2 +#define RCC_CFGR3_UART3SW_HSI 0x3 +/* UART2SW: UART2 clock source selection */ +#define RCC_CFGR3_UART2SW_SHIFT 16 +#define RCC_CFGR3_UART2SW_PCLK 0x0 +#define RCC_CFGR3_UART2SW_SYSCLK 0x1 +#define RCC_CFGR3_UART2SW_LSE 0x2 +#define RCC_CFGR3_UART2SW_HSI 0x3 +/* UART1SW: UART1 clock source selection */ +#define RCC_CFGR3_UART1SW_SHIFT 0 +#define RCC_CFGR3_UART1SW_PCLK 0x0 +#define RCC_CFGR3_UART1SW_SYSCLK 0x1 +#define RCC_CFGR3_UART1SW_LSE 0x2 +#define RCC_CFGR3_UART1SW_HSI 0x3 + + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_clock { + RCC_CLOCK_44MHZ, + RCC_CLOCK_48MHZ, + RCC_CLOCK_64MHZ, + RCC_CLOCK_END +}; + +struct rcc_clock_scale { + uint8_t pll; + uint8_t pllsrc; + uint32_t flash_config; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + uint8_t power_save; + uint32_t ahb_frequency; + uint32_t apb1_frequency; + uint32_t apb2_frequency; +}; + +extern const struct rcc_clock_scale rcc_hsi_8mhz[RCC_CLOCK_END]; + +enum rcc_osc { + RCC_PLL, RCC_HSE, RCC_HSI, RCC_LSE, RCC_LSI +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +/* Availability in comment: + * 0: F30x + * 1: F31x + * 7: F37x + * 8: F38x + */ +enum rcc_periph_clken { + /* AHB peripherals*/ + RCC_DMA1 = _REG_BIT(0x14, 0),/*0178*/ + RCC_DMA2 = _REG_BIT(0x14, 1),/*0178*/ + RCC_SRAM = _REG_BIT(0x14, 2),/*0178*/ + RCC_FLTIF = _REG_BIT(0x14, 4),/*0178*/ + RCC_FMC = _REG_BIT(0x14, 5),/*0178*/ + RCC_CRC = _REG_BIT(0x14, 6),/*0178*/ + RCC_GPIOH = _REG_BIT(0x14, 16),/*0178*/ + RCC_GPIOA = _REG_BIT(0x14, 17),/*0178*/ + RCC_GPIOB = _REG_BIT(0x14, 18),/*0178*/ + RCC_GPIOC = _REG_BIT(0x14, 19),/*0178*/ + RCC_GPIOD = _REG_BIT(0x14, 20),/*0178*/ + RCC_GPIOE = _REG_BIT(0x14, 21),/*0178*/ + RCC_GPIOF = _REG_BIT(0x14, 22),/*0178*/ + RCC_GPIOG = _REG_BIT(0x14, 23),/*0178*/ + RCC_TSC = _REG_BIT(0x14, 24),/*0178*/ + RCC_ADC12 = _REG_BIT(0x14, 28),/*01--*/ + RCC_ADC34 = _REG_BIT(0x14, 29),/*01--*/ + + /* APB2 peripherals */ + RCC_SYSCFG = _REG_BIT(0x18, 0),/*0178*/ + RCC_ADC = _REG_BIT(0x18, 9),/*--78*/ + RCC_TIM1 = _REG_BIT(0x18, 11),/*01--*/ + RCC_SPI1 = _REG_BIT(0x18, 12),/*0178*/ + RCC_TIM8 = _REG_BIT(0x18, 13),/*01--*/ + RCC_USART1 = _REG_BIT(0x18, 14),/*0178*/ + RCC_SPI4 = _REG_BIT(0x18, 15), + RCC_TIM15 = _REG_BIT(0x18, 16),/*0178*/ + RCC_TIM16 = _REG_BIT(0x18, 17),/*0178*/ + RCC_TIM17 = _REG_BIT(0x18, 18),/*0178*/ + RCC_TIM19 = _REG_BIT(0x18, 19),/*--78*/ + RCC_TIM20 = _REG_BIT(0x18, 20), + RCC_DBGMCU = _REG_BIT(0x18, 22),/*--78*/ + RCC_SDADC1 = _REG_BIT(0x18, 24),/*--78*/ + RCC_SDADC2 = _REG_BIT(0x18, 25),/*--78*/ + RCC_SDADC3 = _REG_BIT(0x18, 26),/*--78*/ + + /* APB1 peripherals */ + RCC_TIM2 = _REG_BIT(0x1C, 0),/*0178*/ + RCC_TIM3 = _REG_BIT(0x1C, 1),/*0178*/ + RCC_TIM4 = _REG_BIT(0x1C, 2),/*0178*/ + RCC_TIM5 = _REG_BIT(0x1C, 3),/*--78*/ + RCC_TIM6 = _REG_BIT(0x1C, 4),/*0178*/ + RCC_TIM7 = _REG_BIT(0x1C, 5),/*0178*/ + RCC_TIM12 = _REG_BIT(0x1C, 6),/*--78*/ + RCC_TIM13 = _REG_BIT(0x1C, 7),/*--78*/ + RCC_TIM14 = _REG_BIT(0x1C, 8),/*--78*/ + RCC_TIM18 = _REG_BIT(0x1C, 9),/*--78*/ + RCC_WWDG = _REG_BIT(0x1C, 11),/*0178*/ + RCC_SPI2 = _REG_BIT(0x1C, 14),/*0178*/ + RCC_SPI3 = _REG_BIT(0x1C, 15),/*0178*/ + RCC_USART2 = _REG_BIT(0x1C, 17),/*0178*/ + RCC_USART3 = _REG_BIT(0x1C, 18),/*0178*/ + RCC_UART4 = _REG_BIT(0x1C, 19),/*01--*/ + RCC_UART5 = _REG_BIT(0x1C, 20),/*01--*/ + RCC_I2C1 = _REG_BIT(0x1C, 21),/*0178*/ + RCC_I2C2 = _REG_BIT(0x1C, 22),/*0178*/ + RCC_USB = _REG_BIT(0x1C, 23),/*0178*/ + RCC_CAN = _REG_BIT(0x1C, 25),/*0178*/ + RCC_CAN1 = _REG_BIT(0x1C, 25),/*0178*/ + RCC_DAC2 = _REG_BIT(0x1C, 26), + RCC_PWR = _REG_BIT(0x1C, 28),/*0178*/ + RCC_DAC1 = _REG_BIT(0x1C, 29), + RCC_CEC = _REG_BIT(0x1C, 30),/*--78*/ + RCC_I2C3 = _REG_BIT(0x1C, 30), +}; + +enum rcc_periph_rst { + /* APB2 peripherals*/ + RST_SYSCFG = _REG_BIT(0x0C, 0),/*0178*/ + RST_ADC = _REG_BIT(0x0C, 9),/*--78*/ + RST_TIM1 = _REG_BIT(0x0C, 11),/*01--*/ + RST_SPI1 = _REG_BIT(0x0C, 12),/*0178*/ + RST_TIM8 = _REG_BIT(0x0C, 13),/*01--*/ + RST_USART1 = _REG_BIT(0x0C, 14),/*0178*/ + RST_SPI4 = _REG_BIT(0x0C, 15), + RST_TIM15 = _REG_BIT(0x0C, 16),/*0178*/ + RST_TIM16 = _REG_BIT(0x0C, 17),/*0178*/ + RST_TIM17 = _REG_BIT(0x0C, 18),/*0178*/ + RST_TIM19 = _REG_BIT(0x0C, 19),/*--78*/ + RST_TIM20 = _REG_BIT(0x0C, 20), + RST_SDADC1 = _REG_BIT(0x0C, 24),/*--78*/ + RST_SDADC2 = _REG_BIT(0x0C, 25),/*--78*/ + RST_SDADC3 = _REG_BIT(0x0C, 26),/*--78*/ + + /* APB1 peripherals */ + RST_TIM2 = _REG_BIT(0x10, 0),/*0178*/ + RST_TIM3 = _REG_BIT(0x10, 1),/*0178*/ + RST_TIM4 = _REG_BIT(0x10, 2),/*0178*/ + RST_TIM5 = _REG_BIT(0x10, 3),/*--78*/ + RST_TIM6 = _REG_BIT(0x10, 4),/*0178*/ + RST_TIM7 = _REG_BIT(0x10, 5),/*0178*/ + RST_TIM12 = _REG_BIT(0x10, 6),/*--78*/ + RST_TIM13 = _REG_BIT(0x10, 7),/*--78*/ + RST_TIM14 = _REG_BIT(0x10, 8),/*--78*/ + RST_TIM18 = _REG_BIT(0x10, 9),/*--78*/ + RST_WWDG = _REG_BIT(0x10, 11),/*0178*/ + RST_SPI2 = _REG_BIT(0x10, 14),/*0178*/ + RST_SPI3 = _REG_BIT(0x10, 15),/*0178*/ + RST_USART2 = _REG_BIT(0x10, 17),/*0178*/ + RST_USART3 = _REG_BIT(0x10, 18),/*0178*/ + RST_UART4 = _REG_BIT(0x10, 19),/*01--*/ + RST_UART5 = _REG_BIT(0x10, 20),/*01--*/ + RST_I2C1 = _REG_BIT(0x10, 21),/*0178*/ + RST_I2C2 = _REG_BIT(0x10, 22),/*0178*/ + RST_USB = _REG_BIT(0x10, 23),/*0178*/ + RST_CAN = _REG_BIT(0x10, 25),/*0178*/ + RST_CAN1 = _REG_BIT(0x10, 25),/*0178*/ + RST_DAC2 = _REG_BIT(0x10, 26), + RST_PWR = _REG_BIT(0x10, 28),/*0178*/ + RST_DAC1 = _REG_BIT(0x10, 29), + RST_CEC = _REG_BIT(0x10, 30),/*--78*/ + RST_I2C3 = _REG_BIT(0x10, 30), + + /* AHB peripherals */ + RST_FMC = _REG_BIT(0x28, 5), + RST_GPIOH = _REG_BIT(0x28, 16), + RST_GPIOA = _REG_BIT(0x28, 17),/*0178*/ + RST_GPIOB = _REG_BIT(0x28, 18),/*0178*/ + RST_GPIOC = _REG_BIT(0x28, 19),/*0178*/ + RST_GPIOD = _REG_BIT(0x28, 20),/*0178*/ + RST_GPIOE = _REG_BIT(0x28, 21),/*0178*/ + RST_GPIOF = _REG_BIT(0x28, 22),/*0178*/ + RST_GPIOG = _REG_BIT(0x28, 23), + RST_TSC = _REG_BIT(0x28, 24),/*0178*/ + RST_ADC12 = _REG_BIT(0x28, 28),/*01--*/ + RST_ADC34 = _REG_BIT(0x28, 29),/*01--*/ + + /* BDCR[16] */ + RST_BD = _REG_BIT(0x20, 16), +}; + +#undef _REG_BIT + +#include + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_osc_not_ready(enum rcc_osc osc); +void rcc_wait_for_sysclk_status(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_prediv(uint32_t prediv); +void rcc_set_pll_multiplier(uint32_t pll); +uint32_t rcc_get_system_clock_source(void); +void rcc_backupdomain_reset(void); +void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock); +void rcc_set_i2c_clock_hsi(uint32_t i2c); +void rcc_set_i2c_clock_sysclk(uint32_t i2c); +uint32_t rcc_get_i2c_clocks(void); +void rcc_usb_prescale_1_5(void); +void rcc_usb_prescale_1(void); +void rcc_adc_prescale(uint32_t prescale1, uint32_t prescale2); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rtc.h new file mode 100644 index 00000000..b982496c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/rtc.h @@ -0,0 +1,42 @@ +/** @defgroup rtc_defines RTC Defines + * + * @brief Defined Constants and Types for the STM32F3xx Real Time Clock + * + * @ingroup STM32F3xx_defines + * + * @author @htmlonly © @endhtmlonly 2014 + * Ken Sarkies + * + * @version 1.0.0 + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_F3_H +#define LIBOPENCM3_RTC_F3_H +/**@{*/ + +#include +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/spi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/spi.h new file mode 100644 index 00000000..ad48fdaa --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/spi.h @@ -0,0 +1,36 @@ +/** @defgroup spi_defines SPI Defines + * + * @brief Defined Constants and Types for the STM32F3xx SPI + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 5 December 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SPI_H +#define LIBOPENCM3_SPI_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/st_usbfs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/st_usbfs.h new file mode 100644 index 00000000..7da73f2a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/st_usbfs.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +# error Do not include directly ! +#else + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/syscfg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/syscfg.h new file mode 100644 index 00000000..39733da7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/syscfg.h @@ -0,0 +1,41 @@ +/** @defgroup syscfg_defines SYSCFG Defines + * + * @ingroup STM32F3xx_defines + * + * @brief Defined Constants and Types for the STM32F3xx Sysconfig + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SYSCFG_H +#define LIBOPENCM3_SYSCFG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/timer.h new file mode 100644 index 00000000..f9284c7e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/timer.h @@ -0,0 +1,39 @@ +/** @defgroup timer_defines Timer Defines + * + * @brief Defined Constants and Types for the STM32F3xx Timers + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 8 March 2013 + * + * @author @htmlonly © @endhtmlonly 2011 Fergus Noble + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/usart.h new file mode 100644 index 00000000..61cbaca4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f3/usart.h @@ -0,0 +1,520 @@ +/** @defgroup usart_defines USART Defines + * + * @brief Defined Constants and Types for the STM32F3xx USART + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 5 December 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_USART_H +#define LIBOPENCM3_USART_H + +#include +#include + +/* --- USART registers ----------------------------------------------------- */ + +/* Control register 1 (USARTx_CR1) */ +#define USART_CR1(usart_base) MMIO32((usart_base) + 0x00) +#define USART1_CR1 USART_CR1(USART1_BASE) +#define USART2_CR1 USART_CR1(USART2_BASE) +#define USART3_CR1 USART_CR1(USART3_BASE) +#define UART4_CR1 USART_CR1(UART4_BASE) +#define UART5_CR1 USART_CR1(UART5_BASE) + +/* Control register 2 (USARTx_CR2) */ +#define USART_CR2(usart_base) MMIO32((usart_base) + 0x04) +#define USART1_CR2 USART_CR2(USART1_BASE) +#define USART2_CR2 USART_CR2(USART2_BASE) +#define USART3_CR2 USART_CR2(USART3_BASE) +#define UART4_CR2 USART_CR2(UART4_BASE) +#define UART5_CR2 USART_CR2(UART5_BASE) + +/* Control register 3 (USARTx_CR3) */ +#define USART_CR3(usart_base) MMIO32((usart_base) + 0x08) +#define USART1_CR3 USART_CR3(USART1_BASE) +#define USART2_CR3 USART_CR3(USART2_BASE) +#define USART3_CR3 USART_CR3(USART3_BASE) +#define UART4_CR3 USART_CR3(UART4_BASE) +#define UART5_CR3 USART_CR3(UART5_BASE) + +/* Baud rate register (USARTx_BRR) */ +#define USART_BRR(usart_base) MMIO32((usart_base) + 0x0C) +#define USART1_BRR USART_BRR(USART1_BASE) +#define USART2_BRR USART_BRR(USART2_BASE) +#define USART3_BRR USART_BRR(USART3_BASE) +#define UART4_BRR USART_BRR(UART4_BASE) +#define UART5_BRR USART_BRR(UART5_BASE) + +/* Guard time and prescaler register (USARTx_GTPR) */ +#define USART_GTPR(usart_base) MMIO32((usart_base) + 0x10) +#define USART1_GTPR USART_GTPR(USART1_BASE) +#define USART2_GTPR USART_GTPR(USART2_BASE) +#define USART3_GTPR USART_GTPR(USART3_BASE) +#define UART4_GTPR USART_GTPR(UART4_BASE) +#define UART5_GTPR USART_GTPR(UART5_BASE) + +/* Receiver timeout register (USART_RTOR) */ +#define USART_RTOR(usart_base) MMIO32((usart_base) + 0x14) +#define USART1_RTOR USART_RTOR(USART1_BASE) +#define USART2_RTOR USART_RTOR(USART2_BASE) +#define USART3_RTOR USART_RTOR(USART3_BASE) +#define UART4_RTOR USART_RTOR(UART4_BASE) +#define UART5_RTOR USART_RTOR(UART5_BASE) + +/* Request register (USART_RQR) */ +#define USART_RQR(usart_base) MMIO32((usart_base) + 0x18) +#define USART1_RQR USART_RQR(USART1_BASE) +#define USART2_RQR USART_RQR(USART2_BASE) +#define USART3_RQR USART_RQR(USART3_BASE) +#define UART4_RQR USART_RQR(UART4_BASE) +#define UART5_RQR USART_RQR(UART5_BASE) + +/* Interrupt & status register (USART_ISR) */ +#define USART_ISR(usart_base) MMIO32((usart_base) + 0x1C) +#define USART1_ISR USART_ISR(USART1_BASE) +#define USART2_ISR USART_ISR(USART2_BASE) +#define USART3_ISR USART_ISR(USART3_BASE) +#define UART4_ISR USART_ISR(UART4_BASE) +#define UART5_ISR USART_ISR(UART5_BASE) + +/* Interrupt flag clear register (USART_ICR) */ +#define USART_ICR(usart_base) MMIO32((usart_base) + 0x20) +#define USART1_ICR USART_ICR(USART1_BASE) +#define USART2_ICR USART_ICR(USART2_BASE) +#define USART3_ICR USART_ICR(USART3_BASE) +#define UART4_ICR USART_ICR(UART4_BASE) +#define UART5_ICR USART_ICR(UART5_BASE) + +/* Receive data register (USART_RDR) */ +#define USART_RDR(usart_base) MMIO32((usart_base) + 0x24) +#define USART1_RDR USART_RDR(USART1_BASE) +#define USART2_RDR USART_RDR(USART2_BASE) +#define USART3_RDR USART_RDR(USART3_BASE) +#define UART4_RDR USART_RDR(UART4_BASE) +#define UART5_RDR USART_RDR(UART5_BASE) + +/* Transmit data register (USART_TDR) */ +#define USART_TDR(usart_base) MMIO32((usart_base) + 0x28) +#define USART1_TDR USART_TDR(USART1_BASE) +#define USART2_TDR USART_TDR(USART2_BASE) +#define USART3_TDR USART_TDR(USART3_BASE) +#define UART4_TDR USART_TDR(UART4_BASE) +#define UART5_TDR USART_TDR(UART5_BASE) + + +/* --- USART_CR1 values ---------------------------------------------------- */ + +/* EOBIE: End of Block interrupt enable */ +#define USART_CR1_EOBIE (1 << 27) + +/* RTOIE: Receiver timeout interrupt enable */ +#define USART_CR1_RTOIE (1 << 26) + +/* DEAT[4:0]: Driver Enable assertion time */ + +/* DEDT[4:0]: Driver Enable deassertion time */ + +/* OVER8: Oversampling mode */ +#define USART_CR1_OVER8 (1 << 15) + +/* CMIE: Character match interrupt enable */ +#define USART_CR1_CMIE (1 << 14) + +/* MME: Mute mode enable */ +#define USART_CR1_MME (1 << 13) + +/* M: Word length */ +#define USART_CR1_M (1 << 12) + +/* WAKE: Receiver wakeup method */ +#define USART_CR1_WAKE (1 << 11) + +/* PCE: Parity control enable */ +#define USART_CR1_PCE (1 << 10) + +/* PS: Parity selection */ +#define USART_CR1_PS (1 << 9) + +/* PEIE: PE interrupt enable */ +#define USART_CR1_PEIE (1 << 8) + +/* TXEIE: Interrupt enable */ +#define USART_CR1_TXEIE (1 << 7) + +/* TCIE: Transmission complete interrupt enable */ +#define USART_CR1_TCIE (1 << 6) + +/* RXNEIE: RXNE interrupt enable */ +#define USART_CR1_RXNEIE (1 << 5) + +/* IDLEIE: IDLE interrupt enable */ +#define USART_CR1_IDLEIE (1 << 4) + +/* TE: Transmitter enable */ +#define USART_CR1_TE (1 << 3) + +/* RE: Receiver enable */ +#define USART_CR1_RE (1 << 2) + +/* UESM: USART enable in Stop mode */ +#define USART_CR1_UESM (1 << 1) + +/* UE: USART enable */ +#define USART_CR1_UE (1 << 0) + + +/* --- USART_CR2 values ---------------------------------------------------- */ + +/* ADD[7:4]: Address of the USART node (31,28) */ +#define USART_CR2_ADD1_MASK (0xF << 28) + +/* ADD[3:0]: Address of the USART node (27,24) */ +#define USART_CR2_ADD2_MASK (0xF << 24) + +/* RTOEN: Receiver timeout enable */ +#define USART_CR2_RTOEN (1 << 23) + +/* ABRMOD[1:0]: Auto baud rate mode */ +#define USART_CR2_ABRMOD_BAUD (0x0 << 21) +#define USART_CR2_ABRMOD_FALL_EDGE (0x1 << 21) +#define USART_CR2_ABRMOD_FRAME_0x7F (0x2 << 21) +#define USART_CR2_ABRMOD_FRAME_0x55 (0x3 << 21) + +/* ABREN: Auto baud rate enable */ +#define USART_CR2_ABREN (1 << 20) + +/* MSBFIRST: Most significant bit first */ +#define USART_CR2_MSBFIRST (1 << 19) + +/* DATAINV: Binary data inversion */ +#define USART_CR2_DATAINV (1 << 18) + +/* TXINV: TX pin active level inversion */ +#define USART_CR2_TXINV (1 << 17) + +/* RXINV: RX pin active level inversion */ +#define USART_CR2_RXINV (1 << 16) + +/* SWAP: Swap TX/RX pins */ +#define USART_CR2_SWAP (1 << 15) + +/* LINEN: LIN mode enable */ +#define USART_CR2_LINEN (1 << 14) + +/* STOP[13:12]: STOP bits */ +#define USART_CR2_STOPBITS_1 (0x00 << 12) /* 1 stop bit */ +#define USART_CR2_STOPBITS_0_5 (0x01 << 12) /* 0.5 stop bits */ +#define USART_CR2_STOPBITS_2 (0x02 << 12) /* 2 stop bits */ +#define USART_CR2_STOPBITS_1_5 (0x03 << 12) /* 1.5 stop bits */ +#define USART_CR2_STOPBITS_MASK (0x03 << 12) +#define USART_CR2_STOPBITS_SHIFT 12 + +/* CLKEN: Clock enable */ +#define USART_CR2_CLKEN (1 << 11) + +/* CPOL: Clock polarity */ +#define USART_CR2_CPOL (1 << 10) + +/* CPHA: Clock phase */ +#define USART_CR2_CPHA (1 << 9) + +/* LBCL: Last bit clock pulse */ +#define USART_CR2_LBCL (1 << 8) + +/* LBDIE: LIN break detection interrupt enable */ +#define USART_CR2_LBDIE (1 << 6) + +/* LBDL: LIN break detection length */ +#define USART_CR2_LBDL (1 << 5) + +/* ADDM7:7-bit Address Detection/4-bit Address Detection */ +#define USART_CR2_ADDM7 (1 << 4) + +/* ADD[3:0]: Address of the usart node +#define USART_CR2_ADD_MASK 0xF */ + +/* --- USART_CR3 values ---------------------------------------------------- */ + +/* WUFIE: Wakeup from Stop mode interrupt enable */ +#define USART_CR3_WUFIE (1 << 22) + +/* WUS[1:0]: Wakeup from Stop mode interrupt flag selectio */ +#define USART_CR3_WUS_ON (0x0 << 20) +/* RESERVE #define USART_CR3_WUS (0x1 << 20) */ +#define USART_CR3_WUS_START_BIT (0x2 << 20) +#define USART_CR3_WUS_RXNE (0x3 << 20) + +/* SCARCNT[2:0]: Smartcard auto-retry count */ +#define USART_CR3_SCARCNT_OFF (0x0 << 17) +/* 0x1 to 0x7: number of automatic retransmission attempts */ + +/* DEP: Driver enable polarity selection */ +#define USART_CR3_DEP (1 << 15) + +/* DEM: Driver enable mode */ +#define USART_CR3_DEM (1 << 14) + +/* DDRE: DMA Disable on Reception Error */ +#define USART_CR3_DDRE (1 << 13) + +/* OVRDIS: Overrun Disable */ +#define USART_CR3_OVRDIS (1 << 12) + +/* ONEBIT: One sample bit method enable */ +#define USART_CR3_ONEBIT (1 << 11) + +/* CTSIE: CTS interrupt enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_CTSIE (1 << 10) + +/* CTSE: CTS enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_CTSE (1 << 9) + +/* RTSE: RTS enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_RTSE (1 << 8) + +/* DMAT: DMA enable transmitter */ +/* Note: N/A on UART5 */ +#define USART_CR3_DMAT (1 << 7) + +/* DMAR: DMA enable receiver */ +/* Note: N/A on UART5 */ +#define USART_CR3_DMAR (1 << 6) + +/* SCEN: Smartcard mode enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_SCEN (1 << 5) + +/* NACK: Smartcard NACK enable */ +/* Note: N/A on UART4 & UART5 */ +#define USART_CR3_NACK (1 << 4) + +/* HDSEL: Half-duplex selection */ +#define USART_CR3_HDSEL (1 << 3) + +/* IRLP: IrDA low-power */ +#define USART_CR3_IRLP (1 << 2) + +/* IREN: IrDA mode enable */ +#define USART_CR3_IREN (1 << 1) + +/* EIE: Error interrupt enable */ +#define USART_CR3_EIE (1 << 0) + +/* --- USART_BRR values ---------------------------------------------------- */ + +/* DIV_Mantissa[11:0]: mantissa of USARTDIV */ +#define USART_BRR_DIV_MANTISSA_MASK (0xFFF << 4) +/* DIV_Fraction[3:0]: fraction of USARTDIV */ +#define USART_BRR_DIV_FRACTION_MASK 0xF + +/* --- USART_GTPR values --------------------------------------------------- */ + +/* GT[7:0]: Guard time value */ +/* Note: N/A on UART4 & UART5 */ +#define USART_GTPR_GT_MASK (0xFF << 8) + +/* PSC[7:0]: Prescaler value */ +/* Note: N/A on UART4/5 */ +#define USART_GTPR_PSC_MASK 0xFF + + +/* --- USART_RQR values --------------------------------------------------- */ + +/* TXFRQ: Transmit data flush request */ +#define USART_RQR_TXFRQ (1 << 4) + +/* RXFRQ: Receive data flush request */ +#define USART_RQR_RXFRQ (1 << 3) + +/* MMRQ: Mute mode request */ +#define USART_RQR_MMRQ (1 << 2) + +/* SBKRQ: Send break request */ +#define USART_RQR_SBKRQ (1 << 1) + +/* ABRRQ: Auto baud rate request */ +#define USART_RQR_ABKRQ (1 << 0) + +/* --- USART_ISR values --------------------------------------------------- */ + +/* REACK: Receive enable acknowledge flag */ +#define USART_ISR_REACK (1 << 22) + +/* TEACK: Transmit enable acknowledge flag */ +#define USART_ISR_TEACK (1 << 21) + +/* WUF: Wakeup from Stop mode flag */ +#define USART_ISR_WUF (1 << 20) + +/* RWU: Receiver wakeup from Mute mode */ +#define USART_ISR_RWU (1 << 19) + +/* SBKF: Send break flag */ +#define USART_ISR_SBKF (1 << 18) + +/* CMF: Character match flag */ +#define USART_ISR_CMF (1 << 17) + +/* BUSY: Busy flag */ +#define USART_ISR_BUSY (1 << 16) + +/* ABRF: Auto baud rate flag */ +#define USART_ISR_ABRF (1 << 15) + +/* ABRE: Auto baud rate error */ +#define USART_ISR_ABRE (1 << 14) + +/* EOBF: End of block flag */ +#define USART_ISR_EOBF (1 << 12) + +/* RTOF: Receiver timeout */ +#define USART_ISR_RTOF (1 << 11) + +/* CTS: CTS flag */ +#define USART_ISR_CTS (1 << 10) + +/* CTSIF: CTS interrupt flag */ +#define USART_ISR_CTSIF (1 << 9) + +/* LBDF: LIN break detection flag */ +#define USART_ISR_LBDF (1 << 8) + +/* TXE: Transmit data register empty */ +#define USART_ISR_TXE (1 << 7) + +/* TC: Transmission complete */ +#define USART_ISR_TC (1 << 6) + +/* RXNE: Read data register not empty */ +#define USART_ISR_RXNE (1 << 5) + +/* IDLE: Idle line detected */ +#define USART_ISR_IDLE (1 << 4) + +/* ORE: Overrun error */ +#define USART_ISR_ORE (1 << 3) + +/* NF: Noise detected flag */ +#define USART_ISR_NF (1 << 2) + +/* FE: Framing error */ +#define USART_ISR_FE (1 << 1) + +/* PE: Parity error */ +#define USART_ISR_PE (1 << 0) + +/* --- USART_SR values ----------------------------------------------------- */ +/****************************************************************************/ +/** @defgroup usart_sr_flags USART Status register Flags +@ingroup STM32F_usart_defines + +@{*/ + +/** CTS: CTS flag */ +/** @note: undefined on UART4 and UART5 */ +#define USART_SR_CTS USART_ISR_CTS + +/** LBD: LIN break detection flag */ +#define USART_SR_LBD USART_ISR_LBDF + +/** TXE: Transmit data buffer empty */ +#define USART_SR_TXE USART_ISR_TXE + +/** TC: Transmission complete */ +#define USART_SR_TC USART_ISR_TC + +/** RXNE: Read data register not empty */ +#define USART_SR_RXNE USART_ISR_RXNE + +/** IDLE: Idle line detected */ +#define USART_SR_IDLE USART_ISR_IDLE + +/** ORE: Overrun error */ +#define USART_SR_ORE USART_ISR_ORE + +/** NE: Noise error flag */ +#define USART_SR_NE USART_ISR_NF + +/** FE: Framing error */ +#define USART_SR_FE USART_ISR_FE + +/** PE: Parity error */ +#define USART_SR_PE USART_ISR_PE +/**@}*/ + +/* --- USART_ICR values --------------------------------------------------- */ + +/* WUCF: Wakeup from Stop mode clear flag */ +#define USART_ICR_WUCF (1 << 20) + +/* CMCF: Character match clear flag */ +#define USART_ICR_CMCF (1 << 17) + +/* EOBCF: End of timeout clear flag */ +#define USART_ICR_EOBCF (1 << 12) + +/* RTOCF: Receiver timeout clear flag */ +#define USART_ICR_RTOCF (1 << 11) + +/* CTSCF: CTS clear flag */ +#define USART_ICR_CTSCF (1 << 9) + +/* LBDCF: LIN break detection clear flag */ +#define USART_ICR_LBDCF (1 << 8) + +/* TCCF: Transmission complete clear flag */ +#define USART_ICR_TCCF (1 << 6) + +/* IDLECF: Idle line detected clear flag */ +#define USART_ICR_IDLECF (1 << 4) + +/* ORECF: Overrun error clear flag */ +#define USART_ICR_ORECF (1 << 3) + +/* NCF: Noise detected clear flag */ +#define USART_ICR_NCF (1 << 2) + +/* FECF: Framing error clear flag */ +#define USART_ICR_FECF (1 << 1) + +/* PECF: Parity error clear flag */ +#define USART_ICR_PECF (1 << 0) + +/* --- USART_RDR values --------------------------------------------------- */ + +/* RDR[8:0]: Receive data value */ +#define USART_RDR_MASK (0x1FF << 0) + +/* --- USART_TDR values --------------------------------------------------- */ + +/* TDR[8:0]: Transmit data value */ +#define USART_TDR_MASK (0x1FF << 0) + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/adc.h new file mode 100644 index 00000000..7e5c1c8d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/adc.h @@ -0,0 +1,590 @@ +/** @defgroup adc_defines ADC Defines + +@brief Defined Constants and Types for the STM32F4xx Analog to Digital +Converters + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 +Matthew Lai +@author @htmlonly © @endhtmlonly 2009 +Edward Cheeseman + +@date 31 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Matthew Lai + * Copyright (C) 2009 Edward Cheeseman + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* ADC injected channel data offset register x (ADC_JOFRx) (x=1..4) */ +#define ADC_JOFR1(block) MMIO32((block) + 0x14) +#define ADC_JOFR2(block) MMIO32((block) + 0x18) +#define ADC_JOFR3(block) MMIO32((block) + 0x1c) +#define ADC_JOFR4(block) MMIO32((block) + 0x20) + +/* ADC watchdog high threshold register (ADC_HTR) */ +#define ADC_HTR(block) MMIO32((block) + 0x24) + +/* ADC watchdog low threshold register (ADC_LTR) */ +#define ADC_LTR(block) MMIO32((block) + 0x28) + +/* ADC regular sequence register 1 (ADC_SQR1) */ +#define ADC_SQR1(block) MMIO32((block) + 0x2c) + +/* ADC regular sequence register 2 (ADC_SQR2) */ +#define ADC_SQR2(block) MMIO32((block) + 0x30) + +/* ADC regular sequence register 3 (ADC_SQR3) */ +#define ADC_SQR3(block) MMIO32((block) + 0x34) + +/* ADC injected sequence register (ADC_JSQR) */ +#define ADC_JSQR(block) MMIO32((block) + 0x38) + +/* ADC injected data register x (ADC_JDRx) (x=1..4) */ +#define ADC_JDR1(block) MMIO32((block) + 0x3c) +#define ADC_JDR2(block) MMIO32((block) + 0x40) +#define ADC_JDR3(block) MMIO32((block) + 0x44) +#define ADC_JDR4(block) MMIO32((block) + 0x48) + +/* ADC regular data register (ADC_DR) */ +#define ADC_DR(block) MMIO32((block) + 0x4c) + +/* ADC common (shared) registers */ +#define ADC_COMMON_REGISTERS_BASE (ADC1_BASE+0x300) +#define ADC_CSR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x0) +#define ADC_CCR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x4) +#define ADC_CDR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x8) + +/* --- ADC Channels ------------------------------------------------------- */ + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * Thanks ST! F40x and F41x are on 16, F42x and F43x are on 18! + *@{*/ +#define ADC_CHANNEL_TEMP_F40 16 +#define ADC_CHANNEL_TEMP_F42 18 +#define ADC_CHANNEL_VREF 17 +#define ADC_CHANNEL_VBAT 18 +/**@}*/ + +/* --- ADC_SR values ------------------------------------------------------- */ + +#define ADC_SR_OVR (1 << 5) + +/* --- ADC_CR1 values specific to STM32F2,4--------------------------------- */ + +/* OVRIE: Overrun interrupt enable */ +#define ADC_CR1_OVRIE (1 << 26) + +/* RES[1:0]: Resolution */ +/****************************************************************************/ +/** @defgroup adc_cr1_res ADC Resolution. +@ingroup adc_defines + +@{*/ +#define ADC_CR1_RES_12BIT (0x0 << 24) +#define ADC_CR1_RES_10BIT (0x1 << 24) +#define ADC_CR1_RES_8BIT (0x2 << 24) +#define ADC_CR1_RES_6BIT (0x3 << 24) +/**@}*/ +#define ADC_CR1_RES_MASK (0x3 << 24) +#define ADC_CR1_RES_SHIFT 24 + +/* Note: Bits [21:16] are reserved, and must be kept at reset value. */ + +/* --- ADC_CR1 values (note some of these are defined elsewhere) ----------- */ +#define ADC_CR1_AWDCH_MAX 18 + + +/* --- ADC_CR2 values ------------------------------------------------------ */ + +/* SWSTART: Start conversion of regular channels. */ +#define ADC_CR2_SWSTART (1 << 30) + +/* EXTEN[1:0]: External trigger enable for regular channels. */ +/****************************************************************************/ +/** @defgroup adc_trigger_polarity_regular ADC Trigger Polarity +@ingroup adc_defines + +@{*/ +#define ADC_CR2_EXTEN_DISABLED (0x0 << 28) +#define ADC_CR2_EXTEN_RISING_EDGE (0x1 << 28) +#define ADC_CR2_EXTEN_FALLING_EDGE (0x2 << 28) +#define ADC_CR2_EXTEN_BOTH_EDGES (0x3 << 28) +/**@}*/ +#define ADC_CR2_EXTEN_MASK (0x3 << 28) +#define ADC_CR2_EXTEN_SHIFT 28 + +/* EXTSEL[3:0]: External event selection for regular group. */ +/****************************************************************************/ +/** @defgroup adc_trigger_regular ADC Trigger Identifier for Regular group +@ingroup adc_defines + +@{*/ +/** Timer 1 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 24) +/** Timer 1 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 24) +/** Timer 1 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 24) +/** Timer 2 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 24) +/** Timer 2 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM2_CC3 (0x4 << 24) +/** Timer 2 Compare Output 4 */ +#define ADC_CR2_EXTSEL_TIM2_CC4 (0x5 << 24) +/** Timer 2 TRGO Event */ +#define ADC_CR2_EXTSEL_TIM2_TRGO (0x6 << 24) +/** Timer 3 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM3_CC1 (0x7 << 24) +/** Timer 3 TRGO Event */ +#define ADC_CR2_EXTSEL_TIM3_TRGO (0x8 << 24) +/** Timer 4 Compare Output 4 */ +#define ADC_CR2_EXTSEL_TIM4_CC4 (0x9 << 24) +/** Timer 5 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM5_CC1 (0xA << 24) +/** Timer 5 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM5_CC2 (0xB << 24) +/** Timer 5 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM5_CC3 (0xC << 24) +/** Timer 8 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM8_CC1 (0xD << 24) +/** Timer 8 TRGO Event */ +#define ADC_CR2_EXTSEL_TIM8_TRGO (0xE << 24) +/** EXTI Line 11 Event */ +#define ADC_CR2_EXTSEL_EXTI_LINE_11 (0xF << 24) +/**@}*/ +#define ADC_CR2_EXTSEL_MASK (0xF << 24) +#define ADC_CR2_EXTSEL_SHIFT 24 + +/* Bit 23 is reserved */ + +/* JSWSTART: Start conversion of injected channels. */ +#define ADC_CR2_JSWSTART (1 << 22) + +/* JEXTEN[1:0]: External trigger enable for injected channels. */ +/****************************************************************************/ +/** @defgroup adc_trigger_polarity_injected ADC Injected Trigger Polarity +@ingroup adc_defines + +@{*/ +#define ADC_CR2_JEXTEN_DISABLED (0x0 << 20) +#define ADC_CR2_JEXTEN_RISING_EDGE (0x1 << 20) +#define ADC_CR2_JEXTEN_FALLING_EDGE (0x2 << 20) +#define ADC_CR2_JEXTEN_BOTH_EDGES (0x3 << 20) +/**@}*/ +#define ADC_CR2_JEXTEN_MASK (0x3 << 20) +#define ADC_CR2_JEXTEN_SHIFT 20 + +/* JEXTSEL[3:0]: External event selection for injected group. */ +/****************************************************************************/ +/** @defgroup adc_trigger_injected ADC Trigger Identifier for Injected group +@ingroup adc_defines + +@{*/ +#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x0 << 16) +#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x1 << 16) +#define ADC_CR2_JEXTSEL_TIM2_CC1 (0x2 << 16) +#define ADC_CR2_JEXTSEL_TIM2_TRGO (0x3 << 16) +#define ADC_CR2_JEXTSEL_TIM3_CC2 (0x4 << 16) +#define ADC_CR2_JEXTSEL_TIM3_CC4 (0x5 << 16) +#define ADC_CR2_JEXTSEL_TIM4_CC1 (0x6 << 16) +#define ADC_CR2_JEXTSEL_TIM4_CC2 (0x7 << 16) +#define ADC_CR2_JEXTSEL_TIM4_CC3 (0x8 << 16) +#define ADC_CR2_JEXTSEL_TIM4_TRGO (0x9 << 16) +#define ADC_CR2_JEXTSEL_TIM5_CC4 (0xA << 16) +#define ADC_CR2_JEXTSEL_TIM5_TRGO (0xB << 16) +#define ADC_CR2_JEXTSEL_TIM8_CC2 (0xC << 16) +#define ADC_CR2_JEXTSEL_TIM8_CC3 (0xD << 16) +#define ADC_CR2_JEXTSEL_TIM8_CC4 (0xE << 16) +#define ADC_CR2_JEXTSEL_EXTI_LINE_15 (0xF << 16) +/**@}*/ +#define ADC_CR2_JEXTSEL_MASK (0xF << 16) +#define ADC_CR2_JEXTSEL_SHIFT 16 + +/* ALIGN: Data alignement. */ +#define ADC_CR2_ALIGN_RIGHT (0 << 11) +#define ADC_CR2_ALIGN_LEFT (1 << 11) +#define ADC_CR2_ALIGN (1 << 11) + +/* EOCS: End of conversion selection. */ +#define ADC_CR2_EOCS (1 << 10) + +/* DDS: DMA disable selection */ +#define ADC_CR2_DDS (1 << 9) + +/* DMA: Direct memory access mode. (ADC1 and ADC3 only!) */ +#define ADC_CR2_DMA (1 << 8) + +/* Note: Bits [7:2] are reserved and must be kept at reset value. */ + +/* CONT: Continuous conversion. */ +#define ADC_CR2_CONT (1 << 1) + +/* ADON: A/D converter On/Off. */ +/* Note: If any other bit in this register apart from ADON is changed at the + * same time, then conversion is not triggered. This is to prevent triggering + * an erroneous conversion. + * Conclusion: Must be separately written. + */ +#define ADC_CR2_ADON (1 << 0) + +/* --- ADC_SMPR1 values ---------------------------------------------------- */ + +#define ADC_SMPR1_SMP17_LSB 21 +#define ADC_SMPR1_SMP16_LSB 18 +#define ADC_SMPR1_SMP15_LSB 15 +#define ADC_SMPR1_SMP14_LSB 12 +#define ADC_SMPR1_SMP13_LSB 9 +#define ADC_SMPR1_SMP12_LSB 6 +#define ADC_SMPR1_SMP11_LSB 3 +#define ADC_SMPR1_SMP10_LSB 0 +#define ADC_SMPR1_SMP17_MSK (0x7 << ADC_SMPR1_SMP17_LSB) +#define ADC_SMPR1_SMP16_MSK (0x7 << ADC_SMPR1_SMP16_LSB) +#define ADC_SMPR1_SMP15_MSK (0x7 << ADC_SMPR1_SMP15_LSB) +#define ADC_SMPR1_SMP14_MSK (0x7 << ADC_SMPR1_SMP14_LSB) +#define ADC_SMPR1_SMP13_MSK (0x7 << ADC_SMPR1_SMP13_LSB) +#define ADC_SMPR1_SMP12_MSK (0x7 << ADC_SMPR1_SMP12_LSB) +#define ADC_SMPR1_SMP11_MSK (0x7 << ADC_SMPR1_SMP11_LSB) +#define ADC_SMPR1_SMP10_MSK (0x7 << ADC_SMPR1_SMP10_LSB) + +/* --- ADC_SMPR2 values ---------------------------------------------------- */ + +#define ADC_SMPR2_SMP9_LSB 27 +#define ADC_SMPR2_SMP8_LSB 24 +#define ADC_SMPR2_SMP7_LSB 21 +#define ADC_SMPR2_SMP6_LSB 18 +#define ADC_SMPR2_SMP5_LSB 15 +#define ADC_SMPR2_SMP4_LSB 12 +#define ADC_SMPR2_SMP3_LSB 9 +#define ADC_SMPR2_SMP2_LSB 6 +#define ADC_SMPR2_SMP1_LSB 3 +#define ADC_SMPR2_SMP0_LSB 0 +#define ADC_SMPR2_SMP9_MSK (0x7 << ADC_SMPR2_SMP9_LSB) +#define ADC_SMPR2_SMP8_MSK (0x7 << ADC_SMPR2_SMP8_LSB) +#define ADC_SMPR2_SMP7_MSK (0x7 << ADC_SMPR2_SMP7_LSB) +#define ADC_SMPR2_SMP6_MSK (0x7 << ADC_SMPR2_SMP6_LSB) +#define ADC_SMPR2_SMP5_MSK (0x7 << ADC_SMPR2_SMP5_LSB) +#define ADC_SMPR2_SMP4_MSK (0x7 << ADC_SMPR2_SMP4_LSB) +#define ADC_SMPR2_SMP3_MSK (0x7 << ADC_SMPR2_SMP3_LSB) +#define ADC_SMPR2_SMP2_MSK (0x7 << ADC_SMPR2_SMP2_LSB) +#define ADC_SMPR2_SMP1_MSK (0x7 << ADC_SMPR2_SMP1_LSB) +#define ADC_SMPR2_SMP0_MSK (0x7 << ADC_SMPR2_SMP0_LSB) + +/* --- ADC_SMPRx values --------------------------------------------------- */ +/****************************************************************************/ +/* ADC_SMPRG ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_rg ADC Sample Time Selection for All Channels +@ingroup adc_defines + +@{*/ +#define ADC_SMPR_SMP_3CYC 0x0 +#define ADC_SMPR_SMP_15CYC 0x1 +#define ADC_SMPR_SMP_28CYC 0x2 +#define ADC_SMPR_SMP_56CYC 0x3 +#define ADC_SMPR_SMP_84CYC 0x4 +#define ADC_SMPR_SMP_112CYC 0x5 +#define ADC_SMPR_SMP_144CYC 0x6 +#define ADC_SMPR_SMP_480CYC 0x7 +/**@}*/ + +/* --- ADC_SQR1 values ----------------------------------------------------- */ + +#define ADC_SQR_MAX_CHANNELS_REGULAR 16 + +#define ADC_SQR1_SQ16_LSB 15 +#define ADC_SQR1_SQ15_LSB 10 +#define ADC_SQR1_SQ14_LSB 5 +#define ADC_SQR1_SQ13_LSB 0 +#define ADC_SQR1_L_MSK (0xf << ADC_SQR1_L_LSB) +#define ADC_SQR1_SQ16_MSK (0x1f << ADC_SQR1_SQ16_LSB) +#define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQR1_SQ15_LSB) +#define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQR1_SQ14_LSB) +#define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQR1_SQ13_LSB) + +/* --- ADC_SQR2 values ----------------------------------------------------- */ + +#define ADC_SQR2_SQ12_LSB 25 +#define ADC_SQR2_SQ11_LSB 20 +#define ADC_SQR2_SQ10_LSB 15 +#define ADC_SQR2_SQ9_LSB 10 +#define ADC_SQR2_SQ8_LSB 5 +#define ADC_SQR2_SQ7_LSB 0 +#define ADC_SQR2_SQ12_MSK (0x1f << ADC_SQR2_SQ12_LSB) +#define ADC_SQR2_SQ11_MSK (0x1f << ADC_SQR2_SQ11_LSB) +#define ADC_SQR2_SQ10_MSK (0x1f << ADC_SQR2_SQ10_LSB) +#define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQR2_SQ9_LSB) +#define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQR2_SQ8_LSB) +#define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQR2_SQ7_LSB) + +/* --- ADC_SQR3 values ----------------------------------------------------- */ + +#define ADC_SQR3_SQ6_LSB 25 +#define ADC_SQR3_SQ5_LSB 20 +#define ADC_SQR3_SQ4_LSB 15 +#define ADC_SQR3_SQ3_LSB 10 +#define ADC_SQR3_SQ2_LSB 5 +#define ADC_SQR3_SQ1_LSB 0 +#define ADC_SQR3_SQ6_MSK (0x1f << ADC_SQR3_SQ6_LSB) +#define ADC_SQR3_SQ5_MSK (0x1f << ADC_SQR3_SQ5_LSB) +#define ADC_SQR3_SQ4_MSK (0x1f << ADC_SQR3_SQ4_LSB) +#define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQR3_SQ3_LSB) +#define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQR3_SQ2_LSB) +#define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQR3_SQ1_LSB) + +/* --- ADC_JDRx, ADC_DR values --------------------------------------------- */ + +#define ADC_JDATA_LSB 0 +#define ADC_DATA_LSB 0 +#define ADC_JDATA_MSK (0xffff << ADC_JDATA_LSB) +#define ADC_DATA_MSK (0xffff << ADC_DA) + +/* --- Common Registers ---------------------------------------------------- */ + +/* --- ADC_CSR values (read only images) ------------------------------------ */ + +/* OVR3: Overrun ADC3. */ +#define ADC_CSR_OVR3 (1 << 21) + +/* STRT3: Regular channel start ADC3. */ +#define ADC_CSR_STRT3 (1 << 20) + +/* JSTRT3: Injected channel start ADC3. */ +#define ADC_CSR_JSTRT3 (1 << 19) + +/* JEOC3: Injected channel end of conversion ADC3. */ +#define ADC_CSR_JEOC3 (1 << 18) + +/* EOC3: Regular channel end of conversion ADC3. */ +#define ADC_CSR_EOC3 (1 << 17) + +/* EOC3: Regular channel end of conversion ADC3. */ +#define ADC_CSR_AWD3 (1 << 16) + +/* Bits 15:14 Reserved, must be kept at reset value */ + +/* OVR2: Overrun ADC2. */ +#define ADC_CSR_OVR2 (1 << 13) + +/* STRT2: Regular channel start ADC2. */ +#define ADC_CSR_STRT2 (1 << 12) + +/* JSTRT2: Injected channel start ADC2. */ +#define ADC_CSR_JSTRT2 (1 << 11) + +/* JEOC2: Injected channel end of conversion ADC2. */ +#define ADC_CSR_JEOC2 (1 << 10) + +/* EOC2: Regular channel end of conversion ADC2. */ +#define ADC_CSR_EOC2 (1 << 9) + +/* EOC2: Regular channel end of conversion ADC2. */ +#define ADC_CSR_AWD2 (1 << 8) + +/* Bits 7:6 Reserved, must be kept at reset value */ + +/* OVR1: Overrun ADC1. */ +#define ADC_CSR_OVR1 (1 << 5) + +/* STRT1: Regular channel start ADC1. */ +#define ADC_CSR_STRT1 (1 << 4) + +/* JSTRT1: Injected channel start ADC1. */ +#define ADC_CSR_JSTRT1 (1 << 3) + +/* JEOC1: Injected channel end of conversion ADC1. */ +#define ADC_CSR_JEOC1 (1 << 2) + +/* EOC1: Regular channel end of conversion ADC1. */ +#define ADC_CSR_EOC1 (1 << 1) + +/* EOC1: Regular channel end of conversion ADC1. */ +#define ADC_CSR_AWD1 (1 << 0) + +/* --- ADC_CCR values ------------------------------------------------------ */ + +/* TSVREFE: Temperature sensor and Vrefint enable. */ +#define ADC_CCR_TSVREFE (1 << 23) + +/* VBATE: VBat enable. */ +#define ADC_CCR_VBATE (1 << 22) + +/* Bit 18:21 reserved, must be kept at reset value. */ + +/* ADCPRE: ADC prescaler. */ +/****************************************************************************/ +/** @defgroup adc_ccr_adcpre ADC Prescale +@ingroup adc_defines + +@{*/ +#define ADC_CCR_ADCPRE_BY2 (0x0 << 16) +#define ADC_CCR_ADCPRE_BY4 (0x1 << 16) +#define ADC_CCR_ADCPRE_BY6 (0x2 << 16) +#define ADC_CCR_ADCPRE_BY8 (0x3 << 16) +/**@}*/ +#define ADC_CCR_ADCPRE_MASK (0x3 << 16) +#define ADC_CCR_ADCPRE_SHIFT 16 + +/* DMA: Direct memory access mode for multi ADC mode. */ +/****************************************************************************/ +/** @defgroup adc_dma_mode ADC DMA mode for multi ADC mode +@ingroup adc_defines + +@{*/ +#define ADC_CCR_DMA_DISABLE (0x0 << 14) +#define ADC_CCR_DMA_MODE_1 (0x1 << 14) +#define ADC_CCR_DMA_MODE_2 (0x2 << 14) +#define ADC_CCR_DMA_MODE_3 (0x3 << 14) +/**@}*/ +#define ADC_CCR_DMA_MASK (0x3 << 14) +#define ADC_CCR_DMA_SHIFT 14 + +/* DDS: DMA disable selection (for multi-ADC mode). */ +#define ADC_CCR_DDS (1 << 13) + +/* Bit 12 reserved, must be kept at reset value */ + +/* DELAY: Delay between 2 sampling phases. */ +/****************************************************************************/ +/** @defgroup adc_delay ADC Delay between 2 sampling phases +@ingroup adc_defines + +@{*/ +#define ADC_CCR_DELAY_5ADCCLK (0x0 << 8) +#define ADC_CCR_DELAY_6ADCCLK (0x1 << 8) +#define ADC_CCR_DELAY_7ADCCLK (0x2 << 8) +#define ADC_CCR_DELAY_8ADCCLK (0x3 << 8) +#define ADC_CCR_DELAY_9ADCCLK (0x4 << 8) +#define ADC_CCR_DELAY_10ADCCLK (0x5 << 8) +#define ADC_CCR_DELAY_11ADCCLK (0x6 << 8) +#define ADC_CCR_DELAY_12ADCCLK (0x7 << 8) +#define ADC_CCR_DELAY_13ADCCLK (0x8 << 8) +#define ADC_CCR_DELAY_14ADCCLK (0x9 << 8) +#define ADC_CCR_DELAY_15ADCCLK (0xa << 8) +#define ADC_CCR_DELAY_16ADCCLK (0xb << 8) +#define ADC_CCR_DELAY_17ADCCLK (0xc << 8) +#define ADC_CCR_DELAY_18ADCCLK (0xd << 8) +#define ADC_CCR_DELAY_19ADCCLK (0xe << 8) +#define ADC_CCR_DELAY_20ADCCLK (0xf << 8) +/**@}*/ +#define ADC_CCR_DELAY_MASK (0xf << 8) +#define ADC_CCR_DELAY_SHIFT 8 + +/* Bit 7:5 reserved, must be kept at reset value */ + +/* MULTI: Multi ADC mode selection. */ +/****************************************************************************/ +/** @defgroup adc_multi_mode ADC Multi mode selection +@ingroup adc_defines + +@{*/ + +/** All ADCs independent */ +#define ADC_CCR_MULTI_INDEPENDENT (0x00 << 0) + +/* Dual modes (ADC1 + ADC2) */ +/** + * Dual modes (ADC1 + ADC2) Combined regular simultaneous + + * injected simultaneous mode. + */ +#define ADC_CCR_MULTI_DUAL_REG_SIMUL_AND_INJECTED_SIMUL (0x01 << 0) +/** + * Dual modes (ADC1 + ADC2) Combined regular simultaneous + + * alternate trigger mode. + */ +#define ADC_CCR_MULTI_DUAL_REG_SIMUL_AND_ALTERNATE_TRIG (0x02 << 0) +/** Dual modes (ADC1 + ADC2) Injected simultaneous mode only. */ +#define ADC_CCR_MULTI_DUAL_INJECTED_SIMUL (0x05 << 0) +/** Dual modes (ADC1 + ADC2) Regular simultaneous mode only. */ +#define ADC_CCR_MULTI_DUAL_REGULAR_SIMUL (0x06 << 0) +/** Dual modes (ADC1 + ADC2) Interleaved mode only. */ +#define ADC_CCR_MULTI_DUAL_INTERLEAVED (0x07 << 0) +/** Dual modes (ADC1 + ADC2) Alternate trigger mode only. */ +#define ADC_CCR_MULTI_DUAL_ALTERNATE_TRIG (0x09 << 0) + +/* Triple modes (ADC1 + ADC2 + ADC3) */ +/** + * Triple modes (ADC1 + ADC2 + ADC3) Combined regular simultaneous + + * injected simultaneous mode. + */ +#define ADC_CCR_MULTI_TRIPLE_REG_SIMUL_AND_INJECTED_SIMUL (0x11 << 0) +/** + * Triple modes (ADC1 + ADC2 + ADC3) Combined regular simultaneous + + * alternate trigger mode. + */ +#define ADC_CCR_MULTI_TRIPLE_REG_SIMUL_AND_ALTERNATE_TRIG (0x12 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Injected simultaneous mode only. */ +#define ADC_CCR_MULTI_TRIPLE_INJECTED_SIMUL (0x15 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Regular simultaneous mode only. */ +#define ADC_CCR_MULTI_TRIPLE_REGULAR_SIMUL (0x16 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Interleaved mode only. */ +#define ADC_CCR_MULTI_TRIPLE_INTERLEAVED (0x17 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Alternate trigger mode only. */ +#define ADC_CCR_MULTI_TRIPLE_ALTERNATE_TRIG (0x19 << 0) +/**@}*/ + +#define ADC_CCR_MULTI_MASK (0x1f << 0) +#define ADC_CCR_MULTI_SHIFT 0 + +/* --- ADC_CDR values ------------------------------------------------------ */ + +#define ADC_CDR_DATA2_MASK (0xffff << 16) +#define ADC_CDR_DATA2_SHIFT 16 + +#define ADC_CDR_DATA1_MASK (0xffff << 0) +#define ADC_CDR_DATA1_SHIFT 0 + +BEGIN_DECLS + +void adc_set_clk_prescale(uint32_t prescaler); +void adc_set_multi_mode(uint32_t mode); +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity); +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity); +void adc_set_resolution(uint32_t adc, uint32_t resolution); +void adc_enable_overrun_interrupt(uint32_t adc); +void adc_disable_overrun_interrupt(uint32_t adc); +bool adc_get_overrun_flag(uint32_t adc); +void adc_clear_overrun_flag(uint32_t adc); +bool adc_awd(uint32_t adc); +void adc_eoc_after_each(uint32_t adc); +void adc_eoc_after_group(uint32_t adc); +void adc_set_dma_continue(uint32_t adc); +void adc_set_dma_terminate(uint32_t adc); + +void adc_enable_temperature_sensor(void); +void adc_disable_temperature_sensor(void); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crc.h new file mode 100644 index 00000000..ccda3a40 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crc.h @@ -0,0 +1,38 @@ +/** @defgroup crc_defines CRC Defines + +@brief libopencm3 Defined Constants and Types for the STM32F4xx CRC +Generator + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crypto.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crypto.h new file mode 100644 index 00000000..3dd433f7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/crypto.h @@ -0,0 +1,97 @@ +/** @defgroup crypto_defines CRYPTO Defines + * + * @brief Defined constants and Types for the STM32F4xx Crypto Coprocessor + * + * @ingroup STM32F4xx_defines + * + * @version 1.0.0 + * + * @date 22 Jun 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRYPTO_H +#define LIBOPENCM3_CRYPTO_H + +#include + +/**@{*/ + +/* --- CRYP registers ------------------------------------------------------ */ +/** @defgroup crypto_defines_registers Registers (for F42xx or F43xx only) + * + * @brief Register access to the CRYP controller. Registers for F42xx and 43xx + * + * @ingroup crypto_defines + */ +/**@{*/ + +/* CRYP_CSGCMCCMxR: Crypto context registers CCM mode, i=0-7*/ +#define CRYP_CSGCMCCMR(i) MMIO32(CRYP_BASE + 0x50 + (i) * 4) + +/* CRYP_CSGCMxR: Crypto context registers all modes, i=0-7*/ +#define CRYP_CSGCMR(i) MMIO32(CRYP_BASE + 0x70 + (i) * 4) + +/* --- CRYP_CR values ------------------------------------------------------ */ + +/* Only for part STM32F42xx and STM32F43xx: */ + +/* GCM_CMPH: GCM or CCM phase state */ +#define CRYP_CR_GCM_CMPH_SHIFT 16 +#define CRYP_CR_GCM_CMPH (3 << CRYP_CR_GCM_CMPH_SHIFT) +#define CRYP_CR_GCM_CMPH_INIT (0 << CRYP_CR_GCM_CMPH_SHIFT) +#define CRYP_CR_GCM_CMPH_HEADER (1 << CRYP_CR_GCM_CMPH_SHIFT) +#define CRYP_CR_GCM_CMPH_PAYLOAD (2 << CRYP_CR_GCM_CMPH_SHIFT) +#define CRYP_CR_GCM_CMPH_FINAL (3 << CRYP_CR_GCM_CMPH_SHIFT) + +/* ALGOMODE3: Algorithm mode, fourth bit */ +#define CRYP_CR_ALGOMODE3 (1 << 19) + +/**@}*/ + +/** @defgroup crypto_api API (for F42xx or F43xx only) + * + * @brief API for the CRYP controller. + * + * @warning Only for F42xx and 43xx + * + * @ingroup crypto_defines + */ +/**@{*/ + +enum crypto_mode_mac { + ENCRYPT_GCM = CRYP_CR_ALGOMODE_TDES_ECB | CRYP_CR_ALGOMODE3, + ENCRYPT_CCM = CRYP_CR_ALGOMODE_TDES_CBC | CRYP_CR_ALGOMODE3, + DECRYPT_GCM = CRYP_CR_ALGOMODE_TDES_ECB | CRYP_CR_ALGOMODE3 | + CRYP_CR_ALGODIR, + DECRYPT_CCM = CRYP_CR_ALGOMODE_TDES_CBC | CRYP_CR_ALGOMODE3 | + CRYP_CR_ALGODIR, +}; + +BEGIN_DECLS + +void crypto_context_swap(uint32_t *buf); +void crypto_set_mac_algorithm(enum crypto_mode_mac mode); + +END_DECLS +/**@}*/ +/**@}*/ +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dac.h new file mode 100644 index 00000000..f7714f3d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dac.h @@ -0,0 +1,37 @@ +/** @defgroup dac_defines DAC Defines + +@brief Defined Constants and Types for the STM32F4xx DAC + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma.h new file mode 100644 index 00000000..229c64cd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma.h @@ -0,0 +1,37 @@ +/** @defgroup dma_defines DMA Defines + +@ingroup STM32F4xx_defines + +@brief Defined Constants and Types for the STM32F4xx DMA Controller + +@version 1.0.0 + +@date 30 November 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma2d.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma2d.h new file mode 100644 index 00000000..7d6e1abc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dma2d.h @@ -0,0 +1,187 @@ +/** @defgroup dma2d_defines DMA2D Defines + * + * @ingroup STM32F4xx_defines + * + * @brief Defined Constants and Macros for the STM32x4xx DMA2D Peripheral + * + * @version 1.0.0 + * + * @date 15 August 2016 + * LGPL License Terms @ref lgpl_license + */ + +/* + * STM32F4 DMA2D Register defines + * + * Copyright (C) 2016, Chuck McManis + * + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +#include +#include + +#ifndef DMA2D_H +#define DMA2D_H + +/**@{*/ + +/** DMA2D Control Register */ +#define DMA2D_CR MMIO32(DMA2D_BASE + 0x0U) +#define DMA2D_CR_MODE_SHIFT 16 +#define DMA2D_CR_MODE_MASK 0x3 +#define DMA2D_CR_MODE_M2M 0 /* memory to memory */ +#define DMA2D_CR_MODE_M2MWPFC 1 /* memory to memory with pix convert */ +#define DMA2D_CR_MODE_M2MWB 2 /* memory to memory with blend */ +#define DMA2D_CR_MODE_R2M 3 /* register to memory */ +#define DMA2D_CR_CEIE (1 << 13) +#define DMA2D_CR_CTCIE (1 << 12) +#define DMA2D_CR_CAEIE (1 << 11) +#define DMA2D_CR_TWIE (1 << 10) +#define DMA2D_CR_TCIE (1 << 9) +#define DMA2D_CR_TEIE (1 << 8) +#define DMA2D_CR_ABORT (1 << 2) +#define DMA2D_CR_SUSP (1 << 1) +#define DMA2D_CR_START (1 << 0) + +/** DMA2D Interrupt Status Register */ +#define DMA2D_ISR MMIO32(DMA2D_BASE + 0x4U) +#define DMA2D_ISR_CEIF (1 << 5) +#define DMA2D_ISR_CTCIF (1 << 4) +#define DMA2D_ISR_CAEIF (1 << 3) +#define DMA2D_ISR_TWIF (1 << 2) +#define DMA2D_ISR_TCIF (1 << 1) +#define DMA2D_ISR_TEIF (1 << 0) + +/** DMA2D Interrupt Flag Clear Register */ +#define DMA2D_IFCR MMIO32(DMA2D_BASE + 0x8U) +#define DMA2D_IFCR_CCEIF (1 << 5) +#define DMA2D_IFCR_CCTCIF (1 << 4) +#define DMA2D_IFCR_CCAEIF (1 << 3) +#define DMA2D_IFCR_CTWIF (1 << 2) +#define DMA2D_IFCR_CTCIF (1 << 1) +#define DMA2D_IFCR_CTEIF (1 << 0) + +/** DMA2D Foreground Memory Address Register */ +#define DMA2D_FGMAR MMIO32(DMA2D_BASE + 0xCU) + +/** DMA2D Foreground Offset Register */ +#define DMA2D_FGOR MMIO32(DMA2D_BASE + 0x10U) +#define DMA2D_FGOR_LO_SHIFT 0 +#define DMA2D_FGOR_LO_MASK 0x3fff + +/** DMA2D Background Memory Address Register */ +#define DMA2D_BGMAR MMIO32(DMA2D_BASE + 0x14U) + +/** DMA2D Background Offset Register */ +#define DMA2D_BGOR MMIO32(DMA2D_BASE + 0x18U) +#define DMA2D_BGOR_LO_SHIFT 0 +#define DMA2D_BGOR_LO_MASK 0x3fff + +/** DMA2D Foreground and Background PFC Control Register */ +#define DMA2D_FGPFCCR MMIO32(DMA2D_BASE + 0x1cU) +#define DMA2D_BGPFCCR MMIO32(DMA2D_BASE + 0x24U) + +#define DMA2D_xPFCCR_ALPHA_SHIFT 24 +#define DMA2D_xPFCCR_ALPHA_MASK 0xff +#define DMA2D_xPFCCR_AM_SHIFT 16 +#define DMA2D_xPFCCR_AM_MASK 0x3 +#define DMA2D_xPFCCR_AM_NONE 0 +#define DMA2D_xPFCCR_AM_FORCE 1 +#define DMA2D_xPFCCR_AM_PRODUCT 2 +#define DMA2D_xPFCCR_CS_SHIFT 8 +#define DMA2D_xPFCCR_CS_MASK 0xff +#define DMA2D_xPFCCR_START (1 << 5) +#define DMA2D_xPFCCR_CCM_ARGB8888 (0 << 4) +#define DMA2D_xPFCCR_CCM_RGB888 (1 << 4) +#define DMA2D_xPFCCR_CM_SHIFT 0 +#define DMA2D_xPFCCR_CM_MASK 0xf +#define DMA2D_xPFCCR_CM_ARGB8888 0 +#define DMA2D_xPFCCR_CM_RGB888 1 +#define DMA2D_xPFCCR_CM_RGB565 2 +#define DMA2D_xPFCCR_CM_ARGB1555 3 +#define DMA2D_xPFCCR_CM_ARGB4444 4 +#define DMA2D_xPFCCR_CM_L8 5 +#define DMA2D_xPFCCR_CM_AL44 6 +#define DMA2D_xPFCCR_CM_AL88 7 +#define DMA2D_xPFCCR_CM_L4 8 +#define DMA2D_xPFCCR_CM_A8 9 +#define DMA2D_xPFCCR_CM_A4 10 + +/** DMA2D Foreground and Background Color Register */ +#define DMA2D_FGCOLR MMIO32(DMA2D_BASE + 0x20U) +#define DMA2D_BGCOLR MMIO32(DMA2D_BASE + 0x28U) +#define DMA2D_xCOLR_RED_SHIFT 16 +#define DMA2D_xCOLR_RED_MASK 0xff +#define DMA2D_xCOLR_GREEN_SHIFT 8 +#define DMA2D_xCOLR_GREEN_MASK 0xff +#define DMA2D_xCOLR_BLUE_SHIFT 0 +#define DMA2D_xCOLR_BLUE_MASK 0xff + +/** DMA2D Foreground CLUT Memory Address Register */ +#define DMA2D_FGCMAR MMIO32(DMA2D_BASE + 0x2CU) + +/** DMA2D Background CLUT Memory Address Register */ +#define DMA2D_BGCMAR MMIO32(DMA2D_BASE + 0x30U) + +/** DMA2D Output PFC Control Register */ +#define DMA2D_OPFCCR MMIO32(DMA2D_BASE + 0x34U) +#define DMA2D_OPFCCR_CM_SHIFT 0 +#define DMA2D_OPFCCR_CM_MASK 0x3 +#define DMA2D_OPFCCR_CM_ARGB8888 0 +#define DMA2D_OPFCCR_CM_RGB888 1 +#define DMA2D_OPFCCR_CM_RGB565 2 +#define DMA2D_OPFCCR_CM_ARGB4444 3 + +/** DMA2D Output Color Register */ +/* The format of this register depends on PFC control above */ +#define DMA2D_OCOLR MMIO32(DMA2D_BASE + 0x38U) + +/** DMA2D Output Memory Address Register */ +#define DMA2D_OMAR MMIO32(DMA2D_BASE + 0x3CU) + +/** DMA2D Output offset Register */ +#define DMA2D_OOR MMIO32(DMA2D_BASE + 0x40U) +#define DMA2D_OOR_LO_SHIFT 0 +#define DMA2D_OOR_LO_MASK 0x3fff + +/** DMA2D Number of Lines Register */ +#define DMA2D_NLR MMIO32(DMA2D_BASE + 0x44U) +#define DMA2D_NLR_PL_SHIFT 16 +#define DMA2D_NLR_PL_MASK 0x3fff +#define DMA2D_NLR_NL_SHIFT 0 +#define DMA2D_NLR_NL_MASK 0xffff + +/** DMA2D Line Watermark Register */ +#define DMA2D_LWR MMIO32(DMA2D_BASE + 0x48U) +#define DMA2D_LWR_LW_SHIFT 0 +#define DMA2D_LWR_LW_MASK 0xffff + +/** DMA2D AHB Master Timer Config Register */ +#define DMA2D_AMTCR MMIO32(DMA2D_BASE + 0x4CU) +#define DMA2D_AMTCR_DT_SHIFT 8 +#define DMA2D_AMTCR_DT_MASK 0xff +#define DMA2D_AMTCR_EN (1 << 0) + +/** DMA2D Foreground Color Lookup table */ +#define DMA2D_FG_CLUT (uint32_t *)(DMA2D_BASE + 0x400U) + +/** DMA2D Background Color Lookup table */ +#define DMA2D_BG_CLUT (uint32_t *)(DMA2D_BASE + 0x800U) + +/**@}*/ +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/doc-stm32f4.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/doc-stm32f4.h new file mode 100644 index 00000000..39d70916 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/doc-stm32f4.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32F4 + +@version 1.0.0 + +@date 7 September 2012 + +API documentation for ST Microelectronics STM32F4 Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F4xx STM32F4xx +Libraries for ST Microelectronics STM32F4xx series. + +@version 1.0.0 + +@date 7 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F4xx_defines STM32F4xx Defines + +@brief Defined Constants and Types for the STM32F4xx series + +@version 1.0.0 + +@date 7 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dsi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dsi.h new file mode 100644 index 00000000..cf70c001 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/dsi.h @@ -0,0 +1,817 @@ +/** @defgroup dsi_defines DSI Defines + * + * @ingroup STM32F4xx_defines + * + * @brief Defined Constants and Macros for the STM32F4xx DSI Peripheral + * + * @version 1.0.0 + * + * @date 7 July 2016 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * STM32F4 DSI Host Defines + * + * Copyright (C) 2016, Chuck McManis + * + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +#include +#include + +#ifndef DSI_H +#define DSI_H + +/**@{*/ + + +/** + * DSI Host Version Register + */ +#define DSI_VR MMIO32(DSI_BASE + 0x0U) + +/** + * DSI Host Control Register + */ +#define DSI_CR MMIO32(DSI_BASE + 0x4U) +#define DSI_CR_EN (1 << 0) + +/** + * DSI Host Clock Control Register + */ +#define DSI_CCR MMIO32(DSI_BASE + 0x8U) +#define DSI_CCR_TOCKDIV_SHIFT 8 +#define DSI_CCR_TOCKDIV_MASK 0xff +#define DSI_CCR_TXECKDIV_SHIFT 0 +#define DSI_CCR_TXECKDIV_MASK 0xff + +/** + * DSI Host LTDC VCID Register + */ +#define DSI_LVCIDR MMIO32(DSI_BASE + 0xcU) +#define DSI_LVCIDR_VCID_SHIFT 0 +#define DSI_LVCIDR_VCID_MASK 0x3 + +/** + * DSI Host LTDC Color Coding Register + */ +#define DSI_LCOLCR MMIO32(DSI_BASE + 0x10U) +#define DSI_LCOLCR_LPE (1 << 8) +#define DSI_LCOLCR_COLC_SHIFT 0 +#define DSI_LCOLCR_COLC_MASK 0xf + +/** + * DSI Host LTDC Polarity Configuration Register + */ +#define DSI_LPCR MMIO32(DSI_BASE + 0x14U) +#define DSI_LPCR_HSP (1 << 2) +#define DSI_LPCR_VSP (1 << 1) +#define DSI_LPCR_DEP (1 << 0) + +/** + * DSI Host Low-power Configuration Register + */ +#define DSI_LPMCR MMIO32(DSI_BASE + 0x18U) +#define DSI_LPMCR_LPSIZE_SHIFT 16 +#define DSI_LPMCR_LPSIZE_MASK 0xff +#define DSI_LPMCR_VLPSIZE_SHIFT 0 +#define DSI_LPMCR_VLPSIZE_MASK 0xff + +/** + * DSI Host Protocol Configuration Register + */ +#define DSI_PCR MMIO32(DSI_BASE + 0x2cU) +#define DSI_PCR_CRCRXE (1 << 4) +#define DSI_PCR_ECCRXE (1 << 3) +#define DSI_PCR_BTAE (1 << 2) +#define DSI_PCR_ETRXE (1 << 1) +#define DSI_PCR_ETTXE (1 << 0) + +/** + * DSI Host Generic VCID Register + */ +#define DSI_GVCIDR MMIO32(DSI_BASE + 0x30U) +#define DSI_GVCIDR_VCID_SHIFT 0 +#define DSI_GVCIDR_VCID_MASK 0x3 + +/** + * DSI Host mode Configuration Register + */ +#define DSI_MCR MMIO32(DSI_BASE + 0x34U) +#define DSI_MCR_CMDM (1 << 0) + +/** + * DSI Host Video mode Configuration Register + */ +#define DSI_VMCR MMIO32(DSI_BASE + 0x38U) +#define DSI_VMCR_PGO (1 << 24) +#define DSI_VMCR_PGM (1 << 20) +#define DSI_VMCR_PGE (1 << 16) +#define DSI_VMCR_LPCE (1 << 15) +#define DSI_VMCR_FBTAAE (1 << 14) +#define DSI_VMCR_LPHFE (1 << 13) +#define DSI_VMCR_LPHBPE (1 << 12) +#define DSI_VMCR_LPVAE (1 << 11) +#define DSI_VMCR_LPVFPE (1 << 10) +#define DSI_VMCR_LPVBPE (1 << 9) +#define DSI_VMCR_LPVSAE (1 << 8) +#define DSI_VMCR_VMT_SHIFT 0 +#define DSI_VMCR_VMT_MASK 0x3 +#define DSI_VMCR_VMT_NON_BURST_PULSE 0x0 +#define DSI_VMCR_VMT_NON_BURSE_EVENT 0x1 +#define DSI_VMCR_VMT_BURST 0x2 + +/** + * DSI Host Video Packet Configuration Register + */ +#define DSI_VPCR MMIO32(DSI_BASE + 0x3CU) +#define DSI_VPCR_VPSIZE_SHIFT 0 +#define DSI_VPCR_VPSIZE_MASK 0x3fff + +/** + * DSI Host Video Chunks Configuration Register + */ +#define DSI_VCCR MMIO32(DSI_BASE + 0x40U) +#define DSI_VCCR_NUMC_SHIFT 0 +#define DSI_VCCR_NUMC_MASK 0x1fff + +/** + * DSI Host Video Null Packet Configuration Register + */ +#define DSI_VNPCR MMIO32(DSI_BASE + 0x44U) +#define DSI_VNPCR_NPSIZE_SHIFT 0 +#define DSI_VNPCR_NPSIZE_MASK 0x1fff + +/** + * DSI Host Video HSA Configuration Register + */ +#define DSI_VHSACR MMIO32(DSI_BASE + 0x48U) +#define DSI_VHSACR_HSA_SHIFT 0 +#define DSI_VHSACR_HSA_MASK 0xfff + +/** + * DSI Host Video HBP Configuration Register + */ +#define DSI_VHBPCR MMIO32(DSI_BASE + 0x4CU) +#define DSI_VHBPCR_HBP_SHIFT 0 +#define DSI_VHBPCR_HBP_MASK 0xfff + +/** + * DSI Host Video Line Configuration Register + */ +#define DSI_VLCR MMIO32(DSI_BASE + 0x50U) +#define DSI_VLCR_HLINE_SHIFT 0 +#define DSI_VLCR_HLINE_MASK 0x7fff + +/** + * DSI Host Video VSA Configuration Register + */ +#define DSI_VVSACR MMIO32(DSI_BASE + 0x54U) +#define DSI_VVSACR_VSA_SHIFT 0 +#define DSI_VVSACR_VSA_MASK 0x3ff + +/** + * DSI Host Video VBP Configuration Register + */ +#define DSI_VVBPCR MMIO32(DSI_BASE + 0x58U) +#define DSI_VVBPCR_VBP_SHIFT 0 +#define DSI_VVBPCR_VBP_MASK 0x3ff + +/** + * DSI Host Video VFP Configuration Register + */ +#define DSI_VVFPCR MMIO32(DSI_BASE + 0x5CU) +#define DSI_VVFPCR_VFP_SHIFT 0 +#define DSI_VVFPCR_VFP_MASK 0x3ff + +/** + * DSI Host Video VA Configuration Register + */ +#define DSI_VVACR MMIO32(DSI_BASE + 0x60U) +#define DSI_VVACR_VA_SHIFT 0 +#define DSI_VVACR_VA_MASK 0x3fff + +/** + * DSI Host LTDC Command Configuration Register + */ +#define DSI_LCCR MMIO32(DSI_BASE + 0x64U) +#define DSI_LCCR_CMDSIZE_SHIFT 0 +#define DSI_LCCR_CMDSIZE_MASK 0xffff + +/** + * DSI Host Command mode Configuration Register + */ +#define DSI_CMCR MMIO32(DSI_BASE + 0x68U) +#define DSI_CMCR_MRDPS (1 << 24) +#define DSI_CMCR_DLWTX (1 << 19) +#define DSI_CMCR_DSR0TX (1 << 18) +#define DSI_CMCR_DSW1TX (1 << 17) +#define DSI_CMCR_DSW0TX (1 << 16) +/* Bit 15 reserved */ +#define DSI_CMCR_GLWTX (1 << 14) +#define DSI_CMCR_GSR2TX (1 << 13) +#define DSI_CMCR_GSR1TX (1 << 12) +#define DSI_CMCR_GSR0TX (1 << 11) +#define DSI_CMCR_GSW2TX (1 << 10) +#define DSI_CMCR_GSW1TX (1 << 9) +#define DSI_CMCR_GSW0TX (1 << 8) +/* Bits 7:2 Reserved */ +#define DSI_CMCR_ARE (1 << 1) +#define DSI_CMCR_TEARE (1 << 0) + +/** + * DSI Host Generic Header Configuration Register + */ +#define DSI_GHCR MMIO32(DSI_BASE + 0x6CU) +#define DSI_GHCR_WCMSB_SHIFT 16 +#define DSI_GHCR_WCMSB_MASK 0xff +#define DSI_GHCR_WCLSB_SHIFT 8 +#define DSI_GHCR_WCLSB_MASK 0xff +#define DSI_GHCR_DATA1_SHIFT 16 /* data 1 in 'short' mode */ +#define DSI_GHCR_DATA1_MASK 0xff +#define DSI_GHCR_DATA0_SHIFT 8 /* data 0 in 'short' mode */ +#define DSI_GHCR_DATA0_MASK 0xff +#define DSI_GHCR_VCID_SHIFT 6 +#define DSI_GHCR_VCID_MASK 0x3 +#define DSI_GHCR_DT_SHIFT 0 +#define DSI_GHCR_DT_MASK 0x3f + +/** + * DSI Host Generic Payload Data Register + */ +#define DSI_GPDR MMIO32(DSI_BASE + 0x70U) +#define DSI_GPDR_BYTE4_SHIFT 24 +#define DSI_GPDR_BYTE4_MASK 0xff +#define DSI_GPDR_BYTE3_SHIFT 16 +#define DSI_GPDR_BYTE3_MASK 0xff +#define DSI_GPDR_BYTE2_SHIFT 8 +#define DSI_GPDR_BYTE2_MASK 0xff +#define DSI_GPDR_BYTE1_SHIFT 0 +#define DSI_GPDR_BYTE1_MASK 0xff + +/** + * DSI Host Generate Packet Status Register + */ +#define DSI_GPSR MMIO32(DSI_BASE + 0x74U) +/* Reserved 31:7 */ +#define DSI_GPSR_RCB (1 << 6) +#define DSI_GPSR_PRDFF (1 << 5) +#define DSI_GPSR_PRDFE (1 << 4) +#define DSI_GPSR_PWRFF (1 << 3) +#define DSI_GPSR_PWRFE (1 << 2) +#define DSI_GPSR_CMDFF (1 << 1) +#define DSI_GPSR_CMDFE (1 << 0) + +/** + * DSI Host Timeout Counter Configuration Register + */ +#define DSI_TCCR0 MMIO32(DSI_BASE + 0x78U) +#define DSI_TCCR0_HSTX_TOCNT_SHIFT 16 +#define DSI_TCCR0_HSTX_TOCNT_MASK 0xffff +#define DSI_TCCR0_LPRX_TOCNT_SHIFT 0 +#define DSI_TCCR0_LPRX_TOCNT_MASK 0xffff + +/** + * DSI Host Timeout Counter Configuration Register 1 + */ +#define DSI_TCCR1 MMIO32(DSI_BASE + 0x7CU) +#define DSI_TCCR1_HSRD_TOCNT_SHIFT 0 +#define DSI_TCCR1_HSRD_TOCNT_MASK 0xffff + +/** + * DSI Host Timeout Counter Configuration Register 2 + */ +#define DSI_TCCR2 MMIO32(DSI_BASE + 0x80U) +#define DSI_TCCR2_LPRD_TOCNT_SHIFT 0 +#define DSI_TCCR2_LPRD_TOCNT_MASK 0xffff + +/** + * DSI Host Timeout Counter Configuration Register 3 + */ +#define DSI_TCCR3 MMIO32(DSI_BASE + 0x84U) +#define DSI_TCCR3_PM (1 << 24) +#define DSI_TCCR3_HSWR_TOCNT_SHIFT 0 +#define DSI_TCCR3_HSWR_TOCNT_MASK 0xffff + +/** + * DSI Host Timeout Counter Configuration Register 4 + */ +#define DSI_TCCR4 MMIO32(DSI_BASE + 0x88U) +#define DSI_TCCR4_LSWR_TOCNT_SHIFT 0 +#define DSI_TCCR4_LSWR_TOCNT_MASK 0xffff + +/** + * DSI Host Timeout Counter Configuration Register 5 + */ +#define DSI_TCCR5 MMIO32(DSI_BASE + 0x8CU) +#define DSI_TCCR5_BTA_TOCNT_SHIFT 0 +#define DSI_TCCR5_BTA_TOCNT_MASK 0xffff + +/** + * DSI Host Clock Lane Configuration Register + */ +#define DSI_CLCR MMIO32(DSI_BASE + 0x94U) +#define DSI_CLCR_ACR (1 << 1) +#define DSI_CLCR_DPCC (1 << 0) + +/** + * DSI Host Clock Lane Timer Configuration Register + */ +#define DSI_CLTCR MMIO32(DSI_BASE + 0x98U) +#define DSI_CLTCR_HS2LP_TIME_SHIFT 16 +#define DSI_CLTCR_HS2LP_TIME_MASK 0x3ff +#define DSI_CLTCR_LP2HS_TIME_SHIFT 0 +#define DSI_CLTCR_LP2HS_TIME_MASK 0x3ff + +/** + * DSI Host Data Lane Time Configuration Register + */ +#define DSI_DLTCR MMIO32(DSI_BASE + 0x9CU) +#define DSI_DLTCR_HS2LP_TIME_SHIFT 24 +#define DSI_DLTCR_HS2LP_TIME_MASK 0xff +#define DSI_DLTCR_LP2HS_TIME_SHIFT 16 +#define DSI_DLTCR_LP2HS_TIME_MASK 0xff +#define DSI_DLTCR_MRD_TIME_SHIFT 0 +#define DSI_DLTCR_MRD_TIME_MASK 0x7fff + +/** + * DSI Host PHY Control Register + */ +#define DSI_PCTLR MMIO32(DSI_BASE + 0xA0U) +#define DSI_PCTLR_CKE (1 << 2) +#define DSI_PCTLR_DEN (1 << 1) + +/** + * DSI Host PHY Configuration Register + */ +#define DSI_PCONFR MMIO32(DSI_BASE + 0xA4U) +#define DSI_PCONFR_SW_TIME_SHIFT 8 +#define DSI_PCONFR_SW_TIME_MASK 0xff +#define DSI_PCONFR_NL_SHIFT 0 +#define DSI_PCONFR_NL_MASK 0x3 +#define DSI_PCONFR_NL_1LANE 0 +#define DSI_PCONFR_NL_2LANE 1 + +/** + * DSI Host PHY ULPS Control Register + */ +#define DSI_PUCR MMIO32(DSI_BASE + 0xA8U) +#define DSI_PUCR_UEDL (1 << 3) +#define DSI_PUCR_URDL (1 << 2) +#define DSI_PUCR_UECL (1 << 1) +#define DSI_PUCR_URCL (1 << 0) + +/** + * DSI Host PHY TX Triggers Configuration Register + */ +#define DSI_PTTCR MMIO32(DSI_BASE + 0xACU) +#define DSI_PTTCR_TX_TRIG_SHIFT 0 +#define DSI_PTTCR_TX_TRIG_MASK 0xf +#define DSI_PTTCR_TX_TRIG_1 0x1 +#define DSI_PTTCR_TX_TRIG_2 0x2 +#define DSI_PTTCR_TX_TRIG_3 0x4 +#define DSI_PTTCR_TX_TRIG_4 0x8 + +/** + * DSI Host PHY Status Register + */ +#define DSI_PSR MMIO32(DSI_BASE + 0xB0U) +#define DSI_PSR_UAN1 (1 << 8) +#define DSI_PSR_PSS1 (1 << 7) +#define DSI_PSR_RUE0 (1 << 6) +#define DSI_PSR_UAN0 (1 << 5) +#define DSI_PSR_PSS0 (1 << 4) +#define DSI_PSR_UANC (1 << 3) +#define DSI_PSR_PSSC (1 << 2) +#define DSI_PSR_PD (1 << 1) + +/** + * DSI Host Interrupt & Status Register 0 + */ +#define DSI_ISR0 MMIO32(DSI_BASE + 0xBCU) +#define DSI_ISR0_PE4 (1 << 20) +#define DSI_ISR0_PE3 (1 << 19) +#define DSI_ISR0_PE2 (1 << 18) +#define DSI_ISR0_PE1 (1 << 17) +#define DSI_ISR0_PE0 (1 << 16) +#define DSI_ISR0_AE15 (1 << 15) +#define DSI_ISR0_AE14 (1 << 14) +#define DSI_ISR0_AE13 (1 << 13) +#define DSI_ISR0_AE12 (1 << 12) +#define DSI_ISR0_AE11 (1 << 11) +#define DSI_ISR0_AE10 (1 << 10) +#define DSI_ISR0_AE9 (1 << 9) +#define DSI_ISR0_AE8 (1 << 8) +#define DSI_ISR0_AE7 (1 << 7) +#define DSI_ISR0_AE6 (1 << 6) +#define DSI_ISR0_AE5 (1 << 5) +#define DSI_ISR0_AE4 (1 << 4) +#define DSI_ISR0_AE3 (1 << 3) +#define DSI_ISR0_AE2 (1 << 2) +#define DSI_ISR0_AE1 (1 << 1) +#define DSI_ISR0_AE0 (1 << 0) + +/** + * DSI Host Interrupt & Status Register 1 + */ +#define DSI_ISR1 MMIO32(DSI_BASE + 0xC0U) +#define DSI_ISR1_GPRXE (1 << 12) +#define DSI_ISR1_GPRDE (1 << 11) +#define DSI_ISR1_GPTXE (1 << 10) +#define DSI_ISR1_GPWRE (1 << 9) +#define DSI_ISR1_GCWRE (1 << 8) +#define DSI_ISR1_LPWRE (1 << 7) +#define DSI_ISR1_EOTPE (1 << 6) +#define DSI_ISR1_PSE (1 << 5) +#define DSI_ISR1_CRCE (1 << 4) +#define DSI_ISR1_ECCME (1 << 3) +#define DSI_ISR1_ECCSE (1 << 2) +#define DSI_ISR1_TOLPRX (1 << 1) +#define DSI_ISR1_TOHSTX (1 << 0) + +/** + * DSI Host Interrupt Enable Register 0 + */ +#define DSI_IER0 MMIO32(DSI_BASE + 0xC4U) +#define DSI_IER0_PE4IE (1 << 20) +#define DSI_IER0_PE3IE (1 << 19) +#define DSI_IER0_PE2IE (1 << 18) +#define DSI_IER0_PE1IE (1 << 17) +#define DSI_IER0_PE0IE (1 << 16) +#define DSI_IER0_AE15IE (1 << 15) +#define DSI_IER0_AE14IE (1 << 14) +#define DSI_IER0_AE13IE (1 << 13) +#define DSI_IER0_AE12IE (1 << 12) +#define DSI_IER0_AE11IE (1 << 11) +#define DSI_IER0_AE10IE (1 << 10) +#define DSI_IER0_AE9IE (1 << 9) +#define DSI_IER0_AE8IE (1 << 8) +#define DSI_IER0_AE7IE (1 << 7) +#define DSI_IER0_AE6IE (1 << 6) +#define DSI_IER0_AE5IE (1 << 5) +#define DSI_IER0_AE4IE (1 << 4) +#define DSI_IER0_AE3IE (1 << 3) +#define DSI_IER0_AE2IE (1 << 2) +#define DSI_IER0_AE1IE (1 << 1) +#define DSI_IER0_AE0IE (1 << 0) + +/** + * DSI Host Interrupt Enable Register 1 + */ +#define DSI_IER1 MMIO32(DSI_BASE + 0xC8U) +#define DSI_IER1_GPRXEIE (1 << 12) +#define DSI_IER1_GPRDEIE (1 << 11) +#define DSI_IER1_GPTXEIE (1 << 10) +#define DSI_IER1_GPWREIE (1 << 9) +#define DSI_IER1_GCWREIE (1 << 8) +#define DSI_IER1_LPWREIE (1 << 7) +#define DSI_IER1_EOTPEIE (1 << 6) +#define DSI_IER1_PSEIE (1 << 5) +#define DSI_IER1_CRCEIE (1 << 4) +#define DSI_IER1_ECCMEIE (1 << 3) +#define DSI_IER1_ECCSEIE (1 << 2) +#define DSI_IER1_TOLPRXIE (1 << 1) +#define DSI_IER1_TOHSTXIE (1 << 0) + +/** + * DSI Host Force Interrupt Register 0 + */ +#define DSI_FIR0 MMIO32(DSI_BASE + 0xD8U) +#define DSI_FIR0_FPE4 (1 << 20) +#define DSI_FIR0_FPE3 (1 << 19) +#define DSI_FIR0_FPE2 (1 << 18) +#define DSI_FIR0_FPE1 (1 << 17) +#define DSI_FIR0_FPE0 (1 << 16) +#define DSI_FIR0_FAE15 (1 << 15) +#define DSI_FIR0_FAE14 (1 << 14) +#define DSI_FIR0_FAE13 (1 << 13) +#define DSI_FIR0_FAE12 (1 << 12) +#define DSI_FIR0_FAE11 (1 << 11) +#define DSI_FIR0_FAE10 (1 << 10) +#define DSI_FIR0_FAE9 (1 << 9) +#define DSI_FIR0_FAE8 (1 << 8) +#define DSI_FIR0_FAE7 (1 << 7) +#define DSI_FIR0_FAE6 (1 << 6) +#define DSI_FIR0_FAE5 (1 << 5) +#define DSI_FIR0_FAE4 (1 << 4) +#define DSI_FIR0_FAE3 (1 << 3) +#define DSI_FIR0_FAE2 (1 << 2) +#define DSI_FIR0_FAE1 (1 << 1) +#define DSI_FIR0_FAE0 (1 << 0) + +/** + * DSI Host Force Interrupt Register 1 + */ +#define DSI_FIR1 MMIO32(DSI_BASE + 0xDCU) +#define DSI_FIR1_FGPRXE (1 << 12) +#define DSI_FIR1_FGPRDE (1 << 11) +#define DSI_FIR1_FGPTXE (1 << 10) +#define DSI_FIR1_FGPWRE (1 << 9) +#define DSI_FIR1_FGCWRE (1 << 8) +#define DSI_FIR1_FLPWRE (1 << 7) +#define DSI_FIR1_FEOTPE (1 << 6) +#define DSI_FIR1_FPSE (1 << 5) +#define DSI_FIR1_FCRCE (1 << 4) +#define DSI_FIR1_FECCME (1 << 3) +#define DSI_FIR1_FECCSE (1 << 2) +#define DSI_FIR1_FTOLPRX (1 << 1) +#define DSI_FIR1_FTOHSTX (1 << 0) + +/** + * DSI Host Video Shadow Control Register + */ +#define DSI_VSCR MMIO32(DSI_BASE + 0x100U) +#define DSI_VSCR_UR (1 << 8) +#define DSI_VSCR_EN (1 << 0) + +/** + * DSI Host LTDC Current VCID Register + */ +#define DSI_LCVCIDR MMIO32(DSI_BASE + 0x10CU) +#define DSI_LCVCIDR_VCID_SHIFT 0 +#define DSI_LCVCIDR_VCID_MASK 0x3 + +/** + * DSI Host LTCD Current Color Coding Register + */ +#define DSI_LCCCR MMIO32(DSI_BASE + 0x110U) +#define DSI_LCCR_LPE (1 << 8) +#define DSI_LCCR_COLC_SHIFT 0 +#define DSI_LCCR_COLC_MASK 0xf + +/** + * DSI Host Low-power mode Current Configuration Register + */ +#define DSI_LPMCCR MMIO32(DSI_BASE + 0x118U) +#define DSI_LPMCCR_LPSIZE_SHIFT 16 +#define DSI_LPMCCR_LPSIZE_MASK 0xff +#define DSI_LPMCCR_VLPSIZE_SHIFT 0 +#define DSI_LPMCCR_VLPSIZE_MASK 0xff + +/** + * DSI Host Video mode Current Configuration Register + */ +#define DSI_VMCCR MMIO32(DSI_BASE + 0x138U) +#define DSI_VMCCR_LPCE (1 << 9) +#define DSI_VMCCR_FBTAAE (1 << 8) +#define DSI_VMCCR_LPHFE (1 << 7) +#define DSI_VMCCR_LPHBPE (1 << 6) +#define DSI_VMCCR_LPVAE (1 << 5) +#define DSI_VMCCR_LPVFPE (1 << 4) +#define DSI_VMCCR_LPVBPE (1 << 3) +#define DSI_VMCCR_LPVSAE (1 << 2) +#define DSI_VMCCR_VMT_SHIFT 0 +#define DSI_VMCCR_VMT_MASK 0x3 + +/** + * DSI Host Video Packet Current Configuration Register + */ +#define DSI_VPCCR MMIO32(DSI_BASE + 0x13CU) +#define DSI_VPCCR_VPSIZE_SHIFT 0 +#define DSI_VPCCR_VPSIZE_MASK 0x3fff + +/** + * DSI Host Video Chunks Current Configuration Register + */ +#define DSI_VCCCR MMIO32(DSI_BASE + 0x140U) +#define DSI_VCCCR_NUMC_SHIFT 0 +#define DSI_VCCCR_NUMC_MASK 0x1fff + +/** + * DSI Host Video Null Packet Current Configuration Register + */ +#define DSI_VNPCCR MMIO32(DSI_BASE + 0x144U) +#define DSI_VNPCCR_NPSIZE_SHIFT 0 +#define DSI_VNPCCR_NPSIZE_MASK 0x1fff + +/** + * DSI Host Video HSA Current Configuration Register + */ +#define DSI_VHSACCR MMIO32(DSI_BASE + 0x148U) +#define DSI_VHSACCR_HSA_SHIFT 0 +#define DSI_VHSACCR_HSA_MASK 0xfff + +/** + * DSI Host Video HBP Current Configuration Register + */ +#define DSI_VHBPCCR MMIO32(DSI_BASE + 0x14CU) +#define DSI_VHBPCCR_HBP_SHIFT 0 +#define DSI_VHBPCCR_HBP_MASK 0xfff + +/** + * DSI Host Video Line Current Configuration Register + */ +#define DSI_VLCCR MMIO32(DSI_BASE + 0x150U) +#define DSI_VLCCR_HLINE_SHIFT 0 +#define DSI_VLCCR_HLINE_MASK 0x7fff + +/** + * DSI Host Video VSA Current Configuration Register + */ +#define DSI_VVSACCR MMIO32(DSI_BASE + 0x154U) +#define DSI_VVSACCR_VSA_SHIFT 0 +#define DSI_VVSACCR_VSA_MASK 0x3ff + +/** + * DSI Host Video VBP Current Configuration Register + */ +#define DSI_VVBPCCR MMIO32(DSI_BASE + 0x0158U) +#define DSI_VVBPCCR_VBP_SHIFT 0 +#define DSI_VVBPCCR_VBP_MAST 0x3ff + +/** + * DSI Host Video VFP Current Configuration Register + */ +#define DSI_VVFPCCR MMIO32(DSI_BASE + 0x15CU) +#define DSI_VVFPCCR_VFP_SHIFT 0 +#define DSI_VVFPCCR_VFP_MASK 0x3ff + +/** + * DSI Host Video VA Current Configuration Register + */ +#define DSI_VVACCR MMIO32(DSI_BASE + 0x160U) +#define DSI_VVACCR_VA_SHIFT 0 +#define DSI_VVACCR_VA_MASK 0x3fff + +/** + * DSI Wrapper Configuration Register + */ +#define DSI_WCFGR MMIO32(DSI_BASE + 0x400U) +#define DSI_WCFGR_VSPOL (1 << 7) +#define DSI_WCFGR_AR (1 << 6) +#define DSI_WCFGR_TEPOL (1 << 5) +#define DSI_WCFGR_TESRC (1 << 4) +#define DSI_WCFGR_COLMUX_SHIFT 1 +#define DSI_WCFGR_COLMUX_MASK 7 +#define DSI_WCFGR_DSIM (1 << 0) + +/** + * DSI Wrapper Control Register + */ +#define DSI_WCR MMIO32(DSI_BASE + 0x404U) +#define DSI_WCR_DSIEN (1 << 3) +#define DSI_WCR_LTDCEN (1 << 2) +#define DSI_WCR_SHTDN (1 << 1) +#define DSI_SCR_COLM (1 << 0) + +/** + * DSI Wrapper Interrupt Enable Register + */ +#define DSI_WIER MMIO32(DSI_BASE + 0x408U) +#define DSI_WIER_RRIE (1 << 13) +#define DSI_WIER_PLLUIE (1 << 10) +#define DSI_WIER_PLLLIE (1 << 9) +#define DSI_WIER_ERIE (1 << 1) +#define DSI_WIER_TEIE (1 << 0) + +/** + * DSI Wrapper Interrupt & Status Register + */ +#define DSI_WISR MMIO32(DSI_BASE + 0x40CU) +/* reserved 31:14 */ +#define DSI_WISR_RRIF (1 << 13) +#define DSI_WISR_RRS (1 << 12) +#define DSI_WISR_PLLUIF (1 << 10) +#define DSI_WISR_PLLLIF (1 << 9) +#define DSI_WISR_PLLLS (1 << 8) +/* reserved 7:3 */ +#define DSI_WISR_BUSY (1 << 2) +#define DSI_WISR_ERIF (1 << 1) +#define DSI_WISR_TEIF (1 << 0) + +/** + * DSI Wrapper Interrupt Flag Clear Register + */ +#define DSI_WIFCR MMIO32(DSI_BASE + 0x410U) +/* reserved 31:14 */ +#define DSI_WIFCR_CRRIF (1 << 13) +/* reserved 12:11 */ +#define DSI_WIFCR_CPLLUIF (1 << 10) +#define DSI_WIFCR_CPLLLIF (1 << 9) +/* reserved 8:2 */ +#define DSI_WIFCR_CERIF (1 << 1) +#define DSI_WIFCR_CTEIF (1 << 0) + +/** + * DSI Wrapper PHY Configuration Register 0 + */ +#define DSI_WPCR0 MMIO32(DSI_BASE + 0x418U) +#define DSI_WPCR0_TCLKPOSTEN (1 << 27) +#define DSI_WPCR0_TLPXCEN (1 << 26) +#define DSI_WPCR0_THSEXITEN (1 << 25) +#define DSI_WPCR0_TLPXDEN (1 << 24) +#define DSI_WPCR0_THSZEROEN (1 << 23) +#define DSI_WPCR0_THSTRAILEN (1 << 22) +#define DSI_WPCR0_THSPREPEN (1 << 21) +#define DSI_WPCR0_TCLKZEROEN (1 << 20) +#define DSI_WPCR0_TCLKPREPEN (1 << 19) +#define DSI_WPCR0_PDEN (1 << 18) +#define DSI_WPCR0_TDDL (1 << 16) +#define DSI_WPCR0_CDOFFDL (1 << 14) +#define DSI_WPCR0_FTXSMDL (1 << 13) +#define DSI_WPCR0_FTXSMCL (1 << 12) +#define DSI_WPCR0_HSIDL1 (1 << 11) +#define DSI_WPCR0_HSIDL0 (1 << 10) +#define DSI_WPCR0_HSICL (1 << 9) +#define DSI_WPCR0_SWDL1 (1 << 8) +#define DSI_WPCR0_SWDL0 (1 << 7) +#define DSI_WPCR0_SWCL (1 << 6) +#define DSI_WPCR0_UIX4_SHIFT 0 +#define DSI_WPCR0_UIX4_MASK 0x3f + +/** + * DSI Wrapper PHY Configration Register 1 + */ +#define DSI_WPCR1 MMIO32(DSI_BASE + 0x41CU) +#define DSI_WPCR1_LPRXFT_SHIFT 25 +#define DSI_WPCR1_LPRXFT_MASK 0x3 +#define DSI_WPCR1_FLPRXLPM (1 << 22) +#define DSI_WPCR1_HSTXSRCDL_SHIFT 18 +#define DSI_WPCR1_HSTXSRCDL_MASK 0x3 +#define DSI_WPCR1_HSTXSRCCL_SHIFT 16 +#define DSI_WPCR1_HSTXSRCCL_MASK 0x3 +#define DSI_WPCR1_SDDC (1 << 12) +#define DSI_WPCR1_LPSRCDL_SHIFT 8 +#define DSI_WPCR1_LPSRCDL_MASK 0x3 +#define DSI_WPCR1_HSTXDDL_SHIFT 2 +#define DSI_WPCR1_HSTXDDL_MASK 0x3 +#define DSI_WPCR1_HSTXDCL_SHIFT 0 +#define DSI_WPCR1_HSTXDCL_MASK 0x3 + +/** + * DSI Wrapper PHY Configuration Register 2 + */ +#define DSI_WPCR2 MMIO32(DSI_BASE + 0x420U) +#define DSI_WPCR2_THSTRAIL_SHIFT 24 +#define DSI_WPCR2_THSTRAIL_MASK 0xff +#define DSI_WPCR2_THSPREP_SHIFT 16 +#define DSI_WPCR2_THSPREP_MASK 0xff +#define DSI_WPCR2_TCLKZERO_SHIFT 8 +#define DSI_WPCR2_TCLKZERO_MASK 0xff +#define DSI_WPCR2_TCLKPREP_SHIF 0 +#define DSI_WPCR2_TCLKPREP_MASK 0xff + +/** + * DSI Wrapper PHY Configuration Register 3 + */ +#define DSI_WPCR3 MMIO32(DSI_BASE + 0x424U) +#define DSI_WPCR3_TLPXC_SHIFT 24 +#define DSI_WPCR3_TLPXC_MASK 0xff +#define DSI_WPCR3_THSEXIT_SHIFT 16 +#define DSI_WPCR3_THSEXIT_MASK 0xff +#define DSI_WPCR3_TLPXD_SHIFT 8 +#define DSI_WPCR3_TLPXD_MASK 0xff +#define DSI_WPCR3_THSZERO_SHIFT 0 +#define DSI_WPCR3_THSZERO_MASK 0xff + +/** + * DSI Wrapper PHY Configuration Register 4 + */ +#define DSI_WPCR4 MMIO32(DSI_BASE + 0x428U) +#define DSI_WPCR4_TCLKPOST_SHIFT 0 +#define DSI_WPCR4_TCLKPOST_MASK 0xff + +/** + * DSI Wrapper Regulator and PLL Control Register + */ +#define DSI_WRPCR MMIO32(DSI_BASE + 0x430U) +#define DSI_WRPCR_REGEN (1 << 24) +#define DSI_WRPCR_ODF_SHIFT 16 +#define DSI_WRPCR_ODF_MASK 0x3 +#define DSI_WRPCR_ODF_DIV_1 0 +#define DSI_WRPCR_ODF_DIV_2 1 +#define DSI_WRPCR_ODF_DIV_4 2 +#define DSI_WRPCR_ODF_DIV_8 3 +#define DSI_WRPCR_IDF_SHIFT 11 +#define DSI_WRPCR_IDF_MASK 0xf +#define DSI_WRPCR_IDF_DIV_1 1 +#define DSI_WRPCR_IDF_DIV_2 2 +#define DSI_WRPCR_IDF_DIV_3 3 +#define DSI_WRPCR_IDF_DIV_4 4 +#define DSI_WRPCR_IDF_DIV_5 5 +#define DSI_WRPCR_IDF_DIV_6 6 +#define DSI_WRPCR_IDF_DIV_7 7 +/* valid NDIV values 10 - 125 all other reserved */ +#define DSI_WRPCR_NDIV_SHIFT 2 +#define DSI_WRPCR_NDIV_MASK 0x7f +#define DSI_WRPCR_PLLEN (1 << 0) + +#endif +/**}@*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/exti.h new file mode 100644 index 00000000..b9106787 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/exti.h @@ -0,0 +1,41 @@ +/** @defgroup exti_defines EXTI Defines + * + * @brief Defined Constants and Types for the STM32F4xx External Interrupts + * + * + * @ingroup STM32F4xx_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Piotr Esden-Tempski + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EXTI_H +#define LIBOPENCM3_EXTI_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/flash.h new file mode 100644 index 00000000..55f89721 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/flash.h @@ -0,0 +1,37 @@ +/** @defgroup flash_defines FLASH Defines + * + * @ingroup STM32F4xx_defines + * + * @brief Defined Constants and Types for the STM32F4xx FLASH Memory + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/fmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/fmc.h new file mode 100644 index 00000000..fda08f6d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/fmc.h @@ -0,0 +1,249 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Chuck McManis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FMC_H +#define LIBOPENCM3_FMC_H + +#ifndef LIBOPENCM3_FSMC_H +error "This file should not be included directly, it is included with fsmc.h" +#endif + +/* --- Convenience macros -------------------------------------------------- */ + +#define FMC_BANK5_BASE 0xa0000000U +#define FMC_BANK6_BASE 0xb0000000U +#define FMC_BANK7_BASE 0xc0000000U +#define FMC_BANK8_BASE 0xd0000000U + +/* --- FMC registers ------------------------------------------------------ */ + +/* SDRAM Control Registers 1 .. 2 */ +#define FMC_SDCR(x) MMIO32(FSMC_BASE + 0x140 + 4 * (x)) +#define FMC_SDCR1 FMC_SDCR(0) +#define FMC_SDCR2 FMC_SDCR(1) + + +/* SDRAM Timing Registers 1 .. 2 */ +#define FMC_SDTR(x) MMIO32(FSMC_BASE + 0x148 + 4 * (x)) +#define FMC_SDTR1 FMC_SDTR(0) +#define FMC_SDTR2 FMC_SDTR(1) + +/* SDRAM Command Mode Register */ +#define FMC_SDCMR MMIO32(FSMC_BASE + (uint32_t) 0x150) + +/* SDRAM Refresh Timer Register */ +#define FMC_SDRTR MMIO32(FSMC_BASE + 0x154) + +/* SDRAM Status Register */ +#define FMC_SDSR MMIO32(FSMC_BASE + (uint32_t) 0x158) + +/* --- FMC_SDCRx values ---------------------------------------------------- */ + +/* Bits [31:15]: Reserved. */ + +/* RPIPE: Read Pipe */ +#define FMC_SDCR_RPIPE_SHIFT 13 +#define FMC_SDCR_RPIPE_MASK (3 << FMC_SDCR_RPIPE_SHIFT) +#define FMC_SDCR_RPIPE_NONE (0 << FMC_SDCR_RPIPE_SHIFT) +#define FMC_SDCR_RPIPE_1CLK (1 << FMC_SDCR_RPIPE_SHIFT) +#define FMC_SDCR_RPIPE_2CLK (2 << FMC_SDCR_RPIPE_SHIFT) + +/* RBURST: Burst Read */ +#define FMC_SDCR_RBURST (1 << 12) + +/* SDCLK: SDRAM Clock Configuration */ +#define FMC_SDCR_SDCLK_SHIFT 10 +#define FMC_SDCR_SDCLK_MASK (3 << FMC_SDCR_SDCLK_SHIFT) +#define FMC_SDCR_SDCLK_DISABLE (0 << FMC_SDCR_SDCLK_SHIFT) +#define FMC_SDCR_SDCLK_2HCLK (2 << FMC_SDCR_SDCLK_SHIFT) +#define FMC_SDCR_SDCLK_3HCLK (3 << FMC_SDCR_SDCLK_SHIFT) + +/* WP: Write Protect */ +#define FMC_SDCR_WP_ENABLE (1 << 9) + +/* CAS: CAS Latency */ +#define FMC_SDCR_CAS_SHIFT 7 +#define FMC_SDCR_CAS_1CYC (1 << FMC_SDCR_CAS_SHIFT) +#define FMC_SDCR_CAS_2CYC (2 << FMC_SDCR_CAS_SHIFT) +#define FMC_SDCR_CAS_3CYC (3 << FMC_SDCR_CAS_SHIFT) + +/* NB: Number of Internal banks */ +#define FMC_SDCR_NB2 0 +#define FMC_SDCR_NB4 (1 << 6) + +/* MWID: Memory width */ +#define FMC_SDCR_MWID_SHIFT 4 +#define FMC_SDCR_MWID_8b (0 << FMC_SDCR_MWID_SHIFT) +#define FMC_SDCR_MWID_16b (1 << FMC_SDCR_MWID_SHIFT) +#define FMC_SDCR_MWID_32b (2 << FMC_SDCR_MWID_SHIFT) + +/* NR: Number of rows */ +#define FMC_SDCR_NR_SHIFT 2 +#define FMC_SDCR_NR_11 (0 << FMC_SDCR_NR_SHIFT) +#define FMC_SDCR_NR_12 (1 << FMC_SDCR_NR_SHIFT) +#define FMC_SDCR_NR_13 (2 << FMC_SDCR_NR_SHIFT) + +/* NC: Number of Columns */ +#define FMC_SDCR_NC_SHIFT 0 +#define FMC_SDCR_NC_8 (0 << FMC_SDCR_NC_SHIFT) +#define FMC_SDCR_NC_9 (1 << FMC_SDCR_NC_SHIFT) +#define FMC_SDCR_NC_10 (2 << FMC_SDCR_NC_SHIFT) +#define FMC_SDCR_NC_11 (3 << FMC_SDCR_NC_SHIFT) + +/* --- FMC_SDTRx values --------------------------------------------------- */ + +/* Bits [31:28]: Reserved. */ + +/* TRCD: Row to Column Delay */ +#define FMC_SDTR_TRCD_SHIFT 24 +#define FMC_SDTR_TRCD_MASK (15 << FMC_SDTR_TRCD_SHIFT) + +/* TRP: Row Precharge Delay */ +#define FMC_SDTR_TRP_SHIFT 20 +#define FMC_SDTR_TRP_MASK (15 << FMC_SDTR_TRP_SHIFT) + +/* TWR: Recovery Delay */ +#define FMC_SDTR_TWR_SHIFT 16 +#define FMC_SDTR_TWR_MASK (15 << FMC_SDTR_TWR_SHIFT) + +/* TRC: Row Cycle Delay */ +#define FMC_SDTR_TRC_SHIFT 12 +#define FMC_SDTR_TRC_MASK (15 << FMC_SDTR_TRC_SHIFT) + +/* TRAS: Self Refresh Time */ +#define FMC_SDTR_TRAS_SHIFT 8 +#define FMC_SDTR_TRAS_MASK (15 << FMC_SDTR_TRAS_SHIFT) + +/* TXSR: Exit Self-refresh Delay */ +#define FMC_SDTR_TXSR_SHIFT 4 +#define FMC_SDTR_TXSR_MASK (15 << FMC_SDTR_TXSR_SHIFT) + +/* TRMD: Load Mode Register to Active */ +#define FMC_SDTR_TMRD_SHIFT 0 +#define FMC_SDTR_TMRD_MASK (15 << FMC_SDTR_TMRD_SHIFT) + +/* + * Some config bits only count in CR1 or TR1, even if you + * are just configuring bank 2, so these masks let you copy + * out those bits after you have computed values for CR2 and + * TR2 and put them into CR1 and TR1 + */ +#define FMC_SDTR_DNC_MASK (FMC_SDTR_TRP_MASK | FMC_SDTR_TRC_MASK) +#define FMC_SDCR_DNC_MASK (FMC_SDCR_SDCLK_MASK | \ + FMC_SDCR_RPIPE_MASK | \ + FMC_SDCR_RBURST) + +/* --- FMC_SDCMR values --------------------------------------------------- */ + +/* Bits [31:22]: Reserved. */ + +/* MRD: Mode Register Definition */ +#define FMC_SDCMR_MRD_SHIFT 9 +#define FMC_SDCMR_MRD_MASK (0x1fff << FMC_SDCMR_MRD_SHIFT) + +/* NRFS: Number of Auto-refresh */ +#define FMC_SDCMR_NRFS_SHIFT 5 +#define FMC_SDCMR_NRFS_MASK (15 << FMC_SDCMR_NRFS_SHIFT) + +/* CTB1: Command Target Bank 1 */ +#define FMC_SDCMR_CTB1 (1 << 4) + +/* CTB2: Command Target Bank 2 */ +#define FMC_SDCMR_CTB2 (1 << 3) + +/* MODE: Command Mode */ +#define FMC_SDCMR_MODE_SHIFT 0 +#define FMC_SDCMR_MODE_MASK 7 +#define FMC_SDCMR_MODE_NORMAL 0 +#define FMC_SDCMR_MODE_CLOCK_CONFIG_ENA 1 +#define FMC_SDCMR_MODE_PALL 2 +#define FMC_SDCMR_MODE_AUTO_REFRESH 3 +#define FMC_SDCMR_MODE_LOAD_MODE_REGISTER 4 +#define FMC_SDCMR_MODE_SELF_REFRESH 5 +#define FMC_SDCMR_MODE_POWER_DOWN 6 + +/* --- FMC_SDRTR values ---------------------------------------------------- */ + +/* Bits [31:15]: Reserved. */ + +/* REIE: Refresh Error Interrupt Enable */ +#define FMC_SDRTR_REIE (1 << 14) + +/* COUNT: Refresh Timer Count */ +#define FMC_SDRTR_COUNT_SHIFT 1 +#define FMC_SDRTR_COUNT_MASK (0x1fff << FMC_SDRTR_COUNT_SHIFT) + +/* CRE: Clear Refresh Error Flag */ +#define FMC_SDRTR_CRE (1 << 0) + +/* --- FMC_SDSR values ---------------------------------------------------- */ + +/* Bits [31:6]: Reserved. */ + +/* BUSY: Set if the SDRAM is working on the command */ +#define FMC_SDSR_BUSY (1 << 5) + +/* MODES: Status modes */ +#define FMC_SDSR_MODE_NORMAL 0 +#define FMC_SDSR_MODE_SELF_REFRESH 1 +#define FMC_SDSR_MODE_POWER_DOWN 2 + +/* Mode shift */ +#define FMC_SDSR_MODE2_SHIFT 3 +#define FMC_SDSR_MODE1_SHIFT 1 + +/* RE: Refresh Error */ +#define FMC_SDSR_RE (1 << 0) + +/* Helper function for setting the timing parameters */ +struct sdram_timing { + int trcd; /* RCD Delay */ + int trp; /* RP Delay */ + int twr; /* Write Recovery Time */ + int trc; /* Row Cycle Delay */ + int tras; /* Self Refresh TIme */ + int txsr; /* Exit Self Refresh Time */ + int tmrd; /* Load to Active delay */ +}; + +/* Mode register parameters */ +#define SDRAM_MODE_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODE_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODE_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODE_BURST_LENGTH_8 ((uint16_t)0x0004) +#define SDRAM_MODE_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODE_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define SDRAM_MODE_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODE_CAS_LATENCY_3 ((uint16_t)0x0030) +#define SDRAM_MODE_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define SDRAM_MODE_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODE_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + +enum fmc_sdram_bank { SDRAM_BANK1, SDRAM_BANK2, SDRAM_BOTH_BANKS }; +enum fmc_sdram_command { SDRAM_CLK_CONF, SDRAM_NORMAL, SDRAM_PALL, + SDRAM_AUTO_REFRESH, SDRAM_LOAD_MODE, + SDRAM_SELF_REFRESH, SDRAM_POWER_DOWN }; + +/* Send an array of timing parameters (indices above) to create SDTR register + * value + */ +uint32_t sdram_timing(struct sdram_timing *t); +void sdram_command(enum fmc_sdram_bank bank, enum fmc_sdram_command cmd, + int autorefresh, int modereg); +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/gpio.h new file mode 100644 index 00000000..696b88be --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/gpio.h @@ -0,0 +1,37 @@ +/** @defgroup gpio_defines GPIO Defines + +@brief Defined Constants and Types for the STM32F4xx General Purpose I/O + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/hash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/hash.h new file mode 100644 index 00000000..a44b374b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/hash.h @@ -0,0 +1,36 @@ +/** @defgroup hash_defines HASH Defines + +@ingroup STM32F4xx_defines + +@brief Defined Constants and Types for the STM32F4xx HASH Controller + +@version 1.0.0 + +@date 31 May 2013 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_HASH_H +#define LIBOPENCM3_HASH_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/i2c.h new file mode 100644 index 00000000..890d412f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/i2c.h @@ -0,0 +1,43 @@ +/** @defgroup i2c_defines I2C Defines + +@brief Defined Constants and Types for the STM32F4xx I2C + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 12 October 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +/**@{*/ + +#define I2C3 I2C3_BASE + +/**@}*/ + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/irq.json new file mode 100644 index 00000000..9acf1dd7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/irq.json @@ -0,0 +1,98 @@ +{ + "irqs": [ + "nvic_wwdg", + "pvd", + "tamp_stamp", + "rtc_wkup", + "flash", + "rcc", + "exti0", + "exti1", + "exti2", + "exti3", + "exti4", + "dma1_stream0", + "dma1_stream1", + "dma1_stream2", + "dma1_stream3", + "dma1_stream4", + "dma1_stream5", + "dma1_stream6", + "adc", + "can1_tx", + "can1_rx0", + "can1_rx1", + "can1_sce", + "exti9_5", + "tim1_brk_tim9", + "tim1_up_tim10", + "tim1_trg_com_tim11", + "tim1_cc", + "tim2", + "tim3", + "tim4", + "i2c1_ev", + "i2c1_er", + "i2c2_ev", + "i2c2_er", + "spi1", + "spi2", + "usart1", + "usart2", + "usart3", + "exti15_10", + "rtc_alarm", + "usb_fs_wkup", + "tim8_brk_tim12", + "tim8_up_tim13", + "tim8_trg_com_tim14", + "tim8_cc", + "dma1_stream7", + "fsmc", + "sdio", + "tim5", + "spi3", + "uart4", + "uart5", + "tim6_dac", + "tim7", + "dma2_stream0", + "dma2_stream1", + "dma2_stream2", + "dma2_stream3", + "dma2_stream4", + "eth", + "eth_wkup", + "can2_tx", + "can2_rx0", + "can2_rx1", + "can2_sce", + "otg_fs", + "dma2_stream5", + "dma2_stream6", + "dma2_stream7", + "usart6", + "i2c3_ev", + "i2c3_er", + "otg_hs_ep1_out", + "otg_hs_ep1_in", + "otg_hs_wkup", + "otg_hs", + "dcmi", + "cryp", + "hash_rng", + "fpu", + "uart7", + "uart8", + "spi4", + "spi5", + "spi6", + "sai1", + "lcd_tft", + "lcd_tft_err", + "dma2d" + ], + "partname_humanreadable": "STM32 F4 series", + "partname_doxygen": "STM32F4", + "includeguard": "LIBOPENCM3_STM32_F4_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/iwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/iwdg.h new file mode 100644 index 00000000..12f36120 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/iwdg.h @@ -0,0 +1,39 @@ +/** @defgroup iwdg_defines IWDG Defines + +@brief Defined Constants and Types for the STM32F4xx Independent Watchdog +Timer + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_IWDG_H +#define LIBOPENCM3_IWDG_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/ltdc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/ltdc.h new file mode 100644 index 00000000..adf54d01 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/ltdc.h @@ -0,0 +1,502 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Oliver Meier + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + + +#ifndef LIBOPENCM3_STM32_F4_LTDC_H_ +#define LIBOPENCM3_STM32_F4_LTDC_H_ + + +#include +#include + +/** + * LTDC + */ + + +#define LTDC_SSCR (MMIO32(LTDC_BASE + 0x08)) +#define LTDC_BPCR (MMIO32(LTDC_BASE + 0x0C)) +#define LTDC_AWCR (MMIO32(LTDC_BASE + 0x10)) +#define LTDC_TWCR (MMIO32(LTDC_BASE + 0x14)) +#define LTDC_GCR (MMIO32(LTDC_BASE + 0x18)) +#define LTDC_SRCR (MMIO32(LTDC_BASE + 0x24)) +#define LTDC_BCCR (MMIO32(LTDC_BASE + 0x2C)) +#define LTDC_IER (MMIO32(LTDC_BASE + 0x34)) +#define LTDC_ISR (MMIO32(LTDC_BASE + 0x38)) +#define LTDC_ICR (MMIO32(LTDC_BASE + 0x3C)) +#define LTDC_LIPCR (MMIO32(LTDC_BASE + 0x40)) +#define LTDC_CPSR (MMIO32(LTDC_BASE + 0x44)) +#define LTDC_CDSR (MMIO32(LTDC_BASE + 0x48)) + +/* x == LTDC_LAYER_x */ +#define LTDC_LxCR(x) (MMIO32(LTDC_BASE + 0x84 + 0x80 * ((x) - 1))) +#define LTDC_L1CR LTDC_LxCR(LTDC_LAYER_1) +#define LTDC_L2CR LTDC_LxCR(LTDC_LAYER_2) + +#define LTDC_LxWHPCR(x) (MMIO32(LTDC_BASE + 0x88 + 0x80 * ((x) - 1))) +#define LTDC_L1WHPCR LTDC_LxWHPCR(LTDC_LAYER_1) +#define LTDC_L2WHPCR LTDC_LxWHPCR(LTDC_LAYER_2) + +#define LTDC_LxWVPCR(x) (MMIO32(LTDC_BASE + 0x8C + 0x80 * ((x) - 1))) +#define LTDC_L1WVPCR LTDC_LxWVPCR(LTDC_LAYER_1) +#define LTDC_L2WVPCR LTDC_LxWVPCR(LTDC_LAYER_2) + +#define LTDC_LxCKCR(x) (MMIO32(LTDC_BASE + 0x90 + 0x80 * ((x) - 1))) +#define LTDC_L1CKCR LTDC_LxCKCR(LTDC_LAYER_1) +#define LTDC_L2CKCR LTDC_LxCKCR(LTDC_LAYER_2) + +#define LTDC_LxPFCR(x) (MMIO32(LTDC_BASE + 0x94 + 0x80 * ((x) - 1))) +#define LTDC_L1PFCR LTDC_LxPFCR(LTDC_LAYER_1) +#define LTDC_L2PFCR LTDC_LxPFCR(LTDC_LAYER_2) + +#define LTDC_LxCACR(x) (MMIO32(LTDC_BASE + 0x98 + 0x80 * ((x) - 1))) +#define LTDC_L1CACR LTDC_LxCACR(LTDC_LAYER_1) +#define LTDC_L2CACR LTDC_LxCACR(LTDC_LAYER_2) + +#define LTDC_LxDCCR(x) (MMIO32(LTDC_BASE + 0x9C + 0x80 * ((x) - 1))) +#define LTDC_L1DCCR LTDC_LxDCCR(LTDC_LAYER_1) +#define LTDC_L2DCCR LTDC_LxDCCR(LTDC_LAYER_2) + +#define LTDC_LxBFCR(x) (MMIO32(LTDC_BASE + 0xA0 + 0x80 * ((x) - 1))) +#define LTDC_L1BFCR LTDC_LxBFCR(LTDC_LAYER_1) +#define LTDC_L2BFCR LTDC_LxBFCR(LTDC_LAYER_2) + +#define LTDC_LxCFBAR(x) (MMIO32(LTDC_BASE + 0xAC + 0x80 * ((x) - 1))) +#define LTDC_L1CFBAR LTDC_LxCFBAR(LTDC_LAYER_1) +#define LTDC_L2CFBAR LTDC_LxCFBAR(LTDC_LAYER_2) + +#define LTDC_LxCFBLR(x) (MMIO32(LTDC_BASE + 0xB0 + 0x80 * ((x) - 1))) +#define LTDC_L1CFBLR LTDC_LxCFBLR(LTDC_LAYER_1) +#define LTDC_L2CFBLR LTDC_LxCFBLR(LTDC_LAYER_2) + +#define LTDC_LxCFBLNR(x) (MMIO32(LTDC_BASE + 0xB4 + 0x80 * ((x) - 1))) +#define LTDC_L1CFBLNR LTDC_LxCFBLNR(LTDC_LAYER_1) +#define LTDC_L2CFBLNR LTDC_LxCFBLNR(LTDC_LAYER_2) + +#define LTDC_LxCLUTWR(x) (MMIO32(LTDC_BASE + 0xC4 + 0x80 * ((x) - 1))) +#define LTDC_L1CLUTWR LTDC_LxCLUTWR(LTDC_LAYER_1) +#define LTDC_L2CLUTWR LTDC_LxCLUTWR(LTDC_LAYER_2) + + +#define LTDC_LAYER_1 1 +#define LTDC_LAYER_2 2 + +/* --- LTDC_SSCR values ---------------------------------------------------- */ + +/* Horizontal Synchronization Width */ +#define LTDC_SSCR_HSW_SHIFT 16 +#define LTDC_SSCR_HSW_MASK 0xfff + +/* Vertical Synchronization Height */ +#define LTDC_SSCR_VSH_SHIFT 0 +#define LTDC_SSCR_VSH_MASK 0x7ff + +/* --- LTDC_BPCR values ---------------------------------------------------- */ + +/* Accumulated Horizontal Back Porch */ +#define LTDC_BPCR_AHBP_SHIFT 16 +#define LTDC_BPCR_AHBP_MASK 0xfff + +/* Accumulated Vertical Back Porch */ +#define LTDC_BPCR_AVBP_SHIFT 0 +#define LTDC_BPCR_AVBP_MASK 0x7FF + +/* --- LTDC_AWCR values ---------------------------------------------------- */ + +/* Accumulated Active Width */ +#define LTDC_AWCR_AAW_SHIFT 16 +#define LTDC_AWCR_AAW_MASK 0xfff + +/* Accumulated Active Height */ +#define LTDC_AWCR_AAH_SHIFT 0 +#define LTDC_AWCR_AAH_MASK 0x7ff + +/* --- LTDC_TWCR values ---------------------------------------------------- */ + +/* Total Width */ +#define LTDC_TWCR_TOTALW_SHIFT 16 +#define LTDC_TWCR_TOTALW_MASK 0xfff + +/* Total Height */ +#define LTDC_TWCR_TOTALH_SHIFT 0 +#define LTDC_TWCR_TOTALH_MASK 0x7ff + +/* GCR - control register */ +#define LTDC_GCR_LTDC_ENABLE (1<<0) +#define LTDC_GCR_DITHER_ENABLE (1<<16) + +#define LTDC_GCR_PCPOL_ACTIVE_LOW (0<<28) +#define LTDC_GCR_PCPOL_ACTIVE_HIGH (1<<28) + +#define LTDC_GCR_DEPOL_ACTIVE_LOW (0<<29) +#define LTDC_GCR_DEPOL_ACTIVE_HIGH (1<<29) + +#define LTDC_GCR_VSPOL_ACTIVE_LOW (0<<30) +#define LTDC_GCR_VSPOL_ACTIVE_HIGH (1<<30) + +#define LTDC_GCR_HSPOL_ACTIVE_LOW (0<<31) +#define LTDC_GCR_HSPOL_ACTIVE_HIGH (1<<31) + +/* --- LTDC_SRCR values ---------------------------------------------------- */ + +/* Vertical Blanking Reload */ +#define LTDC_SRCR_VBR (1 << 1) + +/* Immediate Reload */ +#define LTDC_SRCR_IMR (1 << 0) + +/* LTDC_BCCR - reload control */ +#define LTDC_SRCR_RELOAD_IMR (1<<0) +#define LTDC_SRCR_RELOAD_VBR (1<<1) + +/* --- LTDC_IER values ----------------------------------------------------- */ + +/* Register Reload Interrupt Enable */ +#define LTDC_IER_RRIE (1 << 3) + +/* Transfer Error Interrupt Enable */ +#define LTDC_IER_TERRIE (1 << 2) + +/* FIFO Underrun Interrupt Enable */ +#define LTDC_IER_FUIE (1 << 1) + +/* Line Interrupt Enable */ +#define LTDC_IER_LIE (1 << 0) + +/* --- LTDC_ISR values ----------------------------------------------------- */ + +/* Register Reload Interrupt Flag */ +#define LTDC_ISR_RRIF (1 << 3) + +/* Transfer Error Interrupt Flag */ +#define LTDC_ISR_TERRIF (1 << 2) + +/* FIFO Underrun Interrupt Flag */ +#define LTDC_ISR_FUIF (1 << 1) + +/* Line Interrupt Flag */ +#define LTDC_ISR_LIF (1 << 0) + +/* --- LTDC_ICR values ----------------------------------------------------- */ + +/* Clears Register Reload Interrupt Flag */ +#define LTDC_ICR_CRRIF (1 << 3) + +/* Clears Transfer Error Interrupt Flag */ +#define LTDC_ICR_CTERRIF (1 << 2) + +/* Clears FIFO Underrun Interrupt Flag */ +#define LTDC_ICR_CFUIF (1 << 1) + +/* Clears Line Interrupt Flag */ +#define LTDC_ICR_CLIF (1 << 0) + +/* --- LTDC_LIPCR values --------------------------------------------------- */ + +/* Line Interrupt Position */ +#define LTDC_LIPCR_LIPOS_SHIFT 0 +#define LTDC_LIPCR_LIPOS_MASK 0x7ff + +/* --- LTDC_CPSR values ---------------------------------------------------- */ + +/* Current X Position */ +#define LTDC_CPSR_CXPOS_SHIFT 16 +#define LTDC_CPSR_CXPOS_MASK 0xffff + +/* Current Y Position */ +#define LTDC_CPSR_CYPOS_SHIFT 0 +#define LTDC_CPSR_CYPOS_MASK 0xffff + +/* LTDC_CDSR - display status register */ +#define LTDC_CDSR_VDES (1<<0) +#define LTDC_CDSR_HDES (1<<1) +#define LTDC_CDSR_VSYNCS (1<<2) +#define LTDC_CDSR_HSYNCS (1<<3) + +/* LTDC_LxCR - layer control */ +#define LTDC_LxCR_LAYER_ENABLE (1<<0) +#define LTDC_LxCR_COLKEY_ENABLE (1<<1) +#define LTDC_LxCR_COLTAB_ENABLE (1<<4) + +/* --- LTDC_LxWHPCR values ------------------------------------------------- */ + +/* Window Horizontal Stop Position */ +#define LTDC_LxWHPCR_WHSPPOS_SHIFT 16 +#define LTDC_LxWHPCR_WHSPPOS_MASK 0xfff + +/* Window Horizontal Start Position */ +#define LTDC_LxWHPCR_WHSTPOS_SHIFT 0 +#define LTDC_LxWHPCR_WHSTPOS_MASK 0xfff + +/* --- LTDC_LxWVPCR values ------------------------------------------------- */ + +/* Window Vertical Stop Position */ +#define LTDC_LxWVPCR_WVSPPOS_SHIFT 16 +#define LTDC_LxWVPCR_WVSPPOS_MASK 0x7ff + +/* Window Vertical Start Position */ +#define LTDC_LxWVPCR_WVSTPOS_SHIFT 0 +#define LTDC_LxWVPCR_WVSTPOS_MASK 0x7ff + +/* --- LTDC_LxCKCR values -------------------------------------------------- */ + +/* Color Key Red */ +#define LTDC_LxCKCR_CKRED_SHIFT 16 +#define LTDC_LxCKCR_CKRED_MASK 0xff + +/* Color Key Green */ +#define LTDC_LxCKCR_CKGREEN_SHIFT 16 +#define LTDC_LxCKCR_CKGREEN_MASK 0xff + +/* Color Key Blue */ +#define LTDC_LxCKCR_CKBLUE_SHIFT 16 +#define LTDC_LxCKCR_CKBLUE_MASK 0xff + +/* LTDC_LxPFCR - Pixel formats */ +#define LTDC_LxPFCR_ARGB8888 (0b000) +#define LTDC_LxPFCR_RGB888 (0b001) +#define LTDC_LxPFCR_RGB565 (0b010) +#define LTDC_LxPFCR_ARGB1555 (0b011) +#define LTDC_LxPFCR_ARGB4444 (0b100) +#define LTDC_LxPFCR_L8 (0b101) +#define LTDC_LxPFCR_AL44 (0b110) +#define LTDC_LxPFCR_AL88 (0b111) + +/* --- LTDC_LxCACR values -------------------------------------------------- */ + +/* Constant Alpha */ +#define LTDC_LxCACR_CONSTA_SHIFT 0 +#define LTDC_LxCACR_CONSTA_MASK 0xff + +/* --- LTDC_LxDCCR values -------------------------------------------------- */ + +/* Default Color Alpha */ +#define LTDC_LxDCCR_DCALPHA_SHIFT 24 +#define LTDC_LxDCCR_DCALPHA_MASK 1 + +/* Default Color Red */ +#define LTDC_LxDCCR_DCRED_SHIFT 16 +#define LTDC_LxDCCR_DCRED_MASK 1 + +/* Default Color Green */ +#define LTDC_LxDCCR_DCGREEN_SHIFT 8 +#define LTDC_LxDCCR_DCGREEN_MASK 1 + +/* Default Color Blue */ +#define LTDC_LxDCCR_DCBLUE_SHIFT 0 +#define LTDC_LxDCCR_DCBLUE_MASK 1 + +/* LTDC_LxBFCR - Blending factors - BF1 */ +#define LTDC_LxBFCR_BF1_CONST_ALPHA (0b100) +#define LTDC_LxBFCR_BF1_PIXEL_ALPHA_x_CONST_ALPHA (0b110) +/* LTDC_LxBFCR - Blending factors - BF2 */ +#define LTDC_LxBFCR_BF2_CONST_ALPHA (0b101) +#define LTDC_LxBFCR_BF2_PIXEL_ALPHA_x_CONST_ALPHA (0b111) + +/* --- LTDC_LxCFBAR values ------------------------------------------------- */ + +/* Color Frame Buffer Start Address */ +#define LTDC_LxCFBAR_CFBAR_SHIFT 0 +#define LTDC_LxCFBAR_CFBAR_MASK 0xffffffff + +/* --- LTDC_LxCFBLR values ------------------------------------------------- */ + +/* Color Frame Buffer Pitch */ +#define LTDC_LxCFBLR_CFBP_SHIFT 16 +#define LTDC_LxCFBLR_CFBP_MASK 0x1fff + +/* Color Frame Buffer Line Length */ +#define LTDC_LxCFBLR_CFBLL_SHIFT 0 +#define LTDC_LxCFBLR_CFBLL_MASK 0x1fff + +/* --- LTDC_LxCFBLNR values ------------------------------------------------ */ + +/* Frame Buffer Line Number */ +#define LTDC_LxCFBLNR_CFBLNBR_SHIFT 0 +#define LTDC_LxCFBLNR_CFBLNBR_MASK 0x3ff + +/* --- LTDC_LxCLUTWR values ------------------------------------------------ */ + +/* CLUT Address */ +#define LTDC_LxCLUTWR_CLUTADD_SHIFT 24 +#define LTDC_LxCLUTWR_CLUTADD_MASK 0xff + +/* Red */ +#define LTDC_LxCLUTWR_RED_SHIFT 16 +#define LTDC_LxCLUTWR_RED_MASK 0xff + +/* Green */ +#define LTDC_LxCLUTWR_GREEN_SHIFT 8 +#define LTDC_LxCLUTWR_GREEN_MASK 0xff + +/* Blue */ +#define LTDC_LxCLUTWR_BLUE_SHIFT 0 +#define LTDC_LxCLUTWR_BLUE_MASK 0xff + +/** + * simple helper macros + */ + +/* global */ +static inline void ltdc_ctrl_enable(uint32_t ctrl_flags) +{ + LTDC_GCR |= ctrl_flags; +} + +static inline void ltdc_ctrl_disable(uint32_t ctrl_flags) +{ + LTDC_GCR &= ~(ctrl_flags); +} + +static inline void ltdc_reload(uint32_t reload_flags) +{ + LTDC_SRCR = reload_flags; +} + +static inline void ltdc_set_background_color(uint8_t r, uint8_t g, uint8_t b) +{ + LTDC_BCCR = (((r)&255)<<16) | + (((g)&255)<<8) | + (((b)&255)<<0); +} + +static inline void ltdc_get_current_position(uint16_t *x, uint16_t *y) +{ + uint32_t tmp = LTDC_CPSR; + *x = tmp >> 16; + *y = tmp &= 0xFFFF; +} + +static inline uint16_t ltdc_get_current_position_x(void) +{ + return LTDC_CPSR >> 16; +} + +static inline uint16_t ltdc_get_current_position_y(void) +{ + return LTDC_CPSR & 0xffff; +} + +static inline uint32_t ltdc_get_display_status(uint32_t status_flags) +{ + return LTDC_CDSR & status_flags; +} + +/* layers */ +static inline void ltdc_layer_ctrl_enable(uint32_t layer, uint32_t ctrl_flags) +{ + LTDC_LxCR(layer) |= ctrl_flags; +} + +static inline void ltdc_layer_ctrl_disable(uint32_t layer, uint32_t ctrl_flags) +{ + LTDC_LxCR(layer) &= ~(ctrl_flags); +} + +static inline void ltdc_set_color_key(uint32_t layer, + uint8_t r, uint8_t g, uint8_t b) +{ + LTDC_LxCKCR(layer) = ((((r)&255)<<16) | + (((g)&255)<<8) | + (((b)&255)<<0)); +} + +static inline void ltdc_set_pixel_format(uint32_t layer, uint32_t format) +{ + LTDC_LxPFCR(layer) = format; +} + +static inline void ltdc_set_constant_alpha(uint32_t layer, uint8_t alpha) +{ + LTDC_LxCACR(layer) = ((alpha)&255); +} + +static inline void ltdc_set_default_colors(uint32_t layer, + uint8_t a, + uint8_t r, uint8_t g, uint8_t b) +{ + LTDC_LxDCCR(layer) = ((((a)&255)<<24) | + (((r)&255)<<16) | + (((g)&255)<<8) | + (((b)&255)<<0)); +} + +static inline void ltdc_set_blending_factors(uint32_t layer, + uint8_t bf1, uint8_t bf2) +{ + LTDC_LxBFCR(layer) = ((bf1)<<8) | ((bf2)<<0); +} + +static inline void ltdc_set_fbuffer_address(uint32_t layer, uint32_t address) +{ + LTDC_LxCFBAR(layer) = (uint32_t)address; +} + +static inline void ltdc_set_fb_line_length(uint32_t layer, + uint16_t len, uint16_t pitch) +{ + LTDC_LxCFBLR(layer) = ((((pitch)&0x1FFF)<<16) | (((len)&0x1FFF)<<0)); +} + +static inline void ltdc_set_fb_line_count(uint32_t layer, uint16_t linecount) +{ + LTDC_LxCFBLNR(layer) = (((linecount)&0x3FF)<<0); +} + +/** + * more complicated helper functions + */ +void ltdc_set_tft_sync_timings( + uint16_t sync_width, uint16_t sync_height, + uint16_t h_back_porch, uint16_t v_back_porch, + uint16_t active_width, uint16_t active_height, + uint16_t h_front_porch, uint16_t v_front_porch +); +void ltdc_setup_windowing( + uint8_t layer_number, + uint16_t h_back_porch, uint16_t v_back_porch, + uint16_t active_width, uint16_t active_height +); + + + +/** + * Helper function to wait for SRCR reload to complete or so + */ + +static inline bool LTDC_SRCR_IS_RELOADING(void) +{ + return (LTDC_SRCR & (LTDC_SRCR_RELOAD_VBR | + LTDC_SRCR_RELOAD_IMR)) != 0; +} + +/** + * color conversion helper function + * (simulate the ltdc color conversion) + */ + +static inline uint16_t ltdc_get_rgb888_from_rgb565(uint16_t rgb888) +{ + return ((((rgb888) & 0xF800) >> (11-8))/31)<<16 + | ((((rgb888) & 0x07E0) << (8-5))/63)<<8 + | ((((rgb888) & 0x001F) << (8-0))/31)<<0; +} + + +#endif /* LIBOPENCM3_STM32_F4_LTDC_H_ */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/memorymap.h new file mode 100644 index 00000000..fc2c59df --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/memorymap.h @@ -0,0 +1,173 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32F4 specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x20000) +#define PERIPH_BASE_AHB2 0x50000000U +#define PERIPH_BASE_AHB3 0x60000000U + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define TIM12_BASE (PERIPH_BASE_APB1 + 0x1800) +#define TIM13_BASE (PERIPH_BASE_APB1 + 0x1c00) +#define TIM14_BASE (PERIPH_BASE_APB1 + 0x2000) +/* PERIPH_BASE_APB1 + 0x2400 (0x4000 2400 - 0x4000 27FF): Reserved */ +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +#define I2S2_EXT_BASE (PERIPH_BASE_APB1 + 0x3400) +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +#define I2S3_EXT_BASE (PERIPH_BASE_APB1 + 0x4000) +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define UART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define UART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define I2C3_BASE (PERIPH_BASE_APB1 + 0x5C00) +/* PERIPH_BASE_APB1 + 0x6000 (0x4000 6000 - 0x4000 63FF): Reserved */ +#define BX_CAN1_BASE (PERIPH_BASE_APB1 + 0x6400) +#define BX_CAN2_BASE (PERIPH_BASE_APB1 + 0x6800) +/* PERIPH_BASE_APB1 + 0x6C00 (0x4000 6C00 - 0x4000 6FFF): Reserved */ +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define UART7_BASE (PERIPH_BASE_APB1 + 0x7800) +#define UART8_BASE (PERIPH_BASE_APB1 + 0x7c00) +/* PERIPH_BASE_APB1 + 0x7800 (0x4000 8000 - 0x4000 FFFF): Reserved */ + +/* APB2 */ +#define TIM1_BASE (PERIPH_BASE_APB2 + 0x0000) +#define TIM8_BASE (PERIPH_BASE_APB2 + 0x0400) +/* PERIPH_BASE_APB2 + 0x0800 (0x4001 0800 - 0x4001 0FFF): Reserved */ +#define USART1_BASE (PERIPH_BASE_APB2 + 0x1000) +#define USART6_BASE (PERIPH_BASE_APB2 + 0x1400) +/* PERIPH_BASE_APB2 + 0x1800 (0x4001 1800 - 0x4001 1FFF): Reserved */ +#define ADC1_BASE (PERIPH_BASE_APB2 + 0x2000) +#define ADC2_BASE (PERIPH_BASE_APB2 + 0x2100) +#define ADC3_BASE (PERIPH_BASE_APB2 + 0x2200) +#define ADC_COMMON_BASE (PERIPH_BASE_APB2 + 0x2300) +/* PERIPH_BASE_APB2 + 0x2400 (0x4001 2400 - 0x4001 27FF): Reserved */ +#define SDIO_BASE (PERIPH_BASE_APB2 + 0x2C00) +/* PERIPH_BASE_APB2 + 0x2C00 (0x4001 2C00 - 0x4001 2FFF): Reserved */ +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +#define SPI4_BASE (PERIPH_BASE_APB2 + 0x3400) +/* PERIPH_BASE_APB2 + 0x3500 (0x4001 3500 - 0x4001 37FF): Reserved */ +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x3800) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x3C00) +#define TIM9_BASE (PERIPH_BASE_APB2 + 0x4000) +#define TIM10_BASE (PERIPH_BASE_APB2 + 0x4400) +#define TIM11_BASE (PERIPH_BASE_APB2 + 0x4800) +/* PERIPH_BASE_APB2 + 0x4C00 (0x4001 4C00 - 0x4001 4FFF): Reserved */ +#define SPI5_BASE (PERIPH_BASE_APB2 + 0x5000) +#define SPI6_BASE (PERIPH_BASE_APB2 + 0x5400) +#define SAI1_BASE (PERIPH_BASE_APB2 + 0x5800) +#define LTDC_BASE (PERIPH_BASE_APB2 + 0x6800) +#define DSI_BASE (PERIPH_BASE_APB2 + 0x6C00) +/* PERIPH_BASE_APB2 + 0x7400 (0x4001 7400 - 0x4001 FFFF): Reserved */ + +/* AHB1 */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB1 + 0x0000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB1 + 0x0400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB1 + 0x0800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB1 + 0x0C00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB1 + 0x1000) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB1 + 0x1400) +#define GPIO_PORT_G_BASE (PERIPH_BASE_AHB1 + 0x1800) +#define GPIO_PORT_H_BASE (PERIPH_BASE_AHB1 + 0x1C00) +#define GPIO_PORT_I_BASE (PERIPH_BASE_AHB1 + 0x2000) +#define GPIO_PORT_J_BASE (PERIPH_BASE_AHB1 + 0x2400) +#define GPIO_PORT_K_BASE (PERIPH_BASE_AHB1 + 0x2800) +/* PERIPH_BASE_AHB1 + 0x2C00 (0x4002 2C00 - 0x4002 2FFF): Reserved */ +#define CRC_BASE (PERIPH_BASE_AHB1 + 0x3000) +/* PERIPH_BASE_AHB1 + 0x3400 (0x4002 3400 - 0x4002 37FF): Reserved */ +#define RCC_BASE (PERIPH_BASE_AHB1 + 0x3800) +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x3C00) +#define BKPSRAM_BASE (PERIPH_BASE_AHB1 + 0x4000) +/* PERIPH_BASE_AHB1 + 0x5000 (0x4002 5000 - 0x4002 5FFF): Reserved */ +#define DMA1_BASE (PERIPH_BASE_AHB1 + 0x6000) +#define DMA2_BASE (PERIPH_BASE_AHB1 + 0x6400) +/* PERIPH_BASE_AHB1 + 0x6800 (0x4002 6800 - 0x4002 7FFF): Reserved */ +#define ETHERNET_BASE (PERIPH_BASE_AHB1 + 0x8000) +#define DMA2D_BASE (PERIPH_BASE_AHB1 + 0xB000U) +/* PERIPH_BASE_AHB1 + 0x9400 (0x4002 9400 - 0x4003 FFFF): Reserved */ +#define USB_OTG_HS_BASE (PERIPH_BASE_AHB1 + 0x20000) +/* PERIPH_BASE_AHB1 + 0x60000 (0x4008 0000 - 0x4FFF FFFF): Reserved */ + +/* AHB2 */ +#define USB_OTG_FS_BASE (PERIPH_BASE_AHB2 + 0x00000) +/* PERIPH_BASE_AHB2 + 0x40000 (0x5004 0000 - 0x5004 FFFF): Reserved */ +#define DCMI_BASE (PERIPH_BASE_AHB2 + 0x50000) +/* PERIPH_BASE_AHB2 + 0x50400 (0x5005 0400 - 0x5005 FFFF): Reserved */ +#define CRYP_BASE (PERIPH_BASE_AHB2 + 0x60000) +#define HASH_BASE (PERIPH_BASE_AHB2 + 0x60400) +/* PERIPH_BASE_AHB2 + 0x60C00 (0x5006 0C00 - 0x5006 07FF): Reserved */ +#define RNG_BASE (PERIPH_BASE_AHB2 + 0x60800) +/* PERIPH_BASE_AHB2 + 0x61000 (0x5006 1000 - 0x5FFF FFFF): Reserved */ + +/* AHB3 */ +/* Address: 0x60000000 */ +#define FMC_BANK1 (PERIPH_BASE_AHB3) +/* Address: 0x70000000 */ +#define FMC_BANK2 (PERIPH_BASE_AHB3 + 0x10000000U) +/* Address: 0x80000000 */ +#define FMC_BANK3 (PERIPH_BASE_AHB3 + 0x20000000U) +/* Address: 0x90000000 */ +#define QUADSPI_BANK (PERIPH_BASE_AHB3 + 0x30000000U) +#define FSMC_BASE (PERIPH_BASE_AHB3 + 0x40000000U) +#define FMC_BASE (PERIPH_BASE_AHB3 + 0x40000000U) +#define QUADSPI_BASE (PERIPH_BASE_AHB3 + 0x40001000U) +/* Address: 0xC0000000 */ +#define FMC_BANK5 (PERIPH_BASE_AHB3 + 0x60000000U) +/* Address: 0xD0000000 */ +#define FMC_BANK6 (PERIPH_BASE_AHB3 + 0x70000000U) + +/* PPIB */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (0x1FFF7A22U) +#define DESIG_UNIQUE_ID_BASE (0x1FFF7A10U) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 8) + +/* ST provided factory calibration values @ 3.3V */ +#define ST_VREFINT_CAL MMIO16(0x1FFF7A2A) +#define ST_TSENSE_CAL1_30C MMIO16(0x1FFF7A2C) +#define ST_TSENSE_CAL2_110C MMIO16(0x1FFF7A2E) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/pwr.h new file mode 100644 index 00000000..ab608333 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/pwr.h @@ -0,0 +1,86 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32F4xx Power Control + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2011 Stephen Caudle + +@date 4 March 2013 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include + +/* + * This file extends the common STM32 version with definitions only + * applicable to the STM32F4 series of devices. + */ + +/* --- PWR_CR values ------------------------------------------------------- */ + +/* Bits [31:15]: Reserved */ + +/* VOS: Regulator voltage scaling output selection */ +#define PWR_CR_VOS (1 << 14) + +/* Bits [13:10]: Reserved */ + +/* FPDS: Flash power down in stop mode */ +#define PWR_CR_FPDS (1 << 9) + +/* --- PWR_CSR values ------------------------------------------------------ */ + +/* Bits [31:15]: Reserved */ + +/* VOSRDY: Regulator voltage scaling output selection ready bit */ +#define PWR_CSR_VOSRDY (1 << 14) + +/* Bits [13:10]: Reserved */ + +/* BRE: Backup regulator enable */ +#define PWR_CSR_BRE (1 << 9) + +/* Bits [7:4]: Reserved */ + +/* BRR: Backup regulator ready */ +#define PWR_CSR_BRR (1 << 3) + +/* --- Function prototypes ------------------------------------------------- */ + +enum pwr_vos_scale { + PWR_SCALE1, + PWR_SCALE2, +}; + +BEGIN_DECLS + +void pwr_set_vos_scale(enum pwr_vos_scale scale); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/quadspi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/quadspi.h new file mode 100644 index 00000000..c64efd7e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/quadspi.h @@ -0,0 +1,159 @@ +/* + * STM32F4 Quad SPI defines + * + * Copyright (C) 2016, Chuck McManis + * + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +#include + +/* QUADSPI Control register */ +#define QUADSPI_CR MMIO32(QUADSPI_BASE + 0x0U) + +#define QUADSPI_CR_PRESCALE_MASK 0xff +#define QUADSPI_CR_PRESCALE_SHIFT 24 +#define QUADSPI_CR_PMM (1 << 23) +#define QUADSPI_CR_APMS (1 << 22) +/* bit 21 is reserved */ +#define QUADSPI_CR_TOIE (1 << 20) +#define QUADSPI_CR_SMIE (1 << 19) +#define QUADSPI_CR_FTIE (1 << 18) +#define QUADSPI_CR_TCIE (1 << 17) +#define QUADSPI_CR_TEIE (1 << 16) + +/* bits 15:13 reserved */ +#define QUADSPI_CR_FTHRES_MASK 0x1f +#define QUADSPI_CR_FTHRES_SHIFT 8 +#define QUADSPI_CR_FSEL (1 << 7) +#define QUADSPI_CR_DFM (1 << 6) +/* bit 5 reserved */ +#define QUADSPI_CR_SSHIFT (1 << 4) +#define QUADSPI_CR_TCEN (1 << 3) +#define QUADSPI_CR_DMAEN (1 << 2) +#define QUADSPI_CR_ABORT (1 << 1) +#define QUADSPI_CR_EN (1 << 0) + +/* QUADSPI Device Configuration */ +#define QUADSPI_DCR MMIO32(QUADSPI_BASE + 0x4U) + +/* bits 31:21 reserved */ +#define QUADSPI_DCR_FSIZE_MASK 0x1f +#define QUADSPI_DCR_FSIZE_SHIFT 16 +/* bits 15:11 reserved */ +#define QUADSPI_DCR_CSHT_MASK 0x7 +#define QUADSPI_DCR_CSHT_SHIFT 8 +/* bits 7:1 reserved */ +#define QUADSPI_DCR_CKMODE (1 << 0) + +/* QUADSPI Status Register */ +#define QUADSPI_SR MMIO32(QUADSPI_BASE + 0x8U) + +/* bits 31:14 reserved */ +#define QUADSPI_SR_FLEVEL_MASK 0x3f +#define QUADSPI_SR_FLEVEL_SHIFT 8 + +/* bits 7:6 reserved */ +#define QUADSPI_SR_BUSY (1 << 5) +#define QUADSPI_SR_TOF (1 << 4) +#define QUADSPI_SR_SMF (1 << 3) +#define QUADSPI_SR_FTF (1 << 2) +#define QUADSPI_SR_TCF (1 << 1) +#define QUADSPI_SR_TEF (1 << 0) + +/* QUADSPI Flag Clear Register */ +#define QUADSPI_FCR MMIO32(QUADSPI_BASE + 0xCU) + +/* bits 31:5 reserved */ +#define QUADSPI_FCR_CTOF (1 << 4) +#define QUADSPI_FCR_CSMF (1 << 3) +/* bit 2 reserved */ +#define QUADSPI_FCR_CTCF (1 << 1) +#define QUADSPI_FCR_CTEF (1 << 0) + +/* QUADSPI Data Length Register */ +#define QUADSPI_DLR MMIO32(QUADSPI_BASE + 0x10U) + +/* QUADSPI Communication Configuration Register */ +#define QUADSPI_CCR MMIO32(QUADSPI_BASE + 0x14U) + +#define QUADSPI_CCR_DDRM (1 << 31) +#define QUADSPI_CCR_DHHC (1 << 30) +/* bit 29 reserved */ +#define QUADSPI_CCR_SIOO (1 << 28) +#define QUADSPI_CCR_FMODE_MASK 0x3 +#define QUADSPI_CCR_FMODE_SHIFT 26 +#define QUADSPI_CCR_DMODE_MASK 0x3 +#define QUADSPI_CCR_DMODE_SHIFT 24 +/* bit 23 reserved */ +#define QUADSPI_CCR_DCYC_MASK 0x1f +#define QUADSPI_CCR_DCYC_SHIFT 18 + +#define QUADSPI_CCR_ABSIZE_MASK 0x3 +#define QUADSPI_CCR_ABSIZE_SHIFT 16 + +#define QUADSPI_CCR_ABMODE_MASK 0x3 +#define QUADSPI_CCR_ABMODE_SHIFT 14 + +#define QUADSPI_CCR_ADSIZE_MASK 0x3 +#define QUADSPI_CCR_ADSIZE_SHIFT 12 + +#define QUADSPI_CCR_ADMODE_MASK 0x3 +#define QUADSPI_CCR_ADMODE_SHIFT 10 + +#define QUADSPI_CCR_IMODE_MASK 0x3 +#define QUADSPI_CCR_IMODE_SHIFT 8 + +#define QUADSPI_CCR_INST_MASK 0xff +#define QUADSPI_CCR_INST_SHIFT 0 + +/* MODE values */ +#define QUADSPI_CCR_MODE_NONE 0 +#define QUADSPI_CCR_MODE_1LINE 1 +#define QUADSPI_CCR_MODE_2LINE 2 +#define QUADSPI_CCR_MODE_4LINE 3 + +/* FMODE values */ +#define QUADSPI_CCR_FMODE_IWRITE 0 +#define QUADSPI_CCR_FMODE_IREAD 1 +#define QUADSPI_CCR_FMODE_APOLL 2 +#define QUADSPI_CCR_FMODE_MEMMAP 3 + + +/* QUADSPI address register */ +#define QUADSPI_AR MMIO32(QUADSPI_BASE + 0x18U) + +/* QUADSPI alternate bytes register */ +#define QUADSPI_ABR MMI032(QUADSPI_BASE + 0x1CU) + +/* QUADSPI data register */ +#define QUADSPI_DR MMIO32(QUADSPI_BASE + 0x20U) +/* BYTE addressable version for fetching bytes from the interface */ +#define QUADSPI_BYTE_DR MMIO8(QUADSPI_BASE + 0x20U) + +/* QUADSPI polling status */ +#define QUADSPI_PSMKR MMIO32(QUADSPI_BASE + 0x24U) + +/* QUADSPI polling status match */ +#define QUADSPI_PSMAR MMIO32(QUADSPI_BASE + 0x28U) + +/* QUADSPI polling interval register */ +#define QUADSPI_PIR MMIO32(QUADSPI_BASE + 0x2CU) + +/* QUADSPI low power timeout */ +#define QUADSPI_LPTR MMIO32(QUADSPI_BASE + 0x30U) + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rcc.h new file mode 100644 index 00000000..3b6f3806 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rcc.h @@ -0,0 +1,966 @@ +/** @defgroup rcc_defines RCC Defines + * + * @brief Defined Constants and Types for the STM32F4xx Reset and Clock + * Control + * + * @ingroup STM32F4xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2009 + * Federico Ruiz-Ugalde \ + * @author @htmlonly © @endhtmlonly 2009 + * Uwe Hermann + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * @author @htmlonly © @endhtmlonly 2011 + * Stephen Caudle + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2011 Fergus Noble + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_PLLCFGR MMIO32(RCC_BASE + 0x04) +#define RCC_CFGR MMIO32(RCC_BASE + 0x08) +#define RCC_CIR MMIO32(RCC_BASE + 0x0c) +#define RCC_AHB1RSTR MMIO32(RCC_BASE + 0x10) +#define RCC_AHB2RSTR MMIO32(RCC_BASE + 0x14) +#define RCC_AHB3RSTR MMIO32(RCC_BASE + 0x18) +/* RCC_BASE + 0x1c Reserved */ +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x20) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x24) +/* RCC_BASE + 0x28 Reserved */ +/* RCC_BASE + 0x2c Reserved */ +#define RCC_AHB1ENR MMIO32(RCC_BASE + 0x30) +#define RCC_AHB2ENR MMIO32(RCC_BASE + 0x34) +#define RCC_AHB3ENR MMIO32(RCC_BASE + 0x38) +/* RCC_BASE + 0x3c Reserved */ +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x40) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x44) +/* RCC_BASE + 0x48 Reserved */ +/* RCC_BASE + 0x4c Reserved */ +#define RCC_AHB1LPENR MMIO32(RCC_BASE + 0x50) +#define RCC_AHB2LPENR MMIO32(RCC_BASE + 0x54) +#define RCC_AHB3LPENR MMIO32(RCC_BASE + 0x58) +/* RCC_BASE + 0x5c Reserved */ +#define RCC_APB1LPENR MMIO32(RCC_BASE + 0x60) +#define RCC_APB2LPENR MMIO32(RCC_BASE + 0x64) +/* RCC_BASE + 0x68 Reserved */ +/* RCC_BASE + 0x6c Reserved */ +#define RCC_BDCR MMIO32(RCC_BASE + 0x70) +#define RCC_CSR MMIO32(RCC_BASE + 0x74) +/* RCC_BASE + 0x78 Reserved */ +/* RCC_BASE + 0x7c Reserved */ +#define RCC_SSCGR MMIO32(RCC_BASE + 0x80) +#define RCC_PLLI2SCFGR MMIO32(RCC_BASE + 0x84) +#define RCC_PLLSAICFGR MMIO32(RCC_BASE + 0x88) +#define RCC_DCKCFGR MMIO32(RCC_BASE + 0x8C) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLSAIRDY (1 << 29) +#define RCC_CR_PLLSAION (1 << 28) +#define RCC_CR_PLLI2SRDY (1 << 27) +#define RCC_CR_PLLI2SON (1 << 26) +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +/* HSICAL: [15:8] */ +/* HSITRIM: [7:3] */ +#define RCC_CR_HSITRIM_SHIFT 3 +#define RCC_CR_HSITRIM_MASK 0x1f +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +/* --- RCC_PLLCFGR values -------------------------------------------------- */ + +/* PLLR: [30:28] */ +#define RCC_PLLCFGR_PLLR_SHIFT 28 +#define RCC_PLLCFGR_PLLR_MASK 0x7 +/* PLLQ: [27:24] */ +#define RCC_PLLCFGR_PLLQ_SHIFT 24 +#define RCC_PLLCFGR_PLLQ_MASK 0xf +#define RCC_PLLCFGR_PLLSRC (1 << 22) +/* PLLP: [17:16] */ +#define RCC_PLLCFGR_PLLP_SHIFT 16 +#define RCC_PLLCFGR_PLLP_MASK 0x3 +/* PLLN: [14:6] */ +#define RCC_PLLCFGR_PLLN_SHIFT 6 +#define RCC_PLLCFGR_PLLN_MASK 0x1ff +/* PLLM: [5:0] */ +#define RCC_PLLCFGR_PLLM_SHIFT 0 +#define RCC_PLLCFGR_PLLM_MASK 0x3f + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +/* MCO2: Microcontroller clock output 2 */ +#define RCC_CFGR_MCO2_SHIFT 30 +#define RCC_CFGR_MC02_MASK 0x3 +#define RCC_CFGR_MCO2_SYSCLK 0x0 +#define RCC_CFGR_MCO2_PLLI2S 0x1 +#define RCC_CFGR_MCO2_HSE 0x2 +#define RCC_CFGR_MCO2_PLL 0x3 + +/* MCO1/2PRE: MCO Prescalers */ +#define RCC_CFGR_MCO2PRE_SHIFT 27 +#define RCC_CFGR_MCO2PRE_MASK 0x7 +#define RCC_CFGR_MCO1PRE_SHIFT 24 +#define RCC_CFGR_MCO1PRE_MASK 0x7 +#define RCC_CFGR_MCOPRE_DIV_NONE 0x0 +#define RCC_CFGR_MCOPRE_DIV_2 0x4 +#define RCC_CFGR_MCOPRE_DIV_3 0x5 +#define RCC_CFGR_MCOPRE_DIV_4 0x6 +#define RCC_CFGR_MCOPRE_DIV_5 0x7 + +/* I2SSRC: I2S clock selection */ +#define RCC_CFGR_I2SSRC (1 << 23) + +/* MCO1: Microcontroller clock output 1 */ +#define RCC_CFGR_MCO1_SHIFT 21 +#define RCC_CFGR_MCO1_MASK 0x3 +#define RCC_CFGR_MCO1_HSI 0x0 +#define RCC_CFGR_MCO1_LSE 0x1 +#define RCC_CFGR_MCO1_HSE 0x2 +#define RCC_CFGR_MCO1_PLL 0x3 +#define RCC_CFGR_MCO_SHIFT RCC_CFGR_MCO1_SHIFT +#define RCC_CFGR_MCO_MASK RCC_CFGR_MCO1_MASK + +/* RTCPRE: HSE division factor for RTC clock */ +#define RCC_CFGR_RTCPRE_SHIFT 16 +#define RCC_CFGR_RTCPRE_MASK 0x1f + +/* PPRE1/2: APB high-speed prescalers */ +#define RCC_CFGR_PPRE2_SHIFT 13 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 10 +#define RCC_CFGR_PPRE1_MASK 0x7 +#define RCC_CFGR_PPRE_DIV_NONE 0x0 +#define RCC_CFGR_PPRE_DIV_2 0x4 +#define RCC_CFGR_PPRE_DIV_4 0x5 +#define RCC_CFGR_PPRE_DIV_8 0x6 +#define RCC_CFGR_PPRE_DIV_16 0x7 + +/* HPRE: AHB high-speed prescaler */ +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE_MASK 0xf +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_SHIFT 2 +#define RCC_CFGR_SWS_MASK 0x3 +#define RCC_CFGR_SWS_HSI 0x0 +#define RCC_CFGR_SWS_HSE 0x1 +#define RCC_CFGR_SWS_PLL 0x2 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_SHIFT 0 +#define RCC_CFGR_SW_HSI 0x0 +#define RCC_CFGR_SW_HSE 0x1 +#define RCC_CFGR_SW_PLL 0x2 + +/* --- RCC_CIR values ------------------------------------------------------ */ + +/* Clock security system interrupt clear bit */ +#define RCC_CIR_CSSC (1 << 23) + +/* OSC ready interrupt clear bits */ +#define RCC_CIR_PLLSAIRDYC (1 << 22) +#define RCC_CIR_PLLI2SRDYC (1 << 21) +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) + +/* OSC ready interrupt enable bits */ +#define RCC_CIR_PLLSAIRDYIE (1 << 14) +#define RCC_CIR_PLLI2SRDYIE (1 << 13) +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) + +/* Clock security system interrupt flag bit */ +#define RCC_CIR_CSSF (1 << 7) + +/* OSC ready interrupt flag bits */ +#define RCC_CIR_PLLSAIRDYF (1 << 6) +#define RCC_CIR_PLLI2SRDYF (1 << 5) +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_AHB1RSTR values ------------------------------------------------- */ + +#define RCC_AHB1RSTR_OTGHSRST (1 << 29) +#define RCC_AHB1RSTR_ETHMACRST (1 << 25) +#define RCC_AHB1RSTR_DMA2DRST (1 << 23) +#define RCC_AHB1RSTR_DMA2RST (1 << 22) +#define RCC_AHB1RSTR_DMA1RST (1 << 21) +#define RCC_AHB1RSTR_CRCRST (1 << 12) +#define RCC_AHB1RSTR_IOPKRST (1 << 10) +#define RCC_AHB1RSTR_IOPJRST (1 << 9) +#define RCC_AHB1RSTR_IOPIRST (1 << 8) +#define RCC_AHB1RSTR_IOPHRST (1 << 7) +#define RCC_AHB1RSTR_IOPGRST (1 << 6) +#define RCC_AHB1RSTR_IOPFRST (1 << 5) +#define RCC_AHB1RSTR_IOPERST (1 << 4) +#define RCC_AHB1RSTR_IOPDRST (1 << 3) +#define RCC_AHB1RSTR_IOPCRST (1 << 2) +#define RCC_AHB1RSTR_IOPBRST (1 << 1) +#define RCC_AHB1RSTR_IOPARST (1 << 0) + +/* --- RCC_AHB2RSTR values ------------------------------------------------- */ + +#define RCC_AHB2RSTR_OTGFSRST (1 << 7) +#define RCC_AHB2RSTR_RNGRST (1 << 6) +#define RCC_AHB2RSTR_HASHRST (1 << 5) +#define RCC_AHB2RSTR_CRYPRST (1 << 4) +#define RCC_AHB2RSTR_DCMIRST (1 << 0) + +/* --- RCC_AHB3RSTR values ------------------------------------------------- */ + +#define RCC_AHB3RSTR_QSPIRST (1 << 1) +#define RCC_AHB3RSTR_FSMCRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_UART8RST (1 << 31) +#define RCC_APB1RSTR_UART7RST (1 << 30) +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_CAN2RST (1 << 26) +#define RCC_APB1RSTR_CAN1RST (1 << 25) +#define RCC_APB1RSTR_I2C3RST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_UART5RST (1 << 20) +#define RCC_APB1RSTR_UART4RST (1 << 19) +#define RCC_APB1RSTR_USART3RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI3RST (1 << 15) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_TIM14RST (1 << 8) +#define RCC_APB1RSTR_TIM13RST (1 << 7) +#define RCC_APB1RSTR_TIM12RST (1 << 6) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM5RST (1 << 3) +#define RCC_APB1RSTR_TIM4RST (1 << 2) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_DSIRST (1 << 27) +#define RCC_APB2RSTR_LTDCRST (1 << 26) +#define RCC_APB2RSTR_SAI1RST (1 << 22) +#define RCC_APB2RSTR_SPI6RST (1 << 21) +#define RCC_APB2RSTR_SPI5RST (1 << 20) +#define RCC_APB2RSTR_TIM11RST (1 << 18) +#define RCC_APB2RSTR_TIM10RST (1 << 17) +#define RCC_APB2RSTR_TIM9RST (1 << 16) +#define RCC_APB2RSTR_SYSCFGRST (1 << 14) +#define RCC_APB2RSTR_SPI4RST (1 << 13) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_SDIORST (1 << 11) +#define RCC_APB2RSTR_ADCRST (1 << 8) +#define RCC_APB2RSTR_USART6RST (1 << 5) +#define RCC_APB2RSTR_USART1RST (1 << 4) +#define RCC_APB2RSTR_TIM8RST (1 << 1) +#define RCC_APB2RSTR_TIM1RST (1 << 0) + +/* --- RCC_AHB1ENR values ------------------------------------------------- */ + +#define RCC_AHB1ENR_OTGHSULPIEN (1 << 30) +#define RCC_AHB1ENR_OTGHSEN (1 << 29) +#define RCC_AHB1ENR_ETHMACPTPEN (1 << 28) +#define RCC_AHB1ENR_ETHMACRXEN (1 << 27) +#define RCC_AHB1ENR_ETHMACTXEN (1 << 26) +#define RCC_AHB1ENR_ETHMACEN (1 << 25) +#define RCC_AHB1ENR_DMA2DEN (1 << 23) +#define RCC_AHB1ENR_DMA2EN (1 << 22) +#define RCC_AHB1ENR_DMA1EN (1 << 21) +#define RCC_AHB1ENR_CCMDATARAMEN (1 << 20) +#define RCC_AHB1ENR_BKPSRAMEN (1 << 18) +#define RCC_AHB1ENR_CRCEN (1 << 12) +#define RCC_AHB1ENR_IOPKEN (1 << 10) +#define RCC_AHB1ENR_IOPJEN (1 << 9) +#define RCC_AHB1ENR_IOPIEN (1 << 8) +#define RCC_AHB1ENR_IOPHEN (1 << 7) +#define RCC_AHB1ENR_IOPGEN (1 << 6) +#define RCC_AHB1ENR_IOPFEN (1 << 5) +#define RCC_AHB1ENR_IOPEEN (1 << 4) +#define RCC_AHB1ENR_IOPDEN (1 << 3) +#define RCC_AHB1ENR_IOPCEN (1 << 2) +#define RCC_AHB1ENR_IOPBEN (1 << 1) +#define RCC_AHB1ENR_IOPAEN (1 << 0) + +/* --- RCC_AHB2ENR values ------------------------------------------------- */ + +#define RCC_AHB2ENR_OTGFSEN (1 << 7) +#define RCC_AHB2ENR_RNGEN (1 << 6) +#define RCC_AHB2ENR_HASHEN (1 << 5) +#define RCC_AHB2ENR_CRYPEN (1 << 4) +#define RCC_AHB2ENR_DCMIEN (1 << 0) + +/* --- RCC_AHB3ENR values ------------------------------------------------- */ + +#define RCC_AHB3ENR_QSPIEN (1 << 1) +#define RCC_AHB3ENR_FSMCEN (1 << 0) +/* Alternate now that F429 has DRAM controller as well */ +#define RCC_AHB3ENR_FMCEN (1 << 0) + +/* --- RCC_APB1ENR values ------------------------------------------------- */ + +#define RCC_APB1ENR_UART8EN (1 << 31) +#define RCC_APB1ENR_UART7EN (1 << 30) +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_CAN2EN (1 << 26) +#define RCC_APB1ENR_CAN1EN (1 << 25) +#define RCC_APB1ENR_I2C3EN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_UART5EN (1 << 20) +#define RCC_APB1ENR_UART4EN (1 << 19) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI3EN (1 << 15) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_TIM14EN (1 << 8) +#define RCC_APB1ENR_TIM13EN (1 << 7) +#define RCC_APB1ENR_TIM12EN (1 << 6) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM5EN (1 << 3) +#define RCC_APB1ENR_TIM4EN (1 << 2) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) + +/* --- RCC_APB2ENR values ------------------------------------------------- */ + +#define RCC_APB2ENR_DSIEN (1 << 27) +#define RCC_APB2ENR_LTDCEN (1 << 26) +#define RCC_APB2ENR_SAI1EN (1 << 22) +#define RCC_APB2ENR_SPI6EN (1 << 21) +#define RCC_APB2ENR_SPI5EN (1 << 20) +#define RCC_APB2ENR_TIM11EN (1 << 18) +#define RCC_APB2ENR_TIM10EN (1 << 17) +#define RCC_APB2ENR_TIM9EN (1 << 16) +#define RCC_APB2ENR_SYSCFGEN (1 << 14) +#define RCC_APB2ENR_SPI4EN (1 << 13) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_SDIOEN (1 << 11) +#define RCC_APB2ENR_ADC3EN (1 << 10) +#define RCC_APB2ENR_ADC2EN (1 << 9) +#define RCC_APB2ENR_ADC1EN (1 << 8) +#define RCC_APB2ENR_USART6EN (1 << 5) +#define RCC_APB2ENR_USART1EN (1 << 4) +#define RCC_APB2ENR_TIM8EN (1 << 1) +#define RCC_APB2ENR_TIM1EN (1 << 0) + +/* --- RCC_AHB1LPENR values ------------------------------------------------- */ + +#define RCC_AHB1LPENR_OTGHSULPILPEN (1 << 30) +#define RCC_AHB1LPENR_OTGHSLPEN (1 << 29) +#define RCC_AHB1LPENR_ETHMACPTPLPEN (1 << 28) +#define RCC_AHB1LPENR_ETHMACRXLPEN (1 << 27) +#define RCC_AHB1LPENR_ETHMACTXLPEN (1 << 26) +#define RCC_AHB1LPENR_ETHMACLPEN (1 << 25) +#define RCC_AHB1LPENR_DMA2DLPEN (1 << 23) +#define RCC_AHB1LPENR_DMA2LPEN (1 << 22) +#define RCC_AHB1LPENR_DMA1LPEN (1 << 21) +#define RCC_AHB1LPENR_SRAM3LPEN (1 << 19) +#define RCC_AHB1LPENR_BKPSRAMLPEN (1 << 18) +#define RCC_AHB1LPENR_SRAM2LPEN (1 << 17) +#define RCC_AHB1LPENR_SRAM1LPEN (1 << 16) +#define RCC_AHB1LPENR_FLITFLPEN (1 << 15) +#define RCC_AHB1LPENR_CRCLPEN (1 << 12) +#define RCC_AHB1LPENR_IOPKLPEN (1 << 10) +#define RCC_AHB1LPENR_IOPJLPEN (1 << 9) +#define RCC_AHB1LPENR_IOPILPEN (1 << 8) +#define RCC_AHB1LPENR_IOPHLPEN (1 << 7) +#define RCC_AHB1LPENR_IOPGLPEN (1 << 6) +#define RCC_AHB1LPENR_IOPFLPEN (1 << 5) +#define RCC_AHB1LPENR_IOPELPEN (1 << 4) +#define RCC_AHB1LPENR_IOPDLPEN (1 << 3) +#define RCC_AHB1LPENR_IOPCLPEN (1 << 2) +#define RCC_AHB1LPENR_IOPBLPEN (1 << 1) +#define RCC_AHB1LPENR_IOPALPEN (1 << 0) + +/* --- RCC_AHB2LPENR values ------------------------------------------------- */ + +#define RCC_AHB2LPENR_OTGFSLPEN (1 << 7) +#define RCC_AHB2LPENR_RNGLPEN (1 << 6) +#define RCC_AHB2LPENR_HASHLPEN (1 << 5) +#define RCC_AHB2LPENR_CRYPLPEN (1 << 4) +#define RCC_AHB2LPENR_DCMILPEN (1 << 0) + +/* --- RCC_AHB3LPENR values ------------------------------------------------- */ + +#define RCC_AHB3LPENR_QSPIEN (1 << 1) +#define RCC_AHB3LPENR_FSMCLPEN (1 << 0) +#define RCC_AHB3LPENR_FMCLPEN (1 << 0) + +/* --- RCC_APB1LPENR values ------------------------------------------------- */ + +#define RCC_APB1LPENR_UART8EN (1 << 31) +#define RCC_APB1LPENR_UART7EN (1 << 30) +#define RCC_APB1LPENR_DACLPEN (1 << 29) +#define RCC_APB1LPENR_PWRLPEN (1 << 28) +#define RCC_APB1LPENR_CAN2LPEN (1 << 26) +#define RCC_APB1LPENR_CAN1LPEN (1 << 25) +#define RCC_APB1LPENR_I2C3LPEN (1 << 23) +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) +#define RCC_APB1LPENR_UART5LPEN (1 << 20) +#define RCC_APB1LPENR_UART4LPEN (1 << 19) +#define RCC_APB1LPENR_USART3LPEN (1 << 18) +#define RCC_APB1LPENR_USART2LPEN (1 << 17) +#define RCC_APB1LPENR_SPI3LPEN (1 << 15) +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) +#define RCC_APB1LPENR_TIM14LPEN (1 << 8) +#define RCC_APB1LPENR_TIM13LPEN (1 << 7) +#define RCC_APB1LPENR_TIM12LPEN (1 << 6) +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) +#define RCC_APB1LPENR_TIM5LPEN (1 << 3) +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) + +/* --- RCC_APB2LPENR values ------------------------------------------------- */ + +#define RCC_APB2LPENR_DSILPEN (1 << 27) +#define RCC_APB2LPENR_LTDCLPEN (1 << 26) +#define RCC_APB2LPENR_SAI1LPEN (1 << 22) +#define RCC_APB2LPENR_SPI6LPEN (1 << 21) +#define RCC_APB2LPENR_SPI5LPEN (1 << 20) +#define RCC_APB2LPENR_TIM11LPEN (1 << 18) +#define RCC_APB2LPENR_TIM10LPEN (1 << 17) +#define RCC_APB2LPENR_TIM9LPEN (1 << 16) +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 14) +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) +#define RCC_APB2LPENR_SDIOLPEN (1 << 11) +#define RCC_APB2LPENR_ADC3LPEN (1 << 10) +#define RCC_APB2LPENR_ADC2LPEN (1 << 9) +#define RCC_APB2LPENR_ADC1LPEN (1 << 8) +#define RCC_APB2LPENR_USART6LPEN (1 << 5) +#define RCC_APB2LPENR_USART1LPEN (1 << 4) +#define RCC_APB2LPENR_TIM8LPEN (1 << 1) +#define RCC_APB2LPENR_TIM1LPEN (1 << 0) + +/* --- RCC_BDCR values ----------------------------------------------------- */ + +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) +/* RCC_BDCR[9:8]: RTCSEL */ +#define RCC_BDCR_RTCSEL_SHIFT 8 +#define RCC_BDCR_RTCSEL_MASK 0x3 +#define RCC_BDCR_RTCSEL_NONE 0 +#define RCC_BDCR_RTCSEL_LSE 1 +#define RCC_BDCR_RTCSEL_LSI 2 +#define RCC_BDCR_RTCSEL_HSE 3 +#define RCC_BDCR_LSEMOD (1 << 3) +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_BORRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\ + RCC_CSR_PINRSTF | RCC_CSR_BORRSTF) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- RCC_SSCGR values ---------------------------------------------------- */ + +/* PLL spread spectrum clock generation documented in Datasheet. */ + +#define RCC_SSCGR_SSCGEN (1 << 31) +#define RCC_SSCGR_SPREADSEL (1 << 30) +/* RCC_SSCGR[27:13]: INCSTEP */ +#define RCC_SSCGR_INCSTEP_SHIFT 13 +#define RCC_SSCGR_INCSTEP_MASK 0x7fff +/* RCC_SSCGR[15:0]: MODPER */ +#define RCC_SSCGR_MODPER_SHIFT 0 +#define RCC_SSCGR_MODPER_MASK 0x1fff + +/* --- RCC_PLLI2SCFGR values ----------------------------------------------- */ + +/* RCC_PLLI2SCFGR[30:28]: PLLI2SR */ +#define RCC_PLLI2SCFGR_PLLI2SR_SHIFT 28 +#define RCC_PLLI2SCFGR_PLLI2SR_MASK 0x7 +/* RCC_PLLI2SCFGR[27:24] PLLI2SQ */ +#define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT 24 +#define RCC_PLLI2SCFGR_PLLI2SQ_MASK 0xf +/* RCC_PLLI2SCFGR[14:6]: PLLI2SN */ +#define RCC_PLLI2SCFGR_PLLI2SN_SHIFT 6 +#define RCC_PLLI2SCFGR_PLLI2SN_MASK 0x1ff + +/* --- RCC_PLLSAICFGR values ----------------------------------------------- */ + +/* RCC_PLLSAICFGR[30:28]: PLLSAIR */ +#define RCC_PLLSAICFGR_PLLSAIR_SHIFT 28 +#define RCC_PLLSAICFGR_PLLSAIR_MASK 0x7 + +/* RCC_PLLSAICFGR[27:24]: PLLSAIQ */ +#define RCC_PLLSAICFGR_PLLSAIQ_SHIFT 24 +#define RCC_PLLSAICFGR_PLLSAIQ_MASK 0xF + +/* RCC_PLLSAICFGR[18:16]: PLLSAIP */ +#define RCC_PLLSAICFGR_PLLSAIP_SHIFT 16 +#define RCC_PLLSAICFGR_PLLSAIP_MASK 0x3 +/** @defgroup rcc_pllsaicfgr_pllsaip PLLSAICFGR PLLSAIP values +@ingroup rcc_defines +@{*/ +#define RCC_PLLSAICFGR_PLLSAIP_DIV2 0x0 +#define RCC_PLLSAICFGR_PLLSAIP_DIV4 0x1 +#define RCC_PLLSAICFGR_PLLSAIP_DIV6 0x2 +#define RCC_PLLSAICFGR_PLLSAIP_DIV8 0x3 +/**@}*/ + +/* RCC_PLLSAICFGR[14:6]: PLLSAIN */ +#define RCC_PLLSAICFGR_PLLSAIN_SHIFT 6 +#define RCC_PLLSAICFGR_PLLSAIN_MASK 0x1FF + + +/* --- RCC_DCKCFGR values -------------------------------------------------- */ +#define RCC_DCKCFGR_DSISEL (1 << 29) +#define RCC_DCKCFGR_SDMMCSEL (1 << 28) +#define RCC_DCKCFGR_48MSEL (1 << 27) +#define RCC_DCKCFGR_TIMPRE (1 << 24) + +#define RCC_DCKCFGR_SAI1BSRC_SHIFT 22 +#define RCC_DCKCFGR_SAI1BSRC_MASK 0x3 + +#define RCC_DCKCFGR_SAI1ASRC_SHIFT 20 +#define RCC_DCKCFGR_SAI1ASRC_MASK 0x3 + +/* Values for the BSRC and ASRC fields */ +#define RCC_DCKCFGR_SAI1SRC_SAIQ 0x0 +#define RCC_DCKCFGR_SAI1SRC_I2SQ 0x1 +#define RCC_DCKCFGR_SAI1SRC_ALT 0x2 +#define RCC_DCKCFGR_SAI1SRC_ERROR 0x3 + +#define RCC_DCKCFGR_PLLSAIDIVR_SHIFT 16 +#define RCC_DCKCFGR_PLLSAIDIVR_MASK 0x3 +#define RCC_DCKCFGR_PLLSAIDIVR_DIVR_2 0x0 +#define RCC_DCKCFGR_PLLSAIDIVR_DIVR_4 0x1 +#define RCC_DCKCFGR_PLLSAIDIVR_DIVR_8 0x2 +#define RCC_DCKCFGR_PLLSAIDIVR_DIVR_16 0x3 + +#define RCC_DCKCFGR_PLLSAIDIVQ_SHIFT 8 +#define RCC_DCKCFGR_PLLSAIDIVQ_MASK 0x1f + +#define RCC_DCKCFGR_PLLI2SDIVQ_SHIFT 0 +#define RCC_DCKCFGR_PLLI2SDIVQ_MASK 0x1f + +/* PLLSAI1 helper macros */ +static inline void rcc_pllsai_enable(void) +{ + RCC_CR |= RCC_CR_PLLSAION; +} + +static inline bool rcc_pllsai_ready(void) +{ + return (RCC_CR & RCC_CR_PLLSAIRDY) != 0; +} + + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_clock_3v3 { + RCC_CLOCK_3V3_48MHZ, + RCC_CLOCK_3V3_84MHZ, + RCC_CLOCK_3V3_120MHZ, + RCC_CLOCK_3V3_168MHZ, + RCC_CLOCK_3V3_END +}; + +struct rcc_clock_scale { + uint8_t pllm; + uint16_t plln; + uint8_t pllp; + uint8_t pllq; + uint8_t pllr; + uint32_t flash_config; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + uint8_t power_save; + uint32_t ahb_frequency; + uint32_t apb1_frequency; + uint32_t apb2_frequency; +}; + +extern const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END]; +extern const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END]; +extern const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END]; +extern const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END]; + +enum rcc_osc { + RCC_PLL, + RCC_PLLSAI, + RCC_PLLI2S, + RCC_HSE, + RCC_HSI, + RCC_LSE, + RCC_LSI +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + /* AHB1 peripherals*/ + RCC_GPIOA = _REG_BIT(0x30, 0), + RCC_GPIOB = _REG_BIT(0x30, 1), + RCC_GPIOC = _REG_BIT(0x30, 2), + RCC_GPIOD = _REG_BIT(0x30, 3), + RCC_GPIOE = _REG_BIT(0x30, 4), + RCC_GPIOF = _REG_BIT(0x30, 5), + RCC_GPIOG = _REG_BIT(0x30, 6), + RCC_GPIOH = _REG_BIT(0x30, 7), + RCC_GPIOI = _REG_BIT(0x30, 8), + RCC_GPIOJ = _REG_BIT(0x30, 9), + RCC_GPIOK = _REG_BIT(0x30, 10), + RCC_CRC = _REG_BIT(0x30, 12), + RCC_BKPSRAM = _REG_BIT(0x30, 18), + RCC_CCMDATARAM = _REG_BIT(0x30, 20), + RCC_DMA1 = _REG_BIT(0x30, 21), + RCC_DMA2 = _REG_BIT(0x30, 22), + RCC_DMA2D = _REG_BIT(0x30, 23), + RCC_ETHMAC = _REG_BIT(0x30, 25), + RCC_ETHMACTX = _REG_BIT(0x30, 26), + RCC_ETHMACRX = _REG_BIT(0x30, 27), + RCC_ETHMACPTP = _REG_BIT(0x30, 28), + RCC_OTGHS = _REG_BIT(0x30, 29), + RCC_OTGHSULPI = _REG_BIT(0x30, 30), + + /* AHB2 peripherals */ + RCC_DCMI = _REG_BIT(0x34, 0), + RCC_CRYP = _REG_BIT(0x34, 4), + RCC_HASH = _REG_BIT(0x34, 5), + RCC_RNG = _REG_BIT(0x34, 6), + RCC_OTGFS = _REG_BIT(0x34, 7), + + /* AHB3 peripherals */ + RCC_FSMC = _REG_BIT(0x38, 0), + RCC_FMC = _REG_BIT(0x38, 0), + RCC_QUADSPI = _REG_BIT(0x38, 1), + + /* APB1 peripherals*/ + RCC_TIM2 = _REG_BIT(0x40, 0), + RCC_TIM3 = _REG_BIT(0x40, 1), + RCC_TIM4 = _REG_BIT(0x40, 2), + RCC_TIM5 = _REG_BIT(0x40, 3), + RCC_TIM6 = _REG_BIT(0x40, 4), + RCC_TIM7 = _REG_BIT(0x40, 5), + RCC_TIM12 = _REG_BIT(0x40, 6), + RCC_TIM13 = _REG_BIT(0x40, 7), + RCC_TIM14 = _REG_BIT(0x40, 8), + RCC_WWDG = _REG_BIT(0x40, 11), + RCC_SPI2 = _REG_BIT(0x40, 14), + RCC_SPI3 = _REG_BIT(0x40, 15), + RCC_USART2 = _REG_BIT(0x40, 17), + RCC_USART3 = _REG_BIT(0x40, 18), + RCC_UART4 = _REG_BIT(0x40, 19), + RCC_UART5 = _REG_BIT(0x40, 20), + RCC_I2C1 = _REG_BIT(0x40, 21), + RCC_I2C2 = _REG_BIT(0x40, 22), + RCC_I2C3 = _REG_BIT(0x40, 23), + RCC_CAN1 = _REG_BIT(0x40, 25), + RCC_CAN2 = _REG_BIT(0x40, 26), + RCC_PWR = _REG_BIT(0x40, 28), + RCC_DAC = _REG_BIT(0x40, 29), + RCC_UART7 = _REG_BIT(0x40, 30),/* F2xx, F3xx */ + RCC_UART8 = _REG_BIT(0x40, 31),/* F2xx, F3xx */ + + /* APB2 peripherals */ + RCC_TIM1 = _REG_BIT(0x44, 0), + RCC_TIM8 = _REG_BIT(0x44, 1), + RCC_USART1 = _REG_BIT(0x44, 4), + RCC_USART6 = _REG_BIT(0x44, 5), + RCC_ADC1 = _REG_BIT(0x44, 8), + RCC_ADC2 = _REG_BIT(0x44, 9), + RCC_ADC3 = _REG_BIT(0x44, 10), + RCC_SDIO = _REG_BIT(0x44, 11), + RCC_SPI1 = _REG_BIT(0x44, 12), + RCC_SPI4 = _REG_BIT(0x44, 13),/* F2xx, F3xx */ + RCC_SYSCFG = _REG_BIT(0x44, 14), + RCC_TIM9 = _REG_BIT(0x44, 16), + RCC_TIM10 = _REG_BIT(0x44, 17), + RCC_TIM11 = _REG_BIT(0x44, 18), + RCC_SPI5 = _REG_BIT(0x44, 20),/* F2xx, F3xx */ + RCC_SPI6 = _REG_BIT(0x44, 21),/* F2xx, F3xx */ + RCC_SAI1EN = _REG_BIT(0x44, 22),/* F42x, F43x */ + RCC_LTDC = _REG_BIT(0x44, 26),/* F42x, F43x */ + RCC_DSI = _REG_BIT(0x44, 27),/* F4x9, F4x9 */ + + + /* BDCR */ + RCC_RTC = _REG_BIT(0x70, 15), + + /* AHB1 peripherals*/ + SCC_GPIOA = _REG_BIT(0x50, 0), + SCC_GPIOB = _REG_BIT(0x50, 1), + SCC_GPIOC = _REG_BIT(0x50, 2), + SCC_GPIOD = _REG_BIT(0x50, 3), + SCC_GPIOE = _REG_BIT(0x50, 4), + SCC_GPIOF = _REG_BIT(0x50, 5), + SCC_GPIOG = _REG_BIT(0x50, 6), + SCC_GPIOH = _REG_BIT(0x50, 7), + SCC_GPIOI = _REG_BIT(0x50, 8), + SCC_GPIOJ = _REG_BIT(0x50, 9), + SCC_GPIOK = _REG_BIT(0x50, 10), + SCC_CRC = _REG_BIT(0x50, 12), + SCC_FLTIF = _REG_BIT(0x50, 15), + SCC_SRAM1 = _REG_BIT(0x50, 16), + SCC_SRAM2 = _REG_BIT(0x50, 17), + SCC_BKPSRAM = _REG_BIT(0x50, 18), + SCC_SRAM3 = _REG_BIT(0x50, 19),/* F2xx, F3xx */ + SCC_DMA1 = _REG_BIT(0x50, 21), + SCC_DMA2 = _REG_BIT(0x50, 22), + SCC_DMA2D = _REG_BIT(0x50, 23), /* F4x9 */ + SCC_ETHMAC = _REG_BIT(0x50, 25), + SCC_ETHMACTX = _REG_BIT(0x50, 26), + SCC_ETHMACRX = _REG_BIT(0x50, 27), + SCC_ETHMACPTP = _REG_BIT(0x50, 28), + SCC_OTGHS = _REG_BIT(0x50, 29), + SCC_OTGHSULPI = _REG_BIT(0x50, 30), + + /* AHB2 peripherals */ + SCC_DCMI = _REG_BIT(0x54, 0), + SCC_CRYP = _REG_BIT(0x54, 4), + SCC_HASH = _REG_BIT(0x54, 5), + SCC_RNG = _REG_BIT(0x54, 6), + SCC_OTGFS = _REG_BIT(0x54, 7), + + /* AHB3 peripherals */ + SCC_QSPIC = _REG_BIT(0x58, 1), + SCC_FMC = _REG_BIT(0x58, 0), + SCC_FSMC = _REG_BIT(0x58, 0), + + /* APB1 peripherals*/ + SCC_TIM2 = _REG_BIT(0x60, 0), + SCC_TIM3 = _REG_BIT(0x60, 1), + SCC_TIM4 = _REG_BIT(0x60, 2), + SCC_TIM5 = _REG_BIT(0x60, 3), + SCC_TIM6 = _REG_BIT(0x60, 4), + SCC_TIM7 = _REG_BIT(0x60, 5), + SCC_TIM12 = _REG_BIT(0x60, 6), + SCC_TIM13 = _REG_BIT(0x60, 7), + SCC_TIM14 = _REG_BIT(0x60, 8), + SCC_WWDG = _REG_BIT(0x60, 11), + SCC_SPI2 = _REG_BIT(0x60, 14), + SCC_SPI3 = _REG_BIT(0x60, 15), + SCC_USART2 = _REG_BIT(0x60, 17), + SCC_USART3 = _REG_BIT(0x60, 18), + SCC_UART4 = _REG_BIT(0x60, 19), + SCC_UART5 = _REG_BIT(0x60, 20), + SCC_I2C1 = _REG_BIT(0x60, 21), + SCC_I2C2 = _REG_BIT(0x60, 22), + SCC_I2C3 = _REG_BIT(0x60, 23), + SCC_CAN1 = _REG_BIT(0x60, 25), + SCC_CAN2 = _REG_BIT(0x60, 26), + SCC_PWR = _REG_BIT(0x60, 28), + SCC_DAC = _REG_BIT(0x60, 29), + SCC_UART7 = _REG_BIT(0x60, 30),/* F2xx, F3xx */ + SCC_UART8 = _REG_BIT(0x60, 31),/* F2xx, F3xx */ + + /* APB2 peripherals */ + SCC_TIM1 = _REG_BIT(0x64, 0), + SCC_TIM8 = _REG_BIT(0x64, 1), + SCC_USART1 = _REG_BIT(0x64, 4), + SCC_USART6 = _REG_BIT(0x64, 5), + SCC_ADC1 = _REG_BIT(0x64, 8), + SCC_ADC2 = _REG_BIT(0x64, 9), + SCC_ADC3 = _REG_BIT(0x64, 10), + SCC_SDIO = _REG_BIT(0x64, 11), + SCC_SPI1 = _REG_BIT(0x64, 12), + SCC_SPI4 = _REG_BIT(0x64, 13),/* F2xx, F3xx */ + SCC_SYSCFG = _REG_BIT(0x64, 14), + SCC_TIM9 = _REG_BIT(0x64, 16), + SCC_TIM10 = _REG_BIT(0x64, 17), + SCC_TIM11 = _REG_BIT(0x64, 18), + SCC_SPI5 = _REG_BIT(0x64, 20),/* F2xx, F3xx */ + SCC_SPI6 = _REG_BIT(0x64, 21),/* F2xx, F3xx */ + SCC_SAI1 = _REG_BIT(0x64, 22),/* F4x9 */ + SCC_LTDC = _REG_BIT(0x64, 26),/* F4x9 */ + SCC_DSI = _REG_BIT(0x64, 27),/* F4x9 */ +}; + +enum rcc_periph_rst { + /* AHB1 peripherals*/ + RST_GPIOA = _REG_BIT(0x10, 0), + RST_GPIOB = _REG_BIT(0x10, 1), + RST_GPIOC = _REG_BIT(0x10, 2), + RST_GPIOD = _REG_BIT(0x10, 3), + RST_GPIOE = _REG_BIT(0x10, 4), + RST_GPIOF = _REG_BIT(0x10, 5), + RST_GPIOG = _REG_BIT(0x10, 6), + RST_GPIOH = _REG_BIT(0x10, 7), + RST_GPIOI = _REG_BIT(0x10, 8), + RST_GPIOJ = _REG_BIT(0x10, 9), + RST_GPIOK = _REG_BIT(0x10, 10), + RST_CRC = _REG_BIT(0x10, 12), + RST_DMA1 = _REG_BIT(0x10, 21), + RST_DMA2 = _REG_BIT(0x10, 22), + RST_DMA2D = _REG_BIT(0x10, 23), + RST_ETHMAC = _REG_BIT(0x10, 25), + RST_OTGHS = _REG_BIT(0x10, 29), + + /* AHB2 peripherals */ + RST_DCMI = _REG_BIT(0x14, 0), + RST_CRYP = _REG_BIT(0x14, 4), + RST_HASH = _REG_BIT(0x14, 5), + RST_RNG = _REG_BIT(0x14, 6), + RST_OTGFS = _REG_BIT(0x14, 7), + + /* AHB3 peripherals */ + RST_QSPI = _REG_BIT(0x18, 1), /* F4x9 */ + RST_FSMC = _REG_BIT(0x18, 0), + RST_FMC = _REG_BIT(0x18, 0), /* F4x9 */ + + /* APB1 peripherals*/ + RST_TIM2 = _REG_BIT(0x20, 0), + RST_TIM3 = _REG_BIT(0x20, 1), + RST_TIM4 = _REG_BIT(0x20, 2), + RST_TIM5 = _REG_BIT(0x20, 3), + RST_TIM6 = _REG_BIT(0x20, 4), + RST_TIM7 = _REG_BIT(0x20, 5), + RST_TIM12 = _REG_BIT(0x20, 6), + RST_TIM13 = _REG_BIT(0x20, 7), + RST_TIM14 = _REG_BIT(0x20, 8), + RST_WWDG = _REG_BIT(0x20, 11), + RST_SPI2 = _REG_BIT(0x20, 14), + RST_SPI3 = _REG_BIT(0x20, 15), + RST_USART2 = _REG_BIT(0x20, 17), + RST_USART3 = _REG_BIT(0x20, 18), + RST_UART4 = _REG_BIT(0x20, 19), + RST_UART5 = _REG_BIT(0x20, 20), + RST_I2C1 = _REG_BIT(0x20, 21), + RST_I2C2 = _REG_BIT(0x20, 22), + RST_I2C3 = _REG_BIT(0x20, 23), + RST_CAN1 = _REG_BIT(0x20, 25), + RST_CAN2 = _REG_BIT(0x20, 26), + RST_PWR = _REG_BIT(0x20, 28), + RST_DAC = _REG_BIT(0x20, 29), + RST_UART7 = _REG_BIT(0x20, 30),/* F2xx, F3xx */ + RST_UART8 = _REG_BIT(0x20, 31),/* F2xx, F3xx */ + + /* APB2 peripherals */ + RST_TIM1 = _REG_BIT(0x24, 0), + RST_TIM8 = _REG_BIT(0x24, 1), + RST_USART1 = _REG_BIT(0x24, 4), + RST_USART6 = _REG_BIT(0x24, 5), + RST_ADC = _REG_BIT(0x24, 8), + RST_SDIO = _REG_BIT(0x24, 11), + RST_SPI1 = _REG_BIT(0x24, 12), + RST_SPI4 = _REG_BIT(0x24, 13),/* F2xx, F3xx */ + RST_SYSCFG = _REG_BIT(0x24, 14), + RST_TIM9 = _REG_BIT(0x24, 16), + RST_TIM10 = _REG_BIT(0x24, 17), + RST_TIM11 = _REG_BIT(0x24, 18), + RST_SPI5 = _REG_BIT(0x24, 20),/* F2xx, F3xx */ + RST_SPI6 = _REG_BIT(0x24, 21),/* F2xx, F3xx */ + RST_SAI1RST = _REG_BIT(0x24, 22),/* F42x, F43x */ + RST_LTDC = _REG_BIT(0x24, 26),/* F42x, F43x */ + RST_DSI = _REG_BIT(0x24, 27),/* F42x, F43x */ +}; + +#undef _REG_BIT + +#include + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_sysclk_status(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_pllsai_config(uint16_t n, uint16_t p, uint16_t q, uint16_t r); +void rcc_pllsai_postscalers(uint8_t q, uint8_t r); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_rtcpre(uint32_t rtcpre); +void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq, uint32_t pllr); +void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq, uint32_t pllr); +uint32_t rcc_system_clock_source(void); +void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rng.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rng.h new file mode 100644 index 00000000..09d014d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rng.h @@ -0,0 +1,23 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RNG_H +#define LIBOPENCM3_RNG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rtc.h new file mode 100644 index 00000000..555efcb5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/rtc.h @@ -0,0 +1,45 @@ +/** @defgroup rtc_defines RTC Defines + +@brief Defined Constants and Types for the STM32F4xx RTC + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H + +#include + +BEGIN_DECLS + +void rtc_enable_wakeup_timer(void); +void rtc_disable_wakeup_timer(void); +void rtc_enable_wakeup_timer_interrupt(void); +void rtc_disable_wakeup_timer_interrupt(void); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/spi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/spi.h new file mode 100644 index 00000000..2ddeb124 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/spi.h @@ -0,0 +1,37 @@ +/** @defgroup spi_defines SPI Defines + +@brief Defined Constants and Types for the STM32F4xx SPI + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SPI_H +#define LIBOPENCM3_SPI_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/syscfg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/syscfg.h new file mode 100644 index 00000000..5f4fba4a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/syscfg.h @@ -0,0 +1,41 @@ +/** @defgroup syscfg_defines SYSCFG Defines + * + * @ingroup STM32F4xx_defines + * + * @brief Defined Constants and Types for the STM32F4xx Sysconfig + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SYSCFG_H +#define LIBOPENCM3_SYSCFG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/timer.h new file mode 100644 index 00000000..604a83f3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/timer.h @@ -0,0 +1,39 @@ +/** @defgroup timer_defines Timer Defines + +@brief libopencm3 Defined Constants and Types for the STM32F4xx Timers + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 8 March 2013 + +@author @htmlonly © @endhtmlonly 2011 Fergus Noble + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/usart.h new file mode 100644 index 00000000..1332641e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f4/usart.h @@ -0,0 +1,37 @@ +/** @defgroup usart_defines USART Defines + +@brief Defined Constants and Types for the STM32F4xx USART + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_USART_H +#define LIBOPENCM3_USART_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/doc-stm32f7.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/doc-stm32f7.h new file mode 100644 index 00000000..720693f7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/doc-stm32f7.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32F7 + +@version 1.0.0 + +@date 15 September 2014 + +API documentation for ST Microelectronics STM32F7 Cortex M7 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F7xx STM32F7xx +Libraries for ST Microelectronics STM32F7xx series. + +@version 1.0.0 + +@date 15 September 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32F7xx_defines STM32F7xx Defines + +@brief Defined Constants and Types for the STM32F7xx series + +@version 1.0.0 + +@date 15 September 2014 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/flash.h new file mode 100644 index 00000000..f75fc525 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/flash.h @@ -0,0 +1,37 @@ +/** @defgroup flash_defines FLASH Defines + * + * @ingroup STM32F7xx_defines + * + * @brief Defined Constants and Types for the STM32F7xx FLASH Memory + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/gpio.h new file mode 100644 index 00000000..6e88e225 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/gpio.h @@ -0,0 +1,37 @@ +/** @defgroup gpio_defines GPIO Defines + +@brief Defined Constants and Types for the STM32F7xx General Purpose I/O + +@ingroup STM32F7xx_defines + +@version 1.0.0 + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/irq.json new file mode 100644 index 00000000..79e1ee62 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/irq.json @@ -0,0 +1,103 @@ +{ + "irqs": [ + "nvic_wwdg", + "pvd", + "tamp_stamp", + "rtc_wkup", + "flash", + "rcc", + "exti0", + "exti1", + "exti2", + "exti3", + "exti4", + "dma1_stream0", + "dma1_stream1", + "dma1_stream2", + "dma1_stream3", + "dma1_stream4", + "dma1_stream5", + "dma1_stream6", + "adc", + "can1_tx", + "can1_rx0", + "can1_rx1", + "can1_sce", + "exti9_5", + "tim1_brk_tim9", + "tim1_up_tim10", + "tim1_trg_com_tim11", + "tim1_cc", + "tim2", + "tim3", + "tim4", + "i2c1_ev", + "i2c1_er", + "i2c2_ev", + "i2c2_er", + "spi1", + "spi2", + "usart1", + "usart2", + "usart3", + "exti15_10", + "rtc_alarm", + "usb_fs_wkup", + "tim8_brk_tim12", + "tim8_up_tim13", + "tim8_trg_com_tim14", + "tim8_cc", + "dma1_stream7", + "fsmc", + "sdmmc1", + "tim5", + "spi3", + "uart4", + "uart5", + "tim6_dac", + "tim7", + "dma2_stream0", + "dma2_stream1", + "dma2_stream2", + "dma2_stream3", + "dma2_stream4", + "eth", + "eth_wkup", + "can2_tx", + "can2_rx0", + "can2_rx1", + "can2_sce", + "otg_fs", + "dma2_stream5", + "dma2_stream6", + "dma2_stream7", + "usart6", + "i2c3_ev", + "i2c3_er", + "otg_hs_ep1_out", + "otg_hs_ep1_in", + "otg_hs_wkup", + "otg_hs", + "dcmi", + "cryp", + "hash_rng", + "fpu", + "uart7", + "uart8", + "spi4", + "spi5", + "spi6", + "sai1", + "lcd_tft", + "lcd_tft_err", + "dma2d", + "sai2", + "quadspi", + "i2c4_ev", + "i2c4_er", + "spdifrx" + ], + "partname_humanreadable": "STM32 F7 series", + "partname_doxygen": "STM32F7", + "includeguard": "LIBOPENCM3_STM32_F7_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/memorymap.h new file mode 100644 index 00000000..1492974e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/memorymap.h @@ -0,0 +1,164 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32F7 specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x20000) +#define PERIPH_BASE_AHB2 0x50000000U +#define PERIPH_BASE_AHB3 0x60000000U + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define TIM12_BASE (PERIPH_BASE_APB1 + 0x1800) +#define TIM13_BASE (PERIPH_BASE_APB1 + 0x1c00) +#define TIM14_BASE (PERIPH_BASE_APB1 + 0x2000) +#define LPTIM1_BASE (PERIPH_BASE_APB1 + 0x2400) +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +/* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +#define SPDIF_BASE (PERIPH_BASE_APB1 + 0x4000) +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define UART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define UART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define I2C3_BASE (PERIPH_BASE_APB1 + 0x5C00) +#define I2C4_BASE (PERIPH_BASE_APB1 + 0x6000) +#define BX_CAN1_BASE (PERIPH_BASE_APB1 + 0x6400) +#define BX_CAN2_BASE (PERIPH_BASE_APB1 + 0x6800) +#define CEC_BASE (PERIPH_BASE_APB1 + 0x6C00) +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define UART7_BASE (PERIPH_BASE_APB1 + 0x7800) +#define UART8_BASE (PERIPH_BASE_APB1 + 0x7c00) +/* PERIPH_BASE_APB1 + 0x7800 (0x4000 8000 - 0x4000 FFFF): Reserved */ + +/* APB2 */ +#define TIM1_BASE (PERIPH_BASE_APB2 + 0x0000) +#define TIM8_BASE (PERIPH_BASE_APB2 + 0x0400) +/* PERIPH_BASE_APB2 + 0x0800 (0x4001 0800 - 0x4001 0FFF): Reserved */ +#define USART1_BASE (PERIPH_BASE_APB2 + 0x1000) +#define USART6_BASE (PERIPH_BASE_APB2 + 0x1400) +/* PERIPH_BASE_APB2 + 0x1800 (0x4001 1800 - 0x4001 1FFF): Reserved */ +#define ADC1_BASE (PERIPH_BASE_APB2 + 0x2000) /* TODO */ +#define ADC2_BASE (PERIPH_BASE_APB2 + 0x2100) /* TODO */ +#define ADC3_BASE (PERIPH_BASE_APB2 + 0x2200) /* TODO */ +#define ADC_COMMON_BASE (PERIPH_BASE_APB2 + 0x2300) /* TODO */ +/* PERIPH_BASE_APB2 + 0x2400 (0x4001 2400 - 0x4001 27FF): Reserved */ +#define SDIO_BASE (PERIPH_BASE_APB2 + 0x2C00) /* SDMMC */ +/* PERIPH_BASE_APB2 + 0x2C00 (0x4001 2C00 - 0x4001 2FFF): Reserved */ +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +#define SPI4_BASE (PERIPH_BASE_APB2 + 0x3400) +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x3800) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x3C00) +#define TIM9_BASE (PERIPH_BASE_APB2 + 0x4000) +#define TIM10_BASE (PERIPH_BASE_APB2 + 0x4400) +#define TIM11_BASE (PERIPH_BASE_APB2 + 0x4800) +/* PERIPH_BASE_APB2 + 0x4C00 (0x4001 4C00 - 0x4001 4FFF): Reserved */ +#define SPI5_BASE (PERIPH_BASE_APB2 + 0x5000) +#define SPI6_BASE (PERIPH_BASE_APB2 + 0x5400) +#define SAI1_BASE (PERIPH_BASE_APB2 + 0x5800) +#define SAI2_BASE (PERIPH_BASE_APB2 + 0x5C00) +#define LCD_TFT_BASE (PERIPH_BASE_APB2 + 0x6800) +/* PERIPH_BASE_APB2 + 0x6C00 (0x4001 6C00 - 0x4001 FFFF): Reserved */ + +/* AHB1 */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB1 + 0x0000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB1 + 0x0400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB1 + 0x0800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB1 + 0x0C00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB1 + 0x1000) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB1 + 0x1400) +#define GPIO_PORT_G_BASE (PERIPH_BASE_AHB1 + 0x1800) +#define GPIO_PORT_H_BASE (PERIPH_BASE_AHB1 + 0x1C00) +#define GPIO_PORT_I_BASE (PERIPH_BASE_AHB1 + 0x2000) +#define GPIO_PORT_J_BASE (PERIPH_BASE_AHB1 + 0x2400) +#define GPIO_PORT_K_BASE (PERIPH_BASE_AHB1 + 0x2800) +/* PERIPH_BASE_AHB1 + 0x2C00 (0x4002 2C00 - 0x4002 2FFF): Reserved */ +#define CRC_BASE (PERIPH_BASE_AHB1 + 0x3000) +/* PERIPH_BASE_AHB1 + 0x3400 (0x4002 3400 - 0x4002 37FF): Reserved */ +#define RCC_BASE (PERIPH_BASE_AHB1 + 0x3800) +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x3C00) +#define BKPSRAM_BASE (PERIPH_BASE_AHB1 + 0x4000) +/* PERIPH_BASE_AHB1 + 0x5000 (0x4002 5000 - 0x4002 5FFF): Reserved */ +#define DMA1_BASE (PERIPH_BASE_AHB1 + 0x6000) +#define DMA2_BASE (PERIPH_BASE_AHB1 + 0x6400) +/* PERIPH_BASE_AHB1 + 0x6800 (0x4002 6800 - 0x4002 7FFF): Reserved */ +#define ETHERNET_BASE (PERIPH_BASE_AHB1 + 0x8000) + +#define DMA2D_BASE (PERIPH_BASE_AHB1 + 0xB000) + +#define USB_OTG_HS_BASE (PERIPH_BASE_AHB1 + 0x20000) + + +/* AHB2 */ +#define USB_OTG_FS_BASE (PERIPH_BASE_AHB2 + 0x00000) +/* PERIPH_BASE_AHB2 + 0x40000 (0x5004 0000 - 0x5004 FFFF): Reserved */ +#define DCMI_BASE (PERIPH_BASE_AHB2 + 0x50000) +/* PERIPH_BASE_AHB2 + 0x50400 (0x5005 0400 - 0x5005 FFFF): Reserved */ +#define CRYP_BASE (PERIPH_BASE_AHB2 + 0x60000) +#define HASH_BASE (PERIPH_BASE_AHB2 + 0x60400) +/* PERIPH_BASE_AHB2 + 0x60C00 (0x5006 0C00 - 0x5006 07FF): Reserved */ +#define RNG_BASE (PERIPH_BASE_AHB2 + 0x60800) +/* PERIPH_BASE_AHB2 + 0x61000 (0x5006 1000 - 0x5FFF FFFF): Reserved */ + +/* AHB3 */ +#define FMC1_BASE (PERIPH_BASE_AHB3 + 0x00000000U) +#define FMC2_BASE (PERIPH_BASE_AHB3 + 0x10000000U) +#define FMC3_BASE (PERIPH_BASE_AHB3 + 0x20000000U) +#define QSPI_BASE (PERIPH_BASE_AHB3 + 0x30000000U) +#define FMCC_BASE (PERIPH_BASE_AHB3 + 0x40000000U) +#define QSPIC_BASE (PERIPH_BASE_AHB3 + 0x40001000U) +#define FMC5_BASE (PERIPH_BASE_AHB3 + 0x60000000U) +#define FMC6_BASE (PERIPH_BASE_AHB3 + 0x70000000U) + +/* Private peripherals */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (0x1FF0F422U) +#define DESIG_UNIQUE_ID_BASE (0x1FF0F420U) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 8) + +/* ST provided factory calibration values @ 3.3V */ +#define ST_VREFINT_CAL MMIO16(0x1FF07A4A) +#define ST_TSENSE_CAL1_30C MMIO16(0x1FF07A4C) +#define ST_TSENSE_CAL2_110C MMIO16(0x1FF07A4E) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/pwr.h new file mode 100644 index 00000000..87477b44 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/pwr.h @@ -0,0 +1,295 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32F7xx Power Control + +@ingroup STM32F7xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2017 Matthew Lai + +@date 12 March 2017 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017 Matthew Lai + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +/**@{*/ + +/** @defgroup pwr_registers PWR Registers + * @ingroup STM32F_pwr_defines +@{*/ +/** Power control register (PWR_CR1) */ +#define PWR_CR1 MMIO32(POWER_CONTROL_BASE + 0x00) + +/** Power control/status register (PWR_CSR1) */ +#define PWR_CSR1 MMIO32(POWER_CONTROL_BASE + 0x04) + +/** Power control register 2 (PWR_CR2) */ +#define PWR_CR2 MMIO32(POWER_CONTROL_BASE + 0x08) + +/** Power control/status register 2 (PWR_CSR2) */ +#define PWR_CSR2 MMIO32(POWER_CONTROL_BASE + 0x0c) +/*@}*/ + +/** @defgroup pwr_cr1_defines PWR_CR1 values + * @ingroup STM32F_pwr_defines +@{*/ + +/* Bits [31:20]: Reserved, must be kept at reset value. */ + +/** UDEN[19:18]: Under-drive enable in stop mode */ +#define PWR_CR1_UDEN_LSB 18 +/** @defgroup pwr_uden Under-drive enable in stop mode +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CR1_UDEN_DISABLED (0x0 << PWR_CR1_UDEN_LSB) +#define PWR_CR1_UDEN_ENABLED (0x3 << PWR_CR1_UDEN_LSB) +/**@}*/ +#define PWR_CR1_UDEN_MASK (0x3 << PWR_CR1_UDEN_LSB) + +/** ODSWEN: Over-drive switching enabled */ +#define PWR_CR1_ODSWEN (1 << 17) + +/** ODEN: Over-drive enable */ +#define PWR_CR1_ODEN (1 << 16) + +/* VOS[15:14]: Regulator voltage scaling output selection */ +#define PWR_CR1_VOS_LSB 14 +/** @defgroup pwr_vos Regulator voltage scaling output selection +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CR1_VOS_SCALE_3 (0x1 << PWR_CR1_VOS_LSB) +#define PWR_CR1_VOS_SCALE_2 (0x2 << PWR_CR1_VOS_LSB) +#define PWR_CR1_VOS_SCALE_1 (0x3 << PWR_CR1_VOS_LSB) +/**@}*/ +#define PWR_CR1_VOS_MASK (0x3 << PWR_CR1_VOS_LSB) + +/** ADCDC1: Masks extra flash accesses by prefetch (see AN4073) */ +#define PWR_CR1_ADCDC1 (1 << 13) + +/* Bit 12: Reserved, must be kept at reset value. */ + +/** MRUDS: Main regulator in deepsleep under-drive mode */ +#define PWR_CR1_MRUDS (1 << 11) + +/** LPUDS: Low-power regulator in deepsleep under-drive mode */ +#define PWR_CR1_LPUDS (1 << 10) + +/** FPDS: Flash power-down in Stop mode */ +#define PWR_CR1_FPDS (1 << 9) + +/** DBP: Disable backup domain write protection */ +#define PWR_CR1_DBP (1 << 8) + +/* PLS[7:5]: PVD level selection */ +#define PWR_CR1_PLS_LSB 5 +/** @defgroup pwr_pls PVD level selection +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CR1_PLS_2V0 (0x0 << PWR_CR_PLS_LSB) +#define PWR_CR1_PLS_2V1 (0x1 << PWR_CR_PLS_LSB) +#define PWR_CR1_PLS_2V3 (0x2 << PWR_CR_PLS_LSB) +#define PWR_CR1_PLS_2V5 (0x3 << PWR_CR_PLS_LSB) +#define PWR_CR1_PLS_2V6 (0x4 << PWR_CR_PLS_LSB) +#define PWR_CR1_PLS_2V7 (0x5 << PWR_CR_PLS_LSB) +#define PWR_CR1_PLS_2V8 (0x6 << PWR_CR_PLS_LSB) +#define PWR_CR1_PLS_2V9 (0x7 << PWR_CR_PLS_LSB) +/**@}*/ +#define PWR_CR1_PLS_MASK (0x7 << PWR_CR_PLS_LSB) + +/** PVDE: Power voltage detector enable */ +#define PWR_CR1_PVDE (1 << 4) + +/** CSBF: Clear standby flag */ +#define PWR_CR1_CSBF (1 << 3) + +/* Bit 2: Reserved, must be kept at reset value. */ + +/** PDDS: Power down deepsleep */ +#define PWR_CR1_PDDS (1 << 1) + +/** LPDS: Low-power deepsleep */ +#define PWR_CR1_LPDS (1 << 0) +/*@}*/ + +/** @defgroup pwr_csr1_defines PWR_CSR1 values + * @ingroup STM32F_pwr_defines +@{*/ + +/* Bits [31:20]: Reserved, must be kept at reset value. */ + +/* UDRDY[19:18]: Under-drive ready flag */ +#define PWR_CSR1_UDRDY_LSB 18 +/** @defgroup pwr_udrdy Under-drive ready flag +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CSR1_UDRDY_DISABLED (0x0 << PWR_CSR1_UDRDY_LSB) +#define PWR_CSR1_UDRDY_ACTIVATED (0x3 << PWR_CSR1_UDRDY_LSB) +/**@}*/ +#define PWR_CSR1_UDRDY_MASK (0x3 << PWR_CSR1_UDRDY_LSB) + +/** ODSWRDY: Over-drive mode switching ready */ +#define PWR_CSR1_ODSWRDY (1 << 17) + +/** ODRDY: Over-drive mode ready */ +#define PWR_CSR1_ODRDY (1 << 16) + +/* Bit 15: Reserved, must be kept at reset value. */ + +/** VOSRDY: Regulator voltage scaling output selection ready bit */ +#define PWR_CSR1_VOSRDY (1 << 14) + +/* Bits [13:10]: Reserved, must be kept at reset value. */ + +/** BRE: Backup regulator enable */ +#define PWR_CSR1_BRE (1 << 9) + +/** EIWUP: Enable internal wakeup */ +#define PWR_CSR1_EIWUP (1 << 8) + +/* Bits [7:4]: Reserved, must be kept at reset value. */ + +/** BRR: Backup regulator ready */ +#define PWR_CSR1_BRR (1 << 3) + +/** PVDO: PVD output */ +#define PWR_CSR1_PVDO (1 << 2) + +/** SBF: Standby flag */ +#define PWR_CSR1_SBF (1 << 1) + +/** WUIF: Wakeup internal flag */ +#define PWR_CSR1_WUIF (1 << 0) +/*@}*/ + +/** @defgroup pwr_cr2_defines PWR_CR2 values + * @ingroup STM32F_pwr_defines +@{*/ + +/* Bits [31:14]: Reserved, must be kept at reset value. */ + +/** WUPP6: Wakeup pin polarity bit for PI11 */ +#define PWR_CR2_WUPP6 (1 << 13) + +/** WUPP5: Wakeup pin polarity bit for PI8 */ +#define PWR_CR2_WUPP5 (1 << 12) + +/** WUPP4: Wakeup pin polarity bit for PC13 */ +#define PWR_CR2_WUPP4 (1 << 11) + +/** WUPP3: Wakeup pin polarity bit for PC1 */ +#define PWR_CR2_WUPP3 (1 << 10) + +/** WUPP2: Wakeup pin polarity bit for PA2 */ +#define PWR_CR2_WUPP2 (1 << 9) + +/** WUPP1: Wakeup pin polarity bit for PA0 */ +#define PWR_CR2_WUPP1 (1 << 8) + +/* Bits [7:6]: Reserved, must be kept at reset value. */ + +/** CWUPF6: Clear Wakeup Pin flag for PI11 */ +#define PWR_CR2_CWUPF6 (1 << 5) + +/** CWUPF5: Clear Wakeup Pin flag for PI8 */ +#define PWR_CR2_CWUPF5 (1 << 4) + +/** CWUPF4: Clear Wakeup Pin flag for PC13 */ +#define PWR_CR2_CWUPF4 (1 << 3) + +/** CWUPF3: Clear Wakeup Pin flag for PC1 */ +#define PWR_CR2_CWUPF3 (1 << 2) + +/** CWUPF2: Clear Wakeup Pin flag for PA2 */ +#define PWR_CR2_CWUPF2 (1 << 1) + +/** CWUPF1: Clear Wakeup Pin flag for PA0 */ +#define PWR_CR2_CWUPF1 (1 << 0) +/*@}*/ + +/** @defgroup pwr_csr2_defines PWR_CSR2 values + * @ingroup STM32F_pwr_defines +@{*/ + +/* Bits [31:14]: Reserved, must be kept at reset value. */ + +/** EWUP6: Enable Wakeup pin for PI11 */ +#define PWR_CSR2_EWUP6 (1 << 13) + +/** EWUP5: Enable Wakeup pin for PI8 */ +#define PWR_CSR2_EWUP5 (1 << 12) + +/** EWUP4: Enable Wakeup pin for PC13 */ +#define PWR_CSR2_EWUP4 (1 << 11) + +/** EWUP3: Enable Wakeup pin for PC1 */ +#define PWR_CSR2_EWUP3 (1 << 10) + +/** EWUP2: Enable Wakeup pin for PA2 */ +#define PWR_CSR2_EWUP2 (1 << 19) + +/** EWUP1: Enable Wakeup pin for PA0 */ +#define PWR_CSR2_EWUP1 (1 << 18) + +/* Bits [7:6]: Reserved, must be kept at reset value. */ + +/** WUPF6: Wakeup Pin flag for PI11 */ +#define PWR_CSR2_WUPF6 (1 << 5) + +/** WUPF5: Wakeup Pin flag for PI8 */ +#define PWR_CSR2_WUPF5 (1 << 4) + +/** WUPF4: Wakeup Pin flag for PC13 */ +#define PWR_CSR2_WUPF4 (1 << 3) + +/** WUPF3: Wakeup Pin flag for PC1 */ +#define PWR_CSR2_WUPF3 (1 << 2) + +/** WUPF2: Wakeup Pin flag for PA2 */ +#define PWR_CSR2_WUPF2 (1 << 1) + +/** WUPF1: Wakeup Pin flag for PA0 */ +#define PWR_CSR2_WUPF1 (1 << 0) +/*@}*/ +/* --- Function prototypes ------------------------------------------------- */ + +enum pwr_vos_scale { + PWR_SCALE1, /** <= 180MHz w/o overdrive, <= 216MHz w/ overdrive */ + PWR_SCALE2, /** <= 168MHz w/o overdrive, <= 180MHz w/ overdrive */ + PWR_SCALE3, /** <= 144MHz */ +}; + +BEGIN_DECLS + +void pwr_set_vos_scale(enum pwr_vos_scale scale); +void pwr_enable_overdrive(void); +void pwr_disable_overdrive(void); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rcc.h new file mode 100644 index 00000000..9b2fad67 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rcc.h @@ -0,0 +1,938 @@ +/** @defgroup rcc_defines RCC Defines + * + * @brief Defined Constants and Types for the STM32F7xx Reset and Clock + * Control + * + * @ingroup STM32F7xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2015 + * Karl Palsson + * + * @date October, 2015 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +#include + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_PLLCFGR MMIO32(RCC_BASE + 0x04) +#define RCC_CFGR MMIO32(RCC_BASE + 0x08) +#define RCC_CIR MMIO32(RCC_BASE + 0x0c) +#define RCC_AHB1RSTR MMIO32(RCC_BASE + 0x10) +#define RCC_AHB2RSTR MMIO32(RCC_BASE + 0x14) +#define RCC_AHB3RSTR MMIO32(RCC_BASE + 0x18) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x20) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x24) +#define RCC_AHB1ENR MMIO32(RCC_BASE + 0x30) +#define RCC_AHB2ENR MMIO32(RCC_BASE + 0x34) +#define RCC_AHB3ENR MMIO32(RCC_BASE + 0x38) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x40) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x44) +#define RCC_AHB1LPENR MMIO32(RCC_BASE + 0x50) +#define RCC_AHB2LPENR MMIO32(RCC_BASE + 0x54) +#define RCC_AHB3LPENR MMIO32(RCC_BASE + 0x58) +#define RCC_APB1LPENR MMIO32(RCC_BASE + 0x60) +#define RCC_APB2LPENR MMIO32(RCC_BASE + 0x64) +#define RCC_BDCR MMIO32(RCC_BASE + 0x70) +#define RCC_CSR MMIO32(RCC_BASE + 0x74) +#define RCC_SSCGR MMIO32(RCC_BASE + 0x80) +#define RCC_PLLI2SCFGR MMIO32(RCC_BASE + 0x84) +#define RCC_PLLSAICFGR MMIO32(RCC_BASE + 0x88) +#define RCC_DCKCFGR1 MMIO32(RCC_BASE + 0x8C) +#define RCC_DCKCFGR2 MMIO32(RCC_BASE + 0x90) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLSAIRDY (1 << 29) +#define RCC_CR_PLLSAION (1 << 28) +#define RCC_CR_PLLI2SRDY (1 << 27) +#define RCC_CR_PLLI2SON (1 << 26) +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSICAL_MASK 0xff +#define RCC_CR_HSICAL_SHIFT 8 +#define RCC_CR_HSITRIM_MASK 0x1f +#define RCC_CR_HSITRIM_SHIFT 3 +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +/* --- RCC_PLLCFGR values -------------------------------------------------- */ + +#define RCC_PLLCFGR_PLLQ_MASK 0xf +#define RCC_PLLCFGR_PLLQ_SHIFT 24 +#define RCC_PLLCFGR_PLLSRC (1 << 22) +#define RCC_PLLCFGR_PLLP_MASK 0x3 +#define RCC_PLLCFGR_PLLP_SHIFT 16 +#define RCC_PLLCFGR_PLLN_MASK 0x1ff +#define RCC_PLLCFGR_PLLN_SHIFT 6 +#define RCC_PLLCFGR_PLLM_MASK 0x3f +#define RCC_PLLCFGR_PLLM_SHIFT 0 + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +/* MCO2: Microcontroller clock output 2 */ +#define RCC_CFGR_MCO2_MASK 0x3 +#define RCC_CFGR_MCO2_SHIFT 30 +#define RCC_CFGR_MCO2_SYSCLK 0x0 +#define RCC_CFGR_MCO2_PLLI2S 0x1 +#define RCC_CFGR_MCO2_HSE 0x2 +#define RCC_CFGR_MCO2_PLL 0x3 + +/* MCO1/2PRE: MCO Prescalers */ +#define RCC_CFGR_MCOPRE_MASK 0x7 +#define RCC_CFGR_MCO2PRE_SHIFT 27 +#define RCC_CFGR_MCO1PRE_SHIFT 24 +#define RCC_CFGR_MCOPRE_DIV_NONE 0x0 +#define RCC_CFGR_MCOPRE_DIV_2 0x4 +#define RCC_CFGR_MCOPRE_DIV_3 0x5 +#define RCC_CFGR_MCOPRE_DIV_4 0x6 +#define RCC_CFGR_MCOPRE_DIV_5 0x7 + +/* I2SSRC: I2S clock selection */ +#define RCC_CFGR_I2SSRC (1 << 23) + +/* MCO1: Microcontroller clock output 1 */ +#define RCC_CFGR_MCO1_MASK 0x3 +#define RCC_CFGR_MCO1_SHIFT 21 +#define RCC_CFGR_MCO1_HSI 0x0 +#define RCC_CFGR_MCO1_LSE 0x1 +#define RCC_CFGR_MCO1_HSE 0x2 +#define RCC_CFGR_MCO1_PLL 0x3 +#define RCC_CFGR_MCO_SHIFT RCC_CFGR_MCO1_SHIFT +#define RCC_CFGR_MCO_MASK RCC_CFGR_MCO1_MASK + +/* RTCPRE: HSE division factor for RTC clock */ +#define RCC_CFGR_RTCPRE_SHIFT 16 +#define RCC_CFGR_RTCPRE_MASK 0x1f + +/* PPRE1/2: APB high-speed prescalers */ +#define RCC_CFGR_PPRE2_SHIFT 13 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 10 +#define RCC_CFGR_PPRE1_MASK 0x7 +#define RCC_CFGR_PPRE_DIV_NONE 0x0 +#define RCC_CFGR_PPRE_DIV_2 0x4 +#define RCC_CFGR_PPRE_DIV_4 0x5 +#define RCC_CFGR_PPRE_DIV_8 0x6 +#define RCC_CFGR_PPRE_DIV_16 0x7 + +/* HPRE: AHB high-speed prescaler */ +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE_MASK 0xf +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_SHIFT 2 +#define RCC_CFGR_SWS_MASK 0x3 +#define RCC_CFGR_SWS_HSI 0x0 +#define RCC_CFGR_SWS_HSE 0x1 +#define RCC_CFGR_SWS_PLL 0x2 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_SHIFT 0 +#define RCC_CFGR_SW_MASK 0x3 +#define RCC_CFGR_SW_HSI 0x0 +#define RCC_CFGR_SW_HSE 0x1 +#define RCC_CFGR_SW_PLL 0x2 + +/* --- RCC_CIR values ------------------------------------------------------ */ + +/* Clock security system interrupt clear bit */ +#define RCC_CIR_CSSC (1 << 23) + +/* OSC ready interrupt clear bits */ +#define RCC_CIR_PLLSAIRDYC (1 << 22) +#define RCC_CIR_PLLI2SRDYC (1 << 21) +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) + +/* OSC ready interrupt enable bits */ +#define RCC_CIR_PLLSAIRDYIE (1 << 14) +#define RCC_CIR_PLLI2SRDYIE (1 << 13) +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) + +/* Clock security system interrupt flag bit */ +#define RCC_CIR_CSSF (1 << 7) + +/* OSC ready interrupt flag bits */ +#define RCC_CIR_PLLSAIRDYF (1 << 6) +#define RCC_CIR_PLLI2SRDYF (1 << 5) +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_AHB1RSTR values ------------------------------------------------- */ + +#define RCC_AHB1RSTR_OTGHSRST (1 << 29) +#define RCC_AHB1RSTR_ETHMACRST (1 << 25) +#define RCC_AHB1RSTR_DMA2DRST (1 << 23) +#define RCC_AHB1RSTR_DMA2RST (1 << 22) +#define RCC_AHB1RSTR_DMA1RST (1 << 21) +#define RCC_AHB1RSTR_CRCRST (1 << 12) +#define RCC_AHB1RSTR_GPIOKRST (1 << 10) +#define RCC_AHB1RSTR_GPIOJRST (1 << 9) +#define RCC_AHB1RSTR_GPIOIRST (1 << 8) +#define RCC_AHB1RSTR_GPIOHRST (1 << 7) +#define RCC_AHB1RSTR_GPIOGRST (1 << 6) +#define RCC_AHB1RSTR_GPIOFRST (1 << 5) +#define RCC_AHB1RSTR_GPIOERST (1 << 4) +#define RCC_AHB1RSTR_GPIODRST (1 << 3) +#define RCC_AHB1RSTR_GPIOCRST (1 << 2) +#define RCC_AHB1RSTR_GPIOBRST (1 << 1) +#define RCC_AHB1RSTR_GPIOARST (1 << 0) + +/* --- RCC_AHB2RSTR values ------------------------------------------------- */ + +#define RCC_AHB2RSTR_OTGFSRST (1 << 7) +#define RCC_AHB2RSTR_RNGRST (1 << 6) +#define RCC_AHB2RSTR_HASHRST (1 << 5) +#define RCC_AHB2RSTR_CRYPRST (1 << 4) +#define RCC_AHB2RSTR_DCMIRST (1 << 0) + +/* --- RCC_AHB3RSTR values ------------------------------------------------- */ + +#define RCC_AHB3RSTR_QSPIRST (1 << 1) +#define RCC_AHB3RSTR_FSMCRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_UART8RST (1 << 31) +#define RCC_APB1RSTR_UART7RST (1 << 30) +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_CECRST (1 << 27) +#define RCC_APB1RSTR_CAN2RST (1 << 26) +#define RCC_APB1RSTR_CAN1RST (1 << 25) +#define RCC_APB1RSTR_I2C4RST (1 << 24) +#define RCC_APB1RSTR_I2C3RST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_UART5RST (1 << 20) +#define RCC_APB1RSTR_UART4RST (1 << 19) +#define RCC_APB1RSTR_UART3RST (1 << 18) +#define RCC_APB1RSTR_UART2RST (1 << 17) +#define RCC_APB1RSTR_SPDIFRXRST (1 << 16) +#define RCC_APB1RSTR_SPI3RST (1 << 15) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_LPTIM1RST (1 << 9) +#define RCC_APB1RSTR_TIM14RST (1 << 8) +#define RCC_APB1RSTR_TIM13RST (1 << 7) +#define RCC_APB1RSTR_TIM12RST (1 << 6) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM5RST (1 << 3) +#define RCC_APB1RSTR_TIM4RST (1 << 2) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_LTDCRST (1 << 26) +#define RCC_APB2RSTR_SAI2RST (1 << 23) +#define RCC_APB2RSTR_SAI1RST (1 << 22) +#define RCC_APB2RSTR_SPI6RST (1 << 21) +#define RCC_APB2RSTR_SPI5RST (1 << 20) +#define RCC_APB2RSTR_TIM11RST (1 << 18) +#define RCC_APB2RSTR_TIM10RST (1 << 17) +#define RCC_APB2RSTR_TIM9RST (1 << 16) +#define RCC_APB2RSTR_SYSCFGRST (1 << 14) +#define RCC_APB2RSTR_SPI4RST (1 << 13) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_SDMMC1RST (1 << 11) +#define RCC_APB2RSTR_ADCRST (1 << 8) +#define RCC_APB2RSTR_USART6RST (1 << 5) +#define RCC_APB2RSTR_USART1RST (1 << 4) +#define RCC_APB2RSTR_TIM8RST (1 << 1) +#define RCC_APB2RSTR_TIM1RST (1 << 0) + +/* --- RCC_AHB1ENR values ------------------------------------------------- */ + +#define RCC_AHB1ENR_OTGHSULPIEN (1 << 30) +#define RCC_AHB1ENR_OTGHSEN (1 << 29) +#define RCC_AHB1ENR_ETHMACPTPEN (1 << 28) +#define RCC_AHB1ENR_ETHMACRXEN (1 << 27) +#define RCC_AHB1ENR_ETHMACTXEN (1 << 26) +#define RCC_AHB1ENR_ETHMACEN (1 << 25) +#define RCC_AHB1ENR_DMA2DEN (1 << 23) +#define RCC_AHB1ENR_DMA2EN (1 << 22) +#define RCC_AHB1ENR_DMA1EN (1 << 21) +#define RCC_AHB1ENR_DTCMRAMEN (1 << 20) +#define RCC_AHB1ENR_BKPSRAMEN (1 << 18) +#define RCC_AHB1ENR_CRCEN (1 << 12) +#define RCC_AHB1ENR_GPIOKEN (1 << 10) +#define RCC_AHB1ENR_GPIOJEN (1 << 9) +#define RCC_AHB1ENR_GPIOIEN (1 << 8) +#define RCC_AHB1ENR_GPIOHEN (1 << 7) +#define RCC_AHB1ENR_GPIOGEN (1 << 6) +#define RCC_AHB1ENR_GPIOFEN (1 << 5) +#define RCC_AHB1ENR_GPIOEEN (1 << 4) +#define RCC_AHB1ENR_GPIODEN (1 << 3) +#define RCC_AHB1ENR_GPIOCEN (1 << 2) +#define RCC_AHB1ENR_GPIOBEN (1 << 1) +#define RCC_AHB1ENR_GPIOAEN (1 << 0) + +/* --- RCC_AHB2ENR values ------------------------------------------------- */ + +#define RCC_AHB2ENR_OTGFSEN (1 << 7) +#define RCC_AHB2ENR_RNGEN (1 << 6) +#define RCC_AHB2ENR_HASHEN (1 << 5) +#define RCC_AHB2ENR_CRYPEN (1 << 4) +#define RCC_AHB2ENR_DCMIEN (1 << 0) + +/* --- RCC_AHB3ENR values ------------------------------------------------- */ + +#define RCC_AHB3ENR_QSPIEN (1 << 1) +#define RCC_AHB3ENR_FMCEN (1 << 0) + +/* --- RCC_APB1ENR values ------------------------------------------------- */ + +#define RCC_APB1ENR_UART8EN (1 << 31) +#define RCC_APB1ENR_UART7EN (1 << 30) +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_CECEN (1 << 27) +#define RCC_APB1ENR_CAN2EN (1 << 26) +#define RCC_APB1ENR_CAN1EN (1 << 25) +#define RCC_APB1ENR_I2C4EN (1 << 24) +#define RCC_APB1ENR_I2C3EN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_UART5EN (1 << 20) +#define RCC_APB1ENR_UART4EN (1 << 19) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPIDIFRXEN (1 << 16) +#define RCC_APB1ENR_SPI3EN (1 << 15) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_LPTIM1EN (1 << 9) +#define RCC_APB1ENR_TIM14EN (1 << 8) +#define RCC_APB1ENR_TIM13EN (1 << 7) +#define RCC_APB1ENR_TIM12EN (1 << 6) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM5EN (1 << 3) +#define RCC_APB1ENR_TIM4EN (1 << 2) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) + +/* --- RCC_APB2ENR values ------------------------------------------------- */ + +#define RCC_APB2ENR_LTDCEN (1 << 26) +#define RCC_APB2ENR_SAI2EN (1 << 23) +#define RCC_APB2ENR_SAI1EN (1 << 22) +#define RCC_APB2ENR_SPI6EN (1 << 21) +#define RCC_APB2ENR_SPI5EN (1 << 20) +#define RCC_APB2ENR_TIM11EN (1 << 18) +#define RCC_APB2ENR_TIM10EN (1 << 17) +#define RCC_APB2ENR_TIM9EN (1 << 16) +#define RCC_APB2ENR_SYSCFGEN (1 << 14) +#define RCC_APB2ENR_SPI4EN (1 << 13) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_SDMMC1EN (1 << 11) +#define RCC_APB2ENR_ADC3EN (1 << 10) +#define RCC_APB2ENR_ADC2EN (1 << 9) +#define RCC_APB2ENR_ADC1EN (1 << 8) +#define RCC_APB2ENR_USART6EN (1 << 5) +#define RCC_APB2ENR_USART1EN (1 << 4) +#define RCC_APB2ENR_TIM8EN (1 << 1) +#define RCC_APB2ENR_TIM1EN (1 << 0) + +/* --- RCC_AHB1LPENR values ------------------------------------------------- */ + +#define RCC_AHB1LPENR_OTGHSULPILPEN (1 << 30) +#define RCC_AHB1LPENR_OTGHSLPEN (1 << 29) +#define RCC_AHB1LPENR_ETHMACPTPLPEN (1 << 28) +#define RCC_AHB1LPENR_ETHMACRXLPEN (1 << 27) +#define RCC_AHB1LPENR_ETHMACTXLPEN (1 << 26) +#define RCC_AHB1LPENR_ETHMACLPEN (1 << 25) +#define RCC_AHB1LPENR_DMA2DLPEN (1 << 23) +#define RCC_AHB1LPENR_DMA2LPEN (1 << 22) +#define RCC_AHB1LPENR_DMA1LPEN (1 << 21) +#define RCC_AHB1LPENR_DTCMLPEN (1 << 20) +#define RCC_AHB1LPENR_BKPSRAMLPEN (1 << 18) +#define RCC_AHB1LPENR_SRAM2LPEN (1 << 17) +#define RCC_AHB1LPENR_SRAM1LPEN (1 << 16) +#define RCC_AHB1LPENR_FLITFLPEN (1 << 15) +#define RCC_AHB1LPENR_AXILPEN (1 << 13) +#define RCC_AHB1LPENR_CRCLPEN (1 << 12) +#define RCC_AHB1LPENR_GPIOKLPEN (1 << 10) +#define RCC_AHB1LPENR_GPIOJLPEN (1 << 9) +#define RCC_AHB1LPENR_GPIOILPEN (1 << 8) +#define RCC_AHB1LPENR_GPIOHLPEN (1 << 7) +#define RCC_AHB1LPENR_GPIOGLPEN (1 << 6) +#define RCC_AHB1LPENR_GPIOFLPEN (1 << 5) +#define RCC_AHB1LPENR_GPIOELPEN (1 << 4) +#define RCC_AHB1LPENR_GPIODLPEN (1 << 3) +#define RCC_AHB1LPENR_GPIOCLPEN (1 << 2) +#define RCC_AHB1LPENR_GPIOBLPEN (1 << 1) +#define RCC_AHB1LPENR_GPIOALPEN (1 << 0) + +/* --- RCC_AHB2LPENR values ------------------------------------------------- */ + +#define RCC_AHB2LPENR_OTGFSLPEN (1 << 7) +#define RCC_AHB2LPENR_RNGLPEN (1 << 6) +#define RCC_AHB2LPENR_HASHLPEN (1 << 5) +#define RCC_AHB2LPENR_CRYPLPEN (1 << 4) +#define RCC_AHB2LPENR_DCMILPEN (1 << 0) + +/* --- RCC_AHB3LPENR values ------------------------------------------------- */ + +#define RCC_AHB3LPENR_QSPILPEN (1 << 1) +#define RCC_AHB3LPENR_FMCLPEN (1 << 0) + +/* --- RCC_APB1LPENR values ------------------------------------------------- */ + +#define RCC_APB1LPENR_UART8LPEN (1 << 31) +#define RCC_APB1LPENR_UART7LPEN (1 << 30) +#define RCC_APB1LPENR_DACLPEN (1 << 29) +#define RCC_APB1LPENR_PWRLPEN (1 << 28) +#define RCC_APB1LPENR_CECLPEN (1 << 27) +#define RCC_APB1LPENR_CAN2LPEN (1 << 26) +#define RCC_APB1LPENR_CAN1LPEN (1 << 25) +#define RCC_APB1LPENR_I2C4LPEN (1 << 24) +#define RCC_APB1LPENR_I2C3LPEN (1 << 23) +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) +#define RCC_APB1LPENR_UART5LPEN (1 << 20) +#define RCC_APB1LPENR_UART4LPEN (1 << 19) +#define RCC_APB1LPENR_USART3LPEN (1 << 18) +#define RCC_APB1LPENR_USART2LPEN (1 << 17) +#define RCC_APB1LPENR_SPIDIFRXLPEN (1 << 16) +#define RCC_APB1LPENR_SPI3LPEN (1 << 15) +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) +#define RCC_APB1LPENR_LPTIM1LPEN (1 << 9) +#define RCC_APB1LPENR_TIM14LPEN (1 << 8) +#define RCC_APB1LPENR_TIM13LPEN (1 << 7) +#define RCC_APB1LPENR_TIM12LPEN (1 << 6) +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) +#define RCC_APB1LPENR_TIM5LPEN (1 << 3) +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) + +/* --- RCC_APB2LPENR values ------------------------------------------------- */ + +#define RCC_APB2LPENR_LTDCLPEN (1 << 26) +#define RCC_APB2LPENR_SAI2LPEN (1 << 23) +#define RCC_APB2LPENR_SAI1LPEN (1 << 22) +#define RCC_APB2LPENR_SPI6LPEN (1 << 21) +#define RCC_APB2LPENR_SPI5LPEN (1 << 20) +#define RCC_APB2LPENR_TIM11LPEN (1 << 18) +#define RCC_APB2LPENR_TIM10LPEN (1 << 17) +#define RCC_APB2LPENR_TIM9LPEN (1 << 16) +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 14) +#define RCC_APB2LPENR_SPI4LPEN (1 << 13) +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) +#define RCC_APB2LPENR_SDMMC1LPEN (1 << 11) +#define RCC_APB2LPENR_ADC3LPEN (1 << 10) +#define RCC_APB2LPENR_ADC2LPEN (1 << 9) +#define RCC_APB2LPENR_ADC1LPEN (1 << 8) +#define RCC_APB2LPENR_USART6LPEN (1 << 5) +#define RCC_APB2LPENR_USART1LPEN (1 << 4) +#define RCC_APB2LPENR_TIM8LPEN (1 << 1) +#define RCC_APB2LPENR_TIM1LPEN (1 << 0) + +/* --- RCC_BDCR values ----------------------------------------------------- */ + +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) +#define RCC_BDCR_RTCSEL_MASK 0x3 +#define RCC_BDCR_RTCSEL_SHIFT 8 +#define RCC_BDCR_RTCSEL_NONE 0 +#define RCC_BDCR_RTCSEL_LSE 1 +#define RCC_BDCR_RTCSEL_LSI 2 +#define RCC_BDCR_RTCSEL_HSE 3 +#define RCC_BDCR_LSEDRV_MASK 0x3 +#define RCC_BDCR_LSEDRV_SHIFT 3 +#define RCC_BDCR_LSEDRV_LOW 0 +#define RCC_BDCR_LSEDRV_MEDH 1 /* good job st */ +#define RCC_BDCR_LSEDRV_MEDL 2 +#define RCC_BDCR_LSEDRV_HIGH 3 +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_BORRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\ + RCC_CSR_PINRSTF | RCC_CSR_BORRSTF) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- RCC_SSCGR values ---------------------------------------------------- */ + +#define RCC_SSCGR_SSCGEN (1 << 31) +#define RCC_SSCGR_SPREADSEL (1 << 30) +#define RCC_SSCGR_INCSTEP_MASK 0x7fff +#define RCC_SSCGR_INCSTEP_SHIFT 13 +#define RCC_SSCGR_MODPER_MASK 0x1fff +#define RCC_SSCGR_MODPER_SHIFT 0 + +/* --- RCC_PLLI2SCFGR values ----------------------------------------------- */ + +/* RCC_PLLI2SCFGR[30:28]: PLLI2SR */ +#define RCC_PLLI2SCFGR_PLLI2S_MASK 0x7 +#define RCC_PLLI2SCFGR_PLLI2S_SHIFT 28 +#define RCC_PLLI2SCFGR_PLLI2SQ_MASK 0xf +#define RCC_PLLI2SCFGR_PLLI2SQ_SHIFT 24 +#define RCC_PLLI2SCFGR_PLLI2SP_MASK 0x3 +#define RCC_PLLI2SCFGR_PLLI2SP_SHIFT 16 +#define RCC_PLLI2SCFGR_PLLI2SN_MASK 0x1ff +#define RCC_PLLI2SCFGR_PLLI2SN_SHIFT 6 + +/* --- RCC_PLLSAICFGR values ----------------------------------------------- */ + +#define RCC_PLLSAICFGR_PLLSAIR_MASK 0x7 +#define RCC_PLLSAICFGR_PLLSAIR_SHIFT 28 +#define RCC_PLLSAICFGR_PLLSAIQ_MASK 0xf +#define RCC_PLLSAICFGR_PLLSAIQ_SHIFT 24 +#define RCC_PLLSAICFGR_PLLSAIP_MASK 0x3 +#define RCC_PLLSAICFGR_PLLSAIP_SHIFT 16 +#define RCC_PLLSAICFGR_PLLSAIN_MASK 0x1FF +#define RCC_PLLSAICFGR_PLLSAIN_SHIFT 6 + +/* --- RCC_DCKCFGR1 values -------------------------------------------------- */ + +#define RCC_DCKCFGR1_TIMPRE (1<<24) +#define RCC_DCKCFGR1_SAI2SEL_MASK 0x3 +#define RCC_DCKCFGR1_SAI2SEL_SHIFT 22 +#define RCC_DCKCFGR1_SAI1SEL_MASK 0x3 +#define RCC_DCKCFGR1_SAI1SEL_SHIFT 20 +#define RCC_DCKCFGR1_PLLSAIDIVR_MASK 0x3 +#define RCC_DCKCFGR1_PLLSAIDIVR_SHIFT 16 +#define RCC_DCKCFGR1_PLLSAIDIVR_DIVR_2 0 +#define RCC_DCKCFGR1_PLLSAIDIVR_DIVR_4 1 +#define RCC_DCKCFGR1_PLLSAIDIVR_DIVR_8 2 +#define RCC_DCKCFGR1_PLLSAIDIVR_DIVR_16 3 +#define RCC_DCKCFGR1_PLLSAIDIVQ_MASK 0x1f +#define RCC_DCKCFGR1_PLLSAIDIVQ_SHIFT 8 +#define RCC_DCKCFGR1_PLLI2SDIVQ_MASK 0x1f +#define RCC_DCKCFGR1_PLLI2SDIVQ_SHIFT 0 + +/* --- RCC_DCKCFGR2 values -------------------------------------------------- */ + +#define RCC_DCKCFGR2_SDMMCSEL (1<<28) +#define RCC_DCKCFGR2_CK48MSEL (1<<27) +#define RCC_DCKCFGR2_CECSEL (1<<26) +#define RCC_DCKCFGR2_LPTIM1SEL_MASK 0x3 +#define RCC_DCKCFGR2_LPTIM1SEL_SHIFT 24 +#define RCC_DCKCFGR2_I2C4SEL_MASK 0x3 +#define RCC_DCKCFGR2_I2C4SEL_SHIFT 22 +#define RCC_DCKCFGR2_I2C3SEL_MASK 0x3 +#define RCC_DCKCFGR2_I2C3SEL_SHIFT 20 +#define RCC_DCKCFGR2_I2C2SEL_MASK 0x3 +#define RCC_DCKCFGR2_I2C2SEL_SHIFT 18 +#define RCC_DCKCFGR2_I2C1SEL_MASK 0x3 +#define RCC_DCKCFGR2_I2C1SEL_SHIFT 16 +#define RCC_DCKCFGR2_UART8SEL_MASK 0x3 +#define RCC_DCKCFGR2_UART8SEL_SHIFT 14 +#define RCC_DCKCFGR2_UART7SEL_MASK 0x3 +#define RCC_DCKCFGR2_UART7SEL_SHIFT 12 +#define RCC_DCKCFGR2_USART6SEL_MASK 0x3 +#define RCC_DCKCFGR2_USART6SEL_SHIFT 10 +#define RCC_DCKCFGR2_UART5SEL_MASK 0x3 +#define RCC_DCKCFGR2_UART5SEL_SHIFT 8 +#define RCC_DCKCFGR2_UART4SEL_MASK 0x3 +#define RCC_DCKCFGR2_UART4SEL_SHIFT 6 +#define RCC_DCKCFGR2_UART3SEL_MASK 0x3 +#define RCC_DCKCFGR2_UART3SEL_SHIFT 4 +#define RCC_DCKCFGR2_UART2SEL_MASK 0x3 +#define RCC_DCKCFGR2_UART2SEL_SHIFT 2 +#define RCC_DCKCFGR2_UART1SEL_MASK 0x3 +#define RCC_DCKCFGR2_UART1SEL_SHIFT 0 + +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +enum rcc_clock_3v3 { + RCC_CLOCK_3V3_216MHZ, + RCC_CLOCK_3V3_END +}; + +struct rcc_clock_scale { + uint8_t pllm; + uint16_t plln; + uint8_t pllp; + uint8_t pllq; + uint32_t flash_config; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + enum pwr_vos_scale vos_scale; + uint8_t overdrive; + uint32_t apb1_frequency; + uint32_t apb2_frequency; +}; + +extern const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END]; + +enum rcc_osc { + RCC_PLL, + RCC_HSE, + RCC_HSI, + RCC_LSE, + RCC_LSI +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + /* AHB1 peripherals*/ + RCC_GPIOA = _REG_BIT(0x30, 0), + RCC_GPIOB = _REG_BIT(0x30, 1), + RCC_GPIOC = _REG_BIT(0x30, 2), + RCC_GPIOD = _REG_BIT(0x30, 3), + RCC_GPIOE = _REG_BIT(0x30, 4), + RCC_GPIOF = _REG_BIT(0x30, 5), + RCC_GPIOG = _REG_BIT(0x30, 6), + RCC_GPIOH = _REG_BIT(0x30, 7), + RCC_GPIOI = _REG_BIT(0x30, 8), + RCC_GPIOJ = _REG_BIT(0x30, 9), + RCC_GPIOK = _REG_BIT(0x30, 10), + RCC_CRC = _REG_BIT(0x30, 12), + RCC_BKPSRAM = _REG_BIT(0x30, 18), + RCC_DTCMRAM = _REG_BIT(0x30, 20), + RCC_DMA1 = _REG_BIT(0x30, 21), + RCC_DMA2 = _REG_BIT(0x30, 22), + RCC_DMA2D = _REG_BIT(0x30, 23), + RCC_ETHMAC = _REG_BIT(0x30, 25), + RCC_ETHMACTX = _REG_BIT(0x30, 26), + RCC_ETHMACRX = _REG_BIT(0x30, 27), + RCC_ETHMACPTP = _REG_BIT(0x30, 28), + RCC_OTGHS = _REG_BIT(0x30, 29), + RCC_OTGHSULPI = _REG_BIT(0x30, 30), + + /* AHB2 peripherals */ + RCC_DCMI = _REG_BIT(0x34, 0), + RCC_CRYP = _REG_BIT(0x34, 4), + RCC_HASH = _REG_BIT(0x34, 5), + RCC_RNG = _REG_BIT(0x34, 6), + RCC_OTGFS = _REG_BIT(0x34, 7), + + /* AHB3 peripherals */ + RCC_QSPI = _REG_BIT(0x38, 1), + RCC_FMC = _REG_BIT(0x38, 0), + + /* APB1 peripherals*/ + RCC_TIM2 = _REG_BIT(0x40, 0), + RCC_TIM3 = _REG_BIT(0x40, 1), + RCC_TIM4 = _REG_BIT(0x40, 2), + RCC_TIM5 = _REG_BIT(0x40, 3), + RCC_TIM6 = _REG_BIT(0x40, 4), + RCC_TIM7 = _REG_BIT(0x40, 5), + RCC_TIM12 = _REG_BIT(0x40, 6), + RCC_TIM13 = _REG_BIT(0x40, 7), + RCC_TIM14 = _REG_BIT(0x40, 8), + RCC_LPTIM1 = _REG_BIT(0x40, 9), + RCC_WWDG = _REG_BIT(0x40, 11), + RCC_SPI2 = _REG_BIT(0x40, 14), + RCC_SPI3 = _REG_BIT(0x40, 15), + RCC_SPDIFRX = _REG_BIT(0x40, 16), + RCC_USART2 = _REG_BIT(0x40, 17), + RCC_USART3 = _REG_BIT(0x40, 18), + RCC_UART4 = _REG_BIT(0x40, 19), + RCC_UART5 = _REG_BIT(0x40, 20), + RCC_I2C1 = _REG_BIT(0x40, 21), + RCC_I2C2 = _REG_BIT(0x40, 22), + RCC_I2C3 = _REG_BIT(0x40, 23), + RCC_I2C4 = _REG_BIT(0x40, 24), + RCC_CAN1 = _REG_BIT(0x40, 25), + RCC_CAN2 = _REG_BIT(0x40, 26), + RCC_CEC = _REG_BIT(0x40, 27), + RCC_PWR = _REG_BIT(0x40, 28), + RCC_DAC = _REG_BIT(0x40, 29), + RCC_SPI7 = _REG_BIT(0x40, 30), + RCC_SPI8 = _REG_BIT(0x40, 31), + + /* APB2 peripherals */ + RCC_TIM1 = _REG_BIT(0x44, 0), + RCC_TIM8 = _REG_BIT(0x44, 1), + RCC_USART1 = _REG_BIT(0x44, 4), + RCC_USART6 = _REG_BIT(0x44, 5), + RCC_ADC1 = _REG_BIT(0x44, 8), + RCC_ADC2 = _REG_BIT(0x44, 9), + RCC_ADC3 = _REG_BIT(0x44, 10), + RCC_SDMMC1 = _REG_BIT(0x44, 11), + RCC_SPI1 = _REG_BIT(0x44, 12), + RCC_SPI4 = _REG_BIT(0x44, 13), + RCC_SYSCFG = _REG_BIT(0x44, 14), + RCC_TIM9 = _REG_BIT(0x44, 16), + RCC_TIM10 = _REG_BIT(0x44, 17), + RCC_TIM11 = _REG_BIT(0x44, 18), + RCC_SPI5 = _REG_BIT(0x44, 20), + RCC_SPI6 = _REG_BIT(0x44, 21), + RCC_SAI1EN = _REG_BIT(0x44, 22), + RCC_SAI2EN = _REG_BIT(0x44, 23), + RCC_LTDC = _REG_BIT(0x44, 26), + + + /* BDCR */ + RCC_RTC = _REG_BIT(0x70, 15), + + /* AHB1 peripherals*/ + SCC_GPIOA = _REG_BIT(0x50, 0), + SCC_GPIOB = _REG_BIT(0x50, 1), + SCC_GPIOC = _REG_BIT(0x50, 2), + SCC_GPIOD = _REG_BIT(0x50, 3), + SCC_GPIOE = _REG_BIT(0x50, 4), + SCC_GPIOF = _REG_BIT(0x50, 5), + SCC_GPIOG = _REG_BIT(0x50, 6), + SCC_GPIOH = _REG_BIT(0x50, 7), + SCC_GPIOI = _REG_BIT(0x50, 8), + SCC_GPIOJ = _REG_BIT(0x50, 9), + SCC_GPIOK = _REG_BIT(0x50, 10), + SCC_CRC = _REG_BIT(0x50, 12), + SCC_AXI = _REG_BIT(0x50, 13), + SCC_FLTIF = _REG_BIT(0x50, 15), + SCC_SRAM1 = _REG_BIT(0x50, 16), + SCC_SRAM2 = _REG_BIT(0x50, 17), + SCC_BKPSRAM = _REG_BIT(0x50, 18), + SCC_DTCM = _REG_BIT(0x50, 20), + SCC_DMA1 = _REG_BIT(0x50, 21), + SCC_DMA2 = _REG_BIT(0x50, 22), + SCC_DMA2D = _REG_BIT(0x50, 23), + SCC_ETHMAC = _REG_BIT(0x50, 25), + SCC_ETHMACTX = _REG_BIT(0x50, 26), + SCC_ETHMACRX = _REG_BIT(0x50, 27), + SCC_ETHMACPTP = _REG_BIT(0x50, 28), + SCC_OTGHS = _REG_BIT(0x50, 29), + SCC_OTGHSULPI = _REG_BIT(0x50, 30), + + /* AHB2 peripherals */ + SCC_DCMI = _REG_BIT(0x54, 0), + SCC_CRYP = _REG_BIT(0x54, 4), + SCC_HASH = _REG_BIT(0x54, 5), + SCC_RNG = _REG_BIT(0x54, 6), + SCC_OTGFS = _REG_BIT(0x54, 7), + + /* AHB3 peripherals */ + SCC_QSPI = _REG_BIT(0x58, 1), + SCC_FMC = _REG_BIT(0x58, 0), + + /* APB1 peripherals*/ + SCC_TIM2 = _REG_BIT(0x60, 0), + SCC_TIM3 = _REG_BIT(0x60, 1), + SCC_TIM4 = _REG_BIT(0x60, 2), + SCC_TIM5 = _REG_BIT(0x60, 3), + SCC_TIM6 = _REG_BIT(0x60, 4), + SCC_TIM7 = _REG_BIT(0x60, 5), + SCC_TIM12 = _REG_BIT(0x60, 6), + SCC_TIM13 = _REG_BIT(0x60, 7), + SCC_TIM14 = _REG_BIT(0x60, 8), + SCC_LPTIM1 = _REG_BIT(0x60, 9), + SCC_WWDG = _REG_BIT(0x60, 11), + SCC_SPI2 = _REG_BIT(0x60, 14), + SCC_SPI3 = _REG_BIT(0x60, 15), + SCC_SPDIFRX = _REG_BIT(0x60, 16), + SCC_USART2 = _REG_BIT(0x60, 17), + SCC_USART3 = _REG_BIT(0x60, 18), + SCC_UART4 = _REG_BIT(0x60, 19), + SCC_UART5 = _REG_BIT(0x60, 20), + SCC_I2C1 = _REG_BIT(0x60, 21), + SCC_I2C2 = _REG_BIT(0x60, 22), + SCC_I2C3 = _REG_BIT(0x60, 23), + SCC_I2C4 = _REG_BIT(0x60, 24), + SCC_CAN1 = _REG_BIT(0x60, 25), + SCC_CAN2 = _REG_BIT(0x60, 26), + SCC_CEC = _REG_BIT(0x60, 27), + SCC_PWR = _REG_BIT(0x60, 28), + SCC_DAC = _REG_BIT(0x60, 29), + SCC_UART7 = _REG_BIT(0x60, 30), + SCC_UART8 = _REG_BIT(0x60, 31), + + /* APB2 peripherals */ + SCC_TIM1 = _REG_BIT(0x64, 0), + SCC_TIM8 = _REG_BIT(0x64, 1), + SCC_USART1 = _REG_BIT(0x64, 4), + SCC_USART6 = _REG_BIT(0x64, 5), + SCC_ADC1 = _REG_BIT(0x64, 8), + SCC_ADC2 = _REG_BIT(0x64, 9), + SCC_ADC3 = _REG_BIT(0x64, 10), + SCC_SDMMC1 = _REG_BIT(0x64, 11), + SCC_SPI1 = _REG_BIT(0x64, 12), + SCC_SPI4 = _REG_BIT(0x64, 13), + SCC_SYSCFG = _REG_BIT(0x64, 14), + SCC_TIM9 = _REG_BIT(0x64, 16), + SCC_TIM10 = _REG_BIT(0x64, 17), + SCC_TIM11 = _REG_BIT(0x64, 18), + SCC_SPI5 = _REG_BIT(0x64, 20), + SCC_SPI6 = _REG_BIT(0x64, 21), + SCC_SAI1 = _REG_BIT(0x64, 22), + SCC_SAI2 = _REG_BIT(0x64, 23), + SCC_LTDC = _REG_BIT(0x64, 26), +}; + +enum rcc_periph_rst { + /* AHB1 peripherals*/ + RST_GPIOA = _REG_BIT(0x10, 0), + RST_GPIOB = _REG_BIT(0x10, 1), + RST_GPIOC = _REG_BIT(0x10, 2), + RST_GPIOD = _REG_BIT(0x10, 3), + RST_GPIOE = _REG_BIT(0x10, 4), + RST_GPIOF = _REG_BIT(0x10, 5), + RST_GPIOG = _REG_BIT(0x10, 6), + RST_GPIOH = _REG_BIT(0x10, 7), + RST_GPIOI = _REG_BIT(0x10, 8), + RST_GPIOJ = _REG_BIT(0x10, 9), + RST_GPIOK = _REG_BIT(0x10, 10), + RST_CRC = _REG_BIT(0x10, 12), + RST_DMA1 = _REG_BIT(0x10, 21), + RST_DMA2 = _REG_BIT(0x10, 22), + RST_DMA2D = _REG_BIT(0x10, 23), + RST_ETHMAC = _REG_BIT(0x10, 25), + RST_OTGHS = _REG_BIT(0x10, 29), + + /* AHB2 peripherals */ + RST_DCMI = _REG_BIT(0x14, 0), + RST_CRYP = _REG_BIT(0x14, 4), + RST_HASH = _REG_BIT(0x14, 5), + RST_RNG = _REG_BIT(0x14, 6), + RST_OTGFS = _REG_BIT(0x14, 7), + + /* AHB3 peripherals */ + RST_QSPI = _REG_BIT(0x18, 1), + RST_FMC = _REG_BIT(0x18, 0), + + /* APB1 peripherals*/ + RST_TIM2 = _REG_BIT(0x20, 0), + RST_TIM3 = _REG_BIT(0x20, 1), + RST_TIM4 = _REG_BIT(0x20, 2), + RST_TIM5 = _REG_BIT(0x20, 3), + RST_TIM6 = _REG_BIT(0x20, 4), + RST_TIM7 = _REG_BIT(0x20, 5), + RST_TIM12 = _REG_BIT(0x20, 6), + RST_TIM13 = _REG_BIT(0x20, 7), + RST_TIM14 = _REG_BIT(0x20, 8), + RST_LPTIM1 = _REG_BIT(0x20, 9), + RST_WWDG = _REG_BIT(0x20, 11), + RST_SPI2 = _REG_BIT(0x20, 14), + RST_SPI3 = _REG_BIT(0x20, 15), + RST_SPDIFRX = _REG_BIT(0x20, 16), + RST_UART2 = _REG_BIT(0x20, 17), + RST_UART3 = _REG_BIT(0x20, 18), + RST_UART4 = _REG_BIT(0x20, 19), + RST_UART5 = _REG_BIT(0x20, 20), + RST_I2C1 = _REG_BIT(0x20, 21), + RST_I2C2 = _REG_BIT(0x20, 22), + RST_I2C3 = _REG_BIT(0x20, 23), + RST_I2C4 = _REG_BIT(0x20, 24), + RST_CAN1 = _REG_BIT(0x20, 25), + RST_CAN2 = _REG_BIT(0x20, 26), + RST_CEC = _REG_BIT(0x20, 27), + RST_PWR = _REG_BIT(0x20, 28), + RST_DAC = _REG_BIT(0x20, 29), + RST_UART7 = _REG_BIT(0x20, 30), + RST_UART8 = _REG_BIT(0x20, 31), + + /* APB2 peripherals */ + RST_TIM1 = _REG_BIT(0x24, 0), + RST_TIM8 = _REG_BIT(0x24, 1), + RST_USART1 = _REG_BIT(0x24, 4), + RST_USART6 = _REG_BIT(0x24, 5), + RST_ADC = _REG_BIT(0x24, 8), + RST_SDMMC1 = _REG_BIT(0x24, 11), + RST_SPI1 = _REG_BIT(0x24, 12), + RST_SPI4 = _REG_BIT(0x24, 13), + RST_SYSCFG = _REG_BIT(0x24, 14), + RST_TIM9 = _REG_BIT(0x24, 16), + RST_TIM10 = _REG_BIT(0x24, 17), + RST_TIM11 = _REG_BIT(0x24, 18), + RST_SPI5 = _REG_BIT(0x24, 20), + RST_SPI6 = _REG_BIT(0x24, 21), + RST_SAI1RST = _REG_BIT(0x24, 22), + RST_SAI2RST = _REG_BIT(0x24, 23), + RST_LTDC = _REG_BIT(0x24, 26), +}; + +#undef _REG_BIT + +#include + +BEGIN_DECLS +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_sysclk_status(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_rtcpre(uint32_t rtcpre); +void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq); +void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq); +uint32_t rcc_system_clock_source(void); +void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock); +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rng.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rng.h new file mode 100644 index 00000000..09d014d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/f7/rng.h @@ -0,0 +1,23 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RNG_H +#define LIBOPENCM3_RNG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/flash.h new file mode 100644 index 00000000..c95ca361 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/flash.h @@ -0,0 +1,44 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32F7) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/fsmc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/fsmc.h new file mode 100644 index 00000000..2d8ed6a7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/fsmc.h @@ -0,0 +1,308 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FSMC_H +#define LIBOPENCM3_FSMC_H + +#include +#include + +#if defined(STM32F4) +# include +#endif + +/* --- Convenience macros -------------------------------------------------- */ + +#define FSMC_BANK1_BASE 0x60000000U /* NOR / PSRAM */ +#define FSMC_BANK2_BASE 0x70000000U /* NAND flash */ +#define FSMC_BANK3_BASE 0x80000000U /* NAND flash */ +#define FSMC_BANK4_BASE 0x90000000U /* PC card */ + +/* --- FSMC registers ------------------------------------------------------ */ + +/* SRAM/NOR-Flash chip-select control registers 1..4 (FSMC_BCRx) */ +#define FSMC_BCR(x) MMIO32(FSMC_BASE + 0x00 + 8 * (x)) +#define FSMC_BCR1 FSMC_BCR(0) +#define FSMC_BCR2 FSMC_BCR(1) +#define FSMC_BCR3 FSMC_BCR(2) +#define FSMC_BCR4 FSMC_BCR(3) + +/* SRAM/NOR-Flash chip-select timing registers 1..4 (FSMC_BTRx) */ +#define FSMC_BTR(x) MMIO32(FSMC_BASE + 0x04 + 8 * (x)) +#define FSMC_BTR1 FSMC_BTR(0) +#define FSMC_BTR2 FSMC_BTR(1) +#define FSMC_BTR3 FSMC_BTR(2) +#define FSMC_BTR4 FSMC_BTR(3) + +/* SRAM/NOR-Flash write timing registers 1..4 (FSMC_BWTRx) */ +#define FSMC_BWTR(x) MMIO32(FSMC_BASE + 0x104 + 8 * (x)) +#define FSMC_BWTR1 FSMC_BWTR(0) +#define FSMC_BWTR2 FSMC_BWTR(1) +#define FSMC_BWTR3 FSMC_BWTR(2) +#define FSMC_BWTR4 FSMC_BWTR(3) + +/* PC Card/NAND Flash control registers 2..4 (FSMC_PCRx) */ +#define FSMC_PCR(x) MMIO32(FSMC_BASE + 0x40 + 0x20 * (x)) +#define FSMC_PCR2 FSMC_PCR(1) +#define FSMC_PCR3 FSMC_PCR(2) +#define FSMC_PCR4 FSMC_PCR(3) + +/* FIFO status and interrupt registers 2..4 (FSMC_SRx) */ +#define FSMC_SR(x) MMIO32(FSMC_BASE + 0x44 + 0x20 * (x)) +#define FSMC_SR2 FSMC_SR(1) +#define FSMC_SR3 FSMC_SR(2) +#define FSMC_SR4 FSMC_SR(3) + +/* Common memory space timing registers 2..4 (FSMC_PMEMx) */ +#define FSMC_PMEM(x) MMIO32(FSMC_BASE + 0x48 + 0x20 * (x)) +#define FSMC_PMEM2 FSMC_PMEM(1) +#define FSMC_PMEM3 FSMC_PMEM(2) +#define FSMC_PMEM4 FSMC_PMEM(3) + +/* Attribute memory space timing registers 2..4 (FSMC_PATTx) */ +#define FSMC_PATT(x) MMIO32(FSMC_BASE + 0x4c + 0x20 * (x)) +#define FSMC_PATT2 FSMC_PATT(1) +#define FSMC_PATT3 FSMC_PATT(2) +#define FSMC_PATT4 FSMC_PATT(3) + +/* I/O space timing register 4 (FSMC_PIO4) */ +#define FSMC_PIO4 MMIO32(FSMC_BASE + 0xb0) + +/* ECC result registers 2/3 (FSMC_ECCRx) */ +#define FSMC_ECCR(x) MMIO32(FSMC_BASE + 0x54 + 0x20 * (x)) +#define FSMC_ECCR2 FSMC_ECCR(1) +#define FSMC_ECCR3 FSMC_ECCR(2) + +/* --- FSMC_BCRx values ---------------------------------------------------- */ + +/* Bits [31:20]: Reserved. */ + +/* CBURSTRW: Write burst enable */ +#define FSMC_BCR_CBURSTRW (1 << 19) + +/* Bits [18:16]: Reserved. */ + +/* ASYNCWAIT: Wait signal during asynchronous transfers */ +#define FSMC_BCR_ASYNCWAIT (1 << 15) + +/* EXTMOD: Extended mode enable */ +#define FSMC_BCR_EXTMOD (1 << 14) + +/* WAITEN: Wait enable bit */ +#define FSMC_BCR_WAITEN (1 << 13) + +/* WREN: Write enable bit */ +#define FSMC_BCR_WREN (1 << 12) + +/* WAITCFG: Wait timing configuration */ +#define FSMC_BCR_WAITCFG (1 << 11) + +/* WRAPMOD: Wrapped burst mode support */ +#define FSMC_BCR_WRAPMOD (1 << 10) + +/* WAITPOL: Wait signal polarity bit */ +#define FSMC_BCR_WAITPOL (1 << 9) + +/* BURSTEN: Burst enable bit */ +#define FSMC_BCR_BURSTEN (1 << 8) + +/* Bit 7: Reserved. */ + +/* FACCEN: Flash access enable */ +#define FSMC_BCR_FACCEN (1 << 6) + +/* MWID[5:4]: Memory data bus width */ +#define FSMC_BCR_MWID (1 << 4) + +/* MTYP[3:2]: Memory type */ +#define FSMC_BCR_MTYP (1 << 2) + +/* MUXEN: Address/data multiplexing enable bit */ +#define FSMC_BCR_MUXEN (1 << 1) + +/* MBKEN: Memory bank enable bit */ +#define FSMC_BCR_MBKEN (1 << 0) + +/* --- FSMC_BTRx values ---------------------------------------------------- */ + +/* Bits [31:30]: Reserved. */ + +/* Same for read and write */ +#define FSMC_BTx_ACCMOD_A (0) +#define FSMC_BTx_ACCMOD_B (1) +#define FSMC_BTx_ACCMOD_C (2) +#define FSMC_BTx_ACCMOD_D (3) + +/* ACCMOD[29:28]: Access mode */ +#define FSMC_BTR_ACCMOD (1 << 28) +#define FSMC_BTR_ACCMODx(x) (((x) & 0x03) << 28) + +/* DATLAT[27:24]: Data latency (for synchronous burst NOR flash) */ +#define FSMC_BTR_DATLAT (1 << 24) +#define FSMC_BTR_DATLATx(x) (((x) & 0x0f) << 24) + +/* CLKDIV[23:20]: Clock divide ratio (for CLK signal) */ +#define FSMC_BTR_CLKDIV (1 << 20) +#define FSMC_BTR_CLKDIVx(x) (((x) & 0x0f) << 20) + +/* BUSTURN[19:16]: Bus turnaround phase duration */ +#define FSMC_BTR_BUSTURN (1 << 16) +#define FSMC_BTR_BUSTURNx(x) (((x) & 0x0f) << 16) + +/* DATAST[15:8]: Data-phase duration */ +#define FSMC_BTR_DATAST (1 << 8) +#define FSMC_BTR_DATASTx(x) (((x) & 0xff) << 8) + +/* ADDHLD[7:4]: Address-hold phase duration */ +#define FSMC_BTR_ADDHLD (1 << 4) +#define FSMC_BTR_ADDHLDx(x) (((x) & 0x0f) << 4) + +/* ADDSET[3:0]: Address setup phase duration */ +#define FSMC_BTR_ADDSET (1 << 0) +#define FSMC_BTR_ADDSETx(x) (((x) & 0x0f) << 0) + +/* --- FSMC_BWTRx values --------------------------------------------------- */ + +/* Bits [31:30]: Reserved. */ + +/* ACCMOD[29:28]: Access mode */ +#define FSMC_BWTR_ACCMOD (1 << 28) + +/* DATLAT[27:24]: Data latency (for synchronous burst NOR Flash) */ +#define FSMC_BWTR_DATLAT (1 << 24) + +/* CLKDIV[23:20]: Clock divide ratio (for CLK signal) */ +#define FSMC_BWTR_CLKDIV (1 << 20) + +/* Bits [19..16]: Reserved. */ + +/* DATAST[15:8]: Data-phase duration */ +#define FSMC_BWTR_DATAST (1 << 8) + +/* ADDHLD[7:4]: Address-hold phase duration */ +#define FSMC_BWTR_ADDHLD (1 << 4) + +/* ADDSET[3:0]: Address setup phase duration */ +#define FSMC_BWTR_ADDSET (1 << 0) + +/* --- FSMC_PCRx values ---------------------------------------------------- */ + +/* Bits [31:20]: Reserved. */ + +/* ECCPS[19:17]: ECC page size */ +#define FSMC_PCR_ECCPS (1 << 17) + +/* TAR[16:13]: ALE to RE delay */ +#define FSMC_PCR_TAR (1 << 13) + +/* TCLR[12:9]: CLE to RE delay */ +#define FSMC_PCR_TCLR (1 << 9) + +/* Bits [8..7]: Reserved. */ + +/* ECCEN: ECC computation logic enable bit */ +#define FSMC_PCR_ECCEN (1 << 6) + +/* PWID[5:4]: Databus width */ +#define FSMC_PCR_PWID (1 << 4) + +/* PTYP: Memory type */ +#define FSMC_PCR_PTYP (1 << 3) + +/* PBKEN: PC Card/NAND Flash memory bank enable bit */ +#define FSMC_PCR_PBKEN (1 << 2) + +/* PWAITEN: Wait feature enable bit */ +#define FSMC_PCR_PWAITEN (1 << 1) + +/* Bit 0: Reserved. */ + +/* --- FSMC_SRx values ----------------------------------------------------- */ + +/* Bits [31:7]: Reserved. */ + +/* FEMPT: FIFO empty */ +#define FSMC_SR_FEMPT (1 << 6) + +/* IFEN: Interrupt falling edge detection enable bit */ +#define FSMC_SR_IFEN (1 << 5) + +/* ILEN: Interrupt high-level detection enable bit */ +#define FSMC_SR_ILEN (1 << 4) + +/* IREN: Interrupt rising edge detection enable bit */ +#define FSMC_SR_IREN (1 << 3) + +/* IFS: Interrupt falling edge status */ +#define FSMC_SR_IFS (1 << 2) + +/* ILS: Interrupt high-level status */ +#define FSMC_SR_ILS (1 << 1) + +/* IRS: Interrupt rising edge status */ +#define FSMC_SR_IRS (1 << 0) + +/* --- FSMC_PMEMx values --------------------------------------------------- */ + +/* MEMHIZx[31:24]: Common memory x databus HiZ time */ +#define FSMC_PMEM_MEMHIZX (1 << 24) + +/* MEMHOLDx[23:16]: Common memory x hold time */ +#define FSMC_PMEM_MEMHOLDX (1 << 16) + +/* MEMWAITx[15:8]: Common memory x wait time */ +#define FSMC_PMEM_MEMWAITX (1 << 8) + +/* MEMSETx[7:0]: Common memory x setup time */ +#define FSMC_PMEM_MEMSETX (1 << 0) + +/* --- FSMC_PATTx values --------------------------------------------------- */ + +/* ATTHIZx[31:24]: Attribute memory x databus HiZ time */ +#define FSMC_PATT_ATTHIZX (1 << 24) + +/* ATTHOLDx[23:16]: Attribute memory x hold time */ +#define FSMC_PATT_ATTHOLDX (1 << 16) + +/* ATTWAITx[15:8]: Attribute memory x wait time */ +#define FSMC_PATT_ATTWAITX (1 << 8) + +/* ATTSETx[7:0]: Attribute memory x setup time */ +#define FSMC_PATT_ATTSETX (1 << 0) + +/* --- FSMC_PIO4 values ---------------------------------------------------- */ + +/* IOHIZx[31:24]: I/O x databus HiZ time */ +#define FSMC_PIO4_IOHIZX (1 << 24) + +/* IOHOLDx[23:16]: I/O x hold time */ +#define FSMC_PIO4_IOHOLDX (1 << 16) + +/* IOWAITx[15:8]: I/O x wait time */ +#define FSMC_PIO4_IOWAITX (1 << 8) + +/* IOSETx[7:0]: I/O x setup time */ +#define FSMC_PIO4_IOSETX (1 << 0) + +/* --- FSMC_ECCRx values --------------------------------------------------- */ + +/* ECCx[31:0]: ECC result */ +#define FSMC_ECCR_ECCX (1 << 0) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/gpio.h new file mode 100644 index 00000000..d20b8cba --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/gpio.h @@ -0,0 +1,44 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32F7) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/hash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/hash.h new file mode 100644 index 00000000..8f7d19cf --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/hash.h @@ -0,0 +1,30 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F2) +# include +#elif defined(STM32F4) +# include +#else +# error "hash processor is supported only" \ + "in stm32f21, stm32f41 and stm32f43 families." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/i2c.h new file mode 100644 index 00000000..112ece2c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/i2c.h @@ -0,0 +1,44 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32F7) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/iwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/iwdg.h new file mode 100644 index 00000000..4d5fb4c0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/iwdg.h @@ -0,0 +1,38 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/adc.h new file mode 100644 index 00000000..a7b3f1fa --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/adc.h @@ -0,0 +1,76 @@ +/** @defgroup adc_defines ADC Defines + * + * @brief Defined Constants and Types for the STM32L0xx Analog to Digital + * Converter + * + * @ingroup STM32L0xx_defines + * + * @version 1.0.0 + * + * @date 16 Oct 2015 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include +#include + +/** @defgroup adc_reg_base ADC register base addresses + * @ingroup adc_defines + * + *@{*/ +#define ADC1 ADC1_BASE +/**@}*/ + + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_VLCD 16 +#define ADC_CHANNEL_VREF 17 +#define ADC_CHANNEL_TEMP 18 +/**@}*/ + +/* Calibration Factors */ +#define ADC_CALFACT(adc) MMIO32((adc) + 0xB4) + +/* Register values */ +/* ADC_CFGR2 Values ---------------------------------------------------------*/ + +#define ADC_CFGR2_CKMODE_SHIFT 30 +#define ADC_CFGR2_CKMODE (3 << ADC_CFGR2_CKMODE_SHIFT) +#define ADC_CFGR2_CKMODE_CK_ADC (0 << ADC_CFGR2_CKMODE_SHIFT) +#define ADC_CFGR2_CKMODE_PCLK_DIV2 (1 << ADC_CFGR2_CKMODE_SHIFT) +#define ADC_CFGR2_CKMODE_PCLK_DIV4 (2 << ADC_CFGR2_CKMODE_SHIFT) +#define ADC_CFGR2_CKMODE_PCLK (3 << ADC_CFGR2_CKMODE_SHIFT) + + +BEGIN_DECLS + + +END_DECLS + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/doc-stm32l0.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/doc-stm32l0.h new file mode 100644 index 00000000..ad585d3a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/doc-stm32l0.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32L0 + +@version 1.0.0 + +@date 15 November 2014 + +API documentation for ST Microelectronics STM32L0 Cortex M0 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32L0xx STM32L0xx +Libraries for ST Microelectronics STM32L0xx series. + +@version 1.0.0 + +@date 15 November 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32L0xx_defines STM32L0xx Defines + +@brief Defined Constants and Types for the STM32L0xx series + +@version 1.0.0 + +@date 7 September 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/exti.h new file mode 100644 index 00000000..b2af19b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/exti.h @@ -0,0 +1,41 @@ +/** @defgroup exti_defines EXTI Defines + * + * @brief Defined Constants and Types for the STM32L0xx External Interrupts + * + * + * @ingroup STM32L0xx_defines + * + * @author @htmlonly © @endhtmlonly 2015 + * Robin Kreis + * + * @version 1.0.0 + * + * @date 15 July 2015 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Robin Kreis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EXTI_H +#define LIBOPENCM3_EXTI_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/flash.h new file mode 100644 index 00000000..6eaef6e5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/flash.h @@ -0,0 +1,62 @@ +/** @defgroup flash_defines FLASH Defines + * + * @brief Defined Constants and Types for the STM32L0xx Flash memory + * + * @ingroup STM32L0xx_defines + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H +/**@{*/ + +#include + +/* --- FLASH registers ----------------------------------------------------- */ +/* L0 has some alternative names for the same registers */ +#define FLASH_OPTR FLASH_OBR +#define FLASH_WRPROT1 FLASH_WRPR1 +#define FLASH_WRPROT2 FLASH_WRPR2 + +/* --- FLASH_ACR values ---------------------------------------------------- */ +#define FLASH_ACR_PRE_READ (1 << 6) +#define FLASH_ACR_DISAB_BUF (1 << 5) + +/* --- FLASH_PECR values ---------------------------------------------------- */ +#define FLASH_PECR_NZDISABLE (1 << 23) + +/* --- FLASH_SR values ----------------------------------------------------- */ +#define FLASH_SR_RDERR (1 << 13) +#define FLASH_SR_NOTZEROERR (1 << 16) +#define FLASH_SR_FWWERR (1 << 17) + +/* --- FLASH_OPTR values ----------------------------------------------------- */ +#define FLASH_OPTR_NBOOT1 (1 << 31) + +BEGIN_DECLS + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/gpio.h new file mode 100644 index 00000000..a1b48990 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/gpio.h @@ -0,0 +1,75 @@ +/** @defgroup gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the STM32F0xx General Purpose I/O + * + * @ingroup STM32L0xx_defines + * + * @version 1.0.0 + * + * @date 1 July 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define GPIO_BRR(port) MMIO32((port) + 0x28) +#define GPIOA_BRR GPIO_BRR(GPIOA) +#define GPIOB_BRR GPIO_BRR(GPIOB) +#define GPIOC_BRR GPIO_BRR(GPIOC) +#define GPIOD_BRR GPIO_BRR(GPIOD) +#define GPIOH_BRR GPIO_BRR(GPIOH) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/** @defgroup gpio_speed GPIO Output Pin Speed +@ingroup gpio_defines +@{*/ +#define GPIO_OSPEED_LOW 0x0 +#define GPIO_OSPEED_MED 0x1 +#define GPIO_OSPEED_HIGH 0x3 +/**@}*/ + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/i2c.h new file mode 100644 index 00000000..f2bf276d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/i2c.h @@ -0,0 +1,37 @@ +/** @defgroup i2c_defines I2C Defines + +@brief Defined Constants and Types for the STM32L0xx I2C + +@ingroup STM32L0xx_defines + +@version 1.0.0 + +@date 1 December 2016 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/irq.json new file mode 100644 index 00000000..6cf0ebd2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/irq.json @@ -0,0 +1,39 @@ +{ + "irqs": [ + "wwdg", + "pvd", + "rtc", + "flash", + "rcc", + "exti0_1", + "exti2_3", + "exti4_15", + "tsc", + "dma1_channel1", + "dma1_channel2_3", + "dma1_channel4_5", + "adc_comp", + "lptim1", + "reserved1", + "tim2", + "reserved2", + "tim6_dac", + "reserved3", + "reserved4", + "tim21", + "reserved5", + "tim22", + "i2c1", + "i2c2", + "spi1", + "spi2", + "usart1", + "usart2", + "lpuart1", + "lcd", + "usb" + ], + "partname_humanreadable": "STM32 L0 series", + "partname_doxygen": "STM32L0", + "includeguard": "LIBOPENCM3_STM32_L0_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/memorymap.h new file mode 100644 index 00000000..d1466b7d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/memorymap.h @@ -0,0 +1,95 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32 specific peripheral definitions ------------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define IOPORT_BASE (0x50000000U) +#define INFO_BASE (0x1ff80000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB (PERIPH_BASE + 0x20000) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define LCD_BASE (PERIPH_BASE_APB1 + 0x2400) +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define LPUART1_BASE (PERIPH_BASE_APB1 + 0x4800) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define USB_DEV_FS_BASE (PERIPH_BASE_APB1 + 0x5c00) +#define USB_PMA_BASE (PERIPH_BASE_APB1 + 0x6000) +#define CRS_BASE (PERIPH_BASE_APB1 + 0x6C00) +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define LPTIM1_BASE (PERIPH_BASE_APB1 + 0x7c00) + + +/* APB2 */ +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x0000) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x0400) +#define TIM21_BASE (PERIPH_BASE_APB2 + 0x0800) +#define TIM22_BASE (PERIPH_BASE_APB2 + 0x1400) +#define FIREWALL_BASE (PERIPH_BASE_APB2 + 0x1C00) +#define ADC1_BASE (PERIPH_BASE_APB2 + 0x2400) +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +#define USART1_BASE (PERIPH_BASE_APB2 + 0x3800) +#define DBGMCU_BASE (PERIPH_BASE_APB2 + 0x5800) + +/* AHB */ +#define DMA1_BASE (PERIPH_BASE_AHB + 0x00000) +#define RCC_BASE (PERIPH_BASE_AHB + 0x01000) +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB + 0x02000) +#define CRC_BASE (PERIPH_BASE_AHB + 0x03000) +#define TSC_BASE (PERIPH_BASE_AHB + 0x04000) +#define RNG_BASE (PERIPH_BASE_AHB + 0x05000) +#define AES_BASE (PERIPH_BASE_AHB + 0x06000) + +#define GPIO_PORT_A_BASE (IOPORT_BASE + 0x00000) +#define GPIO_PORT_B_BASE (IOPORT_BASE + 0x00400) +#define GPIO_PORT_C_BASE (IOPORT_BASE + 0x00800) +#define GPIO_PORT_D_BASE (IOPORT_BASE + 0x00c00) +#define GPIO_PORT_H_BASE (IOPORT_BASE + 0x01C00) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x7C) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x50) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 0x14) + +/* ST provided factory calibration values @ 3.0V */ +#define ST_VREFINT_CAL MMIO16((INFO_BASE + 0x78)) +#define ST_TSENSE_CAL1_30C MMIO16((INFO_BASE + 0x7A)) +#define ST_TSENSE_CAL2_110C MMIO16((INFO_BASE + 0x7E)) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/pwr.h new file mode 100644 index 00000000..bb2ff9a0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/pwr.h @@ -0,0 +1,37 @@ +/** @defgroup pwr_defines PWR Defines + * + * @brief Defined Constants and Types for the STM32L0xx PWR Control + * + * @ingroup STM32L0xx_defines + * + * @version 1.0.0 + * + * @date 21 May 2015 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rcc.h new file mode 100644 index 00000000..6fb3e3d7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rcc.h @@ -0,0 +1,699 @@ +/** @defgroup rcc_defines RCC Defines + * + * @ingroup STM32L0xx_defines + * + * @brief Defined Constants and Types for the STM32L0xx Reset and Clock + * Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Karl Palsson + * + * @date 17 November 2014 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +/**@{*/ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +#include +#include +#include + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_ICSCR MMIO32(RCC_BASE + 0x04) +#define RCC_CRRCR MMIO32(RCC_BASE + 0x08) +#define RCC_CFGR MMIO32(RCC_BASE + 0x0c) +#define RCC_CIER MMIO32(RCC_BASE + 0x10) +#define RCC_CIFR MMIO32(RCC_BASE + 0x14) +#define RCC_CICR MMIO32(RCC_BASE + 0x18) +#define RCC_IOPRSTR MMIO32(RCC_BASE + 0x1c) +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x20) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x24) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x28) +#define RCC_IOPENR MMIO32(RCC_BASE + 0x2c) +#define RCC_AHBENR MMIO32(RCC_BASE + 0x30) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x34) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x38) +#define RCC_IOPSMEN MMIO32(RCC_BASE + 0x3c) +#define RCC_AHBSMENR MMIO32(RCC_BASE + 0x40) +#define RCC_APB2SMENR MMIO32(RCC_BASE + 0x44) +#define RCC_APB1SMENR MMIO32(RCC_BASE + 0x48) +#define RCC_CCIPR MMIO32(RCC_BASE + 0x4c) +#define RCC_CSR MMIO32(RCC_BASE + 0x50) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_RTCPRE_SHIFT 20 +#define RCC_CR_RTCPRE_MASK 0x3 +#define RCC_CR_RTCPRE_DIV2 0 +#define RCC_CR_RTCPRE_DIV4 1 +#define RCC_CR_RTCPRE_DIV8 2 +#define RCC_CR_RTCPRE_DIV16 3 +#define RCC_CR_CSSHSEON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_MSIRDY (1 << 9) +#define RCC_CR_MSION (1 << 8) +#define RCC_CR_HSI16DIVF (1 << 4) +#define RCC_CR_HSI16DIVEN (1 << 3) +#define RCC_CR_HSI16RDY (1 << 2) +#define RCC_CR_HSI16KERON (1 << 1) +#define RCC_CR_HSI16ON (1 << 0) + + +/* --- RCC_ICSCR values ---------------------------------------------------- */ + +#define RCC_ICSCR_MSITRIM_SHIFT 24 +#define RCC_ICSCR_MSITRIM_MASK 0xff +#define RCC_ICSCR_MSICAL_SHIFT 16 +#define RCC_ICSCR_MSICAL_MASK 0xff + +#define RCC_ICSCR_MSIRANGE_SHIFT 13 +#define RCC_ICSCR_MSIRANGE_MASK 0x7 +#define RCC_ICSCR_MSIRANGE_65KHZ 0x0 +#define RCC_ICSCR_MSIRANGE_131KHZ 0x1 +#define RCC_ICSCR_MSIRANGE_262KHZ 0x2 +#define RCC_ICSCR_MSIRANGE_524KHZ 0x3 +#define RCC_ICSCR_MSIRANGE_1MHZ 0x4 +#define RCC_ICSCR_MSIRANGE_2MHZ 0x5 +#define RCC_ICSCR_MSIRANGE_4MHZ 0x6 + +#define RCC_ICSCR_HSI16TRIM_SHIFT 8 +#define RCC_ICSCR_HSI16TRIM_MASK 0x1f +#define RCC_ICSCR_HSI16CAL_SHIFT 0 +#define RCC_ICSCR_HSI16CAL_MASK 0xff + +/* --- RCC_CRRCR register */ + +#define RCC_CRRCR_HSI48CAL_SHIFT 8 +#define RCC_CRRCR_HSI48CAL_MASK 0xff +#define RCC_CRRCR_HSI48RDY (1<<1) +#define RCC_CRRCR_HSI48ON (1<<0) + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +/* MCOPRE */ +#define RCC_CFGR_MCOPRE_DIV1 0 +#define RCC_CFGR_MCOPRE_DIV2 1 +#define RCC_CFGR_MCOPRE_DIV4 2 +#define RCC_CFGR_MCOPRE_DIV8 3 +#define RCC_CFGR_MCOPRE_DIV16 4 + +/* MCO: Microcontroller clock output */ +#define RCC_CFGR_MCO_NOCLK 0x0 +#define RCC_CFGR_MCO_SYSCLK 0x1 +#define RCC_CFGR_MCO_HSI16 0x2 +#define RCC_CFGR_MCO_MSI 0x3 +#define RCC_CFGR_MCO_HSE 0x4 +#define RCC_CFGR_MCO_PLL 0x5 +#define RCC_CFGR_MCO_LSI 0x6 +#define RCC_CFGR_MCO_LSE 0x7 +#define RCC_CFGR_MCO_HSI48 0x8 +#define RCC_CFGR_MCO_SHIFT 24 +#define RCC_CFGR_MCO_MASK 0xf + +/* PLL Output division selection */ +#define RCC_CFGR_PLLDIV_DIV2 0x1 +#define RCC_CFGR_PLLDIV_DIV3 0x2 +#define RCC_CFGR_PLLDIV_DIV4 0x3 +#define RCC_CFGR_PLLDIV_SHIFT 22 +#define RCC_CFGR_PLLDIV_MASK 0x3 + +/* PLLMUL: PLL multiplication factor */ +#define RCC_CFGR_PLLMUL_MUL3 0x0 +#define RCC_CFGR_PLLMUL_MUL4 0x1 +#define RCC_CFGR_PLLMUL_MUL6 0x2 +#define RCC_CFGR_PLLMUL_MUL8 0x3 +#define RCC_CFGR_PLLMUL_MUL12 0x4 +#define RCC_CFGR_PLLMUL_MUL16 0x5 +#define RCC_CFGR_PLLMUL_MUL24 0x6 +#define RCC_CFGR_PLLMUL_MUL32 0x7 +#define RCC_CFGR_PLLMUL_MUL48 0x8 +#define RCC_CFGR_PLLMUL_SHIFT 18 +#define RCC_CFGR_PLLMUL_MASK 0xf + +/* PLLSRC: PLL entry clock source */ +#define RCC_CFGR_PLLSRC_HSI16_CLK 0x0 +#define RCC_CFGR_PLLSRC_HSE_CLK 0x1 + +/* Wakeup from stop clock selection */ +#define RCC_CFGR_STOPWUCK_MSI (0<<15) +#define RCC_CFGR_STOPWUCK_HSI16 (1<<15) + +/* PPRE2: APB high-speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_NODIV 0x0 +#define RCC_CFGR_PPRE2_DIV2 0x4 +#define RCC_CFGR_PPRE2_DIV4 0x5 +#define RCC_CFGR_PPRE2_DIV8 0x6 +#define RCC_CFGR_PPRE2_DIV16 0x7 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE2_SHIFT 11 + +/* PPRE1: APB low-speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_NODIV 0x0 +#define RCC_CFGR_PPRE1_DIV2 0x4 +#define RCC_CFGR_PPRE1_DIV4 0x5 +#define RCC_CFGR_PPRE1_DIV8 0x6 +#define RCC_CFGR_PPRE1_DIV16 0x7 +#define RCC_CFGR_PPRE1_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 8 + +/* HPRE: AHB prescaler */ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 0x8 +#define RCC_CFGR_HPRE_DIV4 0x9 +#define RCC_CFGR_HPRE_DIV8 0xa +#define RCC_CFGR_HPRE_DIV16 0xb +#define RCC_CFGR_HPRE_DIV64 0xc +#define RCC_CFGR_HPRE_DIV128 0xd +#define RCC_CFGR_HPRE_DIV256 0xe +#define RCC_CFGR_HPRE_DIV512 0xf +#define RCC_CFGR_HPRE_MASK 0xf +#define RCC_CFGR_HPRE_SHIFT 4 + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_MSI 0x0 +#define RCC_CFGR_SWS_HSI16 0x1 +#define RCC_CFGR_SWS_HSE 0x2 +#define RCC_CFGR_SWS_PLL 0x3 +#define RCC_CFGR_SWS_MASK 0x3 +#define RCC_CFGR_SWS_SHIFT 2 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_MSI 0x0 +#define RCC_CFGR_SW_HSI16 0x1 +#define RCC_CFGR_SW_HSE 0x2 +#define RCC_CFGR_SW_PLL 0x3 +#define RCC_CFGR_SW_MASK 0x3 +#define RCC_CFGR_SW_SHIFT 0 + +/* --- RCC_CIER - Clock interrupt enable register */ + +#define RCC_CIER_CSSLSE (1 << 7) +/* OSC ready interrupt enable bits */ +#define RCC_CIER_HSI48RDYIE (1 << 6) +#define RCC_CIER_MSIRDYIE (1 << 5) +#define RCC_CIER_PLLRDYIE (1 << 4) +#define RCC_CIER_HSERDYIE (1 << 3) +#define RCC_CIER_HSI16RDYIE (1 << 2) +#define RCC_CIER_LSERDYIE (1 << 1) +#define RCC_CIER_LSIRDYIE (1 << 0) + +/* --- RCC_CIFR - Clock interrupt flag register */ + +#define RCC_CIFR_CSSHSEF (1 << 8) +#define RCC_CIFR_CSSLSEF (1 << 7) +#define RCC_CIFR_HSI48RDYF (1 << 6) +#define RCC_CIFR_MSIRDYF (1 << 5) +#define RCC_CIFR_PLLRDYF (1 << 4) +#define RCC_CIFR_HSERDYF (1 << 3) +#define RCC_CIFR_HSI16RDYF (1 << 2) +#define RCC_CIFR_LSERDYF (1 << 1) +#define RCC_CIFR_LSIRDYF (1 << 0) + +/* --- RCC_CICR - Clock interrupt clear register */ + +#define RCC_CICR_CSSHSEC (1 << 8) +#define RCC_CICR_CSSLSEC (1 << 7) +#define RCC_CICR_HSI48RDYC (1 << 6) +#define RCC_CICR_MSIRDYC (1 << 5) +#define RCC_CICR_PLLRDYC (1 << 4) +#define RCC_CICR_HSERDYC (1 << 3) +#define RCC_CICR_HSI16RDYC (1 << 2) +#define RCC_CICR_LSERDYC (1 << 1) +#define RCC_CICR_LSIRDYC (1 << 0) + +/* --- RCC_IOPRSTR - GPIO Reset Register */ + +#define RCC_IOPPRSTR_IOPHRST (1<<7) +#define RCC_IOPPRSTR_IOPERST (1<<4) +#define RCC_IOPPRSTR_IOPDRST (1<<3) +#define RCC_IOPPRSTR_IOPCRST (1<<2) +#define RCC_IOPPRSTR_IOPBRST (1<<1) +#define RCC_IOPPRSTR_IOPARST (1<<0) + +/* --- RCC_AHBRSTR values ------------------------------------------------- */ + +#define RCC_AHBRSTR_CRYPRST (1 << 24) +#define RCC_AHBRSTR_RNGRST (1 << 20) +#define RCC_AHBRSTR_TSCRST (1 << 16) +#define RCC_AHBRSTR_CRCRST (1 << 12) +#define RCC_AHBRSTR_MIFRST (1 << 8) +#define RCC_AHBRSTR_DMARST (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_DBGRST (1 << 22) +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_ADC1RST (1 << 9) +#define RCC_APB2RSTR_TIM22RST (1 << 5) +#define RCC_APB2RSTR_TIM21RST (1 << 2) +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_LPTIM1RST (1 << 31) +#define RCC_APB1RSTR_I2C3RST (1 << 30) +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_CRSRST (1 << 27) +#define RCC_APB1RSTR_USBRST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_USART5RST (1 << 20) +#define RCC_APB1RSTR_USART4RST (1 << 19) +#define RCC_APB1RSTR_LPUART1RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_LCDRST (1 << 9) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_IOPENR - GPIO clock enable register */ + +#define RCC_IOPENR_IOPHEN (1<<7) +#define RCC_IOPENR_IOPEEN (1<<4) +#define RCC_IOPENR_IOPDEN (1<<3) +#define RCC_IOPENR_IOPCEN (1<<2) +#define RCC_IOPENR_IOPBEN (1<<1) +#define RCC_IOPENR_IOPAEN (1<<0) + +/* --- RCC_AHBENR values --------------------------------------------------- */ + +/** @defgroup rcc_ahbenr_en RCC_AHBENR enable values +@ingroup STM32L0xx_rcc_defines + +@{*/ +#define RCC_AHBENR_CRYPEN (1 << 24) +#define RCC_AHBENR_RNGEN (1 << 20) +#define RCC_AHBENR_TSCEN (1 << 16) +#define RCC_AHBENR_CRCEN (1 << 12) +#define RCC_AHBENR_MIFEN (1 << 8) +#define RCC_AHBENR_DMAEN (1 << 0) +/*@}*/ + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values +@ingroup STM32L0xx_rcc_defines + +@{*/ +#define RCC_APB2ENR_DBGEN (1 << 22) +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_ADC1EN (1 << 9) +#define RCC_APB2ENR_MIFEN (1 << 7) +#define RCC_APB2ENR_TIM22EN (1 << 5) +#define RCC_APB2ENR_TIM21EN (1 << 2) +#define RCC_APB2ENR_SYSCFGEN (1 << 0) +/*@}*/ + +/* --- RCC_APB1ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values +@ingroup STM32L0xx_rcc_defines + +@{*/ +#define RCC_APB1ENR_LPTIM1EN (1 << 31) +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_CRSEN (1 << 27) +#define RCC_APB1ENR_USBEN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_USART5EN (1 << 20) +#define RCC_APB1ENR_USART4EN (1 << 19) +#define RCC_APB1ENR_LPUART1EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_LCDEN (1 << 9) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) +/*@}*/ + +/* --- RCC_IOPSMENR - GPIO Clock enable in sleep mode */ + +#define RCC_IOPSMENR_IOPHSMEN (1<<7) +#define RCC_IOPSMENR_IOPESMEN (1<<4) +#define RCC_IOPSMENR_IOPDSMEN (1<<3) +#define RCC_IOPSMENR_IOPCSMEN (1<<2) +#define RCC_IOPSMENR_IOPBSMEN (1<<1) +#define RCC_IOPSMENR_IOPASMEN (1<<0) + +/* --- RCC_AHBSMENR - AHB periph clock in sleep mode */ + +#define RCC_AHBSMENR_CRYPSMEN (1 << 24) +#define RCC_AHBSMENR_RNGSMEN (1 << 20) +#define RCC_AHBSMENR_TSCSMEN (1 << 16) +#define RCC_AHBSMENR_CRCSMEN (1 << 12) +#define RCC_AHBSMENR_MIFSMEN (1 << 8) +#define RCC_AHBSMENR_DMASMEN (1 << 0) + +/* --- RCC_APB2SMENR - APB2 periph clock in sleep mode */ + +#define RCC_APB2SMENR_DBGSMEN (1 << 22) +#define RCC_APB2SMENR_USART1SMEN (1 << 14) +#define RCC_APB2SMENR_SPI1SMEN (1 << 12) +#define RCC_APB2SMENR_ADC1SMEN (1 << 9) +#define RCC_APB2SMENR_MIFSMEN (1 << 7) +#define RCC_APB2SMENR_TIM22SMEN (1 << 5) +#define RCC_APB2SMENR_TIM21SMEN (1 << 2) +#define RCC_APB2SMENR_SYSCFGSMEN (1 << 0) + +/* --- RCC_APB1SMENR - APB1 periph clock in sleep mode */ + +#define RCC_APB1SMENR_LPTIM1SMEN (1 << 31) +#define RCC_APB1SMENR_I2C3SMEN (1 << 30) +#define RCC_APB1SMENR_DACSMEN (1 << 29) +#define RCC_APB1SMENR_PWRSMEN (1 << 28) +#define RCC_APB1SMENR_CRSSMEN (1 << 27) +#define RCC_APB1SMENR_USBSMEN (1 << 23) +#define RCC_APB1SMENR_I2C2SMEN (1 << 22) +#define RCC_APB1SMENR_I2C1SMEN (1 << 21) +#define RCC_APB1SMENR_USART5SMEN (1 << 20) +#define RCC_APB1SMENR_USART4SMEN (1 << 19) +#define RCC_APB1SMENR_LPUART1SMEN (1 << 18) +#define RCC_APB1SMENR_USART2SMEN (1 << 17) +#define RCC_APB1SMENR_SPI2SMEN (1 << 14) +#define RCC_APB1SMENR_WWDGSMEN (1 << 11) +#define RCC_APB1SMENR_LCDSMEN (1 << 9) +#define RCC_APB1SMENR_TIM7SMEN (1 << 5) +#define RCC_APB1SMENR_TIM6SMEN (1 << 4) +#define RCC_APB1SMENR_TIM3SMEN (1 << 1) +#define RCC_APB1SMENR_TIM2SMEN (1 << 0) + +/* --- RCC_CCIPR - Clock config register */ + +#define RCC_CCIPR_HSI48SEL (1<<26) + +#define RCC_CCIPR_LPTIM1SEL_APB 0 +#define RCC_CCIPR_LPTIM1SEL_LSI 1 +#define RCC_CCIPR_LPTIM1SEL_HSI16 2 +#define RCC_CCIPR_LPTIM1SEL_LSE 3 +#define RCC_CCIPR_LPTIM1SEL_SHIFT 18 +#define RCC_CCIPR_LPTIM1SEL_MASK 0x3 + +#define RCC_CCIPR_I2C3SEL_APB 0 +#define RCC_CCIPR_I2C3SEL_SYS 1 +#define RCC_CCIPR_I2C3SEL_HSI16 2 +#define RCC_CCIPR_I2C3SEL_SHIFT 16 +#define RCC_CCIPR_I2C3SEL_MASK 0x3 + +#define RCC_CCIPR_I2C1SEL_APB 0 +#define RCC_CCIPR_I2C1SEL_SYS 1 +#define RCC_CCIPR_I2C1SEL_HSI16 2 +#define RCC_CCIPR_I2C1SEL_SHIFT 12 +#define RCC_CCIPR_I2C1SEL_MASK 0x3 + +#define RCC_CCIPR_LPUART1SEL_APB 0 +#define RCC_CCIPR_LPUART1SEL_SYS 1 +#define RCC_CCIPR_LPUART1SEL_HSI16 2 +#define RCC_CCIPR_LPUART1SEL_LSE 3 +#define RCC_CCIPR_LPUART1SEL_SHIFT 10 +#define RCC_CCIPR_LPUART1SEL_MASK 0x3 + +#define RCC_CCIPR_USART2SEL_APB 0 +#define RCC_CCIPR_USART2SEL_SYS 1 +#define RCC_CCIPR_USART2SEL_HSI16 2 +#define RCC_CCIPR_USART2SEL_LSE 3 +#define RCC_CCIPR_USART2SEL_SHIFT 2 +#define RCC_CCIPR_USART2SEL_MASK 0x3 + +#define RCC_CCIPR_USART1SEL_APB 0 +#define RCC_CCIPR_USART1SEL_SYS 1 +#define RCC_CCIPR_USART1SEL_HSI16 2 +#define RCC_CCIPR_USART1SEL_LSE 3 +#define RCC_CCIPR_USART1SEL_SHIFT 0 +#define RCC_CCIPR_USART1SEL_MASK 0x3 + +/* --- RCC_CSRT - Control/Status register */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_OBLRSTF (1 << 25) +#define RCC_CSR_FWRSTF (1 << 24) +#define RCC_CSR_RMVF (1 << 23) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\ + RCC_CSR_PINRSTF | RCC_CSR_OBLRSTF | RCC_CSR_FWRSTF) +#define RCC_CSR_RTCRST (1 << 19) +#define RCC_CSR_RTCEN (1 << 18) +#define RCC_CSR_RTCSEL_SHIFT (16) +#define RCC_CSR_RTCSEL_MASK (0x3) +#define RCC_CSR_RTCSEL_NONE (0x0) +#define RCC_CSR_RTCSEL_LSE (0x1) +#define RCC_CSR_RTCSEL_LSI (0x2) +#define RCC_CSR_RTCSEL_HSE (0x3) +#define RCC_CSR_CSSLSED (1 << 14) +#define RCC_CSR_CSSLSEON (1 << 13) +#define RCC_CSR_LSEDRV_SHIFT 11 +#define RCC_CSR_LSEDRV_MASK 0x3 +#define RCC_CSR_LSEDRV_LOWEST 0 +#define RCC_CSR_LSEDRV_MLOW 1 +#define RCC_CSR_LSEDRV_MHIGH 2 +#define RCC_CSR_LSEDRV_HIGHEST 3 +#define RCC_CSR_LSEBYP (1 << 10) +#define RCC_CSR_LSERDY (1 << 9) +#define RCC_CSR_LSEON (1 << 8) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +struct rcc_clock_scale { + uint8_t pll_mul; + uint16_t pll_div; + uint8_t pll_source; + uint8_t flash_waitstates; + enum pwr_vos_scale voltage_scale; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + // FIXME enum pwr_vos_scale voltage_scale; + uint32_t ahb_frequency; + uint32_t apb1_frequency; + uint32_t apb2_frequency; + uint8_t msi_range; +}; + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_osc { + RCC_PLL, RCC_HSE, RCC_HSI48, RCC_HSI16, RCC_MSI, RCC_LSE, RCC_LSI +}; + + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + /* GPIO peripherals */ + RCC_GPIOA = _REG_BIT(0x2c, 0), + RCC_GPIOB = _REG_BIT(0x2c, 1), + RCC_GPIOC = _REG_BIT(0x2c, 2), + RCC_GPIOD = _REG_BIT(0x2c, 3), + RCC_GPIOE = _REG_BIT(0x2c, 4), + RCC_GPIOH = _REG_BIT(0x2c, 7), + + /* AHB peripherals */ + RCC_DMA = _REG_BIT(0x30, 0), + RCC_MIF = _REG_BIT(0x30, 8), + RCC_CRC = _REG_BIT(0x30, 12), + RCC_TSC = _REG_BIT(0x30, 16), + RCC_RNG = _REG_BIT(0x30, 20), + RCC_CRYPT = _REG_BIT(0x30, 24), + + /* APB2 peripherals */ + RCC_SYSCFG = _REG_BIT(0x34, 0), + RCC_TIM21 = _REG_BIT(0x34, 2), + RCC_TIM22 = _REG_BIT(0x34, 5), + RCC_FW = _REG_BIT(0x34, 7), + RCC_ADC1 = _REG_BIT(0x34, 9), + RCC_SPI1 = _REG_BIT(0x34, 12), + RCC_USART1 = _REG_BIT(0x34, 14), + RCC_DBG = _REG_BIT(0x34, 22), + + /* APB1 peripherals */ + RCC_TIM2 = _REG_BIT(0x38, 0), + RCC_TIM3 = _REG_BIT(0x38, 1), + RCC_TIM6 = _REG_BIT(0x38, 4), + RCC_TIM7 = _REG_BIT(0x38, 5), + RCC_LCD = _REG_BIT(0x38, 9), + RCC_WWDG = _REG_BIT(0x38, 11), + RCC_SPI2 = _REG_BIT(0x38, 14), + RCC_USART2 = _REG_BIT(0x38, 17), + RCC_LPUART1 = _REG_BIT(0x38, 18), + RCC_USART4 = _REG_BIT(0x38, 19), + RCC_USART5 = _REG_BIT(0x38, 20), + RCC_I2C1 = _REG_BIT(0x38, 21), + RCC_I2C2 = _REG_BIT(0x38, 22), + RCC_USB = _REG_BIT(0x38, 23), + RCC_CRS = _REG_BIT(0x38, 27), + RCC_PWR = _REG_BIT(0x38, 28), + RCC_DAC = _REG_BIT(0x38, 29), + RCC_I2C3 = _REG_BIT(0x38, 30), + RCC_LPTIM1 = _REG_BIT(0x38, 31), + + /* GPIO peripherals in sleep mode */ + SCC_GPIOA = _REG_BIT(0x3c, 0), + SCC_GPIOB = _REG_BIT(0x3c, 1), + SCC_GPIOC = _REG_BIT(0x3c, 2), + SCC_GPIOD = _REG_BIT(0x3c, 3), + SCC_GPIOE = _REG_BIT(0x3c, 4), + SCC_GPIOH = _REG_BIT(0x3c, 7), + + /* AHB peripherals in sleep mode */ + SCC_DMA = _REG_BIT(0x40, 0), + SCC_MIF = _REG_BIT(0x40, 8), + SCC_SRAM = _REG_BIT(0x40, 12), + SCC_CRC = _REG_BIT(0x40, 12), + SCC_TSC = _REG_BIT(0x40, 16), + SCC_RNG = _REG_BIT(0x40, 20), + SCC_CRYPT = _REG_BIT(0x40, 24), + + /* APB2 peripherals in sleep mode */ + SCC_SYSCFG = _REG_BIT(0x44, 0), + SCC_TIM21 = _REG_BIT(0x44, 2), + SCC_TIM22 = _REG_BIT(0x44, 5), + SCC_ADC1 = _REG_BIT(0x44, 9), + SCC_SPI1 = _REG_BIT(0x44, 12), + SCC_USART1 = _REG_BIT(0x44, 14), + SCC_DBG = _REG_BIT(0x44, 22), + + /* APB1 peripherals in sleep mode */ + SCC_TIM2 = _REG_BIT(0x48, 0), + SCC_TIM3 = _REG_BIT(0x48, 1), + SCC_TIM6 = _REG_BIT(0x48, 4), + SCC_TIM7 = _REG_BIT(0x48, 5), + SCC_LCD = _REG_BIT(0x48, 9), + SCC_WWDG = _REG_BIT(0x48, 11), + SCC_SPI2 = _REG_BIT(0x48, 14), + SCC_USART2 = _REG_BIT(0x48, 17), + SCC_LPUART1 = _REG_BIT(0x48, 18), + SCC_USART4 = _REG_BIT(0x48, 19), + SCC_USART5 = _REG_BIT(0x48, 20), + SCC_I2C1 = _REG_BIT(0x48, 21), + SCC_I2C2 = _REG_BIT(0x48, 22), + SCC_USB = _REG_BIT(0x48, 23), + SCC_CRS = _REG_BIT(0x48, 27), + SCC_PWR = _REG_BIT(0x48, 28), + SCC_DAC = _REG_BIT(0x48, 29), + SCC_I2C3 = _REG_BIT(0x48, 30), + SCC_LPTIM1 = _REG_BIT(0x48, 31), +}; + +enum rcc_periph_rst { + /* GPIO peripherals */ + RST_GPIOA = _REG_BIT(0x1c, 0), + RST_GPIOB = _REG_BIT(0x1c, 1), + RST_GPIOC = _REG_BIT(0x1c, 2), + RST_GPIOD = _REG_BIT(0x1c, 3), + RST_GPIOE = _REG_BIT(0x1c, 4), + RST_GPIOH = _REG_BIT(0x1c, 7), + + /* AHB peripherals */ + RST_DMA = _REG_BIT(0x20, 0), + RST_MIF = _REG_BIT(0x20, 8), + RST_CRC = _REG_BIT(0x20, 12), + RST_TSC = _REG_BIT(0x20, 16), + RST_RNG = _REG_BIT(0x20, 20), + RST_CRYPT = _REG_BIT(0x20, 24), + + /* APB2 peripherals */ + RST_SYSCFG = _REG_BIT(0x24, 0), + RST_TIM21 = _REG_BIT(0x24, 2), + RST_TIM22 = _REG_BIT(0x24, 5), + RST_ADC1 = _REG_BIT(0x24, 9), + RST_SPI1 = _REG_BIT(0x24, 12), + RST_USART1 = _REG_BIT(0x24, 14), + RST_DBG = _REG_BIT(0x24, 22), + + /* APB1 peripherals*/ + RST_TIM2 = _REG_BIT(0x28, 0), + RST_TIM3 = _REG_BIT(0x28, 1), + RST_TIM6 = _REG_BIT(0x28, 4), + RST_TIM7 = _REG_BIT(0x28, 5), + RST_LCD = _REG_BIT(0x28, 9), + RST_WWDG = _REG_BIT(0x28, 11), + RST_SPI2 = _REG_BIT(0x28, 14), + RST_USART2 = _REG_BIT(0x28, 17), + RST_LPUART1 = _REG_BIT(0x28, 18), + RST_USART4 = _REG_BIT(0x28, 19), + RST_USART5 = _REG_BIT(0x28, 20), + RST_I2C1 = _REG_BIT(0x28, 21), + RST_I2C2 = _REG_BIT(0x28, 22), + RST_USB = _REG_BIT(0x28, 23), + RST_CRS = _REG_BIT(0x28, 27), + RST_PWR = _REG_BIT(0x28, 28), + RST_DAC = _REG_BIT(0x28, 29), + RST_I2C3 = _REG_BIT(0x28, 30), + RST_LPTIM1 = _REG_BIT(0x28, 31), +}; +#include + +BEGIN_DECLS + +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_set_hsi48_source_rc48(void); +void rcc_set_hsi48_source_pll(void); +void rcc_set_sysclk_source(enum rcc_osc osc); +void rcc_set_pll_multiplier(uint32_t factor); +void rcc_set_pll_divider(uint32_t factor); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rng.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rng.h new file mode 100644 index 00000000..09d014d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/rng.h @@ -0,0 +1,23 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RNG_H +#define LIBOPENCM3_RNG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/st_usbfs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/st_usbfs.h new file mode 100644 index 00000000..7b65d2b8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/st_usbfs.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +# error Do not include directly ! +#else + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/syscfg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/syscfg.h new file mode 100644 index 00000000..1ae0a947 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/syscfg.h @@ -0,0 +1,134 @@ +/** @defgroup syscfg_defines SYSCFG Defines + * + * @brief Defined Constants and Types for the STM32L0xx System Config + * + * @ingroup STM32L0xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2015 + * Robin Kreis + * + * @date 1 May 2015 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Robin Kreis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SYSCFG_H +#define LIBOPENCM3_SYSCFG_H +/**@{*/ + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define SYSCFG_CFGR1 MMIO32(SYSCFG_BASE + 0x00) +#define SYSCFG_CFGR2 MMIO32(SYSCFG_BASE + 0x04) +#define SYSCFG_EXTICR(i) MMIO32(SYSCFG_BASE + 0x08 + (i)*4) +#define SYSCFG_EXTICR1 SYSCFG_EXTICR(0) +#define SYSCFG_EXTICR2 SYSCFG_EXTICR(1) +#define SYSCFG_EXTICR3 SYSCFG_EXTICR(2) +#define SYSCFG_EXTICR4 SYSCFG_EXTICR(3) +#define COMP1_CTRL MMIO32(SYSCFG_BASE + 0x18) +#define COMP2_CTRL MMIO32(SYSCFG_BASE + 0x1C) +#define SYSCFG_CFGR3 MMIO32(SYSCFG_BASE + 0x20) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* SYSCFG_CFGR1 Values -- ---------------------------------------------------*/ + +#define SYSCFG_CFGR1_MEM_MODE_SHIFT 0 +#define SYSCFG_CFGR1_MEM_MODE (3 << SYSCFG_CFGR1_MEM_MODE_SHIFT) +#define SYSCFG_CFGR1_MEM_MODE_FLASH (0 << SYSCFG_CFGR1_MEM_MODE_SHIFT) +#define SYSCFG_CFGR1_MEM_MODE_SYSTEM (1 << SYSCFG_CFGR1_MEM_MODE_SHIFT) +#define SYSCFG_CFGR1_MEM_MODE_SRAM (3 << SYSCFG_CFGR1_MEM_MODE_SHIFT) + +#define SYSCFG_CFGR1_UFB (1<<3) + +#define SYSCFG_CFGR1_BOOT_MODE_SHIFT 8 +#define SYSCFG_CFGR1_BOOT_MODE (3 << SYSCFG_CFGR1_BOOT_MODE_SHIFT) +#define SYSCFG_CFGR1_BOOT_MODE_FLASH (0 << SYSCFG_CFGR1_BOOT_MODE_SHIFT) +#define SYSCFG_CFGR1_BOOT_MODE_SYSTEM (1 << SYSCFG_CFGR1_BOOT_MODE_SHIFT) +#define SYSCFG_CFGR1_BOOT_MODE_SRAM (3 << SYSCFG_CFGR1_BOOT_MODE_SHIFT) + +/* SYSCFG_CFGR2 Values -- ---------------------------------------------------*/ + +#define SYSCFG_CFGR2_FWDIS (1 << 0) + +#define SYSCFG_CFGR2_I2C_PB6_FMP (1 << 8) +#define SYSCFG_CFGR2_I2C_PB7_FMP (1 << 9) +#define SYSCFG_CFGR2_I2C_PB8_FMP (1 << 10) +#define SYSCFG_CFGR2_I2C_PB9_FMP (1 << 11) + +#define SYSCFG_CFGR2_I2C1_FMP (1 << 12) +#define SYSCFG_CFGR2_I2C2_FMP (1 << 13) +#define SYSCFG_CFGR2_I2C3_FMP (1 << 14) + +/* REF_CFGR3 Values -- ---------------------------------------------------*/ + +#define SYSCFG_CFGR3_EN_VREFINT (1 << 0) + +#define SYSCFG_CFGR3_SEL_VREF_OUT_SHIFT 4 +#define SYSCFG_CFGR3_SEL_VREF_OUT (3 << SYSCFG_CFGR3_EN_VREFINT_SHIFT) +#define SYSCFG_CFGR3_SEL_VREF_OUT_PB0 (1 << SYSCFG_CFGR3_EN_VREFINT_SHIFT) +#define SYSCFG_CFGR3_SEL_VREF_OUT_PB1 (2 << SYSCFG_CFGR3_EN_VREFINT_SHIFT) + +#define SYSCFG_CFGR3_ENBUF_VREFINT_ADC (1 << 8) +#define SYSCFG_CFGR3_ENBUF_SENSOR_ADC (1 << 9) +#define SYSCFG_CFGR3_ENBUF_VREFINT_COMP (1 << 12) +#define SYSCFG_CFGR3_ENREF_HSI48 (1 << 13) + +#define SYSCFG_CFGR3_REF_HSI48_RDYF (1 << 26) +#define SYSCFG_CFGR3_SENSOR_ADC_RDYF (1 << 27) +#define SYSCFG_CFGR3_VREFINT_ADC_RDYF (1 << 28) +#define SYSCFG_CFGR3_VREFINT_COMP_RDYF (1 << 29) +#define SYSCFG_CFGR3_VREFINT_RDYF (1 << 30) +#define SYSCFG_CFGR3_REF_LOCK (1 << 31) + +/* SYSCFG_EXTICR Values -- --------------------------------------------------*/ + +#define SYSCFG_EXTICR_GPIOA 0 +#define SYSCFG_EXTICR_GPIOB 1 +#define SYSCFG_EXTICR_GPIOC 2 +#define SYSCFG_EXTICR_GPIOD 3 +#define SYSCFG_EXTICR_GPIOE 4 +#define SYSCFG_EXTICR_GPIOH 5 + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/timer.h new file mode 100644 index 00000000..c2ed35a8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l0/timer.h @@ -0,0 +1,211 @@ +/** @defgroup timer_defines Timer Defines + +@brief libopencm3 Defined Constants and Types for the STM32L0xx Timers + +@ingroup STM32L0xx_defines + +@version 1.0.0 + +@date 17 May 2015 + +@author @htmlonly © @endhtmlonly 2015 Robin Kreis + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Robin Kreis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +/* Timer 2/21/22 option register (TIMx_OR) */ + +#define TIM_OR(tim_base) MMIO32((tim_base) + 0x50) +#define TIM2_OR TIM_OR(TIM2) +#define TIM21_OR TIM_OR(TIM21) +#define TIM22_OR TIM_OR(TIM22) + +#define TIM2_OR_ETR_RMP_SHIFT 0 +#define TIM2_OR_ETR_RMP (7 << TIM2_OR_ETR_RMP_SHIFT) +#define TIM2_OR_ETR_RMP_GPIO (0 << TIM2_OR_ETR_RMP_SHIFT) +#define TIM2_OR_ETR_RMP_HSI48 (4 << TIM2_OR_ETR_RMP_SHIFT) +#define TIM2_OR_ETR_RMP_LSE (5 << TIM2_OR_ETR_RMP_SHIFT) +#define TIM2_OR_ETR_RMP_COMP2_OUT (6 << TIM2_OR_ETR_RMP_SHIFT) +#define TIM2_OR_ETR_RMP_COMP1_OUT (7 << TIM2_OR_ETR_RMP_SHIFT) + +#define TIM2_OR_TI4_RMP_SHIFT 3 +#define TIM2_OR_TI4_RMP (3 << TIM2_OR_TI4_RMP_SHIFT) +#define TIM2_OR_TI4_RMP_GPIO (0 << TIM2_OR_TI4_RMP_GPIO) +#define TIM2_OR_TI4_RMP_COMP2_OUT (1 << TIM2_OR_TI4_RMP_GPIO) +#define TIM2_OR_TI4_RMP_COMP1_OUT (2 << TIM2_OR_TI4_RMP_GPIO) + +#define TIM21_OR_ETR_RMP_SHIFT 0 +#define TIM21_OR_ETR_RMP (3 << TIM21_OR_ETR_RMP_SHIFT) +#define TIM21_OR_ETR_RMP_GPIO (0 << TIM21_OR_ETR_RMP_SHIFT) +#define TIM21_OR_ETR_RMP_COMP2_OUT (1 << TIM21_OR_ETR_RMP_SHIFT) +#define TIM21_OR_ETR_RMP_COMP1_OUT (2 << TIM21_OR_ETR_RMP_SHIFT) +#define TIM21_OR_ETR_RMP_LSE (3 << TIM21_OR_ETR_RMP_SHIFT) + +#define TIM21_OR_TI1_RMP_SHIFT 2 +#define TIM21_OR_TI1_RMP (7 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_GPIO (0 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_RTC_WAKEUP (1 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_HSE_RTC (2 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_MSI (3 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_LSE (4 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_LSI (5 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_COMP1_OUT (6 << TIM21_OR_TI1_RMP_SHIFT) +#define TIM21_OR_TI1_RMP_MCO (7 << TIM21_OR_TI1_RMP_SHIFT) + +#define TIM21_OR_TI2_RMP_SHIFT 5 +#define TIM21_OR_TI2_RMP (1 << TIM21_OR_TI2_RMP_SHIFT) +#define TIM21_OR_TI2_RMP_GPIO (0 << TIM21_OR_TI2_RMP_SHIFT) +#define TIM21_OR_TI2_RMP_COMP2_OUT (1 << TIM21_OR_TI2_RMP_SHIFT) + +#define TIM22_OR_ETR_RMP_SHIFT 0 +#define TIM22_OR_ETR_RMP (3 << TIM22_OR_ETR_RMP_SHIFT) +#define TIM22_OR_ETR_GPIO (0 << TIM22_OR_ETR_RMP_SHIFT) +#define TIM22_OR_ETR_COMP2_OUT (1 << TIM22_OR_ETR_RMP_SHIFT) +#define TIM22_OR_ETR_COMP1_OUT (2 << TIM22_OR_ETR_RMP_SHIFT) +#define TIM22_OR_ETR_LSE (3 << TIM22_OR_ETR_RMP_SHIFT) + +#define TIM22_OR_TI1_RMP_SHIFT 2 +#define TIM22_OR_TI1_RMP (3 << TIM22_OR_TI1_RMP_SHIFT) +#define TIM22_OR_TI1_RMP_GPIO (0 << TIM22_OR_TI1_RMP_SHIFT) +#define TIM22_OR_TI1_RMP_COMP2_OUT (1 << TIM22_OR_TI1_RMP_SHIFT) +#define TIM22_OR_TI1_RMP_COMP1_OUT (2 << TIM22_OR_TI1_RMP_SHIFT) + +/* --- LPTIM (low power timer) ------------------------------------------- */ + +#define LPTIM_ISR(tim_base) MMIO32((tim_base) + 0x00) +#define LPTIM_ICR(tim_base) MMIO32((tim_base) + 0x04) +#define LPTIM_IER(tim_base) MMIO32((tim_base) + 0x08) +#define LPTIM_CFGR(tim_base) MMIO32((tim_base) + 0x0C) +#define LPTIM_CR(tim_base) MMIO32((tim_base) + 0x10) +#define LPTIM_CMP(tim_base) MMIO32((tim_base) + 0x14) +#define LPTIM_ARR(tim_base) MMIO32((tim_base) + 0x18) +#define LPTIM_CNT(tim_base) MMIO32((tim_base) + 0x1C) + +#define LPTIM1_ISR LPTIM_ISR(LPTIM1_BASE) +#define LPTIM1_ICR LPTIM_ICR(LPTIM1_BASE) +#define LPTIM1_IER LPTIM_IER(LPTIM1_BASE) +#define LPTIM1_CFGR LPTIM_CFGR(LPTIM1_BASE) +#define LPTIM1_CR LPTIM_CR(LPTIM1_BASE) +#define LPTIM1_CMP LPTIM_CMP(LPTIM1_BASE) +#define LPTIM1_ARR LPTIM_ARR(LPTIM1_BASE) +#define LPTIM1_CNT LPTIM_CNT(LPTIM1_BASE) + +#define LPTIM_ISR_CMPM (1 << 0) +#define LPTIM_ISR_ARRM (1 << 1) +#define LPTIM_ISR_EXTTRIG (1 << 2) +#define LPTIM_ISR_CMPOK (1 << 3) +#define LPTIM_ISR_ARROK (1 << 4) +#define LPTIM_ISR_UP (1 << 5) +#define LPTIM_ISR_DOWN (1 << 6) + +#define LPTIM_ICR_CMPMCF (1 << 0) +#define LPTIM_ICR_ARRMCF (1 << 1) +#define LPTIM_ICR_EXTTRIGCF (1 << 2) +#define LPTIM_ICR_CMPOKCF (1 << 3) +#define LPTIM_ICR_ARROKCF (1 << 4) +#define LPTIM_ICR_UPCF (1 << 5) +#define LPTIM_ICR_DOWNCF (1 << 6) + +#define LPTIM_IER_CMPMIE (1 << 0) +#define LPTIM_IER_ARRMIE (1 << 1) +#define LPTIM_IER_EXTTRIGIE (1 << 2) +#define LPTIM_IER_CMPOKIE (1 << 3) +#define LPTIM_IER_ARROKIE (1 << 4) +#define LPTIM_IER_UPIE (1 << 5) +#define LPTIM_IER_DOWNIE (1 << 6) + +#define LPTIM_CFGR_CKSEL (1 << 0) + +#define LPTIM_CFGR_CKPOL_SHIFT 1 +#define LPTIM_CFGR_CKPOL (3 << LPTIM_CFGR_CKPOL_SHIFT) +#define LPTIM_CFGR_CKPOL_RISING (0 << LPTIM_CFGR_CKPOL_SHIFT) +#define LPTIM_CFGR_CKPOL_FALLING (1 << LPTIM_CFGR_CKPOL_SHIFT) +#define LPTIM_CFGR_CKPOL_BOTH (2 << LPTIM_CFGR_CKPOL_SHIFT) +#define LPTIM_CFGR_CKPOL_ENC_1 (0 << LPTIM_CFGR_CKPOL_SHIFT) +#define LPTIM_CFGR_CKPOL_ENC_2 (1 << LPTIM_CFGR_CKPOL_SHIFT) +#define LPTIM_CFGR_CKPOL_ENC_3 (2 << LPTIM_CFGR_CKPOL_SHIFT) + +#define LPTIM_CFGR_CKFLT_SHIFT 3 +#define LPTIM_CFGR_CKFLT (3 << LPTIM_CFGR_CKFLT_SHIFT) +#define LPTIM_CFGR_CKFLT_2 (1 << LPTIM_CFGR_CKFLT_SHIFT) +#define LPTIM_CFGR_CKFLT_4 (2 << LPTIM_CFGR_CKFLT_SHIFT) +#define LPTIM_CFGR_CKFLT_8 (3 << LPTIM_CFGR_CKFLT_SHIFT) + +#define LPTIM_CFGR_TRGFLT_SHIFT 6 +#define LPTIM_CFGR_TRGFLT (3 << LPTIM_CFGR_TRGFLT_SHIFT) +#define LPTIM_CFGR_TRGFLT_2 (1 << LPTIM_CFGR_TRGFLT_SHIFT) +#define LPTIM_CFGR_TRGFLT_4 (2 << LPTIM_CFGR_TRGFLT_SHIFT) +#define LPTIM_CFGR_TRGFLT_8 (3 << LPTIM_CFGR_TRGFLT_SHIFT) + +#define LPTIM_CFGR_PRESC_SHIFT 9 +#define LPTIM_CFGR_PRESC (7 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_1 (0 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_2 (1 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_4 (2 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_8 (3 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_16 (4 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_32 (5 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_64 (6 << LPTIM_CFGR_PRESC_SHIFT) +#define LPTIM_CFGR_PRESC_128 (7 << LPTIM_CFGR_PRESC_SHIFT) + +#define LPTIM_CFGR_TRIGSEL_SHIFT 13 +#define LPTIM_CFGR_TRIGSEL (7 << LPTIM_CFGR_TRIGSEL_SHIFT) +#define LPTIM_CFGR_TRIGSEL_EXT_TRIG0 (0 << LPTIM_CFGR_TRIGSEL_SHIFT) +#define LPTIM_CFGR_TRIGSEL_EXT_TRIG1 (1 << LPTIM_CFGR_TRIGSEL_SHIFT) +#define LPTIM_CFGR_TRIGSEL_EXT_TRIG2 (2 << LPTIM_CFGR_TRIGSEL_SHIFT) +#define LPTIM_CFGR_TRIGSEL_EXT_TRIG3 (3 << LPTIM_CFGR_TRIGSEL_SHIFT) +#define LPTIM_CFGR_TRIGSEL_EXT_TRIG4 (4 << LPTIM_CFGR_TRIGSEL_SHIFT) +/* 5 is reserved */ +#define LPTIM_CFGR_TRIGSEL_EXT_TRIG6 (6 << LPTIM_CFGR_TRIGSEL_SHIFT) +#define LPTIM_CFGR_TRIGSEL_EXT_TRIG7 (7 << LPTIM_CFGR_TRIGSEL_SHIFT) + +#define LPTIM_CFGR_TRIGEN_SHIFT 17 +#define LPTIM_CFGR_TRIGEN (3 << LPTIM_CFGR_TRIGEN_SHIFT) +#define LPTIM_CFGR_TRIGEN_SW (0 << LPTIM_CFGR_TRIGEN_SHIFT) +#define LPTIM_CFGR_TRIGEN_RISING (1 << LPTIM_CFGR_TRIGEN_SHIFT) +#define LPTIM_CFGR_TRIGEN_FALLING (2 << LPTIM_CFGR_TRIGEN_SHIFT) +#define LPTIM_CFGR_TRIGEN_BOTH (3 << LPTIM_CFGR_TRIGEN_SHIFT) + +#define LPTIM_CFGR_TIMOUT (1 << 19) + +#define LPTIM_CFGR_WAVE (1 << 20) + +#define LPTIM_CFGR_WAVPOL (1 << 21) + +#define LPTIM_CFGR_PRELOAD (1 << 22) + +#define LPTIM_CFGR_COUNTMODE (1 << 23) + +#define LPTIM_CFGR_ENC (1 << 24) + +#define LPTIM_CR_ENABLE (1 << 0) + +#define LPTIM_CR_SNGSTRT (1 << 1) + +#define LPTIM_CR_CNTSTRT (1 << 2) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/adc.h new file mode 100644 index 00000000..5c2bf31c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/adc.h @@ -0,0 +1,230 @@ +/** @defgroup adc_defines ADC Defines + +@brief Defined Constants and Types for the STM32L1xx Analog to +Digital Converters + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2013 Karl Palsson + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include + +#define ADC_MAX_REGULAR_SEQUENCE 28 +/* 26 in L/M, but 32 in two banks for M+/H density */ +#define ADC_MAX_CHANNELS 32 + +/* ADC sample time register 3 (ADC_SMPR3) */ +#define ADC_SMPR3(block) MMIO32((block) + 0x14) +#define ADC1_SMPR3 ADC_SMPR3(ADC1) + +/* ADC injected channel data offset register x (ADC_JOFRx) (x=1..4) */ +#define ADC_JOFR1(block) MMIO32((block) + 0x18) +#define ADC_JOFR2(block) MMIO32((block) + 0x1c) +#define ADC_JOFR3(block) MMIO32((block) + 0x20) +#define ADC_JOFR4(block) MMIO32((block) + 0x24) + +/* ADC watchdog high threshold register (ADC_HTR) */ +#define ADC_HTR(block) MMIO32((block) + 0x28) + +/* ADC watchdog low threshold register (ADC_LTR) */ +#define ADC_LTR(block) MMIO32((block) + 0x2c) + +/* ADC regular sequence register 1 (ADC_SQR1) */ +#define ADC_SQR1(block) MMIO32((block) + 0x30) + +/* ADC regular sequence register 2 (ADC_SQR2) */ +#define ADC_SQR2(block) MMIO32((block) + 0x34) + +/* ADC regular sequence register 3 (ADC_SQR3) */ +#define ADC_SQR3(block) MMIO32((block) + 0x38) + +/* ADC regular sequence register 4 (ADC_SQR4) */ +#define ADC_SQR4(block) MMIO32((block) + 0x3c) +#define ADC1_SQR4 ADC_SQR4(ADC1) + +/* ADC regular sequence register 5 (ADC_SQR5) */ +#define ADC_SQR5(block) MMIO32((block) + 0x40) +#define ADC1_SQR5 ADC_SQR5(ADC1) + +/* ADC injected sequence register (ADC_JSQR) */ +#define ADC_JSQR(block) MMIO32((block) + 0x44) + +/* ADC injected data register x (ADC_JDRx) (x=1..4) */ +#define ADC_JDR1(block) MMIO32((block) + 0x48) +#define ADC_JDR2(block) MMIO32((block) + 0x4c) +#define ADC_JDR3(block) MMIO32((block) + 0x50) +#define ADC_JDR4(block) MMIO32((block) + 0x54) + +/* ADC regular data register (ADC_DR) */ +#define ADC_DR(block) MMIO32((block) + 0x58) + +/* ADC sample time register 0 (ADC_SMPR0) (high/med+ only) */ +#define ADC_SMPR0(block) MMIO32((block) + 0x5c) +#define ADC1_SMPR0 ADC_SMPR0(ADC1) + +#define ADC_CSR MMIO32(ADC1 + 0x300) +#define ADC_CCR MMIO32(ADC1 + 0x304) + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_TEMP ADC_CHANNEL16 +#define ADC_CHANNEL_VREF ADC_CHANNEL17 +#define ADC_CHANNEL_VBAT ADC_CHANNEL18 +/**@}*/ + +/* --- ADC_SR values ------------------------------------------------------- */ +#define ADC_SR_JCNR (1 << 9) +#define ADC_SR_RCNR (1 << 8) +#define ADC_SR_ADONS (1 << 6) +#define ADC_SR_OVR (1 << 5) + +/* --- ADC_CR1 values ------------------------------------------------------- */ +#define ADC_CR1_OVRIE (1 << 28) +/****************************************************************************/ +/** @defgroup adc_cr1_res ADC Resolution. +@ingroup adc_defines +@{*/ +#define ADC_CR1_RES_12_BIT 0 +#define ADC_CR1_RES_10_BIT 1 +#define ADC_CR1_RES_8_BIT 2 +#define ADC_CR1_RES_6_BIT 3 +/**@}*/ +#define ADC_CR1_RES_MASK (0x3) +#define ADC_CR1_RES_SHIFT 24 +#define ADC_CR1_PDI (1 << 17) +#define ADC_CR1_PDD (1 << 16) + +#define ADC_CR1_AWDCH_MAX 26 + +/* --- ADC_CR2 values ------------------------------------------------------- */ +/* SWSTART: */ /** Start conversion of regular channels. */ +#define ADC_CR2_SWSTART (1 << 30) + +/* EXTEN[1:0]: External trigger enable for regular channels. */ +/****************************************************************************/ +#define ADC_CR2_EXTEN_SHIFT 28 +#define ADC_CR2_EXTEN_MASK (0x3 << ADC_CR2_EXTEN_SHIFT) +/** @defgroup adc_trigger_polarity_regular ADC Trigger Polarity +@ingroup adc_defines +@{*/ +#define ADC_CR2_EXTEN_DISABLED (0x0 << ADC_CR2_EXTEN_SHIFT) +#define ADC_CR2_EXTEN_RISING_EDGE (0x1 << ADC_CR2_EXTEN_SHIFT) +#define ADC_CR2_EXTEN_FALLING_EDGE (0x2 << ADC_CR2_EXTEN_SHIFT) +#define ADC_CR2_EXTEN_BOTH_EDGES (0x3 << ADC_CR2_EXTEN_SHIFT) +/**@}*/ + +/* EXTSEL[3:0]: External event selection for regular group. */ +/****************************************************************************/ +#define ADC_CR2_EXTSEL_SHIFT 24 +#define ADC_CR2_EXTSEL_MASK (0xf << ADC_CR2_EXTSEL_SHIFT) +/** @defgroup adc_trigger_regular ADC Trigger Identifier for Regular group +@ingroup adc_defines + +@{*/ +#define ADC_CR2_EXTSEL_TIM9_CC2 (0 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM9_TRGO (1 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM2_CC3 (2 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM2_CC2 (3 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM3_TRGO (4 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM4_CC4 (5 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM2_TRGO (6 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM3_CC1 (7 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM3_CC3 (8 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM4_TRGO (9 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTSEL_TIM6_TRGO (10 << ADC_CR2_EXTSEL_SHIFT) +/* reserved.... */ +#define ADC_CR2_EXTSEL_EXTI11 (15 << ADC_CR2_EXTSEL_SHIFT) +/**@}*/ + +#define ADC_CR2_JSWSTART (1 << 22) + +/* JEXTEN[1:0]: External trigger enable for injected channels. */ +/****************************************************************************/ +#define ADC_CR2_JEXTEN_SHIFT 20 +#define ADC_CR2_JEXTEN_MASK (0x3 << ADC_CR2_JEXTEN_SHIFT) +/** @defgroup adc_trigger_polarity_injected ADC Injected Trigger Polarity +@ingroup adc_defines +@{*/ +#define ADC_CR2_JEXTEN_DISABLED (0x0 << ADC_CR2_JEXTEN_SHIFT) +#define ADC_CR2_JEXTEN_RISING_EDGE (0x1 << ADC_CR2_JEXTEN_SHIFT) +#define ADC_CR2_JEXTEN_FALLING_EDGE (0x2 << ADC_CR2_JEXTEN_SHIFT) +#define ADC_CR2_JEXTEN_BOTH_EDGES (0x3 << ADC_CR2_JEXTEN_SHIFT) +/**@}*/ + +/* FIXME - add the values here */ +#define ADC_CR2_JEXTSEL_SHIFT 16 +#define ADC_CR2_JEXTSEL_MASK (0xf << ADC_CR2_JEXTSEL_SHIFT) + +#define ADC_CR2_EOCS (1 << 10) +#define ADC_CR2_DDS (1 << 9) +/* FIXME- add the values here */ +#define ADC_CR2_DELS_SHIFT 4 +#define ADC_CR2_DELS_MASK 0x7 + +#define ADC_CR2_ADC_CFG (1 << 2) + + + + +/* --- ADC_SMPRx generic values -------------------------------------------- */ +/****************************************************************************/ +/* ADC_SMPRG ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_rg ADC Sample Time Selection for All Channels +@ingroup adc_defines + +@{*/ +#define ADC_SMPR_SMP_4CYC 0x0 +#define ADC_SMPR_SMP_9CYC 0x1 +#define ADC_SMPR_SMP_16CYC 0x2 +#define ADC_SMPR_SMP_24CYC 0x3 +#define ADC_SMPR_SMP_48CYC 0x4 +#define ADC_SMPR_SMP_96CYC 0x5 +#define ADC_SMPR_SMP_192CYC 0x6 +#define ADC_SMPR_SMP_384CYC 0x7 +/**@}*/ + +#define ADC_SQR_MASK 0x1f +#define ADC_SQR_MAX_CHANNELS_REGULAR 28 /* m+/h only, otherwise 27 */ + +#define ADC_CCR_TSVREFE (1 << 23) + +BEGIN_DECLS + /* L1 specific, or not fully unified adc routines */ +void adc_enable_temperature_sensor(void); +void adc_disable_temperature_sensor(void); +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity); +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/crc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/crc.h new file mode 100644 index 00000000..e019c346 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/crc.h @@ -0,0 +1,38 @@ +/** @defgroup crc_defines CRC Defines + +@brief libopencm3 Defined Constants and Types for the STM32L1xx CRC +Generator + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dac.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dac.h new file mode 100644 index 00000000..207c59d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dac.h @@ -0,0 +1,37 @@ +/** @defgroup dac_defines DAC Defines + +@brief Defined Constants and Types for the STM32L1xx DAC + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dma.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dma.h new file mode 100644 index 00000000..c1728d18 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/dma.h @@ -0,0 +1,42 @@ +/** @defgroup dma_defines DMA Defines + * + * @ingroup STM32L1xx_defines + * + * @brief Defined Constants and Types for the STM32L1xx DMA Controller + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2011 + * Fergus Noble + * @author @htmlonly © @endhtmlonly 2012 + * Ken Sarkies + * + * @date 18 October 2012 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/doc-stm32l1.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/doc-stm32l1.h new file mode 100644 index 00000000..96bea000 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/doc-stm32l1.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32L1 + +@version 1.0.0 + +@date 12 November 2012 + +API documentation for ST Microelectronics STM32L1 Cortex M3 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32L1xx STM32L1xx +Libraries for ST Microelectronics STM32L1xx series. + +@version 1.0.0 + +@date 12 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32L1xx_defines STM32L1xx Defines + +@brief Defined Constants and Types for the STM32L1xx series + +@version 1.0.0 + +@date 12 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/exti.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/exti.h new file mode 100644 index 00000000..0f309537 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/exti.h @@ -0,0 +1,41 @@ +/** @defgroup exti_defines EXTI Defines + * + * @brief Defined Constants and Types for the STM32L1xx External Interrupts + * + * + * @ingroup STM32L1xx_defines + * + * @author @htmlonly © @endhtmlonly 2013 + * Piotr Esden-Tempski + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_EXTI_H +#define LIBOPENCM3_EXTI_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/flash.h new file mode 100644 index 00000000..10afcd81 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/flash.h @@ -0,0 +1,68 @@ +/** @defgroup flash_defines FLASH Defines + * + * @ingroup STM32L1xx_defines + * + * @brief Defined Constants and Types for the STM32L1xx FLASH Memory + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2012 + * Karl Palsson + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * All extracted from PM0062 rev2, L15xx and L16xx Flash/EEPROM programming + * manual. + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H +/**@{*/ + +#include + +/* --- FLASH registers ----------------------------------------------------- */ +#define FLASH_WRPR3 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x84) + +/* --- FLASH_ACR values ---------------------------------------------------- */ +#define FLASH_ACR_ACC64 (1 << 2) + +/* --- FLASH_SR values ----------------------------------------------------- */ +#define FLASH_SR_OPTVERRUSR (1 << 12) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_64bit_enable(void); +void flash_64bit_disable(void); + +END_DECLS +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/gpio.h new file mode 100644 index 00000000..ca0b71b4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/gpio.h @@ -0,0 +1,263 @@ +/** @defgroup gpio_defines GPIO Defines + +@brief Defined Constants and Types for the STM32L1xx General Purpose I/O + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Piotr Esden-Tempski + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +/* GPIO port base addresses (for convenience) */ +/** @defgroup gpio_port_id GPIO Port IDs +@ingroup gpio_defines + +@{*/ +#define GPIOA GPIO_PORT_A_BASE +#define GPIOB GPIO_PORT_B_BASE +#define GPIOC GPIO_PORT_C_BASE +#define GPIOD GPIO_PORT_D_BASE +#define GPIOE GPIO_PORT_E_BASE +#define GPIOH GPIO_PORT_H_BASE +/**@}*/ + +/* --- GPIO registers ------------------------------------------------------ */ + +/* Port mode register (GPIOx_MODER) */ +#define GPIO_MODER(port) MMIO32((port) + 0x00) +#define GPIOA_MODER GPIO_MODER(GPIOA) +#define GPIOB_MODER GPIO_MODER(GPIOB) +#define GPIOC_MODER GPIO_MODER(GPIOC) +#define GPIOD_MODER GPIO_MODER(GPIOD) +#define GPIOE_MODER GPIO_MODER(GPIOE) +#define GPIOH_MODER GPIO_MODER(GPIOH) + +/* Port output type register (GPIOx_OTYPER) */ +#define GPIO_OTYPER(port) MMIO32((port) + 0x04) +#define GPIOA_OTYPER GPIO_OTYPER(GPIOA) +#define GPIOB_OTYPER GPIO_OTYPER(GPIOB) +#define GPIOC_OTYPER GPIO_OTYPER(GPIOC) +#define GPIOD_OTYPER GPIO_OTYPER(GPIOD) +#define GPIOE_OTYPER GPIO_OTYPER(GPIOE) +#define GPIOH_OTYPER GPIO_OTYPER(GPIOH) + +/* Port output speed register (GPIOx_OSPEEDR) */ +#define GPIO_OSPEEDR(port) MMIO32((port) + 0x08) +#define GPIOA_OSPEEDR GPIO_OSPEEDR(GPIOA) +#define GPIOB_OSPEEDR GPIO_OSPEEDR(GPIOB) +#define GPIOC_OSPEEDR GPIO_OSPEEDR(GPIOC) +#define GPIOD_OSPEEDR GPIO_OSPEEDR(GPIOD) +#define GPIOE_OSPEEDR GPIO_OSPEEDR(GPIOE) +#define GPIOH_OSPEEDR GPIO_OSPEEDR(GPIOH) + +/* Port pull-up/pull-down register (GPIOx_PUPDR) */ +#define GPIO_PUPDR(port) MMIO32((port) + 0x0c) +#define GPIOA_PUPDR GPIO_PUPDR(GPIOA) +#define GPIOB_PUPDR GPIO_PUPDR(GPIOB) +#define GPIOC_PUPDR GPIO_PUPDR(GPIOC) +#define GPIOD_PUPDR GPIO_PUPDR(GPIOD) +#define GPIOE_PUPDR GPIO_PUPDR(GPIOE) +#define GPIOH_PUPDR GPIO_PUPDR(GPIOH) + +/* Port input data register (GPIOx_IDR) */ +#define GPIO_IDR(port) MMIO32((port) + 0x10) +#define GPIOA_IDR GPIO_IDR(GPIOA) +#define GPIOB_IDR GPIO_IDR(GPIOB) +#define GPIOC_IDR GPIO_IDR(GPIOC) +#define GPIOD_IDR GPIO_IDR(GPIOD) +#define GPIOE_IDR GPIO_IDR(GPIOE) +#define GPIOH_IDR GPIO_IDR(GPIOH) + +/* Port output data register (GPIOx_ODR) */ +#define GPIO_ODR(port) MMIO32((port) + 0x14) +#define GPIOA_ODR GPIO_ODR(GPIOA) +#define GPIOB_ODR GPIO_ODR(GPIOB) +#define GPIOC_ODR GPIO_ODR(GPIOC) +#define GPIOD_ODR GPIO_ODR(GPIOD) +#define GPIOE_ODR GPIO_ODR(GPIOE) +#define GPIOH_ODR GPIO_ODR(GPIOH) + +/* Port bit set/reset register (GPIOx_BSRR) */ +#define GPIO_BSRR(port) MMIO32((port) + 0x18) +#define GPIOA_BSRR GPIO_BSRR(GPIOA) +#define GPIOB_BSRR GPIO_BSRR(GPIOB) +#define GPIOC_BSRR GPIO_BSRR(GPIOC) +#define GPIOD_BSRR GPIO_BSRR(GPIOD) +#define GPIOE_BSRR GPIO_BSRR(GPIOE) +#define GPIOH_BSRR GPIO_BSRR(GPIOH) + +/* Port configuration lock register (GPIOx_LCKR) */ +#define GPIO_LCKR(port) MMIO32((port) + 0x1C) +#define GPIOA_LCKR GPIO_LCKR(GPIOA) +#define GPIOB_LCKR GPIO_LCKR(GPIOB) +#define GPIOC_LCKR GPIO_LCKR(GPIOC) +#define GPIOD_LCKR GPIO_LCKR(GPIOD) +#define GPIOE_LCKR GPIO_LCKR(GPIOE) +#define GPIOH_LCKR GPIO_LCKR(GPIOH) + +/* Alternate function low register (GPIOx_AFRL) */ +#define GPIO_AFRL(port) MMIO32((port) + 0x20) +#define GPIOA_AFRL GPIO_AFRL(GPIOA) +#define GPIOB_AFRL GPIO_AFRL(GPIOB) +#define GPIOC_AFRL GPIO_AFRL(GPIOC) +#define GPIOD_AFRL GPIO_AFRL(GPIOD) +#define GPIOE_AFRL GPIO_AFRL(GPIOE) +#define GPIOH_AFRL GPIO_AFRL(GPIOH) + +/* Alternate function high register (GPIOx_AFRH) */ +#define GPIO_AFRH(port) MMIO32((port) + 0x24) +#define GPIOA_AFRH GPIO_AFRH(GPIOA) +#define GPIOB_AFRH GPIO_AFRH(GPIOB) +#define GPIOC_AFRH GPIO_AFRH(GPIOC) +#define GPIOD_AFRH GPIO_AFRH(GPIOD) +#define GPIOE_AFRH GPIO_AFRH(GPIOE) +#define GPIOH_AFRH GPIO_AFRH(GPIOH) + +/* --- GPIOx_MODER values-------------------------------------------- */ + +#define GPIO_MODE(n, mode) ((mode) << (2 * (n))) +#define GPIO_MODE_MASK(n) (0x3 << (2 * (n))) +/** @defgroup gpio_mode GPIO Pin Direction and Analog/Digital Mode +@ingroup gpio_defines +@{*/ +#define GPIO_MODE_INPUT 0x00 /* Default */ +#define GPIO_MODE_OUTPUT 0x01 +#define GPIO_MODE_AF 0x02 +#define GPIO_MODE_ANALOG 0x03 +/**@}*/ + +/* --- GPIOx_OTYPER values -------------------------------------------- */ +/* Output type (OTx values) */ +/** @defgroup gpio_output_type GPIO Output Pin Driver Type +@ingroup gpio_defines +@{*/ +/** Push-Pull */ +#define GPIO_OTYPE_PP 0x0 +/** Open Drain */ +#define GPIO_OTYPE_OD 0x1 +/**@}*/ + +/* Output speed values */ +#define GPIO_OSPEED(n, speed) ((speed) << (2 * (n))) +#define GPIO_OSPEED_MASK(n) (0x3 << (2 * (n))) +/** @defgroup gpio_speed GPIO Output Pin Speed +@ingroup gpio_defines +@{*/ +#define GPIO_OSPEED_400KHZ 0x0 +#define GPIO_OSPEED_2MHZ 0x1 +#define GPIO_OSPEED_10MHZ 0x2 +#define GPIO_OSPEED_40MHZ 0x3 +/**@}*/ + +/* --- GPIOx_PUPDR values ------------------------------------------- */ + +#define GPIO_PUPD(n, pupd) ((pupd) << (2 * (n))) +#define GPIO_PUPD_MASK(n) (0x3 << (2 * (n))) +/** @defgroup gpio_pup GPIO Output Pin Pullup +@ingroup gpio_defines +@{*/ +#define GPIO_PUPD_NONE 0x0 +#define GPIO_PUPD_PULLUP 0x1 +#define GPIO_PUPD_PULLDOWN 0x2 +/**@}*/ + +/* --- GPIO_IDR values ----------------------------------------------------- */ + +/* GPIO_IDR[15:0]: IDRy[15:0]: Port input data (y = 0..15) */ + +/* --- GPIO_ODR values ----------------------------------------------------- */ + +/* GPIO_ODR[15:0]: ODRy[15:0]: Port output data (y = 0..15) */ + +/* --- GPIO_BSRR values ---------------------------------------------------- */ + +/* GPIO_BSRR[31:16]: BRy: Port x reset bit y (y = 0..15) */ +/* GPIO_BSRR[15:0]: BSy: Port x set bit y (y = 0..15) */ + +/* --- GPIO_LCKR values ---------------------------------------------------- */ + +#define GPIO_LCKK (1 << 16) +/* GPIO_LCKR[15:0]: LCKy: Port x lock bit y (y = 0..15) */ + +/* --- GPIOx_AFRL/H values ------------------------------------------------- */ + +/* Note: AFRL is used for bits 0..7, AFRH is used for 8..15 */ +/* See datasheet table 5, page 35 for the definitions */ + +#define GPIO_AFR(n, af) ((af) << ((n) * 4)) +#define GPIO_AFR_MASK(n) (0xf << ((n) * 4)) +/** @defgroup gpio_af_num Alternate Function Pin Selection +@ingroup gpio_defines +@{*/ +#define GPIO_AF0 0x0 +#define GPIO_AF1 0x1 +#define GPIO_AF2 0x2 +#define GPIO_AF3 0x3 +#define GPIO_AF4 0x4 +#define GPIO_AF5 0x5 +#define GPIO_AF6 0x6 +#define GPIO_AF7 0x7 +#define GPIO_AF8 0x8 +#define GPIO_AF9 0x9 +#define GPIO_AF10 0xa +#define GPIO_AF11 0xb +#define GPIO_AF12 0xc +#define GPIO_AF13 0xd +#define GPIO_AF14 0xe +#define GPIO_AF15 0xf +/**@}*/ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +/* + * L1, like F2 and F4, has the "new" GPIO peripheral, so use that style + * however the number of ports is reduced and H port naming is different. + * TODO: this should all really be moved to a "common" gpio header + */ + +void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t pull_up_down, + uint16_t gpios); +void gpio_set_output_options(uint32_t gpioport, uint8_t otype, uint8_t speed, + uint16_t gpios); +void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint16_t gpios); + +END_DECLS + +#endif +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/i2c.h new file mode 100644 index 00000000..04ac1c75 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/i2c.h @@ -0,0 +1,37 @@ +/** @defgroup i2c_defines I2C Defines + +@brief Defined Constants and Types for the STM32L1xx I2C + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 12 October 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/irq.json new file mode 100644 index 00000000..abea8db8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/irq.json @@ -0,0 +1,64 @@ +{ + "irqs": [ + "wwdg", + "pvd", + "tamper_stamp", + "rtc_wkup", + "flash", + "rcc", + "exti0", + "exti1", + "exti2", + "exti3", + "exti4", + "dma1_channel1", + "dma1_channel2", + "dma1_channel3", + "dma1_channel4", + "dma1_channel5", + "dma1_channel6", + "dma1_channel7", + "adc1", + "usb_hp", + "usb_lp", + "dac", + "comp", + "exti9_5", + "lcd", + "tim9", + "tim10", + "tim11", + "tim2", + "tim3", + "tim4", + "i2c1_ev", + "i2c1_er", + "i2c2_ev", + "i2c2_er", + "spi1", + "spi2", + "usart1", + "usart2", + "usart3", + "exti15_10", + "rtc_alarm", + "usb_fs_wakeup", + "tim6", + "tim7", + "sdio", + "tim5", + "spi3", + "uart4", + "uart5", + "dma2_ch1", + "dma2_ch2", + "dma2_ch3", + "dma2_ch4", + "dma2_ch5", + "aes", + "comp_acq" + ], + "partname_humanreadable": "STM32 L1 series", + "partname_doxygen": "STM32L1", + "includeguard": "LIBOPENCM3_STM32_L1_NVIC_H" +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/iwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/iwdg.h new file mode 100644 index 00000000..699849ad --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/iwdg.h @@ -0,0 +1,39 @@ +/** @defgroup iwdg_defines IWDG Defines + +@brief Defined Constants and Types for the STM32L1xx Independent Watchdog +Timer + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_IWDG_H +#define LIBOPENCM3_IWDG_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/lcd.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/lcd.h new file mode 100644 index 00000000..0a4b02b7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/lcd.h @@ -0,0 +1,231 @@ +/** @defgroup lcd_defines LCD Defines + * + * @ingroup STM32L1xx_defines + * + * @brief Defined Constants and Types for the STM32L1xx LCD Controller + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Nikolay Merinov + * + * @date 2 March 2014 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ +#ifndef LIBOPENCM3_LCD_H +#define LIBOPENCM3_LCD_H + +#include +#include + +/* --- LCD registers ------------------------------------------------------ */ +/****************************************************************************/ +/** @defgroup lcd_reg_base LCD register base addresses +@ingroup lcd_defines +*/ +/* @{ */ +/* Control register */ +#define LCD_CR MMIO32(LCD_BASE + 0x00) +/* Frame control register */ +#define LCD_FCR MMIO32(LCD_BASE + 0x04) +/* Status register */ +#define LCD_SR MMIO32(LCD_BASE + 0x08) +/* Clear register */ +#define LCD_CLR MMIO32(LCD_BASE + 0x0C) +/* @} */ + +/* --- LCD display memory ------------------------------------------------- */ +/* Base address of display memory */ +#define LCD_RAM_BASE (LCD_BASE + 0x14) + +/* COM0 memory */ +#define LCD_RAM_COM0 MMIO64(LCD_RAM_BASE + 0x00) +/* COM1 memory */ +#define LCD_RAM_COM1 MMIO64(LCD_RAM_BASE + 0x08) +/* COM2 memory */ +#define LCD_RAM_COM2 MMIO64(LCD_RAM_BASE + 0x10) +/* COM3 memory */ +#define LCD_RAM_COM3 MMIO64(LCD_RAM_BASE + 0x18) +/* COM4 memory */ +#define LCD_RAM_COM4 MMIO64(LCD_RAM_BASE + 0x20) +/* COM5 memory */ +#define LCD_RAM_COM5 MMIO64(LCD_RAM_BASE + 0x28) +/* COM6 memory */ +#define LCD_RAM_COM6 MMIO64(LCD_RAM_BASE + 0x30) +/* COM7 memory */ +#define LCD_RAM_COM7 MMIO64(LCD_RAM_BASE + 0x38) + +/* --- LCD_CR values ------------------------------------------------------ */ +#define LCD_CR_LCDEN (1 << 0) +#define LCD_CR_VSEL (1 << 1) + +#define LCD_CR_DUTY_SHIFT 2 +#define LCD_CR_DUTY_MASK 0x7 +#define LCD_CR_DUTY_STATIC 0x0 +#define LCD_CR_DUTY_1_2 0x1 +#define LCD_CR_DUTY_1_3 0x2 +#define LCD_CR_DUTY_1_4 0x3 +#define LCD_CR_DUTY_1_8 0x4 + +#define LCD_CR_BIAS_SHIFT 5 +#define LCD_CR_BIAS_MASK 0x3 +#define LCD_CR_BIAS_1_4 0x0 +#define LCD_CR_BIAS_1_2 0x1 +#define LCD_CR_BIAS_1_3 0x2 + +#define LCD_CR_MUX_SEG (1 << 7) + +/* --- LCD_FCR values ------------------------------------------------------ */ +#define LCD_FCR_HD (1 << 0) +#define LCD_FCR_SOFIE (1 << 1) +#define LCD_FCR_UDDIE (1 << 3) + +#define LCD_FCR_PON_SHIFT 4 +#define LCD_FCR_PON_MASK 0x7 +#define LCD_FCR_PON_0 0x0 +#define LCD_FCR_PON_1 0x1 +#define LCD_FCR_PON_2 0x2 +#define LCD_FCR_PON_3 0x3 +#define LCD_FCR_PON_4 0x4 +#define LCD_FCR_PON_5 0x5 +#define LCD_FCR_PON_6 0x6 +#define LCD_FCR_PON_7 0x7 + +#define LCD_FCR_DEAD_SHIFT 7 +#define LCD_FCR_DEAD_MASK 0x7 +#define LCD_FCR_DEAD_NONE 0x0 +#define LCD_FCR_DEAD_1_PHASE 0x1 +#define LCD_FCR_DEAD_2_PHASE 0x2 +#define LCD_FCR_DEAD_3_PHASE 0x3 +#define LCD_FCR_DEAD_4_PHASE 0x4 +#define LCD_FCR_DEAD_5_PHASE 0x5 +#define LCD_FCR_DEAD_6_PHASE 0x6 +#define LCD_FCR_DEAD_7_PHASE 0x7 + +#define LCD_FCR_CC_SHIFT 10 +#define LCD_FCR_CC_MASK 0x7 +#define LCD_FCR_CC_0 0x0 +#define LCD_FCR_CC_1 0x1 +#define LCD_FCR_CC_2 0x2 +#define LCD_FCR_CC_3 0x3 +#define LCD_FCR_CC_4 0x4 +#define LCD_FCR_CC_5 0x5 +#define LCD_FCR_CC_6 0x6 +#define LCD_FCR_CC_7 0x7 + +#define LCD_FCR_BLINKF_SHIFT 13 +#define LCD_FCR_BLINKF_MASK 0x7 +#define LCD_FCR_BLINKF_8 0x0 +#define LCD_FCR_BLINKF_16 0x1 +#define LCD_FCR_BLINKF_32 0x2 +#define LCD_FCR_BLINKF_64 0x3 +#define LCD_FCR_BLINKF_128 0x4 +#define LCD_FCR_BLINKF_256 0x5 +#define LCD_FCR_BLINKF_512 0x6 +#define LCD_FCR_BLINKF_1024 0x7 + +#define LCD_FCR_BLINK_SHIFT 16 +#define LCD_FCR_BLINK_MASK 0x3 +#define LCD_FCR_BLINK_DISABLE 0x0 +#define LCD_FCR_BLINK_SEG0_COM0_ENABLE 0x1 +#define LCD_FCR_BLINK_SEG0_ENABLE 0x2 +#define LCD_FCR_BLINK_ALL_ENABLE 0x3 + +#define LCD_FCR_DIV_SHIFT 18 +#define LCD_FCR_DIV_MASK 0xF +#define LCD_FCR_DIV_16 0x0 +#define LCD_FCR_DIV_17 0x1 +#define LCD_FCR_DIV_18 0x2 +#define LCD_FCR_DIV_19 0x3 +#define LCD_FCR_DIV_20 0x4 +#define LCD_FCR_DIV_21 0x5 +#define LCD_FCR_DIV_22 0x6 +#define LCD_FCR_DIV_23 0x7 +#define LCD_FCR_DIV_24 0x8 +#define LCD_FCR_DIV_25 0x9 +#define LCD_FCR_DIV_26 0xA +#define LCD_FCR_DIV_27 0xB +#define LCD_FCR_DIV_28 0xC +#define LCD_FCR_DIV_29 0xD +#define LCD_FCR_DIV_30 0xE +#define LCD_FCR_DIV_31 0xF + +#define LCD_FCR_PS_SHIFT 22 +#define LCD_FCR_PS_MASK 0xF +#define LCD_FCR_PS_1 0x0 +#define LCD_FCR_PS_2 0x1 +#define LCD_FCR_PS_4 0x2 +#define LCD_FCR_PS_8 0x3 +#define LCD_FCR_PS_16 0x4 +#define LCD_FCR_PS_32 0x5 +#define LCD_FCR_PS_64 0x6 +#define LCD_FCR_PS_128 0x7 +#define LCD_FCR_PS_256 0x8 +#define LCD_FCR_PS_512 0x9 +#define LCD_FCR_PS_1024 0xA +#define LCD_FCR_PS_2048 0xB +#define LCD_FCR_PS_4096 0xC +#define LCD_FCR_PS_8192 0xD +#define LCD_FCR_PS_16384 0xE +#define LCD_FCR_PS_32768 0xF + +/* --- LCD_SR values ------------------------------------------------------ */ +#define LCD_SR_ENS (1 << 0) +#define LCD_SR_SOF (1 << 1) +#define LCD_SR_UDR (1 << 2) +#define LCD_SR_UDD (1 << 3) +#define LCD_SR_RDY (1 << 4) +#define LCD_SR_FCRSF (1 << 5) + +/* --- LCD_CLR values ----------------------------------------------------- */ +#define LCD_CLR_SOFC (1 << 1) +#define LCD_CLR_UDDC (1 << 3) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void lcd_enable(void); +void lcd_update(void); + +void lcd_wait_for_lcd_enabled(void); +void lcd_wait_for_step_up_ready(void); +void lcd_wait_for_update_ready(void); + +int lcd_is_enabled(void); +int lcd_is_step_up_ready(void); +int lcd_is_for_update_ready(void); + +void lcd_set_contrast(uint8_t contrast); +void lcd_set_bias(uint8_t bias); +void lcd_set_duty(uint8_t duty); +void lcd_set_prescaler(uint8_t ps); +void lcd_set_divider(uint8_t div); +void lcd_enable_segment_multiplexing(void); +void lcd_disable_segment_multiplexing(void); +void lcd_set_refresh_frequency(uint32_t frequency); + +END_DECLS + +#endif +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/memorymap.h new file mode 100644 index 00000000..1b9cd10e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/memorymap.h @@ -0,0 +1,121 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32 specific peripheral definitions ------------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define INFO_BASE (0x1ff00000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB (PERIPH_BASE + 0x20000) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define LCD_BASE (PERIPH_BASE_APB1 + 0x2400) +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +/* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +/* PERIPH_BASE_APB1 + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define USART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define USART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define USB_DEV_FS_BASE (PERIPH_BASE_APB1 + 0x5c00) +#define USB_PMA_BASE (PERIPH_BASE_APB1 + 0x6000) +/* gap */ +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define OPAMP_BASE (PERIPH_BASE_APB1 + 0x7c5c) +#define COMP_BASE (PERIPH_BASE_APB1 + 0x7c00) +#define ROUTING_BASE (PERIPH_BASE_APB1 + 0x7c04) + +/* APB2 */ +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x0000) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x0400) +#define TIM9_BASE (PERIPH_BASE_APB2 + 0x0800) +#define TIM10_BASE (PERIPH_BASE_APB2 + 0x0c00) +#define TIM11_BASE (PERIPH_BASE_APB2 + 0x1000) +/* gap */ +#define ADC_BASE (PERIPH_BASE_APB2 + 0x2400) +/* ADC is the name in the L1 refman, but all other stm32's use ADC1 */ +#define ADC1_BASE ADC_BASE +/* gap */ +#define SDIO_BASE (PERIPH_BASE_APB2 + 0x2c00) +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +/* gap */ +#define USART1_BASE (PERIPH_BASE_APB2 + 0x3800) + +/* AHB */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB + 0x00000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB + 0x00400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB + 0x00800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB + 0x00c00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB + 0x01000) +#define GPIO_PORT_H_BASE (PERIPH_BASE_AHB + 0x01400) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB + 0x01800) +#define GPIO_PORT_G_BASE (PERIPH_BASE_AHB + 0x01c00) +/* gap */ +#define CRC_BASE (PERIPH_BASE_AHB + 0x03000) +/* gap */ +#define RCC_BASE (PERIPH_BASE_AHB + 0x03800) +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB + 0x03c00) +/* gap */ +#define DMA1_BASE (PERIPH_BASE_AHB + 0x06000) +#define DMA2_BASE (PERIPH_BASE_AHB + 0x04000) + +/* PPIB */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* FSMC */ +#define FSMC_BASE (PERIPH_BASE + 0x60000000) +/* AES */ +#define AES_BASE (PERIPH_BASE + 0x10000000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x8004C) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x80050) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 0x14) + +/* ST provided factory calibration values @ 3.0V */ +#define ST_VREFINT_CAL MMIO16(0x1FF80078) +#define ST_TSENSE_CAL1_30C MMIO16(0x1FF8007A) +#define ST_TSENSE_CAL2_110C MMIO16(0x1FF8007E) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/pwr.h new file mode 100644 index 00000000..4a694e8d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/pwr.h @@ -0,0 +1,52 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32L1xx Power Control + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2011 Stephen Caudle +@author @htmlonly © @endhtmlonly 2012 Karl Palsson + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include + +/* + * This file extends the common STM32 version with definitions only + * applicable to the STM32L1 series of devices. + */ + +/* --- PWR_CSR values ------------------------------------------------------- */ + +/* Bits [31:11]: Reserved */ +/* EWUP3: Enable WKUP3 pin */ +#define PWR_CSR_EWUP3 (1 << 10) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rcc.h new file mode 100644 index 00000000..8933555c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rcc.h @@ -0,0 +1,636 @@ +/** @defgroup rcc_defines RCC Defines + * + * @ingroup STM32L1xx_defines + * + * @brief Defined Constants and Types for the STM32L1xx Reset and Clock + * Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2009 + * Federico Ruiz-Ugalde \ + * @author @htmlonly © @endhtmlonly 2009 + * Uwe Hermann + * @author @htmlonly © @endhtmlonly 2012 + * Karl Palsson + * + * @date 11 November 2012 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + * Originally based on the F1 code, as it seemed most similar to the L1 + * TODO: very incomplete still! + */ + +/**@{*/ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +#include + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_ICSCR MMIO32(RCC_BASE + 0x04) +#define RCC_CFGR MMIO32(RCC_BASE + 0x08) +#define RCC_CIR MMIO32(RCC_BASE + 0x0c) +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x10) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x14) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x18) +#define RCC_AHBENR MMIO32(RCC_BASE + 0x1c) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x20) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x24) +#define RCC_AHBLPENR MMIO32(RCC_BASE + 0x28) +#define RCC_APB2LPENR MMIO32(RCC_BASE + 0x2c) +#define RCC_APB1LPENR MMIO32(RCC_BASE + 0x30) +#define RCC_CSR MMIO32(RCC_BASE + 0x34) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_RTCPRE_SHIFT 29 +#define RCC_CR_RTCPRE_MASK 0x3 +#define RCC_CR_CSSON (1 << 28) +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_MSIRDY (1 << 9) +#define RCC_CR_MSION (1 << 8) +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +#define RCC_CR_RTCPRE_DIV2 0 +#define RCC_CR_RTCPRE_DIV4 1 +#define RCC_CR_RTCPRE_DIV8 2 +#define RCC_CR_RTCPRE_DIV16 3 +#define RCC_CR_RTCPRE_SHIFT 29 +#define RCC_CR_RTCPRE_MASK 0x3 + +/** @defgroup rcc_icscr_defines RCC_ICSCR definitions + * @brief Internal clock sources calibration register + * @ingroup rcc_defines + *@{*/ +#define RCC_ICSCR_MSITRIM_SHIFT 24 +#define RCC_ICSCR_MSITRIM_MASK 0xff +#define RCC_ICSCR_MSICAL_SHIFT 16 +#define RCC_ICSCR_MSICAL_MASK 0xff + +#define RCC_ICSCR_MSIRANGE_SHIFT 13 +#define RCC_ICSCR_MSIRANGE_MASK 0x7 +/** @defgroup rcc_icscr_msirange MSI Ranges + * @ingroup rcc_icscr_defines + *@{*/ +#define RCC_ICSCR_MSIRANGE_65KHZ 0x0 +#define RCC_ICSCR_MSIRANGE_131KHZ 0x1 +#define RCC_ICSCR_MSIRANGE_262KHZ 0x2 +#define RCC_ICSCR_MSIRANGE_524KHZ 0x3 +#define RCC_ICSCR_MSIRANGE_1MHZ 0x4 +#define RCC_ICSCR_MSIRANGE_2MHZ 0x5 +#define RCC_ICSCR_MSIRANGE_4MHZ 0x6 +/**@}*/ +#define RCC_ICSCR_HSITRIM_SHIFT 8 +#define RCC_ICSCR_HSITRIM_MASK 0x1f +#define RCC_ICSCR_HSICAL_SHIFT 0 +#define RCC_ICSCR_HSICAL_MASK 0xff +/**@}*/ + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +/* MCOPRE */ +#define RCC_CFGR_MCOPRE_DIV1 0 +#define RCC_CFGR_MCOPRE_DIV2 1 +#define RCC_CFGR_MCOPRE_DIV4 2 +#define RCC_CFGR_MCOPRE_DIV8 3 +#define RCC_CFGR_MCOPRE_DIV16 4 +#define RCC_CFGR_MCOPRE_SHIFT 28 +#define RCC_CFGR_MCOPRE_MASK 0x7 + +/* MCO: Microcontroller clock output */ +#define RCC_CFGR_MCO_NOCLK 0x0 +#define RCC_CFGR_MCO_SYSCLK 0x1 +#define RCC_CFGR_MCO_HSI 0x2 +#define RCC_CFGR_MCO_MSI 0x3 +#define RCC_CFGR_MCO_HSE 0x4 +#define RCC_CFGR_MCO_PLL 0x5 +#define RCC_CFGR_MCO_LSI 0x6 +#define RCC_CFGR_MCO_LSE 0x7 +#define RCC_CFGR_MCO_SHIFT 24 +#define RCC_CFGR_MCO_MASK 0x7 + +/* PLL Output division selection */ +#define RCC_CFGR_PLLDIV_DIV2 0x1 +#define RCC_CFGR_PLLDIV_DIV3 0x2 +#define RCC_CFGR_PLLDIV_DIV4 0x3 +#define RCC_CFGR_PLLDIV_SHIFT 22 +#define RCC_CFGR_PLLDIV_MASK 0x3 + +/* PLLMUL: PLL multiplication factor */ +#define RCC_CFGR_PLLMUL_MUL3 0x0 +#define RCC_CFGR_PLLMUL_MUL4 0x1 +#define RCC_CFGR_PLLMUL_MUL6 0x2 +#define RCC_CFGR_PLLMUL_MUL8 0x3 +#define RCC_CFGR_PLLMUL_MUL12 0x4 +#define RCC_CFGR_PLLMUL_MUL16 0x5 +#define RCC_CFGR_PLLMUL_MUL24 0x6 +#define RCC_CFGR_PLLMUL_MUL32 0x7 +#define RCC_CFGR_PLLMUL_MUL48 0x8 +#define RCC_CFGR_PLLMUL_SHIFT 18 +#define RCC_CFGR_PLLMUL_MASK 0xf + +/* PLLSRC: PLL entry clock source */ +#define RCC_CFGR_PLLSRC_HSI_CLK 0x0 +#define RCC_CFGR_PLLSRC_HSE_CLK 0x1 + +/* PPRE2: APB high-speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_HCLK_NODIV 0x0 +#define RCC_CFGR_PPRE2_HCLK_DIV2 0x4 +#define RCC_CFGR_PPRE2_HCLK_DIV4 0x5 +#define RCC_CFGR_PPRE2_HCLK_DIV8 0x6 +#define RCC_CFGR_PPRE2_HCLK_DIV16 0x7 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE2_SHIFT 11 + +/* PPRE1: APB low-speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_HCLK_NODIV 0x0 +#define RCC_CFGR_PPRE1_HCLK_DIV2 0x4 +#define RCC_CFGR_PPRE1_HCLK_DIV4 0x5 +#define RCC_CFGR_PPRE1_HCLK_DIV8 0x6 +#define RCC_CFGR_PPRE1_HCLK_DIV16 0x7 +#define RCC_CFGR_PPRE1_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 8 + +/* HPRE: AHB prescaler */ +#define RCC_CFGR_HPRE_SYSCLK_NODIV 0x0 +#define RCC_CFGR_HPRE_SYSCLK_DIV2 0x8 +#define RCC_CFGR_HPRE_SYSCLK_DIV4 0x9 +#define RCC_CFGR_HPRE_SYSCLK_DIV8 0xa +#define RCC_CFGR_HPRE_SYSCLK_DIV16 0xb +#define RCC_CFGR_HPRE_SYSCLK_DIV64 0xc +#define RCC_CFGR_HPRE_SYSCLK_DIV128 0xd +#define RCC_CFGR_HPRE_SYSCLK_DIV256 0xe +#define RCC_CFGR_HPRE_SYSCLK_DIV512 0xf +#define RCC_CFGR_HPRE_MASK 0xf +#define RCC_CFGR_HPRE_SHIFT 4 + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_SYSCLKSEL_MSICLK 0x0 +#define RCC_CFGR_SWS_SYSCLKSEL_HSICLK 0x1 +#define RCC_CFGR_SWS_SYSCLKSEL_HSECLK 0x2 +#define RCC_CFGR_SWS_SYSCLKSEL_PLLCLK 0x3 +#define RCC_CFGR_SWS_MASK 0x3 +#define RCC_CFGR_SWS_SHIFT 2 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_SYSCLKSEL_MSICLK 0x0 +#define RCC_CFGR_SW_SYSCLKSEL_HSICLK 0x1 +#define RCC_CFGR_SW_SYSCLKSEL_HSECLK 0x2 +#define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x3 +#define RCC_CFGR_SW_MASK 0x3 +#define RCC_CFGR_SW_SHIFT 0 + +/* --- RCC_CIR values ------------------------------------------------------ */ + +/* Clock security system interrupt clear bit */ +#define RCC_CIR_CSSC (1 << 23) + +/* OSC ready interrupt clear bits */ +#define RCC_CIR_MSIRDYC (1 << 21) +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) + +/* OSC ready interrupt enable bits */ +#define RCC_CIR_MSIRDYIE (1 << 13) +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) + +/* Clock security system interrupt flag bit */ +#define RCC_CIR_CSSF (1 << 7) + +/* OSC ready interrupt flag bits */ +#define RCC_CIR_MSIRDYF (1 << 5) /* (**) */ +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_AHBRSTR values ------------------------------------------------- */ +#define RCC_AHBRSTR_DMA1RST (1 << 24) +#define RCC_AHBRSTR_FLITFRST (1 << 15) +#define RCC_AHBRSTR_CRCRST (1 << 12) +#define RCC_AHBRSTR_GPIOHRST (1 << 5) +#define RCC_AHBRSTR_GPIOERST (1 << 4) +#define RCC_AHBRSTR_GPIODRST (1 << 3) +#define RCC_AHBRSTR_GPIOCRST (1 << 2) +#define RCC_AHBRSTR_GPIOBRST (1 << 1) +#define RCC_AHBRSTR_GPIOARST (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_ADC1RST (1 << 9) +#define RCC_APB2RSTR_TIM11RST (1 << 4) +#define RCC_APB2RSTR_TIM10RST (1 << 3) +#define RCC_APB2RSTR_TIM9RST (1 << 2) +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_COMPRST (1 << 31) +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_USBRST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_USART3RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_LCDRST (1 << 9) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM5RST (1 << 3) +#define RCC_APB1RSTR_TIM4RST (1 << 2) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_AHBENR values --------------------------------------------------- */ + +/** @defgroup rcc_ahbenr_en RCC_AHBENR enable values +@ingroup STM32L1xx_rcc_defines + +@{*/ +#define RCC_AHBENR_DMA1EN (1 << 24) +#define RCC_AHBENR_FLITFEN (1 << 15) +#define RCC_AHBENR_CRCEN (1 << 12) +#define RCC_AHBENR_GPIOHEN (1 << 5) +#define RCC_AHBENR_GPIOEEN (1 << 4) +#define RCC_AHBENR_GPIODEN (1 << 3) +#define RCC_AHBENR_GPIOCEN (1 << 2) +#define RCC_AHBENR_GPIOBEN (1 << 1) +#define RCC_AHBENR_GPIOAEN (1 << 0) +/*@}*/ + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values +@ingroup STM32L1xx_rcc_defines + +@{*/ +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_ADC1EN (1 << 9) +#define RCC_APB2ENR_TIM11EN (1 << 4) +#define RCC_APB2ENR_TIM10EN (1 << 3) +#define RCC_APB2ENR_TIM9EN (1 << 2) +#define RCC_APB2ENR_SYSCFGEN (1 << 0) +/*@}*/ + +/* --- RCC_APB1ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values +@ingroup STM32L1xx_rcc_defines + +@{*/ +#define RCC_APB1ENR_COMPEN (1 << 31) +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_USBEN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_LCDEN (1 << 9) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM4EN (1 << 2) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) +/*@}*/ + +/* --- RCC_AHBLPENR -------------------------------------------------------- */ +#define RCC_AHBLPENR_DMA1LPEN (1 << 24) +#define RCC_AHBLPENR_SRAMLPEN (1 << 16) +#define RCC_AHBLPENR_FLITFLPEN (1 << 15) +#define RCC_AHBLPENR_CRCLPEN (1 << 12) +#define RCC_AHBLPENR_GPIOHLPEN (1 << 5) +#define RCC_AHBLPENR_GPIOELPEN (1 << 4) +#define RCC_AHBLPENR_GPIODLPEN (1 << 3) +#define RCC_AHBLPENR_GPIOCLPEN (1 << 2) +#define RCC_AHBLPENR_GPIOBLPEN (1 << 1) +#define RCC_AHBLPENR_GPIOALPEN (1 << 0) + +#define RCC_APB2LPENR_USART1LPEN (1 << 14) +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) +#define RCC_APB2LPENR_ADC1LPEN (1 << 9) +#define RCC_APB2LPENR_TIM11LPEN (1 << 4) +#define RCC_APB2LPENR_TIM10LPEN (1 << 3) +#define RCC_APB2LPENR_TIM9LPEN (1 << 2) +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 0) + +#define RCC_APB1LPENR_COMPLPEN (1 << 31) +#define RCC_APB1LPENR_DACLPEN (1 << 29) +#define RCC_APB1LPENR_PWRLPEN (1 << 28) +#define RCC_APB1LPENR_USBLPEN (1 << 23) +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) +#define RCC_APB1LPENR_USART3LPEN (1 << 18) +#define RCC_APB1LPENR_USART2LPEN (1 << 17) +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) +#define RCC_APB1LPENR_LCDLPEN (1 << 9) +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) + + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_OBLRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\ + RCC_CSR_PINRSTF | RCC_CSR_OBLRSTF) +#define RCC_CSR_RTCRST (1 << 23) +#define RCC_CSR_RTCEN (1 << 22) +#define RCC_CSR_RTCSEL_SHIFT (16) +#define RCC_CSR_RTCSEL_MASK (0x3) +#define RCC_CSR_RTCSEL_NONE (0x0) +#define RCC_CSR_RTCSEL_LSE (0x1) +#define RCC_CSR_RTCSEL_LSI (0x2) +#define RCC_CSR_RTCSEL_HSI (0x3) +#define RCC_CSR_LSECSSD (1 << 12) +#define RCC_CSR_LSECSSON (1 << 11) +#define RCC_CSR_LSEBYP (1 << 10) +#define RCC_CSR_LSERDY (1 << 9) +#define RCC_CSR_LSEON (1 << 8) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +struct rcc_clock_scale { + uint8_t pll_mul; + uint16_t pll_div; + uint8_t pll_source; + uint8_t flash_waitstates; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + enum pwr_vos_scale voltage_scale; + uint32_t ahb_frequency; + uint32_t apb1_frequency; + uint32_t apb2_frequency; + uint8_t msi_range; +}; + +enum rcc_clock_config_entry { + RCC_CLOCK_VRANGE1_HSI_PLL_24MHZ, + RCC_CLOCK_VRANGE1_HSI_PLL_32MHZ, + RCC_CLOCK_VRANGE1_HSI_RAW_16MHZ, + RCC_CLOCK_VRANGE1_HSI_RAW_4MHZ, + RCC_CLOCK_VRANGE1_MSI_RAW_4MHZ, + RCC_CLOCK_VRANGE1_MSI_RAW_2MHZ, + RCC_CLOCK_CONFIG_END +}; + +extern const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END]; + + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_osc { + RCC_PLL, RCC_HSE, RCC_HSI, RCC_MSI, RCC_LSE, RCC_LSI +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + /* AHB peripherals */ + RCC_GPIOA = _REG_BIT(0x1c, 0), + RCC_GPIOB = _REG_BIT(0x1c, 1), + RCC_GPIOC = _REG_BIT(0x1c, 2), + RCC_GPIOD = _REG_BIT(0x1c, 3), + RCC_GPIOE = _REG_BIT(0x1c, 4), + RCC_GPIOH = _REG_BIT(0x1c, 5), + RCC_GPIOF = _REG_BIT(0x1c, 6), + RCC_GPIOG = _REG_BIT(0x1c, 7), + RCC_CRC = _REG_BIT(0x1c, 12), + RCC_FLITF = _REG_BIT(0x1c, 15), + RCC_DMA1 = _REG_BIT(0x1c, 24), + RCC_DMA2 = _REG_BIT(0x1c, 25), + RCC_AES = _REG_BIT(0x1c, 27), + RCC_FSMC = _REG_BIT(0x1c, 30), + + /* APB2 peripherals */ + RCC_SYSCFG = _REG_BIT(0x20, 0), + RCC_TIM9 = _REG_BIT(0x20, 2), + RCC_TIM10 = _REG_BIT(0x20, 3), + RCC_TIM11 = _REG_BIT(0x20, 4), + RCC_ADC1 = _REG_BIT(0x20, 9), + RCC_SDIO = _REG_BIT(0x20, 11), + RCC_SPI1 = _REG_BIT(0x20, 12), + RCC_USART1 = _REG_BIT(0x20, 14), + + /* APB1 peripherals*/ + RCC_TIM2 = _REG_BIT(0x24, 0), + RCC_TIM3 = _REG_BIT(0x24, 1), + RCC_TIM4 = _REG_BIT(0x24, 2), + RCC_TIM5 = _REG_BIT(0x24, 3), + RCC_TIM6 = _REG_BIT(0x24, 4), + RCC_TIM7 = _REG_BIT(0x24, 5), + RCC_LCD = _REG_BIT(0x24, 9), + RCC_WWDG = _REG_BIT(0x24, 11), + RCC_SPI2 = _REG_BIT(0x24, 14), + RCC_SPI3 = _REG_BIT(0x24, 15), + RCC_USART2 = _REG_BIT(0x24, 17), + RCC_USART3 = _REG_BIT(0x24, 18), + RCC_UART4 = _REG_BIT(0x24, 19), + RCC_UART5 = _REG_BIT(0x24, 20), + RCC_I2C1 = _REG_BIT(0x24, 21), + RCC_I2C2 = _REG_BIT(0x24, 22), + RCC_USB = _REG_BIT(0x24, 23), + RCC_PWR = _REG_BIT(0x24, 28), + RCC_DAC = _REG_BIT(0x24, 29), + RCC_COMP = _REG_BIT(0x24, 31), + + /* AHB peripherals */ + SCC_GPIOA = _REG_BIT(0x28, 0), + SCC_GPIOB = _REG_BIT(0x28, 1), + SCC_GPIOC = _REG_BIT(0x28, 2), + SCC_GPIOD = _REG_BIT(0x28, 3), + SCC_GPIOE = _REG_BIT(0x28, 4), + SCC_GPIOH = _REG_BIT(0x28, 5), + SCC_GPIOF = _REG_BIT(0x28, 6), + SCC_GPIOG = _REG_BIT(0x28, 7), + SCC_CRC = _REG_BIT(0x28, 12), + SCC_FLITF = _REG_BIT(0x28, 15), + SCC_SRAM = _REG_BIT(0x28, 16), + SCC_DMA1 = _REG_BIT(0x28, 24), + SCC_DMA2 = _REG_BIT(0x28, 25), + SCC_AES = _REG_BIT(0x28, 27), + SCC_FSMC = _REG_BIT(0x28, 30), + + /* APB2 peripherals */ + SCC_SYSCFG = _REG_BIT(0x2c, 0), + SCC_TIM9 = _REG_BIT(0x2c, 2), + SCC_TIM10 = _REG_BIT(0x2c, 3), + SCC_TIM11 = _REG_BIT(0x2c, 4), + SCC_ADC1 = _REG_BIT(0x2c, 9), + SCC_SDIO = _REG_BIT(0x2c, 11), + SCC_SPI1 = _REG_BIT(0x2c, 12), + SCC_USART1 = _REG_BIT(0x2c, 14), + + /* APB1 peripherals*/ + SCC_TIM2 = _REG_BIT(0x24, 0), + SCC_TIM3 = _REG_BIT(0x24, 1), + SCC_TIM4 = _REG_BIT(0x24, 2), + SCC_TIM5 = _REG_BIT(0x24, 3), + SCC_TIM6 = _REG_BIT(0x24, 4), + SCC_TIM7 = _REG_BIT(0x24, 5), + SCC_LCD = _REG_BIT(0x24, 9), + SCC_WWDG = _REG_BIT(0x24, 11), + SCC_SPI2 = _REG_BIT(0x24, 14), + SCC_SPI3 = _REG_BIT(0x24, 15), + SCC_USART2 = _REG_BIT(0x24, 17), + SCC_USART3 = _REG_BIT(0x24, 18), + SCC_UART4 = _REG_BIT(0x24, 19), + SCC_UART5 = _REG_BIT(0x24, 20), + SCC_I2C1 = _REG_BIT(0x24, 21), + SCC_I2C2 = _REG_BIT(0x24, 22), + SCC_USB = _REG_BIT(0x24, 23), + SCC_PWR = _REG_BIT(0x24, 28), + SCC_DAC = _REG_BIT(0x24, 29), + SCC_COMP = _REG_BIT(0x24, 31), +}; + +enum rcc_periph_rst { + /* AHB peripherals */ + RST_GPIOA = _REG_BIT(0x10, 0), + RST_GPIOB = _REG_BIT(0x10, 1), + RST_GPIOC = _REG_BIT(0x10, 2), + RST_GPIOD = _REG_BIT(0x10, 3), + RST_GPIOE = _REG_BIT(0x10, 4), + RST_GPIOH = _REG_BIT(0x10, 5), + RST_GPIOF = _REG_BIT(0x10, 6), + RST_GPIOG = _REG_BIT(0x10, 7), + RST_CRC = _REG_BIT(0x10, 12), + RST_FLITF = _REG_BIT(0x10, 15), + RST_DMA1 = _REG_BIT(0x10, 24), + RST_DMA2 = _REG_BIT(0x10, 25), + RST_AES = _REG_BIT(0x10, 27), + RST_FSMC = _REG_BIT(0x10, 30), + + /* APB2 peripherals */ + RST_SYSCFG = _REG_BIT(0x14, 0), + RST_TIM9 = _REG_BIT(0x14, 2), + RST_TIM10 = _REG_BIT(0x14, 3), + RST_TIM11 = _REG_BIT(0x14, 4), + RST_ADC1 = _REG_BIT(0x14, 9), + RST_SDIO = _REG_BIT(0x14, 11), + RST_SPI1 = _REG_BIT(0x14, 12), + RST_USART1 = _REG_BIT(0x14, 14), + + /* APB1 peripherals*/ + RST_TIM2 = _REG_BIT(0x18, 0), + RST_TIM3 = _REG_BIT(0x18, 1), + RST_TIM4 = _REG_BIT(0x18, 2), + RST_TIM5 = _REG_BIT(0x18, 3), + RST_TIM6 = _REG_BIT(0x18, 4), + RST_TIM7 = _REG_BIT(0x18, 5), + RST_LCD = _REG_BIT(0x18, 9), + RST_WWDG = _REG_BIT(0x18, 11), + RST_SPI2 = _REG_BIT(0x18, 14), + RST_SPI3 = _REG_BIT(0x18, 15), + RST_USART2 = _REG_BIT(0x18, 17), + RST_USART3 = _REG_BIT(0x18, 18), + RST_UART4 = _REG_BIT(0x18, 19), + RST_UART5 = _REG_BIT(0x18, 20), + RST_I2C1 = _REG_BIT(0x18, 21), + RST_I2C2 = _REG_BIT(0x18, 22), + RST_USB = _REG_BIT(0x18, 23), + RST_PWR = _REG_BIT(0x18, 28), + RST_DAC = _REG_BIT(0x18, 29), + RST_COMP = _REG_BIT(0x18, 31), +}; +#include + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_sysclk_status(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_set_msi_range(uint32_t range); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_configuration(uint32_t source, uint32_t multiplier, + uint32_t divisor); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_adcpre(uint32_t adcpre); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_usbpre(uint32_t usbpre); +void rcc_set_rtcpre(uint32_t rtcpre); +uint32_t rcc_system_clock_source(void); +void rcc_rtc_select_clock(uint32_t clock); +void rcc_clock_setup_msi(const struct rcc_clock_scale *clock); +void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock); +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); +void rcc_backupdomain_reset(void); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/ri.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/ri.h new file mode 100644 index 00000000..7d1b1bcc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/ri.h @@ -0,0 +1,386 @@ +/** @defgroup ri_defines Routing Interface registers + * + * @brief Register definitions for the STM32L1xx Routing Interface + * + * @ingroup STM32L1xx + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Marek Koza + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + * Based on the RM0038 Reference manual + * (STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced ARM®-based + * 32-bit MCUs) + */ +/**@{*/ + +/* + * There is a mismatch in the RM0038 in the RI register offset addresses (they + * are relative to the COMP base address instead of the RI base address for an + * unknown reason). We are subtracting 4 in order to use them with ROUTING_BASE. + */ +#define RI_BASE ROUTING_BASE - 0x04 + +#define RI_ICR MMIO32(RI_BASE + 0x04) +#define RI_ASCR1 MMIO32(RI_BASE + 0x08) +#define RI_ASCR2 MMIO32(RI_BASE + 0x0c) +#define RI_HYSCR1 MMIO32(RI_BASE + 0x10) +#define RI_HYSCR2 MMIO32(RI_BASE + 0x14) +#define RI_HYSCR3 MMIO32(RI_BASE + 0x18) +#define RI_HYSCR4 MMIO32(RI_BASE + 0x1c) +#define RI_ASMR1 MMIO32(RI_BASE + 0x20) +#define RI_CMR1 MMIO32(RI_BASE + 0x24) +#define RI_CICR1 MMIO32(RI_BASE + 0x28) +#define RI_ASMR2 MMIO32(RI_BASE + 0x2c) +#define RI_CMR2 MMIO32(RI_BASE + 0x30) +#define RI_CICR2 MMIO32(RI_BASE + 0x34) +#define RI_ASMR3 MMIO32(RI_BASE + 0x38) +#define RI_CMR3 MMIO32(RI_BASE + 0x3c) +#define RI_CICR3 MMIO32(RI_BASE + 0x40) +#define RI_ASMR4 MMIO32(RI_BASE + 0x44) +#define RI_CMR4 MMIO32(RI_BASE + 0x48) +#define RI_CICR4 MMIO32(RI_BASE + 0x4c) +#define RI_ASMR5 MMIO32(RI_BASE + 0x50) +#define RI_CMR5 MMIO32(RI_BASE + 0x54) +#define RI_CICR5 MMIO32(RI_BASE + 0x58) + +/** + * RI input capture register + * + * The RI_ICR register is used to select the routing of 4 full ports to the + * input captures of TIM2, TIM3 and TIM4. + */ +#define RI_ICR_IC1IOS_SHIFT 0 +#define RI_ICR_IC1IOS_MASK 0xf +#define RI_ICR_IC2IOS_SHIFT 4 +#define RI_ICR_IC2IOS_MASK 0xf +#define RI_ICR_IC3IOS_SHIFT 8 +#define RI_ICR_IC3IOS_MASK 0xf +#define RI_ICR_IC4IOS_SHIFT 12 +#define RI_ICR_IC4IOS_MASK 0xf +#define RI_ICR_TIM_SHIFT 16 +#define RI_ICR_TIM_MASK 0x3 +#define RI_ICR_IC1 (1 << 18) +#define RI_ICR_IC2 (1 << 19) +#define RI_ICR_IC3 (1 << 20) +#define RI_ICR_IC4 (1 << 21) +/* bits 22-31 reserved */ + +/** + * RI analog switches control register 1 + * + * The RI_ASCR1 register is used to configure the analog switches of the I/Os + * linked to the ADC. These I/Os are pointed to by the ADC channel number. + */ +#define RI_ASCR1_CH0_GR1_1 (1 << 0) +#define RI_ASCR1_CH1_GR1_2 (1 << 1) +#define RI_ASCR1_CH2_GR1_3 (1 << 2) +#define RI_ASCR1_CH3_GR1_4 (1 << 3) +#define RI_ASCR1_CH4 (1 << 4) +#define RI_ASCR1_CH5 (1 << 5) +#define RI_ASCR1_CH6_GR2_1 (1 << 6) +#define RI_ASCR1_CH7_GR2_2 (1 << 7) +#define RI_ASCR1_CH8_GR3_1 (1 << 8) +#define RI_ASCR1_CH9_GR3_2 (1 << 9) +#define RI_ASCR1_CH10_GR8_1 (1 << 10) +#define RI_ASCR1_CH11_GR8_2 (1 << 11) +#define RI_ASCR1_CH12_GR8_3 (1 << 12) +#define RI_ASCR1_CH13_GR8_4 (1 << 13) +#define RI_ASCR1_CH14_GR9_1 (1 << 14) +#define RI_ASCR1_CH15_GR9_2 (1 << 15) +#define RI_ASCR1_CH31_GR11_5 (1 << 16) +/* bit 17 reserved */ +#define RI_ASCR1_CH18_GR7_1 (1 << 18) +#define RI_ASCR1_CH19_GR7_2 (1 << 19) +#define RI_ASCR1_CH20_GR7_3 (1 << 20) +#define RI_ASCR1_CH21_GR7_4 (1 << 21) +#define RI_ASCR1_CH22 (1 << 22) +#define RI_ASCR1_CH23 (1 << 23) +#define RI_ASCR1_CH24 (1 << 24) +#define RI_ASCR1_CH25 (1 << 25) +#define RI_ASCR1_VCOMP (1 << 26) +#define RI_ASCR1_CH27_GR11_1 (1 << 27) +#define RI_ASCR1_CH28_GR11_2 (1 << 28) +#define RI_ASCR1_CH29_GR11_3 (1 << 29) +#define RI_ASCR1_CH30_GR11_4 (1 << 30) +#define RI_ASCR1_SCM (1 << 31) + +/** + * RI analog switches control register 2 + * + * The RI_ASCR2 register is used to configure the analog switches of groups of + * I/Os not linked to the ADC. In this way, predefined groups of I/Os can be + * connected together. + */ +#define RI_ASCR2_GR10_1 (1 << 0) +#define RI_ASCR2_GR10_2 (1 << 1) +#define RI_ASCR2_GR10_3 (1 << 2) +#define RI_ASCR2_GR10_4 (1 << 3) +#define RI_ASCR2_GR6_1 (1 << 4) +#define RI_ASCR2_GR6_2 (1 << 5) +#define RI_ASCR2_GR5_1 (1 << 6) +#define RI_ASCR2_GR5_2 (1 << 7) +#define RI_ASCR2_GR5_3 (1 << 8) +#define RI_ASCR2_GR4_1 (1 << 9) +#define RI_ASCR2_GR4_2 (1 << 10) +#define RI_ASCR2_GR4_3 (1 << 11) +/* bits 12-15 reserved */ +#define RI_ASCR2_CH0B_GR3_3 (1 << 16) +#define RI_ASCR2_CH1B_GR3_4 (1 << 17) +#define RI_ASCR2_CH2B_GR3_5 (1 << 18) +#define RI_ASCR2_CH3B_GR9_3 (1 << 19) +#define RI_ASCR2_CH6B_GR9_4 (1 << 20) +#define RI_ASCR2_CH7B_GR2_3 (1 << 21) +#define RI_ASCR2_CH8B_GR2_4 (1 << 22) +#define RI_ASCR2_CH9B_GR2_5 (1 << 23) +#define RI_ASCR2_CH10B_GR7_5 (1 << 24) +#define RI_ASCR2_CH11B_GR7_6 (1 << 25) +#define RI_ASCR2_CH12B_GR7_7 (1 << 26) +#define RI_ASCR2_GR6_3 (1 << 27) +#define RI_ASCR2_GR6_4 (1 << 28) +/* bits 29-31 reserved */ + +/** + * RI hysteresis control register 1 + * + * The RI_HYSCR1 register is used to enable/disable the hysteresis of the input + * Schmitt trigger of ports A and B. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_HYSCR1_PA(x) (x) +#define RI_HYSCR1_PB(x) (x << 16) + +/** + * RI hysteresis control register 2 + * + * RI_HYSCR2 register allows to enable/disable hysteresis of input Schmitt + * trigger of ports C and D. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_HYSCR2_PC(x) (x) +#define RI_HYSCR2_PD(x) (x << 16) + +/** + * RI hysteresis control register 3 + * + * The RI_HYSCR3 register is used to enable/disable the hysteresis of the input + * Schmitt trigger of the entire port E and F. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_HYSCR3_PE(x) (x) +#define RI_HYSCR3_PF(x) (x << 16) + +/** + * RI hysteresis control register 4 + * + * The RI_HYSCR4 register is used to enable/disable the hysteresis of the input + * Schmitt trigger of the entire port G. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_HYSCR2_PG(x) (x) +/* bits 16-31 reserved */ + +/** + * Analog switch mode register (RI_ASMR1) + * + * The RI_ASMR1 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used to select if analog switches of port A are to be controlled + * by the timer OC or through the ADC interface or RI_ASCRx registers. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_ASMR1_PA(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel mask register (RI_CMR1) + * + * RI_CMR1 is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices only and is + * used to mask a port A channel designated as a timer input capture (after + * acquisition completion to avoid triggering multiple detections). + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CMR1_PA(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel identification for capture register (RI_CICR1) + * + * The RI_CICR1 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used when analog switches are controlled by a timer OC. RI_CICR1 + * allows a channel to be identified for timer input capture. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CICR1_PA(x) (x) +/* bits 16-31 reserved */ + +/** + * Analog switch mode register (RI_ASMR2) + * + * The RI_ASMR2 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used to select if analog switches of port B are to be controlled + * by the timer OC or through the ADC interface or RI_ASCRx registers. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_ASMR2_PB(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel mask register (RI_CMR2) + * + * RI_CMR2 is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices only and is + * used to mask a port B channel designated as a timer input capture (after + * acquisition completion to avoid triggering multiple detections). + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CMR2_PB(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel identification for capture register (RI_CICR2) + * + * The RI_CICR2 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used when analog switches are controlled by a timer OC. RI_CICR2 + * allows a channel to be identified for timer input capture. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CICR2_PB(x) (x) +/* bits 16-31 reserved */ + +/** + * Analog switch mode register (RI_ASMR3) + * + * The RI_ASMR3 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used to select if analog switches of port C are to be controlled + * by the timer OC or through the ADC interface or RI_ASCRx registers. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_ASMR3_PC(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel mask register (RI_CMR3) + * + * RI_CMR3 is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices only and is + * used to mask a port C channel designated as a timer input capture (after + * acquisition completion to avoid triggering multiple detections). + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CMR3_PC(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel identification for capture register (RI_CICR3) + * + * The RI_CICR3 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used when analog switches are controlled by a timer OC. RI_CICR3 + * allows a channel to be identified for timer input capture. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CICR3_PC(x) (x) +/* bits 16-31 reserved */ + +/** + * Analog switch mode register (RI_ASMR4) + * + * The RI_ASMR4 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used to select if analog switches of port F are to be controlled + * by the timer OC or through the ADC interface or RI_ASCRx registers. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_ASMR4_PF(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel mask register (RI_CMRF) + * + * RI_CMR4 is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices only and is + * used to mask a port F channel designated as a timer input capture (after + * acquisition completion to avoid triggering multiple detections). + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CMR4_PF(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel identification for capture register (RI_CICR4) + * + * The RI_CICR4 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used when analog switches are controlled by a timer OC. RI_CICR4 + * allows a channel to be identified for timer input capture. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CICR4_PF(x) (x) +/* bits 16-31 reserved */ + +/** + * Analog switch mode register (RI_ASMR5) + * + * The RI_ASMR5 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used to select if analog switches of port G are to be controlled + * by the timer OC or through the ADC interface or RI_ASCRx registers. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_ASMR5_PG(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel mask register (RI_CMR5) + * + * RI_CMR1 is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices only and is + * used to mask a port G channel designated as a timer input capture (after + * acquisition completion to avoid triggering multiple detections). + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CMR5_PG(x) (x) +/* bits 16-31 reserved */ + +/** + * Channel identification for capture register (RI_CICR5) + * + * The RI_CICR5 register is available in Cat.3, Cat.4, Cat.5 and Cat.6 devices + * only and is used when analog switches are controlled by a timer OC. RI_CICR5 + * allows a channel to be identified for timer input capture. + * + * GPIO0-GPIO15 defines should be used as parameters. + */ +#define RI_CICR5_PG(x) (x) +/* bits 16-31 reserved */ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rtc.h new file mode 100644 index 00000000..3ba885c2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/rtc.h @@ -0,0 +1,36 @@ +/** @defgroup rtc_defines RTC Defines + +@brief Defined Constants and Types for the STM32L1xx RTC + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/spi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/spi.h new file mode 100644 index 00000000..0db17fc2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/spi.h @@ -0,0 +1,37 @@ +/** @defgroup spi_defines SPI Defines + +@brief Defined Constants and Types for the STM32L1xx SPI + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SPI_H +#define LIBOPENCM3_SPI_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/st_usbfs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/st_usbfs.h new file mode 100644 index 00000000..7da73f2a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/st_usbfs.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +# error Do not include directly ! +#else + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/syscfg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/syscfg.h new file mode 100644 index 00000000..b2e4991d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/syscfg.h @@ -0,0 +1,41 @@ +/** @defgroup syscfg_defines SYSCFG Defines + * + * @ingroup STM32L1xx_defines + * + * @brief Defined Constants and Types for the STM32L1xx Sysconfig + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SYSCFG_H +#define LIBOPENCM3_SYSCFG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/timer.h new file mode 100644 index 00000000..f2e3cd6d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/timer.h @@ -0,0 +1,89 @@ +/** @defgroup timer_defines Timer Defines + +@brief libopencm3 Defined Constants and Types for the STM32L1xx Timers + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 8 March 2013 + +@author @htmlonly © @endhtmlonly 2011 Fergus Noble + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +/* + * TIM2 and TIM5 are now 32bit and the following registers are now 32-bit wide: + * CNT, ARR, CCR1, CCR2, CCR3, CCR4 + */ + +/* Timer 2/3 option register (TIMx_OR) */ +#define TIM_OR(tim_base) MMIO32((tim_base) + 0x50) +#define TIM2_OR TIM_OR(TIM2) +#define TIM3_OR TIM_OR(TIM3) + +/* --- TIMx_OR values ---------------------------------------------------- */ + +/* ITR1_RMP */ +/****************************************************************************/ +/** @defgroup tim2_opt_trigger_remap TIM2_OR Timer 2 Option Register Internal +Trigger 1 Remap +@ingroup timer_defines + +@{*/ +/** Internal Trigger 1 remapped to timer 10 output compare */ +#define TIM2_OR_ITR1_RMP_TIM10_OC (0x0 << 0) +/** Internal Trigger 1 remapped to timer 5 TGO */ +#define TIM2_OR_ITR1_RMP_TIM5_TGO (0x1 << 0) +/**@}*/ +#define TIM3_OR_ITR1_RMP_MASK (0x1 << 0) + +/* --- TIMx_OR values ---------------------------------------------------- */ + +/* ITR2_RMP */ +/****************************************************************************/ +/** @defgroup tim3_opt_trigger_remap TIM3_OR Timer 3 Option Register Internal Trigger 2 Remap +@ingroup timer_defines + +@{*/ +/** Internal Trigger 1 remapped to timer 11 output compare */ +#define TIM3_OR_ITR2_RMP_TIM8_TRGOU (0x0 << 0) +/** Internal Trigger 1 remapped to timer 5 TGO */ +#define TIM3_OR_ITR2_RMP_PTP (0x1 << 0) +/**@}*/ +#define TIM3_OR_ITR2_RMP_MASK (0x1 << 0) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void timer_set_option(uint32_t timer_peripheral, uint32_t option); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/usart.h new file mode 100644 index 00000000..6fdce0e9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l1/usart.h @@ -0,0 +1,37 @@ +/** @defgroup usart_defines USART Defines + +@brief Defined Constants and Types for the STM32L1xx USART + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_USART_H +#define LIBOPENCM3_USART_H + +#include + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/adc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/adc.h new file mode 100644 index 00000000..e01852fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/adc.h @@ -0,0 +1,89 @@ +/** @defgroup adc_defines ADC Defines + * + * @brief Defined Constants and Types for the STM32L4xx Analog to Digital + * Converter + * + * @ingroup STM32L4xx_defines + * + * @version 1.0.0 + * + * @date 24 Oct 2015 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include +#include + +/** @defgroup adc_reg_base ADC register base addresses + * @ingroup adc_defines + * + *@{*/ +#define ADC1 ADC1_BASE +#define ADC2 ADC2_BASE +#define ADC3 ADC3_BASE +/**@}*/ + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_VREF 0 +#define ADC_CHANNEL_TEMP 17 +#define ADC_CHANNEL_VBAT 18 +/**@}*/ + +/* ADC_CR Values ------------------------------------------------------------*/ + +/* DEEPPWD: Deep power down */ +#define ADC_CR_DEEPPWD (1 << 29) + +/* ADVREGEN: Voltage regulator enable bit */ +#define ADC_CR_ADVREGEN (1 << 28) + + +/****************************************************************************/ +/* ADC_SMPRx ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample ADC Sample Time Selection values +@ingroup adc_defines + +@{*/ +#define ADC_SMPR_SMP_2DOT5CYC 0x0 +#define ADC_SMPR_SMP_6DOT5CYC 0x1 +#define ADC_SMPR_SMP_12DOT5CYC 0x2 +#define ADC_SMPR_SMP_24DOT5CYC 0x3 +#define ADC_SMPR_SMP_47DOT5CYC 0x4 +#define ADC_SMPR_SMP_92DOT5CYC 0x5 +#define ADC_SMPR_SMP_247DOT5CYC 0x6 +#define ADC_SMPR_SMP_640DOT5CYC 0x7 +/**@}*/ + + +BEGIN_DECLS + + +END_DECLS + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/doc-stm32l4.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/doc-stm32l4.h new file mode 100644 index 00000000..ec4ad09e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/doc-stm32l4.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 STM32L4 + +@version 1.0.0 + +@date 12 February 2015 + +API documentation for ST Microelectronics STM32L4 Cortex M4 series. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32L4xx STM32L4xx +Libraries for ST Microelectronics STM32L4xx series. + +@version 1.0.0 + +@date 12 February 2015 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup STM32L4xx_defines STM32L4xx Defines + +@brief Defined Constants and Types for the STM32L4xx series + +@version 1.0.0 + +@date 12 February 2015 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/flash.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/flash.h new file mode 100644 index 00000000..fa76e5fe --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/flash.h @@ -0,0 +1,254 @@ +/** @defgroup flash_defines FLASH Defines + * + * @ingroup STM32L4xx_defines + * + * @brief Defined Constants and Types for the STM32L4xx Flash Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2016 Benjamin Levine + * + * @date 12 February 2016 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * For details see: + * RM0351 Reference manual: STM32L4x6 advanced ARM®-based 32-bit MCUs + * December 2015, Doc ID 024597 Rev 3 + */ + +/**@{*/ +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) +#define FLASH_PDKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) +#define FLASH_KEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) +#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) +#define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) +#define FLASH_CR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_ECCR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x18) +#define FLASH_OPTR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x20) +#define FLASH_PCROP1SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x24) +#define FLASH_PCROP1ER MMIO32(FLASH_MEM_INTERFACE_BASE + 0x28) +#define FLASH_WRP1AR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x2C) +#define FLASH_WRP1BR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x30) +#define FLASH_PCROP2SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x44) +#define FLASH_PCROP2ER MMIO32(FLASH_MEM_INTERFACE_BASE + 0x48) +#define FLASH_WRP2AR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x4C) +#define FLASH_WRP2BR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x50) + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +#define FLASH_ACR_SLEEP_PD (1 << 14) +#define FLASH_ACR_RUN_PD (1 << 13) +#define FLASH_ACR_DCRST (1 << 12) +#define FLASH_ACR_ICRST (1 << 11) +#define FLASH_ACR_DCEN (1 << 10) +#define FLASH_ACR_ICEN (1 << 9) +#define FLASH_ACR_PRFTEN (1 << 8) + +#define FLASH_ACR_LATENCY_SHIFT 0 +#define FLASH_ACR_LATENCY_MASK 0x03 + +#define FLASH_ACR_LATENCY_0WS 0x00 +#define FLASH_ACR_LATENCY_1WS 0x01 +#define FLASH_ACR_LATENCY_2WS 0x02 +#define FLASH_ACR_LATENCY_3WS 0x03 + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_BSY (1 << 16) +#define FLASH_SR_OPTVERR (1 << 15) +#define FLASH_SR_RDERR (1 << 14) +#define FLASH_SR_FASTERR (1 << 9) +#define FLASH_SR_MISERR (1 << 8) +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_SR_SIZERR (1 << 6) +#define FLASH_SR_PGAERR (1 << 5) +#define FLASH_SR_WRPERR (1 << 4) +#define FLASH_SR_PROGERR (1 << 3) +#define FLASH_SR_OPERR (1 << 1) +#define FLASH_SR_EOP (1 << 0) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +#define FLASH_CR_LOCK (1 << 31) +#define FLASH_CR_OPTLOCK (1 << 30) +#define FLASH_CR_OBL_LAUNCH (1 << 27) +#define FLASH_CR_RDERRIE (1 << 26) +#define FLASH_CR_ERRIE (1 << 25) +#define FLASH_CR_EOPIE (1 << 24) +#define FLASH_CR_FSTPG (1 << 18) +#define FLASH_CR_OPTSTRT (1 << 17) +#define FLASH_CR_START (1 << 16) +#define FLASH_CR_MER2 (1 << 15) +#define FLASH_CR_BKER (1 << 11) +#define FLASH_CR_MER1 (1 << 2) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_PG (1 << 0) + +#define FLASH_CR_PNB_SHIFT 3 +#define FLASH_CR_PNB_MASK 0xff + +/* --- FLASH_ECCR values -------------------------------------------------- */ + +#define FLASH_ECCR_ECCD (1 << 31) +#define FLASH_ECCR_ECCC (1 << 30) +#define FLASH_ECCR_ECCIE (1 << 24) +#define FLASH_ECCR_SYSF_ECC (1 << 20) +#define FLASH_ECCR_BK_ECC (1 << 19) + +#define FLASH_ECCR_ADDR_ECC_SHIFT 0 +#define FLASH_ECCR_ADDR_ECC_MASK 0x7ffff + +/* --- FLASH_OPTR values -------------------------------------------------- */ + +#define FLASH_OPTR_SRAM2_RST (1 << 25) +#define FLASH_OPTR_SRAM2_PE (1 << 24) +#define FLASH_OPTR_nBOOT1 (1 << 23) +#define FLASH_OPTR_DUALBANK (1 << 21) +#define FLASH_OPTR_BFB2 (1 << 20) +#define FLASH_OPTR_WWDG_SW (1 << 19) +#define FLASH_OPTR_IWDG_STDBY (1 << 18) +#define FLASH_OPTR_IWDG_STOP (1 << 17) +#define FLASH_OPTR_IDWG_SW (1 << 16) +#define FLASH_OPTR_nRST_SHDW (1 << 14) +#define FLASH_OPTR_nRST_STDBY (1 << 13) +#define FLASH_OPTR_nRST_STOP (1 << 12) + +#define FLASH_OPTR_BOR_SHIFT 8 +#define FLASH_OPTR_BOR_MASK 0x700 +#define FLASH_OPTR_BOR_LEVEL_0 0 +#define FLASH_OPTR_BOR_LEVEL_1 1 +#define FLASH_OPTR_BOR_LEVEL_2 2 +#define FLASH_OPTR_BOR_LEVEL_3 3 +#define FLASH_OPTR_BOR_LEVEL_4 4 + +#define FLASH_OPTR_RDP_SHIFT 0 +#define FLASH_OPTR_RDP_MASK 0xff +#define FLASH_OPTR_RDP_LEVEL_0 0xAA +#define FLASH_OPTR_RDP_LEVEL_1 0xBB +#define FLASH_OPTR_RDP_LEVEL_2 0xCC + +/* --- FLASH_PCROP1SR values -------------------------------------------------- */ + +#define FLASH_PCROP1SR_PCROP1_STRT_SHIFT 0 +#define FLASH_PCROP1SR_PCROP1_STRT_MASK 0xffff + +/* --- FLASH_PCROP1ER values -------------------------------------------------- */ + +#define FLASH_PCROP1ER_PCROP_RDP (1 << 31) +#define FLASH_PCROP1ER_PCROP1_END_SHIFT 0 +#define FLASH_PCROP1ER_PCROP1_END_MASK 0xffff + +/* --- FLASH_WRP1AR values -------------------------------------------------- */ + +#define FLASH_WRP1AR_WRP1A_END_SHIFT 16 +#define FLASH_WRP1AR_WRP1A_END_MASK 0xff + +#define FLASH_WRP1AR_WRP1A_STRT_SHIFT 0 +#define FLASH_WRP1AR_WRP1A_STRT_MASK 0xff + +/* --- FLASH_WRP1BR values -------------------------------------------------- */ + +#define FLASH_WRP1BR_WRP1B_END_SHIFT 16 +#define FLASH_WRP1BR_WRP1B_END_MASK 0xff + +#define FLASH_WRP1BR_WRP1B_STRT_SHIFT 0 +#define FLASH_WRP1BR_WRP1B_STRT_MASK 0xff + +/* --- FLASH_PCROP2SR values -------------------------------------------------- */ + +#define FLASH_PCROP2SR_PCROP2_STRT_SHIFT 0 +#define FLASH_PCROP2SR_PCROP2_STRT_MASK 0xffff + +/* --- FLASH_PCROP2ER values -------------------------------------------------- */ + +#define FLASH_PCROP2ER_PCROP2_END_SHIFT 0 +#define FLASH_PCROP2ER_PCROP2_END_MASK 0xffff + +/* --- FLASH_WRP2AR values -------------------------------------------------- */ + +#define FLASH_WRP2AR_WRP2A_END_SHIFT 16 +#define FLASH_WRP2AR_WRP2A_END_MASK 0xff + +#define FLASH_WRP2AR_WRP2A_STRT_SHIFT 0 +#define FLASH_WRP2AR_WRP2A_STRT_MASK 0xff + +/* --- FLASH_WRP2BR values -------------------------------------------------- */ + +#define FLASH_WRP2BR_WRP2B_END_SHIFT 16 +#define FLASH_WRP2BR_WRP2B_END_MASK 0xff + +#define FLASH_WRP2BR_WRP2B_STRT_SHIFT 0 +#define FLASH_WRP2BR_WRP2B_STRT_MASK 0xff + +/* --- FLASH Keys -----------------------------------------------------------*/ + +#define FLASH_PDKEYR_PDKEY1 ((uint32_t)0x04152637) +#define FLASH_PDKEYR_PDKEY2 ((uint32_t)0xfafbfcfd) + +#define FLASH_KEYR_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEYR_KEY2 ((uint32_t)0xcdef89ab) + +#define FLASH_OPTKEYR_KEY1 ((uint32_t)0x08192a3b) +#define FLASH_OPTKEYR_KEY2 ((uint32_t)0x4c5d6e7f) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_set_ws(uint32_t ws); +void flash_unlock(void); +void flash_lock(void); +void flash_clear_pgperr_flag(void); +void flash_clear_eop_flag(void); +void flash_clear_bsy_flag(void); +void flash_wait_for_last_operation(void); +void flash_dcache_enable(void); +void flash_dcache_disable(void); +void flash_icache_enable(void); +void flash_icache_disable(void); +void flash_prefetch_enable(void); +void flash_prefetch_disable(void); +void flash_dcache_reset(void); +void flash_icache_reset(void); +void flash_clear_pgserr_flag(void); +void flash_clear_pgaerr_flag(void); +void flash_clear_wrperr_flag(void); +void flash_clear_status_flags(void); +void flash_unlock_option_bytes(void); +void flash_lock_option_bytes(void); +void flash_program_word(uint32_t address, uint32_t data); +void flash_program(uint32_t address, uint8_t *data, uint32_t len); +void flash_erase_sector(uint8_t sector); +void flash_erase_all_sectors(void); +void flash_program_option_bytes(uint32_t data); + +END_DECLS + +#endif +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/gpio.h new file mode 100644 index 00000000..15dc7b11 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/gpio.h @@ -0,0 +1,92 @@ +/** @defgroup gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the STM32L4xx General Purpose I/O + * + * @ingroup STM32L4xx_defines + * + * @version 1.0.0 + * + * @date 12 November 2015 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define GPIO_BRR(port) MMIO32((port) + 0x28) +#define GPIOA_BRR GPIO_BRR(GPIOA) +#define GPIOB_BRR GPIO_BRR(GPIOB) +#define GPIOC_BRR GPIO_BRR(GPIOC) +#define GPIOD_BRR GPIO_BRR(GPIOD) +#define GPIOE_BRR GPIO_BRR(GPIOE) +#define GPIOF_BRR GPIO_BRR(GPIOF) +#define GPIOG_BRR GPIO_BRR(GPIOG) +#define GPIOH_BRR GPIO_BRR(GPIOH) + +/* Analog Switch Control Register */ +#define GPIO_ASCR(port) MMIO32((port) + 0x2c) +#define GPIOA_ASCR GPIO_ASCR(GPIOA) +#define GPIOB_ASCR GPIO_ASCR(GPIOB) +#define GPIOC_ASCR GPIO_ASCR(GPIOC) +#define GPIOD_ASCR GPIO_ASCR(GPIOD) +#define GPIOE_ASCR GPIO_ASCR(GPIOE) +#define GPIOF_ASCR GPIO_ASCR(GPIOF) +#define GPIOG_ASCR GPIO_ASCR(GPIOG) +#define GPIOH_ASCR GPIO_ASCR(GPIOH) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/** @defgroup gpio_speed GPIO Output Pin Speed +@ingroup gpio_defines +@{*/ +#define GPIO_OSPEED_LOW 0x0 +#define GPIO_OSPEED_MED 0x1 +#define GPIO_OSPEED_FAST 0x2 +#define GPIO_OSPEED_HIGH 0x3 +/**@}*/ + +/*****************************************************************************/ +/* API definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + +BEGIN_DECLS + +END_DECLS + +#endif +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/i2c.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/i2c.h new file mode 100644 index 00000000..27a0f362 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/i2c.h @@ -0,0 +1,43 @@ +/** @defgroup i2c_defines I2C Defines + +@brief Defined Constants and Types for the STM32L4xx I2C + +@ingroup STM32L4xx_defines + +@version 1.0.0 + +@date 12 October 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +/**@{*/ + +#define I2C3 I2C3_BASE + +/**@}*/ + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/irq.json new file mode 100644 index 00000000..2e575ac4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/irq.json @@ -0,0 +1,89 @@ +{ + "irqs": [ + "wwdg", + "pvd_pvm", + "tamp_stamp", + "rtc_wkup", + "flash", + "rcc", + "exti0", + "exti1", + "exti2", + "exti3", + "exti4", + "dma1_channel1", + "dma1_channel2", + "dma1_channel3", + "dma1_channel4", + "dma1_channel5", + "dma1_channel6", + "dma1_channel7", + "adc1_2", + "can1_tx", + "can1_rx0", + "can1_rx1", + "can1_sce", + "exti9_5", + "tim1_brk_tim15", + "tim1_up_tim16", + "tim1_trg_com_tim17", + "tim1_cc", + "tim2", + "tim3", + "tim4", + "i2c1_ev", + "i2c1_er", + "i2c2_ev", + "i2c2_er", + "spi1", + "spi2", + "usart1", + "usart2", + "usart3", + "exti15_10", + "rtc_alarm", + "dfsdm3", + "tim8_brk", + "tim8_up", + "tim8_trg_com", + "tim8_cc", + "adc3", + "fmc", + "sdmmc1", + "tim5", + "spi3", + "uart4", + "uart5", + "tim6_dacunder", + "tim7", + "dma2_channel1", + "dma2_channel2", + "dma2_channel3", + "dma2_channel4", + "dma2_channel5", + "dfsdm0", + "dfsdm1", + "dfsdm2", + "comp", + "lptim1", + "lptim2", + "otg_fs", + "dma2_channel6", + "dma2_channel7", + "lpuart1", + "quadspi", + "i2c3_ev", + "i2c3_er", + "sai1", + "sai2", + "swpmi1", + "tsc", + "lcd", + "aes", + "rng", + "fpu" + ], + "partname_humanreadable": "STM32 L4 series", + "partname_doxygen": "STM32L4", + "includeguard": "LIBOPENCM3_STM32_L4_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/memorymap.h new file mode 100644 index 00000000..f5d9e02c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/memorymap.h @@ -0,0 +1,126 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32 specific peripheral definitions ------------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define FMC1_BANK_BASE (0x60000000U) +#define FMC3_BANK_BASE (0x80000000U) +#define QUADSPI_BANK_BASE (0x90000000U) +#define FMC_QUADSPI_BASE (0xA0000000U) +#define INFO_BASE (0x1fff0000U) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x20000) +#define PERIPH_BASE_AHB2 (0x48000000U) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define LCD_BASE (PERIPH_BASE_APB1 + 0x2400) +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define UART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define UART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define I2C3_BASE (PERIPH_BASE_APB1 + 0x5c00) +#define CAN1_BASE (PERIPH_BASE_APB1 + 0x6400) +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC1_BASE (PERIPH_BASE_APB1 + 0x7400) +#define OPAMP_BASE (PERIPH_BASE_APB1 + 0x7800) +#define LPTIM1_BASE (PERIPH_BASE_APB1 + 0x7c00) +#define LPUART1_BASE (PERIPH_BASE_APB1 + 0x8000) +#define SWPMI1_BASE (PERIPH_BASE_APB1 + 0x8800) +#define LPTIM2_BASE (PERIPH_BASE_APB1 + 0x9400) + + +/* APB2 */ +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x0000) +#define VREFBUF_BASE (PERIPH_BASE_APB2 + 0x0030) +#define COMP_BASE (PERIPH_BASE_APB2 + 0x0200) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x0400) +#define FIREWALL_BASE (PERIPH_BASE_APB2 + 0x1C00) +#define SDMMC1_BASE (PERIPH_BASE_APB2 + 0x2800) +#define TIM1_BASE (PERIPH_BASE_APB2 + 0x2C00) +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +#define TIM8_BASE (PERIPH_BASE_APB2 + 0x3400) +#define USART1_BASE (PERIPH_BASE_APB2 + 0x3800) +#define TIM15_BASE (PERIPH_BASE_APB2 + 0x4000) +#define TIM16_BASE (PERIPH_BASE_APB2 + 0x4400) +#define TIM17_BASE (PERIPH_BASE_APB2 + 0x4800) +#define SAI1_BASE (PERIPH_BASE_APB2 + 0x5400) +#define SAI2_BASE (PERIPH_BASE_APB2 + 0x5800) +#define DFSDM_BASE (PERIPH_BASE_APB2 + 0x6000) + +/* AHB1 */ +#define DMA1_BASE (PERIPH_BASE_AHB1 + 0x0000) +#define DMA2_BASE (PERIPH_BASE_AHB1 + 0x0400) +#define RCC_BASE (PERIPH_BASE_AHB1 + 0x1000) +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x2000) +#define CRC_BASE (PERIPH_BASE_AHB1 + 0x3000) +#define TSC_BASE (PERIPH_BASE_AHB1 + 0x4000) + +/* AHB2 */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB2 + 0x0000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB2 + 0x0400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB2 + 0x0800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB2 + 0x0c00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB2 + 0x1000) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB2 + 0x1400) +#define GPIO_PORT_G_BASE (PERIPH_BASE_AHB2 + 0x1800) +#define GPIO_PORT_H_BASE (PERIPH_BASE_AHB2 + 0x1c00) +/* Still AHB2, good job ST */ +#define OTG_FS_BASE (0x50000000U + 0x00000) +#define ADC1_BASE (0x50000000U + 0x40000) +#define AES_BASE (0x50000000U + 0x60000) +#define RNG_BASE (0x50000000U + 0x60800) + +/* Private peripherals */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x75e0) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x7590) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 0x14) +#define DESIG_PACKAGE MMIO16((INFO_BASE + 0x7500)) + +/* ST provided factory calibration values @ 3.0V */ +#define ST_VREFINT_CAL MMIO16((INFO_BASE + 0x75aa)) +#define ST_TSENSE_CAL1_30C MMIO16((INFO_BASE + 0x75a8)) +#define ST_TSENSE_CAL2_110C MMIO16((INFO_BASE + 0x75ca)) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/pwr.h new file mode 100644 index 00000000..f4d2b911 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/pwr.h @@ -0,0 +1,177 @@ +/** @defgroup pwr_defines PWR Defines + * + * @ingroup STM32L4xx_defines + * + * @brief Defined Constants and Types for the STM32L4xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2016 Benjamin Levine + * + * @date 12 February 2016 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA PWR.H +The order of header inclusion is important. pwr.h includes the device +specific memorymap.h header before including this header file.*/ + +/**@{*/ +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + + + +/* --- PWR registers ------------------------------------------------------- */ + +#define PWR_CR1 MMIO32(POWER_CONTROL_BASE + 0x00) +#define PWR_CR2 MMIO32(POWER_CONTROL_BASE + 0x04) +#define PWR_CR3 MMIO32(POWER_CONTROL_BASE + 0x08) +#define PWR_CR4 MMIO32(POWER_CONTROL_BASE + 0x0C) +#define PWR_SR1 MMIO32(POWER_CONTROL_BASE + 0x10) +#define PWR_SR2 MMIO32(POWER_CONTROL_BASE + 0x14) +#define PWR_SCR MMIO32(POWER_CONTROL_BASE + 0x18) + +#define PWR_PORT_A MMIO32(POWER_CONTROL_BASE + 0x20) +#define PWR_PORT_B MMIO32(POWER_CONTROL_BASE + 0x28) +#define PWR_PORT_C MMIO32(POWER_CONTROL_BASE + 0x30) +#define PWR_PORT_D MMIO32(POWER_CONTROL_BASE + 0x38) +#define PWR_PORT_E MMIO32(POWER_CONTROL_BASE + 0x40) +#define PWR_PORT_F MMIO32(POWER_CONTROL_BASE + 0x48) +#define PWR_PORT_G MMIO32(POWER_CONTROL_BASE + 0x50) +#define PWR_PORT_H MMIO32(POWER_CONTROL_BASE + 0x58) + +#define PWR_PUCR(pwr_port) MMIO32((pwr_port) + 0x00) +#define PWR_PDCR(pwr_port) MMIO32((pwr_port) + 0x04) + +/* --- PWR_CR1 values ------------------------------------------------------- */ + +#define PWR_CR1_LPR (1 << 14) + +#define PWR_CR1_VOS_SHIFT 9 +#define PWR_CR1_VOS_MASK 0x3 +#define PWR_CR1_VOS_RANGE_1 1 +#define PWR_CR1_VOS_RANGE_2 2 + +#define PWR_CR1_DBP (1 << 8) + +#define PWR_CR1_LPMS_SHIFT 0 +#define PWR_CR1_LPMS_MASK 0x07 +#define PWR_CR1_LPMS_STOP_0 0 +#define PWR_CR1_LPMS_STOP_1 1 +#define PWR_CR1_LPMS_STOP_2 2 +#define PWR_CR1_LPMS_STANDBY 3 +#define PWR_CR1_LPMS_SHUTDOWN 4 + +/* --- PWR_CR2 values ------------------------------------------------------- */ + +#define PWR_CR2_USV (1 << 10) +#define PWR_CR2_IOSV (1 << 9) +#define PWR_CR2_PVME4 (1 << 7) +#define PWR_CR2_PVME3 (1 << 6) +#define PWR_CR2_PVME2 (1 << 5) +#define PWR_CR2_PVME1 (1 << 4) + +#define PWR_CR2_PLS_SHIFT 1 +#define PWR_CR2_PLS_MASK 0x07 +/** @defgroup pwr_pls PVD level selection +@ingroup STM32L4_pwr_defines +@{*/ +#define PWR_CR2_PLS_2V0 0x00 +#define PWR_CR2_PLS_2V2 0x01 +#define PWR_CR2_PLS_2V4 0x02 +#define PWR_CR2_PLS_2V5 0x03 +#define PWR_CR2_PLS_2V6 0x04 +#define PWR_CR2_PLS_2V8 0x05 +#define PWR_CR2_PLS_2V9 0x06 +#define PWR_CR2_PLS_PVD_IN 0x07 +/**@}*/ + +#define PWR_CR2_PVDE (1 << 0) + +/* --- PWR_CR3 values ------------------------------------------------------- */ + +#define PWR_CR3_EIWUL (1 << 15) +#define PWR_CR3_APC (1 << 10) +#define PWR_CR3_RRS (1 << 8) +#define PWR_CR3_EWUP5 (1 << 4) +#define PWR_CR3_EWUP4 (1 << 3) +#define PWR_CR3_EWUP3 (1 << 2) +#define PWR_CR3_EWUP2 (1 << 1) +#define PWR_CR3_EWUP1 (1 << 0) + +/* --- PWR_CR4 values ------------------------------------------------------- */ + +#define PWR_CR4_VBRS (1 << 9) +#define PWR_CR4_VBE (1 << 8) +#define PWR_CR4_WP5 (1 << 4) +#define PWR_CR4_WP4 (1 << 3) +#define PWR_CR4_WP3 (1 << 2) +#define PWR_CR4_WP2 (1 << 1) +#define PWR_CR4_WP1 (1 << 0) + +/* --- PWR_SR1 values ------------------------------------------------------- */ + +#define PWR_SR1_WUFI (1 << 15) +#define PWR_SR1_SBF (1 << 8) +#define PWR_SR1_WUF5 (1 << 4) +#define PWR_SR1_WUF4 (1 << 3) +#define PWR_SR1_WUF3 (1 << 2) +#define PWR_SR1_WUF2 (1 << 1) +#define PWR_SR1_WUF1 (1 << 0) + +/* --- PWR_SR2 values ------------------------------------------------------- */ + +#define PWR_SR2_PVMO4 (1 << 15) +#define PWR_SR2_PVMO3 (1 << 14) +#define PWR_SR2_PVMO2 (1 << 13) +#define PWR_SR2_PVMO1 (1 << 12) +#define PWR_SR2_PVDO (1 << 11) +#define PWR_SR2_VOSF (1 << 10) +#define PWR_SR2_REGLPF (1 << 9) +#define PWR_SR2_REGLPS (1 << 8) + +/* --- PWR_SCR values ------------------------------------------------------- */ + +#define PWR_SCR_CSBF (1 << 8) +#define PWR_SCR_CWUF5 (1 << 4) +#define PWR_SCR_CWUF4 (1 << 3) +#define PWR_SCR_CWUF3 (1 << 2) +#define PWR_SCR_CWUF2 (1 << 1) +#define PWR_SCR_CWUF1 (1 << 0) + +/* --- PWR function prototypes ------------------------------------------- */ + +enum pwr_vos_scale { + PWR_SCALE1, + PWR_SCALE2, +}; + +BEGIN_DECLS + +void pwr_set_vos_scale(enum pwr_vos_scale scale); + +END_DECLS + +#endif +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rcc.h new file mode 100644 index 00000000..84544187 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rcc.h @@ -0,0 +1,955 @@ +/** @defgroup rcc_defines RCC Defines + * + * @ingroup STM32L4xx_defines + * + * @brief Defined Constants and Types for the STM32L4xx Reset and Clock + * Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2015 Karl Palsson + * + * @date 12 November 2015 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +/**@{*/ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_ICSCR MMIO32(RCC_BASE + 0x04) +#define RCC_CFGR MMIO32(RCC_BASE + 0x08) +#define RCC_PLLCFGR MMIO32(RCC_BASE + 0x0c) +#define RCC_PLLSAI1_CFGR MMIO32(RCC_BASE + 0x10) +#define RCC_PLLSAI2_CFGR MMIO32(RCC_BASE + 0x14) +#define RCC_CIER MMIO32(RCC_BASE + 0x18) +#define RCC_CIFR MMIO32(RCC_BASE + 0x1c) +#define RCC_CICR MMIO32(RCC_BASE + 0x20) +#define RCC_AHB1RSTR_OFFSET 0x28 +#define RCC_AHB1RSTR MMIO32(RCC_BASE + RCC_AHB1RSTR_OFFSET) +#define RCC_AHB2RSTR_OFFSET 0x2c +#define RCC_AHB2RSTR MMIO32(RCC_BASE + RCC_AHB2RSTR_OFFSET) +#define RCC_AHB3RSTR_OFFSET 0x30 +#define RCC_AHB3RSTR MMIO32(RCC_BASE + RCC_AHB3RSTR_OFFSET) +#define RCC_APB1RSTR1_OFFSET 0x38 +#define RCC_APB1RSTR1 MMIO32(RCC_BASE + RCC_APB1RSTR1_OFFSET) +#define RCC_APB1RSTR2_OFFSET 0x3c +#define RCC_APB1RSTR2 MMIO32(RCC_BASE + RCC_APB1RSTR2_OFFSET) +#define RCC_APB2RSTR_OFFSET 0x40 +#define RCC_APB2RSTR MMIO32(RCC_BASE + RCC_APB2RSTR_OFFSET) +#define RCC_AHB1ENR_OFFSET 0x48 +#define RCC_AHB1ENR MMIO32(RCC_BASE + RCC_AHB1ENR_OFFSET) +#define RCC_AHB2ENR_OFFSET 0x4c +#define RCC_AHB2ENR MMIO32(RCC_BASE + RCC_AHB2ENR_OFFSET) +#define RCC_AHB3ENR_OFFSET 0x50 +#define RCC_AHB3ENR MMIO32(RCC_BASE + RCC_AHB3ENR_OFFSET) +#define RCC_APB1ENR1_OFFSET 0x58 +#define RCC_APB1ENR1 MMIO32(RCC_BASE + RCC_APB1ENR1_OFFSET) +#define RCC_APB1ENR2_OFFSET 0x5c +#define RCC_APB1ENR2 MMIO32(RCC_BASE + RCC_APB1ENR2_OFFSET) +#define RCC_APB2ENR_OFFSET 0x60 +#define RCC_APB2ENR MMIO32(RCC_BASE + RCC_APB2ENR_OFFSET) +#define RCC_AHB1SMENR_OFFSET 0x68 +#define RCC_AHB1SMENR MMIO32(RCC_BASE + RCC_AHB1SMENR_OFFSET) +#define RCC_AHB2SMENR_OFFSET 0x6c +#define RCC_AHB2SMENR MMIO32(RCC_BASE + RCC_AHB2SMENR_OFFSET) +#define RCC_AHB3SMENR_OFFSET 0x70 +#define RCC_AHB3SMENR MMIO32(RCC_BASE + RCC_AHB3SMENR_OFFSET) +#define RCC_APB1SMENR1_OFFSET 0x78 +#define RCC_APB1SMENR1 MMIO32(RCC_BASE + RCC_APB1SMENR1_OFFSET) +#define RCC_APB1SMENR2_OFFSET 0x7c +#define RCC_APB1SMENR2 MMIO32(RCC_BASE + RCC_APB1SMENR2_OFFSET) +#define RCC_APB2SMENR_OFFSET 0x80 +#define RCC_APB2SMENR MMIO32(RCC_BASE + RCC_APB2SMENR_OFFSET) +#define RCC_CCIPR MMIO32(RCC_BASE + 0x88) +#define RCC_BDCR MMIO32(RCC_BASE + 0x90) +#define RCC_CSR MMIO32(RCC_BASE + 0x94) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLSAI2RDY (1 << 29) +#define RCC_CR_PLLSAI2ON (1 << 28) +#define RCC_CR_PLLSAI1RDY (1 << 27) +#define RCC_CR_PLLSAI1ON (1 << 26) +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSIASFS (1 << 11) +#define RCC_CR_HSIRDY (1 << 10) +#define RCC_CR_HSIKERON (1 << 9) +#define RCC_CR_HSION (1 << 8) +/** @defgroup rcc_cr_msirange MSI Range + * @ingroup STM32L4xx_rcc_defines + * @brief Range of the MSI oscillator +Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, +1 MHz, 2 MHz, 4 MHz (default value), 8 MHz, 16 MHz, 24 MHz, 32 MHz and 48 MHz +@sa rcc_csr_msirange +@{*/ +#define RCC_CR_MSIRANGE_SHIFT 4 +#define RCC_CR_MSIRANGE_MASK 0xf +#define RCC_CR_MSIRANGE_100KHZ 0 +#define RCC_CR_MSIRANGE_200KHZ 1 +#define RCC_CR_MSIRANGE_400KHZ 2 +#define RCC_CR_MSIRANGE_800KHZ 3 +#define RCC_CR_MSIRANGE_1MHZ 4 +#define RCC_CR_MSIRANGE_2MHZ 5 +#define RCC_CR_MSIRANGE_4MHZ 6 +#define RCC_CR_MSIRANGE_8MHZ 7 +#define RCC_CR_MSIRANGE_16MHZ 8 +#define RCC_CR_MSIRANGE_24MHZ 9 +#define RCC_CR_MSIRANGE_32MHZ 10 +#define RCC_CR_MSIRANGE_48MHZ 11 +/*@}*/ +#define RCC_CR_MSIRGSEL (1 << 3) +#define RCC_CR_MSIPLLEN (1 << 2) +#define RCC_CR_MSIRDY (1 << 1) +#define RCC_CR_MSION (1 << 0) + + +/* --- RCC_ICSCR values ---------------------------------------------------- */ + +#define RCC_ICSCR_HSITRIM_SHIFT 24 +#define RCC_ICSCR_HSITRIM_MASK 0x1f +#define RCC_ICSCR_HSICAL_SHIFT 16 +#define RCC_ICSCR_HSICAL_MASK 0xff + +#define RCC_ICSCR_MSITRIM_SHIFT 8 +#define RCC_ICSCR_MSITRIM_MASK 0xff +#define RCC_ICSCR_MSICAL_SHIFT 0 +#define RCC_ICSCR_MSICAL_MASK 0xff + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +/* MCOPRE */ +#define RCC_CFGR_MCOPRE_DIV1 0 +#define RCC_CFGR_MCOPRE_DIV2 1 +#define RCC_CFGR_MCOPRE_DIV4 2 +#define RCC_CFGR_MCOPRE_DIV8 3 +#define RCC_CFGR_MCOPRE_DIV16 4 +#define RCC_CFGR_MCOPRE_SHIFT 28 +#define RCC_CFGR_MCOPRE_MASK 0x7 + +/* MCO: Microcontroller clock output */ +#define RCC_CFGR_MCO_NOCLK 0x0 +#define RCC_CFGR_MCO_SYSCLK 0x1 +#define RCC_CFGR_MCO_MSI 0x2 +#define RCC_CFGR_MCO_HSI16 0x3 +#define RCC_CFGR_MCO_HSE 0x4 +#define RCC_CFGR_MCO_PLL 0x5 +#define RCC_CFGR_MCO_LSI 0x6 +#define RCC_CFGR_MCO_LSE 0x7 +#define RCC_CFGR_MCO_SHIFT 24 +#define RCC_CFGR_MCO_MASK 0xf + +/* Wakeup from stop clock selection */ +#define RCC_CFGR_STOPWUCK_MSI (0 << 15) +#define RCC_CFGR_STOPWUCK_HSI16 (1 << 15) + +/* PPRE2: APB high-speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_NODIV 0x0 +#define RCC_CFGR_PPRE2_DIV2 0x4 +#define RCC_CFGR_PPRE2_DIV4 0x5 +#define RCC_CFGR_PPRE2_DIV8 0x6 +#define RCC_CFGR_PPRE2_DIV16 0x7 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE2_SHIFT 11 + +/* PPRE1: APB low-speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_NODIV 0x0 +#define RCC_CFGR_PPRE1_DIV2 0x4 +#define RCC_CFGR_PPRE1_DIV4 0x5 +#define RCC_CFGR_PPRE1_DIV8 0x6 +#define RCC_CFGR_PPRE1_DIV16 0x7 +#define RCC_CFGR_PPRE1_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 8 + +/* HPRE: AHB prescaler */ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 0x8 +#define RCC_CFGR_HPRE_DIV4 0x9 +#define RCC_CFGR_HPRE_DIV8 0xa +#define RCC_CFGR_HPRE_DIV16 0xb +#define RCC_CFGR_HPRE_DIV64 0xc +#define RCC_CFGR_HPRE_DIV128 0xd +#define RCC_CFGR_HPRE_DIV256 0xe +#define RCC_CFGR_HPRE_DIV512 0xf +#define RCC_CFGR_HPRE_MASK 0xf +#define RCC_CFGR_HPRE_SHIFT 4 + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_MSI 0x0 +#define RCC_CFGR_SWS_HSI16 0x1 +#define RCC_CFGR_SWS_HSE 0x2 +#define RCC_CFGR_SWS_PLL 0x3 +#define RCC_CFGR_SWS_MASK 0x3 +#define RCC_CFGR_SWS_SHIFT 2 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_MSI 0x0 +#define RCC_CFGR_SW_HSI16 0x1 +#define RCC_CFGR_SW_HSE 0x2 +#define RCC_CFGR_SW_PLL 0x3 +#define RCC_CFGR_SW_MASK 0x3 +#define RCC_CFGR_SW_SHIFT 0 + +/* --- RCC_PLLCFGR - PLL Configuration Register */ +#define RCC_PLLCFGR_PLLR_SHIFT 25 +#define RCC_PLLCFGR_PLLR_MASK 0x3 +#define RCC_PLLCFGR_PLLR_DIV2 0 +#define RCC_PLLCFGR_PLLR_DIV4 1 +#define RCC_PLLCFGR_PLLR_DIV6 2 +#define RCC_PLLCFGR_PLLR_DIV8 3 +#define RCC_PLLCFGR_PLLREN (1<<24) + +#define RCC_PLLCFGR_PLLQ_SHIFT 21 +#define RCC_PLLCFGR_PLLQ_MASK 0x3 +#define RCC_PLLCFGR_PLLQ_DIV2 0 +#define RCC_PLLCFGR_PLLQ_DIV4 1 +#define RCC_PLLCFGR_PLLQ_DIV6 2 +#define RCC_PLLCFGR_PLLQ_DIV8 3 +#define RCC_PLLCFGR_PLLQEN (1 << 20) + +/* Division for PLLSAI3CLK, 0 == 7, 1 == 17 */ +#define RCC_PLLCFGR_PLLP (1 << 17) +#define RCC_PLLCFGR_PLLP_DIV7 0 +#define RCC_PLLCFGR_PLLP_DIV17 RCC_PLLCFGR_PLLP +#define RCC_PLLPEN (1 << 16) + +/** @defgroup rcc_pllcfgr_plln RCC_PLLCFGR PLLN values +@ingroup STM32L4xx_rcc_defines + * Allowed values 8 <= n <= 86 +@{*/ +#define RCC_PLLCFGR_PLLN_SHIFT 0x8 +#define RCC_PLLCFGR_PLLN_MASK 0x7f +/*@}*/ + +/** @defgroup rcc_pllcfgr_pllm RCC_PLLCFGR PLLM values +@ingroup STM32L4xx_rcc_defines + * Allowed values 1 <= m <= 8 +@{*/ +#define RCC_PLLCFGR_PLLM_SHIFT 0x4 +#define RCC_PLLCFGR_PLLM_MASK 0x7 +#define RCC_PLLCFGR_PLLM(x) ((x)-1) +/*@}*/ + +#define RCC_PLLCFGR_PLLSRC_SHIFT 0 +#define RCC_PLLCFGR_PLLSRC_MASK 0x3 +#define RCC_PLLCFGR_PLLSRC_NONE 0 +#define RCC_PLLCFGR_PLLSRC_MSI 1 +#define RCC_PLLCFGR_PLLSRC_HSI16 2 +#define RCC_PLLCFGR_PLLSRC_HSE 3 + +/* --- RCC_PLLSAI1CFGR ----------------------------------------------------- */ +/* TODO */ +/* --- RCC_PLLSAI2CFGR ----------------------------------------------------- */ +/* TODO */ + +/* --- RCC_CIER - Clock interrupt enable register -------------------------- */ + +#define RCC_CIER_LSE_CSSIE (1 << 9) +/* OSC ready interrupt enable bits */ +#define RCC_CIER_PLLSAI2RDYIE (1 << 7) +#define RCC_CIER_PLLSAI1RDYIE (1 << 6) +#define RCC_CIER_PLLRDYIE (1 << 5) +#define RCC_CIER_HSERDYIE (1 << 4) +#define RCC_CIER_HSIRDYIE (1 << 3) +#define RCC_CIER_MSIRDYIE (1 << 2) +#define RCC_CIER_LSERDYIE (1 << 1) +#define RCC_CIER_LSIRDYIE (1 << 0) + +/* --- RCC_CIFR - Clock interrupt flag register */ + +#define RCC_CIFR_LSECSSF (1 << 9) +#define RCC_CIFR_CSSF (1 << 8) +#define RCC_CIFR_PLLSAI2RDYF (1 << 7) +#define RCC_CIFR_PLLSAI1RDYF (1 << 6) +#define RCC_CIFR_PLLRDYF (1 << 5) +#define RCC_CIFR_HSERDYF (1 << 4) +#define RCC_CIFR_HSIRDYF (1 << 3) +#define RCC_CIFR_MSIRDYF (1 << 2) +#define RCC_CIFR_LSERDYF (1 << 1) +#define RCC_CIFR_LSIRDYF (1 << 0) + +/* --- RCC_CICR - Clock interrupt clear register */ + +#define RCC_CICR_LSECSSC (1 << 9) +#define RCC_CICR_CSSC (1 << 8) +#define RCC_CICR_PLLSAI2RDYC (1 << 7) +#define RCC_CICR_PLLSAI1RDYC (1 << 6) +#define RCC_CICR_PLLRDYC (1 << 5) +#define RCC_CICR_HSERDYC (1 << 4) +#define RCC_CICR_HSIRDYC (1 << 3) +#define RCC_CICR_MSIRDYC (1 << 2) +#define RCC_CICR_LSERDYC (1 << 1) +#define RCC_CICR_LSIRDYC (1 << 0) + +/* --- RCC_AHB1RSTR values ------------------------------------------------- */ + +#define RCC_AHB1RSTR_TSCRST (1 << 16) +#define RCC_AHB1RSTR_CRCRST (1 << 12) +#define RCC_AHB1RSTR_FLASHRST (1 << 8) +#define RCC_AHB1RSTR_DMA2RST (1 << 1) +#define RCC_AHB1RSTR_DMA1RST (1 << 0) + +/* --- RCC_AHB2RSTR values ------------------------------------------------- */ + +#define RCC_AHB2RSTR_RNGRST (1 << 18) +#define RCC_AHB2RSTR_AESRST (1 << 16) +#define RCC_AHB2RSTR_ADCRST (1 << 13) +#define RCC_AHB2RSTR_OTGFSRST (1 << 12) +#define RCC_AHB2RSTR_GPIOHRST (1 << 7) +#define RCC_AHB2RSTR_GPIOGRST (1 << 6) +#define RCC_AHB2RSTR_GPIOFRST (1 << 5) +#define RCC_AHB2RSTR_GPIOERST (1 << 4) +#define RCC_AHB2RSTR_GPIODRST (1 << 3) +#define RCC_AHB2RSTR_GPIOCRST (1 << 2) +#define RCC_AHB2RSTR_GPIOBRST (1 << 1) +#define RCC_AHB2RSTR_GPIOARST (1 << 0) + +/* --- RCC_AHB3RSTR values ------------------------------------------------- */ + +#define RCC_AHB3RSTR_QSPIRST (1 << 8) +#define RCC_AHB3RSTR_FMCRST (1 << 0) + +/* --- RCC_APB1RSTR1 values ------------------------------------------------- */ + +#define RCC_APB1RSTR1_LPTIM1RST (1 << 31) +#define RCC_APB1RSTR1_OPAMPRST (1 << 30) +#define RCC_APB1RSTR1_DAC1RST (1 << 29) +#define RCC_APB1RSTR1_PWRRST (1 << 28) +#define RCC_APB1RSTR1_CAN1RST (1 << 25) +#define RCC_APB1RSTR1_I2C3RST (1 << 23) +#define RCC_APB1RSTR1_I2C2RST (1 << 22) +#define RCC_APB1RSTR1_I2C1RST (1 << 21) +#define RCC_APB1RSTR1_UART5RST (1 << 20) +#define RCC_APB1RSTR1_UART4RST (1 << 19) +#define RCC_APB1RSTR1_USART3RST (1 << 18) +#define RCC_APB1RSTR1_USART2RST (1 << 17) +#define RCC_APB1RSTR1_SPI3RST (1 << 15) +#define RCC_APB1RSTR1_SPI2RST (1 << 14) +#define RCC_APB1RSTR1_LCDRST (1 << 9) +#define RCC_APB1RSTR1_TIM7RST (1 << 5) +#define RCC_APB1RSTR1_TIM6RST (1 << 4) +#define RCC_APB1RSTR1_TIM5RST (1 << 3) +#define RCC_APB1RSTR1_TIM4RST (1 << 2) +#define RCC_APB1RSTR1_TIM3RST (1 << 1) +#define RCC_APB1RSTR1_TIM2RST (1 << 0) + +/* --- RCC_APB1RSTR2 values ------------------------------------------------- */ + +#define RCC_APB1RSTR2_LPTIM2RST (1 << 5) +#define RCC_APB1RSTR2_SWPMI1RST (1 << 2) +#define RCC_APB1RSTR2_LPUART1RST (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_DFSDMRST (1 << 24) +#define RCC_APB2RSTR_SAI2RST (1 << 22) +#define RCC_APB2RSTR_SAI1RST (1 << 21) +#define RCC_APB2RSTR_TIM17RST (1 << 18) +#define RCC_APB2RSTR_TIM16RST (1 << 17) +#define RCC_APB2RSTR_TIM15RST (1 << 16) +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_TIM8RST (1 << 13) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_TIM1RST (1 << 11) +#define RCC_APB2RSTR_SDMMC1RST (1 << 10) +/* Suspect FW_RST at bit 7 to match APB2_ENR ... */ +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) + +/* --- RCC_AHB1ENR values --------------------------------------------------- */ + +/** @defgroup rcc_ahb1enr_en RCC_AHB1ENR enable values +@ingroup STM32L4xx_rcc_defines + +@{*/ +#define RCC_AHB1ENR_TSCEN (1 << 16) +#define RCC_AHB1ENR_CRCEN (1 << 12) +#define RCC_AHB1ENR_FLASHEN (1 << 8) +#define RCC_AHB1ENR_DMA2EN (1 << 1) +#define RCC_AHB1ENR_DMA1EN (1 << 0) +/*@}*/ + +/* --- RCC_AHB2ENR values --------------------------------------------------- */ + +/** @defgroup rcc_ahb2enr_en RCC_AHB2ENR enable values +@ingroup STM32L4xx_rcc_defines + +@{*/ +#define RCC_AHB2ENR_RNGEN (1 << 18) +#define RCC_AHB2ENR_AESEN (1 << 16) +#define RCC_AHB2ENR_ADCEN (1 << 13) +#define RCC_AHB2ENR_OTGFSEN (1 << 12) +#define RCC_AHB2ENR_GPIOHEN (1 << 7) +#define RCC_AHB2ENR_GPIOGEN (1 << 6) +#define RCC_AHB2ENR_GPIOFEN (1 << 5) +#define RCC_AHB2ENR_GPIOEEN (1 << 4) +#define RCC_AHB2ENR_GPIODEN (1 << 3) +#define RCC_AHB2ENR_GPIOCEN (1 << 2) +#define RCC_AHB2ENR_GPIOBEN (1 << 1) +#define RCC_AHB2ENR_GPIOAEN (1 << 0) +/*@}*/ + +/* --- RCC_AHB3ENR values --------------------------------------------------- */ + +/** @defgroup rcc_ahb3enr_en RCC_AHB3ENR enable values +@ingroup STM32L4xx_rcc_defines + +@{*/ +#define RCC_AHB3ENR_QSPIEN (1 << 8) +#define RCC_AHB3ENR_FMCEN (1 << 0) +/*@}*/ + + +/* --- RCC_APB1ENR1 values -------------------------------------------------- */ + +/** @defgroup rcc_apb1enr1_en RCC_APB1ENR1 enable values +@ingroup STM32L4xx_rcc_defines + +@{*/ +#define RCC_APB1ENR1_LPTIM1EN (1 << 31) +#define RCC_APB1ENR1_OPAMPEN (1 << 30) +#define RCC_APB1ENR1_DAC1EN (1 << 29) +#define RCC_APB1ENR1_PWREN (1 << 28) +#define RCC_APB1ENR1_CAN1EN (1 << 25) +#define RCC_APB1ENR1_I2C3EN (1 << 23) +#define RCC_APB1ENR1_I2C2EN (1 << 22) +#define RCC_APB1ENR1_I2C1EN (1 << 21) +#define RCC_APB1ENR1_UART5EN (1 << 20) +#define RCC_APB1ENR1_UART4EN (1 << 19) +#define RCC_APB1ENR1_USART3EN (1 << 18) +#define RCC_APB1ENR1_USART2EN (1 << 17) +#define RCC_APB1ENR1_SPI3EN (1 << 15) +#define RCC_APB1ENR1_SPI2EN (1 << 14) +#define RCC_APB1ENR1_LCDEN (1 << 9) +#define RCC_APB1ENR1_TIM7EN (1 << 5) +#define RCC_APB1ENR1_TIM6EN (1 << 4) +#define RCC_APB1ENR1_TIM5EN (1 << 3) +#define RCC_APB1ENR1_TIM4EN (1 << 2) +#define RCC_APB1ENR1_TIM3EN (1 << 1) +#define RCC_APB1ENR1_TIM2EN (1 << 0) +/*@}*/ + +/* --- RCC_APB1ENR2 values -------------------------------------------------- */ + +/** @defgroup rcc_apb1enr2_en RCC_APB1ENR2 enable values +@ingroup STM32L4xx_rcc_defines + +@{*/ +#define RCC_APB1ENR2_LPTIM2EN (1 << 5) +#define RCC_APB1ENR2_SWPMI1EN (1 << 2) +#define RCC_APB1ENR2_LPUART1EN (1 << 0) +/*@}*/ + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values +@ingroup STM32L4xx_rcc_defines + +@{*/ +#define RCC_APB2ENR_DFSDMEN (1 << 24) +#define RCC_APB2ENR_SAI2EN (1 << 22) +#define RCC_APB2ENR_SAI1EN (1 << 21) +#define RCC_APB2ENR_TIM17EN (1 << 18) +#define RCC_APB2ENR_TIM16EN (1 << 17) +#define RCC_APB2ENR_TIM15EN (1 << 16) +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_TIM8EN (1 << 13) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_TIM1EN (1 << 11) +#define RCC_APB2ENR_SDMMC1EN (1 << 10) +#define RCC_APB2ENR_FWEN (1 << 7) +#define RCC_APB2ENR_SYSCFGEN (1 << 0) +/*@}*/ + +/* --- RCC_AHB1SMENR - AHB1 periph clock in sleep mode --------------------- */ + +#define RCC_AHB1SMENR_TSCSMEN (1 << 16) +#define RCC_AHB1SMENR_CRCSMEN (1 << 12) +#define RCC_AHB1SMENR_SRAM1SMEN (1 << 9) +#define RCC_AHB1SMENR_FLASHSMEN (1 << 8) +#define RCC_AHB1SMENR_DMA2SMEN (1 << 1) +#define RCC_AHB1SMENR_DMA1SMEN (1 << 0) + +/* --- RCC_AHB2SMENR - AHB2 periph clock in sleep mode --------------------- */ + +#define RCC_AHB2SMENR_RNGSMEN (1 << 18) +#define RCC_AHB2SMENR_AESSMEN (1 << 16) +#define RCC_AHB2SMENR_ADCSMEN (1 << 13) +#define RCC_AHB2SMENR_OTGFSSMEN (1 << 12) +#define RCC_AHB2SMENR_SRAM2SMEN (1 << 9) +#define RCC_AHB2SMENR_GPIOHSMEN (1 << 7) +#define RCC_AHB2SMENR_GPIOGSMEN (1 << 6) +#define RCC_AHB2SMENR_GPIOFSMEN (1 << 5) +#define RCC_AHB2SMENR_GPIOESMEN (1 << 4) +#define RCC_AHB2SMENR_GPIODSMEN (1 << 3) +#define RCC_AHB2SMENR_GPIOCSMEN (1 << 2) +#define RCC_AHB2SMENR_GPIOBSMEN (1 << 1) +#define RCC_AHB2SMENR_GPIOASMEN (1 << 0) + +/* --- RCC_AHB3SMENR - AHB3 periph clock in sleep mode --------------------- */ + +#define RCC_AHB3SMENR_QSPISMEN (1 << 8) +#define RCC_AHB3SMENR_FMCSMEN (1 << 0) + +/* --- RCC_APB1SMENR1 - APB1 periph clock in sleep mode -------------------- */ + +#define RCC_APB1SMENR1_LPTIM1SMEN (1 << 31) +#define RCC_APB1SMENR1_OPAMPSMEN (1 << 30) +#define RCC_APB1SMENR1_DAC1SMEN (1 << 29) +#define RCC_APB1SMENR1_PWRSMEN (1 << 28) +#define RCC_APB1SMENR1_CAN1SMEN (1 << 25) +#define RCC_APB1SMENR1_I2C3SMEN (1 << 23) +#define RCC_APB1SMENR1_I2C2SMEN (1 << 22) +#define RCC_APB1SMENR1_I2C1SMEN (1 << 21) +#define RCC_APB1SMENR1_UART5SMEN (1 << 20) +#define RCC_APB1SMENR1_UART4SMEN (1 << 19) +#define RCC_APB1SMENR1_USART3SMEN (1 << 18) +#define RCC_APB1SMENR1_USART2SMEN (1 << 17) +#define RCC_APB1SMENR1_SPI3SMEN (1 << 15) +#define RCC_APB1SMENR1_SPI2SMEN (1 << 14) +#define RCC_APB1SMENR1_WWDGSMEN (1 << 11) +#define RCC_APB1SMENR1_LCDSMEN (1 << 9) +#define RCC_APB1SMENR1_TIM7SMEN (1 << 5) +#define RCC_APB1SMENR1_TIM6SMEN (1 << 4) +#define RCC_APB1SMENR1_TIM5SMEN (1 << 3) +#define RCC_APB1SMENR1_TIM4SMEN (1 << 2) +#define RCC_APB1SMENR1_TIM3SMEN (1 << 1) +#define RCC_APB1SMENR1_TIM2SMEN (1 << 0) + +/* --- RCC_APB1SMENR2 - APB1 periph clock in sleep mode -------------------- */ + +#define RCC_APB1SMENR2_LPTIM2SMEN (1 << 5) +#define RCC_APB1SMENR2_SWPMI1SMEN (1 << 2) +#define RCC_APB1SMENR2_LPUART1SMEN (1 << 0) + +/* --- RCC_APB2SMENR - APB2 periph clock in sleep mode --------------------- */ + +#define RCC_APB2SMENR_DFSDMSMEN (1 << 24) +#define RCC_APB2SMENR_SAI2SMEN (1 << 22) +#define RCC_APB2SMENR_SAI1SMEN (1 << 21) +#define RCC_APB2SMENR_TIM17SMEN (1 << 18) +#define RCC_APB2SMENR_TIM16SMEN (1 << 17) +#define RCC_APB2SMENR_TIM15SMEN (1 << 16) +#define RCC_APB2SMENR_USART1SMEN (1 << 14) +#define RCC_APB2SMENR_TIM8SMEN (1 << 13) +#define RCC_APB2SMENR_SPI1SMEN (1 << 12) +#define RCC_APB2SMENR_TIM1SMEN (1 << 11) +#define RCC_APB2SMENR_SDMMC1SMEN (1 << 10) +#define RCC_APB2SMENR_SYSCFGSMEN (1 << 0) + +/* --- RCC_CCIPR - Peripherals independent clock config register ----------- */ + +#define RCC_CCIPR_DFSDMSEL (1 << 31) +#define RCC_CCIPR_SWPMI1SEL (1 << 30) + +#define RCC_CCIPR_ADCSEL_NONE 0 +#define RCC_CCIPR_ADCSEL_PLLSAI1R 1 +#define RCC_CCIPR_ADCSEL_PLLSAI2R 2 +#define RCC_CCIPR_ADCSEL_SYS 3 +#define RCC_CCIPR_ADCSEL_MASK 0x3 +#define RCC_CCIPR_ADCSEL_SHIFT 28 + +#define RCC_CCIPR_CLK48SEL_NONE 0 +#define RCC_CCIPR_CLK48SEL_PLLSAI1Q 1 +#define RCC_CCIPR_CLK48SEL_PLL 2 +#define RCC_CCIPR_CLK48SEL_MSI 3 +#define RCC_CCIPR_CLK48SEL_MASK 0x3 +#define RCC_CCIPR_CLK48SEL_SHIFT 26 + +#define RCC_CCIPR_SAIxSEL_PLLSAI1P 0 +#define RCC_CCIPR_SAIxSEL_PLLSAI2P 1 +#define RCC_CCIPR_SAIxSEL_PLL 2 +#define RCC_CCIPR_SAIxSEL_EXT 3 +#define RCC_CCIPR_SAIxSEL_MASK 0x3 +#define RCC_CCIPR_SAI2SEL_SHIFT 24 +#define RCC_CCIPR_SAI1SEL_SHIFT 22 + +#define RCC_CCIPR_LPTIMxSEL_APB 0 +#define RCC_CCIPR_LPTIMxSEL_LSI 1 +#define RCC_CCIPR_LPTIMxSEL_HSI16 2 +#define RCC_CCIPR_LPTIMxSEL_LSE 3 +#define RCC_CCIPR_LPTIMxSEL_MASK 0x3 +#define RCC_CCIPR_LPTIM2SEL_SHIFT 20 +#define RCC_CCIPR_LPTIM1SEL_SHIFT 18 + +#define RCC_CCIPR_I2CxSEL_APB 0 +#define RCC_CCIPR_I2CxSEL_SYS 1 +#define RCC_CCIPR_I2CxSEL_HSI16 2 +#define RCC_CCIPR_I2CxSEL_MASK 0x3 +#define RCC_CCIPR_I2C3SEL_SHIFT 16 +#define RCC_CCIPR_I2C2SEL_SHIFT 14 +#define RCC_CCIPR_I2C1SEL_SHIFT 12 + +#define RCC_CCIPR_LPUART1SEL_APB 0 +#define RCC_CCIPR_LPUART1SEL_SYS 1 +#define RCC_CCIPR_LPUART1SEL_HSI16 2 +#define RCC_CCIPR_LPUART1SEL_LSE 3 +#define RCC_CCIPR_LPUART1SEL_MASK 0x3 +#define RCC_CCIPR_LPUART1SEL_SHIFT 10 + +#define RCC_CCIPR_USARTxSEL_APB 0 +#define RCC_CCIPR_USARTxSEL_SYS 1 +#define RCC_CCIPR_USARTxSEL_HSI16 2 +#define RCC_CCIPR_USARTxSEL_LSE 3 +#define RCC_CCIPR_USARTxSEL_MASK 0x3 +#define RCC_CCIPR_UARTxSEL_APB RCC_CCIPR_USARTxSEL_APB +#define RCC_CCIPR_UARTxSEL_SYS RCC_CCIPR_USARTxSEL_SYS +#define RCC_CCIPR_UARTxSEL_HSI16 RCC_CCIPR_USARTxSEL_HSI16 +#define RCC_CCIPR_UARTxSEL_LSE RCC_CCIPR_USARTxSEL_LSE +#define RCC_CCIPR_UARTxSEL_MASK RCC_CCIPR_USARTxSEL_MASK +#define RCC_CCIPR_UART5SEL_SHIFT 8 +#define RCC_CCIPR_UART4SEL_SHIFT 6 +#define RCC_CCIPR_USART3SEL_SHIFT 4 +#define RCC_CCIPR_USART2SEL_SHIFT 2 +#define RCC_CCIPR_USART1SEL_SHIFT 0 + +#define RCC_CCIPR_USART1SEL_APB 0 +#define RCC_CCIPR_USART1SEL_SYS 1 +#define RCC_CCIPR_USART1SEL_HSI16 2 +#define RCC_CCIPR_USART1SEL_LSE 3 +#define RCC_CCIPR_USART1SEL_SHIFT 0 +#define RCC_CCIPR_USART1SEL_MASK 0x3 + +/* --- RCC_BDCR - Backup domain control register --------------------------- */ + +#define RCC_BDCR_LSCOSEL (1 << 25) +#define RCC_BDCR_LSCOEN (1 << 24) +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) + +#define RCC_BDCR_RTCSEL_NONE 0 +#define RCC_BDCR_RTCSEL_LSE 1 +#define RCC_BDCR_RTCSEL_LSI 2 +#define RCC_BDCR_RTCSEL_HSEDIV32 3 +#define RCC_BDCR_RTCSEL_SHIFT 8 +#define RCC_BDCR_RTCSEL_MASK 0x3 + +#define RCC_BDCR_LSECSSD (1 << 7) +#define RCC_BDCR_LSECSSON (1 << 5) + +#define RCC_BDCR_LSEDRV_LOW 0 +#define RCC_BDCR_LSEDRV_MEDLOW 1 +#define RCC_BDCR_LSEDRV_MEDHIGH 2 +#define RCC_BDCR_LSEDRV_HIGH 3 +#define RCC_BDCR_LSEDRV_SHIFT 3 +#define RCC_BDCR_LSEDRV_MASK 0x3 + +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR - Control/Status register ----------------------------------- */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_BORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_OBLRSTF (1 << 25) +#define RCC_CSR_FWRSTF (1 << 24) +#define RCC_CSR_RMVF (1 << 23) +#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\ + RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_BORRSTF |\ + RCC_CSR_PINRSTF | RCC_CSR_OBLRSTF | RCC_CSR_FWRSTF) + +/** @defgroup rcc_csr_msirange MSI Range after standby values +@brief Range of the MSI oscillator after returning from standby +@ingroup STM32L4xx_rcc_defines +@sa rcc_cr_msirange +@{*/ +#define RCC_CSR_MSIRANGE_MASK 0xf +#define RCC_CSR_MSIRANGE_SHIFT 8 +#define RCC_CSR_MSIRANGE_1MHZ 4 +#define RCC_CSR_MSIRANGE_2MHZ 5 +#define RCC_CSR_MSIRANGE_4MHZ 6 +#define RCC_CSR_MSIRANGE_8MHZ 7 +/*@}*/ + +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- Variable definitions ------------------------------------------------ */ + +extern uint32_t rcc_ahb_frequency; +extern uint32_t rcc_apb1_frequency; +extern uint32_t rcc_apb2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_osc { + RCC_PLL, RCC_HSE, RCC_HSI16, RCC_MSI, RCC_LSE, RCC_LSI +}; + + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + + /* AHB1 peripherals */ + RCC_TSC = _REG_BIT(RCC_AHB1ENR_OFFSET, 16), + RCC_CRC = _REG_BIT(RCC_AHB1ENR_OFFSET, 12), + RCC_FLASH = _REG_BIT(RCC_AHB1ENR_OFFSET, 8), + RCC_DMA2 = _REG_BIT(RCC_AHB1ENR_OFFSET, 1), + RCC_DMA1 = _REG_BIT(RCC_AHB1ENR_OFFSET, 0), + + /* AHB2 peripherals */ + RCC_RNG = _REG_BIT(RCC_AHB2ENR_OFFSET, 18), + RCC_AES = _REG_BIT(RCC_AHB2ENR_OFFSET, 16), + RCC_ADC = _REG_BIT(RCC_AHB2ENR_OFFSET, 13), + RCC_ADC1 = _REG_BIT(RCC_AHB2ENR_OFFSET, 13), /* Compatibility */ + RCC_OTGFS = _REG_BIT(RCC_AHB2ENR_OFFSET, 12), + RCC_GPIOH = _REG_BIT(RCC_AHB2ENR_OFFSET, 7), + RCC_GPIOG = _REG_BIT(RCC_AHB2ENR_OFFSET, 6), + RCC_GPIOF = _REG_BIT(RCC_AHB2ENR_OFFSET, 5), + RCC_GPIOE = _REG_BIT(RCC_AHB2ENR_OFFSET, 4), + RCC_GPIOD = _REG_BIT(RCC_AHB2ENR_OFFSET, 3), + RCC_GPIOC = _REG_BIT(RCC_AHB2ENR_OFFSET, 2), + RCC_GPIOB = _REG_BIT(RCC_AHB2ENR_OFFSET, 1), + RCC_GPIOA = _REG_BIT(RCC_AHB2ENR_OFFSET, 0), + + /* AHB3 peripherals */ + RCC_QSPI = _REG_BIT(RCC_AHB3ENR_OFFSET, 8), + RCC_FMC = _REG_BIT(RCC_AHB3ENR_OFFSET, 0), + + /* APB1 peripherals */ + RCC_LPTIM1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 31), + RCC_OPAMP = _REG_BIT(RCC_APB1ENR1_OFFSET, 30), + RCC_DAC1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 29), + RCC_PWR = _REG_BIT(RCC_APB1ENR1_OFFSET, 28), + RCC_CAN1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 25), + RCC_I2C3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 23), + RCC_I2C2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 22), + RCC_I2C1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 21), + RCC_UART5 = _REG_BIT(RCC_APB1ENR1_OFFSET, 20), + RCC_UART4 = _REG_BIT(RCC_APB1ENR1_OFFSET, 19), + RCC_USART3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 18), + RCC_USART2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 17), + RCC_SPI3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 15), + RCC_SPI2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 14), + RCC_LCD = _REG_BIT(RCC_APB1ENR1_OFFSET, 9), + RCC_TIM7 = _REG_BIT(RCC_APB1ENR1_OFFSET, 5), + RCC_TIM6 = _REG_BIT(RCC_APB1ENR1_OFFSET, 4), + RCC_TIM5 = _REG_BIT(RCC_APB1ENR1_OFFSET, 3), + RCC_TIM4 = _REG_BIT(RCC_APB1ENR1_OFFSET, 2), + RCC_TIM3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 1), + RCC_TIM2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 0), + /* apb1-2 */ + RCC_LPTIM2 = _REG_BIT(RCC_APB1ENR2_OFFSET, 5), + RCC_SWPMI1 = _REG_BIT(RCC_APB1ENR2_OFFSET, 2), + RCC_LPUART1 = _REG_BIT(RCC_APB1ENR2_OFFSET, 0), + + /* APB2 peripherals */ + RCC_DFSDM = _REG_BIT(RCC_APB2ENR_OFFSET, 24), + RCC_SAI2 = _REG_BIT(RCC_APB2ENR_OFFSET, 22), + RCC_SAI1 = _REG_BIT(RCC_APB2ENR_OFFSET, 21), + RCC_TIM17 = _REG_BIT(RCC_APB2ENR_OFFSET, 18), + RCC_TIM16 = _REG_BIT(RCC_APB2ENR_OFFSET, 17), + RCC_TIM15 = _REG_BIT(RCC_APB2ENR_OFFSET, 16), + RCC_USART1 = _REG_BIT(RCC_APB2ENR_OFFSET, 14), + RCC_TIM8 = _REG_BIT(RCC_APB2ENR_OFFSET, 13), + RCC_SPI1 = _REG_BIT(RCC_APB2ENR_OFFSET, 12), + RCC_TIM1 = _REG_BIT(RCC_APB2ENR_OFFSET, 11), + RCC_SDMMC1 = _REG_BIT(RCC_APB2ENR_OFFSET, 10), + RCC_FW = _REG_BIT(RCC_APB2ENR_OFFSET, 7), + RCC_SYSCFG = _REG_BIT(RCC_APB2ENR_OFFSET, 0), + + /* AHB1 peripherals in sleep mode */ + SCC_TSC = _REG_BIT(RCC_AHB1SMENR_OFFSET, 16), + SCC_CRC = _REG_BIT(RCC_AHB1SMENR_OFFSET, 12), + SCC_SRAM1 = _REG_BIT(RCC_AHB1SMENR_OFFSET, 9), + SCC_FLASH = _REG_BIT(RCC_AHB1SMENR_OFFSET, 8), + SCC_DMA2 = _REG_BIT(RCC_AHB1SMENR_OFFSET, 1), + SCC_DMA1 = _REG_BIT(RCC_AHB1SMENR_OFFSET, 0), + + /* AHB2 peripherals in sleep mode */ + SCC_RNG = _REG_BIT(RCC_AHB2SMENR_OFFSET, 18), + SCC_AES = _REG_BIT(RCC_AHB2SMENR_OFFSET, 16), + SCC_ADC = _REG_BIT(RCC_AHB2SMENR_OFFSET, 13), + SCC_ADC1 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 13), /* Compatibility */ + SCC_OTGFS = _REG_BIT(RCC_AHB2SMENR_OFFSET, 12), + SCC_SRAM2 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 9), + SCC_GPIOH = _REG_BIT(RCC_AHB2SMENR_OFFSET, 7), + SCC_GPIOG = _REG_BIT(RCC_AHB2SMENR_OFFSET, 6), + SCC_GPIOF = _REG_BIT(RCC_AHB2SMENR_OFFSET, 5), + SCC_GPIOE = _REG_BIT(RCC_AHB2SMENR_OFFSET, 4), + SCC_GPIOD = _REG_BIT(RCC_AHB2SMENR_OFFSET, 3), + SCC_GPIOC = _REG_BIT(RCC_AHB2SMENR_OFFSET, 2), + SCC_GPIOB = _REG_BIT(RCC_AHB2SMENR_OFFSET, 1), + SCC_GPIOA = _REG_BIT(RCC_AHB2SMENR_OFFSET, 0), + + /* AHB3 peripherals in sleep mode */ + SCC_QSPI = _REG_BIT(RCC_AHB3SMENR_OFFSET, 8), + SCC_FMC = _REG_BIT(RCC_AHB3SMENR_OFFSET, 0), + + /* APB1 peripherals in sleep mode */ + SCC_LPTIM1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 31), + SCC_OPAMP = _REG_BIT(RCC_APB1ENR1_OFFSET, 30), + SCC_DAC1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 29), + SCC_PWR = _REG_BIT(RCC_APB1ENR1_OFFSET, 28), + SCC_CAN1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 25), + SCC_I2C3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 23), + SCC_I2C2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 22), + SCC_I2C1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 21), + SCC_UART5 = _REG_BIT(RCC_APB1ENR1_OFFSET, 20), + SCC_UART4 = _REG_BIT(RCC_APB1ENR1_OFFSET, 19), + SCC_USART3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 18), + SCC_USART2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 17), + SCC_SPI3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 15), + SCC_SPI2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 14), + SCC_WWDG = _REG_BIT(RCC_APB1ENR1_OFFSET, 11), + SCC_LCD = _REG_BIT(RCC_APB1ENR1_OFFSET, 9), + SCC_TIM7 = _REG_BIT(RCC_APB1ENR1_OFFSET, 5), + SCC_TIM6 = _REG_BIT(RCC_APB1ENR1_OFFSET, 4), + SCC_TIM5 = _REG_BIT(RCC_APB1ENR1_OFFSET, 3), + SCC_TIM4 = _REG_BIT(RCC_APB1ENR1_OFFSET, 2), + SCC_TIM3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 1), + SCC_TIM2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 0), + /* apb1-2 */ + SCC_LPTIM2 = _REG_BIT(RCC_APB1ENR2_OFFSET, 5), + SCC_SWPMI1 = _REG_BIT(RCC_APB1ENR2_OFFSET, 2), + SCC_LPUART1 = _REG_BIT(RCC_APB1ENR2_OFFSET, 0), + + /* APB2 peripherals in sleep mode */ + SCC_DFSDM = _REG_BIT(RCC_APB2ENR_OFFSET, 24), + SCC_SAI2 = _REG_BIT(RCC_APB2ENR_OFFSET, 22), + SCC_SAI1 = _REG_BIT(RCC_APB2ENR_OFFSET, 21), + SCC_TIM17 = _REG_BIT(RCC_APB2ENR_OFFSET, 18), + SCC_TIM16 = _REG_BIT(RCC_APB2ENR_OFFSET, 17), + SCC_TIM15 = _REG_BIT(RCC_APB2ENR_OFFSET, 16), + SCC_USART1 = _REG_BIT(RCC_APB2ENR_OFFSET, 14), + SCC_TIM8 = _REG_BIT(RCC_APB2ENR_OFFSET, 13), + SCC_SPI1 = _REG_BIT(RCC_APB2ENR_OFFSET, 12), + SCC_TIM1 = _REG_BIT(RCC_APB2ENR_OFFSET, 11), + SCC_SDMMC1 = _REG_BIT(RCC_APB2ENR_OFFSET, 10), + SCC_SYSCFG = _REG_BIT(RCC_APB2ENR_OFFSET, 0), +}; + +enum rcc_periph_rst { + /* AHB1 peripherals */ + RST_TSC = _REG_BIT(RCC_AHB1RSTR_OFFSET, 16), + RST_CRC = _REG_BIT(RCC_AHB1RSTR_OFFSET, 12), + RST_FLASH = _REG_BIT(RCC_AHB1RSTR_OFFSET, 8), + RST_DMA2 = _REG_BIT(RCC_AHB1RSTR_OFFSET, 1), + RST_DMA1 = _REG_BIT(RCC_AHB1RSTR_OFFSET, 0), + + /* AHB2 peripherals */ + RST_RNG = _REG_BIT(RCC_AHB2RSTR_OFFSET, 18), + RST_AES = _REG_BIT(RCC_AHB2RSTR_OFFSET, 16), + RST_ADC = _REG_BIT(RCC_AHB2RSTR_OFFSET, 13), + RST_ADC1 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 13), /* Compatibility */ + RST_OTGFS = _REG_BIT(RCC_AHB2RSTR_OFFSET, 12), + RST_GPIOH = _REG_BIT(RCC_AHB2RSTR_OFFSET, 7), + RST_GPIOG = _REG_BIT(RCC_AHB2RSTR_OFFSET, 6), + RST_GPIOF = _REG_BIT(RCC_AHB2RSTR_OFFSET, 5), + RST_GPIOE = _REG_BIT(RCC_AHB2RSTR_OFFSET, 4), + RST_GPIOD = _REG_BIT(RCC_AHB2RSTR_OFFSET, 3), + RST_GPIOC = _REG_BIT(RCC_AHB2RSTR_OFFSET, 2), + RST_GPIOB = _REG_BIT(RCC_AHB2RSTR_OFFSET, 1), + RST_GPIOA = _REG_BIT(RCC_AHB2RSTR_OFFSET, 0), + + /* AHB3 peripherals */ + RST_QSPI = _REG_BIT(RCC_AHB3RSTR_OFFSET, 8), + RST_FMC = _REG_BIT(RCC_AHB3RSTR_OFFSET, 0), + + /* APB1 peripherals */ + RST_LPTIM1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 31), + RST_OPAMP = _REG_BIT(RCC_APB1RSTR1_OFFSET, 30), + RST_DAC1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 29), + RST_PWR = _REG_BIT(RCC_APB1RSTR1_OFFSET, 28), + RST_CAN1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 25), + RST_I2C3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 23), + RST_I2C2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 22), + RST_I2C1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 21), + RST_UART5 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 20), + RST_UART4 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 19), + RST_USART3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 18), + RST_USART2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 17), + RST_SPI3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 15), + RST_SPI2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 14), + RST_LCD = _REG_BIT(RCC_APB1RSTR1_OFFSET, 9), + RST_TIM7 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 5), + RST_TIM6 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 4), + RST_TIM5 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 3), + RST_TIM4 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 2), + RST_TIM3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 1), + RST_TIM2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 0), + /* apb1-2 */ + RST_LPTIM2 = _REG_BIT(RCC_APB1RSTR2_OFFSET, 5), + RST_SWPMI1 = _REG_BIT(RCC_APB1RSTR2_OFFSET, 2), + RST_LPUART1 = _REG_BIT(RCC_APB1RSTR2_OFFSET, 0), + + /* APB2 peripherals */ + RST_DFSDM = _REG_BIT(RCC_APB2RSTR_OFFSET, 24), + RST_SAI2 = _REG_BIT(RCC_APB2RSTR_OFFSET, 22), + RST_SAI1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 21), + RST_TIM17 = _REG_BIT(RCC_APB2RSTR_OFFSET, 18), + RST_TIM16 = _REG_BIT(RCC_APB2RSTR_OFFSET, 17), + RST_TIM15 = _REG_BIT(RCC_APB2RSTR_OFFSET, 16), + RST_USART1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 14), + RST_TIM8 = _REG_BIT(RCC_APB2RSTR_OFFSET, 13), + RST_SPI1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 12), + RST_TIM1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 11), + RST_SDMMC1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 10), + RST_SYSCFG = _REG_BIT(RCC_APB2RSTR_OFFSET, 0), + +}; +#include + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_sysclk_status(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_main_pll(uint32_t source, uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t pllq, uint32_t pllr); +uint32_t rcc_system_clock_source(void); +void rcc_set_msi_range(uint32_t msi_range); +void rcc_set_msi_range_standby(uint32_t msi_range); + +END_DECLS + +/**@}*/ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rng.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rng.h new file mode 100644 index 00000000..09d014d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/rng.h @@ -0,0 +1,23 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RNG_H +#define LIBOPENCM3_RNG_H + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/timer.h new file mode 100644 index 00000000..355c1ca1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/l4/timer.h @@ -0,0 +1,44 @@ +/** @defgroup timer_defines Timer Defines + +@brief libopencm3 Defined Constants and Types for the STM32L4xx Timers + +@ingroup STM32L4xx_defines + +@version 1.0.0 + +@date 30 November 2015 + +@author @htmlonly © @endhtmlonly 2015 Karl Palsson + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +BEGIN_DECLS + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/ltdc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/ltdc.h new file mode 100644 index 00000000..71521c53 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/ltdc.h @@ -0,0 +1,27 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F4) +# include +#else +# error "LCD-TFT only defined for STM32F4" +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/memorymap.h new file mode 100644 index 00000000..ecf41281 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/memorymap.h @@ -0,0 +1,45 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_COMMON_H +#define LIBOPENCM3_MEMORYMAP_COMMON_H + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32F7) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + +#endif /* LIBOPENCM3_MEMORYMAP_COMMON_H */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_common.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_common.h new file mode 100644 index 00000000..8c1022b0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_common.h @@ -0,0 +1,497 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * This file is intended to be included by either otg_hs.h or otg_fs.h + * Contains common definitions of Command and Status Registers (CSR) and their + * bit definitions. + */ + +#ifndef LIBOPENCM3_OTG_COMMON_H +#define LIBOPENCM3_OTG_COMMON_H + +/* Core Global Control and Status Registers */ +#define OTG_GOTGCTL 0x000 +#define OTG_GOTGINT 0x004 +#define OTG_GAHBCFG 0x008 +#define OTG_GUSBCFG 0x00C +#define OTG_GRSTCTL 0x010 +#define OTG_GINTSTS 0x014 +#define OTG_GINTMSK 0x018 +#define OTG_GRXSTSR 0x01C +#define OTG_GRXSTSP 0x020 +#define OTG_GRXFSIZ 0x024 +#define OTG_GNPTXFSIZ 0x028 +#define OTG_GNPTXSTS 0x02C +#define OTG_GCCFG 0x038 +#define OTG_CID 0x03C +#define OTG_HPTXFSIZ 0x100 +#define OTG_DIEPTXF(x) (0x104 + 4*((x)-1)) + +/* Host-mode Control and Status Registers */ +#define OTG_HCFG 0x400 +#define OTG_HFIR 0x404 +#define OTG_HFNUM 0x408 +#define OTG_HPTXSTS 0x410 +#define OTG_HAINT 0x414 +#define OTG_HAINTMSK 0x418 +#define OTG_HPRT 0x440 +#define OTG_HCCHAR(x) (0x500 + 0x20*(x)) +#define OTG_HCINT(x) (0x508 + 0x20*(x)) +#define OTG_HCINTMSK(x) (0x50C + 0x20*(x)) +#define OTG_HCTSIZ(x) (0x510 + 0x20*(x)) + + +/* Device-mode Control and Status Registers */ +#define OTG_DCFG 0x800 +#define OTG_DCTL 0x804 +#define OTG_DSTS 0x808 +#define OTG_DIEPMSK 0x810 +#define OTG_DOEPMSK 0x814 +#define OTG_DAINT 0x818 +#define OTG_DAINTMSK 0x81C +#define OTG_DVBUSDIS 0x828 +#define OTG_DVBUSPULSE 0x82C +#define OTG_DIEPEMPMSK 0x834 + +#define OTG_DIEPCTL0 0x900 +#define OTG_DIEPCTL(x) (0x900 + 0x20*(x)) +#define OTG_DOEPCTL0 0xB00 +#define OTG_DOEPCTL(x) (0xB00 + 0x20*(x)) +#define OTG_DIEPINT(x) (0x908 + 0x20*(x)) +#define OTG_DOEPINT(x) (0xB08 + 0x20*(x)) +#define OTG_DIEPTSIZ0 0x910 +#define OTG_DIEPTSIZ(x) (0x910 + 0x20*(x)) +#define OTG_DOEPTSIZ0 0xB10 +#define OTG_DOEPTSIZ(x) (0xB10 + 0x20*(x)) +#define OTG_DTXFSTS(x) (0x918 + 0x20*(x)) + +/* Power and clock gating control and status register */ +#define OTG_PCGCCTL 0xE00 + +/* Data FIFO */ +#define OTG_FIFO(x) (((x) + 1) << 12) + + +/* Global CSRs */ +/* OTG USB control registers (OTG_GOTGCTL) */ +#define OTG_GOTGCTL_BSVLD (1 << 19) +#define OTG_GOTGCTL_ASVLD (1 << 18) +#define OTG_GOTGCTL_DBCT (1 << 17) +#define OTG_GOTGCTL_CIDSTS (1 << 16) +#define OTG_GOTGCTL_DHNPEN (1 << 11) +#define OTG_GOTGCTL_HSHNPEN (1 << 10) +#define OTG_GOTGCTL_HNPRQ (1 << 9) +#define OTG_GOTGCTL_HNGSCS (1 << 8) +#define OTG_GOTGCTL_SRQ (1 << 1) +#define OTG_GOTGCTL_SRQSCS (1 << 0) + +/* OTG USB control registers (OTG_GOTGINT) */ +#define OTG_GOTGINT_DBCDNE (1 << 19) +#define OTG_GOTGINT_ADTOCHG (1 << 18) +#define OTG_GOTGINT_HNGDET (1 << 17) +#define OTG_GOTGINT_HNSSCHG (1 << 9) +#define OTG_GOTGINT_SRSSCHG (1 << 8) +#define OTG_GOTGINT_SEDET (1 << 2) + +/* OTG AHB configuration register (OTG_GAHBCFG) */ +#define OTG_GAHBCFG_GINT 0x0001 +#define OTG_GAHBCFG_TXFELVL 0x0080 +#define OTG_GAHBCFG_PTXFELVL 0x0100 + +/* OTG USB configuration register (OTG_GUSBCFG) */ +#define OTG_GUSBCFG_TOCAL 0x00000003 +#define OTG_GUSBCFG_SRPCAP 0x00000100 +#define OTG_GUSBCFG_HNPCAP 0x00000200 +#define OTG_GUSBCFG_TRDT_MASK (0xf << 10) +#define OTG_GUSBCFG_NPTXRWEN 0x00004000 +#define OTG_GUSBCFG_FHMOD 0x20000000 +#define OTG_GUSBCFG_FDMOD 0x40000000 +#define OTG_GUSBCFG_CTXPKT 0x80000000 +#define OTG_GUSBCFG_PHYSEL (1 << 6) + +/* OTG reset register (OTG_GRSTCTL) */ +#define OTG_GRSTCTL_AHBIDL (1 << 31) +/* Bits 30:11 - Reserved */ +#define OTG_GRSTCTL_TXFNUM_MASK (0x1f << 6) +#define OTG_GRSTCTL_TXFNUM_ALL (0x10 << 6) +#define OTG_GRSTCTL_TXFFLSH (1 << 5) +#define OTG_GRSTCTL_RXFFLSH (1 << 4) +/* Bit 3 - Reserved */ +#define OTG_GRSTCTL_FCRST (1 << 2) +#define OTG_GRSTCTL_HSRST (1 << 1) +#define OTG_GRSTCTL_CSRST (1 << 0) + +/* OTG interrupt status register (OTG_GINTSTS) */ +#define OTG_GINTSTS_WKUPINT (1 << 31) +#define OTG_GINTSTS_SRQINT (1 << 30) +#define OTG_GINTSTS_DISCINT (1 << 29) +#define OTG_GINTSTS_CIDSCHG (1 << 28) +/* Bit 27 - Reserved */ +#define OTG_GINTSTS_PTXFE (1 << 26) +#define OTG_GINTSTS_HCINT (1 << 25) +#define OTG_GINTSTS_HPRTINT (1 << 24) +/* Bits 23:22 - Reserved */ +#define OTG_GINTSTS_IPXFR (1 << 21) +#define OTG_GINTSTS_INCOMPISOOUT (1 << 21) +#define OTG_GINTSTS_IISOIXFR (1 << 20) +#define OTG_GINTSTS_OEPINT (1 << 19) +#define OTG_GINTSTS_IEPINT (1 << 18) +/* Bits 17:16 - Reserved */ +#define OTG_GINTSTS_EOPF (1 << 15) +#define OTG_GINTSTS_ISOODRP (1 << 14) +#define OTG_GINTSTS_ENUMDNE (1 << 13) +#define OTG_GINTSTS_USBRST (1 << 12) +#define OTG_GINTSTS_USBSUSP (1 << 11) +#define OTG_GINTSTS_ESUSP (1 << 10) +/* Bits 9:8 - Reserved */ +#define OTG_GINTSTS_GONAKEFF (1 << 7) +#define OTG_GINTSTS_GINAKEFF (1 << 6) +#define OTG_GINTSTS_NPTXFE (1 << 5) +#define OTG_GINTSTS_RXFLVL (1 << 4) +#define OTG_GINTSTS_SOF (1 << 3) +#define OTG_GINTSTS_OTGINT (1 << 2) +#define OTG_GINTSTS_MMIS (1 << 1) +#define OTG_GINTSTS_CMOD (1 << 0) + +/* OTG interrupt mask register (OTG_GINTMSK) */ +#define OTG_GINTMSK_MMISM 0x00000002 +#define OTG_GINTMSK_OTGINT 0x00000004 +#define OTG_GINTMSK_SOFM 0x00000008 +#define OTG_GINTMSK_RXFLVLM 0x00000010 +#define OTG_GINTMSK_NPTXFEM 0x00000020 +#define OTG_GINTMSK_GINAKEFFM 0x00000040 +#define OTG_GINTMSK_GONAKEFFM 0x00000080 +#define OTG_GINTMSK_ESUSPM 0x00000400 +#define OTG_GINTMSK_USBSUSPM 0x00000800 +#define OTG_GINTMSK_USBRST 0x00001000 +#define OTG_GINTMSK_ENUMDNEM 0x00002000 +#define OTG_GINTMSK_ISOODRPM 0x00004000 +#define OTG_GINTMSK_EOPFM 0x00008000 +#define OTG_GINTMSK_EPMISM 0x00020000 +#define OTG_GINTMSK_IEPINT 0x00040000 +#define OTG_GINTMSK_OEPINT 0x00080000 +#define OTG_GINTMSK_IISOIXFRM 0x00100000 +#define OTG_GINTMSK_IISOOXFRM 0x00200000 +#define OTG_GINTMSK_IPXFRM 0x00200000 +#define OTG_GINTMSK_PRTIM 0x01000000 +#define OTG_GINTMSK_HCIM 0x02000000 +#define OTG_GINTMSK_PTXFEM 0x04000000 +#define OTG_GINTMSK_CIDSCHGM 0x10000000 +#define OTG_GINTMSK_DISCINT 0x20000000 +#define OTG_GINTMSK_SRQIM 0x40000000 +#define OTG_GINTMSK_WUIM 0x80000000 + +/* OTG Receive Status Pop Register (OTG_GRXSTSP) */ +/* Bits 31:25 - Reserved */ +#define OTG_GRXSTSP_FRMNUM_MASK (0xf << 21) +#define OTG_GRXSTSP_PKTSTS_MASK (0xf << 17) +#define OTG_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) +#define OTG_GRXSTSP_PKTSTS_OUT (0x2 << 17) +#define OTG_GRXSTSP_PKTSTS_IN (0x2 << 17) +#define OTG_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) +#define OTG_GRXSTSP_PKTSTS_IN_COMP (0x3 << 17) +#define OTG_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17) +#define OTG_GRXSTSP_PKTSTS_DTERR (0x5 << 17) +#define OTG_GRXSTSP_PKTSTS_SETUP (0x6 << 17) +#define OTG_GRXSTSP_PKTSTS_CHH (0x7 << 17) +#define OTG_GRXSTSP_DPID_MASK (0x3 << 15) +#define OTG_GRXSTSP_DPID_DATA0 (0x0 << 15) +#define OTG_GRXSTSP_DPID_DATA1 (0x2 << 15) +#define OTG_GRXSTSP_DPID_DATA2 (0x1 << 15) +#define OTG_GRXSTSP_DPID_MDATA (0x3 << 15) +#define OTG_GRXSTSP_BCNT_MASK (0x7ff << 4) +#define OTG_GRXSTSP_EPNUM_MASK (0xf << 0) + +/* Bits 31:22 - Reserved */ +/** Only on cores < 0x2000 */ +#define OTG_GCCFG_NOVBUSSENS (1 << 21) +/** Only on cores >= 0x2000 */ +#define OTG_GCCFG_VBDEN (1 << 21) +#define OTG_GCCFG_SOFOUTEN (1 << 20) +#define OTG_GCCFG_VBUSBSEN (1 << 19) +#define OTG_GCCFG_VBUSASEN (1 << 18) +/* Bit 17 - Reserved */ +#define OTG_GCCFG_PWRDWN (1 << 16) +/* Bits 15:0 - Reserved */ + +/* OTG FS Product ID register (OTG_CID) */ +#define OTG_CID_HAS_VBDEN 0x00002000 + +/* Device-mode CSRs */ +/* OTG device control register (OTG_DCTL) */ +/* Bits 31:12 - Reserved */ +#define OTG_DCTL_POPRGDNE (1 << 11) +#define OTG_DCTL_CGONAK (1 << 10) +#define OTG_DCTL_SGONAK (1 << 9) +#define OTG_DCTL_SGINAK (1 << 8) +#define OTG_DCTL_TCTL_MASK (7 << 4) +#define OTG_DCTL_GONSTS (1 << 3) +#define OTG_DCTL_GINSTS (1 << 2) +#define OTG_DCTL_SDIS (1 << 1) +#define OTG_DCTL_RWUSIG (1 << 0) + +/* OTG device configuration register (OTG_DCFG) */ +#define OTG_DCFG_DSPD 0x0003 +#define OTG_DCFG_NZLSOHSK 0x0004 +#define OTG_DCFG_DAD 0x07F0 +#define OTG_DCFG_PFIVL 0x1800 + +/* OTG Device IN Endpoint Common Interrupt Mask Register (OTG_DIEPMSK) */ +/* Bits 31:10 - Reserved */ +#define OTG_DIEPMSK_BIM (1 << 9) +#define OTG_DIEPMSK_TXFURM (1 << 8) +/* Bit 7 - Reserved */ +#define OTG_DIEPMSK_INEPNEM (1 << 6) +#define OTG_DIEPMSK_INEPNMM (1 << 5) +#define OTG_DIEPMSK_ITTXFEMSK (1 << 4) +#define OTG_DIEPMSK_TOM (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_DIEPMSK_EPDM (1 << 1) +#define OTG_DIEPMSK_XFRCM (1 << 0) + +/* OTG Device OUT Endpoint Common Interrupt Mask Register (OTG_DOEPMSK) */ +/* Bits 31:10 - Reserved */ +#define OTG_DOEPMSK_BOIM (1 << 9) +#define OTG_DOEPMSK_OPEM (1 << 8) +/* Bit 7 - Reserved */ +#define OTG_DOEPMSK_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_DOEPMSK_OTEPDM (1 << 4) +#define OTG_DOEPMSK_STUPM (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_DOEPMSK_EPDM (1 << 1) +#define OTG_DOEPMSK_XFRCM (1 << 0) + +/* OTG Device Control IN Endpoint 0 Control Register (OTG_DIEPCTL0) */ +#define OTG_DIEPCTL0_EPENA (1 << 31) +#define OTG_DIEPCTL0_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define OTG_DIEPCTLX_SD0PID (1 << 28) +#define OTG_DIEPCTL0_SNAK (1 << 27) +#define OTG_DIEPCTL0_CNAK (1 << 26) +#define OTG_DIEPCTL0_TXFNUM_MASK (0xf << 22) +#define OTG_DIEPCTL0_STALL (1 << 21) +/* Bit 20 - Reserved */ +#define OTG_DIEPCTL0_EPTYP_MASK (0x3 << 18) +#define OTG_DIEPCTL0_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define OTG_DIEPCTL0_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define OTG_DIEPCTL0_MPSIZ_MASK (0x3 << 0) +#define OTG_DIEPCTL0_MPSIZ_64 (0x0 << 0) +#define OTG_DIEPCTL0_MPSIZ_32 (0x1 << 0) +#define OTG_DIEPCTL0_MPSIZ_16 (0x2 << 0) +#define OTG_DIEPCTL0_MPSIZ_8 (0x3 << 0) + +/* OTG Device Control OUT Endpoint 0 Control Register (OTG_DOEPCTL0) */ +#define OTG_DOEPCTL0_EPENA (1 << 31) +#define OTG_DOEPCTL0_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define OTG_DOEPCTLX_SD0PID (1 << 28) +#define OTG_DOEPCTL0_SNAK (1 << 27) +#define OTG_DOEPCTL0_CNAK (1 << 26) +/* Bits 25:22 - Reserved */ +#define OTG_DOEPCTL0_STALL (1 << 21) +#define OTG_DOEPCTL0_SNPM (1 << 20) +#define OTG_DOEPCTL0_EPTYP_MASK (0x3 << 18) +#define OTG_DOEPCTL0_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define OTG_DOEPCTL0_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define OTG_DOEPCTL0_MPSIZ_MASK (0x3 << 0) +#define OTG_DOEPCTL0_MPSIZ_64 (0x0 << 0) +#define OTG_DOEPCTL0_MPSIZ_32 (0x1 << 0) +#define OTG_DOEPCTL0_MPSIZ_16 (0x2 << 0) +#define OTG_DOEPCTL0_MPSIZ_8 (0x3 << 0) + +/* OTG Device IN Endpoint Interrupt Register (OTG_DIEPINTx) */ +/* Bits 31:8 - Reserved */ +#define OTG_DIEPINTX_TXFE (1 << 7) +#define OTG_DIEPINTX_INEPNE (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_DIEPINTX_ITTXFE (1 << 4) +#define OTG_DIEPINTX_TOC (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_DIEPINTX_EPDISD (1 << 1) +#define OTG_DIEPINTX_XFRC (1 << 0) + +/* OTG Device IN Endpoint Interrupt Register (OTG_DOEPINTx) */ +/* Bits 31:7 - Reserved */ +#define OTG_DOEPINTX_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_DOEPINTX_OTEPDIS (1 << 4) +#define OTG_DOEPINTX_STUP (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_DOEPINTX_EPDISD (1 << 1) +#define OTG_DOEPINTX_XFRC (1 << 0) + +/* OTG Device OUT Endpoint 0 Transfer Size Register (OTG_DOEPTSIZ0) */ +/* Bit 31 - Reserved */ +#define OTG_DIEPSIZ0_STUPCNT_1 (0x1 << 29) +#define OTG_DIEPSIZ0_STUPCNT_2 (0x2 << 29) +#define OTG_DIEPSIZ0_STUPCNT_3 (0x3 << 29) +#define OTG_DIEPSIZ0_STUPCNT_MASK (0x3 << 29) +/* Bits 28:20 - Reserved */ +#define OTG_DIEPSIZ0_PKTCNT (1 << 19) +/* Bits 18:7 - Reserved */ +#define OTG_DIEPSIZ0_XFRSIZ_MASK (0x7f << 0) + + + +/* Host-mode CSRs */ +/* OTG Host non-periodic transmit FIFO size register +(OTG_HNPTXFSIZ)/Endpoint 0 Transmit FIFO size (OTG_DIEPTXF0) */ +#define OTG_HNPTXFSIZ_PTXFD_MASK (0xffff0000) +#define OTG_HNPTXFSIZ_PTXSA_MASK (0x0000ffff) + +/* OTG Host periodic transmit FIFO size register (OTG_HPTXFSIZ) */ +#define OTG_HPTXFSIZ_PTXFD_MASK (0xffff0000) +#define OTG_HPTXFSIZ_PTXSA_MASK (0x0000ffff) + +/* OTG Host Configuration Register (OTG_HCFG) */ +/* Bits 31:3 - Reserved */ +#define OTG_HCFG_FSLSS (1 << 2) +#define OTG_HCFG_FSLSPCS_48MHz (0x1 << 0) +#define OTG_HCFG_FSLSPCS_6MHz (0x2 << 0) +#define OTG_HCFG_FSLSPCS_MASK (0x3 << 0) + +/* OTG Host Frame Interval Register (OTG_HFIR) */ +/* Bits 31:16 - Reserved */ +#define OTG_HFIR_FRIVL_MASK (0x0000ffff) + +/* OTG Host frame number/frame time remaining register (OTG_HFNUM) */ +#define OTG_HFNUM_FTREM_MASK (0xffff0000) +#define OTG_HFNUM_FRNUM_MASK (0x0000ffff) + +/* OTG Host periodic transmit FIFO/queue status register (OTG_HPTXSTS) */ +#define OTG_HPTXSTS_PTXQTOP_MASK (0xff000000) +#define OTG_HPTXSTS_PTXQTOP_ODDFRM (1<<31) +#define OTG_HPTXSTS_PTXQTOP_EVENFRM (0<<31) +#define OTG_HPTXSTS_PTXQTOP_CHANNEL_NUMBER_MASK (0xf<<27) +#define OTG_HPTXSTS_PTXQTOP_ENDPOINT_NUMBER_MASK (0xf<<27) +#define OTG_HPTXSTS_PTXQTOP_TYPE_INOUT (0x00<<25) +#define OTG_HPTXSTS_PTXQTOP_TYPE_ZEROLENGTH (0x01<<25) +#define OTG_HPTXSTS_PTXQTOP_TYPE_DISABLECMD (0x11<<25) +#define OTG_HPTXSTS_PTXQTOP_TERMINATE (1<<24) +#define OTG_HPTXSTS_PTXQSAV_MASK (0x00ff0000) +#define OTG_HPTXSTS_PTXFSAVL_MASK (0x0000ffff) + +/* OTG Host all channels interrupt mask register (OTG_HAINT) */ +/* Bits 31:16 - Reserved */ +#define OTG_HAINTMSK_HAINT_MASK (0x0000ffff) + +/* OTG Host all channels interrupt mask register (OTG_HAINTMSK) */ +/* Bits 31:16 - Reserved */ +#define OTG_HAINTMSK_HAINTM_MASK (0x0000ffff) + +/* OTG Host port control and status register (OTG_HPRT) */ +/* Bits 31:19 - Reserved */ +#define OTG_HPRT_PSPD_HIGH (0x0 << 17) +#define OTG_HPRT_PSPD_FULL (0x1 << 17) +#define OTG_HPRT_PSPD_LOW (0x2 << 17) +#define OTG_HPRT_PSPD_MASK (0x3 << 17) +#define OTG_HPRT_PTCTL_DISABLED (0x0 << 13) +#define OTG_HPRT_PTCTL_J (0x1 << 13) +#define OTG_HPRT_PTCTL_K (0x2 << 13) +#define OTG_HPRT_PTCTL_SE0_NAK (0x3 << 13) +#define OTG_HPRT_PTCTL_PACKET (0x4 << 13) +#define OTG_HPRT_PTCTL_FORCE_ENABLE (0x5 << 13) +#define OTG_HPRT_PPWR (1 << 12) +#define OTG_HPRT_PLSTS_DM (1 << 11) +#define OTG_HPRT_PLSTS_DP (1 << 10) +/* Bit 9 - Reserved */ +#define OTG_HPRT_PRST (1 << 8) +#define OTG_HPRT_PSUSP (1 << 7) +#define OTG_HPRT_PRES (1 << 6) +#define OTG_HPRT_POCCHNG (1 << 5) +#define OTG_HPRT_POCA (1 << 4) +#define OTG_HPRT_PENCHNG (1 << 3) +#define OTG_HPRT_PENA (1 << 2) +#define OTG_HPRT_PCDET (1 << 1) +#define OTG_HPRT_PCSTS (1 << 0) + +/* OTG Host channel-x characteristics register (OTG_HCCHARx) */ +#define OTG_HCCHAR_CHENA (1 << 31) +#define OTG_HCCHAR_CHDIS (1 << 30) +#define OTG_HCCHAR_ODDFRM (1 << 29) +#define OTG_HCCHAR_DAD_MASK (0x7f << 22) +#define OTG_HCCHAR_MCNT_1 (0x1 << 20) +#define OTG_HCCHAR_MCNT_2 (0x2 << 20) +#define OTG_HCCHAR_MCNT_3 (0x3 << 20) +#define OTG_HCCHAR_MCNT_MASK (0x3 << 20) +#define OTG_HCCHAR_EPTYP_CONTROL (0 << 18) +#define OTG_HCCHAR_EPTYP_ISOCHRONOUS (1 << 18) +#define OTG_HCCHAR_EPTYP_BULK (2 << 18) +#define OTG_HCCHAR_EPTYP_INTERRUPT (3 << 18) +#define OTG_HCCHAR_EPTYP_MASK (3 << 18) +#define OTG_HCCHAR_LSDEV (1 << 17) +/* Bit 16 - Reserved */ +#define OTG_HCCHAR_EPDIR_OUT (0 << 15) +#define OTG_HCCHAR_EPDIR_IN (1 << 15) +#define OTG_HCCHAR_EPDIR_MASK (1 << 15) +#define OTG_HCCHAR_EPNUM_MASK (0xf << 11) +#define OTG_HCCHAR_MPSIZ_MASK (0x7ff << 0) + +/* OTG Host channel-x interrupt register (OTG_HCINTx) */ +/* Bits 31:11 - Reserved */ +#define OTG_HCINT_DTERR (1 << 10) +#define OTG_HCINT_FRMOR (1 << 9) +#define OTG_HCINT_BBERR (1 << 8) +#define OTG_HCINT_TXERR (1 << 7) +/* Note: OTG_HCINT_NYET: Only in OTG_HS */ +#define OTG_HCINT_NYET (1 << 6) +#define OTG_HCINT_ACK (1 << 5) +#define OTG_HCINT_NAK (1 << 4) +#define OTG_HCINT_STALL (1 << 3) +/* Note: OTG_HCINT_AHBERR: Only in OTG_HS */ +#define OTG_HCINT_AHBERR (1 << 2) +#define OTG_HCINT_CHH (1 << 1) +#define OTG_HCINT_XFRC (1 << 0) + +/* OTG Host channel-x interrupt mask register (OTG_HCINTMSKx) */ +/* Bits 31:11 - Reserved */ +#define OTG_HCINTMSK_DTERRM (1 << 10) +#define OTG_HCINTMSK_FRMORM (1 << 9) +#define OTG_HCINTMSK_BBERRM (1 << 8) +#define OTG_HCINTMSK_TXERRM (1 << 7) +/* Note: OTG_HCINTMSK_NYET: Only in OTG_HS */ +#define OTG_HCINTMSK_NYET (1 << 6) +#define OTG_HCINTMSK_ACKM (1 << 5) +#define OTG_HCINTMSK_NAKM (1 << 4) +#define OTG_HCINTMSK_STALLM (1 << 3) +/* Note: OTG_HCINTMSK_AHBERR: Only in OTG_HS */ +#define OTG_HCINTMSK_AHBERR (1 << 2) +#define OTG_HCINTMSK_CHHM (1 << 1) +#define OTG_HCINTMSK_XFRCM (1 << 0) + +/* OTG Host channel-x transfer size register (OTG_HCTSIZx) */ +/* Note: OTG_HCTSIZ_DOPING: Only in OTG_HS */ +#define OTG_HCTSIZ_DOPING (1 << 31) +#define OTG_HCTSIZ_DPID_DATA0 (0x0 << 29) +#define OTG_HCTSIZ_DPID_DATA1 (0x2 << 29) +#define OTG_HCTSIZ_DPID_DATA2 (0x1 << 29) +#define OTG_HCTSIZ_DPID_MDATA (0x3 << 29) +#define OTG_HCTSIZ_DPID_MASK (0x3 << 29) +#define OTG_HCTSIZ_PKTCNT_MASK (0x3ff << 19) +#define OTG_HCTSIZ_XFRSIZ_MASK (0x7ffff << 0) + + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_fs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_fs.h new file mode 100644 index 00000000..5b331cc6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_fs.h @@ -0,0 +1,98 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * This file covers definitions for the USB OTG FS peripheral. + * This is the USB core included in the F105, F107, F2, F4 devices + */ + +#ifndef LIBOPENCM3_OTG_FS_H +#define LIBOPENCM3_OTG_FS_H + +#include +#include +#include + +/***********************************************************************/ + +/* Core Global Control and Status Registers */ +#define OTG_FS_GOTGCTL MMIO32(USB_OTG_FS_BASE + OTG_GOTGCTL) +#define OTG_FS_GOTGINT MMIO32(USB_OTG_FS_BASE + OTG_GOTGINT) +#define OTG_FS_GAHBCFG MMIO32(USB_OTG_FS_BASE + OTG_GAHBCFG) +#define OTG_FS_GUSBCFG MMIO32(USB_OTG_FS_BASE + OTG_GUSBCFG) +#define OTG_FS_GRSTCTL MMIO32(USB_OTG_FS_BASE + OTG_GRSTCTL) +#define OTG_FS_GINTSTS MMIO32(USB_OTG_FS_BASE + OTG_GINTSTS) +#define OTG_FS_GINTMSK MMIO32(USB_OTG_FS_BASE + OTG_GINTMSK) +#define OTG_FS_GRXSTSR MMIO32(USB_OTG_FS_BASE + OTG_GRXSTSR) +#define OTG_FS_GRXSTSP MMIO32(USB_OTG_FS_BASE + OTG_GRXSTSP) +#define OTG_FS_GRXFSIZ MMIO32(USB_OTG_FS_BASE + OTG_GRXFSIZ) +#define OTG_FS_GNPTXFSIZ MMIO32(USB_OTG_FS_BASE + OTG_GNPTXFSIZ) +#define OTG_FS_GNPTXSTS MMIO32(USB_OTG_FS_BASE + OTG_GNPTXSTS) +#define OTG_FS_GCCFG MMIO32(USB_OTG_FS_BASE + OTG_GCCFG) +#define OTG_FS_CID MMIO32(USB_OTG_FS_BASE + OTG_CID) +#define OTG_FS_HPTXFSIZ MMIO32(USB_OTG_FS_BASE + OTG_HPTXFSIZ) +#define OTG_FS_DIEPTXF(x) MMIO32(USB_OTG_FS_BASE + OTG_DIEPTXF(x)) + + +/* Host-mode Control and Status Registers */ +#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + OTG_HCFG) +#define OTG_FS_HFIR MMIO32(USB_OTG_FS_BASE + OTG_HFIR) +#define OTG_FS_HFNUM MMIO32(USB_OTG_FS_BASE + OTG_HFNUM) +#define OTG_FS_HPTXSTS MMIO32(USB_OTG_FS_BASE + OTG_HPTXSTS) +#define OTG_FS_HAINT MMIO32(USB_OTG_FS_BASE + OTG_HAINT) +#define OTG_FS_HAINTMSK MMIO32(USB_OTG_FS_BASE + OTG_HAINTMSK) +#define OTG_FS_HPRT MMIO32(USB_OTG_FS_BASE + OTG_HPRT) +#define OTG_FS_HCCHAR(x) MMIO32(USB_OTG_FS_BASE + OTG_HCCHAR(x)) +#define OTG_FS_HCINT(x) MMIO32(USB_OTG_FS_BASE + OTG_HCINT(x)) +#define OTG_FS_HCINTMSK(x) MMIO32(USB_OTG_FS_BASE + OTG_HCINTMSK(x)) +#define OTG_FS_HCTSIZ(x) MMIO32(USB_OTG_FS_BASE + OTG_HCTSIZ(x)) + +/* Device-mode Control and Status Registers */ +#define OTG_FS_DCFG MMIO32(USB_OTG_FS_BASE + OTG_DCFG) +#define OTG_FS_DCTL MMIO32(USB_OTG_FS_BASE + OTG_DCTL) +#define OTG_FS_DSTS MMIO32(USB_OTG_FS_BASE + OTG_DSTS) +#define OTG_FS_DIEPMSK MMIO32(USB_OTG_FS_BASE + OTG_DIEPMSK) +#define OTG_FS_DOEPMSK MMIO32(USB_OTG_FS_BASE + OTG_DOEPMSK) +#define OTG_FS_DAINT MMIO32(USB_OTG_FS_BASE + OTG_DAINT) +#define OTG_FS_DAINTMSK MMIO32(USB_OTG_FS_BASE + OTG_DAINTMSK) +#define OTG_FS_DVBUSDIS MMIO32(USB_OTG_FS_BASE + OTG_DVBUSDIS) +#define OTG_FS_DVBUSPULSE MMIO32(USB_OTG_FS_BASE + OTG_DVBUSPULSE) +#define OTG_FS_DIEPEMPMSK MMIO32(USB_OTG_FS_BASE + OTG_DIEPEMPMSK) +#define OTG_FS_DIEPCTL0 MMIO32(USB_OTG_FS_BASE + OTG_DIEPCTL0) +#define OTG_FS_DIEPCTL(x) MMIO32(USB_OTG_FS_BASE + OTG_DIEPCTL(x)) +#define OTG_FS_DOEPCTL0 MMIO32(USB_OTG_FS_BASE + OTG_DOEPCTL0) +#define OTG_FS_DOEPCTL(x) MMIO32(USB_OTG_FS_BASE + OTG_DOEPCTL(x)) +#define OTG_FS_DIEPINT(x) MMIO32(USB_OTG_FS_BASE + OTG_DIEPINT(x)) +#define OTG_FS_DOEPINT(x) MMIO32(USB_OTG_FS_BASE + OTG_DOEPINT(x)) +#define OTG_FS_DIEPTSIZ0 MMIO32(USB_OTG_FS_BASE + OTG_DIEPTSIZ0) +#define OTG_FS_DOEPTSIZ0 MMIO32(USB_OTG_FS_BASE + OTG_DOEPTSIZ0) +#define OTG_FS_DIEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + OTG_DIEPTSIZ(x)) +#define OTG_FS_DTXFSTS(x) MMIO32(USB_OTG_FS_BASE + OTG_DTXFSTS(x)) +#define OTG_FS_DOEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + OTG_DOEPTSIZ(x)) + +/* Power and clock gating control and status register */ +#define OTG_FS_PCGCCTL MMIO32(USB_OTG_FS_BASE + OTG_PCGCCTL) + +/* Data FIFO */ +#define OTG_FS_FIFO(x) (&MMIO32(USB_OTG_FS_BASE \ + + (((x) + 1) \ + << 12))) + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_hs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_hs.h new file mode 100644 index 00000000..f5c8e157 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/otg_hs.h @@ -0,0 +1,163 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_OTG_HS_H +#define LIBOPENCM3_OTG_HS_H + +#include +#include +#include + +/* OTG_HS specific registers */ + +/* Host-mode Control and Status Registers */ +#define OTG_HCSPLT(x) (0x504 + 0x20*(x)) +#define OTG_HCDMA(x) (0x514 + 0x20*(x)) + +/* Device-mode Control and Status Registers */ +#define OTG_DEACHHINT 0x838 +#define OTG_DEACHHINTMSK 0x83C +#define OTG_DIEPEACHMSK1 0x844 +#define OTG_DOEPEACHMSK1 0x884 +#define OTG_DIEPDMA(x) (0x914 + 0x20*(x)) +#define OTG_DOEPDMA(x) (0xB14 + 0x20*(x)) + + + +/***********************************************************************/ + +/* Core Global Control and Status Registers */ +#define OTG_HS_GOTGCTL MMIO32(USB_OTG_HS_BASE + OTG_GOTGCTL) +#define OTG_HS_GOTGINT MMIO32(USB_OTG_HS_BASE + OTG_GOTGINT) +#define OTG_HS_GAHBCFG MMIO32(USB_OTG_HS_BASE + OTG_GAHBCFG) +#define OTG_HS_GUSBCFG MMIO32(USB_OTG_HS_BASE + OTG_GUSBCFG) +#define OTG_HS_GRSTCTL MMIO32(USB_OTG_HS_BASE + OTG_GRSTCTL) +#define OTG_HS_GINTSTS MMIO32(USB_OTG_HS_BASE + OTG_GINTSTS) +#define OTG_HS_GINTMSK MMIO32(USB_OTG_HS_BASE + OTG_GINTMSK) +#define OTG_HS_GRXSTSR MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSR) +#define OTG_HS_GRXSTSP MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSP) +#define OTG_HS_GRXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GRXFSIZ) +#define OTG_HS_GNPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GNPTXFSIZ) +#define OTG_HS_GNPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_GNPTXSTS) +#define OTG_HS_GCCFG MMIO32(USB_OTG_HS_BASE + OTG_GCCFG) +#define OTG_HS_CID MMIO32(USB_OTG_HS_BASE + OTG_CID) +#define OTG_HS_HPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_HPTXFSIZ) +#define OTG_HS_DIEPTXF(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPTXF(x)) + +/* Host-mode Control and Status Registers */ +#define OTG_HS_HCFG MMIO32(USB_OTG_HS_BASE + OTG_HCFG) +#define OTG_HS_HFIR MMIO32(USB_OTG_HS_BASE + OTG_HFIR) +#define OTG_HS_HFNUM MMIO32(USB_OTG_HS_BASE + OTG_HFNUM) +#define OTG_HS_HPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_HPTXSTS) +#define OTG_HS_HAINT MMIO32(USB_OTG_HS_BASE + OTG_HAINT) +#define OTG_HS_HAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_HAINTMSK) +#define OTG_HS_HPRT MMIO32(USB_OTG_HS_BASE + OTG_HPRT) +#define OTG_HS_HCCHAR(x) MMIO32(USB_OTG_HS_BASE + OTG_HCCHAR(x)) +#define OTG_HS_HCSPLT(x) MMIO32(USB_OTG_HS_BASE + OTG_HCSPLT(x)) +#define OTG_HS_HCINT(x) MMIO32(USB_OTG_HS_BASE + OTG_HCINT(x)) +#define OTG_HS_HCINTMSK(x) MMIO32(USB_OTG_HS_BASE + OTG_HCINTMSK(x)) +#define OTG_HS_HCTSIZ(x) MMIO32(USB_OTG_HS_BASE + OTG_HCTSIZ(x)) +#define OTG_HS_HCDMA(x) MMIO32(USB_OTG_HS_BASE + OTG_HCDMA(x)) + +/* Device-mode Control and Status Registers */ +#define OTG_HS_DCFG MMIO32(USB_OTG_HS_BASE + OTG_DCFG) +#define OTG_HS_DCTL MMIO32(USB_OTG_HS_BASE + OTG_DCTL) +#define OTG_HS_DSTS MMIO32(USB_OTG_HS_BASE + OTG_DSTS) +#define OTG_HS_DIEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPMSK) +#define OTG_HS_DOEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DOEPMSK) +#define OTG_HS_DAINT MMIO32(USB_OTG_HS_BASE + OTG_DAINT) +#define OTG_HS_DAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_DAINTMSK) +#define OTG_HS_DVBUSDIS MMIO32(USB_OTG_HS_BASE + OTG_DVBUSDIS) +#define OTG_HS_DVBUSPULSE MMIO32(USB_OTG_HS_BASE + OTG_DVBUSPULSE) +#define OTG_HS_DIEPEMPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPEMPMSK) +#define OTG_HS_DIEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL0) +#define OTG_HS_DIEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL(x)) +#define OTG_HS_DOEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL0) +#define OTG_HS_DOEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL(x)) +#define OTG_HS_DIEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPINT(x)) +#define OTG_HS_DOEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPINT(x)) +#define OTG_HS_DIEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPTSIZ0) +#define OTG_HS_DOEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPTSIZ0) +#define OTG_HS_DIEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + \ + OTG_DIEPTSIZ(x)) +#define OTG_HS_DTXFSTS(x) MMIO32(USB_OTG_HS_BASE + OTG_DTXFSTS(x)) +#define OTG_HS_DOEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + \ + OTG_DOEPTSIZ(x)) +#define OTG_HS_DEACHHINT MMIO32(USB_OTG_HS_BASE + OTG_DEACHHINT) +#define OTG_HS_DEACHHINTMSK MMIO32(USB_OTG_HS_BASE + OTG_DEACHHINTMSK) +#define OTG_HS_DIEPEACHMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPEACHMSK1) +#define OTG_HS_DOEPEACHMSK MMIO32(USB_OTG_HS_BASE + OTG_DOEPEACHMSK1) +#define OTG_HS_DIEPDMA(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPDMA(x)) +#define OTG_HS_DOEPDMA(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPDMA(x)) + +/* Power and clock gating control and status register */ +#define OTG_HS_PCGCCTL MMIO32(USB_OTG_HS_BASE + OTG_PCGCCTL) + +/* Data FIFO */ +#define OTG_HS_FIFO(x) (&MMIO32(USB_OTG_HS_BASE + OTG_FIFO(x))) + +/* Device-mode CSRs*/ +/* OTG device each endpoint interrupt register (OTG_DEACHINT) */ +/* Bits 31:18 - Reserved */ +#define OTG_DEACHHINT_OEP1INT (1 << 17) +/* Bits 16:2 - Reserved */ +#define OTG_DEACHHINT_IEP1INT (1 << 1) +/* Bit 0 - Reserved */ + +/* OTG device each in endpoint-1 interrupt register (OTG_DIEPEACHMSK1) */ +/* Bits 31:14 - Reserved */ +#define OTG_DIEPEACHMSK1_NAKM (1 << 13) +/* Bits 12:10 - Reserved */ +#define OTG_DIEPEACHMSK1_BIM (1 << 9) +#define OTG_DIEPEACHMSK1_TXFURM (1 << 8) +/* Bit 7 - Reserved */ +#define OTG_DIEPEACHMSK1_INEPNEM (1 << 6) +#define OTG_DIEPEACHMSK1_INEPNMM (1 << 5) +#define OTG_DIEPEACHMSK1_ITTXFEMSK (1 << 4) +#define OTG_DIEPEACHMSK1_TOM (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_DIEPEACHMSK1_EPDM (1 << 1) +#define OTG_DIEPEACHMSK1_XFRCM (1 << 0) + +/* OTG device each OUT endpoint-1 interrupt register (OTG_DOEPEACHMSK1) */ +/* Bits 31:15 - Reserved */ +#define OTG_DOEPEACHMSK1_NYETM (1 << 14) +#define OTG_DOEPEACHMSK1_NAKM (1 << 13) +#define OTG_DOEPEACHMSK1_BERRM (1 << 12) +/* Bits 11:10 - Reserved */ +#define OTG_DOEPEACHMSK1_BIM (1 << 9) +#define OTG_DOEPEACHMSK1_OPEM (1 << 8) +/* Bits 7:3 - Reserved */ +#define OTG_DOEPEACHMSK1_AHBERRM (1 << 2) +#define OTG_DOEPEACHMSK1_EPDM (1 << 1) +#define OTG_DOEPEACHMSK1_XFRCM (1 << 0) + +/* Host-mode CSRs */ +/* OTG host channel-x split control register (OTG_HCSPLTx) */ +#define OTG_HCSPLT_SPLITEN (1 << 31) +/* Bits 30:17 - Reserved */ +#define OTG_HCSPLT_COMPLSPLT (1 << 16) +#define OTG_HCSPLT_XACTPOS_ALL (0x3 << 14) +#define OTG_HCSPLT_XACTPOS_BEGIN (0x2 << 14) +#define OTG_HCSPLT_XACTPOS_MID (0x0 << 14) +#define OTG_HCSPLT_XACTPOS_END (0x1 << 14) +#define OTG_HCSPLT_HUBADDR_MASK (0x7f << 7) +#define OTG_HCSPLT_PORTADDR_MASK (0x7f << 0) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/pwr.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/pwr.h new file mode 100644 index 00000000..2b21be58 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/pwr.h @@ -0,0 +1,44 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32F7) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/quadspi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/quadspi.h new file mode 100644 index 00000000..99d74d9a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/quadspi.h @@ -0,0 +1,28 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F4) +# include +#else +# error "quadspi.h not available for this family." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rcc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rcc.h new file mode 100644 index 00000000..b87f950a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rcc.h @@ -0,0 +1,44 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32F7) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rng.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rng.h new file mode 100644 index 00000000..40687af2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rng.h @@ -0,0 +1,35 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F2) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32F7) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rtc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rtc.h new file mode 100644 index 00000000..9b9dd242 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/rtc.h @@ -0,0 +1,36 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/sdio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/sdio.h new file mode 100644 index 00000000..6695f874 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/sdio.h @@ -0,0 +1,425 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SDIO_H +#define LIBOPENCM3_SDIO_H + +#include +#include + +/* --- SDIO registers ------------------------------------------------------ */ + +/* SDIO power control register (SDIO_POWER) */ +#define SDIO_POWER MMIO32(SDIO_BASE + 0x00) + +/* SDI clock control register (SDIO_CLKCR) */ +#define SDIO_CLKCR MMIO32(SDIO_BASE + 0x04) + +/* SDIO argument register (SDIO_ARG) */ +#define SDIO_ARG MMIO32(SDIO_BASE + 0x08) + +/* SDIO command register (SDIO_CMD) */ +#define SDIO_CMD MMIO32(SDIO_BASE + 0x0C) + +/* SDIO command response register (SDIO_RESPCMD) */ +#define SDIO_RESPCMD MMIO32(SDIO_BASE + 0x10) + +/* SDIO response 1..4 register (SDIO_RESPx) */ +#define SDIO_RESP1 MMIO32(SDIO_BASE + 0x14) +#define SDIO_RESP2 MMIO32(SDIO_BASE + 0x18) +#define SDIO_RESP3 MMIO32(SDIO_BASE + 0x1C) +#define SDIO_RESP4 MMIO32(SDIO_BASE + 0x20) + +/* SDIO data timer register (SDIO_DTIMER) */ +#define SDIO_DTIMER MMIO32(SDIO_BASE + 0x24) + +/* SDIO data length register (SDIO_DLEN) */ +#define SDIO_DLEN MMIO32(SDIO_BASE + 0x28) + +/* SDIO data control register (SDIO_DCTRL) */ +#define SDIO_DCTRL MMIO32(SDIO_BASE + 0x2C) + +/* SDIO data counter register (SDIO_DCOUNT) */ +/* read only, write has no effect */ +#define SDIO_DCOUNT MMIO32(SDIO_BASE + 0x30) + +/* SDIO status register (SDIO_STA) */ +#define SDIO_STA MMIO32(SDIO_BASE + 0x34) + +/* SDIO interrupt clear register (SDIO_ICR) */ +#define SDIO_ICR MMIO32(SDIO_BASE + 0x38) + +/* SDIO mask register (SDIO_MASK) */ +#define SDIO_MASK MMIO32(SDIO_BASE + 0x3C) + +/* SDIO FIFO counter register (SDIO_FIFOCNT) */ +#define SDIO_FIFOCNT MMIO32(SDIO_BASE + 0x48) + +/* SDIO data FIFO register (SDIO_FIFO) */ +/* the SDIO data FIFO is 32 32bit words long, beginning at this address */ +#define SDIO_FIFO MMIO32(SDIO_BASE + 0x80) + + +/* --- SDIO_POWER values --------------------------------------------------- */ + +#define SDIO_POWER_PWRCTRL_SHIFT 0 +#define SDIO_POWER_PWRCTRL_PWROFF (0x0 << SDIO_POWER_PWRCTRL_SHIFT) +/* what does "10: Reserved power-up" mean? */ +#define SDIO_POWER_PWRCTRL_RSVPWRUP (0x2 << SDIO_POWER_PWRCTRL_SHIFT) +#define SDIO_POWER_PWRCTRL_PWRON (0x3 << SDIO_POWER_PWRCTRL_SHIFT) + + +/* --- SDIO_POWER values --------------------------------------------------- */ + +/* HWFC_EN: HW Flow Control enable */ +#define SDIO_CLKCR_HWFC_EN (1 << 14) + +/* NEGEDGE: SDIO_CK dephasing selection bit */ +#define SDIO_CLKCR_NEGEDGE (1 << 13) + +/* WIDBUS: Wide bus mode enable bit */ +/* set the width of the data bus */ +#define SDIO_CLKCR_WIDBUS_SHIFT 11 +#define SDIO_CLKCR_WIDBUS_1 (0x0 << SDIO_CLKCR_WIDBUS_SHIFT) +#define SDIO_CLKCR_WIDBUS_4 (0x1 << SDIO_CLKCR_WIDBUS_SHIFT) +#define SDIO_CLKCR_WIDBUS_8 (0x2 << SDIO_CLKCR_WIDBUS_SHIFT) + +/* BYPASS: Clock divider bypass enable bit */ +#define SDIO_CLKCR_BYPASS (1 << 10) + +/* PWRSAV: Power saving configuration bit */ +#define SDIO_CLKCR_PWRSAV (1 << 9) + +/* CLKEN: Clock enable bit */ +#define SDIO_CLKCR_CLKEN (1 << 8) + +/* CLKDIV: Clock divide factor */ +#define SDIO_CLKCR_CLKDIV_SHIFT 0 +#define SDIO_CLKCR_CLKDIV_MSK (0xFF << SDIO_CLKCR_CLKDIV_SHIFT) + + +/* --- SDIO_CMD values ---------------------------------------------------- */ + +/* ATACMD: CE-ATA command */ +#define SDIO_CMD_ATACMD (1 << 14) + +/* nIEN: not Interrupt Enable */ +#define SDIO_CMD_NIEN (1 << 13) + +/* ENCMDcompl: Enable CMD completion */ +#define SDIO_CMD_ENCMDCOMPL (1 << 12) + +/* SDIOSuspend: SD I/O suspend command */ +#define SDIO_CMD_SDIOSUSPEND (1 << 11) + +/* CPSMEN: Command path state machine (CPSM) Enable bit */ +#define SDIO_CMD_CPSMEN (1 << 10) + +/* WAITPEND: CPSM Waits for ends of data transfer (CmdPend internal signal) */ +#define SDIO_CMD_WAITPEND (1 << 9) + +/* WAITINT: CPSM waits for interrupt request */ +#define SDIO_CMD_WAITINT (1 << 8) + +/* WAITRESP: Wait for response bits */ +#define SDIO_CMD_WAITRESP_SHIFT 6 +/* 00: No response, expect CMDSENT flag */ +#define SDIO_CMD_WAITRESP_NO_0 (0x0 << SDIO_CMD_WAITRESP_SHIFT) +/* 01: Short response, expect CMDREND or CCRCFAIL flag */ +#define SDIO_CMD_WAITRESP_SHORT (0x1 << SDIO_CMD_WAITRESP_SHIFT) +/* 10: No response, expect CMDSENT flag */ +#define SDIO_CMD_WAITRESP_NO_2 (0x2 << SDIO_CMD_WAITRESP_SHIFT) +/* 11: Long response, expect CMDREND or CCRCFAIL flag */ +#define SDIO_CMD_WAITRESP_LONG (0x3 << SDIO_CMD_WAITRESP_SHIFT) + +/* CMDINDEX: Command index */ +#define SDIO_CMD_CMDINDEX_SHIFT 0 +#define SDIO_CMD_CMDINDEX_MSK (0x3F << SDIO_CMD_CMDINDEX_SHIFT) + + +/* --- SDIO_RESPCMD values ------------------------------------------------ */ + +#define SDIO_RESPCMD_SHIFT 0 +#define SDIO_RESPCMD_MSK (0x3F << SDIO_RESPCMD_SHIFT) + + +/* --- SDIO_DCTRL values -------------------------------------------------- */ + +/* SDIOEN: SD I/O enable functions */ +#define SDIO_DCTRL_SDIOEN (1 << 11) + +/* RWMOD: Read wait mode */ +/* 0: Read Wait control stopping SDIO_D2 + * 1: Read Wait control using SDIO_CK + */ +#define SDIO_DCTRL_RWMOD (1 << 10) + +/* RWSTOP: Read wait stop */ +/* 0: Read wait in progress if RWSTART bit is set + * 1: Enable for read wait stop if RWSTART bit is set + */ +#define SDIO_DCTRL_RWSTOP (1 << 9) + +/* RWSTART: Read wait start */ +#define SDIO_DCTRL_RWSTART (1 << 8) + +/* DBLOCKSIZE: Data block size */ +/* SDIO_DCTRL_DBLOCKSIZE_n + * block size is 2**n bytes with 0<=n<=14 + */ +#define SDIO_DCTRL_DBLOCKSIZE_SHIFT 4 +#define SDIO_DCTRL_DBLOCKSIZE_0 (0x0 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_1 (0x1 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_2 (0x2 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_3 (0x3 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_4 (0x4 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_5 (0x5 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_6 (0x6 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_7 (0x7 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_8 (0x8 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_9 (0x9 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_10 (0xA << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_11 (0xB << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_12 (0xC << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_13 (0xD << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_14 (0xE << SDIO_DCTRL_DBLOCKSIZE_SHIFT) + +/* DMAEN: DMA enable bit */ +#define SDIO_DCTRL_DMAEN (1 << 3) + +/* DTMODE: Data transfer mode selection 1: Stream or SDIO multi byte transfer */ +#define SDIO_DCTRL_DTMODE (1 << 2) + +/* DTDIR: Data transfer direction selection */ +/* 0: From controller to card. + * 1: From card to controller. + */ +#define SDIO_DCTRL_DTDIR (1 << 1) + +/* DTEN: Data transfer enabled bit */ +#define SDIO_DCTRL_DTEN (1 << 0) + + +/* --- SDIO_STA values ---------------------------------------------------- */ + +/* CEATAEND: CE-ATA command completion signal received for CMD61 */ +#define SDIO_STA_CEATAEND (1 << 23) + +/* SDIOIT: SDIO interrupt received */ +#define SDIO_STA_SDIOIT (1 << 22) + +/* RXDAVL: Data available in receive FIFO */ +#define SDIO_STA_RXDAVL (1 << 21) + +/* TXDAVL: Data available in transmit FIFO */ +#define SDIO_STA_TXDAVL (1 << 20) + +/* RXFIFOE: Receive FIFO empty */ +#define SDIO_STA_RXFIFOE (1 << 19) + +/* TXFIFOE: Transmit FIFO empty */ +/* HW Flow Control enabled -> TXFIFOE signals becomes activated when the FIFO + * contains 2 words. + */ +#define SDIO_STA_TXFIFOE (1 << 18) + +/* RXFIFOF: Receive FIFO full */ +/* HW Flow Control enabled => RXFIFOF signals becomes activated 2 words before + * the FIFO is full. + */ +#define SDIO_STA_RXFIFOF (1 << 17) + +/* TXFIFOF: Transmit FIFO full */ +#define SDIO_STA_TXFIFOF (1 << 16) + +/* RXFIFOHF: Receive FIFO half full: there are at least 8 words in the FIFO */ +#define SDIO_STA_RXFIFOHF (1 << 15) + +/* TXFIFOHE: Transmit FIFO half empty: at least 8 words can be written into + * the FIFO + */ +#define SDIO_STA_TXFIFOHE (1 << 14) + +/* RXACT: Data receive in progress */ +#define SDIO_STA_RXACT (1 << 13) + +/* TXACT: Data transmit in progress */ +#define SDIO_STA_TXACT (1 << 12) + +/* CMDACT: Command transfer in progress */ +#define SDIO_STA_CMDACT (1 << 11) + +/* DBCKEND: Data block sent/received (CRC check passed) */ +#define SDIO_STA_DBCKEND (1 << 10) + +/* STBITERR: Start bit not detected on all data signals in wide bus mode */ +#define SDIO_STA_STBITERR (1 << 9) + +/* DATAEND: Data end (data counter, SDIDCOUNT, is zero) */ +#define SDIO_STA_DATAEND (1 << 8) + +/* CMDSENT: Command sent (no response required) */ +#define SDIO_STA_CMDSENT (1 << 7) + +/* CMDREND: Command response received (CRC check passed) */ +#define SDIO_STA_CMDREND (1 << 6) + +/* RXOVERR: Received FIFO overrun error */ +#define SDIO_STA_RXOVERR (1 << 5) + +/* TXUNDERR: Transmit FIFO underrun error */ +#define SDIO_STA_TXUNDERR (1 << 4) + +/* DTIMEOUT: Data timeout */ +#define SDIO_STA_DTIMEOUT (1 << 3) + +/* CTIMEOUT: Command response timeout */ +#define SDIO_STA_CTIMEOUT (1 << 2) + +/* DCRCFAIL: Data block sent/received (CRC check failed) */ +#define SDIO_STA_DCRCFAIL (1 << 1) + +/* CCRCFAIL: Command response received (CRC check failed) */ +#define SDIO_STA_CCRCFAIL (1 << 0) + + +/* --- SDIO_ICR values ---------------------------------------------------- */ + +/* CEATAENDC: CEATAEND flag clear bit */ +#define SDIO_ICR_CEATAENDC (1 << 23) + +/* SDIOITC: SDIOIT flag clear bit */ +#define SDIO_ICR_SDIOITC (1 << 22) + +/* DBCKENDC: DBCKEND flag clear bit */ +#define SDIO_ICR_DBCKENDC (1 << 10) + +/* STBITERRC: STBITERR flag clear bit */ +#define SDIO_ICR_STBITERRC (1 << 9) + +/* DATAENDC: DATAEND flag clear bit */ +#define SDIO_ICR_DATAENDC (1 << 8) + +/* CMDSENTC: CMDSENT flag clear bit */ +#define SDIO_ICR_CMDSENTC (1 << 7) + +/* CMDRENDC: CMDREND flag clear bit */ +#define SDIO_ICR_CMDRENDC (1 << 6) + +/* RXOVERRC: RXOVERR flag clear bit */ +#define SDIO_ICR_RXOVERRC (1 << 5) + +/* TXUNDERRC: TXUNDERR flag clear bit */ +#define SDIO_ICR_TXUNDERRC (1 << 4) + +/* DTIMEOUTC: DTIMEOUT flag clear bit */ +#define SDIO_ICR_DTIMEOUTC (1 << 3) + +/* CTIMEOUTC: CTIMEOUT flag clear bit */ +#define SDIO_ICR_CTIMEOUTC (1 << 2) + +/* DCRCFAILC: DCRCFAIL flag clear bit */ +#define SDIO_ICR_DCRCFAILC (1 << 1) + +/* CCRCFAILC: CCRCFAIL flag clear bit */ +#define SDIO_ICR_CCRCFAILC (1 << 0) + + +/* --- SDIO_MASK values --------------------------------------------------- */ + +/* CEATAENDIE: CE-ATA command completion signal received interrupt enable */ +#define SDIO_MASK_CEATAENDIE (1 << 23) + +/* SDIOITIE: SDIO mode interrupt received interrupt enable */ +#define SDIO_MASK_SDIOITIE (1 << 22) + +/* RXDAVLIE: Data available in Rx FIFO interrupt enable */ +#define SDIO_MASK_RXDAVLIE (1 << 21) + +/* TXDAVLIE: Data available in Tx FIFO interrupt enable */ +#define SDIO_MASK_TXDAVLIE (1 << 20) + +/* RXFIFOEIE: Rx FIFO empty interrupt enable */ +#define SDIO_MASK_RXFIFOEIE (1 << 19) + +/* TXFIFOEIE: Tx FIFO empty interrupt enable */ +#define SDIO_MASK_TXFIFOEIE (1 << 18) + +/* RXFIFOFIE: Rx FIFO full interrupt enable */ +#define SDIO_MASK_RXFIFOFIE (1 << 17) + +/* TXFIFOFIE: Tx FIFO full interrupt enable */ +#define SDIO_MASK_TXFIFOFIE (1 << 16) + +/* RXFIFOHFIE: Rx FIFO half full interrupt enable */ +#define SDIO_MASK_RXFIFOHFIE (1 << 15) + +/* TXFIFOHEIE: Tx FIFO half empty interrupt enable */ +#define SDIO_MASK_TXFIFOHEIE (1 << 14) + +/* RXACTIE: Data receive acting interrupt enable */ +#define SDIO_MASK_RXACTIE (1 << 13) + +/* TXACTIE: Data transmit acting interrupt enable */ +#define SDIO_MASK_TXACTIE (1 << 12) + +/* CMDACTIE: Command acting interrupt enable */ +#define SDIO_MASK_CMDACTIE (1 << 11) + +/* DBCKENDIE: Data block end interrupt enable */ +#define SDIO_MASK_DBCKENDIE (1 << 10) + +/* STBITERRIE: Start bit error interrupt enable */ +#define SDIO_MASK_STBITERRIE (1 << 9) + +/* DATAENDIE: Data end interrupt enable */ +#define SDIO_MASK_DATAENDIE (1 << 8) + +/* CMDSENTIE: Command sent interrupt enable */ +#define SDIO_MASK_CMDSENTIE (1 << 7) + +/* CMDRENDIE: Command response received interrupt enable */ +#define SDIO_MASK_CMDRENDIE (1 << 6) + +/* RXOVERRIE: Rx FIFO overrun error interrupt enable */ +#define SDIO_MASK_RXOVERRIE (1 << 5) + +/* TXUNDERRIE: Tx FIFO underrun error interrupt enable */ +#define SDIO_MASK_TXUNDERRIE (1 << 4) + +/* DTIMEOUTIE: Data timeout interrupt enable */ +#define SDIO_MASK_DTIMEOUTIE (1 << 3) + +/* CTIMEOUTIE: Command timeout interrupt enable */ +#define SDIO_MASK_CTIMEOUTIE (1 << 2) + +/* DCRCFAILIE: Data CRC fail interrupt enable */ +#define SDIO_MASK_DCRCFAILIE (1 << 1) + +/* CCRCFAILIE: Command CRC fail interrupt enable */ +#define SDIO_MASK_CCRCFAILIE (1 << 0) + + +/* --- Function prototypes ------------------------------------------------- */ + + +/* TODO */ + + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/spi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/spi.h new file mode 100644 index 00000000..edaea4cf --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/spi.h @@ -0,0 +1,38 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/st_usbfs.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/st_usbfs.h new file mode 100644 index 00000000..efab45fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/st_usbfs.h @@ -0,0 +1,40 @@ +/* This provides unification of USB code for supported STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +#define LIBOPENCM3_ST_USBFS_H + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#else +# error "STM32 family not defined or not supported." +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/syscfg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/syscfg.h new file mode 100644 index 00000000..503556f1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/syscfg.h @@ -0,0 +1,38 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/timer.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/timer.h new file mode 100644 index 00000000..5e4899bd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/timer.h @@ -0,0 +1,44 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L0) +# include +#elif defined(STM32L1) +# include +#elif defined(STM32L4) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tools.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tools.h new file mode 100644 index 00000000..ef8d7b06 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tools.h @@ -0,0 +1,66 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TOOLS_H +#define LIBOPENCM3_TOOLS_H + +/* + * Register accessors / manipulators + */ + +/* Get register content. */ +#define GET_REG(REG) ((uint16_t) *(REG)) + +/* Set register content. */ +#define SET_REG(REG, VAL) (*(REG) = (uint16_t)(VAL)) + +/* Clear register bit. */ +#define CLR_REG_BIT(REG, BIT) SET_REG((REG), (~(BIT))) + +/* Clear register bit masking out some bits that must not be touched. */ +#define CLR_REG_BIT_MSK_AND_SET(REG, MSK, BIT, EXTRA_BITS) \ + SET_REG((REG), (GET_REG((REG)) & (MSK) & (~(BIT))) | (EXTRA_BITS)) + +#define CLR_REG_BIT_MSK(REG, MSK, BIT) \ + CLR_REG_BIT_MSK_AND_SET((REG), (MSK), (BIT), 0) + +/* Get masked out bit value. */ +#define GET_REG_BIT(REG, BIT) (GET_REG(REG) & (BIT)) + +/* + * Set/reset a bit in a masked window by using toggle mechanism. + * + * This means that we look at the bits in the bit window designated by + * the mask. If the bit in the masked window is not matching the + * bit mask BIT then we write 1 and if the bit in the masked window is + * matching the bit mask BIT we write 0. + * + * TODO: We may need a faster implementation of that one? + */ +#define TOG_SET_REG_BIT_MSK_AND_SET(REG, MSK, BIT, EXTRA_BITS) \ +do { \ + register uint16_t toggle_mask = GET_REG(REG) & (MSK); \ + toggle_mask ^= BIT; \ + SET_REG((REG), toggle_mask | (EXTRA_BITS)); \ +} while (0) + +#define TOG_SET_REG_BIT_MSK(REG, MSK, BIT) \ + TOG_SET_REG_BIT_MSK_AND_SET((REG), (MSK), (BIT), 0) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tsc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tsc.h new file mode 100644 index 00000000..18956218 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/tsc.h @@ -0,0 +1,28 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/usart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/usart.h new file mode 100644 index 00000000..6121ff6e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/usart.h @@ -0,0 +1,38 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/wwdg.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/wwdg.h new file mode 100644 index 00000000..ef75f095 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/stm32/wwdg.h @@ -0,0 +1,83 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_WWDG_H +#define LIBOPENCM3_WWDG_H + +#include +#include + +/* --- WWDG registers ------------------------------------------------------ */ + +/* Control register (WWDG_CR) */ +#define WWDG_CR MMIO32(WWDG_BASE + 0x00) + +/* Configuration register (WWDG_CFR) */ +#define WWDG_CFR MMIO32(WWDG_BASE + 0x04) + +/* Status register (WWDG_SR) */ +#define WWDG_SR MMIO32(WWDG_BASE + 0x08) + +/* --- WWDG_CR values ------------------------------------------------------ */ + +/* Bits [31:8]: Reserved */ + +/* WDGA: Activation bit */ +#define WWDG_CR_WDGA (1 << 7) + +/* T[6:0]: 7-bit counter (MSB to LSB) */ +#define WWDG_CR_T_LSB 0 +#define WWDG_CR_T0 (1 << 0) +#define WWDG_CR_T1 (1 << 1) +#define WWDG_CR_T2 (1 << 2) +#define WWDG_CR_T3 (1 << 3) +#define WWDG_CR_T4 (1 << 4) +#define WWDG_CR_T5 (1 << 5) +#define WWDG_CR_T6 (1 << 6) + +/* --- WWDG_CFR values ----------------------------------------------------- */ + +/* Bits [31:10]: Reserved */ + +/* EWI: Early wakeup interrupt */ +#define WWDG_CFR_EWI (1 << 9) + +/* WDGTB[8:7]: Timer base */ +#define WWDG_CFR_WDGTB_LSB 7 +#define WWDG_CFR_WDGTB_CK_DIV1 0x0 +#define WWDG_CFR_WDGTB_CK_DIV2 0x1 +#define WWDG_CFR_WDGTB_CK_DIV4 0x2 +#define WWDG_CFR_WDGTB_CK_DIV8 0x3 + +/* W[6:0]: 7-bit window value */ +#define WWDG_CFG_W_LSB 0 +#define WWDG_CFG_W (1 << 0) + +/* --- WWDG_SR values ------------------------------------------------------ */ + +/* Bits [31:1]: Reserved */ + +/* EWIF: Early wakeup interrupt flag */ +#define WWDG_SR_EWIF (1 << 0) + +/* --- WWDG function prototypes---------------------------------------------- */ + +/* TODO */ + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/audio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/audio.h new file mode 100644 index 00000000..b01deaf0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/audio.h @@ -0,0 +1,94 @@ +/** @defgroup usb_audio_defines USB Audio Type Definitions + +@brief Defined Constants and Types for the USB Audio Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2014 +Daniel Thompson + +@date 19 April 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Daniel Thompson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_USB_AUDIO_H +#define LIBOPENCM3_USB_AUDIO_H + +/* + * Definitions from the USB_AUDIO_ or usb_audio_ namespace come from: + * "Universal Serial Bus Class Definitions for Audio Devices, Revision 1.0" + */ + +/* Table A-1: Audio Interface Class Code */ +#define USB_CLASS_AUDIO 0x01 + +/* Table A-2: Audio Interface Subclass Codes */ +#define USB_AUDIO_SUBCLASS_UNDEFINED 0x00 +#define USB_AUDIO_SUBCLASS_CONTROL 0x01 +#define USB_AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define USB_AUDIO_SUBCLASS_MIDISTREAMING 0x03 + +/* Table A-4: Audio Class-specific Descriptor Types */ +#define USB_AUDIO_DT_CS_UNDEFINED 0x20 +#define USB_AUDIO_DT_CS_DEVICE 0x21 +#define USB_AUDIO_DT_CS_CONFIGURATION 0x22 +#define USB_AUDIO_DT_CS_STRING 0x23 +#define USB_AUDIO_DT_CS_INTERFACE 0x24 +#define USB_AUDIO_DT_CS_ENDPOINT 0x25 + +/* Table A-5: Audio Class-Specific AC Interface Descriptor Subtypes */ +#define USB_AUDIO_TYPE_AC_DESCRIPTOR_UNDEFINED 0x00 +#define USB_AUDIO_TYPE_HEADER 0x01 +#define USB_AUDIO_TYPE_INPUT_TERMINAL 0x02 +#define USB_AUDIO_TYPE_OUTPUT_TERMINAL 0x03 +#define USB_AUDIO_TYPE_MIXER_UNIT 0x04 +#define USB_AUDIO_TYPE_SELECTOR_UNIT 0x05 +#define USB_AUDIO_TYPE_FEATURE_UNIT 0x06 +#define USB_AUDIO_TYPE_PROCESSING_UNIT 0x07 +#define USB_AUDIO_TYPE_EXTENSION_UNIT 0x08 + +/* Table 4-2: Class-Specific AC Interface Header Descriptor (head) */ +struct usb_audio_header_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdADC; + uint16_t wTotalLength; + uint8_t binCollection; + /* ... */ +} __attribute__((packed)); + +/* Table 4-2: Class-Specific AC Interface Header Descriptor (body) */ +struct usb_audio_header_descriptor_body { + /* ... */ + uint8_t baInterfaceNr; +} __attribute__((packed)); + +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/cdc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/cdc.h new file mode 100644 index 00000000..20b7836f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/cdc.h @@ -0,0 +1,162 @@ +/** @defgroup usb_cdc_defines USB CDC Type Definitions + +@brief Defined Constants and Types for the USB CDC Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __CDC_H +#define __CDC_H + +/* Definitions of Communications Device Class from + * "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2" + */ + +/* Table 2: Communications Device Class Code */ +#define USB_CLASS_CDC 0x02 + +/* Table 4: Class Subclass Code */ +#define USB_CDC_SUBCLASS_DLCM 0x01 +#define USB_CDC_SUBCLASS_ACM 0x02 +/* ... */ + +/* Table 5 Communications Interface Class Control Protocol Codes */ +#define USB_CDC_PROTOCOL_NONE 0x00 +#define USB_CDC_PROTOCOL_AT 0x01 +/* ... */ + +/* Table 6: Data Interface Class Code */ +#define USB_CLASS_DATA 0x0A + +/* Table 12: Type Values for the bDescriptorType Field */ +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 + +/* Table 13: bDescriptor SubType in Communications Class Functional + * Descriptors */ +#define USB_CDC_TYPE_HEADER 0x00 +#define USB_CDC_TYPE_CALL_MANAGEMENT 0x01 +#define USB_CDC_TYPE_ACM 0x02 +/* ... */ +#define USB_CDC_TYPE_UNION 0x06 +/* ... */ + +/* Table 15: Class-Specific Descriptor Header Format */ +struct usb_cdc_header_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdCDC; +} __attribute__((packed)); + +/* Table 16: Union Interface Functional Descriptor */ +struct usb_cdc_union_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bControlInterface; + uint8_t bSubordinateInterface0; + /* ... */ +} __attribute__((packed)); + + +/* Definitions for Abstract Control Model devices from: + * "Universal Serial Bus Communications Class Subclass Specification for + * PSTN Devices" + */ + +/* Table 3: Call Management Functional Descriptor */ +struct usb_cdc_call_management_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} __attribute__((packed)); + +/* Table 4: Abstract Control Management Functional Descriptor */ +struct usb_cdc_acm_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} __attribute__((packed)); + +/* Table 13: Class-Specific Request Codes for PSTN subclasses */ +/* ... */ +#define USB_CDC_REQ_SET_LINE_CODING 0x20 +/* ... */ +#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 +/* ... */ + +/* Table 17: Line Coding Structure */ +struct usb_cdc_line_coding { + uint32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} __attribute__((packed)); + +enum usb_cdc_line_coding_bCharFormat { + USB_CDC_1_STOP_BITS = 0, + USB_CDC_1_5_STOP_BITS = 1, + USB_CDC_2_STOP_BITS = 2, +}; + +enum usb_cdc_line_coding_bParityType { + USB_CDC_NO_PARITY = 0, + USB_CDC_ODD_PARITY = 1, + USB_CDC_EVEN_PARITY = 2, + USB_CDC_MARK_PARITY = 3, + USB_CDC_SPACE_PARITY = 4, +}; + +/* Table 30: Class-Specific Notification Codes for PSTN subclasses */ +/* ... */ +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 +/* ... */ + +/* Notification Structure */ +struct usb_cdc_notification { + uint8_t bmRequestType; + uint8_t bNotification; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__((packed)); + +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/dfu.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/dfu.h new file mode 100644 index 00000000..b7f028c0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/dfu.h @@ -0,0 +1,102 @@ +/** @defgroup usb_dfu_defines USB DFU Type Definitions + +@brief Defined Constants and Types for the USB DFU Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __DFU_H +#define __DFU_H + +enum dfu_req { + DFU_DETACH, + DFU_DNLOAD, + DFU_UPLOAD, + DFU_GETSTATUS, + DFU_CLRSTATUS, + DFU_GETSTATE, + DFU_ABORT, +}; + +enum dfu_status { + DFU_STATUS_OK, + DFU_STATUS_ERR_TARGET, + DFU_STATUS_ERR_FILE, + DFU_STATUS_ERR_WRITE, + DFU_STATUS_ERR_ERASE, + DFU_STATUS_ERR_CHECK_ERASED, + DFU_STATUS_ERR_PROG, + DFU_STATUS_ERR_VERIFY, + DFU_STATUS_ERR_ADDRESS, + DFU_STATUS_ERR_NOTDONE, + DFU_STATUS_ERR_FIRMWARE, + DFU_STATUS_ERR_VENDOR, + DFU_STATUS_ERR_USBR, + DFU_STATUS_ERR_POR, + DFU_STATUS_ERR_UNKNOWN, + DFU_STATUS_ERR_STALLEDPKT, +}; + +enum dfu_state { + STATE_APP_IDLE, + STATE_APP_DETACH, + STATE_DFU_IDLE, + STATE_DFU_DNLOAD_SYNC, + STATE_DFU_DNBUSY, + STATE_DFU_DNLOAD_IDLE, + STATE_DFU_MANIFEST_SYNC, + STATE_DFU_MANIFEST, + STATE_DFU_MANIFEST_WAIT_RESET, + STATE_DFU_UPLOAD_IDLE, + STATE_DFU_ERROR, +}; + +#define DFU_FUNCTIONAL 0x21 +struct usb_dfu_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bmAttributes; +#define USB_DFU_CAN_DOWNLOAD 0x01 +#define USB_DFU_CAN_UPLOAD 0x02 +#define USB_DFU_MANIFEST_TOLERANT 0x04 +#define USB_DFU_WILL_DETACH 0x08 + + uint16_t wDetachTimeout; + uint16_t wTransferSize; + uint16_t bcdDFUVersion; +} __attribute__((packed)); + +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/doc-usb.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/doc-usb.h new file mode 100644 index 00000000..faa01b11 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/doc-usb.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 Generic USB + +@version 1.0.0 + +@date 10 March 2013 + +API documentation for Generic USB. + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup USB Generic USB +Libraries for Generic USB. + +@version 1.0.0 + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup USB_defines Generic USB Defines + +@brief Defined Constants and Types for Generic USB. + +@version 1.0.0 + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/hid.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/hid.h new file mode 100644 index 00000000..87f4924d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/hid.h @@ -0,0 +1,59 @@ +/** @defgroup usb_hid_defines USB HID Type Definitions + +@brief Defined Constants and Types for the USB HID Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __HID_H +#define __HID_H + +#include + +#define USB_CLASS_HID 3 + +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 + +struct usb_hid_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; + uint8_t bCountryCode; + uint8_t bNumDescriptors; +} __attribute__((packed)); + +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/midi.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/midi.h new file mode 100644 index 00000000..11101415 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/midi.h @@ -0,0 +1,190 @@ +/** @defgroup usb_audio_defines USB MIDI Type Definitions + +@brief Defined Constants and Types for the USB MIDI Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2014 +Daniel Thompson + +@date 19 April 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Daniel Thompson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_USB_MIDI_H +#define LIBOPENCM3_USB_MIDI_H + +/* + * Definitions from the USB_MIDI_ or usb_midi_ namespace come from: + * "Universal Serial Bus Class Definitions for MIDI Devices, Revision 1.0" + */ + +/* Appendix A.1: MS Class-Specific Interface Descriptor Subtypes */ +#define USB_MIDI_SUBTYPE_MS_DESCRIPTOR_UNDEFINED 0x00 +#define USB_MIDI_SUBTYPE_MS_HEADER 0x01 +#define USB_MIDI_SUBTYPE_MIDI_IN_JACK 0x02 +#define USB_MIDI_SUBTYPE_MIDI_OUT_JACK 0x03 +#define USB_MIDI_SUBTYPE_MIDI_ELEMENT 0x04 + +/* Appendix A.2: MS Class-Specific Endpoint Descriptor Subtypes */ +#define USB_MIDI_SUBTYPE_DESCRIPTOR_UNDEFINED 0x00 +#define USB_MIDI_SUBTYPE_MS_GENERAL 0x01 + +/* Appendix A.3: MS MIDI IN and OUT Jack types */ +#define USB_MIDI_JACK_TYPE_UNDEFINED 0x00 +#define USB_MIDI_JACK_TYPE_EMBEDDED 0x01 +#define USB_MIDI_JACK_TYPE_EXTERNAL 0x02 + +/* Appendix A.5.1 Endpoint Control Selectors */ +#define USB_MIDI_EP_CONTROL_UNDEFINED 0x00 +#define USB_MIDI_ASSOCIATION_CONTROL 0x01 + + +/* Table 6-2: Class-Specific MS Interface Header Descriptor */ +struct usb_midi_header_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdMSC; + uint16_t wTotalLength; +} __attribute__((packed)); + +/* Table 6-3: MIDI IN Jack Descriptor */ +struct usb_midi_in_jack_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bJackType; + uint8_t bJackID; + uint8_t iJack; +} __attribute__((packed)); + +/* Table 6-4: MIDI OUT Jack Descriptor (head) */ +struct usb_midi_out_jack_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bJackType; + uint8_t bJackID; + uint8_t bNrInputPins; + /* ... */ +} __attribute__((packed)); + +/* Table 6.4: MIDI OUT Jack Descriptor (body) */ +struct usb_midi_out_jack_descriptor_body { + /* ... */ + uint8_t baSourceID; + uint8_t baSourcePin; + /* ... */ +} __attribute__((packed)); + +/* Table 6.4: MIDI OUT Jack Descriptor (tail) */ +struct usb_midi_out_jack_descriptor_tail { + /* ... */ + uint8_t iJack; +} __attribute__((packed)); + +/* Table 6.4: MIDI OUT Jack Descriptor (single) + * + * This structure is a convenience covering the (normal) case where + * there is only one input pin. + */ +struct usb_midi_out_jack_descriptor { + struct usb_midi_out_jack_descriptor_head head; + struct usb_midi_out_jack_descriptor_body source[1]; + struct usb_midi_out_jack_descriptor_tail tail; +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (head) */ +struct usb_midi_element_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bElementID; + uint8_t bNrInputPins; + /* ... */ +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (body) */ +struct usb_midi_element_descriptor_body { + /* ... */ + uint8_t baSourceID; + uint8_t baSourcePin; + /* ... */ +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (tail) */ +struct usb_midi_element_descriptor_tail { + /* ... */ + uint8_t bNrOutputPins; + uint8_t bInTerminalLink; + uint8_t bOutTerminalLink; + uint8_t bElCapsSize; + uint16_t bmElementCaps; /* host cannot assume this is 16-bit but device + can (since highest defined bitmap value in + v1.0 is bit 11) */ + uint8_t iElement; +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (single) + * + * This structure is a convenience covering the (common) case where + * there is only one input pin. + */ +struct usb_midi_element_descriptor { + struct usb_midi_element_descriptor_head head; + struct usb_midi_element_descriptor_body source[1]; + struct usb_midi_element_descriptor_tail tail; +} __attribute__((packed)); + +/* Table 6-7: Class-specific MS Bulk Data Endpoint Descriptor (head) */ +struct usb_midi_endpoint_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumEmbMIDIJack; +} __attribute__((packed)); + +/* Table 6-7: Class-specific MS Bulk Data Endpoint Descriptor (body) */ +struct usb_midi_endpoint_descriptor_body { + uint8_t baAssocJackID; +} __attribute__((packed)); + +/* Table 6.7: Class-specific MS Bulk Data Endpoint Descriptor (single) + * + * This structure is a convenience covering the (normal) case where + * there is only one input pin. + */ +struct usb_midi_endpoint_descriptor { + struct usb_midi_endpoint_descriptor_head head; + struct usb_midi_endpoint_descriptor_body jack[1]; +} __attribute__((packed)); + +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/msc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/msc.h new file mode 100644 index 00000000..cf9c54a6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/msc.h @@ -0,0 +1,93 @@ +/** @defgroup usb_msc_defines USB MSC Type Definitions + +@brief Defined Constants and Types for the USB MSC Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2013 +Weston Schmidt +Pavol Rusnak + +@date 27 June 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Weston Schmidt + * Copyright (C) 2013 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __MSC_H +#define __MSC_H + +typedef struct _usbd_mass_storage usbd_mass_storage; + +/* Definitions of Mass Storage Class from: + * + * (A) "Universal Serial Bus Mass Storage Class Bulk-Only Transport + * Revision 1.0" + * + * (B) "Universal Serial Bus Mass Storage Class Specification Overview + * Revision 1.0" + */ + +/* (A) Table 4.5: Mass Storage Device Class Code */ +#define USB_CLASS_MSC 0x08 + +/* (B) Table 2.1: Class Subclass Code */ +#define USB_MSC_SUBCLASS_RBC 0x01 +#define USB_MSC_SUBCLASS_ATAPI 0x02 +#define USB_MSC_SUBCLASS_UFI 0x04 +#define USB_MSC_SUBCLASS_SCSI 0x06 +#define USB_MSC_SUBCLASS_LOCKABLE 0x07 +#define USB_MSC_SUBCLASS_IEEE1667 0x08 + +/* (B) Table 3.1 Mass Storage Interface Class Control Protocol Codes */ +#define USB_MSC_PROTOCOL_CBI 0x00 +#define USB_MSC_PROTOCOL_CBI_ALT 0x01 +#define USB_MSC_PROTOCOL_BBB 0x50 + +/* (B) Table 4.1 Mass Storage Request Codes */ +#define USB_MSC_REQ_CODES_ADSC 0x00 +#define USB_MSC_REQ_CODES_GET 0xFC +#define USB_MSC_REQ_CODES_PUT 0xFD +#define USB_MSC_REQ_CODES_GML 0xFE +#define USB_MSC_REQ_CODES_BOMSR 0xFF + +/* (A) Table 3.1/3.2 Class-Specific Request Codes */ +#define USB_MSC_REQ_BULK_ONLY_RESET 0xFF +#define USB_MSC_REQ_GET_MAX_LUN 0xFE + +usbd_mass_storage *usb_msc_init(usbd_device *usbd_dev, + uint8_t ep_in, uint8_t ep_in_size, + uint8_t ep_out, uint8_t ep_out_size, + const char *vendor_id, + const char *product_id, + const char *product_revision_level, + const uint32_t block_count, + int (*read_block)(uint32_t lba, uint8_t *copy_to), + int (*write_block)(uint32_t lba, const uint8_t *copy_from)); + +#endif + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbd.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbd.h new file mode 100644 index 00000000..bcd28ea0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbd.h @@ -0,0 +1,196 @@ +/** @defgroup usb_driver_defines USB Drivers + +@brief Defined Constants and Types for the USB Drivers + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __USBD_H +#define __USBD_H + +#include + +BEGIN_DECLS + + +enum usbd_request_return_codes { + USBD_REQ_NOTSUPP = 0, + USBD_REQ_HANDLED = 1, + USBD_REQ_NEXT_CALLBACK = 2, +}; + +typedef struct _usbd_driver usbd_driver; +typedef struct _usbd_device usbd_device; + +extern const usbd_driver st_usbfs_v1_usb_driver; +extern const usbd_driver stm32f107_usb_driver; +extern const usbd_driver stm32f207_usb_driver; +extern const usbd_driver st_usbfs_v2_usb_driver; +#define otgfs_usb_driver stm32f107_usb_driver +#define otghs_usb_driver stm32f207_usb_driver +extern const usbd_driver efm32lg_usb_driver; + +/* */ +/** + * Main initialization entry point. + * + * Initialize the USB firmware library to implement the USB device described + * by the descriptors provided. + * + * It is required that the 48MHz USB clock is already available. + * + * @param driver TODO + * @param dev Pointer to USB device descriptor. This must not be changed while + * the device is in use. + * @param conf Pointer to array of USB configuration descriptors. These must + * not be changed while the device is in use. The length of this + * array is determined by the bNumConfigurations field in the + * device descriptor. + * @param strings TODO + * @param control_buffer Pointer to array that would hold the data + * received during control requests with DATA + * stage + * @param control_buffer_size Size of control_buffer + * @return the usb device initialized for use. (currently cannot fail). + */ +extern usbd_device * usbd_init(const usbd_driver *driver, + const struct usb_device_descriptor *dev, + const struct usb_config_descriptor *conf, + const char **strings, int num_strings, + uint8_t *control_buffer, + uint16_t control_buffer_size); + +/** Registers a reset callback */ +extern void usbd_register_reset_callback(usbd_device *usbd_dev, + void (*callback)(void)); +/** Registers a suspend callback */ +extern void usbd_register_suspend_callback(usbd_device *usbd_dev, + void (*callback)(void)); +/** Registers a resume callback */ +extern void usbd_register_resume_callback(usbd_device *usbd_dev, + void (*callback)(void)); +/** Registers a SOF callback */ +extern void usbd_register_sof_callback(usbd_device *usbd_dev, + void (*callback)(void)); + +typedef void (*usbd_control_complete_callback)(usbd_device *usbd_dev, + struct usb_setup_data *req); + +typedef int (*usbd_control_callback)(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, uint16_t *len, + usbd_control_complete_callback *complete); + +typedef void (*usbd_set_config_callback)(usbd_device *usbd_dev, + uint16_t wValue); + +typedef void (*usbd_set_altsetting_callback)(usbd_device *usbd_dev, + uint16_t wIndex, uint16_t wValue); + +typedef void (*usbd_endpoint_callback)(usbd_device *usbd_dev, uint8_t ep); + +/* */ +/** Registers a control callback. + * + * The specified callback will be called if (type == (bmRequestType + * & type_mask)) + * @param type Handled request type + * @param type_mask Mask to apply before matching request type + * @return 0 if successful + */ +extern int usbd_register_control_callback(usbd_device *usbd_dev, uint8_t type, + uint8_t type_mask, + usbd_control_callback callback); + +/* */ +/** Registers a "Set Config" callback + * @return 0 if successful + */ +extern int usbd_register_set_config_callback(usbd_device *usbd_dev, + usbd_set_config_callback callback); +/** Registers a "Set Interface" (alternate setting) callback */ +extern void usbd_register_set_altsetting_callback(usbd_device *usbd_dev, + usbd_set_altsetting_callback callback); + +/* Functions to be provided by the hardware abstraction layer */ +extern void usbd_poll(usbd_device *usbd_dev); + +/** Disconnect, if supported by the driver */ +extern void usbd_disconnect(usbd_device *usbd_dev, bool disconnected); + +/** Setup an endpoint + * @param addr Full EP address including direction (e.g. 0x01 or 0x81) + * @param type Value for bmAttributes (USB_ENDPOINT_ATTR_*) + */ +extern void usbd_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, + uint16_t max_size, usbd_endpoint_callback callback); + +/** Write a packet + * @param addr EP address (direction is ignored) + * @param len # of bytes + * @return 0 if failed, len if successful + */ +extern uint16_t usbd_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len); + +/** Read a packet + * @param addr EP address + * @param len # of bytes + * @return Actual # of bytes read + */ +extern uint16_t usbd_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, + void *buf, uint16_t len); +/** Set/clear STALL condition on an endpoint + * @param addr Full EP address (with direction bit) + * @param stall if 0, clear STALL, else set stall. + */ +extern void usbd_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, + uint8_t stall); + +/** Get STALL status of an endpoint + * @param addr Full EP address (with direction bit) + * @return nonzero if endpoint is stalled + */ +extern uint8_t usbd_ep_stall_get(usbd_device *usbd_dev, uint8_t addr); + +/** Set an Out endpoint to NAK + * @param addr EP address + * @param nak if nonzero, set NAK + */ +extern void usbd_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak); + +END_DECLS + +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbstd.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbstd.h new file mode 100644 index 00000000..78abf247 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/usb/usbstd.h @@ -0,0 +1,277 @@ +/** @defgroup usb_type_defines USB Standard Structure Definitions + +@brief Defined Constants and Types for the USB Standard Structure +Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +A set of structure definitions for the USB control structures +defined in chapter 9 of the "Universal Serial Bus Specification Revision 2.0" +Available from the USB Implementers Forum - http://www.usb.org/ + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __USBSTD_H +#define __USBSTD_H + +#include +#include + +/* + * This file contains structure definitions for the USB control structures + * defined in chapter 9 of the "Universal Serial Bus Specification Revision 2.0" + * Available from the USB Implementers Forum - http://www.usb.org/ + */ + +/* USB Setup Data structure - Table 9-2 */ +struct usb_setup_data { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__((packed)); + +/* Class Definition */ +#define USB_CLASS_VENDOR 0xFF + +/* bmRequestType bit definitions */ +/* bit 7 : direction */ +#define USB_REQ_TYPE_DIRECTION 0x80 +#define USB_REQ_TYPE_IN 0x80 +/* bits 6..5 : type */ +#define USB_REQ_TYPE_TYPE 0x60 +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 +/* bits 4..0 : recipient */ +#define USB_REQ_TYPE_RECIPIENT 0x1F +#define USB_REQ_TYPE_DEVICE 0x00 +#define USB_REQ_TYPE_INTERFACE 0x01 +#define USB_REQ_TYPE_ENDPOINT 0x02 +#define USB_REQ_TYPE_OTHER 0x03 + +/* USB Standard Request Codes - Table 9-4 */ +#define USB_REQ_GET_STATUS 0 +#define USB_REQ_CLEAR_FEATURE 1 +/* Reserved for future use: 2 */ +#define USB_REQ_SET_FEATURE 3 +/* Reserved for future use: 3 */ +#define USB_REQ_SET_ADDRESS 5 +#define USB_REQ_GET_DESCRIPTOR 6 +#define USB_REQ_SET_DESCRIPTOR 7 +#define USB_REQ_GET_CONFIGURATION 8 +#define USB_REQ_SET_CONFIGURATION 9 +#define USB_REQ_GET_INTERFACE 10 +#define USB_REQ_SET_INTERFACE 11 +#define USB_REQ_SET_SYNCH_FRAME 12 + +/* USB Descriptor Types - Table 9-5 */ +#define USB_DT_DEVICE 1 +#define USB_DT_CONFIGURATION 2 +#define USB_DT_STRING 3 +#define USB_DT_INTERFACE 4 +#define USB_DT_ENDPOINT 5 +#define USB_DT_DEVICE_QUALIFIER 6 +#define USB_DT_OTHER_SPEED_CONFIGURATION 7 +#define USB_DT_INTERFACE_POWER 8 +/* From ECNs */ +#define USB_DT_OTG 9 +#define USB_DT_DEBUG 10 +#define USB_DT_INTERFACE_ASSOCIATION 11 + +/* USB Standard Feature Selectors - Table 9-6 */ +#define USB_FEAT_ENDPOINT_HALT 0 +#define USB_FEAT_DEVICE_REMOTE_WAKEUP 1 +#define USB_FEAT_TEST_MODE 2 + +/* Information Returned by a GetStatus() Request to a Device - Figure 9-4 */ +#define USB_DEV_STATUS_SELF_POWERED 0x01 +#define USB_DEV_STATUS_REMOTE_WAKEUP 0x02 + +/* USB Standard Device Descriptor - Table 9-8 */ +struct usb_device_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__((packed)); + +#define USB_DT_DEVICE_SIZE sizeof(struct usb_device_descriptor) + +/* USB Device_Qualifier Descriptor - Table 9-9 + * Not used in this implementation. + */ +struct usb_device_qualifier_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__((packed)); + +/* This is only defined as a top level named struct to improve c++ + * compatibility. You should never need to instance this struct + * in user code! */ +struct usb_interface { + uint8_t *cur_altsetting; + uint8_t num_altsetting; + const struct usb_iface_assoc_descriptor *iface_assoc; + const struct usb_interface_descriptor *altsetting; +}; + +/* USB Standard Configuration Descriptor - Table 9-10 */ +struct usb_config_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; + + /* Descriptor ends here. The following are used internally: */ + const struct usb_interface *interface; +} __attribute__((packed)); +#define USB_DT_CONFIGURATION_SIZE 9 + +/* USB Configuration Descriptor bmAttributes bit definitions */ +#define USB_CONFIG_ATTR_DEFAULT 0x80 /** always required (USB2.0 table 9-10) */ +#define USB_CONFIG_ATTR_SELF_POWERED 0x40 +#define USB_CONFIG_ATTR_REMOTE_WAKEUP 0x20 + +/* Other Speed Configuration is the same as Configuration Descriptor. + * - Table 9-11 + */ + +/* USB Standard Interface Descriptor - Table 9-12 */ +struct usb_interface_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; + + /* Descriptor ends here. The following are used internally: */ + const struct usb_endpoint_descriptor *endpoint; + const void *extra; + int extralen; +} __attribute__((packed)); +#define USB_DT_INTERFACE_SIZE 9 + +/* USB Standard Endpoint Descriptor - Table 9-13 */ +struct usb_endpoint_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + + /* Descriptor ends here. The following are used internally: */ + const void *extra; + int extralen; +} __attribute__((packed)); +#define USB_DT_ENDPOINT_SIZE 7 + +/* USB bEndpointAddress helper macros */ +#define USB_ENDPOINT_ADDR_OUT(x) (x) +#define USB_ENDPOINT_ADDR_IN(x) (0x80 | (x)) + +/* USB Endpoint Descriptor bmAttributes bit definitions - Table 9-13 */ +/* bits 1..0 : transfer type */ +#define USB_ENDPOINT_ATTR_CONTROL 0x00 +#define USB_ENDPOINT_ATTR_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_ATTR_BULK 0x02 +#define USB_ENDPOINT_ATTR_INTERRUPT 0x03 +#define USB_ENDPOINT_ATTR_TYPE 0x03 +/* bits 3..2 : Sync type (only if ISOCHRONOUS) */ +#define USB_ENDPOINT_ATTR_NOSYNC 0x00 +#define USB_ENDPOINT_ATTR_ASYNC 0x04 +#define USB_ENDPOINT_ATTR_ADAPTIVE 0x08 +#define USB_ENDPOINT_ATTR_SYNC 0x0C +#define USB_ENDPOINT_ATTR_SYNCTYPE 0x0C +/* bits 5..4 : usage type (only if ISOCHRONOUS) */ +#define USB_ENDPOINT_ATTR_DATA 0x00 +#define USB_ENDPOINT_ATTR_FEEDBACK 0x10 +#define USB_ENDPOINT_ATTR_IMPLICIT_FEEDBACK_DATA 0x20 +#define USB_ENDPOINT_ATTR_USAGETYPE 0x30 + +/* Table 9-15 specifies String Descriptor Zero. + * Table 9-16 specified UNICODE String Descriptor. + */ +struct usb_string_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wData[]; +} __attribute__((packed)); + +/* From ECN: Interface Association Descriptors, Table 9-Z */ +struct usb_iface_assoc_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} __attribute__((packed)); +#define USB_DT_INTERFACE_ASSOCIATION_SIZE \ + sizeof(struct usb_iface_assoc_descriptor) + +enum usb_language_id { + USB_LANGID_ENGLISH_US = 0x409, +}; +#endif + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/anadig.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/anadig.h new file mode 100644 index 00000000..594da960 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/anadig.h @@ -0,0 +1,224 @@ +/** @defgroup anadig_defines ANADIG Defines + * + * @brief Defined Constants and Types for the VF6xx Analog components + * control digital interface + * + * @ingroup VF6xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Stefan Agner + * + * @date 01 July 2014 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ANADIG_H +#define LIBOPENCM3_ANADIG_H + +#include +#include + +/* --- ANADIG registers ---------------------------------------------------- */ + +#define ANADIG_PLL3_CTRL MMIO32(ANADIG_BASE + 0x010) +#define ANADIG_PLL7_CTRL MMIO32(ANADIG_BASE + 0x020) +#define ANADIG_PLL2_CTRL MMIO32(ANADIG_BASE + 0x030) +#define ANADIG_PLL2_SS MMIO32(ANADIG_BASE + 0x040) +#define ANADIG_PLL2_NUM MMIO32(ANADIG_BASE + 0x050) +#define ANADIG_PLL2_DENOM MMIO32(ANADIG_BASE + 0x060) +#define ANADIG_PLL4_CTRL MMIO32(ANADIG_BASE + 0x070) +#define ANADIG_PLL4_NUM MMIO32(ANADIG_BASE + 0x080) +#define ANADIG_PLL4_DENOM MMIO32(ANADIG_BASE + 0x090) +#define ANADIG_PLL6_CTRL MMIO32(ANADIG_BASE + 0x0A0) +#define ANADIG_PLL6_NUM MMIO32(ANADIG_BASE + 0x0B0) +#define ANADIG_PLL6_DENOM MMIO32(ANADIG_BASE + 0x0C0) +#define ANADIG_PLL5_CTRL MMIO32(ANADIG_BASE + 0x0E0) +#define ANADIG_PLL3_PFD MMIO32(ANADIG_BASE + 0x0F0) +#define ANADIG_PLL2_PFD MMIO32(ANADIG_BASE + 0x100) +#define ANADIG_REG_1P1 MMIO32(ANADIG_BASE + 0x110) +#define ANADIG_REG_3P0 MMIO32(ANADIG_BASE + 0x120) +#define ANADIG_REG_2P5 MMIO32(ANADIG_BASE + 0x130) +#define ANADIG_ANA_MISC0 MMIO32(ANADIG_BASE + 0x150) +#define ANADIG_ANA_MISC1 MMIO32(ANADIG_BASE + 0x160) +#define ANADIG_ANADIG_DIGPROG MMIO32(ANADIG_BASE + 0x260) +#define ANADIG_PLL1_CTRL MMIO32(ANADIG_BASE + 0x270) +#define ANADIG_PLL1_SS MMIO32(ANADIG_BASE + 0x280) +#define ANADIG_PLL1_NUM MMIO32(ANADIG_BASE + 0x290) +#define ANADIG_PLL1_DENOM MMIO32(ANADIG_BASE + 0x2A0) +#define ANADIG_PLL1_PFD MMIO32(ANADIG_BASE + 0x2B0) +#define ANADIG_PLL_LOCK MMIO32(ANADIG_BASE + 0x2C0) + +/* --- ANADIG values -....-------------------------------------------------- */ + +/* ANADIG_PLL3_CTRL: PLL3 Control Register (480MHz PLL of USB0) */ +#define ANADIG_PLL3_CTRL_LOCK (1 << 31) +#define ANADIG_PLL3_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL3_CTRL_BYPASS_CLK_SRC (1 << 14) +#define ANADIG_PLL3_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL3_CTRL_POWER (1 << 12) +#define ANADIG_PLL3_CTRL_EN_USB_CLKS (1 << 6) +#define ANADIG_PLL3_CTRL_DIV_SELECT (1 << 1) + +/* ANADIG_PLL7_CTRL: PLL7 Control Register (480MHz PLL of USB1) */ +#define ANADIG_PLL7_CTRL_LOCK (1 << 31) +#define ANADIG_PLL7_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL7_CTRL_BYPASS_CLK_SRC (1 << 14) +#define ANADIG_PLL7_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL7_CTRL_POWER (1 << 12) +#define ANADIG_PLL7_CTRL_EN_USB_CLKS (1 << 6) +#define ANADIG_PLL7_CTRL_DIV_SELECT (1 << 1) + +/* ANADIG_PLL2_CTRL: PLL2 Control Register (528MHz PLL) */ +#define ANADIG_PLL2_CTRL_LOCK (1 << 31) +#define ANADIG_PLL2_CTRL_PFD_OFFSET_EN (1 << 18) +#define ANADIG_PLL2_CTRL_DITHER_ENABLE (1 << 17) +#define ANADIG_PLL2_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL2_CTRL_BYPASS_CLK_SRC (1 << 14) +#define ANADIG_PLL2_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL2_CTRL_POWERDOWN (1 << 12) +#define ANADIG_PLL2_CTRL_DIV_SELECT (1 << 1) + +/* ANADIG_PLL2_SS: PLL2 Spread Spectrum definition register */ +#define ANADIG_PLL2_SS_STOP_MASK (0xffff << 16) +#define ANADIG_PLL2_SS_ENABLE (1 << 15) +#define ANADIG_PLL2_SS_STEP_MASK 0x8fff + +/* ANADIG_PLL2_NUM: PLL2 Numerator definition register */ +#define ANADIG_PLL2_NUM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL2_DENOM: PLL2 Denominator definition register */ +#define ANADIG_PLL2_DENOM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL4_CTRL: PLL4 Control Register (audio PLL) */ +#define ANADIG_PLL4_CTRL_LOCK (1 << 31) +#define ANADIG_PLL4_CTRL_PFD_OFFSET_EN (1 << 18) +#define ANADIG_PLL4_CTRL_DITHER_ENABLE (1 << 17) +#define ANADIG_PLL4_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL4_CTRL_BYPASS_CLK_SRC (1 << 14) +#define ANADIG_PLL4_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL4_CTRL_POWERDOWN (1 << 12) +#define ANADIG_PLL4_CTRL_DIV_SELECT_MASK (0x7f) + +/* ANADIG_PLL4_NUM: PLL4 Numerator definition register */ +#define ANADIG_PLL4_NUM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL4_DENOM: PLL4 Denominator definition register */ +#define ANADIG_PLL4_DENOM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL6_CTRL: PLL6 Control Register (video PLL) */ +#define ANADIG_PLL6_CTRL_LOCK (1 << 31) +#define ANADIG_PLL6_CTRL_PFD_OFFSET_EN (1 << 18) +#define ANADIG_PLL6_CTRL_DITHER_ENABLE (1 << 17) +#define ANADIG_PLL6_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL6_CTRL_BYPASS_CLK_SRC (1 << 14) +#define ANADIG_PLL6_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL6_CTRL_POWERDOWN (1 << 12) +#define ANADIG_PLL6_CTRL_DIV_SELECT_MASK (0x7f) + +/* ANADIG_PLL6_NUM: PLL6 Numerator definition register */ +#define ANADIG_PLL6_NUM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL6_DENOM: PLL6 Denominator definition register */ +#define ANADIG_PLL6_DENOM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL5_CTRL: PLL5 Control Register (video PLL) */ +#define ANADIG_PLL5_CTRL_LOCK (1 << 31) +#define ANADIG_PLL5_CTRL_PFD_OFFSET_EN (1 << 18) +#define ANADIG_PLL5_CTRL_DITHER_ENABLE (1 << 17) +#define ANADIG_PLL5_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL5_CTRL_BYPASS_CLK_SRC (1 << 14) +#define ANADIG_PLL5_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL5_CTRL_POWERDOWN (1 << 12) +#define ANADIG_PLL5_CTRL_DIV_SELECT_MASK (0x3) + +/* ANADIG_PLL_PFD: PLL1/PLL2/PLL3 PFD Clocks */ +#define ANADIG_PLL_PFD4_CLKGATE (1 << 31) +#define ANADIG_PLL_PFD4_STABLE (1 << 30) +#define ANADIG_PLL_PFD4_FRAC_SHIFT 24 +#define ANADIG_PLL_PFD4_FRAC_MASK (0x3f << 24) +#define ANADIG_PLL_PFD3_CLKGATE (1 << 23) +#define ANADIG_PLL_PFD3_STABLE (1 << 22) +#define ANADIG_PLL_PFD3_FRAC_SHIFT 16 +#define ANADIG_PLL_PFD3_FRAC_MASK (0x3f << 16) +#define ANADIG_PLL_PFD2_CLKGATE (1 << 15) +#define ANADIG_PLL_PFD2_STABLE (1 << 14) +#define ANADIG_PLL_PFD2_FRAC_SHIFT 8 +#define ANADIG_PLL_PFD2_FRAC_MASK (0x3f << 8) +#define ANADIG_PLL_PFD1_CLKGATE (1 << 7) +#define ANADIG_PLL_PFD1_STABLE (1 << 6) +#define ANADIG_PLL_PFD1_FRAC_SHIFT 0 +#define ANADIG_PLL_PFD1_FRAC_MASK (0x3f << 0) + +/* AANADIG_ANA_MISC0: miscellaneous analog blocks */ +#define ANADIG_ANA_MISC0_OSC_XTALOK_EN (1 << 17) +#define ANADIG_ANA_MISC0_OSC_XTALOK (1 << 16) +#define ANADIG_ANA_MISC0_CLK_24M_IRC_XTAL_SEL (1 << 13) +#define ANADIG_ANA_MISC0_STOP_MODE_CONFIG (1 << 12) +#define ANADIG_ANA_MISC0_REFTOP_VBGUP (1 << 7) +#define ANADIG_ANA_MISC0_REFTOP_SELBIASOFF (1 << 3) +#define ANADIG_ANA_MISC0_REFTOP_LOWPOWER (1 << 2) +#define ANADIG_ANA_MISC0_REFTOP_PWDVBGUP (1 << 1) +#define ANADIG_ANA_MISC0_REFTOP_PWD (1 << 0) + +/* AANADIG_ANA_MISC0: miscellaneous analog blocks */ +#define ANADIG_ANA_MISC1_IRQ_ANA_BO (1 << 30) +#define ANADIG_ANA_MISC1_IRQ_TEMPSENSE (1 << 29) +#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12) +#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10) + +/* AANADIG_ANA_DIGPROG: Digital Program register */ +#define ANADIG_ANADIG_DIGPROG_MAJOR_MASK (0xffff << 8) +#define ANADIG_ANADIG_DIGPROG_MINOR_MASK (0xff << 0) + +/* ANADIG_PLL1_CTRL: PLL1 Control Register (video PLL) */ +#define ANADIG_PLL1_CTRL_LOCK (1 << 31) +#define ANADIG_PLL1_CTRL_PFD_OFFSET_EN (1 << 18) +#define ANADIG_PLL1_CTRL_DITHER_ENABLE (1 << 17) +#define ANADIG_PLL1_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL1_CTRL_BYPASS_CLK_SRC (1 << 14) +#define ANADIG_PLL1_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL1_CTRL_POWERDOWN (1 << 12) +#define ANADIG_PLL1_CTRL_DIV_SELECT (1 << 1) + +/* ANADIG_PLL1_SS: PLL1 Spread Spectrum definition register */ +#define ANADIG_PLL1_SS_STOP_MASK (0xffff << 16) +#define ANADIG_PLL1_SS_ENABLE (1 << 15) +#define ANADIG_PLL1_SS_STEP_MASK 0x8fff + +/* ANADIG_PLL1_NUM: PLL1 Numerator definition register */ +#define ANADIG_PLL1_NUM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL1_DENOM: PLL1 Denominator definition register */ +#define ANADIG_PLL1_DENOM_MFN_MASK 0x3fffffff + +/* ANADIG_PLL_LOCK: PLL Lock Register */ +#define ANADIG_PLL_LOCK_PLL1 (1 << 6) +#define ANADIG_PLL_LOCK_PLL2 (1 << 5) +#define ANADIG_PLL_LOCK_PLL4 (1 << 4) +#define ANADIG_PLL_LOCK_PLL6 (1 << 3) +#define ANADIG_PLL_LOCK_PLL5 (1 << 2) +#define ANADIG_PLL_LOCK_PLL3 (1 << 1) +#define ANADIG_PLL_LOCK_PLL7 (1 << 0) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/ccm.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/ccm.h new file mode 100644 index 00000000..b0a2569a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/ccm.h @@ -0,0 +1,351 @@ +/** @defgroup ccm_defines CCM Defines + * + * @brief Defined Constants and Types for the VF6xx Common Clock Module + * + * @ingroup VF6xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Stefan Agner + * + * @date 30 June 2014 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CCM_H +#define LIBOPENCM3_CCM_H + +#include +#include + +/* --- CCM registers ------------------------------------------------------- */ + +#define CCM_CCR MMIO32(CCM_BASE + 0x00) +#define CCM_CSR MMIO32(CCM_BASE + 0x04) +#define CCM_CCSR MMIO32(CCM_BASE + 0x08) +#define CCM_CACRR MMIO32(CCM_BASE + 0x0C) +#define CCM_CSCMR1 MMIO32(CCM_BASE + 0x10) +#define CCM_CSCDR1 MMIO32(CCM_BASE + 0x14) +#define CCM_CSCDR2 MMIO32(CCM_BASE + 0x18) +#define CCM_CSCDR3 MMIO32(CCM_BASE + 0x1C) +#define CCM_CSCMR2 MMIO32(CCM_BASE + 0x20) + +#define CCM_CTOR MMIO32(CCM_BASE + 0x28) +#define CCM_CLPCR MMIO32(CCM_BASE + 0x2C) +#define CCM_CISR MMIO32(CCM_BASE + 0x30) +#define CCM_CIMR MMIO32(CCM_BASE + 0x34) +#define CCM_CCOSR MMIO32(CCM_BASE + 0x38) +#define CCM_CGPR MMIO32(CCM_BASE + 0x3C) +#define CCM_CCGR(offset) MMIO32(CCM_BASE + 0x40 + (offset)) +#define CCM_CMEOR(ovrr) MMIO32(CCM_BASE + 0x70 + (4 * (ovrr))) +#define CCM_CPPDSR MMIO32(CCM_BASE + 0x88) + +#define CCM_CCOWR MMIO32(CCM_BASE + 0x8C) +#define CCM_CCPGR(pcgr) MMIO32(CCM_BASE + 0x90 + (4 * (pcgr))) + +/* --- CCM values -....----------------------------------------------------- */ + +/* CCR: CCM Control Register */ +#define CCM_CCR_FIRC_EN (1 << 16) +#define CCM_CCR_FXOSC_EN (1 << 12) +#define CCM_CCR_OSCNT_MASK 0xff + +/* CSR: CCM Status Register */ +#define CCM_CSR_FXOSC_RDY (1 << 5) + +/* CCSR: CCM Clock Switcher Register */ +#define CCM_CCSR_PLL3_PFDN4_EN (1 << 31) +#define CCM_CCSR_PLL3_PFDN3_EN (1 << 30) +#define CCM_CCSR_PLL3_PFDN2_EN (1 << 29) +#define CCM_CCSR_PLL3_PFDN1_EN (1 << 28) + +#define CCM_CCSR_DAP_EN (1 << 24) + +/* PLL1/PLL2 PFD SEL definition */ +#define CCM_CCSR_PLL2_PFD_CLK_SEL_SHIFT 19 +#define CCM_CCSR_PLL2_PFD_CLK_SEL_MASK (0x7 << 19) +#define CCM_CCSR_PLL1_PFD_CLK_SEL_SHIFT 16 +#define CCM_CCSR_PLL1_PFD_CLK_SEL_MASK (0x7 << 16) + +#define CCM_CCSR_PLL_PFD_CLK_SEL_MAIN 0x0 +#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD1 0x1 +#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD2 0x2 +#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD3 0x3 +#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD4 0x4 + +#define CCM_CCSR_PLL2_PFDN4_EN (1 << 15) +#define CCM_CCSR_PLL2_PFDN3_EN (1 << 14) +#define CCM_CCSR_PLL2_PFDN2_EN (1 << 13) +#define CCM_CCSR_PLL2_PFDN1_EN (1 << 12) + +#define CCM_CCSR_PLL1_PFDN4_EN (1 << 11) +#define CCM_CCSR_PLL1_PFDN3_EN (1 << 10) +#define CCM_CCSR_PLL1_PFDN2_EN (1 << 9) +#define CCM_CCSR_PLL1_PFDN1_EN (1 << 8) + +#define CCM_CCSR_DDRC_CLK_SEL (1 << 7) +#define CCM_CCSR_FAST_CLK_SEL (1 << 6) +#define CCM_CCSR_SLOW_CLK_SEL (1 << 5) + +#define CCM_CCSR_SYS_CLK_SEL_SHIFT 0 +#define CCM_CCSR_SYS_CLK_SEL_MASK 0x7 +#define CCM_CCSR_SYS_CLK_SEL_FAST 0x0 +#define CCM_CCSR_SYS_CLK_SEL_SLOW 0x1 +#define CCM_CCSR_SYS_CLK_SEL_PLL2_PFD 0x2 +#define CCM_CCSR_SYS_CLK_SEL_PLL2 0x3 +#define CCM_CCSR_SYS_CLK_SEL_PLL1_PFD 0x4 +#define CCM_CCSR_SYS_CLK_SEL_PLL3 0x5 + +/* CACRR: ARM Clock Root Register */ +#define CCM_CACRR_FLEX_CLK_DIV_SHIFT 22 +#define CCM_CACRR_FLEX_CLK_DIV_MASK (0x7 << 22) +#define CCM_CACRR_PLL6_CLK_DIV (1 << 21) +#define CCM_CACRR_PLL3_CLK_DIV (1 << 20) +#define CCM_CACRR_PLL1_PFD_CLK_DIV_SHIFT 16 +#define CCM_CACRR_PLL1_PFD_CLK_DIV_MASK (0x3 << 16) +#define CCM_CACRR_IPG_CLK_DIV_SHIFT 11 +#define CCM_CACRR_IPG_CLK_DIV_MASK (0x3 << 11) +#define CCM_CACRR_PLL4_CLK_DIV_SHIFT 6 +#define CCM_CACRR_PLL4_CLK_DIV_MASK (0x7 << 6) +#define CCM_CACRR_BUS_CLK_DIV_SHIFT 3 +#define CCM_CACRR_BUS_CLK_DIV_MASK (0x7 << 3) +#define CCM_CACRR_ARM_CLK_DIV_SHIFT 0 +#define CCM_CACRR_ARM_CLK_DIV_MASK (0x7 << 0) + +/* --- Variable definitions ------------------------------------------------ */ + +extern uint32_t ccm_core_clk; +extern uint32_t ccm_platform_bus_clk; +extern uint32_t ccm_ipg_bus_clk; + +enum ccm_clock_gate { + /* AIPS0 */ + CG0_FLEXCAN0 = 0, + CG1_RESERVED, + CG2_RESERVED, + CG3_RESERVED, + CG4_DMA_MUX0, + CG5_DMA_MUX1, + CG6_RESERVED, + CG7_UART0, + CG8_UART1, + CG9_UART2, + CG10_UART3, + CG11_RESERVED, + CG12_SPI0, + CG13_SPI1, + CG14_RESERVED, + CG15_SAI0, + CG16_SAI1, + CG17_SAI2, + CG18_SAI3, + CG19_CRC, + CG20_USBC0, + CG21_RESERVED, + CG22_PDB, + CG23_PIT, + CG24_FTM0, + CG25_FTM1, + CG26_RESERVED, + CG27_ADC0, + CG28_RESERVED, + CG29_TCON0, + CG30_WDOG_A5, + CG31_WDOG_M4, + CG32_LPTMR, + CG33_RESERVED, + CG34_RLE, + CG35_RESERVED, + CG36_QSPI0, + CG37_RESERVED, + CG38_RESERVED, + CG39_RESERVED, + CG40_IOMUX, + CG41_PORTA, + CG42_PORTB, + CG43_PORTC, + CG44_PORTD, + CG45_PORTE, + CG46_RESERVED, + CG47_RESERVED, + CG48_ANADIG, + CG49_RESERVED, + CG50_SCSCM, + CG51_RESERVED, + CG52_RESERVED, + CG53_RESERVED, + CG54_RESERVED, + CG55_RESERVED, + CG56_DCU0, + CG57_RESERVED, + CG58_RESERVED, + CG59_RESERVED, + CG60_RESERVED, + CG61_RESERVED, + CG62_RESERVED, + CG63_RESERVED, + CG64_ASRC, + CG65_SPDIF, + CG66_ESAI, + CG67_RESERVED, + CG68_RESERVED, + CG69_EWM, + CG70_I2C0, + CG71_I2C1, + CG72_RESERVED, + CG73_RESERVED, + CG74_WKUP, + CG75_CCM, + CG76_GPC, + CG77_VREG_DIG, + CG78_RESERVED, + CG79_CMU, + CG80_NOTUSED, + CG81_NOTUSED, + CG82_NOTUSED, + CG83_NOTUSED, + CG84_NOTUSED, + CG85_NOTUSED, + CG86_NOTUSED, + CG87_NOTUSED, + CG88_NOTUSED, + CG89_NOTUSED, + CG90_NOTUSED, + CG91_NOTUSED, + CG92_NOTUSED, + CG93_NOTUSED, + CG94_NOTUSED, + CG95_NOTUSED, + + /* AIPS1 */ + CG96_RESERVED, + CG97_DMA_MUX2, + CG98_DMA_MUX3, + CG99_RESERVED, + CG100_RESERVED, + CG101_OTP_CTRL, + CG102_RESERVED, + CG103_RESERVED, + CG104_RESERVED, + CG105_UART4, + CG106_UART5, + CG107_RESERVED, + CG108_SPI2, + CG109_SPI3, + CG110_DDRMC, + CG111_RESERVED, + CG112_RESERVED, + CG113_SDHC0, + CG114_SDHC1, + CG115_RESERVED, + CG116_USBC1, + CG117_RESERVED, + CG118_RESERVED, + CG119_RESERVED, + CG120_FTM2, + CG121_FTM3, + CG122_RESERVED, + CG123_ADC1, + CG124_RESERVED, + CG125_TCON1, + CG126_SEG_LCD, + CG127_RESERVED, + CG128_RESERVED, + CG129_RESERVED, + CG130_RESERVED, + CG131_RESERVED, + CG132_QSPI1, + CG133_RESERVED, + CG134_RESERVED, + CG135_VADC, + CG136_VDEC, + CG137_VIU3, + CG138_RESERVED, + CG139_RESERVED, + CG140_DAC0, + CG141_DAC1, + CG142_RESERVED, + CG143_NOTUSED, + CG144_ETH0_1588, + CG145_ETH1_1588, + CG146_RESERVED, + CG147_RESERVED, + CG148_FLEXCAN1, + CG149_RESERVED, + CG150_RESERVED, + CG151_RESERVED, + CG152_DCU1, + CG153_RESERVED, + CG154_RESERVED, + CG155_RESERVED, + CG156_RESERVED, + CG157_RESERVED, + CG158_RESERVED, + CG159_RESERVED, + CG160_NFC, + CG161_RESERVED, + CG162_RESERVED, + CG163_RESERVED, + CG164_RESERVED, + CG165_RESERVED, + CG166_I2C2, + CG167_I2C3, + CG168_ETH_L2, + CG169_RESERVED, + CG170_RESERVED, + CG171_RESERVED, + CG172_RESERVED, + CG173_RESERVED, + CG174_RESERVED, + CG175_RESERVED, + CG176_RESERVED, + CG177_RESERVED, + CG178_RESERVED, + CG179_RESERVED, + CG180_RESERVED, + CG181_RESERVED, + CG182_RESERVED, + CG183_RESERVED, + CG184_RESERVED, + CG185_RESERVED, + CG186_RESERVED, + CG187_RESERVED, + CG188_RESERVED, + CG189_RESERVED, + CG190_RESERVED, + CG191_RESERVED +}; + +/* --- Function prototypes ------------------------------------------------- */ + +#include + +BEGIN_DECLS + +void ccm_clock_gate_enable(enum ccm_clock_gate gr); +void ccm_clock_gate_disable(enum ccm_clock_gate gr); +void ccm_calculate_clocks(void); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/doc-vf6xx.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/doc-vf6xx.h new file mode 100644 index 00000000..2fb634ae --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/doc-vf6xx.h @@ -0,0 +1,32 @@ +/** @mainpage libopencm3 VF6xx + * + * @version 1.0.0 + * + * @date 03 July 2014 + * + * API documentation for Freescale VF6xx series Cortex-M4 core. + * + * LGPL License Terms @ref lgpl_license + */ + +/** @defgroup VF6xx VF6xx + * Libraries for Freescale VF6xx series Cortex-M4 core. + * + * @version 1.0.0 + * + * @date 03 July 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/** @defgroup VF6xx_defines VF6xx Defines + * + * @brief Defined Constants and Types for the VF6xx series + * + * @version 1.0.0 + * + * @date 03 July 2014 + * + * LGPL License Terms @ref lgpl_license + */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/gpio.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/gpio.h new file mode 100644 index 00000000..899e4a73 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/gpio.h @@ -0,0 +1,80 @@ +/** @defgroup VF6xx_gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the VF6xx GPIO Module + * + * @ingroup VF6xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Stefan Agner + * + * @date 03 July 2014 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_VF6XX_GPIO_H +#define LIBOPENCM3_VF6XX_GPIO_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup gpio_reg_base GPIO register base addresses +@ingroup VF6xx_gpio_defines + +@{*/ +#define GPIO(port) (GPIO_BASE + (0x040 * (port))) +#define GPIO0 (GPIO_BASE + 0x000) +#define GPIO1 (GPIO_BASE + 0x040) +#define GPIO2 (GPIO_BASE + 0x080) +#define GPIO3 (GPIO_BASE + 0x0C0) +#define GPIO4 (GPIO_BASE + 0x100) + +#define GPIO_OFFSET(gpio) (0x1 << ((gpio) % 32)) + +/* --- GPIO registers ------------------------------------------------------ */ + +#define GPIO_PDOR(gpio_base) MMIO32((gpio_base) + 0x00) +#define GPIO_PSOR(gpio_base) MMIO32((gpio_base) + 0x04) +#define GPIO_PCOR(gpio_base) MMIO32((gpio_base) + 0x08) +#define GPIO_PTOR(gpio_base) MMIO32((gpio_base) + 0x0C) +#define GPIO_PDIR(gpio_base) MMIO32((gpio_base) + 0x10) + +/* --- Function prototypes ------------------------------------------------- */ + +#include + +BEGIN_DECLS + +void gpio_set(uint32_t gpio); +void gpio_clear(uint32_t gpio); +bool gpio_get(uint32_t gpio); +void gpio_toggle(uint32_t gpio); +uint32_t gpio_port_read(uint32_t gpioport); +void gpio_port_write(uint32_t gpioport, uint32_t data); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/iomuxc.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/iomuxc.h new file mode 100644 index 00000000..b08a24ec --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/iomuxc.h @@ -0,0 +1,256 @@ +/** @defgroup VF6xx_iomuxc_defines IO MUX Controller Defines + * + * @brief Defined Constants and Types for the VF6xx IO MUX Controller + * + * @ingroup VF6xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Stefan Agner + * + * @date 03 July 2014 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_VF6XX_IOMUXC_H +#define LIBOPENCM3_VF6XX_IOMUXC_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup iomuxc_reg IO MUX Controller register +@ingroup VF6xx_iomuxc_defines + +@{*/ +#define IOMUXC(pad) MMIO32(IOMUXC_BASE + (0x4 * (pad))) + +#define IOMUXC_PAD(mode, speed, dse, pus, flags) \ + ((IOMUXC_##mode) << IOMUXC_MUX_MODE_SHIFT | \ + (IOMUXC_##speed) << IOMUXC_SPEED_SHIFT | \ + (IOMUXC_##dse) << IOMUXC_DSE_SHIFT | \ + (IOMUXC_##pus) << IOMUXC_PUS_SHIFT | \ + (flags)) + + +/* --- GPIO registers ------------------------------------------------------ */ + +#define IOMUXC_MUX_MODE_SHIFT 20 +#define IOMUXC_MUX_MODE_MASK (0x7 << 20) +#define IOMUXC_MUX_MODE_ALT0 0x0 +#define IOMUXC_MUX_MODE_ALT1 0x1 +#define IOMUXC_MUX_MODE_ALT2 0x2 +#define IOMUXC_MUX_MODE_ALT3 0x3 +#define IOMUXC_MUX_MODE_ALT4 0x4 +#define IOMUXC_MUX_MODE_ALT5 0x5 +#define IOMUXC_MUX_MODE_ALT6 0x6 +#define IOMUXC_MUX_MODE_ALT7 0x7 +#define IOMUXC_SPEED_SHIFT 12 +#define IOMUXC_SPEED_MASK (0x3 << 12) +#define IOMUXC_SPEED_LOW 0x0 +#define IOMUXC_SPEED_MEDIUM 0x1 +#define IOMUXC_SPEED_HIGH 0x3 +#define IOMUXC_SRE (0x1 << 11) +#define IOMUXC_ODE (0x1 << 10) +#define IOMUXC_HYS (0x1 << 9) +#define IOMUXC_DSE_SHIFT 6 +#define IOMUXC_DSE_MASK (0x7 << 6) +#define IOMUXC_DSE_OFF 0x0 +#define IOMUXC_DSE_150OHM 0x1 +#define IOMUXC_DSE_75OHM 0x2 +#define IOMUXC_DSE_50OHM 0x3 +#define IOMUXC_DSE_37OHM 0x4 +#define IOMUXC_DSE_30OHM 0x5 +#define IOMUXC_DSE_25OHM 0x6 +#define IOMUXC_DSE_20OHM 0x7 +#define IOMUXC_PUS_SHIFT 4 +#define IOMUXC_PUS_MASK (0x3 << 4) +#define IOMUXC_PUS_PD_100KOHM 0x0 +#define IOMUXC_PUS_PU_47KOHM 0x1 +#define IOMUXC_PUS_PU_100KOHM 0x2 +#define IOMUXC_PUS_PU_22KOHM 0x3 +#define IOMUXC_PKE (0x1 << 3) +#define IOMUXC_PUE (0x1 << 2) +#define IOMUXC_OBE (0x1 << 1) +#define IOMUXC_IBE (0x1 << 0) + + +/* --- Type definitions ---------------------------------------------------- */ +/*---------------------------------------------------------------------------*/ +/** @brief IO-MUX Pads + +Pads available by the IO-MUX controller +*/ + +enum vf6xx_pad { + PTA6, + PTA8, + PTA9, + PTA10, + PTA11, + PTA12, + PTA16, + PTA17, + PTA18, + PTA19, + PTA20, + PTA21, + PTA22, + PTA23, + PTA24, + PTA25, + PTA26, + PTA27, + PTA28, + PTA29, + PTA30, + PTA31, + PTB0, + PTB1, + PTB2, + PTB3, + PTB4, + PTB5, + PTB6, + PTB7, + PTB8, + PTB9, + PTB10, + PTB11, + PTB12, + PTB13, + PTB14, + PTB15, + PTB16, + PTB17, + PTB18, + PTB19, + PTB20, + PTB21, + PTB22, + PTC0, + PTC1, + PTC2, + PTC3, + PTC4, + PTC5, + PTC6, + PTC7, + PTC8, + PTC9, + PTC10, + PTC11, + PTC12, + PTC13, + PTC14, + PTC15, + PTC16, + PTC17, + PTD31, + PTD30, + PTD29, + PTD28, + PTD27, + PTD26, + PTD25, + PTD24, + PTD23, + PTD22, + PTD21, + PTD20, + PTD19, + PTD18, + PTD17, + PTD16, + PTD0, + PTD1, + PTD2, + PTD3, + PTD4, + PTD5, + PTD6, + PTD7, + PTD8, + PTD9, + PTD10, + PTD11, + PTD12, + PTD13, + PTB23, + PTB24, + PTB25, + PTB26, + PTB27, + PTB28, + PTC26, + PTC27, + PTC28, + PTC29, + PTC30, + PTC31, + PTE0, + PTE1, + PTE2, + PTE3, + PTE4, + PTE5, + PTE6, + PTE7, + PTE8, + PTE9, + PTE10, + PTE11, + PTE12, + PTE13, + PTE14, + PTE15, + PTE16, + PTE17, + PTE18, + PTE19, + PTE20, + PTE21, + PTE22, + PTE23, + PTE24, + PTE25, + PTE26, + PTE27, + PTE28, + PTA7, +}; + + +/* --- Function prototypes ------------------------------------------------- */ + +#include + +BEGIN_DECLS + +void iomuxc_mux(enum vf6xx_pad pad, uint32_t muxc); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/irq.json b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/irq.json new file mode 100644 index 00000000..d8d15573 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/irq.json @@ -0,0 +1,119 @@ +{ + "irqs": [ + "cpu2cpu_int0", + "cpu2cpu_int1", + "cpu2cpu_int2", + "cpu2cpu_int3", + "directed0_sema4", + "directed1_mcm", + "directed2", + "directed3", + "dma0", + "dma0_error", + "dma1", + "dma1_error", + "reserved0", + "reserved1", + "mscm_ecc0", + "mscm_ecc1", + "csu_alarm", + "reserved2", + "mscm_actzs", + "reserved3", + "wdog_a5", + "wdog_m4", + "wdog_snvs", + "cp1_boot_fail", + "qspi0", + "qspi1", + "ddrmc", + "sdhc0", + "sdhc1", + "reserved4", + "dcu0", + "dcu1", + "viu", + "reserved5", + "reserved6", + "rle", + "seg_lcd", + "reserved7", + "reserved8", + "pit", + "lptimer0", + "reserved9", + "flextimer0", + "flextimer1", + "flextimer2", + "flextimer3", + "reserved10", + "reserved11", + "reserved12", + "reserved13", + "usbphy0", + "usbphy1", + "reserved14", + "adc0", + "adc1", + "dac0", + "dac1", + "reserved15", + "flexcan0", + "flexcan1", + "reserved16", + "uart0", + "uart1", + "uart2", + "uart3", + "uart4", + "uart5", + "spi0", + "spi1", + "spi2", + "spi3", + "i2c0", + "i2c1", + "i2c2", + "i2c3", + "usbc0", + "usbc1", + "reserved17", + "enet0", + "enet1", + "enet0_1588", + "enet1_1588", + "enet_switch", + "nfc", + "sai0", + "sai1", + "sai2", + "sai3", + "esai_bififo", + "spdif", + "asrc", + "vreg", + "wkpu0", + "reserved18", + "ccm_fxosc", + "ccm", + "src", + "pdb", + "ewm", + "reserved19", + "reserved20", + "reserved21", + "reserved22", + "reserved23", + "reserved24", + "reserved25", + "reserved26", + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4" + ], + "partname_humanreadable": "VF6xx series", + "partname_doxygen": "VF6XX", + "includeguard": "LIBOPENCM3_VF6XX_NVIC_H" +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/memorymap.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/memorymap.h new file mode 100644 index 00000000..efb84f69 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/memorymap.h @@ -0,0 +1,65 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- VF6xx specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE (0x40000000U) +#define PERIPH_BASE_AIPS0 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_AIPS1 (PERIPH_BASE + 0x80000) + +/* Pheripheral addresses */ + +/* AIPS0 */ +#define MSCM_BASE (PERIPH_BASE_AIPS0 + 0x01000) + +#define SEMA4_BASE (PERIPH_BASE_AIPS0 + 0x1D000) + +#define UART0_BASE (PERIPH_BASE_AIPS0 + 0x27000) +#define UART1_BASE (PERIPH_BASE_AIPS0 + 0x28000) +#define UART2_BASE (PERIPH_BASE_AIPS0 + 0x29000) +#define UART3_BASE (PERIPH_BASE_AIPS0 + 0x2A000) + +#define SPI0_BASE (PERIPH_BASE_AIPS0 + 0x2C000) +#define SPI1_BASE (PERIPH_BASE_AIPS0 + 0x2D000) + +#define IOMUXC_BASE (PERIPH_BASE_AIPS0 + 0x48000) +#define PORTA_MUX_BASE (PERIPH_BASE_AIPS0 + 0x49000) +#define PORTB_MUX_BASE (PERIPH_BASE_AIPS0 + 0x4A000) +#define PORTC_MUX_BASE (PERIPH_BASE_AIPS0 + 0x4B000) +#define PORTD_MUX_BASE (PERIPH_BASE_AIPS0 + 0x4C000) +#define PORTE_MUX_BASE (PERIPH_BASE_AIPS0 + 0x4D000) + +#define ANADIG_BASE (PERIPH_BASE_AIPS0 + 0x50000) + +#define CCM_BASE (PERIPH_BASE_AIPS0 + 0x6B000) + +/* AIPS1 */ +#define UART4_BASE (PERIPH_BASE_AIPS1 + 0x29000) +#define UART5_BASE (PERIPH_BASE_AIPS1 + 0x2A000) + +/* GPIO module */ +#define GPIO_BASE (PERIPH_BASE + 0xff000) + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/uart.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/uart.h new file mode 100644 index 00000000..369918c9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencm3/vf6xx/uart.h @@ -0,0 +1,182 @@ +/** @defgroup VF6xx_uart_defines UART Defines + * + * @brief Defined Constants and Types for the VF6xx UART Module + * + * @ingroup VF6xx_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Stefan Agner + * + * @date 01 July 2014 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_VF6XX_UART_H +#define LIBOPENCM3_VF6XX_UART_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup uart_reg_base UART register base addresses +@ingroup VF6xx_uart_defines + +@{*/ +#define UART0 UART0_BASE +#define UART1 UART1_BASE +#define UART2 UART2_BASE +#define UART3 UART3_BASE +#define UART4 UART4_BASE +#define UART5 UART5_BASE + +/* --- UART registers ------------------------------------------------------ */ + +#define UART_BDH(uart_base) MMIO8((uart_base) + 0x00) +#define UART_BDL(uart_base) MMIO8((uart_base) + 0x01) +#define UART_C1(uart_base) MMIO8((uart_base) + 0x02) +#define UART_C2(uart_base) MMIO8((uart_base) + 0x03) +#define UART_S1(uart_base) MMIO8((uart_base) + 0x04) +#define UART_S2(uart_base) MMIO8((uart_base) + 0x05) +#define UART_C3(uart_base) MMIO8((uart_base) + 0x06) +#define UART_D(uart_base) MMIO8((uart_base) + 0x07) +#define UART_MA1(uart_base) MMIO8((uart_base) + 0x08) +#define UART_MA2(uart_base) MMIO8((uart_base) + 0x09) +#define UART_C4(uart_base) MMIO8((uart_base) + 0x0A) +#define UART_C5(uart_base) MMIO8((uart_base) + 0x0B) +#define UART_ED(uart_base) MMIO8((uart_base) + 0x0C) +#define UART_MODEM(uart_base) MMIO8((uart_base) + 0x0D) +/* Incomplete */ + +/* --- CCM values -....----------------------------------------------------- */ + +/* BDH: Baud Rate Register High */ +#define UART_BDH_LBKDIE (1 << 7) +#define UART_BDH_RXEDGIE (1 << 6) +#define UART_BDH_SBR_MASK 0x1f + +/* BDL: Baud Rate Register Low */ +#define UART_BDL_SBR_MASK 0xff + +/* C1: Control register 1 */ +#define UART_C1_LOOPS (1 << 7) +#define UART_C1_RSRC (1 << 5) +#define UART_C1_M (1 << 4) +#define UART_C1_WAKE (1 << 3) +#define UART_C1_ILT (1 << 2) +#define UART_C1_PE (1 << 1) +#define UART_C1_PT (1 << 0) + +/* C2: Control register 2 */ +#define UART_C2_TIE (1 << 7) +#define UART_C2_TCIE (1 << 6) +#define UART_C2_RIE (1 << 5) +#define UART_C2_ILIE (1 << 4) +#define UART_C2_TE (1 << 3) +#define UART_C2_RE (1 << 2) +#define UART_C2_RWU (1 << 1) +#define UART_C2_SBK (1 << 0) + +/* S1: Status register 1 */ +#define UART_S1_TDRE (1 << 7) +#define UART_S1_TC (1 << 6) +#define UART_S1_RDRF (1 << 5) +#define UART_S1_IDLE (1 << 4) +#define UART_S1_OR (1 << 3) +#define UART_S1_NF (1 << 2) +#define UART_S1_FE (1 << 1) +#define UART_S1_PF (1 << 0) + +/* S2: Status register 2 */ +#define UART_S2_LBKDIF (1 << 7) +#define UART_S2_RXEDGIF (1 << 6) +#define UART_S2_MSBF (1 << 5) +#define UART_S2_RXINV (1 << 4) +#define UART_S2_RWUID (1 << 3) +#define UART_S2_BRK13 (1 << 2) +#define UART_S2_LBKDE (1 << 1) +#define UART_S2_RAF (1 << 0) + +/* C3: Control register 3 */ +#define UART_C3_R8 (1 << 7) +#define UART_C3_T8 (1 << 6) +#define UART_C3_TXDIR (1 << 5) +#define UART_C3_TXINV (1 << 4) +#define UART_C3_ORIE (1 << 3) +#define UART_C3_NEIE (1 << 2) +#define UART_C3_FEIE (1 << 1) +#define UART_C3_PEIE (1 << 0) + +/* MODEM: Modem configuration register */ +#define UART_MODEM_RXRTSE (1 << 3) +#define UART_MODEM_TXRTSPOL (1 << 2) +#define UART_MODEM_TXRTSE (1 << 1) +#define UART_MODEM_TXCTSE (1 << 0) + +/****************************************************************************/ +/** @defgroup uart_parity UART Parity Selection +@ingroup VF6xx_uart_defines + +@{*/ +#define UART_PARITY_NONE 0x00 +#define UART_PARITY_EVEN UART_C1_PE +#define UART_PARITY_ODD (UART_C1_PE | UART_C1_PT) +/**@}*/ +#define UART_PARITY_MASK 0x3 + +/* CR3_CTSE/CR3_RTSE combined values */ +/****************************************************************************/ +/** @defgroup usart_cr3_flowcontrol USART Hardware Flow Control Selection +@ingroup STM32F_usart_defines + +@{*/ +#define UART_FLOWCONTROL_NONE 0x00 +#define UART_FLOWCONTROL_RTS UART_MODEM_RXRTSE +#define UART_FLOWCONTROL_CTS UART_MODEM_TXCTSE +#define UART_FLOWCONTROL_RTS_CTS (UART_MODEM_RXRTSE | UART_MODEM_TXCTSE) +/**@}*/ +#define UART_FLOWCONTROL_MASK (UART_MODEM_RXRTSE | UART_MODEM_TXCTSE) + +/* --- Function prototypes ------------------------------------------------- */ + +#include + +BEGIN_DECLS + +void uart_enable(uint32_t uart); +void uart_disable(uint32_t uart); +void uart_set_baudrate(uint32_t uart, uint32_t baud); +void uart_set_parity(uint32_t uart, uint8_t parity); +void uart_set_flow_control(uint32_t uart, uint8_t flowcontrol); +void uart_send(uint32_t uart, uint8_t data); +void uart_send_blocking(uint32_t usart, uint8_t data); +void uart_wait_send_ready(uint32_t uart); +uint8_t uart_recv(uint32_t uart); +uint8_t uart_recv_blocking(uint32_t uart); +void uart_wait_recv_ready(uint32_t uart); + +END_DECLS + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/core_cm3.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/core_cm3.h new file mode 100644 index 00000000..c54137b4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/core_cm3.h @@ -0,0 +1,183 @@ +/* big fat FIXME: this should use a consistent structure, and reference + * functionality from libopencm3 instead of copypasting. + * + * particularly unimplemented features are FIXME'd extra + * */ + +/* the original core_cm3.h is nonfree by arm; this provides libopencm3 variant + * of the symbols efm32lib needs of CMSIS. */ + +#ifndef OPENCMSIS_CORECM3_H +#define OPENCMSIS_CORECM3_H + +#include +#include +#include +#include +#include +#include + +/* needed by system_efm32.h:196, guessing */ +#define __INLINE inline +/* new since emlib 3.0 */ +#define __STATIC_INLINE static inline + +/* needed around efm32tg840f32.h:229. comparing the efm32lib definitions to the + * libopencm3 ones, "volatile" is all that's missing. */ +#define __IO volatile +#define __O volatile +#define __I volatile + +/* -> style access for what is defined in libopencm3/stm32/f1/scb.h / + * cm3/memorymap.h, as it's needed by efm32lib/inc/efm32_emu.h */ + +/* from cm3/scb.h */ +#define SCB_SCR_SLEEPDEEP_Msk SCB_SCR_SLEEPDEEP + +/* structure as in, for example, + * DeviceSupport/EnergyMicro/EFM32/efm32tg840f32.h, data from + * libopencm3/cm3/scb.h. FIXME incomplete. */ +typedef struct { + __IO uint32_t CPUID; + __IO uint32_t ICSR; + __IO uint32_t VTOR; + __IO uint32_t AIRCR; + __IO uint32_t SCR; + __IO uint32_t CCR; + __IO uint8_t SHPR[12]; /* FIXME: how is this properly indexed? */ + __IO uint32_t SHCSR; +} SCB_TypeDef; +#define SCB ((SCB_TypeDef *) SCB_BASE) + +/* needed by efm32_emu.h, guessing and taking the implementation used in + * lightswitch-interrupt.c */ +#define __WFI() __asm__("wfi") + +/* needed by efm32_cmu.h, probably it's just what gcc provides anyway */ +#define __CLZ(div) __builtin_clz(div) + +/* needed by efm32_aes.c. __builtin_bswap32 does the same thing as the rev + * instruction according to https://bugzilla.mozilla.org/show_bug.cgi?id=600106 + */ +#define __REV(x) __builtin_bswap32(x) + +/* stubs for efm32_dbg.h */ +typedef struct { + uint32_t DHCSR; + uint32_t DEMCR; /* needed by efm32tg stk trace.c */ +} CoreDebug_TypeDef; +/* FIXME let's just hope writes to flash are protected */ +#define CoreDebug ((CoreDebug_TypeDef *) 0) +#define CoreDebug_DHCSR_C_DEBUGEN_Msk 0 +#define CoreDebug_DEMCR_TRCENA_Msk 0 + +/* stubs for efm32_dma */ + +static inline void NVIC_ClearPendingIRQ(uint8_t irqn) +{ + nvic_clear_pending_irq(irqn); +} +static inline void NVIC_EnableIRQ(uint8_t irqn) +{ + nvic_enable_irq(irqn); +} +static inline void NVIC_DisableIRQ(uint8_t irqn) +{ + nvic_disable_irq(irqn); +} + +/* stubs for efm32_int */ + +static inline void __enable_irq(void) +{ + cm_enable_interrupts(); +} +static inline void __disable_irq(void) +{ + cm_disable_interrupts(); +} + +/* stubs for efm32_mpu FIXME */ + +#define SCB_SHCSR_MEMFAULTENA_Msk 0 + +typedef struct { + uint32_t CTRL; + uint32_t RNR; + uint32_t RBAR; + uint32_t RASR; +} MPU_TypeDef; +/* FIXME struct at NULL */ +#define MPU ((MPU_TypeDef *) 0) +#define MPU_CTRL_ENABLE_Msk 0 +#define MPU_RASR_XN_Pos 0 +#define MPU_RASR_AP_Pos 0 +#define MPU_RASR_TEX_Pos 0 +#define MPU_RASR_S_Pos 0 +#define MPU_RASR_C_Pos 0 +#define MPU_RASR_B_Pos 0 +#define MPU_RASR_SRD_Pos 0 +#define MPU_RASR_SIZE_Pos 0 +#define MPU_RASR_ENABLE_Pos 0 + +/* required for the blink example */ + +/* if if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ; + * configures the sys ticks to 1ms, then the argument to SysTick_Config + * describes how many cycles to wait between two systicks. + * + * the endless loop part looks like an "if it returns an error condition, + * rather loop here than continue"; every other solution would involve things + * that are dark magic to my understanding. + * + * implementation more or less copypasted from lib/stm32/systick.c, FIXME until + * the generic cm3 functionality is moved out from stm32 and can be used here + * easily (systick_set_reload, systick_interrupt_enable, systick_counter_enable + * and systick_set_clocksource). + * + * modified for CMSIS style array as the powertest example needs it. + * */ + +/* from d0002_efm32_cortex-m3_reference_manual.pdf section 4.4 */ +typedef struct { + uint32_t CTRL; + uint32_t LOAD; + uint32_t VAL; + uint32_t CALIB; +} SysTick_TypeDef; +#define SysTick ((SysTick_TypeDef *) SYS_TICK_BASE) + +static inline uint32_t SysTick_Config(uint32_t n_ticks) +{ + /* constant from systick_set_reload -- as this returns something that's + * not void, this is the only possible error condition */ + if (n_ticks & ~0x00FFFFFF) { + return 1; + } + + systick_set_reload(n_ticks); + systick_set_clocksource(true); + systick_interrupt_enable(); + systick_counter_enable(); + + return 0; +} + +/* stubs for efm32tg stk trace.c */ +typedef struct { + uint32_t LAR; + uint32_t TCR; +} ITM_TypeDef; +/* FIXME struct at NULL */ +#define ITM ((ITM_TypeDef *) 0) + +/* blink.h expects the isr for systicks to be named SysTick_Handler. with this, + * its Systick_Handler function gets renamed to the weak symbol exported by + * vector.c */ + +#define SysTick_Handler sys_tick_handler +/* FIXME: this needs to be done for all of the 14 hard vectors */ + +#include + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/dispatch/irqhandlers.h b/hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/dispatch/irqhandlers.h new file mode 100644 index 00000000..ad64306b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/include/libopencmsis/dispatch/irqhandlers.h @@ -0,0 +1,50 @@ +#if defined(STM32F0) +# include +#elif defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F3) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include + +#elif defined(EFM32TG) +# include +#elif defined(EFM32G) +# include +#elif defined(EFM32LG) +# include +#elif defined(EFM32GG) +# include + +#elif defined(LPC13XX) +# include +#elif defined(LPC17XX) +# include +#elif defined(LPC43XX_M4) +# include +#elif defined(LPC43XX_M0) +# include + +#elif defined(SAM3A) +# include +#elif defined(SAM3N) +# include +#elif defined(SAM3S) +# include +#elif defined(SAM3U) +# include +#elif defined(SAM3X) +# include + +#elif defined(LM3S) || defined(LM4F) +/* Yes, we use the same interrupt table for both LM3S and LM4F */ +# include + +#else +# warning"no chipset defined; user interrupts are not redirected" + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.example b/hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.example new file mode 100644 index 00000000..60b01af4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.example @@ -0,0 +1,46 @@ +BINARY = button + +DEVICE = stm32f407vgt6 + +# common Makefile.include from examples directory unpacked and stripped +#include ../../Makefile.include + +CC = arm-none-eabi-gcc +LD = arm-none-eabi-gcc +OBJCOPY = arm-none-eabi-objcopy +OBJDUMP = arm-none-eabi-objdump +GDB = arm-none-eabi-gdb + +TOOLCHAIN_DIR ?= ../../../../../libopencm3 + +CFLAGS += <...> +LDSCRIPT ?= $(BINARY).ld +LDFLAGS += <..> +OBJS += $(BINARY).o + +GENFILES ?= *.o + +all: images + +## This is the place where the translation DEVICE->LDSCRIPT will be executed +include $(TOOLCHAIN_DIR)/ld/Makefile.linker + +images: $(BINARY).images +flash: $(BINARY).flash + +<... comon makefile continues ...> + +clean: + $(Q)rm -f *.o + $(Q)rm -f *.d + $(Q)rm -f *.elf + $(Q)rm -f *.bin + $(Q)rm -f *.hex + $(Q)rm -f *.srec + $(Q)rm -f *.list + $(Q)rm -f $(GENFILES) + +.PHONY: images clean + +-include $(OBJS:.o=.d) + diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.linker b/hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.linker new file mode 100644 index 00000000..ae730a97 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/Makefile.linker @@ -0,0 +1,71 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2013 Frantisek Burian +## +## Linker script generator feature +## ------------------------------- +## +## This generator will generate .ld linker script file in the project +## directory for the specified device, and this script will be automatically +## used as main linker script during the build process. +## +## WARNING: You must include this file after all shared variables are setup, +## and before the command section begins. Ideal place of the include is exactly +## after the all: rule in Your makefile. +## +## Options +## ------- +## +## This feature is configured by specifying variable DEVICE= +## in the makefile of Your project. +## +## WARNING Please don't forget to specify full name of the chip you are using. +## Many chip families have device specific letters specified on the end of +## device name string. +## +## Example: +## -------- +## +## @code +## DEVICE=stm32f407vgt6 +## <... common makefile code ...> +## all: images +## +## include /ld/Makefile.linker +## +## images: <....> +## @endcode + +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +ifneq ($(DEVICE),) + +LDSCRIPT=$(DEVICE).ld +LD_PARAMS=$(shell awk -v PAT="$(DEVICE)" -f $(SRCLIBDIR)/scripts/genlink.awk $(SRCLIBDIR)/ld/devices.data 2>/dev/null) +CFLAGS+=$(LD_PARAMS) +LDFLAGS+=$(LD_PARAMS) +ARCH_FLAGS= + +$(LDSCRIPT):$(SRCLIBDIR)/ld/linker.ld.S +ifeq ($(LD_PARAMS),) + $(error unknown device $(DEVICE) for the linker. Cannot generate ldscript) +endif + @#printf " GENLNK $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(LD_PARAMS) -P -E $< > $@ + +GENFILES += $(LDSCRIPT) +endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/README b/hardware-wallet/firmware/vendor/libopencm3/ld/README new file mode 100644 index 00000000..f270afbf --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/README @@ -0,0 +1,157 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +LIBOPENCM3 LINKER SCRIPT GENERATOR +---------------------------------- + +This folder contains files needed for the automatic linker script generation +mechanism developed for libopencm3 library. + +File contents +------------- + +* {ROOT}/ld/tests/* - Prepared tests for the testing of the script +* {ROOT}/ld/devices.data - Device database file +* {ROOT}/ld/Makefile.linker - Common makefile part +* {ROOT}/ld/linker.ld.S - Linker script template +* {ROOT}/scripts/genlink.awk - Device database file search script +* {ROOT}/scripts/genlinktest.sh - Device database file search test script + +Principle of operation +---------------------- + +The user specifies in the project Makefile the device part name the project is +using, in the variable DEVICE. Note that full device part name must be +specified, because the device specific features is usually dependent on the +last characters of device name string. Note that the device name string search +is case insensitive. + +DEVICE=stm32f407vgt6 + +Then, the user includes the file /ld/Makefile.linker exactly after the first +target (usually all) has been defined. + +The script automatically modifies the $(LDSCRIPT) variable to meet the new +generated script with .ld in the project directory, and adds +a rule to make it from the scratch. + +Making the script is done by looking to device database file for the needed +definitions, and applying those definitions to the C preprocessor source +linker.ld.S outputting the preprocessed ld file. + +Device database contains definitions of common sections and its origins for +the linker preprocessor. Every definition is interpreted in the linker script +template as a macro, and it can be used for conditional insertion of the device +dependent stuff. + +The search in the device database is pattern-based, and using awk script +genlink.awk. The awk script traverses the file as a tree, joining the options +for the preprocessor together by single space. The awk script adds -D to each +parameter for you. + +Testing +------- + +The testing of feature is done by executing in the root of libopencm3 library. + +make genlinktests + +The test cases are defined in subdirectory {ROOT}/ld/tests/. Each test contains +two files, the database file *.data and the expected result *.result file. If +the particular test fails, the file *.out containing output of the script is +not deleted to help resolving problem with the script. + +The search pattern for the test is the base filename of particular test. + +The testing stops after all test cases are valid, or at first error found. + +Example of use +-------------- + +* See Makefile.example file + +Device database file structure +------------------------------ + +Line description: + ( ...) + + : is the pattern for the chip description to be searched for. + The case of the pattern string is ignored. + Pattern match symbols: + ? - matches exactly one character + * - matches none or more characters + + - matches single or more characters + + : is the parent group name, where the search will continue. + There are special parents names that controls traversing: + "END" - Exit traversal. + "+" - Don't change the parent. Use for split long line to two. + + : space-separated list of preprocessor symbols supplied to the linker. + -D option name with single underscore is automatically prepended to each + symbol definition + if the symbol starts with dash "-", it is interpreted as parameter to + linker, and no -D or underscore is generated. + +All lines starting with # symbol are treated as Comments + +Recommended tree hierarchy: + + + +- + +- + +- END + +You can split the long line into two or more by using "+" in the parent field, +and defining same regex with appropriate parent on the next line. Example: + + device + PARAM1=aaa PARAM2=bbbb PARAM3=ccc PARAM4=dddd PARAM5=eeee + device parent PARAM6=ffff PARAM7=gggg PARAM8=hhhh + parent END + +The order of the lines is important. After the regex match, its parent will +be used for match on the next line. If two regexp lines matches input, only +the first will be evaluated, except special group definition "+" + +The regex matches entire sym + +Example: + +--- devices.data file --- +stm32f05[01]?4* stm32f0 ROM=16K RAM=4K +stm32f0 stm32 ROM_OFF=0x08000000 RAM_OFF=0x20000000 -mcpu=cortex-m0 -mthumb +stm32 END + +--- queried chip name --- +stm32f051c4t6 + +--- output of the awk script --- +-D_ROM=16K -D_RAM=4K -D_ROM_OFF=0x08000000 -D_RAM_OFF=0x20000000 \ +-mcpu=cortex-m0 -mthumb + +The generated linker script file will contain sections rom and ram with +appropriate initialization code, specified in linker file source linker.ld.S + + +Copyright +--------- + +This file is part of the libopencm3 project. + +Copyright (C) 2013 Frantisek Burian +Copyright (C) 2013 Werner Almesberger + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This library 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see . \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/devices.data b/hardware-wallet/firmware/vendor/libopencm3/ld/devices.data new file mode 100644 index 00000000..a27ef62b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/devices.data @@ -0,0 +1,474 @@ +################################################################################ +# +# Device chip tree definition file. +# +# Copyright (c) 2013 Frantisek Burian +# Copyright (C) 2013 Werner Almesberger +# +# Line description: +# ( ...) +# +# : is the pattern for the chip description to be searched for. +# The case of the pattern string is ignored. +# Pattern match symbols: +# ? - matches exactly one character +# * - matches none or more characters +# + - matches single or more characters +# +# : is the parent group name, where the search will continue. +# There are special parents names that controls traversing: +# "END" - Exit traversal. +# "+" - Don't change the parent. Use for split long line to two. +# +# : space-separated list of preprocessor symbols supplied to the linker. +# -D option name is automatically prepended to each symbol definition +# +# All lines starting with # symbol are treated as Comments +# +# Recommended tree hierarchy: +# +# +# +- +# +- +# +- END +# +# You can split the long line into two or more by using "+" in the parent field, +# and defining same regex with appropriate parent on the next line. Example: +# +# device + PARAM1=aaa PARAM2=bbbb PARAM3=ccc PARAM4=dddd PARAM5=eeee +# device parent PARAM6=ffff PARAM7=gggg PARAM8=hhhh +# parent END +# +# The order of the lines is important. After the regex match, its parent will +# be used for match on the next line. If two regexp lines matches input, only +# the first will be evaluated, except special group definition "+" +# +# The regex matches entire sym +# +# Example: +# +# --- devices.data file --- +# stm32f05[01]?4* stm32f0 ROM=16K RAM=4K +# stm32f0 stm32 ROM_OFF=0x08000000 RAM_OFF=0x20000000 +# stm32 END +# +# --- queried chip name --- +# stm32f051c8t6 +# +# --- output of the awk script --- +# -DROM=16K -DRAM=4K -DROM_OFF=0x08000000 -DRAM_OFF=0x20000000 +# +# The generated linker script file will contain sections rom and ram with +# appropriate initialization code, specified in linker file source linker.ld.S +# + +################################################################################ +# the STM32 chips + +stm32f03[01]?4* stm32f0 ROM=16K RAM=4K +stm32f03[01]?6* stm32f0 ROM=32K RAM=4K +stm32f030?8* stm32f0 ROM=64K RAM=8K +stm32f042?4* stm32f0 ROM=16K RAM=6K +stm32f042?6* stm32f0 ROM=32K RAM=6K +stm32f050?4* stm32f0 ROM=16K RAM=4K +stm32f050?6* stm32f0 ROM=32K RAM=4K +stm32f051?4* stm32f0 ROM=16K RAM=8K +stm32f051?6* stm32f0 ROM=32K RAM=8K +stm32f051?8* stm32f0 ROM=64K RAM=8K +stm32f072?8* stm32f0 ROM=64K RAM=16K +stm32f07[12]?b* stm32f0 ROM=128K RAM=16K + +stm32f10[012]?4* stm32f1 ROM=16K RAM=4K +stm32f103?4* stm32f1 ROM=16K RAM=6K +stm32f100?6* stm32f1 ROM=32K RAM=4K +stm32f103?6* stm32f1 ROM=32K RAM=10K +stm32f10[12]?6* stm32f1 ROM=32K RAM=6K +stm32f100?8* stm32f1 ROM=64K RAM=8K +stm32f10[12]?8* stm32f1 ROM=64K RAM=10K +stm32f103?8* stm32f1 ROM=64K RAM=20K +stm32f105?8* stm32f1 ROM=64K RAM=64K +stm32f100?b* stm32f1 ROM=128K RAM=8K +stm32f10[12]?b* stm32f1 ROM=128K RAM=16K +stm32f103?b* stm32f1 ROM=128K RAM=20K +stm32f10[57]?b* stm32f1 ROM=128K RAM=64K +stm32f100?c* stm32f1 ROM=256K RAM=24K +stm32f101?c* stm32f1 ROM=256K RAM=32K +stm32f103?c* stm32f1 ROM=256K RAM=48K +stm32f10[57]?c* stm32f1 ROM=256K RAM=64K +stm32f100?d* stm32f1 ROM=384K RAM=32K +stm32f101?d* stm32f1 ROM=384K RAM=48K +stm32f103?d* stm32f1 ROM=384K RAM=64K +stm32f100?e* stm32f1 ROM=512K RAM=32K +stm32f101?e* stm32f1 ROM=512K RAM=48K +stm32f103?e* stm32f1 ROM=512K RAM=64K +stm32f100?f* stm32f1 ROM=768K RAM=80K +stm32f103?f* stm32f1 ROM=768K RAM=96K +stm32f100?g* stm32f1 ROM=1024K RAM=80K +stm32f103?g* stm32f1 ROM=1024K RAM=96K + +stm32f205?b* stm32f2 ROM=128K RAM=64K +stm32f205?c* stm32f2 ROM=256K RAM=96K +stm32f207?c* stm32f2 ROM=256K RAM=128K +stm32f2[01][57]?e* stm32f2 ROM=512K RAM=128K +stm32f20[57]?f* stm32f2 ROM=768K RAM=128K +stm32f2[01][57]?g* stm32f2 ROM=1024K RAM=128K + +stm32f302?b* stm32f3ccm ROM=128K RAM=24K CCM=8K +stm32f302?c* stm32f3ccm ROM=256K RAM=32K CCM=8K +stm32f302?8* stm32f3 ROM=64K RAM=16K +stm32f303?b* stm32f3ccm ROM=128K RAM=32K CCM=8K +stm32f3[01]3?c* stm32f3ccm ROM=256K RAM=40K CCM=8K +stm32f373?8* stm32f3 ROM=64K RAM=16K +stm32f373?b* stm32f3 ROM=128K RAM=24K +stm32f373?c* stm32f3 ROM=256K RAM=32K +stm32f3[78]3?8* stm32f3 ROM=256K RAM=32K + +stm32f401?b* stm32f4 ROM=128K RAM=64K +stm32f401?c* stm32f4 ROM=256K RAM=64K +stm32f401?d* stm32f4 ROM=384K RAM=96K +stm32f401?e* stm32f4 ROM=512K RAM=96K +stm32f4[01][57]?e* stm32f4ccm ROM=512K RAM=128K CCM=64K +stm32f4[01][57]?g* stm32f4ccm ROM=1024K RAM=128K CCM=64K +stm32f411re stm32f4 ROM=512K RAM=128K +stm32f4[23][79]?g* stm32f4ccm ROM=1024K RAM=192K CCM=64K +stm32f4[23][79]?i* stm32f4ccm ROM=2048K RAM=192K CCM=64K + +# on F7 CCM is in some datasheets named as DTCM +stm32f7[23][23]?c* stm32f7ccm ROM=256K RAM=192K CCM=64K +stm32f7[23][23]?e* stm32f7ccm ROM=512K RAM=192K CCM=64K +stm32f745?e* stm32f7ccm ROM=512K RAM=256K CCM=64K +stm32f745?g* stm32f7ccm ROM=1024K RAM=256K CCM=64K +stm32f765?g* stm32f7ccm ROM=512K RAM=384K CCM=128K +stm32f765?i* stm32f7ccm ROM=2048K RAM=384K CCM=128K +stm32f7[45]6?e* stm32f7ccm ROM=512K RAM=256K CCM=64K +stm32f7[45]6?g* stm32f7ccm ROM=1024K RAM=256K CCM=64K +stm32f7[67]7?g* stm32f7ccm ROM=1024K RAM=384K CCM=128K +stm32f7[67]7?i* stm32f7ccm ROM=2048K RAM=384K CCM=128K +stm32f769?g* stm32f7ccm ROM=1024K RAM=384K CCM=128K +stm32f7[67][89]?i* stm32f7ccm ROM=2048K RAM=384K CCM=128K + +stm32l01??3* stm32l0 ROM=8K RAM=2K +stm32l0[12]??4* stm32l0 ROM=16K RAM=2K +stm32l03??4* stm32l0 ROM=16K RAM=8K +stm32l0???6* stm32l0 ROM=32K RAM=8K +stm32l0[56]??8* stm32l0 ROM=64K RAM=8K +stm32l0[78]??8* stm32l0 ROM=64K RAM=20K +stm32l0???b* stm32l0 ROM=128K RAM=20K +stm32l0???z* stm32l0 ROM=192K RAM=20K + +stm32l100?6* stm32l1 ROM=32K RAM=4K +stm32l100?8* stm32l1 ROM=64K RAM=8K +stm32l100?b* stm32l1 ROM=128K RAM=10K +stm32l100?c* stm32l1 ROM=256K RAM=16K +stm32l15[12]?6* stm32l1eep ROM=32K RAM=10K EEP=4K +stm32l15[12]?8* stm32l1eep ROM=64K RAM=10K EEP=4K +stm32l15[12]?b* stm32l1eep ROM=128K RAM=16K EEP=4K +stm32l15[12]?c* stm32l1eep ROM=256K RAM=32K EEP=8K +stm32l15[12]?d* stm32l1eep ROM=384K RAM=48K EEP=12K +stm32l162?c* stm32l1eep ROM=256K RAM=32K EEP=8K +stm32l162?d* stm32l1eep ROM=384K RAM=48K EEP=12K + +stm32l4?6?c* stm32l4 ROM=256K RAM=96K RAM2=32K +stm32l4?6?e* stm32l4 ROM=512K RAM=96K RAM2=32K +stm32l4?6?g* stm32l4 ROM=1024K RAM=96K RAM2=32K + +stm32ts60 stm32t ROM=32K RAM=10K + +stm32w108c8 stm32w ROM=64K RAM=8K +stm32w108?b stm32w ROM=128K RAM=8K +stm32w108cz stm32w ROM=192K RAM=12K +stm32w108cc stm32w ROM=256K RAM=16K + +################################################################################ +# the SAM3 chips + +sam3a4* sam3a ROM=256K RAM=32K RAM1=32K +sam3a8* sam3a ROM=512K RAM=64K RAM1=32K + +sam3n00* sam3n ROM=16K RAM=4K +sam3n0* sam3n ROM=32K RAM=8K +sam3n1* sam3n ROM=64K RAM=8K +sam3n2* sam3n ROM=128K RAM=16K +sam3n4* sam3n ROM=256K RAM=24K + +sam3s1* sam3s ROM=64K RAM=16K +sam3s2* sam3s ROM=128K RAM=32K +sam3s4* sam3s ROM=256K RAM=48K +sam3s8* sam3s ROM=512K RAM=64K +sam3sd8* sam3s ROM=512K RAM=64K + +sam3u1* sam3u ROM=64K RAM=8K RAM1=8K +sam3u2* sam3u ROM=128K RAM=16K RAM1=16K +sam3u4* sam3u ROM=265K RAM=32K RAM1=16K + +sam3x4c* sam3x ROM=256K RAM=32K RAM1=32K +sam3x4e* sam3xnfc ROM=256K RAM=32K RAM1=32K +sam3x8c* sam3x ROM=512K RAM=64K RAM1=32K +sam3x8e* sam3xnfc ROM=512K RAM=64K RAM1=32K + +samd10?13* samd ROM=8K RAM=4K +samd10?14* samd ROM=16K RAM=4K + +################################################################################ +# the lpc chips + +lpc1311* lpc13 ROM=8K RAM=4K +lpc1313* lpc13 ROM=32K RAM=8K +lpc1342* lpc13 ROM=16K RAM=4K +lpc1343* lpc13 ROM=32K RAM=8K +lpc1315* lpc13u ROM=32K RAM=8K +lpc1316* lpc13u ROM=48K RAM=8K +lpc1317* lpc13u ROM=64K RAM=8K RAM1=2K +lpc1345* lpc13u ROM=32K RAM=8K USBRAM=2K +lpc1346* lpc13u ROM=48K RAM=8K USBRAM=2K +lpc1346* lpc13u ROM=64K RAM=8K USBRAM=2K RAM1=2K + +lpc1751* lpc175x ROM=32K RAM=8K +lpc1752* lpc175x ROM=64K RAM=16K +lpc1754* lpc175x ROM=128K RAM=16K RAM1=16K +lpc1756* lpc175x ROM=256K RAM=16K RAM1=16K +lpc1758* lpc175x ROM=512K RAM=32K RAM1=16K RAM2=16K +lpc1759* lpc175x ROM=512K RAM=32K RAM1=16K RAM2=16K +lpc1763* lpc176x ROM=256K RAM=32K RAM1=16K RAM2=16K +lpc1764* lpc176x ROM=128K RAM=16K RAM1=16K +lpc1765* lpc176x ROM=256K RAM=32K RAM1=16K RAM2=16K +lpc1766* lpc176x ROM=256K RAM=32K RAM1=16K RAM2=16K +lpc1767* lpc176x ROM=512K RAM=32K RAM1=16K RAM2=16K +lpc1768* lpc176x ROM=512K RAM=32K RAM1=16K RAM2=16K +lpc1769* lpc176x ROM=512K RAM=32K RAM1=16K RAM2=16K +lpc1774* lpc177x ROM=128K RAM=32K RAM1=8K +lpc1776* lpc177x ROM=256K RAM=64K RAM1=16K +lpc1777* lpc177x ROM=512K RAM=64K RAM1=16K RAM2=16K +lpc1778* lpc177x ROM=512K RAM=64K RAM1=16K RAM2=16K +lpc1785* lpc178x ROM=256K RAM=64K RAM1=16K +lpc1786* lpc178x ROM=256K RAM=64K RAM1=16K +lpc1787* lpc178x ROM=512K RAM=64K RAM1=16K RAM2=16K +lpc1788* lpc178x ROM=512K RAM=64K RAM1=16K RAM2=16K + +lpc4370* lpc43xx RAM=128K RAM1=72K RAM2=32K RAM3=16K +lpc4350* lpc43xx RAM=128K RAM1=72K RAM2=32K RAM3=16K +lpc4330* lpc43xx RAM=128K RAM1=72K RAM2=32K RAM3=16K +lpc4320* lpc43xx RAM=96K RAM1=40K RAM2=32K RAM3=16K +lpc4310* lpc43xx RAM=96K RAM1=40K RAM2=16K +lpc43S70* lpc43xx RAM=128K RAM1=72K RAM2=32K RAM3=16K +lpc43S50* lpc43xx RAM=128K RAM1=72K RAM2=32K RAM3=16K +lpc43S30* lpc43xx RAM=128K RAM1=72K RAM2=32K RAM3=16K +lpc43S20* lpc43xx RAM=96K RAM1=40K RAM2=32K RAM3=16K +lpc43S10* lpc43xx RAM=96K RAM1=40K RAM2=16K +lpc4367* lpc43xx ROM=512K ROM1=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4357* lpc43xx ROM=512K ROM1=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4355* lpc43xx ROM=384K ROM1=384K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4353* lpc43xx ROM=256K ROM1=256K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4352* lpc43xx ROM=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4350* lpc43xx RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4337* lpc43xx ROM=512K ROM1=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4335* lpc43xx ROM=384K ROM1=384K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4333* lpc43xx ROM=256K ROM1=256K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4332* lpc43xx ROM=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4330* lpc43xx RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4327* lpc43xx ROM=512K ROM1=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4325* lpc43xx ROM=384K ROM1=384K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4323* lpc43xx ROM=256K ROM1=256K RAM=32K RAM1=40K RAM2=16K +lpc4322* lpc43xx ROM=512K RAM=32K RAM1=40K RAM2=16K +lpc4317* lpc43xx ROM=512K ROM1=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4315* lpc43xx ROM=384K ROM1=384K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc4313* lpc43xx ROM=256K ROM1=256K RAM=32K RAM1=40K RAM2=16K +lpc4312* lpc43xx ROM=512K RAM=32K RAM1=40K RAM2=16K +lpc43S67* lpc43xx ROM=512K ROM1=512K RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc43S57* lpc43xx RAM=32K RAM1=40K RAM2=32K RAM3=16K +lpc43S37* lpc43xx RAM=32K RAM1=40K RAM2=32K RAM3=16K + +################################################################################ +# the efm32 chips + +# Zero Gecko +efm32zg???f4 efm32zg ROM=4K RAM=2K +efm32zg???f8 efm32zg ROM=8K RAM=2K +efm32zg???f16 efm32zg ROM=16K RAM=4K +efm32zg???f32 efm32zg ROM=32K RAM=4K + +# Tiny Gecko +efm32tg108f4 efm32tg ROM=4K RAM=1K +efm32tg110f4 efm32tg ROM=4K RAM=2K +efm32tg???f8 efm32tg ROM=8K RAM=2K +efm32tg???f16 efm32tg ROM=16K RAM=4K +efm32tg???f32 efm32tg ROM=32K RAM=4K + +# Gecko +efm32g200f16 efm32g ROM=16K RAM=8K +efm32g???f32 efm32g ROM=32K RAM=8K +efm32g???f64 efm32g ROM=64K RAM=16K +efm32g???f128 efm32g ROM=128K RAM=16K + +# Large Gecko +efm32lg???f64 efm32lg ROM=64K RAM=32K +efm32lg???f128 efm32lg ROM=128K RAM=32K +efm32lg???f256 efm32lg ROM=256K RAM=32K + +# Giant Gecko +efm32gg???f512 efm32gg ROM=512K RAM=128K +efm32gg???f1024 efm32gg ROM=1024K RAM=128K + +# Wonder Gecko +efm32wg???f64 efm32gg ROM=64K RAM=32K +efm32wg???f128 efm32gg ROM=128K RAM=32K +efm32wg???f256 efm32gg ROM=256K RAM=32K + +################################################################################ +# the TI cortex M3 chips + +lm3s101 lm3sandstorm ROM=8K RAM=2K +lm3s102 lm3sandstorm ROM=8K RAM=2K + +lm3s300 lm3sandstorm ROM=16K RAM=4K +lm3s301 lm3sandstorm ROM=16K RAM=2K +lm3s308 lm3sandstorm ROM=16K RAM=4K +lm3s310 lm3sandstorm ROM=16K RAM=4K +lm3s315 lm3sandstorm ROM=16K RAM=4K +lm3s316 lm3sandstorm ROM=16K RAM=4K +lm3s317 lm3sandstorm ROM=16K RAM=4K +lm3s328 lm3sandstorm ROM=16K RAM=4K +lm3s600 lm3sandstorm ROM=32K RAM=8K +lm3s601 lm3sandstorm ROM=32K RAM=8K +lm3s608 lm3sandstorm ROM=32K RAM=8K +lm3s610 lm3sandstorm ROM=32K RAM=8K +lm3s611 lm3sandstorm ROM=32K RAM=8K +lm3s612 lm3sandstorm ROM=32K RAM=8K +lm3s613 lm3sandstorm ROM=32K RAM=8K +lm3s615 lm3sandstorm ROM=32K RAM=8K +lm3s617 lm3sandstorm ROM=32K RAM=8K +lm3s618 lm3sandstorm ROM=32K RAM=8K +lm3s628 lm3sandstorm ROM=32K RAM=8K +lm3s800 lm3sandstorm ROM=64K RAM=8K +lm3s801 lm3sandstorm ROM=64K RAM=8K +lm3s808 lm3sandstorm ROM=64K RAM=8K +lm3s811 lm3sandstorm ROM=64K RAM=8K +lm3s812 lm3sandstorm ROM=64K RAM=8K +lm3s815 lm3sandstorm ROM=64K RAM=8K +lm3s817 lm3sandstorm ROM=64K RAM=8K +lm3s818 lm3sandstorm ROM=64K RAM=8K +lm3s828 lm3sandstorm ROM=64K RAM=8K + +lm3s1110 lm3fury ROM=64K RAM=16K +lm3s1133 lm3fury ROM=64K RAM=16K +lm3s1138 lm3fury ROM=64K RAM=16K +lm3s1150 lm3fury ROM=64K RAM=16K +lm3s1162 lm3fury ROM=64K RAM=16K +lm3s1165 lm3fury ROM=64K RAM=16K +lm3s1332 lm3fury ROM=96K RAM=16K +lm3s1435 lm3fury ROM=96K RAM=32K +lm3s1439 lm3fury ROM=96K RAM=32K +lm3s1512 lm3fury ROM=96K RAM=64K +lm3s1538 lm3fury ROM=96K RAM=64K +lm3s1601 lm3fury ROM=128K RAM=32K +lm3s1607 lm3fury ROM=128K RAM=32K +lm3s1608 lm3fury ROM=128K RAM=32K +lm3s1620 lm3fury ROM=128K RAM=32K +lm3s3748 lm3fury ROM=128K RAM=64K +lm3s6965 lm3fury ROM=256K RAM=64K +lm3s8962 lm3fury ROM=256K RAM=64K + +lm4f120xl lm4f ROM=128K RAM=32K + + +################################################################################ +# the TI cortex R4F chips + +rm46l852* rm46l ROM=1280K RAM=192K + +################################################################################ +# NXP/Freescale Vybrid VF6xx parts. (Cortex A5+M4 pair) + +vf610 vf6xx RAM=256K RAM1=256K RAM_OFF=0x1f000000 RAM1_OFF=0x3f040000 + +################################################################################ +################################################################################ +################################################################################ +# the STM32 family groups + +stm32f3ccm stm32f3 CCM_OFF=0x10000000 +stm32f4ccm stm32f4 CCM_OFF=0x10000000 +stm32f7ccm stm32f7 CCM_OFF=0x20000000 +stm32l1eep stm32l1 EEP_OFF=0x08080000 + +################################################################################ +# the SAM3 family groups +sam3xnfc sam3x NFCRAM=4K NFCRAM_OFF=0x20100000 + +################################################################################ +# the lpc family groups + +lpc13 lpc13xx +lpc13u lpc13xx USBRAM_OFF=0x20004000 + +lpc17[56]x lpc17xx RAM1_OFF=0x2007C000 RAM2_OFF=0x20080000 +lpc17[78]x lpc17xx RAM1_OFF=0x20000000 RAM2_OFF=0x20040000 + +lpc43xx_m0 lpc43xx CPU=cortex-m0 FPU=soft +lpc43xx_m4 lpc43xx CPU=cortex-m4 FPU=hard-fp4-sp-d16 + +################################################################################ +################################################################################ +################################################################################ +# the STM32 families + +stm32f0 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m0 FPU=soft +stm32f1 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +stm32f2 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +stm32f3 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 +stm32f4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 +#stm32f7 is supported on GCC-arm-embedded 4.8 2014q4 +stm32f7 END ROM_OFF=0x08000000 RAM_OFF=0x20010000 CPU=cortex-m7 FPU=hard-fpv5-sp-d16 +stm32l0 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m0plus FPU=soft +stm32l1 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +stm32l4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 RAM2_OFF=0x10000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 +stm32w END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +stm32t END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft + +################################################################################ +# the SAM3 families + +sam3a END ROM_OFF=0x00080000 RAM_OFF=0x20000000 RAM1_OFF=0x20080000 CPU=cortex-m3 FPU=soft +sam3n END ROM_OFF=0x00400000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +sam3s END ROM_OFF=0x00400000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +sam3u END ROM_OFF=0x00080000 RAM_OFF=0x20000000 RAM1_OFF=0x20080000 NFCRAM=4K NFCRAM_OFF=0x20100000 CPU=cortex-m3 FPU=soft +sam3x END ROM_OFF=0x00080000 RAM_OFF=0x20000000 RAM1_OFF=0x20080000 CPU=cortex-m3 FPU=soft +samd END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m0plus FPU=soft + +################################################################################ +# the lpc families + +lpc13xx END ROM_OFF=0x00000000 RAM_OFF=0x10000000 RAM1_OFF=0x20000000 CPU=cortex-m3 FPU=soft +lpc17xx END ROM_OFF=0x00000000 RAM_OFF=0x10000000 CPU=cortex-m3 FPU=soft +lpc43xx + ROM_OFF=0x1A000000 ROM1_OFF=0x1B000000 RAM_OFF=0x10000000 RAM1_OFF=0x10080000 +lpc43xx + RAM2_OFF=0x20000000 RAM3_OFF=0x20008000 +lpc43xx END CPU=cortex-m4 FPU=hard-fpv4-sp-d16 + +################################################################################ +# the efm32 Gecko families + +efm32zg END ROM_OFF=0x00000000 RAM_OFF=0x20000000 RAM1_OFF=0x10000000 CPU=cortex-m0plus FPU=soft +efm32tg END ROM_OFF=0x00000000 RAM_OFF=0x20000000 RAM1_OFF=0x10000000 CPU=cortex-m3 FPU=soft +efm32g END ROM_OFF=0x00000000 RAM_OFF=0x20000000 RAM1_OFF=0x10000000 CPU=cortex-m3 FPU=soft +efm32lg END ROM_OFF=0x00000000 RAM_OFF=0x20000000 RAM1_OFF=0x10000000 CPU=cortex-m3 FPU=soft +efm32gg END ROM_OFF=0x00000000 RAM_OFF=0x20000000 RAM1_OFF=0x10000000 CPU=cortex-m3 FPU=soft +efm32wg END ROM_OFF=0x00000000 RAM_OFF=0x20000000 RAM1_OFF=0x10000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 + +################################################################################ +# Cortex LM3 and LM4 families + +lm3fury lm3s +lm3sandstorm lm3s +lm3s END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +lm4f END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 + + +################################################################################ +# Cortex R4F families + +rm46l END ROM_OFF=0x00000000 RAM_OFF=0x08000000 RAM1_OFF=0x08400000 + +################################################################################ +# VF6xx families + +vf6xx END CPU=cortex-m4 FPU=hard-fpv4-sp-d16 diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/linker.ld.S b/hardware-wallet/firmware/vendor/libopencm3/ld/linker.ld.S new file mode 100644 index 00000000..51cdacd5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/linker.ld.S @@ -0,0 +1,186 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for all targets using libopencm3. */ + +/* Enforce emmition of the vector table. */ +EXTERN(vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define memory regions. */ +MEMORY +{ + /* RAM is always used */ + ram (rwx) : ORIGIN = _RAM_OFF, LENGTH = _RAM + +#if defined(_ROM) + rom (rx) : ORIGIN = _ROM_OFF, LENGTH = _ROM +#endif +#if defined(_ROM1) + rom1 (rx) : ORIGIN = _ROM1_OFF, LENGTH = _ROM1 +#endif +#if defined(_ROM2) + rom2 (rx) : ORIGIN = _ROM2_OFF, LENGTH = _ROM2 +#endif +#if defined(_RAM1) + ram1 (rwx) : ORIGIN = _RAM1_OFF, LENGTH = _RAM1 +#endif +#if defined(_RAM2) + ram2 (rwx) : ORIGIN = _RAM2_OFF, LENGTH = _RAM2 +#endif +#if defined(_CCM) + ccm (rwx) : ORIGIN = _CCM_OFF, LENGTH = _CCM +#endif +#if defined(_EEP) + eep (r) : ORIGIN = _EEP_OFF, LENGTH = _EEP +#endif +#if defined(_XSRAM) + xsram (rw) : ORIGIN = _XSRAM_OFF, LENGTH = _XSRAM +#endif +#if defined(_XDRAM) + xdram (rw) : ORIGIN = _XDRAM_OFF, LENGTH = _XDRAM +#endif +#if defined(_NFCRAM) + nfcram (rw) : ORIGIN _NFCRAM_OFF, LENGTH = _NFCRAM +#endif +} + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for + * __attribute__((constructor)) and the likes. + */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + +#if defined(_CCM) + .ccm : { + *(.ccmram*) + . = ALIGN(4); + } >ccm +#endif + +#if defined(_RAM1) + .ram1 : { + *(.ram1*) + . = ALIGN(4); + } >ram1 +#endif + +#if defined(_RAM2) + .ram2 : { + *(.ram2*) + . = ALIGN(4); + } >ram2 +#endif + +#if defined(_XSRAM) + .xsram : { + *(.xsram*) + . = ALIGN(4); + } >xsram +#endif + +#if defined(_XDRAM) + .xdram : { + *(.xdram*) + . = ALIGN(4); + } >xdram +#endif + +#if defined(_NFCRAM) + .nfcram : { + *(.nfcram*) + . = ALIGN(4); + } >nfcram +#endif + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.data b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.data new file mode 100644 index 00000000..eb12e28e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.data @@ -0,0 +1 @@ +dash END A B C D -mcpu=cortex-m0 \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.result b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.result new file mode 100644 index 00000000..8d876a24 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/dash.result @@ -0,0 +1 @@ +-D_A -D_B -D_C -D_D -mcpu=cortex-m0 \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.data b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.data new file mode 100644 index 00000000..5f71d37a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.data @@ -0,0 +1,2 @@ +longline + A=parameter B=parameter C=parameter D=parameter E==parameter +longline END F=parameter G=parameter \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.result b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.result new file mode 100644 index 00000000..78a1477a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/longline.result @@ -0,0 +1 @@ +-D_A=parameter -D_B=parameter -D_C=parameter -D_D=parameter -D_E==parameter -D_F=parameter -D_G=parameter \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.data b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.data new file mode 100644 index 00000000..027025ae --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.data @@ -0,0 +1 @@ +single END A B C D \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.result b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.result new file mode 100644 index 00000000..3191ddd9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/single.result @@ -0,0 +1 @@ +-D_A -D_B -D_C -D_D \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.data b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.data new file mode 100644 index 00000000..7867a613 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.data @@ -0,0 +1,2 @@ +tree1 treeparent A B C D +treeparent END E F diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.result b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.result new file mode 100644 index 00000000..b71bb04e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree1.result @@ -0,0 +1 @@ +-D_A -D_B -D_C -D_D -D_E -D_F \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.data b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.data new file mode 100644 index 00000000..d51a33a0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.data @@ -0,0 +1,5 @@ +tree5 tree4 A +tree4 tree3 B +tree3 tree2 C +tree2 tree1 D +tree1 END E F diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.result b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.result new file mode 100644 index 00000000..b71bb04e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/tree5.result @@ -0,0 +1 @@ +-D_A -D_B -D_C -D_D -D_E -D_F \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.data b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.data new file mode 100644 index 00000000..e55df615 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.data @@ -0,0 +1,4 @@ +twomatch treeparent A B C D +# the next line will be ignored because previous matches before and no + there +twomatch treeparent P Q R S +treeparent END E F diff --git a/hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.result b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.result new file mode 100644 index 00000000..b71bb04e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/ld/tests/twomatch.result @@ -0,0 +1 @@ +-D_A -D_B -D_C -D_D -D_E -D_F \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/Makefile.include b/hardware-wallet/firmware/vendor/libopencm3/lib/Makefile.include new file mode 100644 index 00000000..f6c805f9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/Makefile.include @@ -0,0 +1,56 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 Piotr Esden-Tempski +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +endif + +# common objects +OBJS += vector.o systick.o scb.o nvic.o assert.o sync.o dwt.o + +# Slightly bigger .elf files but gains the ability to decode macros +DEBUG_FLAGS ?= -ggdb3 +STANDARD_FLAGS ?= -std=c99 + +all: $(SRCLIBDIR)/$(LIBNAME).a + +$(SRCLIBDIR)/$(LIBNAME).a: $(SRCLIBDIR)/$(LIBNAME).ld $(OBJS) + @printf " AR $(LIBNAME).a\n" + $(Q)$(AR) $(ARFLAGS) "$@" $(OBJS) + +$(SRCLIBDIR)/$(LIBNAME).ld: $(LIBNAME).ld + @printf " CP $(LIBNAME).ld\n" + $(Q)cp $^ "$@" + $(Q)if [ -f $(LIBNAME)_rom_to_ram.ld ]; then cp $(LIBNAME)_rom_to_ram.ld $(SRCLIBDIR); fi + +%.o: %.c + @printf " CC $( + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void __attribute__((weak)) cm3_assert_failed(void) +{ + while (1); +} + +void __attribute__((weak)) cm3_assert_failed_verbose( + const char *file __attribute__((unused)), + int line __attribute__((unused)), + const char *func __attribute__((unused)), + const char *assert_expr __attribute__((unused))) +{ + cm3_assert_failed(); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/dwt.c b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/dwt.c new file mode 100644 index 00000000..b4408b0c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/dwt.c @@ -0,0 +1,77 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief DebugTrace Enable the CPU cycle counter + * + * This function will try to enable the CPU cycle counter that is intended for + * benchmarking performance of the code. If function fails, the cycle counter + * isn't available on this architecture. + * + * @return true, if success + */ +bool dwt_enable_cycle_counter(void) +{ +#if defined(__ARM_ARCH_6M__) + return false; /* Not supported on ARMv6M */ +#endif /* defined(__ARM_ARCH_6M__) */ + +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + /* Note TRCENA is for 7M and above*/ + SCS_DEMCR |= SCS_DEMCR_TRCENA; + if (DWT_CTRL & DWT_CTRL_NOCYCCNT) { + return false; /* Not supported in implementation */ + } + + DWT_CYCCNT = 0; + DWT_CTRL |= DWT_CTRL_CYCCNTENA; + return true; +#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */ + + /* not supported on other architectures */ + return false; +} +/*---------------------------------------------------------------------------*/ +/** @brief DebugTrace Read the CPU cycle counter + * + * This function reads the core cycle counter if it is enabled. It is the + * fastest clock running on the system. + * + * @note The CPU cycle counter must be enabled by @ref dwt_enable_cycle_counter + * + * @returns 0 if cycle counter is not supported or enabled, the cycle counter + * value otherwise. + */ +uint32_t dwt_read_cycle_counter(void) +{ +#if defined(__ARM_ARCH_6M__) + return 0; /* Not supported on ARMv6M */ +#endif /* defined(__ARM_ARCH_6M__) */ + +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + if (DWT_CTRL & DWT_CTRL_CYCCNTENA) { + return DWT_CYCCNT; + } else { + return 0; /* not supported or enabled */ + } +#endif /* defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) */ +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/nvic.c b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/nvic.c new file mode 100644 index 00000000..6c2188a8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/nvic.c @@ -0,0 +1,199 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Fergus Noble + * Copyright (C) 2012 Benjamin Vernoux + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/** @defgroup CM3_nvic_file NVIC + * + * @ingroup CM3_files + * + * @brief libopencm3 Cortex Nested Vectored Interrupt Controller + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 Thomas Otto + * @author @htmlonly © @endhtmlonly 2012 Fergus Noble + * + * + * @date 18 August 2012 + * + * Cortex processors provide 14 cortex-defined interrupts (NMI, usage faults, + * systicks etc.) and varying numbers of implementation defined interrupts + * (typically peripherial interrupts and DMA). + * + * @see Cortex-M3 Devices Generic User Guide + * @see STM32F10xxx Cortex-M3 programming manual + * + * LGPL License Terms @ref lgpl_license +*/ +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Enable Interrupt + * + * Enables a user interrupt. + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + */ + +void nvic_enable_irq(uint8_t irqn) +{ + NVIC_ISER(irqn / 32) = (1 << (irqn % 32)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Disable Interrupt + * + * Disables a user interrupt. + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + */ + +void nvic_disable_irq(uint8_t irqn) +{ + NVIC_ICER(irqn / 32) = (1 << (irqn % 32)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Return Pending Interrupt + * + * True if the interrupt has occurred and is waiting for service. + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + * @return Boolean. Interrupt pending. + */ + +uint8_t nvic_get_pending_irq(uint8_t irqn) +{ + return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Set Pending Interrupt + * + * Force a user interrupt to a pending state. This has no effect if the + * interrupt is already pending. + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + */ + +void nvic_set_pending_irq(uint8_t irqn) +{ + NVIC_ISPR(irqn / 32) = (1 << (irqn % 32)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Clear Pending Interrupt + * + * Force remove a user interrupt from a pending state. This has no effect if + * the interrupt is actively being serviced. + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + */ + +void nvic_clear_pending_irq(uint8_t irqn) +{ + NVIC_ICPR(irqn / 32) = (1 << (irqn % 32)); +} + + + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Return Enabled Interrupt + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + * @return Boolean. Interrupt enabled. + */ + +uint8_t nvic_get_irq_enabled(uint8_t irqn) +{ + return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Set Interrupt Priority + * + * CM3, CM4: + * + * There are 16 priority levels only, given by the upper four bits of the + * priority byte, as required by ARM standards. The priority levels are + * interpreted according to the pre-emptive priority grouping set in the + * SCB Application Interrupt and Reset Control Register (SCB_AIRCR), as done + * in @ref scb_set_priority_grouping. + * + * CM0: + * + * There are 4 priority levels only, given by the upper two bits of the + * priority byte, as required by ARM standards. No grouping available. + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + * @param[in] priority Unsigned int8. Interrupt priority (0 ... 255 in steps of + * 16) + */ + +void nvic_set_priority(uint8_t irqn, uint8_t priority) +{ + /* code from lpc43xx/nvic.c -- this is quite a hack and alludes to the + * negative interrupt numbers assigned to the system interrupts. better + * handling would mean signed integers. */ + if (irqn >= NVIC_IRQ_COUNT) { + /* Cortex-M system interrupts */ + SCS_SHPR((irqn & 0xF) - 4) = priority; + } else { + /* Device specific interrupts */ + NVIC_IPR(irqn) = priority; + } +} + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Return Active Interrupt + * + * Interrupt has occurred and is currently being serviced. + * + * @param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint + * @return Boolean. Interrupt active. + */ + +uint8_t nvic_get_active_irq(uint8_t irqn) +{ + return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief NVIC Software Trigger Interrupt + * + * Generate an interrupt from software. This has no effect for unprivileged + * access unless the privilege level has been elevated through the System + * Control Registers. + * + * @param[in] irqn Unsigned int16. Interrupt number (0 ... 239) + */ + +void nvic_generate_software_interrupt(uint16_t irqn) +{ + if (irqn <= 239) { + NVIC_STIR |= irqn; + } +} +#endif +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/scb.c b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/scb.c new file mode 100644 index 00000000..8c5a2f3a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/scb.c @@ -0,0 +1,47 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +void scb_reset_core(void) +{ + SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET; + + while (1); +} +#endif + +void scb_reset_system(void) +{ + SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ; + + while (1); +} + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +void scb_set_priority_grouping(uint32_t prigroup) +{ + SCB_AIRCR = SCB_AIRCR_VECTKEY | prigroup; +} +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/sync.c b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/sync.c new file mode 100644 index 00000000..2a77d4f6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/sync.c @@ -0,0 +1,79 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/* DMB is supported on CM0 */ +void __dmb() +{ + __asm__ volatile ("dmb"); +} + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +uint32_t __ldrex(volatile uint32_t *addr) +{ + uint32_t res; + __asm__ volatile ("ldrex %0, [%1]" : "=r" (res) : "r" (addr)); + return res; +} + +uint32_t __strex(uint32_t val, volatile uint32_t *addr) +{ + uint32_t res; + __asm__ volatile ("strex %0, %2, [%1]" + : "=&r" (res) : "r" (addr), "r" (val)); + return res; +} + +void mutex_lock(mutex_t *m) +{ + while (!mutex_trylock(m)); +} + +/* returns 1 if the lock was acquired */ +uint32_t mutex_trylock(mutex_t *m) +{ + uint32_t status = 1; + + /* If the mutex is unlocked. */ + if (__ldrex(m) == MUTEX_UNLOCKED) { + /* Try to lock it. */ + status = __strex(MUTEX_LOCKED, m); + } + + /* Execute the mysterious Data Memory Barrier instruction! */ + __dmb(); + + /* Did we get the lock? If not then try again + * by calling this function once more. */ + return status == 0; +} + +void mutex_unlock(mutex_t *m) +{ + /* Ensure accesses to protected resource are finished */ + __dmb(); + + /* Free the lock. */ + *m = MUTEX_UNLOCKED; +} + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/systick.c b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/systick.c new file mode 100644 index 00000000..a99593b6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/systick.c @@ -0,0 +1,203 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Benjamin Vernoux + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/** @defgroup CM3_systick_file SysTick + * + * @ingroup CM3_files + * + * @brief libopencm3 Cortex System Tick Timer + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 Thomas Otto + * + * @date 19 August 2012 + * + * This library supports the System Tick timer in ARM Cortex Microcontrollers. + * + * The System Tick timer is part of the ARM Cortex core. It is a 24 bit + * down counter that can be configured with an automatical reload value. + * + * LGPL License Terms @ref lgpl_license + */ + +/**@{*/ +#include + +/*---------------------------------------------------------------------------*/ +/** @brief SysTick Set the Automatic Reload Value. + * + * The counter is set to the reload value when the counter starts and after it + * reaches zero. + * + * @note The systick counter value might be undefined upon startup. To get + * predictable behavior, it is a good idea to set or clear the counter after + * set reload. @seealso systick_clear + * + * @param[in] value uint32_t. 24 bit reload value. + */ + +void systick_set_reload(uint32_t value) +{ + STK_RVR = (value & STK_RVR_RELOAD); +} + +/*---------------------------------------------------------------------------*/ +/** @brief SysTick Read the Automatic Reload Value. + * + * @returns 24 bit reload value as uint32_t. + */ + +uint32_t systick_get_reload(void) +{ + return STK_RVR & STK_RVR_RELOAD; +} + +/** @brief SysTick Set clock and frequency of overflow + * + * This function sets the systick to AHB clock source, and the prescaler to + * generate interrupts with the desired frequency. The function fails, if + * the frequency is too low. + * + * @param[in] freq uint32_t The desired frequency in Hz + * @param[in] ahb uint32_t The current AHB frequency in Hz + * @returns true, if success, false if the desired frequency cannot be set. + */ +bool systick_set_frequency(uint32_t freq, uint32_t ahb) +{ + uint32_t ratio = ahb / freq; + +#if defined(__ARM_ARCH_6M__) + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); +#else + if (ratio >= (STK_RVR_RELOAD * 8)) { + /* This frequency is too slow */ + return false; + } else if (ratio >= STK_RVR_RELOAD) { + ratio /= 8; + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); + } else { + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); + } +#endif + systick_set_reload(ratio - 1); + return true; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the current SysTick counter value. + * + * @returns 24 bit current value as uint32_t. + */ + +uint32_t systick_get_value(void) +{ + return STK_CVR & STK_CVR_CURRENT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the SysTick Clock Source. + * + * The clock source can be either the AHB clock or the same clock divided by 8. + * + * @param[in] clocksource uint8_t. Clock source from @ref systick_clksource. + */ + +void systick_set_clocksource(uint8_t clocksource) +{ + STK_CSR = (STK_CSR & ~STK_CSR_CLKSOURCE) | + (clocksource & STK_CSR_CLKSOURCE); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable SysTick Interrupt. + * + */ + +void systick_interrupt_enable(void) +{ + STK_CSR |= STK_CSR_TICKINT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable SysTick Interrupt. + * + */ + +void systick_interrupt_disable(void) +{ + STK_CSR &= ~STK_CSR_TICKINT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable SysTick Counter. + * + */ + +void systick_counter_enable(void) +{ + STK_CSR |= STK_CSR_ENABLE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable SysTick Counter. + * + */ + +void systick_counter_disable(void) +{ + STK_CSR &= ~STK_CSR_ENABLE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SysTick Read the Counter Flag. + * + * The count flag is set when the timer count becomes zero, and is cleared when + * the flag is read. + * + * @returns Boolean if flag set. + */ + +uint8_t systick_get_countflag(void) +{ + return (STK_CSR & STK_CSR_COUNTFLAG) ? 1 : 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SysTick Clear counter Value. + * + * The counter value is cleared. Useful for well defined startup. + */ + +void systick_clear(void) +{ + STK_CVR = 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SysTick Get Calibration Value + * + * @returns Current calibration value + */ +uint32_t systick_get_calib(void) +{ + return STK_CALIB & STK_CALIB_TENMS; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/vector.c b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/vector.c new file mode 100644 index 00000000..b9c22a25 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/cm3/vector.c @@ -0,0 +1,126 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski , + * Copyright (C) 2012 chrysn + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/* load optional platform dependent initialization routines */ +#include "../dispatch/vector_chipset.c" +/* load the weak symbols for IRQ_HANDLERS */ +#include "../dispatch/vector_nvic.c" + +/* Symbols exported by the linker script(s): */ +extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; +typedef void (*funcp_t) (void); +extern funcp_t __preinit_array_start, __preinit_array_end; +extern funcp_t __init_array_start, __init_array_end; +extern funcp_t __fini_array_start, __fini_array_end; + +void main(void); +void blocking_handler(void); +void null_handler(void); + +__attribute__ ((section(".vectors"))) +vector_table_t vector_table = { + .initial_sp_value = &_stack, + .reset = reset_handler, + .nmi = nmi_handler, + .hard_fault = hard_fault_handler, + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + .memory_manage_fault = mem_manage_handler, + .bus_fault = bus_fault_handler, + .usage_fault = usage_fault_handler, + .debug_monitor = debug_monitor_handler, +#endif + + .sv_call = sv_call_handler, + .pend_sv = pend_sv_handler, + .systick = sys_tick_handler, + .irq = { + IRQ_HANDLERS + } +}; + +void __attribute__ ((weak, naked)) reset_handler(void) +{ + volatile unsigned *src, *dest; + funcp_t *fp; + + for (src = &_data_loadaddr, dest = &_data; + dest < &_edata; + src++, dest++) { + *dest = *src; + } + + while (dest < &_ebss) { + *dest++ = 0; + } + + /* Ensure 8-byte alignment of stack pointer on interrupts */ + /* Enabled by default on most Cortex-M parts, but not M3 r1 */ + SCB_CCR |= SCB_CCR_STKALIGN; + + /* might be provided by platform specific vector.c */ + pre_main(); + + /* Constructors. */ + for (fp = &__preinit_array_start; fp < &__preinit_array_end; fp++) { + (*fp)(); + } + for (fp = &__init_array_start; fp < &__init_array_end; fp++) { + (*fp)(); + } + + /* Call the application's entry point. */ + main(); + + /* Destructors. */ + for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) { + (*fp)(); + } + +} + +void blocking_handler(void) +{ + while (1); +} + +void null_handler(void) +{ + /* Do nothing. */ +} + +#pragma weak nmi_handler = null_handler +#pragma weak hard_fault_handler = blocking_handler +#pragma weak sv_call_handler = null_handler +#pragma weak pend_sv_handler = null_handler +#pragma weak sys_tick_handler = null_handler + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +#pragma weak mem_manage_handler = blocking_handler +#pragma weak bus_fault_handler = blocking_handler +#pragma weak usage_fault_handler = blocking_handler +#pragma weak debug_monitor_handler = null_handler +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/dispatch/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/dispatch/vector_chipset.c new file mode 100644 index 00000000..2515664f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/dispatch/vector_chipset.c @@ -0,0 +1,20 @@ +#if defined(STM32F3) +# include "../stm32/f3/vector_chipset.c" +#elif defined(STM32F4) +# include "../stm32/f4/vector_chipset.c" +#elif defined(STM32F7) +# include "../stm32/f7/vector_chipset.c" +#elif defined(STM32L4) +# include "../stm32/l4/vector_chipset.c" +#elif defined(LM4F) +# include "../lm4f/vector_chipset.c" +#elif defined(LPC43XX_M4) +# include "../lpc43xx/m4/vector_chipset.c" +#elif defined(VF6XX) +# include "../vf6xx/vector_chipset.c" + +#else + +static void pre_main(void) {} + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/Makefile new file mode 100644 index 00000000..1aace7c6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/Makefile @@ -0,0 +1,45 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 chrysn +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_efm32g +SRCLIBDIR ?= ../.. +FAMILY = EFM32G + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../:../../cm3 + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g.ld new file mode 100644 index 00000000..87d6ee63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g880f128.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g880f128.ld new file mode 100644 index 00000000..09c6fb0f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/g/libopencm3_efm32g880f128.ld @@ -0,0 +1,15 @@ +/* lengths from d011_efm32tg840_datasheet.pdf table 1.1, offset from + * d0034_efm32tg_reference_manual.pdf figure 5.2. + * + * the origins and memory structure are constant over all tinygeckos, but the + * MEMORY section requires the use of constants, and has thus to be duplicated + * over the chip variants. + * */ + +MEMORY +{ + rom (rx) : ORIGIN = 0, LENGTH = 128k + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16k +} + +INCLUDE libopencm3_efm32g.ld; diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/Makefile new file mode 100644 index 00000000..a96b3df8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/Makefile @@ -0,0 +1,45 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 chrysn +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_efm32gg +SRCLIBDIR ?= ../.. +FAMILY = EFM32GG + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../:../../cm3 + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg.ld new file mode 100644 index 00000000..87d6ee63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg990f1024.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg990f1024.ld new file mode 100644 index 00000000..694e17a9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/gg/libopencm3_efm32gg990f1024.ld @@ -0,0 +1,15 @@ +/* lengths from d046_efm32gg990_datasheet.pdf table 1.1, offset from + * d0034_efm32tg_reference_manual.pdf figure 5.2. + * + * the origins and memory structure are constant over all giantgeckos, but the + * MEMORY section requires the use of constants, and has thus to be duplicated + * over the chip variants. + * */ + +MEMORY +{ + rom (rx) : ORIGIN = 0, LENGTH = 1024k + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128k +} + +INCLUDE libopencm3_efm32gg.ld; diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/Makefile new file mode 100644 index 00000000..78b40790 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/Makefile @@ -0,0 +1,49 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 chrysn +## Copyright (C) 2015 Kuldeep Singh Dhaka +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_efm32lg +SRCLIBDIR ?= ../.. +FAMILY = EFM32LG + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +OBJS = gpio.o cmu.o prs.o adc.o dma.o timer.o dac.o +OBJS += usb.o usb_control.o usb_standard.o usb_efm32lg.o + +VPATH += ../../usb:../:../../cm3 + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/adc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/adc.c new file mode 100644 index 00000000..980c7151 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/adc.c @@ -0,0 +1,667 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/** + * Set ADC over sampling + * @param[in] adc ADC (use ADCx) + * @param[in] oversamp Oversampling (use ADC_CTRL_OVERSEL_Xx) + */ +void adc_set_oversampling(uint32_t adc, uint32_t oversamp) +{ + ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_OVERSEL_MASK) | oversamp; +} + +/** + * Set ADC warm up + * @param[in] adc ADC (use ADCx) + * @param[in] clocks Clock cycles (1 - 128) + * @note warm-up-time = (@a clocks / HFPERCLK) + */ +void adc_set_warm_up(uint32_t adc, uint8_t clocks) +{ + uint32_t timebase = ADC_CTRL_TIMEBASE(clocks - 1); + ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_TIMEBASE_MASK) | timebase; +} + +/** Clock division factor + * @param[in] adc ADC (use ADCx) + * @param[in] factor Factor (1 - 128) + * @note output-clock = input-clock / @a factor + */ +void adc_set_clock_prescaler(uint32_t adc, uint8_t factor) +{ + uint32_t presc = ADC_CTRL_PRESC(factor - 1); + ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_PRESC_MASK) | presc; +} + +/** + * Set low pass filter mode + * @param[in] adc ADC (use ADCx) + * @param[in] lpfmode Low pass filter mode (use ADC_CTRL_LPFMODE_*) + */ +void adc_set_lowpass_filter(uint32_t adc, uint32_t lpfmode) +{ + ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_LPFMODE_MASK) | lpfmode; +} + +/** + * Enable tail gating + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_tailgating(uint32_t adc) +{ + ADC_CTRL(adc) |= ADC_CTRL_TAILGATE; +} + +/** + * Disable tail gating + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_tailgating(uint32_t adc) +{ + ADC_CTRL(adc) &= ~ADC_CTRL_TAILGATE; +} + +/** + * Set warm up mode + * @param[in] adc ADC (use ADCx) + * @param[in] warmupmode Warm Up Mode (use ADC_CTRL_WARMUPMODE_*) + */ +void adc_set_warm_up_mode(uint32_t adc, uint32_t warmupmode) +{ + ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_WARMUPMODE_MASK) + | warmupmode; +} + +/** + * Start ADC in single acquisition + * @param[in] adc ADC (use ADCx) + */ +void adc_single_start(uint32_t adc) +{ + ADC_CMD(adc) = ADC_CMD_SINGLESTART; +} + +/** + * Stop ADC in single acquisition + * @param[in] adc ADC (use ADCx) + */ +void adc_single_stop(uint32_t adc) +{ + ADC_CMD(adc) = ADC_CMD_SINGLESTOP; +} + +/** + * Start ADC in scan acquisition + * @param[in] adc ADC (use ADCx) + */ +void adc_scan_start(uint32_t adc) +{ + ADC_CMD(adc) = ADC_CMD_SCANSTART; +} + +/** + * Stop ADC in scan acquisition + * @param[in] adc ADC (use ADCx) + */ +void adc_scan_stop(uint32_t adc) +{ + ADC_CMD(adc) = ADC_CMD_SCANSTOP; +} + +/* Single ----------------------------------------------------------- */ +/** + * Set single PRS trigger + * @param[in] adc ADC (use ADCx) + * @param[in] prssel PRS Selected (use PRS_CHx) + */ +void adc_set_single_prs_trigger(uint32_t adc, uint8_t prssel) +{ + ADC_SINGLECTRL(adc) = + (ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_PRSSEL_MASK) | + (ADC_SINGLECTRL_PRSSEL_PRSCHx(prssel)); +} + +/** + * Enable single PRS Triggering + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_single_prs_trigger(uint32_t adc) +{ + ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_PRSEN; +} + +/** + * Disable single PRS Triggering + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_single_prs_trigger(uint32_t adc) +{ + ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_PRSEN; +} + +/** + * Set single acquisition cycle + * @param[in] adc ADC (use ADCx) + * @param[in] at Acquisition time (use ADC_SINGLECTRL_AT_x) + */ +void adc_set_single_acquisition_cycle(uint32_t adc, uint32_t at) +{ + ADC_SINGLECTRL(adc) = + (ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_AT_MASK) | at; +} + +/** + * Set single reference for acquisition + * @param[in] adc ADC (use ADCx) + * @param[in] ref Reference (use ADC_SINGLECTRL_REF_x) + */ +void adc_set_single_reference(uint32_t adc, uint32_t ref) +{ + ADC_SINGLECTRL(adc) = + (ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_REF_MASK) | ref; +} + +/** + * Set single channel + * @param[in] adc ADC (use ADCx) + * @param[in] ch Channel (use ADC_CHx and ADC_CH_*) + */ +void adc_set_single_channel(uint32_t adc, uint8_t ch) +{ + ADC_SINGLECTRL(adc) = + (ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_INPUTSEL_MASK) | + ADC_SINGLECTRL_INPUTSEL(ch); +} + +/** + * Set single resolution of conversion + * @param[in] adc ADC (use ADCx) + * @param[in] res Resolution (use ADC_SINGLECTRL_RES_*) + */ +void adc_set_single_resolution(uint32_t adc, uint32_t res) +{ + ADC_SINGLECTRL(adc) = + (ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_RES_MASK) | res; +} + +/** + * Set single left aligned output + * @param[in] adc ADC (use ADCx) + */ +void adc_set_single_left_aligned(uint32_t adc) +{ + ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_ADJ; +} + +/** + * Set single right aligned output + * @param[in] adc ADC (use ADCx) + */ +void adc_set_single_right_aligned(uint32_t adc) +{ + ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_ADJ; +} + +/** + * Set single single-ended conversion + * @param[in] adc ADC (use ADCx) + */ +void adc_set_single_single_ended(uint32_t adc) +{ + ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_DIFF; +} + +/** + * Set single differential conversion + * @param[in] adc ADC (use ADCx) + */ +void adc_set_single_differential(uint32_t adc) +{ + ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_DIFF; +} + +/** + * Enable single channel repeated conversion + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_single_repeat_conv(uint32_t adc) +{ + ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_REP; +} + +/** + * Disable single repeated conversion + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_single_repeat_conv(uint32_t adc) +{ + ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_REP; +} + +/* Scan ------------------------------------------------------------- */ +/** + * Set scan PRS trigger + * @param[in] adc ADC (use ADCx) + * @param[in] prssel PRS Selected (use PRS_CHx) + */ +void adc_set_scan_prs_trigger(uint32_t adc, uint8_t prssel) +{ + ADC_SCANCTRL(adc) = + (ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_PRSSEL_MASK) | + ADC_SCANCTRL_PRSSEL_PRSCHx(prssel); +} + +/** + * Enable scan PRS Triggering + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_scan_prs_trigger(uint32_t adc) +{ + ADC_SCANCTRL(adc) |= ADC_SCANCTRL_PRSEN; +} + +/** + * Disable scan PRS Triggering + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_scan_prs_trigger(uint32_t adc) +{ + ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_PRSEN; +} + +/** + * Set scan acquisition cycle + * @param[in] adc ADC (use ADCx) + * @param[in] at Acquisition time (use ADC_SCANCTRL_AT_x) + */ +void adc_set_scan_acquisition_cycle(uint32_t adc, uint32_t at) +{ + ADC_SCANCTRL(adc) = + (ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_AT_MASK) | at; +} + +/** + * Set scan reference for acquisition + * @param[in] adc ADC (use ADCx) + * @param[in] ref Reference (use ADC_SCANCTRL_REF_x) + */ +void adc_set_scan_reference(uint32_t adc, uint32_t ref) +{ + ADC_SCANCTRL(adc) = + (ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_REF_MASK) | ref; +} + +/** + * Set scan channel list + * @param[in] adc ADC (use ADCx) + * @param[in] length Length of @a channel + * @param[in] channel channel list (use ADC_CHx) + * @note channel[0] is used as single acuqisition + */ +void adc_set_scan_channel(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + unsigned i; + uint32_t val = 0; + + for (i = 0; i < length; i++) { + val |= 1 << (channel[i] + ADC_SCANCTRL_INPUTSEL_SHIFT); + } + + ADC_SCANCTRL(adc) = + (ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_INPUTSEL_MASK) | + (val & ADC_SCANCTRL_INPUTSEL_MASK); +} + +/** + * Set scan resolution of conversion + * @param[in] adc ADC (use ADCx) + * @param[in] res Resolution (use ADC_SCANCTRL_RES_*) + */ +void adc_set_scan_resolution(uint32_t adc, uint32_t res) +{ + ADC_SCANCTRL(adc) = + (ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_RES_MASK) | res; +} + +/** + * Set scan left aligned output + * @param[in] adc ADC (use ADCx) + */ +void adc_set_scan_left_aligned(uint32_t adc) +{ + ADC_SCANCTRL(adc) |= ADC_SCANCTRL_ADJ; +} + +/** + * Set scan right aligned output + * @param[in] adc ADC (use ADCx) + */ +void adc_set_scan_right_aligned(uint32_t adc) +{ + ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_ADJ; +} + +/** + * Set scan single ended conversion + * @param[in] adc ADC (use ADCx) + */ +void adc_set_scan_single_ended(uint32_t adc) +{ + ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_DIFF; +} + +/** + * Set scan differential conversion + * @param[in] adc ADC (use ADCx) + */ +void adc_set_scan_differential(uint32_t adc) +{ + ADC_SCANCTRL(adc) |= ADC_SCANCTRL_DIFF; +} + +/** + * Enable scan repeated conversion + * @param[in] adc ADC (use ADCx) + * @note In SINGLE mode, channel is repeated + * @note In SCAN mode, channel sequence is repeated + */ +void adc_enable_scan_repeat_conv(uint32_t adc) +{ + ADC_SCANCTRL(adc) |= ADC_SCANCTRL_REP; +} + +/** + * Disable scan repeated conversion + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_scan_repeat_conv(uint32_t adc) +{ + ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_REP; +} + +/** + * Enable single result overflow interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_single_result_overflow_interrupt(uint32_t adc) +{ + ADC_IEN(adc) |= ADC_IEN_SINGLEOF; +} + +/** + * Disable single result overflow interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_single_result_overflow_interrupt(uint32_t adc) +{ + ADC_IEN(adc) &= ~ADC_IEN_SINGLEOF; +} + +/** + * Enable single conversion complete interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_single_conversion_complete_interrupt(uint32_t adc) +{ + ADC_IEN(adc) |= ADC_IEN_SINGLE; +} + +/** + * Disable single conversion complete interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_single_conversion_complete_interrupt(uint32_t adc) +{ + ADC_IEN(adc) &= ~ADC_IEN_SINGLE; +} + +/** + * Enable scan result overflow interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_scan_result_overflow_interrupt(uint32_t adc) +{ + ADC_IEN(adc) |= ADC_IEN_SCANOF; +} + +/** + * Disable scan result overflow interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_scan_result_overflow_interrupt(uint32_t adc) +{ + ADC_IEN(adc) &= ~ADC_IEN_SCANOF; +} + +/** + * Disable scan conversion complete interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_enable_scan_conversion_complete_interrupt(uint32_t adc) +{ + ADC_IEN(adc) |= ADC_IEN_SCAN; +} + +/** + * Disable scan conversion complete interrupt + * @param[in] adc ADC (use ADCx) + */ +void adc_disable_scan_conversion_complete_interrupt(uint32_t adc) +{ + ADC_IEN(adc) &= ~ADC_IEN_SCAN; +} + +/** + * Get single result overflow flag + * @param[in] adc ADC (use ADCx) + * @retval true if flag set + * @retval false if flag is not set + */ +bool adc_get_single_result_overflow_flag(uint32_t adc) +{ + return (ADC_IF(adc) & ADC_IF_SCANOF) != 0; +} + +/** + * Get single conversion complete flag + * @param[in] adc ADC (use ADCx) + * @retval true if flag set + * @retval false if flag is not set + */ +bool adc_get_single_conversion_complete_flag(uint32_t adc) +{ + return (ADC_IF(adc) & ADC_IF_SINGLE) != 0; +} + +/** + * Get scan result overflow flag + * @param[in] adc ADC (use ADCx) + * @retval true if flag set + * @retval false if flag is not set + */ +bool adc_get_scan_result_overflow_flag(uint32_t adc) +{ + return (ADC_IF(adc) & ADC_IF_SCANOF) != 0; +} + +/** + * Get scan conversion complete flag + * @param[in] adc ADC (use ADCx) + * @retval true if flag is set + * @retval false if flag is not set + */ +bool adc_get_scan_conversion_complete_flag(uint32_t adc) +{ + return (ADC_IF(adc) & ADC_IF_SCAN) != 0; +} + +/** + * Set single result overflow flag + * @param[in] adc ADC (use ADCx) + */ +void adc_set_single_result_overflow_flag(uint32_t adc) +{ + ADC_IFS(adc) = ADC_IFS_SINGLEOF; +} + +/** + * Set single conversion complete flag + * @param[in] adc ADC (use ADCx) + */ +void adc_set_single_conversion_complete_flag(uint32_t adc) +{ + ADC_IFS(adc) = ADC_IFS_SINGLE; +} + +/** + * Set scan result overflow flag + * @param[in] adc ADC (use ADCx) + */ +void adc_set_scan_result_overflow_flag(uint32_t adc) +{ + ADC_IFS(adc) = ADC_IFS_SCANOF; +} + +/** + * Set scan conversion complete flag + * @param[in] adc ADC (use ADCx) + */ +void adc_set_scan_conversion_complete_flag(uint32_t adc) +{ + ADC_IFS(adc) = ADC_IFS_SCAN; +} + +/** + * Clear single result overflow flag + * @param[in] adc ADC (use ADCx) + */ +void adc_clear_single_result_overflow_flag(uint32_t adc) +{ + ADC_IFC(adc) = ADC_IFC_SINGLEOF; +} + +/** + * Clear single conversion complete flag + * @param[in] adc ADC (use ADCx) + */ +void adc_clear_single_conversion_complete_flag(uint32_t adc) +{ + ADC_IFC(adc) = ADC_IFC_SINGLE; +} + +/** + * Clear scan result overflow flag + * @param[in] adc ADC (use ADCx) + */ +void adc_clear_scan_result_overflow_flag(uint32_t adc) +{ + ADC_IFC(adc) = ADC_IFC_SCANOF; +} + +/** + * Clear scan conversion complete flag + * @param[in] adc ADC (use ADCx) + */ +void adc_clear_scan_conversion_complete_flag(uint32_t adc) +{ + ADC_IFC(adc) = ADC_IFC_SCAN; +} + +/** + * Get result from last scan conversion + * @param[in] adc ADC (use ADCx) + * @return result + */ +uint32_t adc_single_data(uint32_t adc) +{ + return ADC_SINGLEDATA(adc); +} + +/** + * Get result from last scan conversion + * @param[in] adc ADC (use ADCx) + * @return result + */ +uint32_t adc_scan_data(uint32_t adc) +{ + return ADC_SCANDATA(adc); +} + +/** + * Get result from last single conversion (peak) + * Reading result using this function will not clear + * SINGLEDV in ADC_STATUS or SINGLE DMA request. + * @param[in] adc ADC (use ADCx) + * @return result + */ +uint32_t adc_single_data_peak(uint32_t adc) +{ + return ADC_SINGLEDATAP(adc); +} + +/** + * Get result from last scan conversion (peak) + * Reading result using this function will not clear + * SCANDV in ADC_STATUS or SCAN DMA request. + * @param[in] adc ADC (use ADCx) + * @return result + */ +uint32_t adc_scan_data_peak(uint32_t adc) +{ + return ADC_SCANDATAP(adc); +} + +/** + * Set ADC scan gain calibration + * @param[in] adc ADC (use ADCx) + */ +void adc_set_calibration_scan_gain(uint32_t adc, uint8_t scan_gain) +{ + ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SCANGAIN_MASK) | scan_gain; +} + +/** + * Set ADC scan offset calibration + * @param[in] adc ADC (use ADCx) + */ +void adc_set_calibration_scan_offset(uint32_t adc, uint8_t scan_offset) +{ + ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SCANOFF_MASK) | scan_offset; +} + +/** + * Set ADC single gain calibration + * @param[in] adc ADC (use ADCx) + */ +void adc_set_calibration_single_gain(uint32_t adc, uint8_t single_gain) +{ + ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SINGLEGAIN_MASK) | single_gain; +} + +/** + * Set ADC single offset calibration + * @param[in] adc ADC (use ADCx) + */ +void adc_set_calibration_single_offset(uint32_t adc, uint8_t single_offset) +{ + ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SINGLEOFF_MASK) | single_offset; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/cmu.c b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/cmu.c new file mode 100644 index 00000000..6edc42dd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/cmu.c @@ -0,0 +1,272 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/** + * Enable CMU registers lock. + */ +void cmu_enable_lock(void) +{ + CMU_LOCK = CMU_LOCK_LOCKKEY_LOCK; +} + +/** + * Disable CMU registers lock + */ +void cmu_disable_lock(void) +{ + CMU_LOCK = CMU_LOCK_LOCKKEY_UNLOCK; +} + +/** + * Get CMU register lock flag + * @retval true if flag is set + * @retval false if flag is not set + */ +bool cmu_get_lock_flag(void) +{ + return (CMU_LOCK & CMU_LOCK_LOCKKEY_MASK) == CMU_LOCK_LOCKKEY_LOCKED; +} + +#define _CMU_REG(i) MMIO32(CMU_BASE + ((i) >> 5)) +#define _CMU_BIT(i) (1 << ((i) & 0x1f)) + +/** + * @brief Enable Peripheral Clock in running mode. + * + * Enable the clock on particular peripheral. + * + * @param[in] periph enum cmu_periph_clken Peripheral Name + * + * For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for + * example) + */ + +void cmu_periph_clock_enable(enum cmu_periph_clken clken) +{ + _CMU_REG(clken) |= _CMU_BIT(clken); +} + +/** + * @brief Disable Peripheral Clock in running mode. + * Disable the clock on particular peripheral. + * + * @param[in] periph enum cmu_periph_clken Peripheral Name + * + * For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for + * example) + */ + +void cmu_periph_clock_disable(enum cmu_periph_clken clken) +{ + _CMU_REG(clken) &= ~_CMU_BIT(clken); +} + +/** + * Turn on Oscillator + * @param[in] osc enum cmu_osc Oscillator name + */ +void cmu_osc_on(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_HFRCOEN; + break; + case LFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_LFRCOEN; + break; + case ULFRCO: + /* TODO: but how? */ + break; + case HFXO: + CMU_OSCENCMD = CMU_OSCENCMD_HFXOEN; + break; + case LFXO: + CMU_OSCENCMD = CMU_OSCENCMD_LFXOEN; + break; + case AUXHFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN; + break; + } +} + +/** + * Turn off Oscillator + * @param[in] osc enum cmu_osc Oscillator name + */ +void cmu_osc_off(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS; + break; + case LFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_LFRCODIS; + break; + case ULFRCO: + /* TODO: but how? */ + break; + case HFXO: + CMU_OSCENCMD = CMU_OSCENCMD_HFXODIS; + break; + case LFXO: + CMU_OSCENCMD = CMU_OSCENCMD_LFXODIS; + break; + case AUXHFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCODIS; + break; + } +} + +/** + * Get Oscillator read flag + * @param[in] osc enum cmu_osc Oscillator name + * @retval true if flag is set + * @retval false if flag is not set + */ +bool cmu_osc_ready_flag(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + return (CMU_STATUS & CMU_STATUS_HFRCORDY) != 0; + break; + case LFRCO: + return (CMU_STATUS & CMU_STATUS_LFRCORDY) != 0; + break; + case ULFRCO: + /* TODO: but how? */ + break; + case HFXO: + return (CMU_STATUS & CMU_STATUS_HFXORDY) != 0; + break; + case LFXO: + return (CMU_STATUS & CMU_STATUS_LFXORDY) != 0; + break; + case AUXHFRCO: + return (CMU_STATUS & CMU_STATUS_AUXHFRCORDY) != 0; + break; + } + + return false; +} + +/** + * Wait till oscillator is not ready + * @param[in] osc enum cmu_osc Oscillator name + */ +void cmu_wait_for_osc_ready(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + while ((CMU_STATUS & CMU_STATUS_HFRCORDY) == 0); + break; + case LFRCO: + while ((CMU_STATUS & CMU_STATUS_LFRCORDY) == 0); + break; + case ULFRCO: + /* TODO: but how? */ + break; + case HFXO: + while ((CMU_STATUS & CMU_STATUS_HFXORDY) == 0); + break; + case LFXO: + while ((CMU_STATUS & CMU_STATUS_LFXORDY) == 0); + break; + case AUXHFRCO: + while ((CMU_STATUS & CMU_STATUS_AUXHFRCORDY) == 0); + break; + } +} + +/** + * Set HFCLK clock source + * @param[in] osc enum cmu_osc Oscillator name + * @note calling cmu_set_hfclk_source() do not set source immediately, use + * @a cmu_get_hfclk_source() to verify that the source has been set. + * @see cmu_get_hfclk_source() + */ +void cmu_set_hfclk_source(enum cmu_osc osc) +{ + switch (osc) { + case HFXO: + CMU_CMD = CMU_CMD_HFCLKSEL_HFXO; + break; + case HFRCO: + CMU_CMD = CMU_CMD_HFCLKSEL_HFRCO; + break; + case LFXO: + CMU_CMD = CMU_CMD_HFCLKSEL_LFXO; + break; + case LFRCO: + CMU_CMD = CMU_CMD_HFCLKSEL_LFRCO; + break; + default: + /* not applicable */ + return; + } +} + +enum cmu_osc cmu_get_hfclk_source(void) +{ + uint32_t status = CMU_STATUS; + if (status & CMU_STATUS_LFXOSEL) { + return LFXO; + } else if (status & CMU_STATUS_LFRCOSEL) { + return LFRCO; + } else if (status & CMU_STATUS_HFXOSEL) { + return HFXO; + } else if (status & CMU_STATUS_HFRCOSEL) { + return HFRCO; + } + + /* never reached */ + return (enum cmu_osc) -1; +} + +/** + * HFXO output 48Mhz and core running at 48Mhz + */ +void cmu_clock_setup_in_hfxo_out_48mhz(void) +{ + /* configure HFXO and prescaler */ + CMU_HFCORECLKDIV = CMU_HFCORECLKDIV_HFCORECLKDIV_NODIV + | CMU_HFCORECLKDIV_HFCORECLKLEDIV; + CMU_CTRL = (CMU_CTRL + & ~(CMU_CTRL_HFCLKDIV_MASK | CMU_CTRL_HFXOBUFCUR_MASK)) + | (CMU_CTRL_HFCLKDIV_NODIV + | CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ); + + /* enable HFXO */ + cmu_osc_on(HFXO); + + /* wait for HFXO */ + cmu_wait_for_osc_ready(HFXO); + + /* set flash wait state */ + MSC_READCTRL = (MSC_READCTRL & ~MSC_READCTRL_MODE_MASK) + | MSC_READCTRL_MODE_WS2; + + /* switch to HFXO */ + cmu_set_hfclk_source(HFXO); + + /* wait till HFXO not selected */ + while (cmu_get_hfclk_source() != HFXO); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dac.c new file mode 100644 index 00000000..8a211afc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dac.c @@ -0,0 +1,168 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/** + * Set DAC refresh cycle + * @param[in] dac DAC (use DACx) + * @param[in] refrsel (use DAC_CTRL_REFRSEL_*CYCLES) + * @see dac_disable_auto_refresh() + * @see dac_enable_auto_refresh() + */ +void dac_set_refresh_cycle(uint32_t dac, uint32_t refrsel) +{ + DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_REFRSEL_MASK) | refrsel; +} + +/** + * Set DAC clock prescaler + * @param[in] dac DAC (use DACx) + * @param[in] presc Prescaler (use DAC_CTRL_PRESC_*) + */ +void dac_set_clock_prescaler(uint32_t dac, uint32_t presc) +{ + DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_PRESC_MASK) | presc; +} + +/** + * Set DAC reference + * @param[in] dac DAC (use DACx) + * @param[in] refsel Reference (DAC_CTRL_REFSEL_*) + */ +void dac_set_reference(uint32_t dac, uint32_t refsel) +{ + DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_REFSEL_MASK) | refsel; +} + +/** + * Set DAC output mode + * @param[in] dac DAC (use DACx) + * @param[in] outmode Output mode (DAC_CTRL_OUTMODE_*) + */ +void dac_set_out_mode(uint32_t dac, uint32_t outmode) +{ + DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_OUTMODE_MASK) | outmode; +} + +/** + * Set conversion mode + * @param[in] dac DAC (use DACx) + * @param[in] convmode Conversion mode (use DAC_CTRL_CONVMODE_*) + */ +void dac_set_conversion_mode(uint32_t dac, uint32_t convmode) +{ + DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_CONVMODE_MASK) | convmode; +} + +/** + * Enable Sine wave on output + * @param[in] dac DAC (use DACx) + */ +void dac_enable_sine(uint32_t dac) +{ + DAC_CTRL(dac) |= DAC_CTRL_SINMODE; +} + +/** + * Disable Sine wave on output + * @param[in] dac DAC (use DACx) + */ +void dac_disable_sine(uint32_t dac) +{ + DAC_CTRL(dac) &= ~DAC_CTRL_SINMODE; +} + +/** + * Set PRS trigger source on DAC channel + * @param[in] dac DAC (use DACx) + * @param[in] dac_ch DAC Channel (use DAC_CHx) + * @param[in] prs_ch PRS Channel (use PRS_CHx) + */ +void dac_set_prs_trigger(uint32_t dac, enum dac_ch dac_chan, + enum prs_ch prs_chan) +{ + uint32_t ch_ctrl = DAC_CHx_CTRL(dac, dac_chan); + ch_ctrl &= DAC_CH_CTRL_PRSSEL_MASK; + ch_ctrl |= DAC_CH_CTRL_PRSSEL(prs_chan); + DAC_CHx_CTRL(dac, dac_chan) = ch_ctrl; +} + +/** + * Enable PRS triggerring + * @param[in] dac DAC (use DACx) + * @param[in] dac_ch DAC Channel (use DAC_CHx) + */ +void dac_enable_prs_trigger(uint32_t dac, enum dac_ch ch) +{ + DAC_CHx_CTRL(dac, ch) |= DAC_CH_CTRL_PRSEN; +} + +/** + * Disable PRS triggerring + * @param[in] dac DAC (use DACx) + * @param[in] dac_ch DAC Channel (use DAC_CHx) + */ +void dac_disable_prs_trigger(uint32_t dac, enum dac_ch ch) +{ + DAC_CHx_CTRL(dac, ch) &= ~DAC_CH_CTRL_PRSEN; +} + +/** + * Enable auto refresh + * @param[in] dac DAC (use DACx) + * @param[in] dac_ch DAC Channel (use DAC_CHx) + */ +void dac_enable_auto_refresh(uint32_t dac, enum dac_ch ch) +{ + DAC_CHx_CTRL(dac, ch) |= DAC_CH_CTRL_REFREN; +} + +/** + * Disable auto refresh + * @param[in] dac DAC (use DACx) + * @param[in] dac_ch DAC Channel (use DAC_CHx) + */ +void dac_disable_auto_refresh(uint32_t dac, enum dac_ch ch) +{ + DAC_CHx_CTRL(dac, ch) &= ~DAC_CH_CTRL_REFREN; +} + +/** + * Enable channel + * @param[in] dac DAC (use DACx) + * @param[in] dac_ch DAC Channel (use DAC_CHx) + */ +void dac_enable_channel(uint32_t dac, enum dac_ch ch) +{ + DAC_CHx_CTRL(dac, ch) |= DAC_CH_CTRL_EN; +} + +/** + * Disable channel + * @param[in] dac DAC (use DACx) + * @param[in] dac_ch DAC Channel (use DAC_CHx) + */ +void dac_disable_channel(uint32_t dac, enum dac_ch ch) +{ + DAC_CHx_CTRL(dac, ch) &= ~DAC_CH_CTRL_REFREN; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dma.c b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dma.c new file mode 100644 index 00000000..e6967bfe --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/dma.c @@ -0,0 +1,621 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#define CHANNEL_SUPPORT_LOOP(ch) (((ch) == DMA_CH0) || ((ch) == DMA_CH1)) + +/** + * Enable DMA with privileged access + * @see dma_enable_with_unprivileged_access() + */ +void dma_enable_with_privileged_access(void) +{ + DMA_CONFIG = DMA_CONFIG_EN | DMA_CONFIG_CHPROT; +} + +/** + * Enable DMA with un-privileged access + * @see dma_enable_with_privileged_access() + */ +void dma_enable_with_unprivileged_access(void) +{ + DMA_CONFIG = DMA_CONFIG_EN; +} + +/** + * same as @a dma_enable_with_unprivileged_access() + * @see dma_enable_with_unprivileged_access() + */ +void dma_enable(void) +{ + dma_enable_with_unprivileged_access(); +} + +/** + * Disable DMA + */ +void dma_disable(void) +{ + DMA_CONFIG = 0; +} + +/** + * Set channel's descriptor address + * @param[in] desc_base Address of channel's descriptor address + * @note @a desc_base 8LSB's should be 0x00 + */ +void dma_set_desc_address(uint32_t desc_base) +{ + if (desc_base & 0xFF) { + return; + } + + DMA_CTRLBASE = desc_base; +} + +/** + * Get channel wait on request status flag + * @retval true if flag is set + * @retval false if flag is not set + */ +bool dma_get_wait_on_request_flag(enum dma_ch ch) +{ + uint32_t mask = DMA_CHWAITSTATUS_CHxWAITSTATUS(ch); + return (DMA_CHWAITSTATUS & mask) != 0; +} + +/** + * Generate a software request on channel + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_generate_software_request(enum dma_ch ch) +{ + DMA_CHSWREQ = DMA_CHSWREQ_CHxSWREQ(ch); +} + +/** + * Enable channel burst only + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_burst_only(enum dma_ch ch) +{ + DMA_CHUSEBURSTS = DMA_CHUSEBURSTS_CHxSUSEBURSTS(ch); +} + +/** + * Enable channel single and burst + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_single_and_burst(enum dma_ch ch) +{ + DMA_CHUSEBURSTC = DMA_CHUSEBURSTC_CHxSUSEBURSTC(ch); +} + +/** + * Enable channel peripherial request + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_periph_request(enum dma_ch ch) +{ + DMA_CHREQMASKC = DMA_CHREQMASKC_CHxSREQMASKC(ch); +} + +/** + * Disable channel peripherial request + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_disable_periph_request(enum dma_ch ch) +{ + DMA_CHREQMASKS = DMA_CHREQMASKS_CHxSREQMASKS(ch); +} + +/** + * Enable channel + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_channel(enum dma_ch ch) +{ + DMA_CHENS = DMA_CHENS_CHxSENS(ch); +} + +/** + * Disable channel + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_disable_channel(enum dma_ch ch) +{ + DMA_CHENC = DMA_CHENC_CHxSENC(ch); +} + +/** + * Disable channel alternate structure + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_disable_alternate_structure(enum dma_ch ch) +{ + DMA_CHALTC = DMA_CHALTC_CHxSALTC(ch); +} + +/** + * Enable channel alternate structure + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_alternate_structure(enum dma_ch ch) +{ + DMA_CHALTS = DMA_CHALTS_CHxSALTS(ch); +} + +/** + * Enable channel high priority + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_priority(enum dma_ch ch) +{ + DMA_CHPRIS = DMA_CHPRIS_CHxSPRIC(ch); +} + +/** + * Disable channel high priority + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_disable_priority(enum dma_ch ch) +{ + DMA_CHPRIC = DMA_CHPRIC_CHxSPRIC(ch); +} + +/** + * Get bus error flag + * @retval true if flag is set + * @retval false if flag is not set + */ +bool dma_get_bus_error_flag(void) +{ + return (DMA_ERRORC & DMA_ERRORC_ERRORC) != 0; +} + +/** + * Clear bus error flag + */ +void dma_clear_bus_error_flag(void) +{ + DMA_ERRORC = DMA_ERRORC_ERRORC; +} + +/** + * Get channel request flag + * @param[in] ch Channel (use DMA_CHx) + * @retval true if flag is set + * @retval false if flag is not set + */ +bool dma_get_request_flag(enum dma_ch ch) +{ + uint32_t mask = DMA_CHREQSTATUS_CHxSREQSTATUS(ch); + return (DMA_CHREQSTATUS & mask) != 0; +} + +/** + * Get bus error interrupt flag + * @retval true if flag is set + * @retval false if flag is not set + */ +bool dma_get_bus_error_interrupt_flag(void) +{ + return (DMA_IF & DMA_IF_ERR) != 0; +} + +/** + * Get channel done interrupt flag + * @param[in] ch Channel (use DMA_CHx) + * @retval true if flag is set + * @retval false if flag is not set + * + */ +bool dma_get_done_interrupt_flag(enum dma_ch ch) +{ + return (DMA_IF & DMA_IF_CHxDONE(ch)) != 0; +} + +/** + * Set bus error interrupt flag + */ +void dma_set_bus_error_interrupt_flag(void) +{ + DMA_IFS = DMA_IFS_ERR; +} + +/** + * Set channel done interrupt flag + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_set_done_interrupt_flag(enum dma_ch ch) +{ + DMA_IFS = DMA_IFS_CHxDONE(ch); +} + +/** + * Clear bus error interrupt flag + */ +void dma_clear_bus_error_interrupt_flag(void) +{ + DMA_IFC = DMA_IFC_ERR; +} + +/** + * Clear channel done interrupt flag + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_clear_done_interrupt_flag(enum dma_ch ch) +{ + DMA_IFC = DMA_IFC_CHxDONE(ch); +} + +/** + * Enable bus error interrupt + */ +void dma_enable_bus_error_interrupt(void) +{ + DMA_IEN |= DMA_IEN_ERR; +} + +/** + * Disable bus error interrupt + */ +void dma_disable_bus_error_interrupt(void) +{ + DMA_IEN &= ~DMA_IEN_ERR; +} + +/** + * Enable channel done interrupt + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_done_interrupt(enum dma_ch ch) +{ + DMA_IEN |= DMA_IEN_CHxDONE(ch); +} + +/** + * Disable channel done interrupt + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_disable_done_interrupt(enum dma_ch ch) +{ + DMA_IEN &= ~DMA_IEN_CHxDONE(ch); +} + +/** + * Set channel source + * @param[in] ch Channel (use DMA_CHx) + * @param[in] source Source (use DMA_CH_CTRL_SOURCESEL_*) + */ +void dma_set_source(enum dma_ch ch, uint32_t source) +{ + DMA_CHx_CTRL(ch) = (DMA_CHx_CTRL(ch) & ~DMA_CH_CTRL_SOURCESEL_MASK) + | source; +} + +/** + * Set channel source signal + * @param[in] ch Channel (use DMA_CHx) + * @param[in] signal Signal (use DMA_CH_CTRL_SIGSEL_*) + */ +void dma_set_signal(enum dma_ch ch, uint32_t signal) +{ + DMA_CHx_CTRL(ch) = (DMA_CHx_CTRL(ch) & ~DMA_CH_CTRL_SIGSEL_MASK) + | signal; +} + +/** + * Reset channel + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_channel_reset(enum dma_ch ch) +{ + /* Disable channel */ + DMA_CHENC = DMA_CHENC_CHxSENC(ch); + /* reset channel alternate desc */ + DMA_CHALTC = DMA_CHALTC_CHxSALTC(ch); + /* reset channel priority */ + DMA_CHPRIC = DMA_CHPRIC_CHxSPRIC(ch); + /* clear channel interrupt */ + DMA_IFC = DMA_IFC_CHxDONE(ch); + /* disable loop */ + if (CHANNEL_SUPPORT_LOOP(ch)) { + DMA_LOOPx(ch) = 0; + } + /* reset signal {source, select} */ + DMA_CHx_CTRL(ch) = 0; +} + +/** + * Set channel loop width to ( @a count + 1) + * @param[in] ch Channel (use DMA_CHx) + * @param[in] count Count + * @note @a count is expected to be equal to (n_minus_1 + 1) + */ +void dma_set_loop_count(enum dma_ch ch, uint16_t count) +{ + if (!CHANNEL_SUPPORT_LOOP(ch)) { + return; + } + + DMA_LOOPx(ch) = (DMA_LOOPx(ch) & ~DMA_LOOP_WIDTH_MASK) + | DMA_LOOP_WIDTH(count - 1); +} + +/** + * Enable channel loop + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_enable_loop(enum dma_ch ch) +{ + if (!CHANNEL_SUPPORT_LOOP(ch)) { + return; + } + + DMA_LOOPx(ch) |= DMA_LOOP_EN; +} + +/** + * Disable channel loop + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_disable_loop(enum dma_ch ch) +{ + if (!CHANNEL_SUPPORT_LOOP(ch)) { + return; + } + + DMA_LOOPx(ch) &= ~DMA_LOOP_EN; +} + +/** + * Set desination size + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] size Size (use DMA_MEM_*) + */ +void dma_desc_set_dest_size(uint32_t desc_base, enum dma_ch ch, + enum dma_mem size) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + cfg &= ~DMA_DESC_CH_CFG_DEST_SIZE_MASK; + cfg |= DMA_DESC_CH_CFG_DEST_SIZE(size); + DMA_DESC_CHx_CFG(desc_base, ch) = cfg; +} + +/** + * Set destination increment + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] inc Increment (use DMA_MEM_*) + */ +void dma_desc_set_dest_inc(uint32_t desc_base, enum dma_ch ch, + enum dma_mem inc) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + cfg &= ~DMA_DESC_CH_CFG_DEST_INC_MASK; + cfg |= DMA_DESC_CH_CFG_DEST_INC(inc); + DMA_DESC_CHx_CFG(desc_base, ch) = cfg; +} + +/** + * Set source size + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] size Size (use DMA_MEM_*) + */ +void dma_desc_set_src_size(uint32_t desc_base, enum dma_ch ch, + enum dma_mem size) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + cfg &= ~DMA_DESC_CH_CFG_SRC_SIZE_MASK; + cfg |= DMA_DESC_CH_CFG_SRC_SIZE(size); + DMA_DESC_CHx_CFG(desc_base, ch) = cfg; +} + +/** + * Set source increment + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] inc Increment (use DMA_MEM_*) + */ +void dma_desc_set_src_inc(uint32_t desc_base, enum dma_ch ch, enum dma_mem inc) +{ + + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + cfg &= ~DMA_DESC_CH_CFG_SRC_INC_MASK; + cfg |= DMA_DESC_CH_CFG_SRC_INC(inc); + DMA_DESC_CHx_CFG(desc_base, ch) = cfg; +} + +/** + * Set R Power + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] r_power R Power (Use DMA_R_POWER_*) + */ +void dma_desc_set_r_power(uint32_t desc_base, enum dma_ch ch, + enum dma_r_power r_power) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + cfg &= ~DMA_DESC_CH_CFG_R_POWER_MASK; + cfg |= DMA_DESC_CH_CFG_R_POWER(r_power); + DMA_DESC_CHx_CFG(desc_base, ch) = cfg; +} + +/** + * Enable next useburst + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_desc_enable_next_useburst(uint32_t desc_base, enum dma_ch ch) +{ + DMA_DESC_CHx_CFG(desc_base, ch) &= ~DMA_DESC_CH_CFG_NEXT_USEBURST; +} + +/** + * Disable next useburst + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + */ +void dma_desc_disable_next_useburst(uint32_t desc_base, enum dma_ch ch) +{ + DMA_DESC_CHx_CFG(desc_base, ch) |= DMA_DESC_CH_CFG_NEXT_USEBURST; +} + +/** + * Set number (count) of transfer to be performed + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] count Count + */ +void dma_desc_set_count(uint32_t desc_base, enum dma_ch ch, uint16_t count) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + cfg &= ~DMA_DESC_CH_CFG_N_MINUS_1_MASK; + cfg |= DMA_DESC_CH_CFG_N_MINUS_1(count - 1); + DMA_DESC_CHx_CFG(desc_base, ch) = cfg; +} + +/** + * Store user data field in channel descriptor + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] user_data User data + */ +void dma_desc_set_user_data(uint32_t desc_base, enum dma_ch ch, + uint32_t user_data) +{ + DMA_DESC_CHx_USER_DATA(desc_base, ch) = user_data; +} + +/** + * Extract user data field from channel descriptor + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @return user data + */ +uint32_t dma_desc_get_user_data(uint32_t desc_base, enum dma_ch ch) +{ + return DMA_DESC_CHx_USER_DATA(desc_base, ch); +} + +/** + * Calculate end from start address. + * + * @details + * See "8.4.3.4 Address calculation" p68, EFM32LG-RM "d0183_Rev1.10" + * + * @param[in] start address to start of memory + * @param[in] inc Increment (use DMA_MEM_*) + * @param[in] n_minus_1 the number of transfers minus 1 (ie count - 1) + * @return the calculate end address + * @note can be used to calculate {source, destination} end address + */ +static inline uint32_t dma_calc_end_from_start(uint32_t start, uint8_t inc, + uint16_t n_minus_1) +{ + switch (inc) { + case DMA_MEM_BYTE: + return start + n_minus_1; + case DMA_MEM_HALF_WORD: + return start + (n_minus_1 << 1); + case DMA_MEM_WORD: + return start + (n_minus_1 << 2); + case DMA_MEM_NONE: + return start; + } + + return 0; +} + +/** + * Assign Source address to DMA Channel + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] src_start Source data start address + * @param[in] this function use dma_desc_set_count() and dma_desc_set_src_inc() + * set value to calculate the src data end address from @a src_start + * @note dma_desc_set_count() should be called first. + * @note dma_desc_set_src_inc() should be called first. + */ +void dma_desc_set_src_address(uint32_t desc_base, enum dma_ch ch, + uint32_t src_start) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + uint8_t inc = (cfg & DMA_DESC_CH_CFG_SRC_INC_MASK) + >> DMA_DESC_CH_CFG_SRC_INC_SHIFT; + uint16_t n_minus_1 = (cfg & DMA_DESC_CH_CFG_N_MINUS_1_MASK) + >> DMA_DESC_CH_CFG_N_MINUS_1_SHIFT; + uint32_t src_end = dma_calc_end_from_start(src_start, inc, n_minus_1); + DMA_DESC_CHx_SRC_DATA_END_PTR(desc_base, ch) = src_end; +} + +/** + * Assign Destination address to DMA Channel + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] dest_start Destination data start address + * @param[in] this function use dma_desc_set_count() and + * dma_desc_set_dest_inc() set value to calculate the dest data end + * address from @a dest_start + * @note dma_desc_set_count() should be called first. + * @note dma_desc_set_dest_inc() should be called first. + */ +void dma_desc_set_dest_address(uint32_t desc_base, enum dma_ch ch, + uint32_t dest_start) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + uint8_t inc = (cfg & DMA_DESC_CH_CFG_DEST_INC_MASK) + >> DMA_DESC_CH_CFG_DEST_INC_SHIFT; + uint16_t n_minus_1 = (cfg & DMA_DESC_CH_CFG_N_MINUS_1_MASK) + >> DMA_DESC_CH_CFG_N_MINUS_1_SHIFT; + uint32_t dest_end = dma_calc_end_from_start(dest_start, inc, + n_minus_1); + DMA_DESC_CHx_DEST_DATA_END_PTR(desc_base, ch) = dest_end; +} + +/** + * Set the channel mode ("Cycle control") + * @param[in] desc_base start of memory location that contain channel + * descriptor + * @param[in] ch Channel (use DMA_CHx) + * @param[in] mode Mode (use DMA_MODE_*) + */ +void dma_desc_set_mode(uint32_t desc_base, enum dma_ch ch, enum dma_mode mode) +{ + uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch); + cfg &= ~DMA_DESC_CH_CFG_CYCLE_CTRL_MASK; + cfg |= DMA_DESC_CH_CFG_CYCLE_CTRL(mode); + DMA_DESC_CHx_CFG(desc_base, ch) = cfg; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/gpio.c new file mode 100644 index 00000000..23574228 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/gpio.c @@ -0,0 +1,175 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/** + * Enable GPIO registers lock. + * @see gpio_disable_lock() + * @see gpio_get_lock_flag() + */ +void gpio_enable_lock(void) +{ + GPIO_LOCK = GPIO_LOCK_LOCKKEY_LOCK; +} + +/** + * Disable GPIO registers lock. + * @see gpio_enable_lock() + * @see gpio_get_lock_flag() + */ +void gpio_disable_lock(void) +{ + GPIO_LOCK = GPIO_LOCK_LOCKKEY_UNLOCK; +} + +/** + * Get GPIO register lock flag + * @retval true if flag is set + * @retval false if flag is not set + * @see gpio_enable_lock() + * @see gpio_disable_lock() + */ +bool gpio_get_lock_flag(void) +{ + return (GPIO_LOCK & GPIO_LOCK_LOCKKEY_MASK) + == GPIO_LOCK_LOCKKEY_LOCKED; +} + +/** + * Set port pins drive strength + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] drive_stength Driver Stength (use GPIO_STENGTH_*) + */ +void gpio_set_drive_strength(uint32_t gpio_port, + enum gpio_drive_strength drive_stength) +{ + GPIO_P_CTRL(gpio_port) = GPIO_P_CTRL_DRIVEMODE(drive_stength); +} + +/** + * Set port pins mode + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] mode Mode (use GPIO_MODE_*) + * @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL, + * use bitwise OR '|' to separate) + */ +void gpio_mode_setup(uint32_t gpio_port, enum gpio_mode mode, uint16_t gpios) +{ + unsigned i; + + uint32_t high = GPIO_P_MODEH(gpio_port); + uint32_t low = GPIO_P_MODEL(gpio_port); + + for (i = 0; i < 8; i++) { + if (gpios & (1 << i)) { + low &= ~GPIO_P_MODE_MODEx_MASK(i); + low |= GPIO_P_MODE_MODEx(i, mode); + } + + if (gpios & (1 << (i + 8))) { + high &= ~GPIO_P_MODE_MODEx_MASK(i); + high |= GPIO_P_MODE_MODEx(i, mode); + } + } + + GPIO_P_MODEL(gpio_port) = low; + GPIO_P_MODEH(gpio_port) = high; +} + +/** + * Set port pins output value (Atomic) + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL, + * use bitwise OR '|' to separate) + */ +void gpio_set(uint32_t gpio_port, uint16_t gpios) +{ + GPIO_P_DOUTSET(gpio_port) = gpios; +} + +/** + * Set port pins output value (Atomic) + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL, + * use bitwise OR '|' to separate) + */ +void gpio_clear(uint32_t gpio_port, uint16_t gpios) +{ + GPIO_P_DOUTCLR(gpio_port) = gpios; +} + +/** + * Get port pins input value + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL, + * use bitwise OR '|' to separate) + * @return masked pins value (separated by bitwise OR '|') + */ +uint16_t gpio_get(uint32_t gpio_port, uint16_t gpios) +{ + return GPIO_P_DIN(gpio_port) & gpios; +} + +/** + * Toggle port pins output value (Atomic) + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL, + * use bitwise OR '|' to separate) + */ +void gpio_toggle(uint32_t gpio_port, uint16_t gpios) +{ + GPIO_P_DOUTTGL(gpio_port) = gpios; +} + +/** + * Get port (all) input value's + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @return all pins input value + */ +uint16_t gpio_port_read(uint32_t gpio_port) +{ + return GPIO_P_DIN(gpio_port); +} + +/** + * Set port (all) output value's + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] data Data (all pins output value) + */ +void gpio_port_write(uint32_t gpio_port, uint16_t data) +{ + GPIO_P_DOUT(gpio_port) = data; +} + +/** + * @brief Lock the Configuration of a Group of Pins + * + * The configuration of one or more pins of the given GPIO port is locked. + * There is no mechanism to unlock these via software. Unlocking occurs at the + * next reset. + * + * @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....) + * @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL, + * use bitwise OR '|' to separate) +*/ +void gpio_port_config_lock(uint32_t gpio_port, uint16_t gpios) +{ + GPIO_P_PINLOCKN(gpio_port) = ~gpios; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/libopencm3_efm32lg.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/libopencm3_efm32lg.ld new file mode 100644 index 00000000..87d6ee63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/libopencm3_efm32lg.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/prs.c b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/prs.c new file mode 100644 index 00000000..bcd47f7f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/prs.c @@ -0,0 +1,140 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/** + * Enable PRS output to GPIO. + * @param[in] ch Channel (use PRS_CHx) + * @see prs_set_output_loc() + */ +void prs_enable_gpio_output(enum prs_ch ch) +{ + PRS_ROUTE |= PRS_ROUTE_CHxPEN(ch); +} + +/** + * Disable PRS output to GPIO. + * @param[in] ch Channel (use PRS_CHx) + * @see prs_set_output_loc() + */ +void prs_disable_gpio_output(enum prs_ch ch) +{ + PRS_ROUTE &= ~PRS_ROUTE_CHxPEN(ch); +} + +/** + * Location of the PRS to be output on GPIO. + * @param[in] loc location (use PRS_ROUTE_LOCATION_LOCx) + * @see prs_set_output_loc() + */ +void prs_set_output_loc(uint32_t loc) +{ + PRS_ROUTE = (PRS_ROUTE & ~PRS_ROUTE_LOCATION_MASK) | loc; +} + +/** + * Generate software pulse. + * @param[in] ch Channel (use PRS_CHx) + * @note the final output is dependent on "software level" value of the channel + * @see prs_software_level_high() + * @see prs_software_level_low() + */ +void prs_software_pulse(enum prs_ch ch) +{ + PRS_SWPULSE = PRS_SWPULSE_CHxPULSE(ch); +} + +/** + * HIGH is XOR'ed with the corresponding bit in the software-pulse and + * the PRS input signal to generate. + * @param[in] ch Channel (use PRS_CHx) + * @see prs_software_level_low() + * @see prs_software_pulse() + */ +void prs_software_level_high(enum prs_ch ch) +{ + PRS_SWLEVEL |= PRS_SWLEVEL_CHxLEVEL(ch); +} + +/** + * LOW is XOR'ed with the corresponding bit in the software-pulse and + * the PRS input signal to generate. + * @param[in] ch Channel (use PRS_CHx) + * @see prs_software_level_high() + * @see prs_software_pulse() + */ +void prs_software_level_low(enum prs_ch ch) +{ + PRS_SWLEVEL &= ~PRS_SWLEVEL_CHxLEVEL(ch); +} + +/** + * disable synchronization of this channel reflex signal + * @param[in] ch Channel (use PRS_CHx) + * @see prs_disable_async() + */ +void prs_enable_async(enum prs_ch ch) +{ + PRS_CHx_CTRL(ch) |= PRS_CH_CTRL_ASYNC; +} + +/** + * enable synchronization of this channel reflex signal + * @param[in] ch Channel (use PRS_CHx) + * @see prs_disable_async() + */ +void prs_disable_async(enum prs_ch ch) +{ + PRS_CHx_CTRL(ch) &= ~PRS_CH_CTRL_ASYNC; +} + +/** + * Edge detection for the channel + * @param[in] ch Channel (use PRS_CHx) + * @param[in] edge Edge (use PRS_CH_CTRL_EDSEL_*) + */ +void prs_set_edge(enum prs_ch ch, uint32_t edge) +{ + PRS_CHx_CTRL(ch) = (PRS_CHx_CTRL(ch) & ~PRS_CH_CTRL_EDSEL_MASK) | edge; +} + +/** + * Source for the channel + * @param[in] ch Channel (use PRS_CHx) + * @param[in] source Source (use PRS_CH_CTRL_SOURCESEL_*) + * @see prs_set_signal() + */ +void prs_set_source(enum prs_ch ch, uint32_t source) +{ + PRS_CHx_CTRL(ch) = (PRS_CHx_CTRL(ch) & ~PRS_CH_CTRL_SOURCESEL_MASK) + | source; +} + +/** + * Source for the channel + * @param[in] ch Channel (use PRS_CHx) + * @param[in] signal Signal (use PRS_CH_CTRL_SIGSEL_*) + * @see prs_set_source() + */ +void prs_set_signal(enum prs_ch ch, uint32_t signal) +{ + PRS_CHx_CTRL(ch) = (PRS_CHx_CTRL(ch) & ~PRS_CH_CTRL_SIGSEL_MASK) + | signal; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/timer.c new file mode 100644 index 00000000..0a67b6b8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/lg/timer.c @@ -0,0 +1,62 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#define HAS_DEAD_TIME_INSERTION(timer) (timer == TIMER0) + +/** + * Start timer + * @param[in] timer Timer (use TIMERx) + */ +void timer_start(uint32_t timer) +{ + TIMER_CMD(timer) = TIMER_CMD_START; +} + +/** + * Stop timer + * @param[in] timer Timer (use TIMERx) + */ +void timer_stop(uint32_t timer) +{ + TIMER_CMD(timer) = TIMER_CMD_STOP; +} + +/** Clock division factor + * @param[in] timer Timer (use TIMERx) + * @param[in] presc Factor (use TIMER_CTRL_PRESC_DIV*) + * @note output-clock = input-clock / @a presc + */ +void timer_set_clock_prescaler(uint32_t timer, uint32_t presc) +{ + TIMER_CTRL(timer) = (TIMER_CTRL(timer) & ~TIMER_CTRL_PRESC_MASK) + | presc; +} + +/** + * Start timer top value + * the timer reload after it reaches top value + * @param[in] timer Timer (use TIMERx) + * @param[in] top Top value + */ +void timer_set_top(uint32_t timer, uint32_t top) +{ + TIMER_TOP(timer) = top; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/Makefile new file mode 100644 index 00000000..43ab711c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/Makefile @@ -0,0 +1,45 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 chrysn +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_efm32tg +SRCLIBDIR ?= ../.. +FAMILY = EFM32TG + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../:../../cm3 + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg.ld new file mode 100644 index 00000000..87d6ee63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg840f32.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg840f32.ld new file mode 100644 index 00000000..2cb8daf0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/efm32/tg/libopencm3_efm32tg840f32.ld @@ -0,0 +1,15 @@ +/* lengths from d011_efm32tg840_datasheet.pdf table 1.1, offset from + * d0034_efm32tg_reference_manual.pdf figure 5.2. + * + * the origins and memory structure are constant over all tinygeckos, but the + * MEMORY section requires the use of constants, and has thus to be duplicated + * over the chip variants. + * */ + +MEMORY +{ + rom (rx) : ORIGIN = 0, LENGTH = 32k + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4k +} + +INCLUDE libopencm3_efm32tg.ld; diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac.c new file mode 100644 index 00000000..3b7db129 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac.c @@ -0,0 +1,43 @@ +/** @defgroup ethernet_mac_file MAC Generic Drivers + * + * @ingroup ETH + * + * @brief Ethernet MAC Generic Drivers + * + * @version 1.0.0 + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/**@{*/ + + +/*---------------------------------------------------------------------------*/ + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac_stm32fxx7.c b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac_stm32fxx7.c new file mode 100644 index 00000000..283c40fa --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/mac_stm32fxx7.c @@ -0,0 +1,379 @@ +/** @defgroup ethernet_mac_stm32fxx7_file MAC STM32Fxx7 + * + * @ingroup ETH + * + * @brief Ethernet MAC STM32Fxx7 Drivers + * + * @version 1.0.0 + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include + +/**@{*/ + +uint32_t TxBD; +uint32_t RxBD; + +/*---------------------------------------------------------------------------*/ +/** @brief Set MAC to the PHY + * + * @param[in] mac uint8_t* Desired MAC + */ +void eth_set_mac(uint8_t *mac) +{ + ETH_MACAHR(0) = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4] | + ETH_MACA0HR_MACA0H; + ETH_MACALR(0) = ((uint32_t)mac[3] << 24) | ((uint32_t)mac[2] << 16) | + ((uint32_t)mac[1] << 8) | mac[0]; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Initialize descriptors + * + * @param[in] buf uint8_t* Buffer for the descriptors + * @param[in] nTx uint32_t Count of Transmit Descriptors + * @param[in] nRx uint32_t Count of Receive Descriptors + * @param[in] cTx uint32_t Bytes in each Transmit Descriptor + * @param[in] cRx uint32_t Bytes in each Receive Descriptor + * @param[in] isext bool true, if extended descriptors should be used + */ +void eth_desc_init(uint8_t *buf, uint32_t nTx, uint32_t nRx, uint32_t cTx, + uint32_t cRx, bool isext) +{ + memset(buf, 0, nTx * cTx + nRx * cRx); + + uint32_t bd = (uint32_t)buf; + uint32_t sz = isext ? ETH_DES_EXT_SIZE : ETH_DES_STD_SIZE; + + /* enable / disable extended frames */ + if (isext) { + ETH_DMABMR |= ETH_DMABMR_EDFE; + } else { + ETH_DMABMR &= ~ETH_DMABMR_EDFE; + } + + TxBD = bd; + while (--nTx > 0) { + ETH_DES0(bd) = ETH_TDES0_TCH; + ETH_DES2(bd) = bd + sz; + ETH_DES3(bd) = bd + sz + cTx; + bd = ETH_DES3(bd); + } + + ETH_DES0(bd) = ETH_TDES0_TCH; + ETH_DES2(bd) = bd + sz; + ETH_DES3(bd) = TxBD; + bd += sz + cTx; + + RxBD = bd; + while (--nRx > 0) { + ETH_DES0(bd) = ETH_RDES0_OWN; + ETH_DES1(bd) = ETH_RDES1_RCH | cRx; + ETH_DES2(bd) = bd + sz; + ETH_DES3(bd) = bd + sz + cRx; + bd = ETH_DES3(bd); + } + + ETH_DES0(bd) = ETH_RDES0_OWN; + ETH_DES1(bd) = ETH_RDES1_RCH | cRx; + ETH_DES2(bd) = bd + sz; + ETH_DES3(bd) = RxBD; + + ETH_DMARDLAR = (uint32_t) RxBD; + ETH_DMATDLAR = (uint32_t) TxBD; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Transmit packet + * + * @param[in] ppkt uint8_t* Pointer to the beginning of the packet + * @param[in] n uint32_t Size of the packet + * @returns bool true, if success + */ +bool eth_tx(uint8_t *ppkt, uint32_t n) +{ + if (ETH_DES0(TxBD) & ETH_TDES0_OWN) { + return false; + } + + memcpy((void *)ETH_DES2(TxBD), ppkt, n); + + ETH_DES1(TxBD) = n & ETH_TDES1_TBS1; + ETH_DES0(TxBD) |= ETH_TDES0_LS | ETH_TDES0_FS | ETH_TDES0_OWN; + TxBD = ETH_DES3(TxBD); + + if (ETH_DMASR & ETH_DMASR_TBUS) { + ETH_DMASR = ETH_DMASR_TBUS; + ETH_DMATPDR = 0; + } + + return true; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Receive packet + * + * @param[inout] ppkt uint8_t* Pointer to the data buffer where to store data + * @param[inout] len uint32_t* Pointer to the variable with the packet length + * @param[in] maxlen uint32_t Maximum length of the packet + * @returns bool true, if the buffer contains readed packet data + */ +bool eth_rx(uint8_t *ppkt, uint32_t *len, uint32_t maxlen) +{ + bool fs = false; + bool ls = false; + bool overrun = false; + uint32_t l = 0; + + while (!(ETH_DES0(RxBD) & ETH_RDES0_OWN) && !ls) { + l = (ETH_DES0(RxBD) & ETH_RDES0_FL) >> ETH_RDES0_FL_SHIFT; + + fs |= ETH_DES0(RxBD) & ETH_RDES0_FS; + ls |= ETH_DES0(RxBD) & ETH_RDES0_LS; + /* frame buffer overrun ?*/ + overrun |= fs && (maxlen < l); + + if (fs && !overrun) { + memcpy(ppkt, (void *)ETH_DES2(RxBD), l); + ppkt += l; + *len += l; + maxlen -= l; + } + + ETH_DES0(RxBD) = ETH_RDES0_OWN; + RxBD = ETH_DES3(RxBD); + } + + if (ETH_DMASR & ETH_DMASR_RBUS) { + ETH_DMASR = ETH_DMASR_RBUS; + ETH_DMARPDR = 0; + } + + return fs && ls && !overrun; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Start the Ethernet DMA processing + */ +void eth_start(void) +{ + ETH_MACCR |= ETH_MACCR_TE; + ETH_DMAOMR |= ETH_DMAOMR_FTF; + ETH_MACCR |= ETH_MACCR_RE; + + ETH_DMAOMR |= ETH_DMAOMR_ST; + ETH_DMAOMR |= ETH_DMAOMR_SR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Initialize ethernet + * + * This function will initialize ethernet, set up clocks, and initialize DMA. + * + * @param[in] phy phy id + * @param[in] clock enum eth_clk Core clock speed + */ +void eth_init(uint8_t phy, enum eth_clk clock) +{ + ETH_MACMIIAR = clock; + phy_reset(phy); + + ETH_MACCR = ETH_MACCR_CSTF | ETH_MACCR_FES | ETH_MACCR_DM | + ETH_MACCR_APCS | ETH_MACCR_RD; + ETH_MACFFR = ETH_MACFFR_RA | ETH_MACFFR_PM; + ETH_MACHTHR = 0; /* pass all frames */ + ETH_MACHTLR = 0; + ETH_MACFCR = (0x100 << ETH_MACFCR_PT_SHIFT); + ETH_MACVLANTR = 0; + ETH_DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_DFRF | + ETH_DMAOMR_TSF | ETH_DMAOMR_FEF | ETH_DMAOMR_OSF; + ETH_DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_FB | + (32 << ETH_DMABMR_RDP_SHIFT) | (32 << ETH_DMABMR_PBL_SHIFT) | + ETH_DMABMR_PM_2_1 | ETH_DMABMR_USP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Ethernet IRQ + * + * @param[in] reason uint32_t Which irq will be enabled + */ +void eth_irq_enable(uint32_t reason) +{ + ETH_DMAIER |= reason; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the Ethernet IRQ + * + * @param[in] reason uint32_t Which irq will be disabled + */ +void eth_irq_disable(uint32_t reason) +{ + ETH_DMAIER &= ~reason; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Check if IRQ is pending + * + * @param[in] reason uint32_t Which irq type has to be tested + * @returns bool true, if IRQ is pending + */ +bool eth_irq_is_pending(uint32_t reason) +{ + return (ETH_DMASR & reason) != 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Check if IRQ is pending, and acknowledge it + * + * @param[in] reason uint32_t Which irq type has to be tested + * @returns bool true, if IRQ is pending + */ +bool eth_irq_ack_pending(uint32_t reason) +{ + reason &= ETH_DMASR; + ETH_DMASR = reason; + return reason != 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable checksum offload feature + * + * This function will enable the Checksum offload feature for all of the + * transmit descriptors. Note to use this feature, descriptors must be in + * extended format. + */ +void eth_enable_checksum_offload(void) +{ + uint32_t tab = TxBD; + do { + ETH_DES0(tab) |= ETH_TDES0_CIC_IPPLPH; + tab = ETH_DES3(tab); + } + while (tab != TxBD); + + ETH_MACCR |= ETH_MACCR_IPCO; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Process pending SMI transaction and wait to be done. + */ +static void eth_smi_transact(void) +{ + /* Begin transaction. */ + ETH_MACMIIAR |= ETH_MACMIIAR_MB; + + /* Wait for not busy. */ + while (ETH_MACMIIAR & ETH_MACMIIAR_MB); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Write 16-bit register to the PHY + * + * @param[in] phy uint8_t ID of the PHY (defaults to 1) + * @param[in] reg uint8_t Register address + * @param[in] data uint16_t Data to write + */ +void eth_smi_write(uint8_t phy, uint8_t reg, uint16_t data) +{ + /* Write operation MW=1*/ + ETH_MACMIIAR = (ETH_MACMIIAR & ETH_MACMIIAR_CR) | /* save clocks */ + (phy << ETH_MACMIIAR_PA_SHIFT) | + (reg << ETH_MACMIIAR_MR_SHIFT) | + ETH_MACMIIAR_MW; + + ETH_MACMIIDR = data & ETH_MACMIIDR_MD; + + eth_smi_transact(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read the 16-bit register from the PHY + * + * @param[in] phy uint8_t ID of the PHY (defaults to 1) + * @param[in] reg uint8_t Register address + * @returns uint16_t Readed data + */ +uint16_t eth_smi_read(uint8_t phy, uint8_t reg) +{ + /* Read operation MW=0*/ + ETH_MACMIIAR = (ETH_MACMIIAR & ETH_MACMIIAR_CR) | /* save clocks */ + (phy << ETH_MACMIIAR_PA_SHIFT) | + (reg << ETH_MACMIIAR_MR_SHIFT); + + eth_smi_transact(); + + return (uint16_t)(ETH_MACMIIDR & ETH_MACMIIDR_MD); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Process the bit-operation on PHY register + * + * @param[in] phy uint8_t ID of the PHY (defaults to 1) + * @param[in] reg uint8_t Register address + * @param[in] bits uint16_t Bits that have to be set (or'ed) + * @param[in] mask uint16_t Bits that have to be clear (and'ed) + */ +void eth_smi_bit_op(uint8_t phy, uint8_t reg, uint16_t bits, uint16_t mask) +{ + uint16_t val = eth_smi_read(phy, reg); + eth_smi_write(phy, reg, (val & mask) | bits); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear bits in the register + * + * @param[in] phy uint8_t ID of the PHY (defaults to 1) + * @param[in] reg uint8_t Register address + * @param[in] clearbits uint16_t Bits that have to be cleared + */ +void eth_smi_bit_clear(uint8_t phy, uint8_t reg, uint16_t clearbits) +{ + uint16_t val = eth_smi_read(phy, reg); + eth_smi_write(phy, reg, val & (uint16_t)~(clearbits)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set bits in the register + * + * @param[in] phy uint8_t ID of the PHY (defaults to 1) + * @param[in] reg uint8_t Register address + * @param[in] bits uint16_t Bits that have to be set (or'ed) + */ +void eth_smi_bit_set(uint8_t phy, uint8_t reg, uint16_t setbits) +{ + uint16_t val = eth_smi_read(phy, reg); + eth_smi_write(phy, reg, val | setbits); +} + +/*---------------------------------------------------------------------------*/ + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy.c b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy.c new file mode 100755 index 00000000..363e1466 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy.c @@ -0,0 +1,65 @@ +/** @defgroup ethernet_phy_file PHY Generic Drivers + * + * @ingroup ETH + * + * @brief Ethernet PHY Generic Drivers + * + * @version 1.0.0 + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief Is the link up ? + * + * @param[in] phy uint8_t phy ID of the PHY + * @returns bool true, if link is up + */ +bool phy_link_isup(uint8_t phy) +{ + return eth_smi_read(phy, PHY_REG_BSR) & PHY_REG_BSR_UP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset the PHY + * + * Reset the PHY chip and wait for done + * @param[in] phy uint8_t phy ID of the PHY + */ +void phy_reset(uint8_t phy) +{ + eth_smi_write(phy, PHY_REG_BCR, PHY_REG_BCR_RESET); + while (eth_smi_read(phy, PHY_REG_BCR) & PHY_REG_BCR_RESET); +} + +/*---------------------------------------------------------------------------*/ + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy_ksz8051mll.c b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy_ksz8051mll.c new file mode 100755 index 00000000..275b5db9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/ethernet/phy_ksz8051mll.c @@ -0,0 +1,93 @@ +/** @defgroup ethernet_phy_ksz8051mll_file PHY KSZ8051MLL + * + * @ingroup ETH + * + * @brief Ethernet PHY STM32Fxx7 Drivers + * + * @version 1.0.0 + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 1 September 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief Get the current link status + * + * Retrieve the link speed and duplex status of the link. + * + * @param[in] phy uint8_t phy ID of the PHY + * @returns ::phy_status Link status + */ +enum phy_status phy_link_status(uint8_t phy) +{ + return eth_smi_read(phy, PHY_REG_CR1) & 0x07; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Force autonegotiation + * + * Force the autonegotiation and set link speed and duplex mode of the link + * + * @param[in] phy uint8_t phy ID of the PHY + * @param[in] mode enum phy_status Desired link status + */ +void phy_autoneg_force(uint8_t phy, enum phy_status mode) +{ + uint16_t bst = 0; + + if ((mode == LINK_FD_10M) || (mode == LINK_FD_100M) || + (mode == LINK_FD_1000M) || (mode == LINK_FD_10000M)) { + bst |= PHY_REG_BCR_FD; + } + + if ((mode == LINK_FD_100M) || (mode == LINK_HD_100M)) { + bst |= PHY_REG_BCR_100M; + } + + eth_smi_bit_op(phy, PHY_REG_BCR, bst, + ~(PHY_REG_BCR_AN | PHY_REG_BCR_100M | PHY_REG_BCR_FD)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the autonegotiation + * + * Enable the autonegotiation of the link speed and duplex mode + * + * @param[in] phy uint8_t phy ID of the PHY + */ +void phy_autoneg_enable(uint8_t phy) +{ + eth_smi_bit_set(phy, PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST); +} + +/*---------------------------------------------------------------------------*/ + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/Makefile new file mode 100644 index 00000000..7bce6313 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/Makefile @@ -0,0 +1,42 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_lm3s +SRCLIBDIR ?= .. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DLM3S +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio.o vector.o assert.o rcc.o usart.o + +VPATH += ../cm3 + +include ../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/gpio.c new file mode 100644 index 00000000..e0dd264f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/gpio.c @@ -0,0 +1,52 @@ +/** @defgroup gpio_file General Purpose I/O + +@brief LM3S General Purpose I/O + +@ingroup LM3Sxx + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2011 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +void gpio_set(uint32_t gpioport, uint8_t gpios) +{ + /* ipaddr[9:2] mask the bits to be set, hence the array index */ + GPIO_DATA(gpioport)[gpios] = 0xff; +} + +void gpio_clear(uint32_t gpioport, uint8_t gpios) +{ + GPIO_DATA(gpioport)[gpios] = 0; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/libopencm3_lm3s.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/libopencm3_lm3s.ld new file mode 100644 index 00000000..6c8c7f2e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/libopencm3_lm3s.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for LM3S targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/lm3s6965.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/lm3s6965.ld new file mode 100644 index 00000000..68094f92 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/lm3s6965.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Daniele Lacamera + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for the LM3S6965 chip (256K flash, 64K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lm3s.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/rcc.c new file mode 100644 index 00000000..96c09504 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/rcc.c @@ -0,0 +1,77 @@ +/** @defgroup rcc_file RCC Controller + +@brief LM3S RCC Controller + +@ingroup LM3Sxx + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2015 +Daniele Lacamera + +@date 21 November 2015 + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Daniele Lacamera + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +int rcc_clock_setup_in_xtal_8mhz_out_50mhz(void) +{ + uint32_t rcc = RCC_RESET_VALUE; + uint32_t rcc2 = RCC2_RESET_VALUE; + + /* Stage 0: Reset values applied */ + RCC_CR = rcc; + RCC2_CR = rcc2; + __dmb(); + + /* Stage 1: Reset Oscillators and select configured values */ + RCC_CR = RCC_SYSDIV_50MHZ | RCC_PWMDIV_64 | RCC_XTAL_8MHZ_400MHZ | RCC_USEPWMDIV; + RCC2_CR = (4 - 1) << RCC2_SYSDIV2_SHIFT; + __dmb(); + + /* Stage 2: Power on oscillators */ + rcc &= ~RCC_OFF; + rcc2 &= ~RCC2_OFF; + RCC_CR = rcc; + RCC2_CR = rcc2; + __dmb(); + + /* Stage 3: Set USESYSDIV */ + rcc |= RCC_BYPASS | RCC_USESYSDIV; + RCC_CR = rcc; + __dmb(); + + /* Stage 4: Wait for PLL raw interrupt */ + while ((RCC_RIS & RIS_PLLLRIS) == 0) + ; + + /* Stage 5: Disable bypass */ + rcc &= ~RCC_BYPASS; + rcc2 &= ~RCC2_BYPASS; + RCC_CR = rcc; + RCC2_CR = rcc2; + __dmb(); + return 0; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/usart.c new file mode 100644 index 00000000..97bdaa4b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm3s/usart.c @@ -0,0 +1,88 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * Copyright (C) 2015 Daniele Lacamera + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void usart_send(uint32_t usart, uint16_t data) +{ + USART_DR(usart) = data; +} + +uint16_t usart_recv(uint32_t usart) +{ + return USART_DR(usart) & 0xff; +} + +void usart_send_blocking(uint32_t usart, uint16_t data) +{ + while (!usart_is_send_ready(usart)); + usart_send(usart, data); +} + +bool usart_is_recv_ready(uint32_t usart) +{ + return ((USART_FR(usart) & USART_FR_RXFE) == 0); +} + +bool usart_is_send_ready(uint32_t usart) +{ + return ((USART_FR(usart) & USART_FR_BUSY) == 0); +} + +uint16_t usart_recv_blocking(uint32_t usart) +{ + while (!usart_is_recv_ready(usart)); + return usart_recv(usart); +} + +void usart_enable_rx_interrupt(uint32_t usart) +{ + USART_IM(usart) |= USART_IM_RX; +} + +void usart_enable_tx_interrupt(uint32_t usart) +{ + USART_IM(usart) |= USART_IM_TX; +} + +void usart_disable_rx_interrupt(uint32_t usart) +{ + USART_IM(usart) &= (~USART_IM_RX); +} + +void usart_disable_tx_interrupt(uint32_t usart) +{ + USART_IM(usart) &= (~USART_IM_TX); +} + +void usart_clear_rx_interrupt(uint32_t usart) +{ + USART_IC(usart) |= USART_IC_RX; +} + +void usart_clear_tx_interrupt(uint32_t usart) +{ + USART_IC(usart) |= USART_IC_TX; +} + +bool usart_get_interrupt_source(uint32_t usart, uint32_t flag) +{ + return ((USART_RIS(usart) & flag) != 0); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/Makefile new file mode 100644 index 00000000..6a5d6cf7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/Makefile @@ -0,0 +1,45 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2013 Alexandru Gagniuc +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_lm4f +SRCLIBDIR ?= .. + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../include -fno-common \ + -mcpu=cortex-m4 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DLM4F +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio.o vector.o assert.o systemcontrol.o rcc.o uart.o \ + usb_lm4f.o usb.o usb_control.o usb_standard.o + +VPATH += ../usb:../cm3 + +include ../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/gpio.c new file mode 100644 index 00000000..e89bbebb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/gpio.c @@ -0,0 +1,598 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * Copyright (C) 2013 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @defgroup gpio_file GPIO + * + * + * @ingroup LM4Fxx + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2011 + * Gareth McMullin + * @author @htmlonly © @endhtmlonly 2013 + * Alexandru Gagniuc + * + * @date 16 March 2013 + * + * LGPL License Terms @ref lgpl_license + * + * @brief libopencm3 LM4F General Purpose I/O + * + * The LM4F GPIO API provides functionality for accessing the GPIO pins of the + * LM4F. + * + * @attention @code An important aspect to consider is that libopencm3 uses the + * AHB aperture for accessing the GPIO registers on the LM4F. The AHB must be + * explicitly enabled with a call to gpio_enable_ahb_aperture() before accessing + * any GPIO functionality. + * @endcode + * + * Please see the individual GPIO modules for more details. To use the GPIO, the + * gpio.h header needs to be included: + * @code{.c} + * #include + * @endcode + */ + +/**@{*/ + +#include +#include + +/* Value we need to write to unlock the GPIO commit register */ +#define GPIO_LOCK_UNLOCK_CODE 0x4C4F434B + + +/** @defgroup gpio_config GPIO pin configuration + * @ingroup gpio_file + * + * \brief Enabling and configuring GPIO pins + * + * @section gpio_api_enable Enabling GPIO ports + * @attention + * Before accessing GPIO functionality through this API, the AHB aperture for + * GPIO ports must be enabled via a call to @ref gpio_enable_ahb_aperture(). + * Failing to do so will cause a hard fault. + * + * @note + * Once the AHB aperture is enabled, GPIO registers can no longer be accessed + * via the APB aperture. The two apertures are mutually exclusive. + * + * Enabling the AHB aperture only needs to be done once. However, in order to + * access a certain GPIO port, its clock must also be enabled. Enabling the + * GPIO clock needs to be done for every port that will be used. + * + * For example, to enable GPIOA and GPIOD: + * @code{.c} + * // Make sure we can access the GPIO via the AHB aperture + * gpio_enable_ahb_aperture(); + * ... + * // Enable GPIO ports A and D + * periph_clock_enable(RCC_GPIOA); + * periph_clock_enable(RCC_GPIOD); + * @endcode + * + * On reset all ports are configured as digital floating inputs (no pull-up or + * pull-down), except for special function pins. + * + * + * @section gpio_api_in Configuring pins as inputs + * + * Configuring GPIO pins as inputs is done with @ref gpio_mode_setup(), with + * @ref GPIO_MODE_INPUT for the mode parameter. The direction of the pull-up + * must be specified with the same call + * + * For example, PA2, PA3, and PA4 as inputs, with pull-up on PA4: + * @code{.c} + * gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO2 | GPIO3); + * gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO4); + * @endcode + * + * + * @section gpio_api_out Configuring pins as outputs + * + * Output pins have more configuration options than input pins. LM4F pins can be + * configured as either push-pull, or open drain. The drive strength of each pin + * can be adjusted between 2mA, 4mA, or 8mA. Slew-rate control is available when + * the pins are configured to drive 8mA. These extra options can be specified + * with @ref gpio_set_output_config(). + * The default is push-pull configuration with 2mA drive capability. + * + * @note + * @ref gpio_set_output_config() controls different capabilities than the + * similar sounding gpio_set_output_options() from the STM GPIO API. They are + * intentionally named differently to prevent confusion between the two. They + * are API incompatible. + * + * For example, to set PA2 to output push-pull with a drive strength of 8mA: + * @code{.c} + * gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO2); + * gpio_set_output_config(GPIOA, GPIO_OTYPE_PP, GPIO_DRIVE_8MA, GPIO2); + * @endcode + * + * + * @section gpio_api_analog Configuring pins as analog function + * + * Configuring GPIO pins to their analog function is done with + * @ref gpio_mode_setup(), with @ref GPIO_MODE_ANALOG for the mode parameter. + * + * Suppose PD4 and PD5 are the USB pins. To enable their analog functionality + * (USB D+ and D- in this case), use: + * @code + * // Mux USB pins to their analog function + * gpio_mode_setup(GPIOD, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO4 | GPIO5); + * @endcode + * + * @section gpio_api_alf_func Configuring pins as alternate functions + * + * Most pins have alternate functions associated with them. When a pin is set to + * an alternate function, it is multiplexed to one of the dedicated hardware + * peripheral in the chip. The alternate function mapping can be found in the + * part's datasheet, and usually varies between arts of the same family. + * + * Multiplexing a pin, or group of pins to an alternate function is done with + * @ref gpio_set_af(). Because AF0 is not used on the LM4F, passing 0 as the + * alt_func_num parameter will disable the alternate function of the given pins. + * + * @code + * // Mux PB0 and PB1 to AF1 (UART1 TX/RX in this case) + * gpio_set_af(GPIOB, 1, GPIO0 | GPIO1); + * @endcode + * + * @section gpio_api_sfpins Changing configuration of special function pins + * + * On the LM4F, the NMI and JTAG/SWD default to their alternate function. These + * pins cannot normally be committed to GPIO usage. To enable these special + * function pins to be used as GPIO, they must be unlocked. This may be achieved + * via @ref gpio_unlock_commit. Once a special function pin is unlocked, its + * settings may be altered in the usual way. + * + * For example, to unlock the PF0 pin (NMI on the LM4F120): + * @code + * // PF0 is an NMI pin, and needs to be unlocked + * gpio_unlock_commit(GPIOF, GPIO0); + * // Now the pin can be configured + * gpio_mode_setup(RGB_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, btnpins); + * @endcode + */ +/**@{*/ + +/** + * \brief Enable access to GPIO registers via the AHB aperture + * + * All GPIO registers are accessed in libopencm3 via the AHB aperture. It + * provides faster control over the older APB aperture. This aperture must be + * enabled before calling any other gpio_*() function. + * + */ +void gpio_enable_ahb_aperture(void) +{ + SYSCTL_GPIOHBCTL = 0xffffffff; +} + +/** + * \brief Configure a group of pins + * + * Sets the Pin direction, analog/digital mode, and pull-up configuration of + * or a set of GPIO pins on a given GPIO port. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] mode Pin mode (@ref gpio_mode) \n + * - GPIO_MODE_OUTPUT -- Configure pin as output \n + * - GPIO_MODE_INPUT -- Configure pin as input \n + * - GPIO_MODE_ANALOG -- Configure pin as analog function + * @param[in] pullup Pin pullup/pulldown configuration (@ref gpio_pullup) \n + * - GPIO_PUPD_NONE -- Do not pull the pin high or low \n + * - GPIO_PUPD_PULLUP -- Pull the pin high \n + * - GPIO_PUPD_PULLDOWN -- Pull the pin low + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together + */ +void gpio_mode_setup(uint32_t gpioport, enum gpio_mode mode, + enum gpio_pullup pullup, uint8_t gpios) +{ + switch (mode) { + case GPIO_MODE_OUTPUT: + GPIO_DIR(gpioport) |= gpios; + GPIO_DEN(gpioport) |= gpios; + GPIO_AMSEL(gpioport) &= ~gpios; + break; + case GPIO_MODE_INPUT: + GPIO_DIR(gpioport) &= ~gpios; + GPIO_DEN(gpioport) |= gpios; + GPIO_AMSEL(gpioport) &= ~gpios; + break; + case GPIO_MODE_ANALOG: + GPIO_DEN(gpioport) &= ~gpios; + GPIO_AMSEL(gpioport) |= gpios; + break; + default: + /* Don't do anything */ + break; + } + + /* + * Setting a bit in the GPIO_PDR register clears the corresponding bit + * in the GPIO_PUR register, and vice-versa. + */ + switch (pullup) { + case GPIO_PUPD_PULLUP: + GPIO_PUR(gpioport) |= gpios; + break; + case GPIO_PUPD_PULLDOWN: + GPIO_PDR(gpioport) |= gpios; + break; + case GPIO_PUPD_NONE: /* Fall through */ + default: + GPIO_PUR(gpioport) &= ~gpios; + GPIO_PDR(gpioport) &= ~gpios; + break; + } +} + +/** + * \brief Configure output parameters of a group of pins + * + * Sets the output configuration and drive strength, of or a set of GPIO pins + * for a set of GPIO pins in output mode. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] otype Output driver configuration (@ref gpio_output_type) \n + * - GPIO_OTYPE_PP -- Configure pin driver as push-pull \n + * - GPIO_OTYPE_OD -- Configure pin driver as open drain + * @param[in] drive Pin drive strength (@ref gpio_drive_strength) \n + * - GPIO_DRIVE_2MA -- 2mA drive \n + * - GPIO_DRIVE_4MA -- 4mA drive \n + * - GPIO_DRIVE_8MA -- 8mA drive \n + * - GPIO_DRIVE_8MA_SLEW_CTL -- 8mA drive with slew rate + * control + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together + */ +void gpio_set_output_config(uint32_t gpioport, enum gpio_output_type otype, + enum gpio_drive_strength drive, uint8_t gpios) +{ + if (otype == GPIO_OTYPE_OD) { + GPIO_ODR(gpioport) |= gpios; + } else { + GPIO_ODR(gpioport) &= ~gpios; + } + + /* + * Setting a bit in the GPIO_DRxR register clears the corresponding bit + * in the other GPIO_DRyR registers, and vice-versa. + */ + switch (drive) { + case GPIO_DRIVE_8MA_SLEW_CTL: + GPIO_DR8R(gpioport) |= gpios; + GPIO_SLR(gpioport) |= gpios; + break; + case GPIO_DRIVE_8MA: + GPIO_DR8R(gpioport) |= gpios; + GPIO_SLR(gpioport) &= ~gpios; + break; + case GPIO_DRIVE_4MA: + GPIO_DR4R(gpioport) |= gpios; + break; + case GPIO_DRIVE_2MA: /* Fall through */ + default: + GPIO_DR2R(gpioport) |= gpios; + break; + } +} + +#define PCTL_AF(pin, af) ((af) << ((pin) << 2)) +#define PCTL_MASK(pin) PCTL_AF((pin), 0xf) +/** + * \brief Multiplex group of pins to the given alternate function + * + * Mux the pin or group of pins to the given alternate function. Note that a + * number of pins may be set but only with a single AF number. This is useful + * when one or more of a peripheral's pins are assigned to the same alternate + * function. + * + * Because AF0 is not used on the LM4F, passing 0 as the alt_func_num parameter + * will disable the alternate function of the given pins. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] alt_func_num Pin alternate function number or 0 to disable the + * alternate function multiplexing. + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together + */ +void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint8_t gpios) +{ + uint32_t pctl32; + uint8_t pin_mask; + int i; + + /* Did we mean to disable the alternate function? */ + if (alt_func_num == 0) { + GPIO_AFSEL(gpioport) &= ~gpios; + return; + } + + /* Enable the alternate function */ + GPIO_AFSEL(gpioport) |= gpios; + /* Alternate functions are digital */ + GPIO_DEN(gpioport) |= gpios; + + /* Now take care of the actual multiplexing */ + pctl32 = GPIO_PCTL(gpioport); + for (i = 0; i < 8; i++) { + pin_mask = (1 << i); + + if (!(gpios & pin_mask)) { + continue; + } + + pctl32 &= ~PCTL_MASK(i); + pctl32 |= PCTL_AF(i, (alt_func_num & 0xf)); + } + + GPIO_PCTL(gpioport) = pctl32; +} + +/** + * \brief Unlock the commit control of a special function pin + * + * Unlocks the commit control of the given pin or group of pins. If a pin is a + * JTAG/SWD or NMI, the pin may then be reconfigured as a GPIO pin. If the pin + * is not locked by default, this has no effect. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together. + */ +void gpio_unlock_commit(uint32_t gpioport, uint8_t gpios) +{ + /* Unlock the GPIO_CR register */ + GPIO_LOCK(gpioport) = GPIO_LOCK_UNLOCK_CODE; + /* Enable committing changes */ + GPIO_CR(gpioport) |= gpios; + /* Lock the GPIO_CR register */ + GPIO_LOCK(gpioport) = ~GPIO_LOCK_UNLOCK_CODE; +} +/**@}*/ + +/** @defgroup gpio_control GPIO pin control + * @ingroup gpio_file + * + * \brief Controlling GPIO pins + * + * Each I/O port has 8 individually configurable bits. When reading and writing + * data to the GPIO ports, address bits [9:2] mask the pins to be read or + * written. This mechanism makes all GPIO port reads and writes on the LM4F + * atomic operations. The GPIO API takes full advantage of this fact to preserve + * the atomicity of these operations. + * + * Setting or clearing a group of bits can be accomplished with @ref gpio_set() + * and @ref gpio_clear() respectively. These operation use the masking mechanism + * described above to only affect the specified pins. + * + * Sometimes it is more appropriate to read or set the level of a group of pins + * on a port, in one atomic operation. Reading the status can be accomplished + * with @ref gpio_read(). The result is equivalent to reading all the pins, then + * masking only the desired pins; however, the masking is done in hardware, and + * does not require an extra hardware operation. + * + * Writing a group of pins can be accomplished with @ref gpio_write(). The mask + * ('gpios' parameter) is applied in hardware, and the masked pins are not + * affected, regardless of the value of the respective bits written to the GPIO + * port. + * + * Two extra functions are provided, @ref gpio_port_read() and + * @ref gpio_port_write(). They are functionally identical to + * @ref gpio_read (port, GPIO_ALL) and @ref gpio_write (port, GPIO_ALL, val) + * respectively. Hence, they are also atomic. + * + * GPIO pins may be toggled with @ref gpio_toggle(). This function does not + * translate to an atomic operation. + * + * @note + * The @ref gpio_toggle() operation is the only GPIO port operation which is not + * atomic. It involves a read-modify-write cycle. + * + * Suppose PA0, PA1, PA2, and PA3 are to be modified without affecting the other + * pins on port A. This is common when controlling, for example, a 4-bit bus: + * @code{.c} + * // Pins 4,5,6, and 7 are unaffected, regardless of the bits in val + * gpio_write(GPIOA, GPIO0 | GPIO1 | GPIO2 | GPIO3, val); + * // Wait a bit then send the other 4 bits + * wait_a_bit(); + * gpio_write(GPIOA, GPIO0 | GPIO1 | GPIO2 | GPIO3, val >> 4); + * @endcode + * + * Suppose a LED is connected to PD4, and we want to flash the LED for a brief + * period of time: + * @code + * gpio_set(GPIOD, GPIO4); + * wait_a_bit(); + * gpio_set(GPIOD, GPIO4); + * @endcode + */ +/**@{*/ +/** + * \brief Toggle a Group of Pins + * + * Toggle one or more pins of the given GPIO port. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios Pin identifiers. @ref gpio_pin_id + */ +void gpio_toggle(uint32_t gpioport, uint8_t gpios) +{ + /* The mask makes sure we only toggle the GPIOs we want to */ + GPIO_DATA(gpioport)[gpios] ^= GPIO_ALL; +} +/**@}*/ + + +/** @defgroup gpio_irq GPIO Interrupt control + * @ingroup gpio_file + * + * \brief Configuring interrupts from GPIO pins + * + * GPIO pins can trigger interrupts on either edges or levels. The type of + * trigger can be configured with @ref gpio_configure_int_trigger(). To have an + * event on the given pin generate an interrupt, its interrupt source must be + * unmasked. This can be achieved with @ref gpio_enable_interrupts(). Interrupts + * which are no longer needed can be disabled through + * @ref gpio_disable_interrupts(). + * + * In order for the interrupt to generate an IRQ and a call to the interrupt + * service routine, the interrupt for the GPIO port must be routed through the + * NVIC with @ref nvic_enable_irq(). For this last step, the nvic.h header is + * needed: + * @code{.c} + * #include + * @endcode + * + * Enabling an interrupt is as simple as configuring the desired trigger, + * unmasking the desired interrupt, and routing the desired GPIO port's + * interrupt through the NVIC. + * @code{.c} + * // Trigger interrupt on each rising edge + * gpio_configure_trigger(GPIOF, GPIO_TRIG_EDGE_RISE, GPIO0 | GPIO4); + * // Unmask the interrupt on those pins + * gpio_enable_interrupts(GPIOF, GPIO0 | GPIO4); + * // Enable the interrupt in the NVIC as well + * nvic_enable_irq(NVIC_GPIOF_IRQ); + * @endcode + * + * After interrupts are properly enabled and routed through the NVIC, when an + * event occurs, the appropriate IRQ flag is set by hardware, and execution + * jumps to the GPIO ISR. The ISR should query the IRQ flags to determine which + * event caused the interrupt. For this, use @ref gpio_is_interrupt_source(), + * with the desired GPIO flag. After one or more interrupt sources are + * serviced, the IRQ flags must be cleared by the ISR. This can be done with + * @ref gpio_clear_interrupt_flag(). + * + * A typical GPIO ISR may look like the following: + * @code{.c} + * void gpiof_isr(void) + * { + * uint8_t serviced_irqs = 0; + * + * // Process individual IRQs + * if (gpio_is_interrupt_source(GPIOF, GPIO0)) { + * process_gpio0_event(); + * serviced_irq |= GPIO0; + * } + * if (gpio_is_interrupt_source(GPIOF, GPIO4)) { + * process_gpio4_event(); + * serviced_irq |= GPIO4; + * } + * + * // Clear the interrupt flag for the processed IRQs + * gpio_clear_interrupt_flag(GPIOF, serviced_irqs); + * } + * @endcode + */ +/**@{*/ +/** + * \brief Configure the interrupt trigger on the given GPIO pins + * + * Sets the Pin direction, analog/digital mode, and pull-up configuration of + * or a set of GPIO pins on a given GPIO port. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] trigger Trigger configuration (@ref gpio_trigger) \n + * - GPIO_TRIG_LVL_LOW -- Trigger on low level \n + * - GPIO_TRIG_LVL_HIGH -- Trigger on high level \n + * - GPIO_TRIG_EDGE_FALL -- Trigger on falling edges \n + * - GPIO_TRIG_EDGE_RISE -- Trigger on rising edges \n + * - GPIO_TRIG_EDGE_BOTH -- Trigger on all edges + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be specified + * by OR'ing then together + */ +void gpio_configure_trigger(uint32_t gpioport, enum gpio_trigger trigger, + uint8_t gpios) +{ + switch (trigger) { + case GPIO_TRIG_LVL_LOW: + GPIO_IS(gpioport) |= gpios; + GPIO_IEV(gpioport) &= ~gpios; + break; + case GPIO_TRIG_LVL_HIGH: + GPIO_IS(gpioport) |= gpios; + GPIO_IEV(gpioport) |= gpios; + break; + case GPIO_TRIG_EDGE_FALL: + GPIO_IS(gpioport) &= ~gpios; + GPIO_IBE(gpioport) &= ~gpios; + GPIO_IEV(gpioport) &= ~gpios; + break; + case GPIO_TRIG_EDGE_RISE: + GPIO_IS(gpioport) &= ~gpios; + GPIO_IBE(gpioport) &= ~gpios; + GPIO_IEV(gpioport) |= gpios; + break; + case GPIO_TRIG_EDGE_BOTH: + GPIO_IS(gpioport) &= ~gpios; + GPIO_IBE(gpioport) |= gpios; + break; + default: + /* Don't do anything */ + break; + } +} + +/** + * \brief Enable interrupts on specified GPIO pins + * + * Enable interrupts on the specified GPIO pins + * + * Note that the NVIC must be enabled and properly configured for the interrupt + * to be routed to the CPU. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Pins whose interrupts to enable. Any + * combination of pins may be specified by OR'ing them + * together. + */ +void gpio_enable_interrupts(uint32_t gpioport, uint8_t gpios) +{ + GPIO_IM(gpioport) |= gpios; +} + +/** + * \brief Disable interrupts on specified GPIO pins + * + * Disable interrupts on the specified GPIO pins + * + * Note that the NVIC must be enabled and properly configured for the interrupt + * to be routed to the CPU. + * + * @param[in] gpioport GPIO block register address base @ref gpio_reg_base + * @param[in] gpios @ref gpio_pin_id. Pins whose interrupts to disable. Any + * combination of pins may be specified by OR'ing them + * together. + */ +void gpio_disable_interrupts(uint32_t gpioport, uint8_t gpios) +{ + GPIO_IM(gpioport) |= gpios; +} + +/**@}*/ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/libopencm3_lm4f.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/libopencm3_lm4f.ld new file mode 100644 index 00000000..12d939e2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/libopencm3_lm4f.ld @@ -0,0 +1,2 @@ +/* Yes, we can simply use the lm3s linker script */ +INCLUDE "libopencm3_lm3s.ld" diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/rcc.c new file mode 100644 index 00000000..ee16de6c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/rcc.c @@ -0,0 +1,499 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +/** + * @defgroup rcc_file RCC + * + * @ingroup LM4Fxx + * +@author @htmlonly © @endhtmlonly 2012 +Alexandru Gagniuc + + * \brief libopencm3 LM4F Clock control API + * + * The LM$F clock API provides functionaliity for manipulating the system clock, + * oscillator, and PLL. Functions are provided for fine-grained control of clock + * control registers, while also providing higher level functionality to easily + * configure the main system clock source. + * + * The following code snippet uses fine-grained mechanisms to configures the + * chip to run off an external 16MHz crystal, and use the PLL to derive a clock + * frequency of 80MHz. + * @code{.c} + * // A divisor of 5 gives us a clock of 400/5 = 80MHz + * #define PLLDIV_80MHZ 5 + * + * // Enable the main oscillator + * rcc_enable_main_osc(); + * + * // Make RCC2 override RCC + * rcc_enable_rcc2(); + * + * // Set XTAL value to 16MHz + * rcc_configure_xtal(XTAL_16M); + * // Set the oscillator source as the main oscillator + * rcc_set_osc_source(OSCSRC_MOSC); + * // Enable the PLL + * rcc_pll_on(); + * + * // Change the clock divisor + * rcc_set_pll_divisor(PLLDIV_80MHZ); + * + * // We cannot use the PLL as a clock source until it locks + * rcc_wait_for_pll_ready(); + * // Disable PLL bypass to derive the system clock from the PLL clock + * rcc_pll_bypass_disable(); + * + * // Keep track of frequency + * lm4f_rcc_sysclk_freq = 80E6; + * @endcode + * + * The same can be achieved by a simple call to high-level routines: + * @code + * // A divisor of 5 gives us a clock of 400/5 = 80MHz + * #define PLLDIV_80MHZ 5 + * + * rcc_sysclk_config(OSCSRC_MOSC, XTAL_16M, PLLDIV_80MHZ); + * @endcode + * + * @{ + */ + +#include + +/** + * @defgroup rcc_low_level Low-level clock control API +@ingroup rcc_file + * @{ + */ +/** + * \brief System clock frequency + * + * This variable is provided to keep track of the system clock frequency. It + * should be updated every time the system clock is changed via the fine-grained + * mechanisms. The initial value is 16MHz, which corresponds to the clock of the + * internal 16MHz oscillator. + * + * High-level routines update the system clock automatically. + * For read access, it is recommended to access this variable via + * @code + * rcc_get_system_clock_frequency(); + * @endcode + * + * If write access is desired (i.e. when changing the system clock via the + * fine-grained mechanisms), then include the following line in your code: + * @code + * extern uint32_t lm4f_rcc_sysclk_freq; + * @endcode + */ +uint32_t lm4f_rcc_sysclk_freq = 16000000; + + +/** + * \brief Configure the crystal type connected to the device. + * + * Configure the crystal type connected between the OSCO and OSCI pins by + * writing the appropriate value to the XTAL field in SYSCTL_RCC. The PLL + * parameters are automatically adjusted in hardware to provide a PLL clock of + * 400MHz. + * + * @param[in] xtal predefined crystal type @see xtal_t + */ +void rcc_configure_xtal(enum xtal_t xtal) +{ + uint32_t reg32; + + reg32 = SYSCTL_RCC; + reg32 &= ~SYSCTL_RCC_XTAL_MASK; + reg32 |= (xtal & SYSCTL_RCC_XTAL_MASK); + SYSCTL_RCC = reg32; +} + +/** + * \brief Disable the main oscillator + * + * Sets the IOSCDIS bit in SYSCTL_RCC, disabling the main oscillator. + */ +void rcc_disable_main_osc(void) +{ + SYSCTL_RCC |= SYSCTL_RCC_MOSCDIS; +} + +/** + * \brief Disable the internal oscillator + * + * Sets the IOSCDIS bit in SYSCTL_RCC, disabling the internal oscillator. + */ +void rcc_disable_interal_osc(void) +{ + SYSCTL_RCC |= SYSCTL_RCC_IOSCDIS; +} + +/** + * \brief Enable the main oscillator + * + * Clears the MOSCDIS bit in SYSCTL_RCC, enabling the main oscillator. + */ +void rcc_enable_main_osc(void) +{ + SYSCTL_RCC &= ~SYSCTL_RCC_MOSCDIS; +} + +/** + * \brief Enable the internal oscillator + * + * Clears the IOSCDIS bit in SYSCTL_RCC, enabling the internal oscillator. + */ +void rcc_enable_interal_osc(void) +{ + SYSCTL_RCC &= ~SYSCTL_RCC_IOSCDIS; +} + +/** + * \brief Enable the use of SYSCTL_RCC2 register for clock control + * + * Enables the USERCC2 bit in SYSCTTL_RCC2. Settings in SYSCTL_RCC2 will + * override settings in SYSCTL_RCC. + * This function must be called before other calls to manipulate the clock, as + * libopencm3 uses the SYSCTL_RCC2 register. + */ +void rcc_enable_rcc2(void) +{ + SYSCTL_RCC2 |= SYSCTL_RCC2_USERCC2; +} + +/** + * \brief Power down the main PLL + * + * Sets the SYSCTL_RCC2_PWRDN2 in SYSCTL_RCC2 to power down the PLL. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + */ +void rcc_pll_off(void) +{ + SYSCTL_RCC2 |= SYSCTL_RCC2_PWRDN2; +} + +/** + * \brief Power up the main PLL + * + * Clears the PWRDN2 in SYSCTL_RCC2 to power on the PLL. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + */ +void rcc_pll_on(void) +{ + SYSCTL_RCC2 &= ~SYSCTL_RCC2_PWRDN2; +} + +/** + * \brief Set the oscillator source to be used by the system clock + * + * Set the clock source for the system clock. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + */ +void rcc_set_osc_source(enum osc_src src) +{ + uint32_t reg32; + + reg32 = SYSCTL_RCC2; + reg32 &= ~SYSCTL_RCC2_OSCSRC2_MASK; + reg32 |= (src & SYSCTL_RCC2_OSCSRC2_MASK); + SYSCTL_RCC2 = reg32; +} + +/** + * \brief Disable the PLL bypass and use the PLL clock + * + * Clear BYPASS2 in SYSCTL_RCC2. The system clock is derived from the PLL + * clock divided by the divisor specified in SYSDIV2. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + */ +void rcc_pll_bypass_disable(void) +{ + SYSCTL_RCC2 &= ~SYSCTL_RCC2_BYPASS2; +} + +/** + * \brief Enable the PLL bypass and use the oscillator clock + * + * Set BYPASS2 in SYSCTL_RCC2. The system clock is derived from the oscillator + * clock divided by the divisor specified in SYSDIV2. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + */ +void rcc_pll_bypass_enable(void) +{ + SYSCTL_RCC2 |= SYSCTL_RCC2_BYPASS2; +} + +/** + * \brief Set the PLL clock divisor (from 400MHz) + * + * Set the binary divisor used to predivide the system clock down for use as the + * timing reference for the PWM module. The divisor is expected to be a divisor + * from 400MHz, not 200MHz. The DIV400 is also set. + * + * Specifies the divisor that used to generate the system clock from either the + * PLL output or the oscillator source (depending on the BYPASS2 bit in + * SYSCTL_RCC2). SYSDIV2 is used for the divisor when both the USESYSDIV bit in + * SYSCTL_RCC is set. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + * + * @param[in] div clock divisor to apply to the 400MHz PLL clock. It is the + * caller's responsibility to ensure that the divisor will not create + * a system clock that is out of spec. + */ +void rcc_set_pll_divisor(uint8_t div400) +{ + uint32_t reg32; + + SYSCTL_RCC |= SYSCTL_RCC_USESYSDIV; + + reg32 = SYSCTL_RCC2; + reg32 &= ~SYSCTL_RCC2_SYSDIV400_MASK; + reg32 |= ((div400 - 1) << 22) & SYSCTL_RCC2_SYSDIV400_MASK; + /* We are expecting a divider from 400MHz */ + reg32 |= SYSCTL_RCC2_DIV400; + SYSCTL_RCC2 = reg32; +} +/** + * \brief Set the PWM unit clock divisor + * + * Set the binary divisor used to predivide the system clock down for use as the + * timing reference for the PWM module. + * + * @param[in] div clock divisor to use @see pwm_clkdiv_t + */ +void rcc_set_pwm_divisor(enum pwm_clkdiv div) +{ + uint32_t reg32; + + reg32 = SYSCTL_RCC; + reg32 &= ~SYSCTL_RCC_PWMDIV_MASK; + reg32 |= (div & SYSCTL_RCC_PWMDIV_MASK); + SYSCTL_RCC = reg32; +} + +/** + * \brief Power down the USB PLL + * + * Sets the USBPWRDN in SYSCTL_RCC2 to power down the USB PLL. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + */ +void rcc_usb_pll_off(void) +{ + SYSCTL_RCC2 |= SYSCTL_RCC2_USBPWRDN; +} + +/** + * \brief Power up the USB PLL + * + * Clears the USBPWRDN in SYSCTL_RCC2 to power on the USB PLL. + * + * USERCC2 must have been set by a call to rcc_enable_rcc2() before calling this + * function. + */ +void rcc_usb_pll_on(void) +{ + SYSCTL_RCC2 &= ~SYSCTL_RCC2_USBPWRDN; +} + +/** + * \brief Wait for main PLL to lock + * + * Waits until the LOCK bit in SYSCTL_PLLSTAT is set. This guarantees that the + * PLL is locked, and ready to use. + */ +void rcc_wait_for_pll_ready(void) +{ + while (!(SYSCTL_PLLSTAT & SYSCTL_PLLSTAT_LOCK)); +} + +/** + * @} + */ + +/** + * @defgroup rcc_high_level High-level clock control API +@ingroup rcc_file + * @{ + */ + +/** + * \brief Change the PLL divisor + * + * Changes the divisor applied to the 400MHz PLL clock. The PLL must have + * previously been configured by selecting an appropriate XTAL value, and + * turning on the PLL. This function does not reconfigure the XTAL value or + * oscillator source. It only changes the PLL divisor. + * + * The PLL is bypassed before modifying the divisor, and the function blocks + * until the PLL is locked, then the bypass is disabled, before returning. + * + * @param [in] pll_div400 The clock divisor to apply to the 400MHz PLL clock. + */ +void rcc_change_pll_divisor(uint8_t pll_div400) +{ + /* Bypass the PLL while its settings are modified */ + rcc_pll_bypass_enable(); + /* Change the clock divisor */ + rcc_set_pll_divisor(pll_div400); + /* We cannot use the PLL as a clock source until it locks */ + rcc_wait_for_pll_ready(); + /* Disable PLL bypass to derive the system clock from the PLL clock */ + rcc_pll_bypass_disable(); + /* Update the system clock frequency for housekeeping */ + lm4f_rcc_sysclk_freq = (uint32_t)400E6 / pll_div400; +} + +/** + * \brief Get the system clock frequency + * + * @return System clock frequency in Hz + */ +uint32_t rcc_get_system_clock_frequency(void) +{ + return lm4f_rcc_sysclk_freq; +} + +/* Get the clock frequency corresponding to a given XTAL value */ +static uint32_t xtal_to_freq(enum xtal_t xtal) +{ + const uint32_t freqs[] = { + 4000000, /* XTAL_4M */ + 4096000, /* XTAL_4M_096 */ + 4915200, /* XTAL_4M_9152 */ + 5000000, /* ,XTAL_5M */ + 5120000, /* XTAL_5M_12 */ + 6000000, /* XTAL_6M */ + 6144000, /* XTAL_6M_144 */ + 7372800, /* XTAL_7M_3728 */ + 8000000, /* XTAL_8M */ + 8192000, /* XTAL_8M_192 */ + 10000000, /* XTAL_10M */ + 12000000, /* XTAL_12M */ + 12288000, /* XTAL_12M_288 */ + 13560000, /* XTAL_13M_56 */ + 14318180, /* XTAL_14M_31818 */ + 16000000, /* XTAL_16M */ + 16384000, /* XTAL_16M_384 */ + 18000000, /* XTAL_18M */ + 20000000, /* XTAL_20M */ + 24000000, /* XTAL_24M */ + 25000000, /* XTAL_25M */ + }; + + return freqs[xtal - XTAL_4M]; +} + +/** + * \brief Configure the system clock source + * + * Sets up the system clock, including configuring the oscillator source, and + * PLL to acheve the desired system clock frequency. Where applicable, The LM4F + * clock API uses the new RCC2 register to configure clock parameters. + * + * Enables the main oscillator if the clock source is OSCSRC_MOSC. If the main + * oscillator was previously enabled, it will not be disabled. If desired, it + * can be separately disabled by a call to rcc_disable_main_osc(). + * + * Configures the system clock to run from the 400MHz PLL with a divisor of + * pll_div400 applied. If pll_div400 is 0, then the PLL is disabled, and the + * system clock is configured to run off a "raw" clock. If the PLL was + * previously powered on, it will not be disabled. If desired, it can de powered + * off by a call to rcc_pll_off(). + * + * @param [in] osc_src Oscillator from where to derive the system clock. + * @param [in] xtal Type of crystal connected to the OSCO/OSCI pins + * @param [in] pll_div400 The clock divisor to apply to the 400MHz PLL clock. + * If 0, then the PLL is disabled, and the system runs + * off a "raw" clock. + * + * @return System clock frequency in Hz + */ +void rcc_sysclk_config(enum osc_src src, enum xtal_t xtal, uint8_t pll_div400) +{ + /* + * We could be using the PLL at this point, or we could be running of a + * raw clock. Either way, it is safer to bypass the PLL now. + */ + rcc_pll_bypass_enable(); + + /* Enable the main oscillator, if needed */ + if (src == OSCSRC_MOSC) { + rcc_enable_main_osc(); + } + + /* Make RCC2 override RCC */ + rcc_enable_rcc2(); + + /* Set XTAL value to 16MHz */ + rcc_configure_xtal(xtal); + /* Set the oscillator source */ + rcc_set_osc_source(src); + if (pll_div400) { + /* Enable the PLL */ + rcc_pll_on(); + /* Configure the PLL to the divisor we want */ + rcc_change_pll_divisor(pll_div400); + } else { + /* We are running off a raw clock */ + switch (src) { + case OSCSRC_PIOSC: + lm4f_rcc_sysclk_freq = 16000000; + break; + case OSCSRC_PIOSC_D4: + lm4f_rcc_sysclk_freq = 4000000; + break; + case OSCSRC_MOSC: + lm4f_rcc_sysclk_freq = xtal_to_freq(xtal); + break; + case OSCSRC_32K_EXT: + lm4f_rcc_sysclk_freq = 32768; + break; + case OSCSRC_30K_INT: /* Fall through. */ + default: + /* + * We either are running off the internal 30KHz + * oscillator, which is +- 50% imprecise, or we got a + * bad osc_src parameter. + */ + lm4f_rcc_sysclk_freq = 0; + } + } + +} + +/** + * @} + * @} + */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/systemcontrol.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/systemcontrol.c new file mode 100644 index 00000000..c2993b91 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/systemcontrol.c @@ -0,0 +1,40 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/** + * \brief Enable the clock source for the peripheral + * + * @param[in] periph peripheral and clock type to enable @see lm4f_clken + */ +void periph_clock_enable(enum lm4f_clken periph) +{ + MMIO32(SYSCTL_BASE + (periph >> 5)) |= 1 << (periph & 0x1f); +} + +/** + * \brief Disable the clock source for the peripheral + * + * @param[in] periph peripheral and clock type to enable @see lm4f_clken + */ +void periph_clock_disable(enum lm4f_clken periph) +{ + MMIO32(SYSCTL_BASE + (periph >> 5)) &= ~(1 << (periph & 0x1f)); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/uart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/uart.c new file mode 100644 index 00000000..f37907b4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/uart.c @@ -0,0 +1,627 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** + * @defgroup uart_file UART + * + * @ingroup LM4Fxx + * + * @author @htmlonly © @endhtmlonly 2013 Alexandru Gagniuc + * + * \brief libopencm3 LM4F Universal Asynchronous Receiver Transmitter + * + * The LM4F UART API provides functionality for accessing the UART hardware of + * the LM4F. + * + * Please see the individual UART modules for more details. To use the UART, the + * uart.h header needs to be included: + * @code{.c} + * #include + * @endcode + * + * @{ + */ + +#include +#include +#include + +/** @defgroup uart_config UART configuration + * @ingroup uart_file + * + * \brief Enabling and configuring the UART + * + * Enabling the UART is a two step process. The GPIO on which the UART resides + * must be enabled, and the UART pins must be configured as alternate function, + * digital pins. Pins must also be muxed to the appropriate alternate function. + * This is done with the GPIO API. + * + * The second step involves enabling and the UART itself. The UART should be + * disabled while it is being configured. + * -# The UART clock must be enabled with @ref periph_clock_enable(). + * -# The UART must be disabled with @ref uart_disable(). + * -# The UART clock source should be chosen before setting the baudrate. + * -# Baudrate, data bits, stop bit length, and parity can be configured. + * -# If needed, enable CTS or RTS lines via the @ref uart_set_flow_control(). + * -# The UART can now be enabled with @ref uart_enable(). + * + * For example, to enable UART1 at 115200 8n1 with hardware flow control: + * @code{.c} + * // Enable the UART clock + * periph_clock_enable(RCC_UART1); + * // We need a brief delay before we can access UART config registers + * __asm__("nop"); __asm__("nop"); __asm__("nop"); + * // Disable the UART while we mess with its settings + * uart_disable(UART1); + * // Configure the UART clock source as precision internal oscillator + * uart_clock_from_piosc(); + * // Set communication parameters + * uart_set_baudrate(UART1, 115200); + * uart_set_databits(UART1, 8); + * uart_set_parity(UART1, UART_PARITY_NONE); + * uart_set_stopbits(UART1, 1); + * // Enable RTC and CTS lines + * uart_set_flow_control(UART1, UART_FLOWCTL_HARD_RTS_CTS); + * // Now that we're done messing with the settings, enable the UART + * uart_enable(UART1); + * @endcode + */ +/**@{*/ +/** + * \brief Enable the UART + * + * Enable the UART. The Rx and Tx lines are also enabled. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_enable(uint32_t uart) +{ + UART_CTL(uart) |= (UART_CTL_UARTEN | UART_CTL_RXE | UART_CTL_TXE); +} + +/** + * \brief Disable the UART + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_disable(uint32_t uart) +{ + UART_CTL(uart) &= ~UART_CTL_UARTEN; +} + +/** + * \brief Set UART baudrate + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] baud Baud rate in bits per second (bps).* + */ +void uart_set_baudrate(uint32_t uart, uint32_t baud) +{ + uint32_t clock; + + /* Are we running off the internal clock or system clock? */ + if (UART_CC(uart) == UART_CC_CS_PIOSC) { + clock = 16000000; + } else { + clock = rcc_get_system_clock_frequency(); + } + + /* Find the baudrate divisor */ + uint32_t div = (((clock * 8) / baud) + 1) / 2; + + /* Set the baudrate divisors */ + UART_IBRD(uart) = div / 64; + UART_FBRD(uart) = div % 64; +} + +/** + * \brief Set UART databits + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] databits number of data bits per transmission. + */ +void uart_set_databits(uint32_t uart, uint8_t databits) +{ + uint32_t reg32, bitint32_t; + + /* This has the same effect as using UART_LCRH_WLEN_5/6/7/8 directly */ + bitint32_t = (databits - 5) << 5; + + /* TODO: What about 9 data bits? */ + + reg32 = UART_LCRH(uart); + reg32 &= ~UART_LCRH_WLEN_MASK; + reg32 |= bitint32_t; + UART_LCRH(uart) = reg32; +} + +/** + * \brief Set UART stopbits + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] bits the requested number of stopbits, either 1 or 2. + */ +void uart_set_stopbits(uint32_t uart, uint8_t stopbits) +{ + if (stopbits == 2) { + UART_LCRH(uart) |= UART_LCRH_STP2; + } else { + UART_LCRH(uart) &= ~UART_LCRH_STP2; + } +} + +/** + * \brief Set UART parity + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] bits the requested parity scheme. + */ +void uart_set_parity(uint32_t uart, enum uart_parity parity) +{ + uint32_t reg32; + + reg32 = UART_LCRH(uart); + reg32 |= UART_LCRH_PEN; + reg32 &= ~(UART_LCRH_SPS | UART_LCRH_EPS); + + switch (parity) { + case UART_PARITY_NONE: + /* Once we disable parity the other bits are meaningless */ + UART_LCRH(uart) &= ~UART_LCRH_PEN; + return; + case UART_PARITY_ODD: + break; + case UART_PARITY_EVEN: + reg32 |= UART_LCRH_EPS; + break; + case UART_PARITY_STICK_0: + reg32 |= (UART_LCRH_SPS | UART_LCRH_EPS); + break; + case UART_PARITY_STICK_1: + reg32 |= UART_LCRH_SPS; + break; + } + + UART_LCRH(uart) = reg32; +} + +/** + * \brief Set the flow control scheme + * + * Set the flow control scheme by enabling or disabling RTS and CTS lines. This + * will only have effect if the given UART supports the RTS and CTS lines. + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] flow The flow control scheme to use (none, RTS, CTS or both) \n + * UART_FLOWCTL_RTS -- enable the RTS line \n + * UART_FLOWCTL_CTS -- enable the CTS line \n + * UART_FLOWCTL_RTS_CTS -- enable both RTS and CTS lines + */ +void uart_set_flow_control(uint32_t uart, enum uart_flowctl flow) +{ + uint32_t reg32 = UART_CTL(uart); + + reg32 &= ~(UART_CTL_RTSEN | UART_CTL_CTSEN); + + if (flow == UART_FLOWCTL_RTS) { + reg32 |= UART_CTL_RTSEN; + } else if (flow == UART_FLOWCTL_CTS) { + reg32 |= UART_CTL_CTSEN; + } else if (flow == UART_FLOWCTL_RTS_CTS) { + reg32 |= (UART_CTL_RTSEN | UART_CTL_CTSEN); + } + + UART_CTL(uart) = reg32; +} + +/** + * \brief Clock the UART module from the internal oscillator + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_clock_from_piosc(uint32_t uart) +{ + UART_CC(uart) = UART_CC_CS_PIOSC; +} + +/** + * \brief Clock the UART module from the system clock + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_clock_from_sysclk(uint32_t uart) +{ + UART_CC(uart) = UART_CC_CS_SYSCLK; +} +/**@}*/ + +/** @defgroup uart_send_recv UART transmission and reception + * @ingroup uart_file + * + * \brief Sending and receiving data through the UART + * + * Primitives for sending and receiving data are provided, @ref uart_send() and + * @ref uart_recv(). These primitives do not check if data can be transmitted + * or wait for data. If waiting until data is available or can be transmitted is + * desired, blocking primitives are also available, @ref uart_send_blocking() + * and @ref uart_recv_blocking(). + * + * These primitives only handle one byte at at time, and thus may be unsuited + * for some applications. You may also consider using @ref uart_dma. + */ +/**@{*/ +/** + * \brief UART Send a Data Word. + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] data data to send. + */ +void uart_send(uint32_t uart, uint16_t data) +{ + data &= 0xFF; + UART_DR(uart) = data; +} + +/** + * \brief UART Read a Received Data Word. + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @return data from the Rx FIFO. + */ +uint16_t uart_recv(uint32_t uart) +{ + return UART_DR(uart) & UART_DR_DATA_MASK; +} + +/** + * \brief UART Wait for Transmit Data Buffer Not Full + * + * Blocks until the transmit data FIFO is not empty and can accept the next data + * word. + * \n + * Even if the FIFO is not empty, this function will return as long as there is + * room for at least one more word. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_wait_send_ready(uint32_t uart) +{ + /* Wait until the Tx FIFO is no longer full */ + while (UART_FR(uart) & UART_FR_TXFF); +} + +/** + * \brief UART Wait for Received Data Available + * + * Blocks until the receive data FIFO holds a at least valid received data word. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_wait_recv_ready(uint32_t uart) +{ + /* Wait until the Tx FIFO is no longer empty */ + while (UART_FR(uart) & UART_FR_RXFE); +} + +/** + * \brief UART Send Data Word with Blocking + * + * Blocks until the transmit data FIFO can accept the next data word for + * transmission. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_send_blocking(uint32_t uart, uint16_t data) +{ + uart_wait_send_ready(uart); + uart_send(uart, data); +} + +/** + * \brief UART Read a Received Data Word with Blocking. + * + * Wait until a data word has been received then return the word. + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @return data from the Rx FIFO. + */ +uint16_t uart_recv_blocking(uint32_t uart) +{ + uart_wait_recv_ready(uart); + return uart_recv(uart); +} +/**@}*/ + +/** @defgroup uart_irq UART Interrupt control + * @ingroup uart_file + * + * \brief Configuring interrupts from the UART + * + * To have an event generate an interrupt, its interrupt source must be + * unmasked. This can be achieved with @ref uart_enable_interrupts(). Interrupts + * which are no longer needed can be disabled through + * @ref uart_disable_interrupts(). + * + * In order for the interrupt to generate an IRQ and a call to the interrupt + * service routine, the interrupt for the target UART must be routed through the + * NVIC with @ref nvic_enable_irq(). For this last step, the nvic.h header is + * needed: + * @code{.c} + * #include + * @endcode + * + * Enabling an interrupt is as simple as unmasking the desired interrupt, and + * routing the desired UART's interrupt through the NVIC. + * @code{.c} + * // Unmask receive interrupt + * uart_enable_rx_interrupt(UART0); + * // Make sure the interrupt is routed through the NVIC + * nvic_enable_irq(NVIC_UART0_IRQ); + * @endcode + * + * If a more than one interrupt is to be enabled at one time, the interrupts + * can be enabled by a single call to @ref uart_enable_interrupts(). + * For example: + * @code{.c} + * // Unmask receive, CTS, and RI, interrupts + * uart_enable_interrupts(UART0, UART_INT_RX | UART_INT_RI | UART_INT_CTS); + * @endcode + * + * After interrupts are properly enabled and routed through the NVIC, when an + * event occurs, the appropriate IRQ flag is set by hardware, and execution + * jumps to the UART ISR. The ISR should query the IRQ flags to determine which + * event caused the interrupt. For this, use @ref uart_is_interrupt_source(), + * with the desired UART_INT flag. After one or more interrupt sources are + * serviced, the IRQ flags must be cleared by the ISR. This can be done with + * @ref uart_clear_interrupt_flag(). + * + * A typical UART ISR may look like the following: + * @code{.c} + * void uart0_isr(void) + * { + * uint32_t serviced_irqs = 0; + * + * // Process individual IRQs + * if (uart_is_interrupt_source(UART0, UART_INT_RX)) { + * process_rx_event(); + * serviced_irq |= UART_INT_RX; + * } + * if (uart_is_interrupt_source(UART0, UART_INT_CTS)) { + * process_cts_event(); + * serviced_irq |= UART_INT_CTS; + * } + * + * // Clear the interrupt flag for the processed IRQs + * uart_clear_interrupt_flag(UART0, serviced_irqs); + * } + * @endcode + */ +/**@{*/ +/** + * \brief Enable Specific UART Interrupts + * + * Enable any combination of interrupts. Interrupts may be OR'ed together to + * enable them with one call. For example, to enable both the RX and CTS + * interrupts, pass (UART_INT_RX | UART_INT_CTS) + * + * Note that the NVIC must be enabled and properly configured for the interrupt + * to be routed to the CPU. + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] ints Interrupts which to enable. Any combination of interrupts may + * be specified by OR'ing then together + */ +void uart_enable_interrupts(uint32_t uart, enum uart_interrupt_flag ints) +{ + UART_IM(uart) |= ints; +} + +/** + * \brief Enable Specific UART Interrupts + * + * Disabe any combination of interrupts. Interrupts may be OR'ed together to + * disable them with one call. For example, to disable both the RX and CTS + * interrupts, pass (UART_INT_RX | UART_INT_CTS) + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] ints Interrupts which to disable. Any combination of interrupts + * may be specified by OR'ing then together + */ +void uart_disable_interrupts(uint32_t uart, enum uart_interrupt_flag ints) +{ + UART_IM(uart) &= ~ints; +} + +/** + * \brief Enable the UART Receive Interrupt. + * + * Note that the NVIC must be enabled and properly configured for the interrupt + * to be routed to the CPU. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_enable_rx_interrupt(uint32_t uart) +{ + uart_enable_interrupts(uart, UART_INT_RX); +} + +/** + * \brief Disable the UART Receive Interrupt. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_disable_rx_interrupt(uint32_t uart) +{ + uart_disable_interrupts(uart, UART_INT_RX); +} + +/** + * \brief Enable the UART Transmit Interrupt. + * + * Note that the NVIC must be enabled and properly configured for the interrupt + * to be routed to the CPU. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_enable_tx_interrupt(uint32_t uart) +{ + uart_enable_interrupts(uart, UART_INT_TX); +} + +/** + * \brief Disable the UART Transmit Interrupt. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_disable_tx_interrupt(uint32_t uart) +{ + uart_disable_interrupts(uart, UART_INT_TX); +} + +/** + * \brief Mark interrupt as serviced + * + * After an interrupt is services, its flag must be cleared. If the flag is not + * cleared, then execution will jump back to the start of the ISR after the ISR + * returns. + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] ints Interrupts which to clear. Any combination of interrupts may + * be specified by OR'ing then together + */ +void uart_clear_interrupt_flag(uint32_t uart, enum uart_interrupt_flag ints) +{ + UART_ICR(uart) |= ints; +} +/**@}*/ + +/** @defgroup uart_dma UART DMA control + * @ingroup uart_file + * + * \brief Enabling Direct Memory Access transfers for the UART + * + */ +/**@{*/ + +/** + * \brief Enable the UART Receive DMA. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_enable_rx_dma(uint32_t uart) +{ + UART_DMACTL(uart) |= UART_DMACTL_RXDMAE; +} + +/** + * \brief Disable the UART Receive DMA. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_disable_rx_dma(uint32_t uart) +{ + UART_DMACTL(uart) &= ~UART_DMACTL_RXDMAE; +} + +/** + * \brief Enable the UART Transmit DMA. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_enable_tx_dma(uint32_t uart) +{ + UART_DMACTL(uart) |= UART_DMACTL_TXDMAE; +} + +/** + * \brief Disable the UART Transmit DMA. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_disable_tx_dma(uint32_t uart) +{ + UART_DMACTL(uart) &= ~UART_DMACTL_TXDMAE; +} +/**@}*/ + +/** @defgroup uart_fifo UART FIFO control + * @ingroup uart_file + * + * \brief Enabling and controlling UART FIFO + * + * The UART on the LM4F can either be used with a single character TX and RX + * buffer, or with a 8 character TX and RX FIFO. In order to use the FIFO it + * must be enabled, this is done with uart_enable_fifo() and can be disabled + * again with uart_disable_fifo(). On reset the FIFO is disabled, and it must + * be explicitly be enabled. + * + * When enabling the UART FIFOs, RX and TX interrupts are triggered according + * to the amount of data in the FIFOs. For the RX FIFO the trigger level is + * defined by how full the FIFO is. The TX FIFO trigger level is defined by + * how empty the FIFO is instead. + * + * For example, to enable the FIFOs and trigger interrupts for a single + * received and single transmitted character: + * @code{.c} + * uart_enable_fifo(UART0); + * uart_set_fifo_trigger_levels(UART0, UART_FIFO_RX_TRIG_1_8, + * UART_FIFO_TX_TRIG_7_8); + * @endcode + */ +/**@{*/ + +/** + * \brief Enable FIFO for the UART. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_enable_fifo(uint32_t uart) +{ + UART_LCRH(uart) |= UART_LCRH_FEN; +} + +/** + * \brief Disable FIFO for the UART. + * + * @param[in] uart UART block register address base @ref uart_reg_base + */ +void uart_disable_fifo(uint32_t uart) +{ + UART_LCRH(uart) &= ~UART_LCRH_FEN; +} + +/** + * \brief Set the FIFO trigger levels. + * + * @param[in] uart UART block register address base @ref uart_reg_base + * @param[in] rx_level Trigger level for RX FIFO + * @param[in] tx_level Trigger level for TX FIFO + */ +void uart_set_fifo_trigger_levels(uint32_t uart, + enum uart_fifo_rx_trigger_level rx_level, + enum uart_fifo_tx_trigger_level tx_level) +{ + UART_IFLS(uart) = rx_level | tx_level; +} +/**@}*/ + + +/** + * @} + */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/vector_chipset.c new file mode 100644 index 00000000..894fded7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lm4f/vector_chipset.c @@ -0,0 +1,24 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +static void pre_main(void) +{ + /* Enable FPU */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/Makefile new file mode 100644 index 00000000..5b6ec485 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/Makefile @@ -0,0 +1,42 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_lpc13xx +SRCLIBDIR ?= .. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DLPC13XX +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio.o + +VPATH += ../cm3 + +include ../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/gpio.c new file mode 100644 index 00000000..271572b5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/gpio.c @@ -0,0 +1,42 @@ +/** @defgroup gpio_file GPIO + +@ingroup LPC13xx + +@brief libopencm3 LPC13xx General Purpose I/O + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +void gpio_set(uint32_t gpioport, uint16_t gpios) +{ + GPIO_DATA(gpioport) = gpios; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/libopencm3_lpc13xx.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/libopencm3_lpc13xx.ld new file mode 100644 index 00000000..bd0005c7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc13xx/libopencm3_lpc13xx.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for LPC13XX targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/Makefile new file mode 100644 index 00000000..5a34606e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/Makefile @@ -0,0 +1,42 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_lpc17xx +SRCLIBDIR ?= .. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DLPC17XX +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio.o pwr.o + +VPATH += ../cm3 + +include ../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/gpio.c new file mode 100644 index 00000000..4831af7f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/gpio.c @@ -0,0 +1,48 @@ +/** @defgroup gpio_file GPIO + +@ingroup LPC17xx + +@brief libopencm3 LPC17xx General Purpose I/O + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +void gpio_set(uint32_t gpioport, uint32_t gpios) +{ + GPIO_SET(gpioport) = gpios; +} + +void gpio_clear(uint32_t gpioport, uint32_t gpios) +{ + GPIO_CLR(gpioport) = gpios; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/libopencm3_lpc17xx.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/libopencm3_lpc17xx.ld new file mode 100644 index 00000000..a122ea93 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/libopencm3_lpc17xx.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for LPC17XX targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/pwr.c new file mode 100644 index 00000000..cbe794ce --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc17xx/pwr.c @@ -0,0 +1,48 @@ +/** @defgroup pwr-file PWR + +@ingroup LPC17xx + +@brief libopencm3 LPC17xx Power Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2013 Silvio Gissi + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Silvio Gissi + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +void pwr_enable_peripherals(uint32_t peripherals) +{ + PWR_PCONP |= peripherals; +} + +void pwr_disable_peripherals(uint32_t peripherals) +{ + PWR_PCONP &= ~peripherals; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/gpio.c new file mode 100644 index 00000000..935feb31 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/gpio.c @@ -0,0 +1,53 @@ +/** @defgroup gpio_file GPIO + +@ingroup LPC43xx + +@brief libopencm3 LPC43xx General Purpose I/O + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +void gpio_set(uint32_t gpioport, uint32_t gpios) +{ + GPIO_SET(gpioport) = gpios; +} + +void gpio_clear(uint32_t gpioport, uint32_t gpios) +{ + GPIO_CLR(gpioport) = gpios; +} + +void gpio_toggle(uint32_t gpioport, uint32_t gpios) +{ + GPIO_NOT(gpioport) = gpios; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/i2c.c new file mode 100644 index 00000000..0d6c4c67 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/i2c.c @@ -0,0 +1,102 @@ +/** @defgroup i2c_file I2C + +@ingroup LPC43xx + +@brief libopencm3 LPC43xx I2C + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Michael Ossmann + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * This is a very minimal I2C driver just to make sure we can get the + * peripheral working. + */ + +/**@{*/ + +#include +#include +#include + +void i2c0_init(const uint16_t duty_cycle_count) +{ + /* enable input on SCL and SDA pins */ + SCU_SFSI2C0 = SCU_I2C0_NOMINAL; + + I2C0_SCLH = duty_cycle_count; + I2C0_SCLL = duty_cycle_count; + + /* clear the control bits */ + I2C0_CONCLR = (I2C_CONCLR_AAC | I2C_CONCLR_SIC + | I2C_CONCLR_STAC | I2C_CONCLR_I2ENC); + + /* enable I2C0 */ + I2C0_CONSET = I2C_CONSET_I2EN; +} + +/* transmit start bit */ +void i2c0_tx_start(void) +{ + I2C0_CONCLR = I2C_CONCLR_SIC; + I2C0_CONSET = I2C_CONSET_STA; + while (!(I2C0_CONSET & I2C_CONSET_SI)); + I2C0_CONCLR = I2C_CONCLR_STAC; +} + +/* transmit data byte */ +void i2c0_tx_byte(uint8_t byte) +{ + if (I2C0_CONSET & I2C_CONSET_STA) { + I2C0_CONCLR = I2C_CONCLR_STAC; + } + I2C0_DAT = byte; + I2C0_CONCLR = I2C_CONCLR_SIC; + while (!(I2C0_CONSET & I2C_CONSET_SI)); +} + +/* receive data byte */ +uint8_t i2c0_rx_byte(void) +{ + if (I2C0_CONSET & I2C_CONSET_STA) { + I2C0_CONCLR = I2C_CONCLR_STAC; + } + I2C0_CONCLR = I2C_CONCLR_SIC; + while (!(I2C0_CONSET & I2C_CONSET_SI)); + return I2C0_DAT; +} + +/* transmit stop bit */ +void i2c0_stop(void) +{ + if (I2C0_CONSET & I2C_CONSET_STA) { + I2C0_CONCLR = I2C_CONCLR_STAC; + } + I2C0_CONSET = I2C_CONSET_STO; + I2C0_CONCLR = I2C_CONCLR_SIC; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ipc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ipc.c new file mode 100644 index 00000000..c26931f2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ipc.c @@ -0,0 +1,58 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* This library is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This library 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this library. If not, see . +*/ + +#include +#include +#include + +/* Set M0 in reset mode */ +void ipc_halt_m0(void) +{ + volatile uint32_t rst_active_status1; + + /* Check if M0 is reset by reading status */ + rst_active_status1 = RESET_ACTIVE_STATUS1; + + /* If the M0 has reset not asserted, halt it... */ + while (rst_active_status1 & RESET_CTRL1_M0APP_RST) { + RESET_CTRL1 = ((~rst_active_status1) | RESET_CTRL1_M0APP_RST); + rst_active_status1 = RESET_ACTIVE_STATUS1; + } +} + +void ipc_start_m0(uint32_t cm0_baseaddr) +{ + volatile uint32_t rst_active_status1; + + /* Set M0 memory mapping to point to start of M0 image */ + CREG_M0APPMEMMAP = cm0_baseaddr; + + /* Start/run M0 core */ + + /* Release Slave from reset, first read status */ + rst_active_status1 = RESET_ACTIVE_STATUS1; + + /* If the M0 is being held in reset, release it */ + /* 1 = no reset, 0 = reset */ + while (!(rst_active_status1 & RESET_CTRL1_M0APP_RST)) { + RESET_CTRL1 = ((~rst_active_status1) & ~RESET_CTRL1_M0APP_RST); + rst_active_status1 = RESET_ACTIVE_STATUS1; + } +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/Makefile new file mode 100644 index 00000000..e05b799c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/Makefile @@ -0,0 +1,45 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 Michael Ossmann +## Copyright (C) 2012/2013 Benjamin Vernoux +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_lpc43xx_m0 +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -O2 -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m0 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DLPC43XX -DLPC43XX_M0 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs + +# LPC43xx common files for M4 / M0 +OBJ_LPC43XX = gpio.o scu.o i2c.o ssp.o uart.o timer.o + +#LPC43xx M0 specific file + Generic LPC43xx M4/M0 files +OBJS = $(OBJ_LPC43XX) + +VPATH += ../:../../cm3 + +include ../../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld new file mode 100644 index 00000000..e69de29b diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld new file mode 100644 index 00000000..fedd3e1d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld @@ -0,0 +1,96 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * Copyright (C) 2012 Jared Boone + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for LPC43XX targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + . = ORIGIN(ram_ahb2); + + .text : { + . = ALIGN(0x400); + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >ram_ahb2 + + /* exception index - required due to libgcc.a issuing /0 exceptions */ + __exidx_start = .; + .ARM.exidx : { + *(.ARM.exidx*) + } > ram_ahb2 + __exidx_end = .; + + _etext = .; + + . = ORIGIN(ram_ahb2); + + .data : { + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + } >ram_ahb2 + + _data = .; + _edata = .; + + .bss : { + _bss = .; + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram_ahb2 + + /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ + .ARM.extab : { + *(.ARM.extab*) + } >ram_ahb2 + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support - discard it for now. + */ + /DISCARD/ : { *(.ARM.exidx) } + + end = .; + + /* Leave room above stack for IAP to run. */ + __StackTop = ORIGIN(ram_ahb2) + LENGTH(ram_ahb2) - 32; + PROVIDE(_stack = __StackTop); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/Makefile new file mode 100644 index 00000000..4c022f92 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/Makefile @@ -0,0 +1,52 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 Michael Ossmann +## Copyright (C) 2012 Benjamin Vernoux +## Copyright (C) 2013 Alexandru Gagniuc +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_lpc43xx +SRCLIBDIR ?= ../.. + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -O2 \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m4 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD \ + $(FP_FLAGS) -DLPC43XX -DLPC43XX_M4 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) + +ARFLAGS = rcs + +# LPC43xx common files for M4 / M0 +OBJ_LPC43XX = gpio.o scu.o i2c.o ssp.o uart.o timer.o + +#LPC43xx M4 specific file + Generic LPC43xx M4/M0 files +OBJS = $(OBJ_LPC43XX) ipc.o + +VPATH += ../:../../cm3 + +include ../../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld new file mode 100644 index 00000000..c289b351 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx.ld @@ -0,0 +1,127 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * Copyright (C) 2012 Jared Boone + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for LPC43XX targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + . = ALIGN(0x400); + _text_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + + /* exception index - required due to libgcc.a issuing /0 exceptions */ + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + _etext_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + _etext_rom = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + + . = ORIGIN(ram_local2); + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram_local2 AT >rom + _data_loadaddr = LOADADDR(.data); + + _data_rom = LOADADDR (.data) + ORIGIN(rom); + _edata_rom = _data_rom + SIZEOF (.data); + + .bss : { + _bss = .; + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram_local2 + + /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ + .ARM.extab : { + *(.ARM.extab*) + } >ram_local2 + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; + + /* Leave room above stack for IAP to run. */ + __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32; + PROVIDE(_stack = __StackTop); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld new file mode 100644 index 00000000..5bcdea61 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld @@ -0,0 +1,139 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * Copyright (C) 2012 Jared Boone + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for LPC43XX targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + . = ORIGIN(ram_local1); + + .text : { + . = ALIGN(0x400); + _text_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >ram_local1 + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >ram_local1 + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >ram_local1 + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >ram_local1 + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >ram_local1 + + /* exception index - required due to libgcc.a issuing /0 exceptions */ + __exidx_start = .; + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > ram_local1 + + . = ALIGN(4); + _etext = .; + _etext_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + _etext_rom = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + + . = ORIGIN(ram_local2); + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram_local2 + _data_loadaddr = LOADADDR(.data); + + /* Running from RAM only, loading the .elf will initialize data for us. */ + _data_rom = .; + _edata_rom = .; + + _data = .; + _edata = .; + + .bss : { + _bss = .; + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram_local2 + + /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ + .ARM.extab : { + *(.ARM.extab*) + } >ram_local2 + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support - discard it for now. + */ + /DISCARD/ : { *(.ARM.exidx) } + + end = .; + + /* Leave room above stack for IAP to run. */ + __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32; + PROVIDE(_stack = __StackTop); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld new file mode 100644 index 00000000..e50040eb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld @@ -0,0 +1,128 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * Copyright (C) 2012 Jared Boone + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for LPC43XX targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + . = ALIGN(0x400); + _text_ram = (. - ORIGIN(rom)) + ORIGIN(ram_local1); /* Start of Code in RAM */ + + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + + /* exception index - required due to libgcc.a issuing /0 exceptions */ + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + _etext_ram = (. - ORIGIN(rom)) + ORIGIN(ram_local1); + _etext_rom = (. - ORIGIN(rom)) + ORIGIN(rom_flash); + + . = ORIGIN(ram_local2); + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram_local2 AT >rom + _data_loadaddr = LOADADDR(.data); + + _data_rom = LOADADDR (.data) + ORIGIN(rom_flash); + _edata_rom = _data_rom + SIZEOF (.data); + + .bss : { + _bss = .; + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram_local2 + + /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ + .ARM.extab : { + *(.ARM.extab*) + } >ram_local2 + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; + + /* Leave room above stack for IAP to run. */ + __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32; + PROVIDE(_stack = __StackTop); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/vector_chipset.c new file mode 100644 index 00000000..270e30ea --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/m4/vector_chipset.c @@ -0,0 +1,48 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2012 Michael Ossmann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +extern unsigned _etext_ram, _text_ram, _etext_rom; + +#define CREG_M4MEMMAP MMIO32((0x40043000U + 0x100)) + +static void pre_main(void) +{ + volatile unsigned *src, *dest; + + /* Copy the code from ROM to Real RAM (if enabled) */ + if ((&_etext_ram-&_text_ram) > 0) { + src = &_etext_rom-(&_etext_ram-&_text_ram); + /* Change Shadow memory to ROM (for Debug Purpose in case Boot + * has not set correctly the M4MEMMAP because of debug) + */ + CREG_M4MEMMAP = (unsigned long)src; + + for (dest = &_text_ram; dest < &_etext_ram; ) { + *dest++ = *src++; + } + + /* Change Shadow memory to Real RAM */ + CREG_M4MEMMAP = (unsigned long)&_text_ram; + + /* Continue Execution in RAM */ + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/scu.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/scu.c new file mode 100644 index 00000000..c20cd840 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/scu.c @@ -0,0 +1,52 @@ +/** @defgroup scu_file System Control Unit + +@ingroup LPC43xx + +@brief libopencm3 LPC43xx System Control Unit + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Benjamin Vernoux + +LGPL License Terms @ref lgpl_license +*/ + +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* This library is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This library 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this library. If not, see . +*/ + +/**@{*/ + +#include + +/* For pin_conf_normal value see scu.h define SCU_CONF_XXX or Configuration for + * different I/O pins types + */ +void scu_pinmux(scu_grp_pin_t group_pin, uint32_t scu_conf) +{ + MMIO32(group_pin) = scu_conf; +} + +/* For other special SCU register USB1, I2C0, ADC0/1, DAC, EMC clock delay See + * scu.h + */ + +/* For Pin interrupt select register see scu.h SCU_PINTSEL0 & SCU_PINTSEL1 */ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ssp.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ssp.c new file mode 100644 index 00000000..b63ec9bd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/ssp.c @@ -0,0 +1,140 @@ +/** @defgroup ssp_file SSP + +@ingroup LPC43xx + +@brief libopencm3 LPC43xx SSP + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Benjamin Vernoux + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Benjamin Vernoux + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/* Disable SSP */ +void ssp_disable(ssp_num_t ssp_num) +{ + uint32_t ssp_port; + + if (ssp_num == SSP0_NUM) { + ssp_port = SSP0; + } else { + ssp_port = SSP1; + } + /* Disable SSP */ + SSP_CR1(ssp_port) = 0x0; +} + +/* +* SSP Init function +*/ +void ssp_init(ssp_num_t ssp_num, + ssp_datasize_t data_size, + ssp_frame_format_t frame_format, + ssp_cpol_cpha_t cpol_cpha_format, + uint8_t serial_clock_rate, + uint8_t clk_prescale, + ssp_mode_t mode, + ssp_master_slave_t master_slave, + ssp_slave_option_t slave_option) +{ + uint32_t ssp_port; + uint32_t clock; + + if (ssp_num == SSP0_NUM) { + ssp_port = SSP0; + } else { + ssp_port = SSP1; + } + + /* use PLL1 as clock source for SSP1 */ + CGU_BASE_SSP1_CLK = + CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1) + | CGU_BASE_SSP1_CLK_AUTOBLOCK; + + /* Disable SSP before to configure it */ + SSP_CR1(ssp_port) = 0x0; + + /* Configure SSP */ + clock = serial_clock_rate; + SSP_CPSR(ssp_port) = clk_prescale; + SSP_CR0(ssp_port) = + (data_size | frame_format | cpol_cpha_format | (clock<<8)); + + /* Enable SSP */ + SSP_CR1(ssp_port) = (SSP_ENABLE | mode | master_slave | slave_option); +} + +static void ssp_wait_until_not_busy(ssp_num_t ssp_num) +{ + uint32_t ssp_port; + + if (ssp_num == SSP0_NUM) { + ssp_port = SSP0; + } else { + ssp_port = SSP1; + } + + while ((SSP_SR(ssp_port) & SSP_SR_BSY)); +} + +/* This Function Wait Data TX Ready, and Write Data to SSP */ +uint16_t ssp_transfer(ssp_num_t ssp_num, uint16_t data) +{ + uint32_t ssp_port; + + if (ssp_num == SSP0_NUM) { + ssp_port = SSP0; + } else { + ssp_port = SSP1; + } + + /* Wait Until FIFO not full */ + while ((SSP_SR(ssp_port) & SSP_SR_TNF) == 0); + + SSP_DR(ssp_port) = data; + + /* Wait for not busy, since we're controlling CS# of + * devices manually and need to wait for the data to + * be sent. It may also be important to wait here + * in case we're configuring devices via SPI and also + * with GPIO control -- we need to know when SPI + * commands are effective before altering a device's + * state with GPIO. I'm thinking the MAX2837, for + * example... + */ + ssp_wait_until_not_busy(ssp_num); + + /* Wait Until Data Received (Rx FIFO not Empty) */ + while ((SSP_SR(ssp_port) & SSP_SR_RNE) == 0); + + return SSP_DR(ssp_port); +} + + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/timer.c new file mode 100644 index 00000000..f263c24a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/timer.c @@ -0,0 +1,72 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Ben Gamari + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + * This provides the code for the "next gen" EXTI block provided in F2/F4/L1 + * devices. (differences only in the source selection) + */ + +#include + +void timer_reset(uint32_t timer_peripheral) +{ + TIMER_TCR(timer_peripheral) |= TIMER_TCR_CRST; + TIMER_TCR(timer_peripheral) &= ~TIMER_TCR_CRST; +} + +void timer_enable_counter(uint32_t timer_peripheral) +{ + TIMER_TCR(timer_peripheral) |= TIMER_TCR_CEN; +} + +void timer_disable_counter(uint32_t timer_peripheral) +{ + TIMER_TCR(timer_peripheral) &= ~TIMER_TCR_CEN; +} + +void timer_set_counter(uint32_t timer_peripheral, uint32_t count) +{ + TIMER_TC(timer_peripheral) = count; +} + +uint32_t timer_get_counter(uint32_t timer_peripheral) +{ + return TIMER_TC(timer_peripheral); +} + +uint32_t timer_get_prescaler(uint32_t timer_peripheral) +{ + return TIMER_PR(timer_peripheral); +} + +void timer_set_prescaler(uint32_t timer_peripheral, uint32_t prescaler) +{ + TIMER_PR(timer_peripheral) = prescaler; +} + +void timer_set_mode(uint32_t timer_peripheral, uint32_t mode) +{ + TIMER_CTCR(timer_peripheral) = mode | + (TIMER_CTCR(timer_peripheral) & TIMER_CTCR_MODE_MASK); +} + +void timer_set_count_input(uint32_t timer_peripheral, uint32_t input) +{ + TIMER_CTCR(timer_peripheral) = input | + (TIMER_CTCR(timer_peripheral) & TIMER_CTCR_CINSEL_MASK); +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/uart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/uart.c new file mode 100644 index 00000000..3168ce20 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/lpc43xx/uart.c @@ -0,0 +1,243 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* This library is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This library 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this library. If not, see . +*/ + +#include +#include + +#define UART_SRC_32K 0x00 +#define UART_SRC_IRC 0x01 +#define UART_SRC_ENET_RX 0x02 +#define UART_SRC_ENET_TX 0x03 +#define UART_SRC_GP_CLKIN 0x04 +#define UART_SRC_XTAL 0x06 +#define UART_SRC_PLL0USB 0x07 +#define UART_SRC_PLL0AUDIO 0x08 +#define UART_SRC_PLL1 0x09 +#define UART_SRC_IDIVA 0x0C +#define UART_SRC_IDIVB 0x0D +#define UART_SRC_IDIVC 0x0E +#define UART_SRC_IDIVD 0x0F +#define UART_SRC_IDIVE 0x10 + +#define UART_CGU_AUTOBLOCK_CLOCK_BIT 11 +/* clock source selection (5 bits) */ +#define UART_CGU_BASE_CLK_SEL_SHIFT 24 + +uint32_t dummy_read; + +/* +* UART Init function +*/ +void uart_init(uart_num_t uart_num, uart_databit_t data_nb_bits, + uart_stopbit_t data_nb_stop, uart_parity_t data_parity, + uint16_t uart_divisor, uint8_t uart_divaddval, uint8_t uart_mulval) +{ + uint32_t lcr_config; + uint32_t uart_port; + + uart_port = uart_num; + + switch (uart_num) { + case UART0_NUM: + /* use PLL1 as clock source for UART0 */ + CGU_BASE_UART0_CLK = (1< 0) { + counter++; + if (counter >= rx_timeout_nb_cycles) { + *error = UART_TIMEOUT_ERROR; + return 0; + } + } + } + + uart_val = (UART_RBR(uart_port) & UART_RBR_MASKBIT); + + /* Clear error */ + *error = UART_NO_ERROR; + + return uart_val; +} + +/* This Function Wait Data TX Ready, and Write Data to UART + if rx_timeout_nb_cycles = 0 Infinite wait +*/ +void uart_write(uart_num_t uart_num, uint8_t data) +{ + uint32_t uart_port; + + uart_port = uart_num; + + /* Wait Until FIFO not full */ + while ((UART_LSR(uart_port) & UART_LSR_THRE) == 0); + + UART_THR(uart_port) = data; +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/Makefile new file mode 100644 index 00000000..7f24e228 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/Makefile @@ -0,0 +1,39 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_sam3a +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSAM3A +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio_common_all.o gpio_common_3a3u3x.o pmc.o usart.o + +VPATH += ../../usb:../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/libopencm3_sam3a.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/libopencm3_sam3a.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3a/libopencm3_sam3a.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/Makefile new file mode 100644 index 00000000..815cf037 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/Makefile @@ -0,0 +1,39 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_sam3n +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSAM3N +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio_common_all.o gpio_common_3n3s.o pmc.o usart.o + +VPATH += ../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/libopencm3_sam3n.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/libopencm3_sam3n.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3n/libopencm3_sam3n.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/Makefile new file mode 100644 index 00000000..d998bef1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/Makefile @@ -0,0 +1,40 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2014 Felix Held +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_sam3s +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSAM3S +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio_common_all.o gpio_common_3n3s.o pmc.o usart.o + +VPATH += ../../usb:../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/libopencm3_sam3s.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/libopencm3_sam3s.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3s/libopencm3_sam3s.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/Makefile new file mode 100644 index 00000000..f77bbd85 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/Makefile @@ -0,0 +1,40 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2014 Felix Held +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_sam3u +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSAM3U +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio_common_all.o gpio_common_3a3u3x.o pmc.o usart.o + +VPATH += ../../usb:../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/libopencm3_sam3u.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/libopencm3_sam3u.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3u/libopencm3_sam3u.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/Makefile new file mode 100644 index 00000000..50b99900 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/Makefile @@ -0,0 +1,39 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_sam3x +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSAM3X +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio_common_all.o gpio_common_3a3u3x.o pmc.o usart.o + +VPATH += ../../usb:../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/libopencm3_sam3x.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/libopencm3_sam3x.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/3x/libopencm3_sam3x.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3a3u3x.c b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3a3u3x.c new file mode 100644 index 00000000..0a430b4f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3a3u3x.c @@ -0,0 +1,73 @@ +/** @addtogroup gpio_defines + * + * @brief Access functions for the SAM3A/U/X I/O Controller + * @ingroup SAM3_defines + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2012 + * Gareth McMullin + * @author @htmlonly © @endhtmlonly 2014 + * Felix Held + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + +/** @brief Initialize GPIO pins + * + * @param[in] port uint32_t: GPIO Port base address + * @param[in] pin uint32_t + * @param[in] flags enum gpio_flags + */ +void gpio_init(uint32_t port, uint32_t pins, enum gpio_flags flags) +{ + switch (flags & 0x7) { + case GPIO_FLAG_GPINPUT: + PIO_ODR(port) = pins; + PIO_PER(port) = pins; + break; + case GPIO_FLAG_GPOUTPUT: + PIO_OER(port) = pins; + PIO_PER(port) = pins; + break; + case GPIO_FLAG_PERIPHA: + PIO_ABSR(port) &= ~pins; + PIO_PDR(port) = pins; + break; + case GPIO_FLAG_PERIPHB: + PIO_ABSR(port) |= pins; + PIO_PDR(port) = pins; + } + + if (flags & GPIO_FLAG_OPEN_DRAIN) { + PIO_MDER(port) = pins; + } else { + PIO_MDDR(port) = pins; + } + + if (flags & GPIO_FLAG_PULL_UP) { + PIO_PUER(port) = pins; + } else { + PIO_PUDR(port) = pins; + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3n3s.c b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3n3s.c new file mode 100644 index 00000000..034c20ff --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_3n3s.c @@ -0,0 +1,86 @@ +/** @addtogroup gpio_defines + * + * @brief Access functions for the SAM3N/S I/O Controller + * @ingroup SAM3_defines + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2012 + * Gareth McMullin + * @author @htmlonly © @endhtmlonly 2014 + * Felix Held + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + +/** @brief Initialize GPIO pins + * + * @param[in] port uint32_t: GPIO Port base address + * @param[in] pin uint32_t + * @param[in] flags enum gpio_flags + */ +void gpio_init(uint32_t port, uint32_t pins, enum gpio_flags flags) +{ + switch (flags & 0x7) { + case GPIO_FLAG_GPINPUT: + PIO_ODR(port) = pins; + PIO_PER(port) = pins; + break; + case GPIO_FLAG_GPOUTPUT: + PIO_OER(port) = pins; + PIO_PER(port) = pins; + break; + case GPIO_FLAG_PERIPHA: + PIO_ABCDSR1(port) &= ~pins; + PIO_ABCDSR2(port) &= ~pins; + PIO_PDR(port) = pins; + break; + case GPIO_FLAG_PERIPHB: + PIO_ABCDSR1(port) |= pins; + PIO_ABCDSR2(port) &= ~pins; + PIO_PDR(port) = pins; + break; + case GPIO_FLAG_PERIPHC: + PIO_ABCDSR1(port) &= ~pins; + PIO_ABCDSR2(port) |= pins; + PIO_PDR(port) = pins; + break; + case GPIO_FLAG_PERIPHD: + PIO_ABCDSR1(port) |= pins; + PIO_ABCDSR2(port) |= pins; + PIO_PDR(port) = pins; + break; + } + + if (flags & GPIO_FLAG_OPEN_DRAIN) { + PIO_MDER(port) = pins; + } else { + PIO_MDDR(port) = pins; + } + + if (flags & GPIO_FLAG_PULL_UP) { + PIO_PUER(port) = pins; + } else { + PIO_PUDR(port) = pins; + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_all.c new file mode 100644 index 00000000..a89161ec --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/gpio_common_all.c @@ -0,0 +1,66 @@ +/** @addtogroup gpio_defines + * + * @brief Access functions for the SAM3 I/O Controller + * @ingroup SAM3_defines + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2012 + * Gareth McMullin + * @author @htmlonly © @endhtmlonly 2014 + * Felix Held + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Gareth McMullin + * Copyright (C) 2014 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/** @brief Atomic set output + * + * @param[in] gpioport uint32_t: GPIO Port base address + * @param[in] gpios uint32_t + */ +void gpio_set(uint32_t gpioport, uint32_t gpios) +{ + PIO_SODR(gpioport) = gpios; +} + +/** @brief Atomic clear output + * + * @param[in] gpioport uint32_t: GPIO Port base address + * @param[in] gpios uint32_t + */ +void gpio_clear(uint32_t gpioport, uint32_t gpios) +{ + PIO_CODR(gpioport) = gpios; +} + +/** @brief Toggle output + * + * @param[in] gpioport uint32_t: GPIO Port base address + * @param[in] gpios uint32_t + */ +void gpio_toggle(uint32_t gpioport, uint32_t gpios) +{ + uint32_t odsr = PIO_ODSR(gpioport); + PIO_CODR(gpioport) = odsr & gpios; + PIO_SODR(gpioport) = ~odsr & gpios; +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/pmc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/pmc.c new file mode 100644 index 00000000..38f27d7c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/pmc.c @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/** Default peripheral clock frequency after reset. */ +uint32_t pmc_mck_frequency = 4000000; + +void pmc_xtal_enable(bool en, uint8_t startup_time) +{ + if (en) { + CKGR_MOR = (CKGR_MOR & ~CKGR_MOR_MOSCXTST_MASK) | + CKGR_MOR_KEY | CKGR_MOR_MOSCXTEN | + (startup_time << 8); + while (!(PMC_SR & PMC_SR_MOSCXTS)); + } else { + CKGR_MOR = CKGR_MOR_KEY | (CKGR_MOR & ~CKGR_MOR_MOSCXTEN); + } +} + +void pmc_plla_config(uint8_t mul, uint8_t div) +{ + CKGR_PLLAR = CKGR_PLLAR_ONE | ((mul - 1) << 16) | + CKGR_PLLAR_PLLACOUNT_MASK | div; + while (!(PMC_SR & PMC_SR_LOCKA)); +} + +void pmc_peripheral_clock_enable(uint8_t pid) +{ +#if defined(PMC_PCER1) + if (pid < 32) { + PMC_PCER0 = 1 << pid; + } else { + PMC_PCER1 = 1 << (pid & 31); + } +#else + /* SAM3N and SAM3U only have one Peripheral Clock Enable Register */ + PMC_PCER = 1 << pid; +#endif +} + +void pmc_peripheral_clock_disable(uint8_t pid) +{ +#if defined(PMC_PCER1) + if (pid < 32) { + PMC_PCDR0 = 1 << pid; + } else { + PMC_PCDR1 = 1 << (pid & 31); + } +#else + PMC_PCDR = 1 << pid; +#endif +} + +void pmc_mck_set_source(enum mck_src src) +{ + PMC_MCKR = (PMC_MCKR & ~PMC_MCKR_CSS_MASK) | src; + while (!(PMC_SR & PMC_SR_MCKRDY)); +} + +void pmc_clock_setup_in_xtal_12mhz_out_84mhz(void) +{ + eefc_set_latency(4); + + /* 12MHz external xtal, maximum possible startup time */ + pmc_xtal_enable(true, 0xff); + /* Select as main oscillator */ + CKGR_MOR |= CKGR_MOR_KEY | CKGR_MOR_MOSCSEL; + /* Multiply by 7 for 84MHz */ + pmc_plla_config(7, 1); + pmc_mck_set_source(MCK_SRC_PLLA); + + pmc_mck_frequency = 84000000; +} + +void pmc_clock_setup_in_rc_4mhz_out_84mhz(void) +{ + eefc_set_latency(4); + + /* Select as main oscillator */ + CKGR_MOR = CKGR_MOR_KEY | + (CKGR_MOR & ~(CKGR_MOR_MOSCSEL | CKGR_MOR_MOSCRCF_MASK)); + /* Multiply by 21 for 84MHz */ + pmc_plla_config(21, 1); + pmc_mck_set_source(MCK_SRC_PLLA); + + pmc_mck_frequency = 84000000; +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/usart.c new file mode 100644 index 00000000..36833f7e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/common/usart.c @@ -0,0 +1,110 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +void usart_set_baudrate(uint32_t usart, uint32_t baud) +{ + USART_BRGR(usart) = pmc_mck_frequency / (16 * baud); +} + +void usart_set_databits(uint32_t usart, int bits) +{ + USART_MR(usart) = (USART_MR(usart) & ~USART_MR_CHRL_MASK) | + ((bits - 5) << 6); +} + +void usart_set_stopbits(uint32_t usart, enum usart_stopbits sb) +{ + USART_MR(usart) = (USART_MR(usart) & ~USART_MR_NBSTOP_MASK) | + (sb << 12); +} + +void usart_set_parity(uint32_t usart, enum usart_parity par) +{ + USART_MR(usart) = (USART_MR(usart) & ~USART_MR_PAR_MASK) | (par << 9); +} + +void usart_set_mode(uint32_t usart, enum usart_mode mode) +{ + USART_CR(usart) = + (mode & USART_MODE_RX) ? USART_CR_RXEN : USART_CR_RXDIS; + USART_CR(usart) = (mode & USART_MODE_TX) ? USART_CR_TXEN + : USART_CR_TXDIS; +} + +void usart_set_flow_control(uint32_t usart, enum usart_flowcontrol fc) +{ + USART_MR(usart) = (USART_MR(usart) & ~USART_MR_MODE_MASK) | + (fc ? USART_MR_MODE_HW_HANDSHAKING : 0); +} + +void usart_enable(uint32_t usart) +{ + (void)usart; +} + +void usart_disable(uint32_t usart) +{ + (void)usart; +} + +void usart_send(uint32_t usart, uint16_t data) +{ + USART_THR(usart) = data; +} + +uint16_t usart_recv(uint32_t usart) +{ + return USART_RHR(usart) & 0x1f; +} + +void usart_wait_send_ready(uint32_t usart) +{ + while ((USART_CSR(usart) & USART_CSR_TXRDY) == 0); +} + +void usart_wait_recv_ready(uint32_t usart) +{ + while ((USART_CSR(usart) & USART_CSR_RXRDY) == 0); +} + +void usart_send_blocking(uint32_t usart, uint16_t data) +{ + usart_wait_send_ready(usart); + usart_send(usart, data); +} + +uint16_t usart_recv_blocking(uint32_t usart) +{ + usart_wait_recv_ready(usart); + + return usart_recv(usart); +} + +void usart_enable_rx_interrupt(uint32_t usart) +{ + USART_IER(usart) = USART_CSR_RXRDY; +} + +void usart_disable_rx_interrupt(uint32_t usart) +{ + USART_IDR(usart) = USART_CSR_RXRDY; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/Makefile new file mode 100644 index 00000000..0a2a5c89 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/Makefile @@ -0,0 +1,39 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2016 Karl Palsson +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_samd +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m0plus -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSAMD +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/libopencm3_samd.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/libopencm3_samd.ld new file mode 100644 index 00000000..ada86c36 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/sam/d/libopencm3_samd.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/can.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/can.c new file mode 100644 index 00000000..44a6cd65 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/can.c @@ -0,0 +1,555 @@ +/** @defgroup can_file CAN + +@ingroup STM32F_files + +@brief libopencm3 STM32Fxxx CAN + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski + +@date 12 November 2012 + +Devices can have up to two CAN peripherals. The peripherals support up to 1MBit +transmission rate. The peripheral has several filters for incoming messages that +can be distributed between two FIFOs and three transmit mailboxes. + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/* Timeout for CAN INIT acknowledge + * this value is difficult to define. + * INIT is set latest after finishing the current transfer. + * Assuming the lowest CAN speed of 100kbps one CAN frame may take about 1.6ms + * WAIT loop timeout varies on compiler switches, optimization, CPU architecture + * and CPU speed + * + * The same timeout value is used for leaving INIT where the longest time is + * 11 bits(110 us on 100 kbps). + */ +#define CAN_MSR_INAK_TIMEOUT 0x0000FFFF + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Reset + +The CAN peripheral and all its associated configuration registers are placed in +the reset condition. The reset is effective via the RCC peripheral reset +system. + +@param[in] canport Unsigned int32. CAN block register address base @ref +can_reg_base. + */ +void can_reset(uint32_t canport) +{ + if (canport == CAN1) { + rcc_periph_reset_pulse(RST_CAN1); + } else { +#if defined(BX_CAN2_BASE) + rcc_periph_reset_pulse(RST_CAN2); +#endif + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Init + +Initialize the selected CAN peripheral block. + +@param[in] canport Unsigend int32. CAN register base address @ref can_reg_base. +@param[in] ttcm bool. Time triggered communication mode. +@param[in] abom bool. Automatic bus-off management. +@param[in] awum bool. Automatic wakeup mode. +@param[in] nart bool. No automatic retransmission. +@param[in] rflm bool. Receive FIFO locked mode. +@param[in] txfp bool. Transmit FIFO priority. +@param[in] sjw Unsigned int32. Resynchronization time quanta jump width. +@param[in] ts1 Unsigned int32. Time segment 1 time quanta width. +@param[in] ts2 Unsigned int32. Time segment 2 time quanta width. +@param[in] brp Unsigned int32. Baud rate prescaler. +@returns int 0 on success, 1 on initialization failure. +*/ +int can_init(uint32_t canport, bool ttcm, bool abom, bool awum, bool nart, + bool rflm, bool txfp, uint32_t sjw, uint32_t ts1, uint32_t ts2, + uint32_t brp, bool loopback, bool silent) +{ + volatile uint32_t wait_ack; + int ret = 0; + + /* Exit from sleep mode. */ + CAN_MCR(canport) &= ~CAN_MCR_SLEEP; + + /* Request initialization "enter". */ + CAN_MCR(canport) |= CAN_MCR_INRQ; + + /* Wait for acknowledge. */ + wait_ack = CAN_MSR_INAK_TIMEOUT; + while ((--wait_ack) && + ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)); + + /* Check the acknowledge. */ + if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK) { + return 1; + } + + /* clear can timing bits */ + CAN_BTR(canport) = 0; + + /* Set the automatic bus-off management. */ + if (ttcm) { + CAN_MCR(canport) |= CAN_MCR_TTCM; + } else { + CAN_MCR(canport) &= ~CAN_MCR_TTCM; + } + + if (abom) { + CAN_MCR(canport) |= CAN_MCR_ABOM; + } else { + CAN_MCR(canport) &= ~CAN_MCR_ABOM; + } + + if (awum) { + CAN_MCR(canport) |= CAN_MCR_AWUM; + } else { + CAN_MCR(canport) &= ~CAN_MCR_AWUM; + } + + if (nart) { + CAN_MCR(canport) |= CAN_MCR_NART; + } else { + CAN_MCR(canport) &= ~CAN_MCR_NART; + } + + if (rflm) { + CAN_MCR(canport) |= CAN_MCR_RFLM; + } else { + CAN_MCR(canport) &= ~CAN_MCR_RFLM; + } + + if (txfp) { + CAN_MCR(canport) |= CAN_MCR_TXFP; + } else { + CAN_MCR(canport) &= ~CAN_MCR_TXFP; + } + + if (silent) { + CAN_BTR(canport) |= CAN_BTR_SILM; + } else { + CAN_BTR(canport) &= ~CAN_BTR_SILM; + } + + if (loopback) { + CAN_BTR(canport) |= CAN_BTR_LBKM; + } else { + CAN_BTR(canport) &= ~CAN_BTR_LBKM; + } + + /* Set bit timings. */ + CAN_BTR(canport) |= sjw | ts2 | ts1 | + ((brp - 1ul) & CAN_BTR_BRP_MASK); + + /* Request initialization "leave". */ + CAN_MCR(canport) &= ~CAN_MCR_INRQ; + + /* Wait for acknowledge. */ + wait_ack = CAN_MSR_INAK_TIMEOUT; + while ((--wait_ack) && + ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)); + + if ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK) { + ret = 1; + } + + return ret; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Filter Init + +Initialize incoming message filter and assign to FIFO. + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] scale_32bit true for single 32bit, false for dual 16bit +@param[in] id_list_mode true for id lists, false for id/mask +@param[in] fr1 Unsigned int32. First filter register content. +@param[in] fr2 Unsigned int32. Second filter register content. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ +void can_filter_init(uint32_t canport, uint32_t nr, bool scale_32bit, + bool id_list_mode, uint32_t fr1, uint32_t fr2, + uint32_t fifo, bool enable) +{ + uint32_t filter_select_bit = 0x00000001 << nr; + + /* Request initialization "enter". */ + CAN_FMR(canport) |= CAN_FMR_FINIT; + + /* Deactivate the filter. */ + CAN_FA1R(canport) &= ~filter_select_bit; + + if (scale_32bit) { + /* Set 32-bit scale for the filter. */ + CAN_FS1R(canport) |= filter_select_bit; + } else { + /* Set 16-bit scale for the filter. */ + CAN_FS1R(canport) &= ~filter_select_bit; + } + + if (id_list_mode) { + /* Set filter mode to ID list mode. */ + CAN_FM1R(canport) |= filter_select_bit; + } else { + /* Set filter mode to id/mask mode. */ + CAN_FM1R(canport) &= ~filter_select_bit; + } + + /* Set the first filter register. */ + CAN_FiR1(canport, nr) = fr1; + + /* Set the second filter register. */ + CAN_FiR2(canport, nr) = fr2; + + /* Select FIFO0 or FIFO1 as filter assignement. */ + if (fifo) { + CAN_FFA1R(canport) |= filter_select_bit; /* FIFO1 */ + } else { + CAN_FFA1R(canport) &= ~filter_select_bit; /* FIFO0 */ + } + + if (enable) { + CAN_FA1R(canport) |= filter_select_bit; /* Activate filter. */ + } + + /* Request initialization "leave". */ + CAN_FMR(canport) &= ~CAN_FMR_FINIT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 16bit Message ID Mask Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id1 Unsigned int16. First message ID to filter. +@param[in] mask1 Unsigned int16. First message ID bit mask. +@param[in] id2 Unsigned int16. Second message ID to filter. +@param[in] mask2 Unsigned int16. Second message ID bit mask. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ +void can_filter_id_mask_16bit_init(uint32_t canport, uint32_t nr, uint16_t id1, + uint16_t mask1, uint16_t id2, + uint16_t mask2, uint32_t fifo, bool enable) +{ + can_filter_init(canport, nr, false, false, + ((uint32_t)mask1 << 16) | (uint32_t)id1, + ((uint32_t)mask2 << 16) | (uint32_t)id2, fifo, enable); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 32bit Message ID Mask Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id Unsigned int32. Message ID to filter. +@param[in] mask Unsigned int32. Message ID bit mask. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ +void can_filter_id_mask_32bit_init(uint32_t canport, uint32_t nr, uint32_t id, + uint32_t mask, uint32_t fifo, bool enable) +{ + can_filter_init(canport, nr, true, false, id, mask, fifo, enable); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 16bit Message ID List Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id1 Unsigned int16. First message ID to match. +@param[in] id2 Unsigned int16. Second message ID to match. +@param[in] id3 Unsigned int16. Third message ID to match. +@param[in] id4 Unsigned int16. Fourth message ID to match. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ +void can_filter_id_list_16bit_init(uint32_t canport, uint32_t nr, + uint16_t id1, uint16_t id2, + uint16_t id3, uint16_t id4, + uint32_t fifo, bool enable) +{ + can_filter_init(canport, nr, false, true, + ((uint32_t)id1 << 16) | (uint32_t)id2, + ((uint32_t)id3 << 16) | (uint32_t)id4, fifo, enable); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 32bit Message ID List Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id1 Unsigned int32. First message ID to match. +@param[in] id2 Unsigned int32. Second message ID to match. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ +void can_filter_id_list_32bit_init(uint32_t canport, uint32_t nr, + uint32_t id1, uint32_t id2, + uint32_t fifo, bool enable) +{ + can_filter_init(canport, nr, true, true, id1, id2, fifo, enable); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Enable IRQ + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] irq Unsigned int32. IRQ bit(s). + */ +void can_enable_irq(uint32_t canport, uint32_t irq) +{ + CAN_IER(canport) |= irq; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Disable IRQ + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] irq Unsigned int32. IRQ bit(s). + */ +void can_disable_irq(uint32_t canport, uint32_t irq) +{ + CAN_IER(canport) &= ~irq; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Transmit Message + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] id Unsigned int32. Message ID. +@param[in] ext bool. Extended message ID? +@param[in] rtr bool. Request transmit? +@param[in] length Unsigned int8. Message payload length. +@param[in] data Unsigned int8[]. Message payload data. +@returns int 0, 1 or 2 on success and depending on which outgoing mailbox got +selected. -1 if no mailbox was available and no transmission got queued. + */ +int can_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr, + uint8_t length, uint8_t *data) +{ + int ret = 0; + uint32_t mailbox = 0; + union { + uint8_t data8[4]; + uint32_t data32; + } tdlxr, tdhxr; + + /* Check which transmit mailbox is empty if any. */ + if ((CAN_TSR(canport) & CAN_TSR_TME0) == CAN_TSR_TME0) { + ret = 0; + mailbox = CAN_MBOX0; + } else if ((CAN_TSR(canport) & CAN_TSR_TME1) == CAN_TSR_TME1) { + ret = 1; + mailbox = CAN_MBOX1; + } else if ((CAN_TSR(canport) & CAN_TSR_TME2) == CAN_TSR_TME2) { + ret = 2; + mailbox = CAN_MBOX2; + } else { + ret = -1; + } + + /* If we have no empty mailbox return with an error. */ + if (ret == -1) { + return ret; + } + + if (ext) { + /* Set extended ID. */ + CAN_TIxR(canport, mailbox) = (id << CAN_TIxR_EXID_SHIFT) | + CAN_TIxR_IDE; + } else { + /* Set standard ID. */ + CAN_TIxR(canport, mailbox) = id << CAN_TIxR_STID_SHIFT; + } + + /* Set/clear remote transmission request bit. */ + if (rtr) { + CAN_TIxR(canport, mailbox) |= CAN_TIxR_RTR; /* Set */ + } + + /* Set the DLC. */ + CAN_TDTxR(canport, mailbox) &= ~CAN_TDTxR_DLC_MASK; + CAN_TDTxR(canport, mailbox) |= (length & CAN_TDTxR_DLC_MASK); + + switch (length) { + case 8: + tdhxr.data8[3] = data[7]; + /* no break */ + case 7: + tdhxr.data8[2] = data[6]; + /* no break */ + case 6: + tdhxr.data8[1] = data[5]; + /* no break */ + case 5: + tdhxr.data8[0] = data[4]; + /* no break */ + case 4: + tdlxr.data8[3] = data[3]; + /* no break */ + case 3: + tdlxr.data8[2] = data[2]; + /* no break */ + case 2: + tdlxr.data8[1] = data[1]; + /* no break */ + case 1: + tdlxr.data8[0] = data[0]; + /* no break */ + default: + break; + } + /* Set the data. */ + + CAN_TDLxR(canport, mailbox) = tdlxr.data32; + CAN_TDHxR(canport, mailbox) = tdhxr.data32; + + /* Request transmission. */ + CAN_TIxR(canport, mailbox) |= CAN_TIxR_TXRQ; + + return ret; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Release FIFO + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] fifo Unsigned int8. FIFO id. + */ +void can_fifo_release(uint32_t canport, uint8_t fifo) +{ + if (fifo == 0) { + CAN_RF0R(canport) |= CAN_RF1R_RFOM1; + } else { + CAN_RF1R(canport) |= CAN_RF1R_RFOM1; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Receive Message + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] fifo Unsigned int8. FIFO id. +@param[in] release bool. Release the FIFO automatically after coping data out. +@param[out] id Unsigned int32 pointer. Message ID. +@param[out] ext bool pointer. The message ID is extended? +@param[out] rtr bool pointer. Request of transmission? +@param[out] fmi Unsigned int8 pointer. ID of the matched filter. +@param[out] length Unsigned int8 pointer. Length of message payload. +@param[out] data Unsigned int8[]. Message payload data. +@param[out] timestamp. Pointer to store the message timestamp. + Only valid on time triggered CAN. Use NULL to ignore. + */ +void can_receive(uint32_t canport, uint8_t fifo, bool release, uint32_t *id, + bool *ext, bool *rtr, uint8_t *fmi, uint8_t *length, + uint8_t *data, uint16_t *timestamp) +{ + uint32_t fifo_id = 0; + union { + uint8_t data8[4]; + uint32_t data32; + } rdlxr, rdhxr; + const uint32_t fifoid_array[2] = {CAN_FIFO0, CAN_FIFO1}; + + fifo_id = fifoid_array[fifo]; + + /* Get type of CAN ID and CAN ID. */ + if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_IDE) { + *ext = true; + /* Get extended CAN ID. */ + *id = (CAN_RIxR(canport, fifo_id) >> CAN_RIxR_EXID_SHIFT) & + CAN_RIxR_EXID_MASK; + } else { + *ext = false; + /* Get standard CAN ID. */ + *id = (CAN_RIxR(canport, fifo_id) >> CAN_RIxR_STID_SHIFT) & + CAN_RIxR_STID_MASK; + } + + /* Get remote transmit flag. */ + if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_RTR) { + *rtr = true; + } else { + *rtr = false; + } + + /* Get filter match ID. */ + *fmi = ((CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_FMI_MASK) >> + CAN_RDTxR_FMI_SHIFT); + + /* Get data length. */ + *length = CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_DLC_MASK; + /* accelerate reception by copying the CAN data from the controller + * memory to the fast internal RAM + */ + + if (timestamp) { + *timestamp = (CAN_RDTxR(canport, fifo_id) & + CAN_RDTxR_TIME_MASK) >> CAN_RDTxR_TIME_SHIFT; + } + + rdlxr.data32 = CAN_RDLxR(canport, fifo_id); + rdhxr.data32 = CAN_RDHxR(canport, fifo_id); + /* */ + /* Get data. + * Byte wise copy is needed because we do not know the alignment + * of the input buffer. + * Here copying 8 bytes unconditionally is faster than using loop + * + * It is OK to copy all 8 bytes because the upper layer must be + * prepared for data length bigger expected. + * In contrary the driver has no information about the intended size. + * This could be different if the max length would be handed over + * to the function, but it is not the case + */ + data[0] = rdlxr.data8[0]; + data[1] = rdlxr.data8[1]; + data[2] = rdlxr.data8[2]; + data[3] = rdlxr.data8[3]; + data[4] = rdhxr.data8[0]; + data[5] = rdhxr.data8[1]; + data[6] = rdhxr.data8[2]; + data[7] = rdhxr.data8[3]; + + /* Release the FIFO. */ + if (release) { + can_fifo_release(canport, fifo); + } +} + +bool can_available_mailbox(uint32_t canport) +{ + return CAN_TSR(canport) & (CAN_TSR_TME0 | CAN_TSR_TME1 | CAN_TSR_TME2); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v1.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v1.c new file mode 100644 index 00000000..45d9e2b4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v1.c @@ -0,0 +1,752 @@ +/** @addtogroup adc_file + +@author @htmlonly © @endhtmlonly +2009 Edward Cheeseman +@author @htmlonly © @endhtmlonly +2012 Ken Sarkies +@author @htmlonly © @endhtmlonly +2014 Karl Palsson + +This library supports one style of the Analog to Digital Conversion System in +the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics. + +The style of ADC Peripheral supported by this code is found in the F1, F2, +F37x, F38x, F4, and L1 series devices (at the time of writing) but is quite +different to the style found on the F0 and F30x and F31x. +Devices can have up to three A/D converters each with their own set of +registers. +However all the A/D converters share a common clock. On most devices, this is +prescaled from the APB2 clock by default by a minimum factor of 2 to a maximum +of 8, though on the L1 this is always a divider from the HSI. (And therefore HSI +_must_ be enabled before attempting to enable the ADC) + +Each A/D converter has up to ADC_MAX_CHANNELS channels: +@li On ADC1 the analog channels 16 and 17 are internally connected to the +temperature sensor and VREFINT, respectively. +@li On ADC2 (if available) the analog channels 16 and 17 are internally +connected to VSS. +@li On ADC3 (if available) the analog channels 9, 14, 15, 16 and 17 are +internally connected to VSS. + +The conversions can occur as a one-off conversion whereby the process stops once +conversion is complete. The conversions can also be continuous wherein a new +conversion starts immediately the previous conversion has ended. + +Conversion can occur as a single channel conversion or a scan of a group of +channels in either continuous or one-off mode. If more than one channel is +converted in a scan group, DMA must be used to transfer the data as there is +only one result register available. An interrupt can be set to occur at the end +of conversion, which occurs after all channels have been scanned. + +A discontinuous mode allows a subgroup of group of a channels to be converted in +bursts of a given length. + +Injected conversions allow a second group of channels to be converted separately +from the regular group. An interrupt can be set to occur at the end of +conversion, which occurs after all channels have been scanned. + +@section adc_api_ex Basic ADC Handling API. + +Example 1: Simple single channel conversion polled. Enable the peripheral clock +and ADC, reset ADC and set the prescaler divider. Set dual mode to independent +(default). Enable triggering for a software trigger. + +@code + rcc_periph_clock_enable(RCC_ADC1); + adc_power_off(ADC1); + rcc_periph_reset_pulse(RST_ADC1); + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); + adc_set_dual_mode(ADC_CR1_DUALMOD_IND); + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); + adc_enable_trigger(ADC1, ADC_CR2_EXTSEL_SWSTART); + adc_power_on(ADC1); + adc_reset_calibration(ADC1); + adc_calibration(ADC1); + adc_start_conversion_regular(ADC1); + while (! adc_eoc(ADC1)); + reg16 = adc_read_regular(ADC1); +@endcode + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Off + +Turn off the ADC to reduce power consumption to a few microamps. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_power_off(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ADON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Regular Conversions + +The analog watchdog allows the monitoring of an analog signal between two +threshold levels. The thresholds must be preset. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_enable_analog_watchdog_regular(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_AWDEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Regular Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_disable_analog_watchdog_regular(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Injected Conversions + +The analog watchdog allows the monitoring of an analog signal between two +threshold levels. The thresholds must be preset. Comparison is done before data +alignment takes place, so the thresholds are left-aligned. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_analog_watchdog_injected(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_JAWDEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_analog_watchdog_injected(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JAWDEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Regular Conversions + +In this mode the ADC converts, on each trigger, a subgroup of up to 8 of the +defined regular channel group. The subgroup is defined by the number of +consecutive channels to be converted. After a subgroup has been converted +the next trigger will start conversion of the immediately following subgroup +of the same length or until the whole group has all been converted. When the +the whole group has been converted, the next trigger will restart conversion +of the subgroup at the beginning of the whole group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group @ref +adc_cr1_discnum +*/ + +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length) +{ + if ((length-1) > 7) { + return; + } + ADC_CR1(adc) |= ADC_CR1_DISCEN; + ADC_CR1(adc) |= ((length-1) << ADC_CR1_DISCNUM_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Regular Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_discontinuous_mode_regular(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_DISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Injected Conversions + +In this mode the ADC converts sequentially one channel of the defined group of +injected channels, cycling back to the first channel in the group once the +entire group has been converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_discontinuous_mode_injected(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_JDISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_discontinuous_mode_injected(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JDISCEN; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Automatic Injected Conversions + +The ADC converts a defined injected group of channels immediately after the +regular channels have been converted. The external trigger on the injected +channels is disabled as required. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_automatic_injected_group_conversion(uint32_t adc) +{ + adc_disable_external_trigger_injected(adc); + ADC_CR1(adc) |= ADC_CR1_JAUTO; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Automatic Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_automatic_injected_group_conversion(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JAUTO; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for All Regular and/or Injected Channels + +The analog watchdog allows the monitoring of an analog signal between two +threshold levels. The thresholds must be preset. Comparison is done before data +alignment takes place, so the thresholds are left-aligned. + +@note The analog watchdog must be enabled for either or both of the regular or +injected channels. If neither are enabled, the analog watchdog feature will be +disabled. +@ref adc_enable_analog_watchdog_injected, @ref +adc_enable_analog_watchdog_regular. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDSGL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for a Selected Channel + +The analog watchdog allows the monitoring of an analog signal between two +threshold levels. The thresholds must be preset. Comparison is done before data +alignment takes place, so the thresholds are left-aligned. + +@note The analog watchdog must be enabled for either or both of the regular or +injected channels. If neither are enabled, the analog watchdog feature will be +disabled. If both are enabled, the same channel number is monitored. +@ref adc_enable_analog_watchdog_injected, @ref +adc_enable_analog_watchdog_regular. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] channel Unsigned int8. ADC channel number @ref adc_watchdog_channel +*/ + +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel) +{ + uint32_t reg32; + + reg32 = (ADC_CR1(adc) & ~ADC_CR1_AWDCH_MASK); /* Clear bits [4:0]. */ + if (channel <= ADC_CR1_AWDCH_MAX) { + reg32 |= channel; + } + ADC_CR1(adc) = reg32; + ADC_CR1(adc) |= ADC_CR1_AWDSGL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Scan Mode + +In this mode a conversion consists of a scan of the predefined set of channels, +regular and injected, each channel conversion immediately following the +previous one. It can use single, continuous or discontinuous mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_scan_mode(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_SCAN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Scan Mode + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_scan_mode(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_SCAN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_eoc_interrupt_injected(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_JEOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_eoc_interrupt_injected(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JEOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_awd_interrupt(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_AWDIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_awd_interrupt(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Regular End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_eoc_interrupt(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_EOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_eoc_interrupt(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_EOCIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Data as Left Aligned + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_set_left_aligned(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_ALIGN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Data as Right Aligned + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_set_right_aligned(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ALIGN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag + +This flag is set after all channels of a regular or injected group have been +converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. End of conversion flag. +*/ + +bool adc_eoc(uint32_t adc) +{ + return (ADC_SR(adc) & ADC_SR_EOC) != 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion + +This flag is set after all channels of an injected group have been converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. End of conversion flag. +*/ + +bool adc_eoc_injected(uint32_t adc) +{ + return (ADC_SR(adc) & ADC_SR_JEOC) != 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read from the Regular Conversion Result Register + +The result read back is 12 bits, right or left aligned within the first 16 bits. +For ADC1 only, the higher 16 bits will hold the result from ADC2 if +an appropriate dual mode has been set @see adc_set_dual_mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +uint32_t adc_read_regular(uint32_t adc) +{ + return ADC_DR(adc); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read from an Injected Conversion Result Register + +The result read back from the selected injected result register (one of four) +is 12 bits, right or left aligned within the first 16 bits. The result can have +a negative value if the injected channel offset has been set @see +adc_set_injected_offset. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] reg Unsigned int8. Register number (1 ... 4). +@returns Unsigned int32 conversion result. +*/ + +uint32_t adc_read_injected(uint32_t adc, uint8_t reg) +{ + switch (reg) { + case 1: + return ADC_JDR1(adc); + case 2: + return ADC_JDR2(adc); + case 3: + return ADC_JDR3(adc); + case 4: + return ADC_JDR4(adc); + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Continuous Conversion Mode + +In this mode the ADC starts a new conversion of a single channel or a channel +group immediately following completion of the previous channel group conversion. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_continuous_conversion_mode(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_CONT; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Single Conversion Mode + +In this mode the ADC performs a conversion of one channel or a channel group +and stops. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_set_single_conversion_mode(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_CONT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Upper Threshold + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] threshold Upper threshold value, 12bit right aligned. +*/ + +void adc_set_watchdog_high_threshold(uint32_t adc, uint16_t threshold) +{ + uint32_t reg32 = 0; + + reg32 = (uint32_t)threshold; + reg32 &= ADC_HT_MSK; + ADC_HTR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Lower Threshold + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] threshold Lower threshold value, 12bit right aligned. +*/ + +void adc_set_watchdog_low_threshold(uint32_t adc, uint16_t threshold) +{ + uint32_t reg32 = 0; + + reg32 = (uint32_t)threshold; + reg32 &= ADC_LT_MSK; + ADC_LTR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ + +/** @brief ADC Set a Regular Channel Conversion Sequence + +Define a sequence of channels to be converted as a regular group with a length +from 1 to ADC_REGULAR_SEQUENCE_MAX channels. If this is called during +conversion, the current conversion is reset and conversion begins again with +the newly defined group. + +@param[in] adc Unsigned int32. ADC block base address @ref adc_reg_base. +@param[in] length Unsigned int8. Number of channels in the group. +@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..31. + */ + +void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + uint32_t fifth6 = 0; + uint32_t fourth6 = 0; + uint32_t third6 = 0; + uint32_t second6 = 0; + uint32_t first6 = 0; + uint8_t i = 0; + + if (length > ADC_SQR_MAX_CHANNELS_REGULAR) { + return; + } + + for (i = 1; i <= length; i++) { + if (i <= 6) { + first6 |= (channel[i - 1] << ((i - 1) * 5)); + } + if ((i > 6) & (i <= 12)) { + second6 |= (channel[i - 1] << ((i - 6 - 1) * 5)); + } + if ((i > 12) & (i <= 18)) { + third6 |= (channel[i - 1] << ((i - 12 - 1) * 5)); + } + if ((i > 18) & (i <= 24)) { + fourth6 |= (channel[i - 1] << ((i - 18 - 1) * 5)); + } + if ((i > 24) & (i <= 28)) { + fifth6 |= (channel[i - 1] << ((i - 24 - 1) * 5)); + } + } +#if defined(ADC_SQR5) + ADC_SQR1(adc) = fifth6 | ((length - 1) << ADC_SQR1_L_LSB); + ADC_SQR2(adc) = fourth6; + ADC_SQR3(adc) = third6; + ADC_SQR4(adc) = second6; + ADC_SQR5(adc) = first6; +#else + ADC_SQR1(adc) = third6 | ((length - 1) << ADC_SQR1_L_LSB); + ADC_SQR2(adc) = second6; + ADC_SQR3(adc) = first6; +#endif +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set an Injected Channel Conversion Sequence + +Defines a sequence of channels to be converted as an injected group with a +length from 1 to 4 channels. If this is called during conversion, the current +conversion is reset and conversion begins again with the newly defined group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group. +@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18 +*/ + +void adc_set_injected_sequence(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + uint32_t reg32 = 0; + uint8_t i = 0; + + /* Maximum sequence length is 4 channels. Minimum sequence is 1.*/ + if ((length - 1) > 3) { + return; + } + + for (i = 0; i < length; i++) { + reg32 |= ADC_JSQR_JSQ_VAL(4 - i, channel[length - i - 1]); + } + + reg32 |= ADC_JSQR_JL_VAL(length); + + ADC_JSQR(adc) = reg32; +} + + +/*----------------------------------------------------------------------------*/ +/** @brief ADC Set the Injected Channel Data Offset + +This value is subtracted from the injected channel results after conversion is +complete, and can result in negative results. A separate value can be specified +for each injected data register. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] reg Unsigned int8. Register number (1 ... 4). +@param[in] offset Unsigned int32. +*/ + +void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset) +{ + switch (reg) { + case 1: + ADC_JOFR1(adc) = offset; + break; + case 2: + ADC_JOFR2(adc) = offset; + break; + case 3: + ADC_JOFR3(adc) = offset; + break; + case 4: + ADC_JOFR4(adc) = offset; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Regular Channels + +This starts conversion on a set of defined regular channels if the ADC trigger +is set to be a software trigger. It is cleared by hardware once conversion +starts. + +Special F1 Note this is a software trigger and requires triggering to be +enabled and the trigger source to be set appropriately otherwise conversion +will not start. This is not the same as the ADC start conversion operation. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_start_conversion_regular(uint32_t adc) +{ + /* Start conversion on regular channels. */ + ADC_CR2(adc) |= ADC_CR2_SWSTART; + + /* Wait until the ADC starts the conversion. */ + while (ADC_CR2(adc) & ADC_CR2_SWSTART); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Injected Channels + +This starts conversion on a set of defined injected channels if the ADC trigger +is set to be a software trigger. It is cleared by hardware once conversion +starts. + +Special F1 Note this is a software trigger and requires triggering to be +enabled and the trigger source to be set appropriately otherwise conversion +will not start. This is not the same as the ADC start conversion operation. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_start_conversion_injected(uint32_t adc) +{ + /* Start conversion on injected channels. */ + ADC_CR2(adc) |= ADC_CR2_JSWSTART; + + /* Wait until the ADC starts the conversion. */ + while (ADC_CR2(adc) & ADC_CR2_JSWSTART); +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable DMA Transfers + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_dma(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_DMA; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable DMA Transfers + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_dma(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_DMA; +} + + + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2.c new file mode 100644 index 00000000..dda7aa0c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2.c @@ -0,0 +1,392 @@ +/** @addtogroup adc_file + +@author @htmlonly © @endhtmlonly +2015 Karl Palsson + +This library supports one style of the Analog to Digital Conversion System in +the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics. + +The style of ADC Peripheral supported by this code is found in the F0, L0 and +F30x series devices (at the time of writing) + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + + +/** @brief ADC Read the End-of-Conversion Flag + * + * This flag is set by hardware at the end of each regular conversion of a + * channel when a new data is available in the ADCx_DR register. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. End of conversion flag. + */ +bool adc_eoc(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_EOC; +} + +/** @brief ADC Read the End-of-Sequence Flag for Regular Conversions + * + * This flag is set after all channels of an regular group have been + * converted. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. End of conversion flag. + */ +bool adc_eos(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_EOS; +} + +/** + * Turn on the ADC (async) + * @sa adc_wait_power_on + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_power_on_async(uint32_t adc) +{ + ADC_CR(adc) |= ADC_CR_ADEN; +} + +/** + * Is the ADC powered up and ready? + * @sa adc_power_on_async + * @param adc ADC Block register address base @ref adc_reg_base + * @return true if adc is ready for use + */ +bool adc_is_power_on(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_ADRDY; +} + +/** + * Turn on the ADC + * @sa adc_power_on_async + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_power_on(uint32_t adc) +{ + adc_power_on_async(adc); + while (!adc_is_power_on(adc)); +} + +/** + * Turn off the ADC (async) + * This will actually block if it needs to turn off a currently running + * conversion, as per ref man. (Handles injected on hardware that supports + * injected conversions. + * @sa adc_wait_power_off + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_power_off_async(uint32_t adc) +{ + if (adc_is_power_off(adc)) { + return; + } + + uint32_t checks = ADC_CR_ADSTART; + uint32_t stops = ADC_CR_ADSTP; +#if defined(ADC_CR_JADSTART) + checks |= ADC_CR_JADSTART; + stops |= ADC_CR_JADSTP; +#endif + if (ADC_CR(adc) & checks) { + ADC_CR(adc) |= stops; + while (ADC_CR(adc) & checks); + } + ADC_CR(adc) |= ADC_CR_ADDIS; +} + +/** + * Is the ADC powered down? + * @sa adc_power_off_async + * @param adc ADC Block register address base @ref adc_reg_base + */ +bool adc_is_power_off(uint32_t adc) +{ + return !(ADC_CR(adc) & ADC_CR_ADEN); +} + +/** + * Turn off the ADC + * This will actually block if it needs to turn off a currently running + * conversion, as per ref man. + * @sa adc_power_off_async + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_power_off(uint32_t adc) +{ + adc_power_off_async(adc); + while (!adc_is_power_off(adc)); +} + +/** + * Start the ADC calibration and immediately return. + * @sa adc_calibrate + * @sa adc_is_calibrating + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_calibrate_async(uint32_t adc) +{ + ADC_CR(adc) = ADC_CR_ADCAL; +} + +/** + * Is the ADC Calibrating? + * @param adc ADC Block register address base @ref adc_reg_base + * @return true if the adc is currently calibrating + */ +bool adc_is_calibrating(uint32_t adc) +{ + return ADC_CR(adc) & ADC_CR_ADCAL; +} + +/** + * Start ADC calibration and wait for it to finish + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_calibrate(uint32_t adc) +{ + adc_calibrate_async(adc); + while (adc_is_calibrating(adc)); +} + +/** + * Enable Continuous Conversion Mode + * In this mode the ADC starts a new conversion of a single channel or a channel + * group immediately following completion of the previous channel group + * conversion. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + */ +void adc_set_continuous_conversion_mode(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_CONT; +} + +/** + * Enable Single Conversion Mode + * In this mode the ADC performs a conversion of one channel or a channel group + * and stops. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + */ +void adc_set_single_conversion_mode(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_CONT; +} + +/** @brief ADC Set Resolution + * + * ADC Resolution can be reduced from 12 bits to 10, 8 or 6 bits for a + * corresponding reduction in conversion time. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] resolution Unsigned int16. Resolution value (@ref adc_api_res) + */ +void adc_set_resolution(uint32_t adc, uint16_t resolution) +{ + ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_RES_MASK) | resolution; +} + +/** @brief ADC Set the Data as Left Aligned + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_set_left_aligned(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_ALIGN; +} + +/** @brief ADC Set the Data as Right Aligned + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_set_right_aligned(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_ALIGN; +} + +/** @brief ADC Enable DMA Transfers + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_enable_dma(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_DMAEN; +} + +/** @brief ADC Disable DMA Transfers + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_disable_dma(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_DMAEN; +} + +/** @brief ADC Enable the Overrun Interrupt + * + * The overrun interrupt is generated when data is not read from a result + * register before the next conversion is written. If DMA is enabled, all + * transfers are terminated and any conversion sequence is aborted. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_enable_overrun_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_OVRIE; +} + +/** @brief ADC Disable the Overrun Interrupt + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_disable_overrun_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_OVRIE; +} + +/** @brief ADC Read the Overrun Flag + * + * The overrun flag is set when data is not read from a result register before + * the next conversion is written. If DMA is enabled, all transfers are + * terminated and any conversion sequence is aborted. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +bool adc_get_overrun_flag(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_OVR; +} + +/** @brief ADC Clear Overrun Flags + * + * The overrun flag is cleared. Note that if an overrun occurs, DMA is + * terminated. + * The flag must be cleared and the DMA stream and ADC reinitialised to resume + * conversions (see the reference manual). + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_clear_overrun_flag(uint32_t adc) +{ + ADC_ISR(adc) = ADC_ISR_OVR; +} + +/** @brief ADC Enable Regular End-Of-Conversion Interrupt + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_enable_eoc_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_EOCIE; +} + +/** @brief ADC Disable Regular End-Of-Conversion Interrupt + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_disable_eoc_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_EOCIE; +} + +/** @brief ADC Read from the Regular Conversion Result Register + * + * The result read back is 12 bits, right or left aligned within the first + * 16 bits. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns Unsigned int32 conversion result. + */ +uint32_t adc_read_regular(uint32_t adc) +{ + return ADC_DR(adc); +} + +/** + * Enable the temperature sensor (only) + * The channel this is available on is unfortunately not + * consistent, even though the bit used to enable it is. + * @sa adc_disable_temperature_sensor + */ +void adc_enable_temperature_sensor(void) +{ + ADC_CCR(ADC1) |= ADC_CCR_TSEN; +} + +/** + * Disable the temperature sensor (only) + * @sa adc_enable_temperature_sensor + */ +void adc_disable_temperature_sensor(void) +{ + ADC_CCR(ADC1) &= ~ADC_CCR_TSEN; +} + +/** + * Enable the internal voltage reference (only) + * The channel this is available on is unfortunately not + * consistent, even though the bit used to enable it is. + * FIXME - on f3, you can actually have it on ADC34 as well! + * @sa adc_disable_vrefint + */ +void adc_enable_vrefint(void) +{ + ADC_CCR(ADC1) |= ADC_CCR_VREFEN; +} + +/** + * Disable the internal voltage reference (only) + * @sa adc_enable_vrefint + */ +void adc_disable_vrefint(void) +{ + ADC_CCR(ADC1) &= ~ADC_CCR_VREFEN; +} + +/** @brief ADC Software Triggered Conversion on Regular Channels + * + * This starts conversion on a set of defined regular channels. It is cleared + * by hardware once conversion starts. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + */ +void adc_start_conversion_regular(uint32_t adc) +{ + /* Start conversion on regular channels. */ + ADC_CR(adc) |= ADC_CR_ADSTART; + + /* Wait until the ADC starts the conversion. */ + while (ADC_CR(adc) & ADC_CR_ADSTART); +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2_multi.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2_multi.c new file mode 100644 index 00000000..334af8de --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/adc_common_v2_multi.c @@ -0,0 +1,132 @@ +/** @addtogroup adc_file + +@author @htmlonly © @endhtmlonly +2016 Karl Palsson + +This provides the "multi" extensions to the "v2" ADC peripheral. This is those +devices that support injected channels and per channel sampling times. +At the time of writing, this is the STM32F30x and the STM32L4x + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + + +/** @brief ADC Set the Sample Time for a Single Channel + * + * The sampling time can be selected in ADC clock cycles, exact values + * depend on the device. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + * @param[in] channel ADC Channel integer @ref adc_channel + * @param[in] time Sampling time selection from @ref adc_sample + */ +void adc_set_sample_time(uint32_t adc, uint8_t channel, uint8_t time) +{ + uint32_t reg32; + + if (channel < 10) { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0x7 << (channel * 3)); + reg32 |= (time << (channel * 3)); + ADC_SMPR1(adc) = reg32; + } else { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0x7 << ((channel - 10) * 3)); + reg32 |= (time << ((channel - 10) * 3)); + ADC_SMPR2(adc) = reg32; + } +} + +/** @brief ADC Set the Sample Time for All Channels + * + * The sampling time can be selected in ADC clock cycles, exact values + * depend on the device. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + * @param[in] time Sampling time selection from @ref adc_sample + */ +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time) +{ + uint8_t i; + uint32_t reg32 = 0; + + for (i = 0; i <= 9; i++) { + reg32 |= (time << (i * 3)); + } + ADC_SMPR1(adc) = reg32; + + for (i = 10; i <= 17; i++) { + reg32 |= (time << ((i - 10) * 3)); + } + ADC_SMPR2(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set a Regular Channel Conversion Sequence + * + * Define a sequence of channels to be converted as a regular group with a + * length from 1 to 16 channels. If this is called during conversion, the + * current conversion is reset and conversion begins again with the newly + * defined group. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + * @param[in] length Number of channels in the group, range 0..16 + * @param[in] channel Set of channels in sequence, range @ref adc_channel + */ +void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + uint32_t reg32_1 = 0, reg32_2 = 0, reg32_3 = 0, reg32_4 = 0; + uint8_t i = 0; + + /* Maximum sequence length is 16 channels. */ + if (length > 16) { + return; + } + + for (i = 1; i <= length; i++) { + if (i <= 4) { + reg32_1 |= (channel[i - 1] << (i * 6)); + } + if ((i > 4) & (i <= 9)) { + reg32_2 |= (channel[i - 1] << ((i - 4 - 1) * 6)); + } + if ((i > 9) & (i <= 14)) { + reg32_3 |= (channel[i - 1] << ((i - 9 - 1) * 6)); + } + if ((i > 14) & (i <= 16)) { + reg32_4 |= (channel[i - 1] << ((i - 14 - 1) * 6)); + } + } + reg32_1 |= ((length - 1) << ADC_SQR1_L_SHIFT); + + ADC_SQR1(adc) = reg32_1; + ADC_SQR2(adc) = reg32_2; + ADC_SQR3(adc) = reg32_3; + ADC_SQR4(adc) = reg32_4; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crc_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crc_common_all.c new file mode 100644 index 00000000..5794c8f9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crc_common_all.c @@ -0,0 +1,81 @@ +/** @addtogroup crc_file + +@author @htmlonly © @endhtmlonly 2012 Karl Palsson + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief CRC Reset. + +Reset the CRC unit and forces the data register to all 1s. + +*/ + +void crc_reset(void) +{ + CRC_CR |= CRC_CR_RESET; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CRC Calculate. + +Writes a data word to the register, the write operation stalling until the +computation is complete. + +@param[in] data Unsigned int32. +@returns int32 Computed CRC result +*/ + +uint32_t crc_calculate(uint32_t data) +{ + CRC_DR = data; + /* Data sheet says this blocks until it's ready.... */ + return CRC_DR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CRC Calculate of a Block of Data. + +Writes data words consecutively to the register, the write operation stalling +until the computation of each word is complete. + +@param[in] datap Unsigned int32. pointer to an array of 32 bit data words. +@param[in] size int. Size of the array. +@returns int32 Final computed CRC result +*/ + +uint32_t crc_calculate_block(uint32_t *datap, int size) +{ + int i; + + for (i = 0; i < size; i++) { + CRC_DR = datap[i]; + } + + return CRC_DR; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crs_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crs_common_all.c new file mode 100644 index 00000000..2ebc9610 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crs_common_all.c @@ -0,0 +1,48 @@ +/** @defgroup crs_file CRS + * + * @ingroup STM32xx + * + * @brief libopencm3 STM32 Clock Recovery Subsystem + * + * @version 1.0.0 + * + * @date 5 Feb 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/** + * This function enables automatic trimming of internal RC oscillator by USB SOF + * frames + */ +void crs_autotrim_usb_enable(void) +{ + rcc_periph_clock_enable(RCC_CRS); + + CRS_CFGR &= ~CRS_CFGR_SYNCSRC; + CRS_CFGR |= CRS_CFGR_SYNCSRC_USB_SOF; + + CRS_CR |= CRS_CR_AUTOTRIMEN; + CRS_CR |= CRS_CR_CEN; +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crypto_common_f24.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crypto_common_f24.c new file mode 100644 index 00000000..22f329c6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/crypto_common_f24.c @@ -0,0 +1,175 @@ +/** @addtogroup crypto_file + * + * @brief libopencm3 STM32 Cryptographic controller + * + * @version 1.0.0 + * + * @date 17 Jun 2013 + * + * This library supports the cryptographic coprocessor system for the + * STM32 series of ARM Cortex Microcontrollers + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +#define CRYP_CR_ALGOMODE_MASK ((1 << 19) | CRYP_CR_ALGOMODE) + +/** + * @brief Wait, if the Controller is busy + */ +void crypto_wait_busy(void) +{ + while (CRYP_SR & CRYP_SR_BUSY); +} + +/** + * @brief Set key value to the controller + * @param[in] keysize enum crypto_keysize Specified size of the key. + * @param[in] key uint64_t[] Key value (array of 4 items) + */ +void crypto_set_key(enum crypto_keysize keysize, uint64_t key[]) +{ + int i; + + crypto_wait_busy(); + + CRYP_CR = (CRYP_CR & ~CRYP_CR_KEYSIZE) | + (keysize << CRYP_CR_KEYSIZE_SHIFT); + + for (i = 0; i < 4; i++) { + CRYP_KR(i) = key[i]; + } +} + +/** + * @brief Set Initialization Vector + * + * @param[in] iv uint64_t[] Initialization vector (array of 4 items) + + * @note Cryptographic controller must be in disabled state + */ +void crypto_set_iv(uint64_t iv[]) +{ + int i; + + crypto_wait_busy(); + + for (i = 0; i < 4; i++) { + CRYP_IVR(i) = iv[i]; + } +} + +/** + * @brief Set the order of the data to be crypted + * + * @param[in] datatype enum crypto_datatype Specified datatype of the key. + */ +void crypto_set_datatype(enum crypto_datatype datatype) +{ + CRYP_CR = (CRYP_CR & ~CRYP_CR_DATATYPE) | + (datatype << CRYP_CR_DATATYPE_SHIFT); +} + +/** + * @brief Set the algorithm for Encryption/decryption + * + *@param[in] mode enum crypto_mode Mode of execution + */ +void crypto_set_algorithm(enum crypto_mode mode) +{ + mode &= ~CRYP_CR_ALGOMODE_MASK; + + if ((mode == DECRYPT_AES_ECB) || (mode == DECRYPT_AES_CBC)) { + /* Unroll keys for the AES encoder for the user automatically */ + + CRYP_CR = (CRYP_CR & ~CRYP_CR_ALGOMODE_MASK) | + CRYP_CR_ALGOMODE_AES_PREP; + + crypto_start(); + crypto_wait_busy(); + /* module switches to DISABLE automatically */ + } + /* set algo mode */ + CRYP_CR = (CRYP_CR & ~CRYP_CR_ALGOMODE_MASK) | mode; + + /* flush buffers */ + CRYP_CR |= CRYP_CR_FFLUSH; +} + +/** + * @brief Enable the cryptographic controller and start processing + */ +void crypto_start(void) +{ + CRYP_CR |= CRYP_CR_CRYPEN; +} + +/** + * @brief Disable the cryptographic controller and stop processing + */ + +void crypto_stop(void) +{ + CRYP_CR &= ~CRYP_CR_CRYPEN; +} + +/** + * @brief Start of encryption or decryption on data buffers + * + * This blocking method transfers input buffer of specified length to the + * cryptographic coprocessor, and instructs him to begin of ciphering or + * deciphering. It waits for data to be ready, and then fills the processed + * data to output buffer. + * + * @param[in] inp uint32_t* Input array to crypt/decrypt. + * @param[in] outp uint32_t* Output array with crypted/encrypted data. + * @param[in] length uint32_t Length of the arrays + * + * @returns uint32_t Number of written words + */ +uint32_t crypto_process_block(uint32_t *inp, uint32_t *outp, uint32_t length) +{ + uint32_t rd = 0, wr = 0; + + /* Transfer the data */ + while (rd != length) { + if ((wr < length) && (CRYP_SR & CRYP_SR_IFNF)) { + CRYP_DIN = *inp++; + wr++; + } + + if (CRYP_SR & CRYP_SR_OFNE) { + *outp++ = CRYP_DOUT; + rd++; + } + } + + /* Wait to finish - Not needed ? */ + crypto_wait_busy(); + + return wr; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dac_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dac_common_all.c new file mode 100644 index 00000000..a8a0daf8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dac_common_all.c @@ -0,0 +1,503 @@ +/** @addtogroup dac_file + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +This library supports the Digital to Analog Conversion System in the +STM32F series of ARM Cortex Microcontrollers by ST Microelectronics. + +The DAC is present only in a limited set of devices, notably some +of the connection line, high density and XL devices. + +Two DAC channels are available, however unlike the ADC channels these +are separate DAC devices controlled by the same register block. + +The DAC is on APB1. Its clock must be enabled in RCC and depending on +specific family, the GPIO +ports set to alternate function output before it can be used. +On most families, the GPIO pins should be configured to Analog IN to +avoid parasitic consumption. +The digital output driver is disabled so the output driver mode +(push-pull/open drain) is arbitrary. + +The DAC has a holding (buffer) register and an output register from +which the analog output is derived. The holding register must be +loaded first. If triggering is enabled the output register is loaded +from the holding register after a trigger occurs. If triggering is +not enabled the holding register contents are transferred directly +to the output register. + +@note To avoid nonlinearities, do not allow outputs to range close +to zero or V_analog. + +@section dac_api_dual Dual Channel Conversion + +There are dual modes in which both DACs are used to output data +simultaneously or independently on both channels. The data must be +presented according to the formats described in the datasheets. A +convenience function @ref dac_load_data_buffer_dual is provided +for software controlled use. + +A variety of modes are available depending on whether independent +or simultaneous output is desired, and whether waveforms are to be +superimposed. Refer to the datasheets. + +If DMA is used, only enable it for one of the channels. The DMA +requests will then serve data in dual format to the data register +dedicated to dual mode. The data will then be split and loaded to the +appropriate DAC following the next trigger. There are three registers +available, one for each of the formats: 12 bit right-aligned, 12 bit +left-aligned and 8 bit right-aligned. The desired format is determined +by specifying the appropriate register to the DMA controller. + +@section dac_api_basic_ex Basic DAC handling API. + +Set the DAC's GPIO port to Analog IN. Enable the +DAC clock. Enable the DAC, set a trigger source and load the buffer +with the first value. After the DAC is triggered, load the buffer with +the next value. This example uses software triggering and added noise. +The trigger and further buffer load calls are made when data is to be +sent out. + +@code + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_DACEN); + dac_disable(CHANNEL_1); + dac_set_waveform_characteristics(DAC_CR_MAMP1_8); + dac_set_waveform_generation(DAC_CR_WAVE1_NOISE); + dac_enable(CHANNEL_1); + dac_set_trigger_source(DAC_CR_TSEL1_SW); + dac_load_data_buffer_single(0, RIGHT12, CHANNEL_1); + .... + dac_software_trigger(CHANNEL_1); + dac_load_data_buffer_single(value, RIGHT12, CHANNEL_1); +@endcode + +@section dac_api_dma_ex Simultaneous Dual DAC with DMA. + +This example in part sets up the DAC channel 1 DMA (DMA2 channel 3) to read +16 bit data from memory into the right-aligned 8 bit dual register DAC_DHR8RD. +Both DAC channels are enabled, and both triggers are set to the same timer +2 input as required for simultaneous operation. DMA is enabled for DAC channel +1 only to ensure that only one DMA request is generated. + +@code + dma_set_memory_size(DMA2,DMA_CHANNEL3,DMA_CCR_MSIZE_16BIT); + dma_set_peripheral_size(DMA2,DMA_CHANNEL3,DMA_CCR_PSIZE_16BIT); + dma_set_read_from_memory(DMA2,DMA_CHANNEL3); + dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(uint32_t) &DAC_DHR8RD); + dma_enable_channel(DMA2,DMA_CHANNEL3); + ... + dac_trigger_enable(CHANNEL_D); + dac_set_trigger_source(DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); + dac_dma_enable(CHANNEL_1); + dac_enable(CHANNEL_D); +@endcode + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +#define MASK8 0xFF +#define MASK12 0xFFF + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Enable. + +Enable a digital to analog converter channel. After setting this enable, the +DAC requires a twakeup time typically around 10 microseconds before +it actually wakes up. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_EN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_EN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_EN1 | DAC_CR_EN2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Disable. + +Disable a digital to analog converter channel. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_EN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_EN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_EN1 | DAC_CR_EN2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Enable. + +Enable a digital to analog converter channel output drive buffer. This is an +optional amplifying buffer that provides additional drive for the output +signal. The buffer is enabled by default after a reset and needs to be +explicitly disabled if required. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_buffer_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_BOFF1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_BOFF2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Disable. + +Disable a digital to analog converter channel output drive buffer. Disabling +this will reduce power consumption slightly and will increase the output +impedance of the DAC. The buffers are enabled by default after a reset. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_buffer_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_BOFF1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_BOFF2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel DMA Enable. + +Enable a digital to analog converter channel DMA mode (connected to DMA2 channel +3 for DAC channel 1 and DMA2 channel 4 for DAC channel 2). A DMA request is +generated following an external trigger. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_dma_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_DMAEN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_DMAEN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel DMA Disable. + +Disable a digital to analog converter channel DMA mode. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_dma_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_DMAEN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_DMAEN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Trigger Enable. + +Enable a digital to analog converter channel external trigger mode. This allows +an external trigger to initiate register transfers from the buffer register to +the DAC output register, followed by a DMA transfer to the buffer register if +DMA is enabled. The trigger source must also be selected. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_trigger_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_TEN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_TEN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_TEN1 | DAC_CR_TEN2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Trigger Disable. + +Disable a digital to analog converter channel external trigger. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_trigger_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_TEN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_TEN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_TEN1 | DAC_CR_TEN2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set DAC Channel Trigger Source. + +Sets the digital to analog converter trigger source, which can be taken from +various timers, an external trigger or a software trigger. + +@param[in] dac_trig_src uint32_t. Taken from @ref dac_trig2_sel or @ref +dac_trig1_sel or a logical OR of one of each of these to set both channels +simultaneously. +*/ + +void dac_set_trigger_source(uint32_t dac_trig_src) +{ + DAC_CR |= dac_trig_src; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable and Set DAC Channel Waveform Generation. + +Enable the digital to analog converter waveform generation as either +pseudo-random noise or triangular wave. These signals are superimposed on +existing output values in the DAC output registers. + +@note The DAC trigger must be enabled for this to work. + +@param[in] dac_wave_ens uint32_t. Taken from @ref dac_wave1_en or @ref +dac_wave2_en or a logical OR of one of each of these to set both channels +simultaneously. +*/ + +void dac_set_waveform_generation(uint32_t dac_wave_ens) +{ + DAC_CR |= dac_wave_ens; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable DAC Channel Waveform Generation. + +Disable a digital to analog converter channel superimposed waveform generation. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_disable_waveform_generation(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_WAVE1_DIS; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_WAVE2_DIS; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_WAVE1_DIS | DAC_CR_WAVE2_DIS); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set DAC Channel LFSR Mask or Triangle Wave Amplitude. + +Sets the digital to analog converter superimposed waveform generation +characteristics. @li If the noise generation mode is set, this sets the length +of the PRBS sequence and hence the amplitude of the output noise signal. +Default setting is length 1. @li If the triangle wave generation mode is set, +this sets the amplitude of the output signal as 2^(n)-1 where n is the +parameter value. Default setting is 1. + +@note High amplitude levels of these waveforms can overload the DAC and distort +the signal output. +@note This must be called before enabling the DAC as the settings will then +become read-only. +@note The DAC trigger must be enabled for this to work. + +@param[in] dac_mamp uint32_t. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a +logical OR of one of each of these to set both channels simultaneously. +*/ + +void dac_set_waveform_characteristics(uint32_t dac_mamp) +{ + DAC_CR |= dac_mamp; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Load DAC Data Register. + +Loads the appropriate digital to analog converter data register with 12 or 8 bit +data to be converted on a channel. The data can be aligned as follows: +@li right-aligned 8 bit data in bits 0-7 +@li right-aligned 12 bit data in bits 0-11 +@li left aligned 12 bit data in bits 4-15 + +@param[in] dac_data uint16_t with appropriate alignment. +@param[in] dac_data_format enum ::data_align. Alignment and size. +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_load_data_buffer_single(uint16_t dac_data, data_align dac_data_format, + data_channel dac_channel) +{ + if (dac_channel == CHANNEL_1) { + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8R1 = dac_data; + break; + case RIGHT12: + DAC_DHR12R1 = dac_data; + break; + case LEFT12: + DAC_DHR12L1 = dac_data; + break; + } + } else if (dac_channel == CHANNEL_2) { + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8R2 = dac_data; + break; + case RIGHT12: + DAC_DHR12R2 = dac_data; + break; + case LEFT12: + DAC_DHR12L2 = dac_data; + break; + } + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Load DAC Dual Data Register. + +Loads the appropriate digital to analog converter dual data register with 12 or +8 bit data to be converted for both channels. This allows high bandwidth +simultaneous or independent analog output. The data in both channels are aligned +identically. + +@param[in] dac_data1 uint16_t for channel 1 with appropriate alignment. +@param[in] dac_data2 uint16_t for channel 2 with appropriate alignment. +@param[in] dac_data_format enum ::data_align. Right or left aligned, and 8 or +12 bit. +*/ + +void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, + data_align dac_data_format) +{ + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8RD = ((dac_data1 & MASK8) | ((dac_data2 & MASK8) << 8)); + break; + case RIGHT12: + DAC_DHR12RD = ((dac_data1 & MASK12) | + ((dac_data2 & MASK12) << 16)); + break; + case LEFT12: + DAC_DHR12LD = ((dac_data1 & MASK12) | + ((dac_data2 & MASK12) << 16)); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Trigger the DAC by a Software Trigger. + +If the trigger source is set to be a software trigger, cause a trigger to occur. +The trigger is cleared by hardware after conversion. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_software_trigger(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG1; + break; + case CHANNEL_2: + DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG2; + break; + case CHANNEL_D: + DAC_SWTRIGR |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2); + break; + } +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_f24.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_f24.c new file mode 100644 index 00000000..6b655636 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_f24.c @@ -0,0 +1,794 @@ +/** @addtogroup dma_file + +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +This library supports the DMA Control System in the STM32F2 and STM32F4 +series of ARM Cortex Microcontrollers by ST Microelectronics. + +Up to two DMA controllers are supported each with 8 streams, and each stream +having up to 8 channels hardware dedicated to various peripheral DMA signals. + +DMA transfers can be configured to occur between peripheral and memory in +either direction, and memory to memory. Peripheral to peripheral transfer +is not supported. Circular mode transfers are also supported in transfers +involving a peripheral. An arbiter is provided to resolve priority DMA +requests. Transfers can be made with 8, 16 or 32 bit words. + +Each stream has access to a 4 word deep FIFO and can use double buffering +by means of two memory pointers. When using the FIFO it is possible to +configure transfers to occur in indivisible bursts. + +It is also possible to select a peripheral instead of the DMA controller to +control the flow of data. This limits the functionality but is useful when the +number of transfers is unknown. + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Reset + +The specified stream is disabled and configuration registers are cleared. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_stream_reset(uint32_t dma, uint8_t stream) +{ +/* Disable stream (must be done before register is otherwise changed). */ + DMA_SCR(dma, stream) &= ~DMA_SxCR_EN; +/* Reset all config bits. */ + DMA_SCR(dma, stream) = 0; +/* Reset data transfer number. */ + DMA_SNDTR(dma, stream) = 0; +/* Reset peripheral and memory addresses. */ + DMA_SPAR(dma, stream) = 0; + DMA_SM0AR(dma, stream) = 0; + DMA_SM1AR(dma, stream) = 0; +/* This is the default setting */ + DMA_SFCR(dma, stream) = 0x21; +/* Reset all stream interrupt flags using the interrupt flag clear register. */ + uint32_t mask = DMA_ISR_MASK(stream); + if (stream < 4) { + DMA_LIFCR(dma) |= mask; + } else { + DMA_HIFCR(dma) |= mask; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Clear Interrupt Flag + +The interrupt flag for the stream is cleared. More than one interrupt for the +same stream may be cleared by using the bitwise OR of the interrupt flags. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] interrupts unsigned int32. Bitwise OR of interrupt numbers: @ref +dma_if_offset +*/ + +void dma_clear_interrupt_flags(uint32_t dma, uint8_t stream, + uint32_t interrupts) +{ + /* Get offset to interrupt flag location in stream field */ + uint32_t flags = (interrupts << DMA_ISR_OFFSET(stream)); + /* First four streams are in low register. Flag clear must be set then + * reset. + */ + if (stream < 4) { + DMA_LIFCR(dma) = flags; + } else { + DMA_HIFCR(dma) = flags; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Read Interrupt Flag + +The interrupt flag for the stream is returned. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] interrupt unsigned int32. Interrupt number: @ref dma_if_offset +@returns bool interrupt flag is set. +*/ + +bool dma_get_interrupt_flag(uint32_t dma, uint8_t stream, uint32_t interrupt) +{ + /* get offset to interrupt flag location in stream field. Assumes + * stream and interrupt parameters are integers. + */ + uint32_t flag = (interrupt << DMA_ISR_OFFSET(stream)); + /* First four streams are in low register */ + if (stream < 4) { + return ((DMA_LISR(dma) & flag) > 0); + } else { + return ((DMA_HISR(dma) & flag) > 0); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Transfer Direction + +Set peripheral to memory, memory to peripheral or memory to memory. If memory +to memory mode is selected, circular mode and double buffer modes are disabled. +Ensure that these modes are not enabled at a later time. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] direction unsigned int32. Data transfer direction @ref dma_st_dir +*/ + +void dma_set_transfer_mode(uint32_t dma, uint8_t stream, uint32_t direction) +{ + uint32_t reg32 = (DMA_SCR(dma, stream) & ~DMA_SxCR_DIR_MASK); + /* Disable circular and double buffer modes if memory to memory + * transfers are in effect. (Direct Mode is automatically disabled by + * hardware) + */ + if (direction == DMA_SxCR_DIR_MEM_TO_MEM) { + reg32 &= ~(DMA_SxCR_CIRC | DMA_SxCR_DBM); + } + + DMA_SCR(dma, stream) = (reg32 | direction); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Priority + +Stream Priority has four levels: low to very high. This has precedence over the +hardware priority. In the event of equal software priority the lower numbered +stream has priority. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] prio unsigned int32. Priority level @ref dma_st_pri. +*/ + +void dma_set_priority(uint32_t dma, uint8_t stream, uint32_t prio) +{ + DMA_SCR(dma, stream) &= ~(DMA_SxCR_PL_MASK); + DMA_SCR(dma, stream) |= prio; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Memory Word Width + +Set the memory word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for +alignment information if the source and destination widths do not match. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] mem_size unsigned int32. Memory word width @ref dma_st_memwidth. +*/ + +void dma_set_memory_size(uint32_t dma, uint8_t stream, uint32_t mem_size) +{ + DMA_SCR(dma, stream) &= ~(DMA_SxCR_MSIZE_MASK); + DMA_SCR(dma, stream) |= mem_size; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Peripheral Word Width + +Set the peripheral word width 8 bits, 16 bits, or 32 bits. Refer to datasheet +for alignment information if the source and destination widths do not match, or +if the peripheral does not support byte or half-word writes. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] peripheral_size unsigned int32. Peripheral word width @ref +dma_st_perwidth. +*/ + +void dma_set_peripheral_size(uint32_t dma, uint8_t stream, + uint32_t peripheral_size) +{ + DMA_SCR(dma, stream) &= ~(DMA_SxCR_PSIZE_MASK); + DMA_SCR(dma, stream) |= peripheral_size; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Memory Increment after Transfer + +Following each transfer the current memory address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_memory_size. The +value held by the base memory address register is unchanged. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_memory_increment_mode(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) |= DMA_SxCR_MINC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Memory Increment after Transfer + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_memory_increment_mode(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_MINC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Variable Sized Peripheral Increment after Transfer + +Following each transfer the current peripheral address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_peripheral_size. The +value held by the base peripheral address register is unchanged. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_peripheral_increment_mode(uint32_t dma, uint8_t stream) +{ + uint32_t reg32 = (DMA_SCR(dma, stream) | DMA_SxCR_PINC); + DMA_SCR(dma, stream) = (reg32 & ~DMA_SxCR_PINCOS); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Peripheral Increment after Transfer + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_peripheral_increment_mode(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_PINC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Fixed Sized Peripheral Increment after Transfer + +Following each transfer the current peripheral address is incremented by +4 regardless of the data size. The value held by the base peripheral address +register is unchanged. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_fixed_peripheral_increment_mode(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) |= (DMA_SxCR_PINC | DMA_SxCR_PINCOS); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Memory Circular Mode + +After the number of bytes/words to be transferred has been completed, the +original transfer block size, memory and peripheral base addresses are +reloaded and the process repeats. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@note This cannot be used with memory to memory mode. It is disabled +automatically if the peripheral is selected as the flow controller. +It is enabled automatically if double buffered mode is selected. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_circular_mode(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) |= DMA_SxCR_CIRC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Channel Select + +Associate an input channel to the stream. Not every channel is allocated to a +hardware DMA request signal. The allocations for each stream are given in the +STM32F4 Reference Manual. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] channel unsigned int8. Channel selection @ref dma_ch_sel +*/ + +void dma_channel_select(uint32_t dma, uint8_t stream, uint32_t channel) +{ + DMA_SCR(dma, stream) |= channel; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Memory Burst Configuration + +Set the memory burst type to none, 4 8 or 16 word length. This is forced to none +if direct mode is used. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] burst unsigned int8. Memory Burst selection @ref dma_mburst +*/ + +void dma_set_memory_burst(uint32_t dma, uint8_t stream, uint32_t burst) +{ + uint32_t reg32 = (DMA_SCR(dma, stream) & ~DMA_SxCR_MBURST_MASK); + DMA_SCR(dma, stream) = (reg32 | burst); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Peripheral Burst Configuration + +Set the memory burst type to none, 4 8 or 16 word length. This is forced to none +if direct mode is used. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] burst unsigned int8. Peripheral Burst selection @ref dma_pburst +*/ + +void dma_set_peripheral_burst(uint32_t dma, uint8_t stream, uint32_t burst) +{ + uint32_t reg32 = (DMA_SCR(dma, stream) & ~DMA_SxCR_PBURST_MASK); + DMA_SCR(dma, stream) = (reg32 | burst); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Initial Target Memory + +In double buffered mode, set the target memory (M0 or M1) to be used for the +first transfer. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] memory unsigned int8. Initial memory pointer to use: 0 or 1 +*/ + +void dma_set_initial_target(uint32_t dma, uint8_t stream, uint8_t memory) +{ + uint32_t reg32 = (DMA_SCR(dma, stream) & ~DMA_SxCR_CT); + if (memory == 1) { + reg32 |= DMA_SxCR_CT; + } + + DMA_SCR(dma, stream) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Read Current Memory Target + +In double buffer mode, return the current memory target (M0 or M1). It is +possible to update the memory pointer in the register that is not +currently in use. An attempt to change the register currently in use will cause +the stream to be disabled and the transfer error flag to be set. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@returns unsigned int8. Memory buffer in use: 0 or 1 +*/ + +uint8_t dma_get_target(uint32_t dma, uint8_t stream) +{ + if (DMA_SCR(dma, stream) & DMA_SxCR_CT) { + return 1; + } + + return 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Double Buffer Mode + +Double buffer mode is used for memory to/from peripheral transfers only, and in +circular mode which is automatically enabled. Two memory buffers must be +established with pointers stored in the memory pointer registers. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@note This cannot be used with memory to memory mode. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_double_buffer_mode(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) |= DMA_SxCR_DBM; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Double Buffer Mode + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_double_buffer_mode(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_DBM; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Peripheral Flow Control + +Set the peripheral to control DMA flow. Useful when the number of transfers is +unknown. This is forced off when memory to memory mode is selected. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_set_peripheral_flow_control(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) |= DMA_SxCR_PFCTRL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set DMA Flow Control + +Set the DMA controller to control DMA flow. This is the default. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_set_dma_flow_control(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_PFCTRL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_transfer_error_interrupt(uint32_t dma, uint8_t stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_TEIF); + DMA_SCR(dma, stream) |= DMA_SxCR_TEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_transfer_error_interrupt(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_TEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_half_transfer_interrupt(uint32_t dma, uint8_t stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_HTIF); + DMA_SCR(dma, stream) |= DMA_SxCR_HTIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_half_transfer_interrupt(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_HTIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_transfer_complete_interrupt(uint32_t dma, uint8_t stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_TCIF); + DMA_SCR(dma, stream) |= DMA_SxCR_TCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_transfer_complete_interrupt(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_TCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Direct Mode Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_direct_mode_error_interrupt(uint32_t dma, uint8_t stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_DMEIF); + DMA_SCR(dma, stream) |= DMA_SxCR_DMEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Direct Mode Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_direct_mode_error_interrupt(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_DMEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Enable Interrupt on FIFO Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_fifo_error_interrupt(uint32_t dma, uint8_t stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_FEIF); + DMA_SFCR(dma, stream) |= DMA_SxFCR_FEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Disable Interrupt on FIFO Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_fifo_error_interrupt(uint32_t dma, uint8_t stream) +{ + DMA_SFCR(dma, stream) &= ~DMA_SxFCR_FEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Get FIFO Status + +Status of FIFO (empty. full or partial filled states) is returned. This has no +meaning if direct mode is enabled (as the FIFO is not used). + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@returns uint32_t FIFO Status @ref dma_fifo_status +*/ + +uint32_t dma_fifo_status(uint32_t dma, uint8_t stream) +{ + return DMA_SFCR(dma, stream) & DMA_SxFCR_FS_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Enable Direct Mode + +Direct mode is the default. Data is transferred as soon as a DMA request is +received. The FIFO is not used. This must not be set when memory to memory +mode is selected. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_direct_mode(uint32_t dma, uint8_t stream) +{ + DMA_SFCR(dma, stream) &= ~DMA_SxFCR_DMDIS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Enable FIFO Mode + +Data is transferred via a FIFO. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_fifo_mode(uint32_t dma, uint8_t stream) +{ + DMA_SFCR(dma, stream) |= DMA_SxFCR_DMDIS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Set FIFO Threshold + +This is the filled level at which data is transferred out of the FIFO to the +destination. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] threshold unsigned int8. Threshold setting @ref dma_fifo_thresh +*/ + +void dma_set_fifo_threshold(uint32_t dma, uint8_t stream, uint32_t threshold) +{ + uint32_t reg32 = (DMA_SFCR(dma, stream) & ~DMA_SxFCR_FTH_MASK); + DMA_SFCR(dma, stream) = (reg32 | threshold); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_stream(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) |= DMA_SxCR_EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable + +@note The DMA stream registers retain their values when the stream is disabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_stream(uint32_t dma, uint8_t stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SxCR_EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Peripheral Address + +Set the address of the peripheral register to or from which data is to be +transferred. Refer to the documentation for the specific peripheral. + +@note The DMA stream must be disabled before setting this address. This function +has no effect if the stream is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] address unsigned int32. Peripheral Address. +*/ + +void dma_set_peripheral_address(uint32_t dma, uint8_t stream, uint32_t address) +{ + if (!(DMA_SCR(dma, stream) & DMA_SxCR_EN)) { + DMA_SPAR(dma, stream) = (uint32_t *) address; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Base Memory Address 0 + +Set the address pointer to the memory location for DMA transfers. The DMA stream +must normally be disabled before setting this address, however it is possible +to change this in double buffer mode when the current target is memory area 1 +(see @ref dma_get_target). + +This is the default base memory address used in direct mode. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] address unsigned int32. Memory Initial Address. +*/ + +void dma_set_memory_address(uint32_t dma, uint8_t stream, uint32_t address) +{ + uint32_t reg32 = DMA_SCR(dma, stream); + if (!(reg32 & DMA_SxCR_EN) || + ((reg32 & DMA_SxCR_CT) && (reg32 & DMA_SxCR_DBM))) { + DMA_SM0AR(dma, stream) = (uint32_t *) address; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Base Memory Address 1 + +Set the address pointer to the memory location for DMA transfers. The DMA stream +must normally be disabled before setting this address, however it is possible +to change this in double buffer mode when the current target is memory area 0 +(see @ref dma_get_target). + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] address unsigned int32. Memory Initial Address. +*/ + +void dma_set_memory_address_1(uint32_t dma, uint8_t stream, uint32_t address) +{ + uint32_t reg32 = DMA_SCR(dma, stream); + if (!(reg32 & DMA_SxCR_EN) || + (!(reg32 & DMA_SxCR_CT) && (reg32 & DMA_SxCR_DBM))) { + DMA_SM1AR(dma, stream) = (uint32_t *) address; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Transfer Block Size + +@note The DMA stream must be disabled before setting this count value. The count +is not changed if the stream is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] number unsigned int16. Number of data words to transfer (65535 +maximum). +*/ + +void dma_set_number_of_data(uint32_t dma, uint8_t stream, uint16_t number) +{ + DMA_SNDTR(dma, stream) = number; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_l1f013.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_l1f013.c new file mode 100644 index 00000000..0005c113 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/dma_common_l1f013.c @@ -0,0 +1,435 @@ +/** @addtogroup dma_file + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +This library supports the DMA Control System in the STM32 series of ARM Cortex +Microcontrollers by ST Microelectronics. + +Up to two DMA controllers are supported. 12 DMA channels are allocated 7 to +the first DMA controller and 5 to the second. Each channel is connected to +between 3 and 6 hardware peripheral DMA signals in a logical OR arrangement. + +DMA transfers can be configured to occur between peripheral and memory in +any combination including memory to memory. Circular mode transfers are +also supported in transfers involving a peripheral. An arbiter is provided +to resolve priority DMA requests. Transfers can be made with 8, 16 or 32 bit +words. + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Reset + +The channel is disabled and configuration registers are cleared. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_channel_reset(uint32_t dma, uint8_t channel) +{ + /* Disable channel and reset config bits. */ + DMA_CCR(dma, channel) = 0; + /* Reset data transfer number. */ + DMA_CNDTR(dma, channel) = 0; + /* Reset peripheral address. */ + DMA_CPAR(dma, channel) = 0; + /* Reset memory address. */ + DMA_CMAR(dma, channel) = 0; + /* Reset interrupt flags. */ + DMA_IFCR(dma) |= DMA_IFCR_CIF(channel); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Clear Interrupt Flag + +The interrupt flag for the channel is cleared. More than one interrupt for the +same channel may be cleared by using the logical OR of the interrupt flags. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: @ref dma_ch +@param[in] interrupts unsigned int32. Logical OR of interrupt numbers: @ref +dma_if_offset +*/ + +void dma_clear_interrupt_flags(uint32_t dma, uint8_t channel, + uint32_t interrupts) +{ +/* Get offset to interrupt flag location in channel field */ + uint32_t flags = (interrupts << DMA_FLAG_OFFSET(channel)); + DMA_IFCR(dma) = flags; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Read Interrupt Flag + +The interrupt flag for the channel is returned. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: @ref dma_ch +@param[in] interrupt unsigned int32. Interrupt number: @ref dma_if_offset +@returns bool interrupt flag is set. +*/ + +bool dma_get_interrupt_flag(uint32_t dma, uint8_t channel, uint32_t interrupt) +{ +/* get offset to interrupt flag location in channel field. */ + uint32_t flag = (interrupt << DMA_FLAG_OFFSET(channel)); + return ((DMA_ISR(dma) & flag) > 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Memory to Memory Transfers + +Memory to memory transfers do not require a trigger to activate each transfer. +Transfers begin immediately the channel has been enabled, and proceed without +intervention. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_mem2mem_mode(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_MEM2MEM; + DMA_CCR(dma, channel) &= ~DMA_CCR_CIRC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Set Priority + +Channel Priority has four levels: low to very high. This has precedence over the +hardware priority. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] prio unsigned int32. Priority level @ref dma_ch_pri. +*/ + +void dma_set_priority(uint32_t dma, uint8_t channel, uint32_t prio) +{ + DMA_CCR(dma, channel) &= ~(DMA_CCR_PL_MASK); + DMA_CCR(dma, channel) |= prio; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Set Memory Word Width + +Set the memory word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for +alignment information if the source and destination widths do not match. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] mem_size unsigned int32. Memory word width @ref dma_ch_memwidth. +*/ + +void dma_set_memory_size(uint32_t dma, uint8_t channel, uint32_t mem_size) +{ + + DMA_CCR(dma, channel) &= ~(DMA_CCR_MSIZE_MASK); + DMA_CCR(dma, channel) |= mem_size; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Set Peripheral Word Width + +Set the peripheral word width 8 bits, 16 bits, or 32 bits. Refer to datasheet +for alignment information if the source and destination widths do not match, or +if the peripheral does not support byte or half-word writes. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] peripheral_size unsigned int32. Peripheral word width @ref +dma_ch_perwidth. +*/ + +void dma_set_peripheral_size(uint32_t dma, uint8_t channel, + uint32_t peripheral_size) +{ + DMA_CCR(dma, channel) &= ~(DMA_CCR_PSIZE_MASK); + DMA_CCR(dma, channel) |= peripheral_size; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Memory Increment after Transfer + +Following each transfer the current memory address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_memory_size. The +value held by the base memory address register is unchanged. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_memory_increment_mode(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_MINC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Memory Increment after Transfer + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_disable_memory_increment_mode(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_MINC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Peripheral Increment after Transfer + +Following each transfer the current peripheral address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_peripheral_size. The +value held by the base peripheral address register is unchanged. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_peripheral_increment_mode(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_PINC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Peripheral Increment after Transfer + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_disable_peripheral_increment_mode(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_PINC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Memory Circular Mode + +After the number of bytes/words to be transferred has been completed, the +original transfer block size, memory and peripheral base addresses are +reloaded and the process repeats. + +@note This cannot be used with memory to memory mode, which is explicitly +disabled here. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_circular_mode(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_CIRC; + DMA_CCR(dma, channel) &= ~DMA_CCR_MEM2MEM; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Transfers from a Peripheral + +The data direction is set to read from a peripheral. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_set_read_from_peripheral(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_DIR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Transfers from Memory + +The data direction is set to read from memory. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_set_read_from_memory(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_DIR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_transfer_error_interrupt(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_TEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_disable_transfer_error_interrupt(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_TEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_half_transfer_interrupt(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_HTIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_disable_half_transfer_interrupt(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_HTIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_transfer_complete_interrupt(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_TCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_disable_transfer_complete_interrupt(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_TCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_enable_channel(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) |= DMA_CCR_EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable + +@note The DMA channel registers retain their values when the channel is +disabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_disable_channel(uint32_t dma, uint8_t channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Peripheral Address + +Set the address of the peripheral register to or from which data is to be +transferred. Refer to the documentation for the specific peripheral. + +@note The DMA channel must be disabled before setting this address. This +function has no effect if the channel is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] address unsigned int32. Peripheral Address. +*/ + +void dma_set_peripheral_address(uint32_t dma, uint8_t channel, uint32_t address) +{ + if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) { + DMA_CPAR(dma, channel) = (uint32_t) address; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Base Memory Address + +@note The DMA channel must be disabled before setting this address. This +function has no effect if the channel is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] address unsigned int32. Memory Initial Address. +*/ + +void dma_set_memory_address(uint32_t dma, uint8_t channel, uint32_t address) +{ + if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) { + DMA_CMAR(dma, channel) = (uint32_t) address; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Transfer Block Size + +@note The DMA channel must be disabled before setting this count value. The +count is not changed if the channel is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] number unsigned int16. Number of data words to transfer (65535 +maximum). +*/ + +void dma_set_number_of_data(uint32_t dma, uint8_t channel, uint16_t number) +{ + DMA_CNDTR(dma, channel) = number; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/exti_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/exti_common_all.c new file mode 100644 index 00000000..d2135f29 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/exti_common_all.c @@ -0,0 +1,164 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Mark Butler + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + * This provides the code for the "next gen" EXTI block provided in F2/F4/L1 + * devices. (differences only in the source selection) + */ +/**@{*/ + + +#include +#include +#if !defined(AFIO_BASE) +# include +#endif + +void exti_set_trigger(uint32_t extis, enum exti_trigger_type trig) +{ + switch (trig) { + case EXTI_TRIGGER_RISING: + EXTI_RTSR |= extis; + EXTI_FTSR &= ~extis; + break; + case EXTI_TRIGGER_FALLING: + EXTI_RTSR &= ~extis; + EXTI_FTSR |= extis; + break; + case EXTI_TRIGGER_BOTH: + EXTI_RTSR |= extis; + EXTI_FTSR |= extis; + break; + } +} + +void exti_enable_request(uint32_t extis) +{ + /* Enable interrupts. */ + EXTI_IMR |= extis; + + /* Enable events. */ + EXTI_EMR |= extis; +} + +void exti_disable_request(uint32_t extis) +{ + /* Disable interrupts. */ + EXTI_IMR &= ~extis; + + /* Disable events. */ + EXTI_EMR &= ~extis; +} + +/* + * Reset the interrupt request by writing a 1 to the corresponding + * pending bit register. + */ +void exti_reset_request(uint32_t extis) +{ + EXTI_PR = extis; +} + +/* + * Check the flag of a given EXTI interrupt. + * */ +uint32_t exti_get_flag_status(uint32_t exti) +{ + return EXTI_PR & exti; +} + +/* + * Remap an external interrupt line to the corresponding pin on the + * specified GPIO port. + * + * TODO: This could be rewritten in fewer lines of code. + */ +void exti_select_source(uint32_t exti, uint32_t gpioport) +{ + uint32_t line; + for (line = 0; line < 16; line++) { + if (!(exti & (1 << line))) { + continue; + } + + uint32_t bits = 0, mask = 0x0F; + + switch (gpioport) { + case GPIOA: + bits = 0; + break; + case GPIOB: + bits = 1; + break; + case GPIOC: + bits = 2; + break; + case GPIOD: + bits = 3; + break; +#if defined(GPIOE) && defined(GPIO_PORT_E_BASE) + case GPIOE: + bits = 4; + break; +#endif +#if defined(GPIOF) && defined(GPIO_PORT_F_BASE) + case GPIOF: + bits = 5; + break; +#endif +#if defined(GPIOG) && defined(GPIO_PORT_G_BASE) + case GPIOG: + bits = 6; + break; +#endif +#if defined(GPIOH) && defined(GPIO_PORT_H_BASE) + case GPIOH: + bits = 7; + break; +#endif +#if defined(GPIOI) && defined(GPIO_PORT_I_BASE) + case GPIOI: + bits = 8; + break; +#endif +#if defined(GPIOJ) && defined(GPIO_PORT_J_BASE) + case GPIOJ: + bits = 9; + break; +#endif +#if defined(GPIOK) && defined(GPIO_PORT_K_BASE) + case GPIOK: + bits = 10; + break; +#endif + } + + uint8_t shift = (uint8_t)(4 * (line % 4)); + uint32_t reg = line / 4; + bits <<= shift; + mask <<= shift; + +#if defined(AFIO_BASE) + AFIO_EXTICR(reg) = (AFIO_EXTICR(reg) & ~mask) | bits; +#else + SYSCFG_EXTICR(reg) = (SYSCFG_EXTICR(reg) & ~mask) | bits; +#endif + }; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f01.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f01.c new file mode 100644 index 00000000..8c1a79ac --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f01.c @@ -0,0 +1,235 @@ +/** @addtogroup flash_file + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the FLASH Prefetch Buffer + +This buffer is used for instruction fetches and is enabled by default after +reset. + +Note carefully the clock restrictions under which the prefetch buffer may be +enabled or disabled. Changes are normally made while the clock is running in +the power-on low frequency mode before being set to a higher speed mode. +See the reference manual for details. +*/ + +void flash_prefetch_buffer_enable(void) +{ + FLASH_ACR |= FLASH_ACR_PRFTBE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the FLASH Prefetch Buffer + +Note carefully the clock restrictions under which the prefetch buffer may be +set to disabled. See the reference manual for details. +*/ + +void flash_prefetch_buffer_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_PRFTBE; +} +/*---------------------------------------------------------------------------*/ +/** @brief Set the Number of Wait States + +Used to match the system clock to the FLASH memory access time. See the +reference manual for more information on clock speed ranges for each wait state. +The latency must be changed to the appropriate value before any increase +in clock speed, or after any decrease in clock speed. + +@param[in] ws values from @ref flash_latency. +*/ + +void flash_set_ws(uint32_t ws) +{ + FLASH_ACR = (FLASH_ACR & ~FLASH_ACR_LATENCY) | ws; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock the Flash Program and Erase Controller + +This enables write access to the Flash memory. It is locked by default on +reset. +*/ + +void flash_unlock(void) +{ + /* Clear the unlock state. */ + FLASH_CR |= FLASH_CR_LOCK; + + /* Authorize the FPEC access. */ + FLASH_KEYR = FLASH_KEYR_KEY1; + FLASH_KEYR = FLASH_KEYR_KEY2; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock the Flash Program and Erase Controller + +Used to prevent spurious writes to FLASH. +*/ + +void flash_lock(void) +{ + FLASH_CR |= FLASH_CR_LOCK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Error Status Flag + +*/ + +void flash_clear_pgerr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the End of Operation Status Flag + +*/ + +void flash_clear_eop_flag(void) +{ + FLASH_SR |= FLASH_SR_EOP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Write Protect Error Status Flag + +*/ + +void flash_clear_wrprterr_flag(void) +{ + FLASH_SR |= FLASH_SR_WRPRTERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Busy Status Flag + +*/ + +void flash_clear_bsy_flag(void) +{ + FLASH_SR &= ~FLASH_SR_BSY; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Wait until Last Operation has Ended + +This loops indefinitely until an operation (write or erase) has completed by +testing the busy flag. +*/ + +void flash_wait_for_last_operation(void) +{ + while ((flash_get_status_flags() & FLASH_SR_BSY) == FLASH_SR_BSY); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a 32 bit Word to FLASH + +This performs all operations necessary to program a 32 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +Status bit polling is used to detect end of operation. + +@param[in] address Full address of flash word to be programmed. +@param[in] data word to write +*/ + +void flash_program_word(uint32_t address, uint32_t data) +{ + flash_program_half_word(address, (uint16_t)data); + flash_program_half_word(address+2, (uint16_t)(data>>16)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock the Option Byte Access + +This enables write access to the option bytes. It is locked by default on +reset. +*/ + +void flash_unlock_option_bytes(void) +{ + /* F1 uses same keys for flash and option */ + FLASH_OPTKEYR = FLASH_KEYR_KEY1; + FLASH_OPTKEYR = FLASH_KEYR_KEY2; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase All Option Bytes + +This performs all operations necessary to erase the option bytes. These must +first be fully erased before attempting to program them, therefore it is +recommended to check these after an erase attempt. +*/ + +void flash_erase_option_bytes(void) +{ + flash_wait_for_last_operation(); + + if ((FLASH_CR & FLASH_CR_OPTWRE) == 0) { + flash_unlock_option_bytes(); + } + + FLASH_CR |= FLASH_CR_OPTER; /* Enable option byte erase. */ + FLASH_CR |= FLASH_CR_STRT; + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_OPTER; /* Disable option byte erase. */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program the Option Bytes + +This performs all operations necessary to program the option bytes. +The write protect error flag should be checked separately for the event that +an option byte had not been properly erased before calling this function. + +Only the lower 8 bits of the data is significant. + +@param[in] address Address of option byte from @ref flash_options. +@param[in] data value to write +*/ + +void flash_program_option_bytes(uint32_t address, uint16_t data) +{ + flash_wait_for_last_operation(); + + if ((FLASH_CR & FLASH_CR_OPTWRE) == 0) { + flash_unlock_option_bytes(); + } + + FLASH_CR |= FLASH_CR_OPTPG; /* Enable option byte programming. */ + MMIO16(address) = data; + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_OPTPG; /* Disable option byte programming. */ +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f234.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f234.c new file mode 100644 index 00000000..1977fbbe --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f234.c @@ -0,0 +1,120 @@ +/** @addtogroup flash_file + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Number of Wait States + +Used to match the system clock to the FLASH memory access time. See the +programming manual for more information on clock speed ranges. The latency must +be changed to the appropriate value before any increase in clock +speed, or after any decrease in clock speed. + +@param[in] ws values from @ref flash_latency. +*/ +void flash_set_ws(uint32_t ws) +{ + uint32_t reg32; + + reg32 = FLASH_ACR; + reg32 &= ~(FLASH_ACR_LATENCY_MASK); + reg32 |= ws; + FLASH_ACR = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock the Flash Program and Erase Controller + +This enables write access to the Flash memory. It is locked by default on +reset. +*/ + +void flash_unlock(void) +{ + /* Clear the unlock sequence state. */ + FLASH_CR |= FLASH_CR_LOCK; + + /* Authorize the FPEC access. */ + FLASH_KEYR = FLASH_KEYR_KEY1; + FLASH_KEYR = FLASH_KEYR_KEY2; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock the Flash Program and Erase Controller + +Used to prevent spurious writes to FLASH. +*/ + +void flash_lock(void) +{ + FLASH_CR |= FLASH_CR_LOCK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Error Status Flag + +*/ + +void flash_clear_pgperr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGPERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the End of Operation Status Flag + +*/ + +void flash_clear_eop_flag(void) +{ + FLASH_SR |= FLASH_SR_EOP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Busy Status Flag + +*/ + +void flash_clear_bsy_flag(void) +{ + FLASH_SR &= ~FLASH_SR_BSY; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief Wait until Last Operation has Ended + +This loops indefinitely until an operation (write or erase) has completed by +testing the busy flag. +*/ + +void flash_wait_for_last_operation(void) +{ + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f24.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f24.c new file mode 100644 index 00000000..4864bd6b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_f24.c @@ -0,0 +1,414 @@ +/** @addtogroup flash_file + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Program Parallelism Size + +Set the programming word width. Note carefully the power supply voltage +restrictions under which the different word sizes may be used. See the +programming manual for more information. +@param[in] psize The programming word width one of: @ref flash_cr_program_width +*/ + +static inline void flash_set_program_size(uint32_t psize) +{ + FLASH_CR &= ~(FLASH_CR_PROGRAM_MASK << FLASH_CR_PROGRAM_SHIFT); + FLASH_CR |= psize << FLASH_CR_PROGRAM_SHIFT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Data Cache + +*/ + +void flash_dcache_enable(void) +{ + FLASH_ACR |= FLASH_ACR_DCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the Data Cache + +*/ + +void flash_dcache_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_DCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Instruction Cache + +*/ + +void flash_icache_enable(void) +{ + FLASH_ACR |= FLASH_ACR_ICEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the Instruction Cache + +*/ + +void flash_icache_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_ICEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the FLASH Prefetch Buffer + +This buffer is used for instruction fetches and is enabled by default after +reset. + +Note carefully the clock restrictions under which the prefetch buffer may be +enabled or disabled. Changes are normally made while the clock is running in +the power-on low frequency mode before being set to a higher speed mode. +See the reference manual for details. +*/ + +void flash_prefetch_enable(void) +{ + FLASH_ACR |= FLASH_ACR_PRFTEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the FLASH Prefetch Buffer + +Note carefully the clock restrictions under which the prefetch buffer may be +set to disabled. See the reference manual for details. +*/ + +void flash_prefetch_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_PRFTEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset the Data Cache + +The data cache must be disabled for this to have effect. +*/ + +void flash_dcache_reset(void) +{ + FLASH_ACR |= FLASH_ACR_DCRST; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset the Instruction Cache + +The instruction cache must be disabled for this to have effect. +*/ + +void flash_icache_reset(void) +{ + FLASH_ACR |= FLASH_ACR_ICRST; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Sequence Error Flag + +This flag is set when incorrect programming configuration has been made. +*/ + +void flash_clear_pgserr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGSERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Alignment Error Flag + +*/ + +void flash_clear_pgaerr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGAERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Write Protect Error Flag + +*/ + +void flash_clear_wrperr_flag(void) +{ + FLASH_SR |= FLASH_SR_WRPERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Program error, end of operation, write protect error, busy. +*/ + +void flash_clear_status_flags(void) +{ + flash_clear_pgserr_flag(); + flash_clear_pgaerr_flag(); + flash_clear_wrperr_flag(); + flash_clear_pgperr_flag(); + flash_clear_eop_flag(); + flash_clear_bsy_flag(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock the Option Byte Access + +This enables write access to the option bytes. It is locked by default on +reset. +*/ + +void flash_unlock_option_bytes(void) +{ + /* Clear the unlock state. */ + FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK; + + /* Unlock option bytes. */ + FLASH_OPTKEYR = FLASH_OPTKEYR_KEY1; + FLASH_OPTKEYR = FLASH_OPTKEYR_KEY2; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock the Option Byte Access + +This disables write access to the option bytes. It is locked by default on +reset. +*/ + +void flash_lock_option_bytes(void) +{ + FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a 64 bit Word to FLASH + +This performs all operations necessary to program a 64 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] address Starting address in Flash. +@param[in] data Double word to write +*/ + +void flash_program_double_word(uint32_t address, uint64_t data) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X64); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_CR_PG; + + /* Program the double_word. */ + MMIO64(address) = data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_CR_PG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a 32 bit Word to FLASH + +This performs all operations necessary to program a 32 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] address Starting address in Flash. +@param[in] data word to write +*/ + +void flash_program_word(uint32_t address, uint32_t data) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X32); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_CR_PG; + + /* Program the word. */ + MMIO32(address) = data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_CR_PG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a Half Word to FLASH + +This performs all operations necessary to program a 16 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] address Starting address in Flash. +@param[in] data half word to write +*/ + +void flash_program_half_word(uint32_t address, uint16_t data) +{ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X16); + + FLASH_CR |= FLASH_CR_PG; + + MMIO16(address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_CR_PG; /* Disable the PG bit. */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program an 8 bit Byte to FLASH + +This performs all operations necessary to program an 8 bit byte to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] address Starting address in Flash. +@param[in] data byte to write +*/ + +void flash_program_byte(uint32_t address, uint8_t data) +{ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X8); + + FLASH_CR |= FLASH_CR_PG; + + MMIO8(address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_CR_PG; /* Disable the PG bit. */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a Data Block to FLASH + +This programs an arbitrary length data block to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] address Starting address in Flash. +@param[in] data Pointer to start of data block. +@param[in] len Length of data block. +*/ + +void flash_program(uint32_t address, uint8_t *data, uint32_t len) +{ + /* TODO: Use dword and word size program operations where possible for + * turbo speed. + */ + uint32_t i; + for (i = 0; i < len; i++) { + flash_program_byte(address+i, data[i]); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase a Sector of FLASH + +This performs all operations necessary to erase a sector in FLASH memory. +The page should be checked to ensure that it was properly erased. A sector must +first be fully erased before attempting to program it. + +See the reference manual or the FLASH programming manual for details. + +@param[in] sector (0 - 11 for some parts, 0-23 on others) +@param program_size: 0 (8-bit), 1 (16-bit), 2 (32-bit), 3 (64-bit) +*/ + +void flash_erase_sector(uint8_t sector, uint32_t program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + FLASH_CR &= ~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT); + FLASH_CR |= (sector & FLASH_CR_SNB_MASK) << FLASH_CR_SNB_SHIFT; + FLASH_CR |= FLASH_CR_SER; + FLASH_CR |= FLASH_CR_STRT; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_SER; + FLASH_CR &= ~(FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase All FLASH + +This performs all operations necessary to erase all sectors in the FLASH +memory. + +@param program_size: 0 (8-bit), 1 (16-bit), 2 (32-bit), 3 (64-bit) +*/ + +void flash_erase_all_sectors(uint32_t program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */ + FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */ + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program the Option Bytes + +This performs all operations necessary to program the option bytes. +The option bytes do not need to be erased first. + +@param[in] data value to be programmed. +*/ + +void flash_program_option_bytes(uint32_t data) +{ + flash_wait_for_last_operation(); + + if (FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) { + flash_unlock_option_bytes(); + } + + FLASH_OPTCR = data & ~0x3; + FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT; /* Enable option byte prog. */ + flash_wait_for_last_operation(); +} +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_l01.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_l01.c new file mode 100644 index 00000000..48b99f14 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/flash_common_l01.c @@ -0,0 +1,191 @@ +/** @addtogroup flash_file + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * Copyright (C) 2012-13 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Flash routines shared by L0/L1. L4 has a different flash controller */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the FLASH Prefetch Buffer + +This buffer is used for instruction fetches and is enabled by default after +reset. + +Note carefully the restrictions under which the prefetch buffer may be +enabled or disabled. Prefetch is only available when 64-bit +access is enabled. +*/ + +void flash_prefetch_enable(void) +{ + FLASH_ACR |= FLASH_ACR_PRFTEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the FLASH Prefetch Buffer + +Note carefully the restrictions under which the prefetch buffer may be +set to disabled. See the reference and programming manuals for details. +*/ + +void flash_prefetch_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_PRFTEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Number of Wait States + +Used to match the system clock to the FLASH memory access time. See the +programming manual for more information on clock speed and voltage ranges. The +latency must be changed to the appropriate value before any increase in +clock speed, or after any decrease in clock speed. A latency setting of +zero only applies if 64-bit mode is not used. + +@param[in] ws values from @ref flash_latency. +*/ + +void flash_set_ws(uint32_t ws) +{ + uint32_t reg32; + + reg32 = FLASH_ACR; + reg32 &= ~(1 << 0); + reg32 |= ws; + FLASH_ACR = reg32; +} + +/** + * Unlock primary access to the flash control/erase block + * You must call this before using any of the low level routines + * yourself. + * @sa flash_unlock + */ +void flash_unlock_pecr(void) +{ + FLASH_PEKEYR = FLASH_PEKEYR_PEKEY1; + FLASH_PEKEYR = FLASH_PEKEYR_PEKEY2; +} + +void flash_lock_pecr(void) +{ + FLASH_PECR |= FLASH_PECR_PELOCK; +} + +/** + * Unlock program memory itself. + * Writes the magic sequence to unlock the program memory + * you must have already unlocked access to this register! + * @sa flash_unlock_pecr + */ +void flash_unlock_progmem(void) +{ + FLASH_PRGKEYR = FLASH_PRGKEYR_PRGKEY1; + FLASH_PRGKEYR = FLASH_PRGKEYR_PRGKEY2; +} + +void flash_lock_progmem(void) +{ + FLASH_PECR |= FLASH_PECR_PRGLOCK; +} + +/** + * Unlock option bytes. + * Writes the magic sequence to unlock the option bytes, + * you must have already unlocked access to this register! + * @sa flash_unlock_pecr + */ +void flash_unlock_option_bytes(void) +{ + FLASH_OPTKEYR = FLASH_OPTKEYR_OPTKEY1; + FLASH_OPTKEYR = FLASH_OPTKEYR_OPTKEY2; +} + +void flash_lock_option_bytes(void) +{ + FLASH_PECR |= FLASH_PECR_OPTLOCK; +} + +/** @brief Unlock all segments of flash + * + */ +void flash_unlock(void) +{ + flash_unlock_pecr(); + flash_unlock_progmem(); + flash_unlock_option_bytes(); +} + +/** @brief Lock all segments of flash + * + */ +void flash_lock(void) +{ + flash_lock_option_bytes(); + flash_lock_progmem(); + flash_lock_pecr(); +} + +/** @brief Write a word to eeprom + * + * @param address assumed to be in the eeprom space, no checking + * @param data word to write + */ +void eeprom_program_word(uint32_t address, uint32_t data) +{ + flash_unlock_pecr(); + /* erase only if needed */ + FLASH_PECR &= ~FLASH_PECR_FTDW; + MMIO32(address) = data; + flash_lock_pecr(); +} + +/** @brief Write a block of words to eeprom + * + * Writes a block of words to EEPROM at the requested address, erasing if + * necessary, and locking afterwards. Only wordwise writing is safe for + * writing any value + * + * @param[in] address must point to EEPROM space, no checking! + * @param[in] data pointer to data to write + * @param[in] length_in_words size of of data in WORDS! + */ +void eeprom_program_words(uint32_t address, uint32_t *data, int length_in_words) +{ + int i; + flash_unlock_pecr(); + while (FLASH_SR & FLASH_SR_BSY); + /* erase only if needed */ + FLASH_PECR &= ~FLASH_PECR_FTDW; + for (i = 0; i < length_in_words; i++) { + MMIO32(address + (i * sizeof(uint32_t))) = *(data+i); + while (FLASH_SR & FLASH_SR_BSY); + } + flash_lock_pecr(); +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_all.c new file mode 100644 index 00000000..98d15ad4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_all.c @@ -0,0 +1,151 @@ +/** @addtogroup gpio_file + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief Set a Group of Pins Atomic + +Set one or more pins of the given GPIO port to 1 in an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use bitwise OR '|' to separate + them. +*/ +void gpio_set(uint32_t gpioport, uint16_t gpios) +{ + GPIO_BSRR(gpioport) = gpios; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear a Group of Pins Atomic + +Clear one or more pins of the given GPIO port to 0 in an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use bitwise OR '|' to separate + them. +*/ +void gpio_clear(uint32_t gpioport, uint16_t gpios) +{ + GPIO_BSRR(gpioport) = (gpios << 16); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read a Group of Pins. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be read, use bitwise OR '|' to separate + them. +@return Unsigned int16 value of the pin values. The bit position of the pin + value returned corresponds to the pin number. +*/ +uint16_t gpio_get(uint32_t gpioport, uint16_t gpios) +{ + return gpio_port_read(gpioport) & gpios; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Toggle a Group of Pins + +Toggle one or more pins of the given GPIO port. The toggling is not atomic, but +the non-toggled pins are not affected. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use bitwise OR '|' to separate + them. +*/ +void gpio_toggle(uint32_t gpioport, uint16_t gpios) +{ + uint32_t port = GPIO_ODR(gpioport); + GPIO_BSRR(gpioport) = ((port & gpios) << 16) | (~port & gpios); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read from a Port + +Read the current value of the given GPIO port. Only the lower 16 bits contain +valid pin data. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@return Unsigned int16. The value held in the specified GPIO port. +*/ +uint16_t gpio_port_read(uint32_t gpioport) +{ + return (uint16_t)GPIO_IDR(gpioport); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Write to a Port + +Write a value to the given GPIO port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] data Unsigned int16. The value to be written to the GPIO port. +*/ +void gpio_port_write(uint32_t gpioport, uint16_t data) +{ + GPIO_ODR(gpioport) = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock the Configuration of a Group of Pins + +The configuration of one or more pins of the given GPIO port is locked. There +is no mechanism to unlock these via software. Unlocking occurs at the next +reset. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be locked, use bitwise OR '|' to separate + them. +*/ +void gpio_port_config_lock(uint32_t gpioport, uint16_t gpios) +{ + uint32_t reg32; + + /* Special "Lock Key Writing Sequence", see datasheet. */ + GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ + GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */ + GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ + reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */ + reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */ + + /* Tell the compiler the variable is actually used. It will get + * optimized out anyways. + */ + reg32 = reg32; + + /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */ +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_f0234.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_f0234.c new file mode 100644 index 00000000..f92c2f94 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/gpio_common_f0234.c @@ -0,0 +1,206 @@ +/** @addtogroup gpio_file + +@author @htmlonly © @endhtmlonly 2009 +Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +Each I/O port has 16 individually configurable bits. Many I/O pins share GPIO +functionality with a number of alternate functions and must be configured to +the alternate function mode if these are to be accessed. A feature is available +to remap alternative functions to a limited set of alternative pins in the +event of a clash of requirements. + +The data registers associated with each port for input and output are 32 bit +with the upper 16 bits unused. The output buffer must be written as a 32 bit +word, but individual bits may be set or reset separately in atomic operations +to avoid race conditions during interrupts. Bits may also be individually +locked to prevent accidental configuration changes. Once locked the +configuration cannot be changed until after the next reset. + +Each port bit can be configured as analog or digital input, the latter can be +floating or pulled up or down. As outputs they can be configured as either +push-pull or open drain, digital I/O or alternate function, and with maximum +output speeds of 2MHz, 10MHz, or 50MHz. + +On reset all ports are configured as digital floating input. + +@section gpio_api_ex Basic GPIO Handling API. + +Example 1: Push-pull digital output actions with pullup on ports C2 and C9 + +@code + gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, + GPIO_PUPD_PULLUP, GPIO2 | GPIO9); + gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, + GPIO_OSPEED_25MHZ, GPIO2 | GPIO9); + gpio_set(GPIOC, GPIO2 | GPIO9); + gpio_clear(GPIOC, GPIO2); + gpio_toggle(GPIOC, GPIO2 | GPIO9); + gpio_port_write(GPIOC, 0x204); +@endcode + +Example 2: Digital input on port C12 with pullup + +@code + gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, + GPIO_PUPD_PULLUP, GPIO12); + reg16 = gpio_port_read(GPIOC); +@endcode + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO Pin Mode + +Sets the Pin Direction and Analog/Digital Mode, and Output Pin Pullup, +for a set of GPIO pins on a given GPIO port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] mode Unsigned int8. Pin mode @ref gpio_mode +@param[in] pull_up_down Unsigned int8. Pin pullup/pulldown configuration @ref +gpio_pup +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be set, use bitwise OR '|' to separate + them. +*/ +void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t pull_up_down, + uint16_t gpios) +{ + uint16_t i; + uint32_t moder, pupd; + + /* + * We want to set the config only for the pins mentioned in gpios, + * but keeping the others, so read out the actual config first. + */ + moder = GPIO_MODER(gpioport); + pupd = GPIO_PUPDR(gpioport); + + for (i = 0; i < 16; i++) { + if (!((1 << i) & gpios)) { + continue; + } + + moder &= ~GPIO_MODE_MASK(i); + moder |= GPIO_MODE(i, mode); + pupd &= ~GPIO_PUPD_MASK(i); + pupd |= GPIO_PUPD(i, pull_up_down); + } + + /* Set mode and pull up/down control registers. */ + GPIO_MODER(gpioport) = moder; + GPIO_PUPDR(gpioport) = pupd; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO Output Options + +When the pin is set to output mode, this sets the configuration (analog/digital +and open drain/push pull) and speed, for a set of GPIO pins on a given GPIO +port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] otype Unsigned int8. Pin output type @ref gpio_output_type +@param[in] speed Unsigned int8. Pin speed @ref gpio_speed +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be set, use bitwise OR '|' to separate + them. +*/ +void gpio_set_output_options(uint32_t gpioport, uint8_t otype, uint8_t speed, + uint16_t gpios) +{ + uint16_t i; + uint32_t ospeedr; + + if (otype == 0x1) { + GPIO_OTYPER(gpioport) |= gpios; + } else { + GPIO_OTYPER(gpioport) &= ~gpios; + } + + ospeedr = GPIO_OSPEEDR(gpioport); + + for (i = 0; i < 16; i++) { + if (!((1 << i) & gpios)) { + continue; + } + ospeedr &= ~GPIO_OSPEED_MASK(i); + ospeedr |= GPIO_OSPEED(i, speed); + } + + GPIO_OSPEEDR(gpioport) = ospeedr; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO Alternate Function Selection + +Set the alternate function mapping number for each pin. Most pins have +alternate functions associated with them. When set to AF mode, a pin may be +used for one of its allocated alternate functions selected by the number given +here. To determine the number to be used for the desired function refer to the +individual datasheet for the particular device. A table is given under the Pin +Selection chapter. + +Note that a number of pins may be set but only with a single AF number. In +practice this would rarely be useful as each pin is likely to require a +different number. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] alt_func_num Unsigned int8. Pin alternate function number @ref +gpio_af_num +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be set, use bitwise OR '|' to separate + them. +*/ +void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint16_t gpios) +{ + uint16_t i; + uint32_t afrl, afrh; + + afrl = GPIO_AFRL(gpioport); + afrh = GPIO_AFRH(gpioport); + + for (i = 0; i < 8; i++) { + if (!((1 << i) & gpios)) { + continue; + } + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR(i, alt_func_num); + } + + for (i = 8; i < 16; i++) { + if (!((1 << i) & gpios)) { + continue; + } + afrh &= ~GPIO_AFR_MASK(i - 8); + afrh |= GPIO_AFR(i - 8, alt_func_num); + } + + GPIO_AFRL(gpioport) = afrl; + GPIO_AFRH(gpioport) = afrh; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/hash_common_f24.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/hash_common_f24.c new file mode 100644 index 00000000..24d489c1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/hash_common_f24.c @@ -0,0 +1,163 @@ +/** @addtogroup hash_file + * + * @author @htmlonly © @endhtmlonly 2013 + * Mikhail Avkhimenia + * + * This library supports the HASH processor in the STM32F2 and STM32F4 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Mikhail Avkhimenia + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Set Mode + +Sets up the specified mode - either HASH or HMAC. + +@param[in] mode unsigned int8. Hash processor mode: @ref hash_mode +*/ + +void hash_set_mode(uint8_t mode) +{ + HASH_CR &= ~HASH_CR_MODE; + HASH_CR |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Set Algorithm + +Sets up the specified algorithm - either MD5 or SHA1. + +@param[in] algorithm unsigned int8. Hash algorithm: @ref hash_algorithm +*/ + +void hash_set_algorithm(uint8_t algorithm) +{ + HASH_CR &= ~HASH_CR_ALGO; + HASH_CR |= algorithm; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Set Data Type + +Sets up the specified data type: 32Bit, 16Bit, 8Bit, Bitstring. + +@param[in] datatype unsigned int8. Hash data type: @ref hash_data_type +*/ + +void hash_set_data_type(uint8_t datatype) +{ + HASH_CR &= ~HASH_CR_DATATYPE; + HASH_CR |= datatype; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Set Key Length + +Sets up the specified key length: Long, Short. + +@param[in] keylength unsigned int8. Hash data type: @ref hash_key_length +*/ + +void hash_set_key_length(uint8_t keylength) +{ + HASH_CR &= ~HASH_CR_LKEY; + HASH_CR |= keylength; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Set Last Word Valid Bits + +Specifies the number of valid bits in the last word. + +@param[in] validbits unsigned int8. Number of valid bits. +*/ + +void hash_set_last_word_valid_bits(uint8_t validbits) +{ + HASH_STR &= ~(HASH_STR_NBW); + HASH_STR |= validbits; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Init + +Initializes the HASH processor. + +*/ + +void hash_init() +{ + HASH_CR |= HASH_CR_INIT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Add data + +Puts data into the HASH processor's queue. + +@param[in] data unsigned int32. Hash input data. +*/ + +void hash_add_data(uint32_t data) +{ + HASH_DIN = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Digest + +Starts the processing of the last data block. + +*/ + +void hash_digest() +{ + HASH_STR |= HASH_STR_DCAL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief HASH Get Hash Result + +Makes a copy of the resulting hash. + +@param[out] data unsigned int32. Hash 4\5 words long depending on the algorithm. +@param[in] algorithm unsigned int8. Hash algorithm: @ref hash_algorithm +*/ + +void hash_get_result(uint32_t *data) +{ + data[0] = HASH_HR[0]; + data[1] = HASH_HR[1]; + data[2] = HASH_HR[2]; + data[3] = HASH_HR[3]; + + if ((HASH_CR & HASH_CR_ALGO) == HASH_ALGO_SHA1) { + data[4] = HASH_HR[4]; + } +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v1.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v1.c new file mode 100644 index 00000000..2cd5785a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v1.c @@ -0,0 +1,570 @@ +/** @addtogroup i2c_file + +@author @htmlonly © @endhtmlonly 2010 +Thomas Otto +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +Devices can have up to three I2C peripherals. The peripherals support SMBus and +PMBus variants. + +A peripheral begins after reset in Slave mode. To become a Master a start +condition must be generated. The peripheral will remain in Master mode unless +a multimaster contention is lost or a stop condition is generated. + +@todo all sorts of lovely stuff like DMA, Interrupts, SMBus variant, Status +register access, Error conditions + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Reset. + +The I2C peripheral and all its associated configuration registers are placed in +the reset condition. The reset is effected via the RCC peripheral reset system. + +@param[in] i2c Unsigned int32. I2C peripheral identifier @ref i2c_reg_base. +*/ + +void i2c_reset(uint32_t i2c) +{ + switch (i2c) { + case I2C1: + rcc_periph_reset_pulse(RST_I2C1); + break; +#if defined(I2C2_BASE) + case I2C2: + rcc_periph_reset_pulse(RST_I2C2); + break; +#endif +#if defined(I2C3_BASE) + case I2C3: + rcc_periph_reset_pulse(RST_I2C3); + break; +#endif +#if defined(I2C4_BASE) + case I2C4: + rcc_periph_reset_pulse(RST_I2C4); + break; +#endif + default: + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Peripheral Enable. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_peripheral_enable(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_PE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Peripheral Disable. + +This must not be reset while in Master mode until a communication has finished. +In Slave mode, the peripheral is disabled only after communication has ended. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_peripheral_disable(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_PE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Send Start Condition. + +If in Master mode this will cause a restart condition to occur at the end of the +current transmission. If in Slave mode, this will initiate a start condition +when the current bus activity is completed. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_send_start(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_START; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Send Stop Condition. + +After the current byte transfer this will initiate a stop condition if in Master +mode, or simply release the bus if in Slave mode. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_send_stop(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_STOP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Clear Stop Flag. + +Clear the "Send Stop" flag in the I2C config register + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_clear_stop(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_STOP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set the 7 bit Slave Address for the Peripheral. + +This sets an address for Slave mode operation, in 7 bit form. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] slave Unsigned int8. Slave address 0...127. +*/ + +void i2c_set_own_7bit_slave_address(uint32_t i2c, uint8_t slave) +{ + uint16_t val = (uint16_t)(slave << 1); + /* Datasheet: always keep 1 by software. */ + val |= (1 << 14); + I2C_OAR1(i2c) = val; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set the 10 bit Slave Address for the Peripheral. + +This sets an address for Slave mode operation, in 10 bit form. + +@todo add "I2C_OAR1(i2c) |= (1 << 14);" as above + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] slave Unsigned int16. Slave address 0...1023. +*/ + +void i2c_set_own_10bit_slave_address(uint32_t i2c, uint16_t slave) +{ + I2C_OAR1(i2c) = (uint16_t)(I2C_OAR1_ADDMODE | slave); +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set the secondary 7 bit Slave Address for the Peripheral. + +This sets a secondary address for Slave mode operation, in 7 bit form. + + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] slave Unsigned int8. Slave address 0...127. +*/ + +void i2c_set_own_7bit_slave_address_two(uint32_t i2c, uint8_t slave) +{ + uint16_t val = (uint16_t)(slave << 1); + I2C_OAR2(i2c) = val; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Enable dual addressing mode for the Peripheral. + +Both OAR1 and OAR2 are recognised in 7-bit addressing mode. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_enable_dual_addressing_mode(uint32_t i2c) +{ + I2C_OAR2(i2c) |= I2C_OAR2_ENDUAL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Disable dual addressing mode for the Peripheral. + +Only OAR1 is recognised in 7-bit addressing mode. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_disable_dual_addressing_mode(uint32_t i2c) +{ + I2C_OAR2(i2c) &= ~(I2C_OAR2_ENDUAL); +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set Peripheral Clock Frequency. + +Set the peripheral clock frequency: 2MHz to 36MHz (the APB frequency). Note +that this is not the I2C bus clock. This is set in conjunction with +the Clock Control register to generate the Master bus clock, see @ref +i2c_set_ccr + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] freq Unsigned int8. Clock Frequency Setting @ref i2c_clock. +*/ + +void i2c_set_clock_frequency(uint32_t i2c, uint8_t freq) +{ + uint16_t reg16; + reg16 = I2C_CR2(i2c) & 0xffc0; /* Clear bits [5:0]. */ + reg16 |= freq; + I2C_CR2(i2c) = reg16; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Send Data. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] data Unsigned int8. Byte to send. +*/ + +void i2c_send_data(uint32_t i2c, uint8_t data) +{ + I2C_DR(i2c) = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set Fast Mode. + +Set the clock frequency to the high clock rate mode (up to 400kHz). The actual +clock frequency must be set with @ref i2c_set_clock_frequency + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_set_fast_mode(uint32_t i2c) +{ + I2C_CCR(i2c) |= I2C_CCR_FS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set Standard Mode. + +Set the clock frequency to the standard clock rate mode (up to 100kHz). The +actual clock frequency must be set with @ref i2c_set_clock_frequency + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ + +void i2c_set_standard_mode(uint32_t i2c) +{ + I2C_CCR(i2c) &= ~I2C_CCR_FS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set Bus Clock Frequency. + +Set the bus clock frequency. This is a 12 bit number (0...4095) calculated +from the formulae given in the STM32F1 reference manual in the description +of the CCR field. It is a divisor of the peripheral clock frequency +@ref i2c_set_clock_frequency modified by the fast mode setting +@ref i2c_set_fast_mode + +@todo provide additional API assitance to set the clock, eg macros + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] freq Unsigned int16. Bus Clock Frequency Setting 0...4095. +*/ + +void i2c_set_ccr(uint32_t i2c, uint16_t freq) +{ + uint16_t reg16; + reg16 = I2C_CCR(i2c) & 0xf000; /* Clear bits [11:0]. */ + reg16 |= freq; + I2C_CCR(i2c) = reg16; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set the Rise Time. + +Set the maximum rise time on the bus according to the I2C specification, as 1 +more than the specified rise time in peripheral clock cycles. This is a 6 bit +number. + +@todo provide additional APIP assistance. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] trise Unsigned int16. Rise Time Setting 0...63. +*/ + +void i2c_set_trise(uint32_t i2c, uint16_t trise) +{ + I2C_TRISE(i2c) = trise; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Send the 7-bit Slave Address. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] slave Unsigned int16. Slave address 0...1023. +@param[in] readwrite Unsigned int8. Single bit to instruct slave to receive or +send @ref i2c_rw. +*/ + +void i2c_send_7bit_address(uint32_t i2c, uint8_t slave, uint8_t readwrite) +{ + I2C_DR(i2c) = (uint8_t)((slave << 1) | readwrite); +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Get Data. + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +uint8_t i2c_get_data(uint32_t i2c) +{ + return I2C_DR(i2c) & 0xff; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Enable Interrupt + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] interrupt Unsigned int32. Interrupt to enable. +*/ +void i2c_enable_interrupt(uint32_t i2c, uint32_t interrupt) +{ + I2C_CR2(i2c) |= interrupt; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Disable Interrupt + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] interrupt Unsigned int32. Interrupt to disable. +*/ +void i2c_disable_interrupt(uint32_t i2c, uint32_t interrupt) +{ + I2C_CR2(i2c) &= ~interrupt; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Enable ACK + +Enables acking of own 7/10 bit address +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_enable_ack(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_ACK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Disable ACK + +Disables acking of own 7/10 bit address +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_disable_ack(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_ACK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C NACK Next Byte + +Causes the I2C controller to NACK the reception of the next byte +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_nack_next(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_POS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C NACK Next Byte + +Causes the I2C controller to NACK the reception of the current byte + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_nack_current(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_POS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set clock duty cycle + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] dutycycle Unsigned int32. I2C duty cycle @ref i2c_duty_cycle. +*/ +void i2c_set_dutycycle(uint32_t i2c, uint32_t dutycycle) +{ + if (dutycycle == I2C_CCR_DUTY_DIV2) { + I2C_CCR(i2c) &= ~I2C_CCR_DUTY; + } else { + I2C_CCR(i2c) |= I2C_CCR_DUTY; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Enable DMA + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_enable_dma(uint32_t i2c) +{ + I2C_CR2(i2c) |= I2C_CR2_DMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Disable DMA + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_disable_dma(uint32_t i2c) +{ + I2C_CR2(i2c) &= ~I2C_CR2_DMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set DMA last transfer + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_set_dma_last_transfer(uint32_t i2c) +{ + I2C_CR2(i2c) |= I2C_CR2_LAST; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Clear DMA last transfer + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ +void i2c_clear_dma_last_transfer(uint32_t i2c) +{ + I2C_CR2(i2c) &= ~I2C_CR2_LAST; +} + +static void i2c_write7_v1(uint32_t i2c, int addr, uint8_t *data, size_t n) +{ + while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) { + } + + i2c_send_start(i2c); + + /* Wait for master mode selected */ + while (!((I2C_SR1(i2c) & I2C_SR1_SB) + & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); + + i2c_send_7bit_address(i2c, addr, I2C_WRITE); + + /* Waiting for address is transferred. */ + while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); + + /* Clearing ADDR condition sequence. */ + (void)I2C_SR2(i2c); + + for (size_t i = 0; i < n; i++) { + i2c_send_data(i2c, data[i]); + while (!(I2C_SR1(i2c) & (I2C_SR1_BTF))); + } +} + +static void i2c_read7_v1(uint32_t i2c, int addr, uint8_t *res, size_t n) +{ + i2c_send_start(i2c); + i2c_enable_ack(i2c); + + /* Wait for master mode selected */ + while (!((I2C_SR1(i2c) & I2C_SR1_SB) + & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); + + i2c_send_7bit_address(i2c, addr, I2C_READ); + + /* Waiting for address is transferred. */ + while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); + /* Clearing ADDR condition sequence. */ + (void)I2C_SR2(i2c); + + for (size_t i = 0; i < n; ++i) { + if (i == n - 1) { + i2c_disable_ack(i2c); + } + while (!(I2C_SR1(i2c) & I2C_SR1_RxNE)); + res[i] = i2c_get_data(i2c); + } + i2c_send_stop(i2c); + + return; +} + +/** + * Run a write/read transaction to a given 7bit i2c address + * If both write & read are provided, the read will use repeated start. + * Both write and read are optional + * There are likely still issues with repeated start/stop condtions! + * @param i2c peripheral of choice, eg I2C1 + * @param addr 7 bit i2c device address + * @param w buffer of data to write + * @param wn length of w + * @param r destination buffer to read into + * @param rn number of bytes to read (r should be at least this long) + */ +void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) { + if (wn) { + i2c_write7_v1(i2c, addr, w, wn); + } + if (rn) { + i2c_read7_v1(i2c, addr, r, rn); + } else { + i2c_send_stop(i2c); + } +} + +/** + * Set the i2c communication speed. + * @param i2c peripheral, eg I2C1 + * @param speed one of the listed speed modes @ref i2c_speeds + * @param clock_megahz i2c peripheral clock speed in MHz. Usually, rcc_apb1_frequency / 1e6 + */ +void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz) +{ + i2c_set_clock_frequency(i2c, clock_megahz); + switch(speed) { + case i2c_speed_fm_400k: + i2c_set_fast_mode(i2c); + i2c_set_ccr(i2c, clock_megahz * 5 / 6); + i2c_set_trise(i2c, clock_megahz + 1); + break; + default: + /* fall back to standard mode */ + case i2c_speed_sm_100k: + i2c_set_standard_mode(i2c); + /* x Mhz / (100kHz * 2) */ + i2c_set_ccr(i2c, clock_megahz * 5); + /* Sm mode, (100kHz) freqMhz + 1 */ + i2c_set_trise(i2c, clock_megahz + 1); + break; + } +} + + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v2.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v2.c new file mode 100644 index 00000000..2116064f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/i2c_common_v2.c @@ -0,0 +1,477 @@ +/** @addtogroup i2c_file + * + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Reset. + * + * The I2C peripheral and all its associated configuration registers are placed + * in the reset condition. The reset is effected via the RCC peripheral reset + * system. + * + * @param[in] i2c Unsigned int32. I2C peripheral identifier @ref i2c_reg_base. + */ + +void i2c_reset(uint32_t i2c) +{ + switch (i2c) { + case I2C1: + rcc_periph_reset_pulse(RST_I2C1); + break; +#if defined(I2C2_BASE) + case I2C2: + rcc_periph_reset_pulse(RST_I2C2); + break; +#endif +#if defined(I2C3_BASE) + case I2C3: + rcc_periph_reset_pulse(RST_I2C3); + break; +#endif +#if defined(I2C4_BASE) + case I2C4: + rcc_periph_reset_pulse(RST_I2C4); + break; +#endif + default: + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Peripheral Enable. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ + +void i2c_peripheral_enable(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_PE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Peripheral Disable. + * + * This must not be reset while in Master mode until a communication has + * finished. In Slave mode, the peripheral is disabled only after communication + * has ended. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ + +void i2c_peripheral_disable(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_PE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Send Start Condition. + * + * If in Master mode this will cause a restart condition to occur at the end of + * the current transmission. If in Slave mode, this will initiate a start + * condition when the current bus activity is completed. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ + +void i2c_send_start(uint32_t i2c) +{ + I2C_CR2(i2c) |= I2C_CR2_START; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Send Stop Condition. + * + * After the current byte transfer this will initiate a stop condition if in + * Master mode, or simply release the bus if in Slave mode. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ + +void i2c_send_stop(uint32_t i2c) +{ + I2C_CR2(i2c) |= I2C_CR2_STOP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Clear Stop Flag. + * + * Clear the "Send Stop" flag in the I2C config register + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ +void i2c_clear_stop(uint32_t i2c) +{ + I2C_ICR(i2c) |= I2C_ICR_STOPCF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set the 7 bit Slave Address for the Peripheral. + * + * This sets an address for Slave mode operation, in 7 bit form. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + * @param[in] slave Unsigned int8. Slave address 0...127. + */ + +void i2c_set_own_7bit_slave_address(uint32_t i2c, uint8_t slave) +{ + I2C_OAR1(i2c) = (uint16_t)(slave << 1); + I2C_OAR1(i2c) &= ~I2C_OAR1_OA1MODE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Set the 10 bit Slave Address for the Peripheral. + * + * This sets an address for Slave mode operation, in 10 bit form. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + * @param[in] slave Unsigned int16. Slave address 0...1023. + */ + +void i2c_set_own_10bit_slave_address(uint32_t i2c, uint16_t slave) +{ + I2C_OAR1(i2c) = (uint16_t)(I2C_OAR1_OA1MODE | slave); +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Send Data. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + * @param[in] data Unsigned int8. Byte to send. + */ + +void i2c_send_data(uint32_t i2c, uint8_t data) +{ + I2C_TXDR(i2c) = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Get Data. + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ +uint8_t i2c_get_data(uint32_t i2c) +{ + return I2C_RXDR(i2c) & 0xff; +} + +void i2c_enable_analog_filter(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_ANFOFF; +} + +void i2c_disable_analog_filter(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_ANFOFF; +} + +void i2c_set_digital_filter(uint32_t i2c, uint8_t dnf_setting) +{ + I2C_CR1(i2c) = (I2C_CR1(i2c) & ~I2C_CR1_DNF_MASK) | dnf_setting; +} + +/* t_presc= (presc+1)*t_i2cclk */ +void i2c_set_prescaler(uint32_t i2c, uint8_t presc) +{ + I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_PRESC_MASK) | + (presc << I2C_TIMINGR_PRESC_SHIFT); +} + +void i2c_set_data_setup_time(uint32_t i2c, uint8_t s_time) +{ + I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_SCLDEL_MASK) | + (s_time << I2C_TIMINGR_SCLDEL_SHIFT); +} + +void i2c_set_data_hold_time(uint32_t i2c, uint8_t h_time) +{ + I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_SDADEL_MASK) | + (h_time << I2C_TIMINGR_SDADEL_SHIFT); +} + +void i2c_set_scl_high_period(uint32_t i2c, uint8_t period) +{ + I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_SCLH_MASK) | + (period << I2C_TIMINGR_SCLH_SHIFT); +} + +void i2c_set_scl_low_period(uint32_t i2c, uint8_t period) +{ + I2C_TIMINGR(i2c) = (I2C_TIMINGR(i2c) & ~I2C_TIMINGR_SCLL_MASK) | + (period << I2C_TIMINGR_SCLL_SHIFT); +} + +void i2c_enable_stretching(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_NOSTRETCH; +} + +void i2c_disable_stretching(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_NOSTRETCH; +} + +void i2c_set_7bit_addr_mode(uint32_t i2c) +{ + I2C_CR2(i2c) &= ~I2C_CR2_ADD10; +} + +void i2c_set_10bit_addr_mode(uint32_t i2c) +{ + I2C_CR2(i2c) |= I2C_CR2_ADD10; +} + +void i2c_set_7bit_address(uint32_t i2c, uint8_t addr) +{ + I2C_CR2(i2c) = (I2C_CR2(i2c) & ~I2C_CR2_SADD_7BIT_MASK) | + ((addr & 0x7F) << I2C_CR2_SADD_7BIT_SHIFT); +} + +void i2c_set_10bit_address(uint32_t i2c, uint16_t addr) +{ + I2C_CR2(i2c) = (I2C_CR2(i2c) & ~I2C_CR2_SADD_10BIT_MASK) | + ((addr & 0x3FF) << I2C_CR2_SADD_10BIT_SHIFT); +} + +void i2c_set_write_transfer_dir(uint32_t i2c) +{ + I2C_CR2(i2c) &= ~I2C_CR2_RD_WRN; +} + +void i2c_set_read_transfer_dir(uint32_t i2c) +{ + I2C_CR2(i2c) |= I2C_CR2_RD_WRN; +} + +void i2c_set_bytes_to_transfer(uint32_t i2c, uint32_t n_bytes) +{ + I2C_CR2(i2c) = (I2C_CR2(i2c) & ~I2C_CR2_NBYTES_MASK) | + (n_bytes << I2C_CR2_NBYTES_SHIFT); +} + +bool i2c_is_start(uint32_t i2c) +{ + return (I2C_CR2(i2c) & I2C_CR2_START); +} + +void i2c_enable_autoend(uint32_t i2c) +{ + I2C_CR2(i2c) |= I2C_CR2_AUTOEND; +} + +void i2c_disable_autoend(uint32_t i2c) +{ + I2C_CR2(i2c) &= ~I2C_CR2_AUTOEND; +} + +bool i2c_nack(uint32_t i2c) +{ + return (I2C_ISR(i2c) & I2C_ISR_NACKF); +} + +bool i2c_busy(uint32_t i2c) +{ + return (I2C_ISR(i2c) & I2C_ISR_BUSY); +} + +bool i2c_transmit_int_status(uint32_t i2c) +{ + return (I2C_ISR(i2c) & I2C_ISR_TXIS); +} + +bool i2c_transfer_complete(uint32_t i2c) +{ + return (I2C_ISR(i2c) & I2C_ISR_TC); +} + +bool i2c_received_data(uint32_t i2c) +{ + return (I2C_ISR(i2c) & I2C_ISR_RXNE); +} + + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Enable Interrupt + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + * @param[in] interrupt Unsigned int32. Interrupt to enable. + */ +void i2c_enable_interrupt(uint32_t i2c, uint32_t interrupt) +{ + I2C_CR1(i2c) |= interrupt; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Disable Interrupt + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + * @param[in] interrupt Unsigned int32. Interrupt to disable. + */ +void i2c_disable_interrupt(uint32_t i2c, uint32_t interrupt) +{ + I2C_CR1(i2c) &= ~interrupt; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Enable reception DMA + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ +void i2c_enable_rxdma(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_RXDMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Disable reception DMA + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ +void i2c_disable_rxdma(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_RXDMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Enable transmission DMA + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ +void i2c_enable_txdma(uint32_t i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_TXDMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief I2C Disable transmission DMA + * + * @param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. + */ +void i2c_disable_txdma(uint32_t i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_TXDMAEN; +} + +/** + * Run a write/read transaction to a given 7bit i2c address + * If both write & read are provided, the read will use repeated start. + * Both write and read are optional + * @param i2c peripheral of choice, eg I2C1 + * @param addr 7 bit i2c device address + * @param w buffer of data to write + * @param wn length of w + * @param r destination buffer to read into + * @param rn number of bytes to read (r should be at least this long) + */ +void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) +{ + /* waiting for busy is unnecessary. read the RM */ + if (wn) { + i2c_set_7bit_address(i2c, addr); + i2c_set_write_transfer_dir(i2c); + i2c_set_bytes_to_transfer(i2c, wn); + if (rn) { + i2c_disable_autoend(i2c); + } else { + i2c_enable_autoend(i2c); + } + i2c_send_start(i2c); + + while (wn--) { + bool wait = true; + while (wait) { + if (i2c_transmit_int_status(i2c)) { + wait = false; + } + while (i2c_nack(i2c)); /* FIXME Some error */ + } + i2c_send_data(i2c, *w++); + } + /* not entirely sure this is really necessary. + * RM implies it will stall until it can write out the later bits + */ + if (rn) { + while (!i2c_transfer_complete(i2c)); + } + } + + if (rn) { + /* Setting transfer properties */ + i2c_set_7bit_address(i2c, addr); + i2c_set_read_transfer_dir(i2c); + i2c_set_bytes_to_transfer(i2c, rn); + /* start transfer */ + i2c_send_start(i2c); + /* important to do it afterwards to do a proper repeated start! */ + i2c_enable_autoend(i2c); + + for (size_t i = 0; i < rn; i++) { + while (i2c_received_data(i2c) == 0); + r[i] = i2c_get_data(i2c); + } + } +} + + +/** + * Set the i2c communication speed. + * NOTE: 1MHz mode not yet implemented! + * Min clock speed: 8MHz for FM, 2Mhz for SM, + * @param i2c peripheral, eg I2C1 + * @param speed one of the listed speed modes @ref i2c_speeds + * @param clock_megahz i2c peripheral clock speed in MHz. Usually, rcc_apb1_frequency / 1e6 + */ +void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz) +{ + int prescaler; + switch(speed) { + case i2c_speed_fmp_1m: + /* FIXME - add support for this mode! */ + break; + case i2c_speed_fm_400k: + /* target 8Mhz input, so tpresc = 125ns */ + prescaler = clock_megahz / 8 - 1; + i2c_set_prescaler(i2c, prescaler); + i2c_set_scl_low_period(i2c, 10-1); // 1250ns + i2c_set_scl_high_period(i2c, 4-1); // 500ns + i2c_set_data_hold_time(i2c, 3); // 375ns + i2c_set_data_setup_time(i2c, 4-1); // 500ns + break; + default: + /* fall back to standard mode */ + case i2c_speed_sm_100k: + /* target 4Mhz input, so tpresc = 250ns */ + prescaler = (clock_megahz / 4) - 1; + i2c_set_prescaler(i2c, prescaler); + i2c_set_scl_low_period(i2c, 20-1); // 5usecs + i2c_set_scl_high_period(i2c, 16-1); // 4usecs + i2c_set_data_hold_time(i2c, 2); // 0.5usecs + i2c_set_data_setup_time(i2c, 5-1); // 1.25usecs + break; + } +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/iwdg_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/iwdg_common_all.c new file mode 100644 index 00000000..d9aca5a9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/iwdg_common_all.c @@ -0,0 +1,149 @@ +/** @addtogroup iwdg_file + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +This library supports the Independent Watchdog Timer System in the STM32F1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +The watchdog timer uses the LSI (low speed internal) clock which is low power +and continues to operate during stop and standby modes. Its frequency is +nominally 32kHz (40kHz for the STM32F1xx series) but can vary from as low +as 17kHz up to 60kHz (refer to datasheet electrical characteristics). + +Note that the User Configuration option byte provides a means of automatically +enabling the IWDG timer at power on (with counter value 0xFFF). If the +relevant bit is not set, the IWDG timer must be enabled by software. + +@note: Tested: CPU STM32F103RET6, Board ET-ARM Stamp STM32 + +*/ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +#define LSI_FREQUENCY 32000 +#define COUNT_LENGTH 12 +#define COUNT_MASK ((1 << COUNT_LENGTH)-1) + +/*---------------------------------------------------------------------------*/ +/** @brief IWDG Enable Watchdog Timer + +The watchdog timer is started. The timeout period defaults to 512 milliseconds +unless it has been previously defined. + +*/ + +void iwdg_start(void) +{ + IWDG_KR = IWDG_KR_START; +} + +/*---------------------------------------------------------------------------*/ +/** @brief IWDG Set Period in Milliseconds + +The countdown period is converted into count and prescale values. The maximum +period is 32.76 seconds; values above this are truncated. Periods less than 1ms +are not supported by this library. + +A delay of up to 5 clock cycles of the LSI clock (about 156 microseconds) +can occasionally occur if the prescale or preload registers are currently busy +loading a previous value. + +@param[in] period uint32_t Period in milliseconds (< 32760) from a watchdog +reset until a system reset is issued. +*/ + +void iwdg_set_period_ms(uint32_t period) +{ + uint32_t count, prescale, reload, exponent; + + /* Set the count to represent ticks of the 32kHz LSI clock */ + count = (period << 5); + + /* Strip off the first 12 bits to get the prescale value required */ + prescale = (count >> 12); + if (prescale > 256) { + exponent = IWDG_PR_DIV256; reload = COUNT_MASK; + } else if (prescale > 128) { + exponent = IWDG_PR_DIV256; reload = (count >> 8); + } else if (prescale > 64) { + exponent = IWDG_PR_DIV128; reload = (count >> 7); + } else if (prescale > 32) { + exponent = IWDG_PR_DIV64; reload = (count >> 6); + } else if (prescale > 16) { + exponent = IWDG_PR_DIV32; reload = (count >> 5); + } else if (prescale > 8) { + exponent = IWDG_PR_DIV16; reload = (count >> 4); + } else if (prescale > 4) { + exponent = IWDG_PR_DIV8; reload = (count >> 3); + } else { + exponent = IWDG_PR_DIV4; reload = (count >> 2); + } + + /* Avoid the undefined situation of a zero count */ + if (count == 0) { + count = 1; + } + + while (iwdg_prescaler_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_PR = exponent; + while (iwdg_reload_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_RLR = (reload & COUNT_MASK); +} + +/*---------------------------------------------------------------------------*/ +/** @brief IWDG Get Reload Register Status + +@returns boolean: TRUE if the reload register is busy and unavailable for +loading a new count value. +*/ + +bool iwdg_reload_busy(void) +{ + return IWDG_SR & IWDG_SR_RVU; +} + +/*---------------------------------------------------------------------------*/ +/** @brief IWDG Get Prescaler Register Status + +@returns boolean: TRUE if the prescaler register is busy and unavailable for +loading a new period value. +*/ + +bool iwdg_prescaler_busy(void) +{ + return IWDG_SR & IWDG_SR_PVU; +} + +/*---------------------------------------------------------------------------*/ +/** @brief IWDG reset Watchdog Timer + +The watchdog timer is reset. The counter restarts from the value in the reload +register. +*/ + +void iwdg_reset(void) +{ + IWDG_KR = IWDG_KR_RESET; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v1.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v1.c new file mode 100644 index 00000000..ef3ec8f9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v1.c @@ -0,0 +1,205 @@ +/** @addtogroup pwr_file + +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Backup Domain Write Protection. + +This allows backup domain registers to be changed. These registers are write +protected after a reset. +*/ + +void pwr_disable_backup_domain_write_protect(void) +{ + PWR_CR |= PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Re-enable Backup Domain Write Protection. + +This protects backup domain registers from inadvertent change. +*/ + +void pwr_enable_backup_domain_write_protect(void) +{ + PWR_CR &= ~PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Power Voltage Detector. + +This provides voltage level threshold detection. The result of detection is +provided in the power voltage detector output flag (see @ref pwr_voltage_high) +or by setting the EXTI16 interrupt (see datasheet for configuration details). + +@param[in] pvd_level uint32_t. Taken from @ref pwr_pls. +*/ + +void pwr_enable_power_voltage_detect(uint32_t pvd_level) +{ + PWR_CR &= ~PWR_CR_PLS_MASK; + PWR_CR |= (PWR_CR_PVDE | pvd_level); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Power Voltage Detector. + +*/ + +void pwr_disable_power_voltage_detect(void) +{ + PWR_CR &= ~PWR_CR_PVDE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Standby Flag. + +This is set when the processor returns from a standby mode. +*/ + +void pwr_clear_standby_flag(void) +{ + PWR_CR |= PWR_CR_CSBF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Wakeup Flag. + +This is set when the processor receives a wakeup signal. +*/ + +void pwr_clear_wakeup_flag(void) +{ + PWR_CR |= PWR_CR_CWUF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Standby Mode in Deep Sleep. + +*/ + +void pwr_set_standby_mode(void) +{ + PWR_CR |= PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Stop Mode in Deep Sleep. + +*/ + +void pwr_set_stop_mode(void) +{ + PWR_CR &= ~PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator On in Stop Mode. + +*/ + +void pwr_voltage_regulator_on_in_stop(void) +{ + PWR_CR &= ~PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator Low Power in Stop Mode. + +*/ + +void pwr_voltage_regulator_low_power_in_stop(void) +{ + PWR_CR |= PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Wakeup Pin. + +The wakeup pin is used for waking the processor from standby mode. +*/ + +void pwr_enable_wakeup_pin(void) +{ + PWR_CSR |= PWR_CSR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Release Wakeup Pin. + +The wakeup pin is used for general purpose I/O. +*/ + +void pwr_disable_wakeup_pin(void) +{ + PWR_CSR &= ~PWR_CSR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Voltage Detector Output. + +The voltage detector threshold must be set when the power voltage detector is +enabled, see @ref pwr_enable_power_voltage_detect. + +@returns boolean: TRUE if the power voltage is above the preset voltage +threshold. +*/ + +bool pwr_voltage_high(void) +{ + return PWR_CSR & PWR_CSR_PVDO; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Standby Flag. + +The standby flag is set when the processor returns from a standby state. It is +cleared by software (see @ref pwr_clear_standby_flag). + +@returns boolean: TRUE if the processor was in standby state. +*/ + +bool pwr_get_standby_flag(void) +{ + return PWR_CSR & PWR_CSR_SBF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Wakeup Flag. + +The wakeup flag is set when a wakeup event has been received. It is +cleared by software (see @ref pwr_clear_wakeup_flag). + +@returns boolean: TRUE if a wakeup event was received. +*/ + +bool pwr_get_wakeup_flag(void) +{ + return PWR_CSR & PWR_CSR_WUF; +} +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v2.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v2.c new file mode 100644 index 00000000..b895e7d0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/pwr_common_v2.c @@ -0,0 +1,48 @@ +/** @addtogroup pwr_file + * + * @author @htmlonly © @endhtmlonly 2012 Karl Palsson + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#include +#include + +void pwr_set_vos_scale(enum pwr_vos_scale scale) +{ + /* You are not allowed to write zeros here, don't try and optimize! */ + uint32_t reg = PWR_CR; + reg &= ~(PWR_CR_VOS_MASK); + switch (scale) { + case PWR_SCALE1: + reg |= PWR_CR_VOS_RANGE1; + break; + case PWR_SCALE2: + reg |= PWR_CR_VOS_RANGE2; + break; + case PWR_SCALE3: + reg |= PWR_CR_VOS_RANGE3; + break; + } + PWR_CR = reg; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rcc_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rcc_common_all.c new file mode 100644 index 00000000..0c14313f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rcc_common_all.c @@ -0,0 +1,263 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * .. file is merged from many other copyrighted files of stm32 family + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable Peripheral Clocks. + * + * Enable the clock on particular peripherals. There are three registers + * involved, each one controlling the enabling of clocks associated with the + * AHB, APB1 and APB2 respectively. Several peripherals could be enabled + * simultaneously only if they are controlled by the same register. + * + * @param[in] *reg Unsigned int32. Pointer to a Clock Enable Register + * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) + * + * @param[in] en Unsigned int32. Logical OR of all enables to be set + * @li If register is RCC_AHBER, from @ref rcc_ahbenr_en + * @li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en + * @li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en + */ + +void rcc_peripheral_enable_clock(volatile uint32_t *reg, uint32_t en) +{ + *reg |= en; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable Peripheral Clocks. + * + * Enable the clock on particular peripherals. There are three registers + * involved, each one controlling the enabling of clocks associated with + * the AHB, APB1 and APB2 respectively. Several peripherals could be disabled + * simultaneously only if they are controlled by the same register. + * + * @param[in] *reg Unsigned int32. Pointer to a Clock Enable Register + * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) + * @param[in] en Unsigned int32. Logical OR of all enables to be used for + * disabling. + * @li If register is RCC_AHBER, from @ref rcc_ahbenr_en + * @li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en + * @li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en + */ +void rcc_peripheral_disable_clock(volatile uint32_t *reg, uint32_t en) +{ + *reg &= ~en; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Reset Peripherals. + * + * Reset particular peripherals. There are three registers involved, each one + * controlling reset of peripherals associated with the AHB, APB1 and APB2 + * respectively. Several peripherals could be reset simultaneously only if + * they are controlled by the same register. + * + * @param[in] *reg Unsigned int32. Pointer to a Reset Register + * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) + * @param[in] reset Unsigned int32. Logical OR of all resets. + * @li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst + * @li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst + * @li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst + */ +void rcc_peripheral_reset(volatile uint32_t *reg, uint32_t reset) +{ + *reg |= reset; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Remove Reset on Peripherals. + * + * Remove the reset on particular peripherals. There are three registers + * involved, each one controlling reset of peripherals associated with the AHB, + * APB1 and APB2 respectively. Several peripherals could have the reset removed + * simultaneously only if they are controlled by the same register. + * + * @param[in] *reg Unsigned int32. Pointer to a Reset Register + * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) + * @param[in] clear_reset Unsigned int32. Logical OR of all resets to be + * removed: + * @li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst + * @li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst + * @li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst + */ +void rcc_peripheral_clear_reset(volatile uint32_t *reg, uint32_t clear_reset) +{ + *reg &= ~clear_reset; +} + +#define _RCC_REG(i) MMIO32(RCC_BASE + ((i) >> 5)) +#define _RCC_BIT(i) (1 << ((i) & 0x1f)) + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Peripheral Clock in running mode. + * + * Enable the clock on particular peripheral. + * + * @param[in] clken rcc_periph_clken Peripheral RCC + * + * For available constants, see #rcc_periph_clken (RCC_UART1 for example) + */ + +void rcc_periph_clock_enable(enum rcc_periph_clken clken) +{ + _RCC_REG(clken) |= _RCC_BIT(clken); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Peripheral Clock in running mode. + * Disable the clock on particular peripheral. + * + * @param[in] clken rcc_periph_clken Peripheral RCC + * + * For available constants, see #rcc_periph_clken (RCC_UART1 for example) + */ + +void rcc_periph_clock_disable(enum rcc_periph_clken clken) +{ + _RCC_REG(clken) &= ~_RCC_BIT(clken); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset Peripheral, pulsed + * + * Reset particular peripheral, and restore to working state. + * + * @param[in] rst rcc_periph_rst Peripheral reset + * + * For available constants, see #rcc_periph_rst (RST_UART1 for example) + */ + +void rcc_periph_reset_pulse(enum rcc_periph_rst rst) +{ + _RCC_REG(rst) |= _RCC_BIT(rst); + _RCC_REG(rst) &= ~_RCC_BIT(rst); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset Peripheral, hold + * + * Reset particular peripheral, and hold in reset state. + * + * @param[in] rst rcc_periph_rst Peripheral reset + * + * For available constants, see #rcc_periph_rst (RST_UART1 for example) + */ + +void rcc_periph_reset_hold(enum rcc_periph_rst rst) +{ + _RCC_REG(rst) |= _RCC_BIT(rst); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset Peripheral, release + * + * Restore peripheral from reset state to working state. + * + * @param[in] rst rcc_periph_rst Peripheral reset + * + * For available constants, see #rcc_periph_rst (RST_UART1 for example) + */ + +void rcc_periph_reset_release(enum rcc_periph_rst rst) +{ + _RCC_REG(rst) &= ~_RCC_BIT(rst); +} + +/** @brief Select the source of Microcontroller Clock Output + * + * Exact sources available depend on your target. On devices with multiple + * MCO pins, this function controls MCO1 + * + * @parame[in] mcosrc the unshifted source bits + */ + +void rcc_set_mco(uint32_t mcosrc) +{ + RCC_CFGR = (RCC_CFGR & ~(RCC_CFGR_MCO_MASK << RCC_CFGR_MCO_SHIFT)) | + (mcosrc << RCC_CFGR_MCO_SHIFT); +} + +/** + * RCC Enable Bypass. + * Enable an external clock to bypass the internal clock (high speed and low + * speed clocks only). The external clock must be enabled (see @ref rcc_osc_on) + * and the internal clock must be disabled (see @ref rcc_osc_off) for this to + * have effect. + * @note The LSE clock is in the backup domain and cannot be bypassed until the + * backup domain write protection has been removed (see @ref + * pwr_disable_backup_domain_write_protect). + * @param[in] osc Oscillator ID. Only HSE and LSE have effect. + */ +void rcc_osc_bypass_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSE: + RCC_CR |= RCC_CR_HSEBYP; + break; + case RCC_LSE: +#ifdef RCC_CSR_LSEBYP + RCC_CSR |= RCC_CSR_LSEBYP; +#else + RCC_BDCR |= RCC_BDCR_LSEBYP; +#endif + break; + default: + /* Do nothing, only HSE/LSE allowed here. */ + break; + } +} + +/** + * RCC Disable Bypass. + * Re-enable the internal clock (high speed and low speed clocks only). The + * internal clock must be disabled (see @ref rcc_osc_off) for this to have + * effect. + * @note The LSE clock is in the backup domain and cannot have bypass removed + * until the backup domain write protection has been removed (see @ref + * pwr_disable_backup_domain_write_protect) or the backup domain has been reset + * (see @ref rcc_backupdomain_reset). + * @param[in] osc Oscillator ID. Only HSE and LSE have effect. + */ +void rcc_osc_bypass_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEBYP; + break; + case RCC_LSE: +#ifdef RCC_CSR_LSEBYP + RCC_CSR &= ~RCC_CSR_LSEBYP; +#else + RCC_BDCR &= ~RCC_BDCR_LSEBYP; +#endif + break; + default: + /* Do nothing, only HSE/LSE allowed here. */ + break; + } +} + +/**@}*/ + +#undef _RCC_REG +#undef _RCC_BIT diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rng_common_v1.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rng_common_v1.c new file mode 100644 index 00000000..7ed1e635 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rng_common_v1.c @@ -0,0 +1,91 @@ +/** @addtogroup rng_file + * + * This library supports the random number generator peripheral (RNG) in the + * STM32F4 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/** Disable the Random Number Generator peripheral. +*/ +void rng_disable(void) +{ + RNG_CR &= ~RNG_CR_RNGEN; +} + +/** Enable the Random Number Generator peripheral. +*/ +void rng_enable(void) +{ + RNG_CR |= RNG_CR_RNGEN; +} + +/** Randomizes a number (non-blocking). + * Can fail if a clock error or seed error is detected. Consult the Reference + * Manual, but "try again", potentially after resetting the peripheral + * @param pointer to a uint32_t that will be randomized. + * @returns true on success, pointer is only written to on success + * @sa rng_get_random_blocking + */ +bool rng_get_random(uint32_t *rand_nr) +{ + /* data ready */ + if (!(RNG_SR & RNG_SR_DRDY)) { + return false; + } + + /* Check for errors */ + if (RNG_SR & (RNG_SR_CECS | RNG_SR_SECS)) { + return false; + } + + *rand_nr = RNG_DR; + + return true; +} + + +/** + * Get a random number and block until it works. + * Unless you have a clock problem, this should always return "promptly" + * If you have a clock problem, you will wait here forever! + * @returns a random 32bit number + */ +uint32_t rng_get_random_blocking(void) +{ + uint32_t rv; + bool done; + do { + if (RNG_SR & RNG_SR_SECS) { + rng_disable(); + rng_enable(); + } + done = rng_get_random(&rv); + } while (!done); + + return rv; +} + + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rtc_common_l1f024.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rtc_common_l1f024.c new file mode 100644 index 00000000..7579dfdc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/rtc_common_l1f024.c @@ -0,0 +1,123 @@ +/** @addtogroup rtc_file + +@author @htmlonly © @endhtmlonly 2012 Karl Palsson + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set RTC prescalars. + +This sets the RTC synchronous and asynchronous prescalars. +*/ + +void rtc_set_prescaler(uint32_t sync, uint32_t async) +{ + /* + * Even if only one of the two fields needs to be changed, + * 2 separate write accesses must be performed to the RTC_PRER register. + */ + RTC_PRER = (sync & RTC_PRER_PREDIV_S_MASK); + RTC_PRER |= (async << RTC_PRER_PREDIV_A_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Wait for RTC registers to be synchronised with the APB1 bus + + Time and Date are accessed through shadow registers which must be synchronized +*/ + +void rtc_wait_for_synchro(void) +{ + /* Unlock RTC registers */ + RTC_WPR = 0xca; + RTC_WPR = 0x53; + + RTC_ISR &= ~(RTC_ISR_RSF); + + while (!(RTC_ISR & RTC_ISR_RSF)); + + /* disable write protection again */ + RTC_WPR = 0xff; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock write access to the RTC registers + +*/ +void rtc_unlock(void) +{ + RTC_WPR = 0xca; + RTC_WPR = 0x53; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock write access to the RTC registers + +*/ +void rtc_lock(void) +{ + RTC_WPR = 0xff; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the wakeup time auto-reload value + +*/ +void rtc_set_wakeup_time(uint16_t wkup_time, uint8_t rtc_cr_wucksel) +{ + /* FTFM: + * The following sequence is required to configure or change the wakeup + * timer auto-reload value (WUT[15:0] in RTC_WUTR): + * 1. Clear WUTE in RTC_CR to disable the wakeup timer. + */ + RTC_CR &= ~RTC_CR_WUTE; + /* 2. Poll WUTWF until it is set in RTC_ISR to make sure the access to + * wakeup auto-reload counter and to WUCKSEL[2:0] bits is allowed. + * It takes around 2 RTCCLK clock cycles (due to clock + * synchronization). + */ + while (!((RTC_ISR) & (RTC_ISR_WUTWF))); + /* 3. Program the wakeup auto-reload value WUT[15:0], and the wakeup + * clock selection (WUCKSEL[2:0] bits in RTC_CR).Set WUTE in RTC_CR + * to enable the timer again. The wakeup timer restarts + * down-counting. + */ + RTC_WUTR = wkup_time; + RTC_CR |= (rtc_cr_wucksel << RTC_CR_WUCLKSEL_SHIFT); + RTC_CR |= RTC_CR_WUTE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clears the wakeup flag + +@details This function should be called first in the rtc_wkup_isr() +*/ +void rtc_clear_wakeup_flag(void) +{ + RTC_ISR &= ~RTC_ISR_WUTF; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_all.c new file mode 100644 index 00000000..e6faaf72 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_all.c @@ -0,0 +1,741 @@ +/** @addtogroup spi_file + +@author @htmlonly © @endhtmlonly 2009 +Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +Devices can have up to three SPI peripherals. The common 4-wire full-duplex +mode of operation is supported, along with 3-wire variants using unidirectional +communication modes or half-duplex bidirectional communication. A variety of +options allows many of the SPI variants to be supported. Multimaster operation +is also supported. A CRC can be generated and checked in hardware. + +@note Some JTAG pins need to be remapped if SPI is to be used. + +@note The I2S protocol shares the SPI hardware so the two protocols cannot be +used at the same time on the same peripheral. + +Example: 1Mbps, positive clock polarity, leading edge trigger, 8-bit words, +LSB first. +@code + spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, + SPI_CR1_LSBFIRST); + spi_write(SPI1, 0x55); // 8-bit write + spi_write(SPI1, 0xaa88); // 16-bit write + reg8 = spi_read(SPI1); // 8-bit read + reg16 = spi_read(SPI1); // 16-bit read +@endcode + +@todo need additional functions to aid ISRs in retrieving status + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/* + * SPI and I2S code. + * + * Examples: + * spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + * SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, + * SPI_CR1_LSBFIRST); + * spi_write(SPI1, 0x55); // 8-bit write + * spi_write(SPI1, 0xaa88); // 16-bit write + * reg8 = spi_read(SPI1); // 8-bit read + * reg16 = spi_read(SPI1); // 16-bit read + */ + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Reset. + +The SPI peripheral and all its associated configuration registers are placed in +the reset condition. The reset is effected via the RCC peripheral reset system. + +@param[in] spi_peripheral Unsigned int32. SPI peripheral identifier @ref +spi_reg_base. +*/ + +void spi_reset(uint32_t spi_peripheral) +{ switch (spi_peripheral) { +#if defined(SPI1_BASE) + case SPI1_BASE: + rcc_periph_reset_pulse(RST_SPI1); + break; +#endif +#if defined(SPI2_BASE) + case SPI2_BASE: + rcc_periph_reset_pulse(RST_SPI2); + break; +#endif +#if defined(SPI3_BASE) + case SPI3_BASE: + rcc_periph_reset_pulse(RST_SPI3); + break; +#endif +#if defined(SPI4_BASE) + case SPI4_BASE: + rcc_periph_reset_pulse(RST_SPI4); + break; +#endif +#if defined(SPI5_BASE) + case SPI5_BASE: + rcc_periph_reset_pulse(RST_SPI5); + break; +#endif +#if defined(SPI6_BASE) + case SPI6_BASE: + rcc_periph_reset_pulse(RST_SPI6); + break; +#endif + default: + break; + } +} + +/* TODO: Error handling? */ +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable. + +The SPI peripheral is enabled. + +@todo Error handling? + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_SPE; /* Enable SPI. */ +} + +/* TODO: Error handling? */ +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable. + +The SPI peripheral is disabled. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable(uint32_t spi) +{ + uint32_t reg32; + + reg32 = SPI_CR1(spi); + reg32 &= ~(SPI_CR1_SPE); /* Disable SPI. */ + SPI_CR1(spi) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Clean Disable. + +Disable the SPI peripheral according to the procedure in section 23.3.8 of the +reference manual. This prevents corruption of any ongoing transfers and +prevents the BSY flag from becoming unreliable. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@returns data Unsigned int16. 8 or 16 bit data from final read. +*/ + +uint16_t spi_clean_disable(uint32_t spi) +{ + /* Wait to receive last data */ + while (!(SPI_SR(spi) & SPI_SR_RXNE)); + + uint16_t data = SPI_DR(spi); + + /* Wait to transmit last data */ + while (!(SPI_SR(spi) & SPI_SR_TXE)); + + /* Wait until not busy */ + while (SPI_SR(spi) & SPI_SR_BSY); + + SPI_CR1(spi) &= ~SPI_CR1_SPE; + + return data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Data Write. + +Data is written to the SPI interface. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@param[in] data Unsigned int16. 8 or 16 bit data to be written. +*/ + +void spi_write(uint32_t spi, uint16_t data) +{ + /* Write data (8 or 16 bits, depending on DFF) into DR. */ + SPI_DR(spi) = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Data Write with Blocking. + +Data is written to the SPI interface after the previous write transfer has +finished. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@param[in] data Unsigned int16. 8 or 16 bit data to be written. +*/ + +void spi_send(uint32_t spi, uint16_t data) +{ + /* Wait for transfer finished. */ + while (!(SPI_SR(spi) & SPI_SR_TXE)); + + /* Write data (8 or 16 bits, depending on DFF) into DR. */ + SPI_DR(spi) = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Data Read. + +Data is read from the SPI interface after the incoming transfer has finished. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@returns data Unsigned int16. 8 or 16 bit data. +*/ + +uint16_t spi_read(uint32_t spi) +{ + /* Wait for transfer finished. */ + while (!(SPI_SR(spi) & SPI_SR_RXNE)); + + /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ + return SPI_DR(spi); +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Data Write and Read Exchange. + +Data is written to the SPI interface, then a read is done after the incoming +transfer has finished. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@param[in] data Unsigned int16. 8 or 16 bit data to be written. +@returns data Unsigned int16. 8 or 16 bit data. +*/ + +uint16_t spi_xfer(uint32_t spi, uint16_t data) +{ + spi_write(spi, data); + + /* Wait for transfer finished. */ + while (!(SPI_SR(spi) & SPI_SR_RXNE)); + + /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ + return SPI_DR(spi); +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Bidirectional Simplex Mode. + +The SPI peripheral is set for bidirectional transfers in two-wire simplex mode +(using a clock wire and a bidirectional data wire). + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_bidirectional_mode(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_BIDIMODE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Unidirectional Mode. + +The SPI peripheral is set for unidirectional transfers. This is used in full +duplex mode or when the SPI is placed in two-wire simplex mode that uses a +clock wire and a unidirectional data wire. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_unidirectional_mode(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_BIDIMODE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Bidirectional Simplex Receive Only Mode. + +The SPI peripheral is set for bidirectional transfers in two-wire simplex mode +(using a clock wire and a bidirectional data wire), and is placed in a receive +state. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_bidirectional_receive_only_mode(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_BIDIMODE; + SPI_CR1(spi) &= ~SPI_CR1_BIDIOE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Bidirectional Simplex Receive Only Mode. + +The SPI peripheral is set for bidirectional transfers in two-wire simplex mode +(using a clock wire and a bidirectional data wire), and is placed in a transmit +state. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_bidirectional_transmit_only_mode(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_BIDIMODE; + SPI_CR1(spi) |= SPI_CR1_BIDIOE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable the CRC. + +The SPI peripheral is set to use a CRC field for transmit and receive. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_crc(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_CRCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable the CRC. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_crc(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CRCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Next Transmit is a Data Word + +The next transmission to take place is a data word from the transmit buffer. +This must be called before transmission to distinguish between sending +of a data or CRC word. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_next_tx_from_buffer(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CRCNEXT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Next Transmit is a CRC Word + +The next transmission to take place is a crc word from the hardware crc unit. +This must be called before transmission to distinguish between sending +of a data or CRC word. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_next_tx_from_crc(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_CRCNEXT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Full Duplex (3-wire) Mode + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_full_duplex_mode(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_RXONLY; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Receive Only Mode for Simplex (2-wire) Unidirectional +Transfers + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_receive_only_mode(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_RXONLY; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable Slave Management by Hardware + +In slave mode the NSS hardware input is used as a select enable for the slave. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_software_slave_management(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_SSM; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable Slave Management by Software + +In slave mode the NSS hardware input is replaced by an internal software +enable/disable of the slave (@ref spi_set_nss_high). + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_software_slave_management(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_SSM; + /* allow slave select to be an input */ + SPI_CR2(spi) &= ~SPI_CR2_SSOE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the Software NSS Signal High + +In slave mode, and only when software slave management is used, this replaces +the NSS signal with a slave select enable signal. + +@todo these should perhaps be combined with an SSM enable as it is meaningless +otherwise + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_nss_high(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_SSI; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the Software NSS Signal Low + +In slave mode, and only when software slave management is used, this replaces +the NSS signal with a slave select disable signal. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_nss_low(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_SSI; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set to Send LSB First + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_send_lsb_first(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_LSBFIRST; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set to Send MSB First + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_send_msb_first(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_LSBFIRST; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the Baudrate Prescaler + +@todo Why is this specification different to the spi_init_master baudrate +values? + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@param[in] baudrate Unsigned int8. Baudrate prescale value @ref spi_br_pre. +*/ + +void spi_set_baudrate_prescaler(uint32_t spi, uint8_t baudrate) +{ + uint32_t reg32; + + if (baudrate > 7) { + return; + } + + reg32 = (SPI_CR1(spi) & 0xffc7); /* Clear bits [5:3]. */ + reg32 |= (baudrate << 3); + SPI_CR1(spi) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set to Master Mode + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_master_mode(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_MSTR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set to Slave Mode + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_slave_mode(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_MSTR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the Clock Polarity to High when Idle + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@sa spi_set_clock_polarity_0 +*/ + +void spi_set_clock_polarity_1(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_CPOL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the Clock Polarity to Low when Idle + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@sa spi_set_clock_polarity_1 +*/ + +void spi_set_clock_polarity_0(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CPOL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the Clock Phase to Capture on Trailing Edge + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@sa spi_set_clock_phase_0 +*/ + +void spi_set_clock_phase_1(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_CPHA; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the Clock Phase to Capture on Leading Edge + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@sa spi_set_clock_phase_1 +*/ + +void spi_set_clock_phase_0(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CPHA; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable the Transmit Buffer Empty Interrupt + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_tx_buffer_empty_interrupt(uint32_t spi) +{ + SPI_CR2(spi) |= SPI_CR2_TXEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable the Transmit Buffer Empty Interrupt + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_tx_buffer_empty_interrupt(uint32_t spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_TXEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable the Receive Buffer Ready Interrupt + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_rx_buffer_not_empty_interrupt(uint32_t spi) +{ + SPI_CR2(spi) |= SPI_CR2_RXNEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable the Receive Buffer Ready Interrupt + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_rx_buffer_not_empty_interrupt(uint32_t spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_RXNEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable the Error Interrupt + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_error_interrupt(uint32_t spi) +{ + SPI_CR2(spi) |= SPI_CR2_ERRIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable the Error Interrupt + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_error_interrupt(uint32_t spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_ERRIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the NSS Pin as an Output + +Normally used in master mode to allows the master to place all devices on the +SPI bus into slave mode. Multimaster mode is not possible. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_ss_output(uint32_t spi) +{ + SPI_CR2(spi) |= SPI_CR2_SSOE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set the NSS Pin as an Input + +In master mode this allows the master to sense the presence of other masters. If +NSS is then pulled low the master is placed into slave mode. In slave mode NSS +becomes a slave enable. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_ss_output(uint32_t spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_SSOE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable Transmit Transfers via DMA + +This allows transmissions to proceed unattended using DMA to move data to the +transmit buffer as it becomes available. The DMA channels provided for each +SPI peripheral are given in the Technical Manual DMA section. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_tx_dma(uint32_t spi) +{ + SPI_CR2(spi) |= SPI_CR2_TXDMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable Transmit Transfers via DMA + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_tx_dma(uint32_t spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_TXDMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Enable Receive Transfers via DMA + +This allows received data streams to proceed unattended using DMA to move data +from the receive buffer as data becomes available. The DMA channels provided +for each SPI peripheral are given in the Technical Manual DMA section. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_enable_rx_dma(uint32_t spi) +{ + SPI_CR2(spi) |= SPI_CR2_RXDMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Disable Receive Transfers via DMA + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_disable_rx_dma(uint32_t spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_RXDMAEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Standard Mode selection +@details Set SPI standard Modes +Mode | CPOL | CPHA +---- | ---- | ---- + 0 | 0 | 0 + 1 | 0 | 1 + 2 | 1 | 0 + 3 | 1 | 1 +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@param[in] mode Unsigned int8. Standard SPI mode (0, 1, 2, 3) +@sa spi_set_clock_phase_0 spi_set_clock_phase_1 +@sa spi_set_clock_polarity_0 spi_set_clock_polarity_1 +*/ + +void spi_set_standard_mode(uint32_t spi, uint8_t mode) +{ + if (mode > 3) { + return; + } + + uint32_t reg32 = SPI_CR1(spi) & ~(SPI_CR1_CPOL | SPI_CR1_CPHA); + SPI_CR1(spi) = reg32 | mode; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_f03.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_f03.c new file mode 100644 index 00000000..5713653a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_f03.c @@ -0,0 +1,177 @@ +/** @addtogroup spi_file + +@author @htmlonly © @endhtmlonly 2009 +Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +Devices can have up to three SPI peripherals. The common 4-wire full-duplex +mode of operation is supported, along with 3-wire variants using unidirectional +communication modes or half-duplex bidirectional communication. A variety of +options allows many of the SPI variants to be supported. Multimaster operation +is also supported. A CRC can be generated and checked in hardware. + +@note Some JTAG pins need to be remapped if SPI is to be used. + +@note The I2S protocol shares the SPI hardware so the two protocols cannot be +used at the same time on the same peripheral. + +Example: 1Mbps, positive clock polarity, leading edge trigger, 8-bit words, +LSB first. +@code + spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_CRCL_8BIT, + SPI_CR1_LSBFIRST); + spi_write(SPI1, 0x55); // 8-bit write + spi_write(SPI1, 0xaa88); // 16-bit write + reg8 = spi_read(SPI1); // 8-bit read + reg16 = spi_read(SPI1); // 16-bit read +@endcode + +@todo need additional functions to aid ISRs in retrieving status + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/* + * SPI and I2S code. + * + * Examples: + * spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + * SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_CRCL_8BIT, + * SPI_CR1_LSBFIRST); + * spi_write(SPI1, 0x55); // 8-bit write + * spi_write(SPI1, 0xaa88); // 16-bit write + * reg8 = spi_read(SPI1); // 8-bit read + * reg16 = spi_read(SPI1); // 16-bit read + */ + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief Configure the SPI as Master. + +The SPI peripheral is configured as a master with communication parameters +baudrate, crc length 8/16 bits, frame format lsb/msb first, clock polarity +and phase. The SPI enable, CRC enable and CRC next controls are not affected. +These must be controlled separately. + +@todo NSS pin handling. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@param[in] br Unsigned int32. Baudrate @ref spi_baudrate. +@param[in] cpol Unsigned int32. Clock polarity @ref spi_cpol. +@param[in] cpha Unsigned int32. Clock Phase @ref spi_cpha. +@param[in] crcl Unsigned int32. CRC length 8/16 bits @ref spi_crcl. +@param[in] lsbfirst Unsigned int32. Frame format lsb/msb first @ref +spi_lsbfirst. +@returns int. Error code. +*/ + +int spi_init_master(uint32_t spi, uint32_t br, uint32_t cpol, uint32_t cpha, + uint32_t crcl, uint32_t lsbfirst) +{ + uint32_t reg32 = SPI_CR1(spi); + + /* Reset all bits omitting SPE, CRCEN and CRCNEXT bits. */ + reg32 &= SPI_CR1_SPE | SPI_CR1_CRCEN | SPI_CR1_CRCNEXT; + + reg32 |= SPI_CR1_MSTR; /* Configure SPI as master. */ + + reg32 |= br; /* Set baud rate bits. */ + reg32 |= cpol; /* Set CPOL value. */ + reg32 |= cpha; /* Set CPHA value. */ + reg32 |= crcl; /* Set crc length (8 or 16 bits). */ + reg32 |= lsbfirst; /* Set frame format (LSB- or MSB-first). */ + + /* TODO: NSS pin handling. */ + + SPI_CR1(spi) = reg32; + + return 0; /* TODO */ +} + +void spi_send8(uint32_t spi, uint8_t data) +{ + /* Wait for transfer finished. */ + while (!(SPI_SR(spi) & SPI_SR_TXE)); + + /* Write data (8 or 16 bits, depending on DFF) into DR. */ + SPI_DR8(spi) = data; +} + +uint8_t spi_read8(uint32_t spi) +{ + /* Wait for transfer finished. */ + while (!(SPI_SR(spi) & SPI_SR_RXNE)); + + /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ + return SPI_DR8(spi); +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set CRC length to 8 bits + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_crcl_8bit(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CRCL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set CRC length to 16 bits + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_crcl_16bit(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_CRCL; +} + +void spi_set_data_size(uint32_t spi, uint16_t data_s) +{ + SPI_CR2(spi) = (SPI_CR2(spi) & ~SPI_CR2_DS_MASK) | + (data_s & SPI_CR2_DS_MASK); +} + +void spi_fifo_reception_threshold_8bit(uint32_t spi) +{ + SPI_CR2(spi) |= SPI_CR2_FRXTH; +} + +void spi_fifo_reception_threshold_16bit(uint32_t spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_FRXTH; +} + +void spi_i2s_mode_spi_mode(uint32_t spi) +{ + SPI_I2SCFGR(spi) &= ~SPI_I2SCFGR_I2SMOD; +} + + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_l1f124.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_l1f124.c new file mode 100644 index 00000000..d1150c36 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/spi_common_l1f124.c @@ -0,0 +1,138 @@ +/** @addtogroup spi_file + +@author @htmlonly © @endhtmlonly 2009 +Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +Devices can have up to three SPI peripherals. The common 4-wire full-duplex +mode of operation is supported, along with 3-wire variants using unidirectional +communication modes or half-duplex bidirectional communication. A variety of +options allows many of the SPI variants to be supported. Multimaster operation +is also supported. A CRC can be generated and checked in hardware. + +@note Some JTAG pins need to be remapped if SPI is to be used. + +@note The I2S protocol shares the SPI hardware so the two protocols cannot be +used at the same time on the same peripheral. + +Example: 1Mbps, positive clock polarity, leading edge trigger, 8-bit words, +LSB first. +@code + spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, + SPI_CR1_LSBFIRST); + spi_write(SPI1, 0x55); // 8-bit write + spi_write(SPI1, 0xaa88); // 16-bit write + reg8 = spi_read(SPI1); // 8-bit read + reg16 = spi_read(SPI1); // 16-bit read +@endcode + +@todo need additional functions to aid ISRs in retrieving status + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/* + * SPI and I2S code. + * + * Examples: + * spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + * SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, + * SPI_CR1_LSBFIRST); + * spi_write(SPI1, 0x55); // 8-bit write + * spi_write(SPI1, 0xaa88); // 16-bit write + * reg8 = spi_read(SPI1); // 8-bit read + * reg16 = spi_read(SPI1); // 16-bit read + */ + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief Configure the SPI as Master. + +The SPI peripheral is configured as a master with communication parameters +baudrate, data format 8/16 bits, frame format lsb/msb first, clock polarity +and phase. The SPI enable, CRC enable and CRC next controls are not affected. +These must be controlled separately. + +To support multiple masters (dynamic switching between master and slave) +you must set SSOE to 0 and select either software or hardware control of +the NSS pin. + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +@param[in] br Unsigned int32. Baudrate @ref spi_baudrate. +@param[in] cpol Unsigned int32. Clock polarity @ref spi_cpol. +@param[in] cpha Unsigned int32. Clock Phase @ref spi_cpha. +@param[in] dff Unsigned int32. Data frame format 8/16 bits @ref spi_dff. +@param[in] lsbfirst Unsigned int32. Frame format lsb/msb first @ref +spi_lsbfirst. +@returns int. Error code. +*/ + +int spi_init_master(uint32_t spi, uint32_t br, uint32_t cpol, uint32_t cpha, + uint32_t dff, uint32_t lsbfirst) +{ + uint32_t reg32 = SPI_CR1(spi); + + /* Reset all bits omitting SPE, CRCEN and CRCNEXT bits. */ + reg32 &= SPI_CR1_SPE | SPI_CR1_CRCEN | SPI_CR1_CRCNEXT; + + reg32 |= SPI_CR1_MSTR; /* Configure SPI as master. */ + + reg32 |= br; /* Set baud rate bits. */ + reg32 |= cpol; /* Set CPOL value. */ + reg32 |= cpha; /* Set CPHA value. */ + reg32 |= dff; /* Set data format (8 or 16 bits). */ + reg32 |= lsbfirst; /* Set frame format (LSB- or MSB-first). */ + + SPI_CR2(spi) |= SPI_CR2_SSOE; /* common case */ + SPI_CR1(spi) = reg32; + + return 0; /* TODO */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Data Frame Format to 8 bits + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_dff_8bit(uint32_t spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_DFF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief SPI Set Data Frame Format to 16 bits + +@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base. +*/ + +void spi_set_dff_16bit(uint32_t spi) +{ + SPI_CR1(spi) |= SPI_CR1_DFF; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.c new file mode 100644 index 00000000..09a6e22e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.c @@ -0,0 +1,277 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * Copyright (C) 2015 Robin Kreis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include "../../usb/usb_private.h" +#include "st_usbfs_core.h" + +/* TODO - can't these be inside the impls, not globals from the core? */ +uint8_t st_usbfs_force_nak[8]; +struct _usbd_device st_usbfs_dev; + +void st_usbfs_set_address(usbd_device *dev, uint8_t addr) +{ + (void)dev; + /* Set device address and enable. */ + SET_REG(USB_DADDR_REG, (addr & USB_DADDR_ADDR) | USB_DADDR_EF); +} + +/** + * Set the receive buffer size for a given USB endpoint. + * + * @param ep Index of endpoint to configure. + * @param size Size in bytes of the RX buffer. + */ +void st_usbfs_set_ep_rx_bufsize(usbd_device *dev, uint8_t ep, uint32_t size) +{ + (void)dev; + if (size > 62) { + if (size & 0x1f) { + size -= 32; + } + USB_SET_EP_RX_COUNT(ep, (size << 5) | 0x8000); + } else { + if (size & 1) { + size++; + } + USB_SET_EP_RX_COUNT(ep, size << 10); + } +} + +void st_usbfs_ep_setup(usbd_device *dev, uint8_t addr, uint8_t type, + uint16_t max_size, + void (*callback) (usbd_device *usbd_dev, + uint8_t ep)) +{ + /* Translate USB standard type codes to STM32. */ + const uint16_t typelookup[] = { + [USB_ENDPOINT_ATTR_CONTROL] = USB_EP_TYPE_CONTROL, + [USB_ENDPOINT_ATTR_ISOCHRONOUS] = USB_EP_TYPE_ISO, + [USB_ENDPOINT_ATTR_BULK] = USB_EP_TYPE_BULK, + [USB_ENDPOINT_ATTR_INTERRUPT] = USB_EP_TYPE_INTERRUPT, + }; + uint8_t dir = addr & 0x80; + addr &= 0x7f; + + /* Assign address. */ + USB_SET_EP_ADDR(addr, addr); + USB_SET_EP_TYPE(addr, typelookup[type]); + + if (dir || (addr == 0)) { + USB_SET_EP_TX_ADDR(addr, dev->pm_top); + if (callback) { + dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = + (void *)callback; + } + USB_CLR_EP_TX_DTOG(addr); + USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_NAK); + dev->pm_top += max_size; + } + + if (!dir) { + USB_SET_EP_RX_ADDR(addr, dev->pm_top); + st_usbfs_set_ep_rx_bufsize(dev, addr, max_size); + if (callback) { + dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = + (void *)callback; + } + USB_CLR_EP_RX_DTOG(addr); + USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); + dev->pm_top += max_size; + } +} + +void st_usbfs_endpoints_reset(usbd_device *dev) +{ + int i; + + /* Reset all endpoints. */ + for (i = 1; i < 8; i++) { + USB_SET_EP_TX_STAT(i, USB_EP_TX_STAT_DISABLED); + USB_SET_EP_RX_STAT(i, USB_EP_RX_STAT_DISABLED); + } + dev->pm_top = USBD_PM_TOP + (2 * dev->desc->bMaxPacketSize0); +} + +void st_usbfs_ep_stall_set(usbd_device *dev, uint8_t addr, + uint8_t stall) +{ + (void)dev; + if (addr == 0) { + USB_SET_EP_TX_STAT(addr, stall ? USB_EP_TX_STAT_STALL : + USB_EP_TX_STAT_NAK); + } + + if (addr & 0x80) { + addr &= 0x7F; + + USB_SET_EP_TX_STAT(addr, stall ? USB_EP_TX_STAT_STALL : + USB_EP_TX_STAT_NAK); + + /* Reset to DATA0 if clearing stall condition. */ + if (!stall) { + USB_CLR_EP_TX_DTOG(addr); + } + } else { + /* Reset to DATA0 if clearing stall condition. */ + if (!stall) { + USB_CLR_EP_RX_DTOG(addr); + } + + USB_SET_EP_RX_STAT(addr, stall ? USB_EP_RX_STAT_STALL : + USB_EP_RX_STAT_VALID); + } +} + +uint8_t st_usbfs_ep_stall_get(usbd_device *dev, uint8_t addr) +{ + (void)dev; + if (addr & 0x80) { + if ((*USB_EP_REG(addr & 0x7F) & USB_EP_TX_STAT) == + USB_EP_TX_STAT_STALL) { + return 1; + } + } else { + if ((*USB_EP_REG(addr) & USB_EP_RX_STAT) == + USB_EP_RX_STAT_STALL) { + return 1; + } + } + return 0; +} + +void st_usbfs_ep_nak_set(usbd_device *dev, uint8_t addr, uint8_t nak) +{ + (void)dev; + /* It does not make sense to force NAK on IN endpoints. */ + if (addr & 0x80) { + return; + } + + st_usbfs_force_nak[addr] = nak; + + if (nak) { + USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_NAK); + } else { + USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); + } +} + +uint16_t st_usbfs_ep_write_packet(usbd_device *dev, uint8_t addr, + const void *buf, uint16_t len) +{ + (void)dev; + addr &= 0x7F; + + if ((*USB_EP_REG(addr) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) { + return 0; + } + + st_usbfs_copy_to_pm(USB_GET_EP_TX_BUFF(addr), buf, len); + USB_SET_EP_TX_COUNT(addr, len); + USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_VALID); + + return len; +} + +uint16_t st_usbfs_ep_read_packet(usbd_device *dev, uint8_t addr, + void *buf, uint16_t len) +{ + (void)dev; + if ((*USB_EP_REG(addr) & USB_EP_RX_STAT) == USB_EP_RX_STAT_VALID) { + return 0; + } + + len = MIN(USB_GET_EP_RX_COUNT(addr) & 0x3ff, len); + st_usbfs_copy_from_pm(buf, USB_GET_EP_RX_BUFF(addr), len); + USB_CLR_EP_RX_CTR(addr); + + if (!st_usbfs_force_nak[addr]) { + USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); + } + + return len; +} + +void st_usbfs_poll(usbd_device *dev) +{ + uint16_t istr = *USB_ISTR_REG; + + if (istr & USB_ISTR_RESET) { + USB_CLR_ISTR_RESET(); + dev->pm_top = USBD_PM_TOP; + _usbd_reset(dev); + return; + } + + if (istr & USB_ISTR_CTR) { + uint8_t ep = istr & USB_ISTR_EP_ID; + uint8_t type; + + if (istr & USB_ISTR_DIR) { + /* OUT or SETUP? */ + if (*USB_EP_REG(ep) & USB_EP_SETUP) { + type = USB_TRANSACTION_SETUP; + } else { + type = USB_TRANSACTION_OUT; + } + } else { + type = USB_TRANSACTION_IN; + USB_CLR_EP_TX_CTR(ep); + } + + if (dev->user_callback_ctr[ep][type]) { + dev->user_callback_ctr[ep][type] (dev, ep); + } else { + USB_CLR_EP_RX_CTR(ep); + } + } + + if (istr & USB_ISTR_SUSP) { + USB_CLR_ISTR_SUSP(); + if (dev->user_callback_suspend) { + dev->user_callback_suspend(); + } + } + + if (istr & USB_ISTR_WKUP) { + USB_CLR_ISTR_WKUP(); + if (dev->user_callback_resume) { + dev->user_callback_resume(); + } + } + + if (istr & USB_ISTR_SOF) { + USB_CLR_ISTR_SOF(); + if (dev->user_callback_sof) { + dev->user_callback_sof(); + } + } + + if (dev->user_callback_sof) { + *USB_CNTR_REG |= USB_CNTR_SOFM; + } else { + *USB_CNTR_REG &= ~USB_CNTR_SOFM; + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.h b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.h new file mode 100644 index 00000000..b389a637 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/st_usbfs_core.h @@ -0,0 +1,76 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * Copyright (C) 2015 Robin Kreis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * This is a "private" header file for usbd implementations. + * As opposed to the "public" headers under include that describe the hardware, + * this is purely an implementation detail of usbd drivers. + */ + +#ifndef ST_USBFS_CORE +#define ST_USBFS_CORE + +#include +#include + +#define USBD_PM_TOP 0x40 + +void st_usbfs_set_address(usbd_device *dev, uint8_t addr); +void st_usbfs_set_ep_rx_bufsize(usbd_device *dev, uint8_t ep, uint32_t size); + +void st_usbfs_ep_setup(usbd_device *usbd_dev, uint8_t addr, + uint8_t type, uint16_t max_size, + void (*callback) (usbd_device *usbd_dev, + uint8_t ep)); + +void st_usbfs_endpoints_reset(usbd_device *usbd_dev); +void st_usbfs_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, uint8_t stall); +uint8_t st_usbfs_ep_stall_get(usbd_device *usbd_dev, uint8_t addr); +void st_usbfs_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak); +uint16_t st_usbfs_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len); +uint16_t st_usbfs_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, + void *buf, uint16_t len); +void st_usbfs_poll(usbd_device *usbd_dev); + +/* These must be implemented by the device specific driver */ + +/** + * Copy a data buffer to packet memory. + * + * @param vPM Destination pointer into packet memory. + * @param buf Source pointer to data buffer. + * @param len Number of bytes to copy. + */ +void st_usbfs_copy_from_pm(void *buf, const volatile void *vPM, uint16_t len); + +/** + * Copy a data buffer from packet memory. + * + * @param vPM Destination pointer into packet memory. + * @param buf Source pointer to data buffer. + * @param len Number of bytes to copy. + */ +void st_usbfs_copy_to_pm(volatile void *vPM, const void *buf, uint16_t len); + +extern uint8_t st_usbfs_force_nak[8]; +extern struct _usbd_device st_usbfs_dev; + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_all.c new file mode 100644 index 00000000..3619a234 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_all.c @@ -0,0 +1,2191 @@ +/** @addtogroup timer_file + +@author @htmlonly © @endhtmlonly 2010 +Edward Cheeseman +@author @htmlonly © @endhtmlonly 2011 +Stephen Caudle + +@section tim_common Notes for All Timers + +This library supports the General Purpose and Advanced Control Timers for +the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics. + +The STM32 series have four general purpose timers (2-5), while some have +an additional two advanced timers (1,8), and some have two basic timers (6,7). +Some of the larger devices have additional general purpose timers (9-14). + +@todo Add timer DMA burst settings + +@section tim_api_ex Basic TIMER handling API. + +Enable the timer clock first. The timer mode sets the clock division ratio, the +count alignment (edge or centred) and count direction. Finally enable the +timer. + +The timer output compare block produces a signal that can be configured for +output to a pin or passed to other peripherals for use as a trigger. In all +cases the output compare mode must be set to define how the output responds to +a compare match, and the output must be enabled. If output to a pin is +required, enable the appropriate GPIO clock and set the pin to alternate output +mode. + +Example: Timer 2 with 2x clock divide, edge aligned and up counting. +@code + rcc_periph_clock_enable(RCC_TIM2); + timer_reset(TIM2); + timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT_MUL_2, + TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + ... + timer_set_period(TIM2, 1000); + timer_enable_counter(TIM2); +@endcode +Example: Timer 1 with PWM output, no clock divide and centre alignment. Set the +Output Compare mode to PWM and enable the output of channel 1. Note that for +the advanced timers the break functionality must be enabled before the signal +will appear at the output, even though break is not being used. This is in +addition to the normal output enable. Enable the alternate function clock (APB2 +only) and port A clock. Set ports A8 and A9 (timer 1 channel 1 compare outputs) +to alternate function push-pull outputs where the PWM output will appear. + +@code + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_TIM1); + gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, + GPIO_OSPEED_50MHZ, GPIO8 | GPIO9); + rcc_periph_clock_enable(RCC_TIM1); + timer_reset(TIM1); + timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1, + TIM_CR1_DIR_UP); + timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM2); + timer_enable_oc_output(TIM1, TIM_OC1); + timer_enable_break_main_output(TIM1); + timer_set_oc_value(TIM1, TIM_OC1, 200); + timer_set_period(TIM1, 1000); + timer_enable_counter(TIM1); +@endcode +Example: Timer 3 as a Quadrature encoder counting input from a motor or control +knob. + +@code + rcc_periph_clock_enable(RCC_TIM3); + timer_set_period(TIM3, 1024); + timer_slave_set_mode(TIM3, 0x3); // encoder + timer_ic_set_input(TIM3, TIM_IC1, TIM_IC_IN_TI1); + timer_ic_set_input(TIM3, TIM_IC2, TIM_IC_IN_TI2); + timer_enable_counter(TIM3); + ... + int motor_pos = timer_get_count(TIM3); +@endcode + +@todo input capture example + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * Basic TIMER handling API. + * + * Examples: + * timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2, + * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP); + */ + +/**@{*/ + +#include +#include + +#define ADVANCED_TIMERS (defined(TIM1_BASE) || defined(TIM8_BASE)) + +#if defined(TIM8) +#define TIMER_IS_ADVANCED(periph) (((periph) == TIM1) || ((periph) == TIM8)) +#else +#define TIMER_IS_ADVANCED(periph) ((periph) == TIM1) +#endif + +/*---------------------------------------------------------------------------*/ +/** @brief Reset a Timer. + +The counter and all its associated configuration registers are placed in the +reset condition. The reset is effected via the RCC peripheral reset system. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref + tim_reg_base (TIM9 .. TIM14 not yet supported here). +*/ + +void timer_reset(uint32_t timer_peripheral) +{ + switch (timer_peripheral) { +#if defined(TIM1_BASE) + case TIM1: + rcc_periph_reset_pulse(RST_TIM1); + break; +#endif + case TIM2: + rcc_periph_reset_pulse(RST_TIM2); + break; + case TIM3: + rcc_periph_reset_pulse(RST_TIM3); + break; +#if defined(TIM4_BASE) + case TIM4: + rcc_periph_reset_pulse(RST_TIM4); + break; +#endif +#if defined(TIM5_BASE) + case TIM5: + rcc_periph_reset_pulse(RST_TIM5); + break; +#endif + case TIM6: + rcc_periph_reset_pulse(RST_TIM6); + break; + case TIM7: + rcc_periph_reset_pulse(RST_TIM7); + break; +#if defined(TIM8_BASE) + case TIM8: + rcc_periph_reset_pulse(RST_TIM8); + break; +#endif +/* These timers are not supported in libopencm3 yet */ +/* + case TIM9: + rcc_periph_reset_pulse(RST_TIM9); + break; + case TIM10: + rcc_periph_reset_pulse(RST_TIM10); + break; + case TIM11: + rcc_periph_reset_pulse(RST_TIM11); + break; + case TIM12: + rcc_periph_reset_pulse(RST_TIM12); + break; + case TIM13: + rcc_periph_reset_pulse(RST_TIM13); + break; + case TIM14: + rcc_periph_reset_pulse(RST_TIM14); + break; +*/ + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Interrupts for a Timer + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt +enable bits to be set +*/ + +void timer_enable_irq(uint32_t timer_peripheral, uint32_t irq) +{ + TIM_DIER(timer_peripheral) |= irq; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Interrupts for a Timer. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt +enable bits to be cleared +*/ + +void timer_disable_irq(uint32_t timer_peripheral, uint32_t irq) +{ + TIM_DIER(timer_peripheral) &= ~irq; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Return Interrupt Source. + +Returns true if the specified interrupt flag (UIF, TIF or CCxIF, with BIF or +COMIF for advanced timers) was set and the interrupt was enabled. If the +specified flag is not an interrupt flag, the function returns false. + +@todo Timers 6-7, 9-14 have fewer interrupts, but invalid flags are not caught +here. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values. +@returns boolean: flag set. +*/ + +bool timer_interrupt_source(uint32_t timer_peripheral, uint32_t flag) +{ +/* flag not set or interrupt disabled or not an interrupt source */ + if (((TIM_SR(timer_peripheral) & + TIM_DIER(timer_peripheral) & flag) == 0) || + (flag > TIM_SR_BIF)) { + return false; + } +/* Only an interrupt source for advanced timers */ +#if ADVANCED_TIMERS + if ((flag == TIM_SR_BIF) || (flag == TIM_SR_COMIF)) { + return TIMER_IS_ADVANCED(timer_peripheral); + } +#endif + return true; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read a Status Flag. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values. +@returns boolean: flag set. +*/ + +bool timer_get_flag(uint32_t timer_peripheral, uint32_t flag) +{ + if ((TIM_SR(timer_peripheral) & flag) != 0) { + return true; + } + + return false; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear a Status Flag. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] flag Unsigned int32. @ref tim_sr_values. Status register flag. +*/ + +void timer_clear_flag(uint32_t timer_peripheral, uint32_t flag) +{ + /* All defined bits are rc_w0 */ + TIM_SR(timer_peripheral) = ~flag; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer Mode. + +The modes are: + +@li Clock divider ratio (to form the sampling clock for the input filters, +and the dead-time clock in the advanced timers 1 and 8) +@li Edge/centre alignment +@li Count direction + +The alignment and count direction are effective only for timers 1 to 5 and 8 +while the clock divider ratio is effective for all timers except 6,7 +The remaining timers are limited hardware timers which do not support these mode +settings. + +@note: When center alignment mode is selected, count direction is controlled by +hardware and cannot be written. The count direction setting has no effect +in this case. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base (TIM1, TIM2 ... TIM5, TIM8) +@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref +tim_x_cr1_cdr +@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms +@param[in] direction Unsigned int32. Count direction in bit 4,: @ref +tim_x_cr1_dir +*/ + +void timer_set_mode(uint32_t timer_peripheral, uint32_t clock_div, + uint32_t alignment, uint32_t direction) +{ + uint32_t cr1; + + cr1 = TIM_CR1(timer_peripheral); + + cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | TIM_CR1_CMS_MASK | TIM_CR1_DIR_DOWN); + + cr1 |= clock_div | alignment | direction; + + TIM_CR1(timer_peripheral) = cr1; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Filter and Dead-time Clock Divider Ratio. + +This forms the sampling clock for the input filters and the dead-time clock +in the advanced timers 1 and 8, by division from the timer clock. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref +tim_x_cr1_cdr +*/ + +void timer_set_clock_division(uint32_t timer_peripheral, uint32_t clock_div) +{ + clock_div &= TIM_CR1_CKD_CK_INT_MASK; + TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK; + TIM_CR1(timer_peripheral) |= clock_div; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Auto-Reload Buffering. + +During counter operation this causes the counter to be loaded from its +auto-reload register only at the next update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_enable_preload(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Auto-Reload Buffering. + +This causes the counter to be loaded immediately with a new count value when the +auto-reload register is written, so that the new value becomes effective for the +current count cycle rather than for the cycle following an update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_disable_preload(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Specify the counter alignment mode. + +The mode can be edge aligned or centered. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms +*/ + +void timer_set_alignment(uint32_t timer_peripheral, uint32_t alignment) +{ + alignment &= TIM_CR1_CMS_MASK; + TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK; + TIM_CR1(timer_peripheral) |= alignment; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Count Up. + +This has no effect if the timer is set to center aligned. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_direction_up(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Count Down. + +This has no effect if the timer is set to center aligned. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_direction_down(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Timer for One Cycle and Stop. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_one_shot_mode(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Timer to Run Continuously. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_continuous_mode(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Generate Update IRQ or DMA on any Event. + +The events which will generate an interrupt or DMA request can be +@li a counter underflow/overflow, +@li a forced update, +@li an event from the slave mode controller. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_update_on_any(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Generate Update IRQ or DMA only from Under/Overflow +Events. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_update_on_overflow(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_URS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Update Events. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_enable_update_event(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Update Events. + +Update events are not generated and the shadow registers keep their values. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_disable_update_event(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the timer to start counting. + +This should be called after the timer initial configuration has been completed. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_enable_counter(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Stop the timer from counting. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_disable_counter(uint32_t timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Output Idle States High. + +This determines the value of the timer output compare when it enters idle state. + +@sa @ref timer_set_oc_idle_state_set + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref +tim_x_cr2_ois. If several settings are to be made, use the logical OR of the +output control values. +*/ + +void timer_set_output_idle_state(uint32_t timer_peripheral, uint32_t outputs) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; + } +#else + (void)timer_peripheral; + (void)outputs; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Output Idle States Low. + +This determines the value of the timer output compare when it enters idle state. + +@sa @ref timer_set_oc_idle_state_unset + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref +tim_x_cr2_ois +*/ + +void timer_reset_output_idle_state(uint32_t timer_peripheral, uint32_t outputs) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); + } +#else + (void)timer_peripheral; + (void)outputs; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer 1 Input to XOR of Three Channels. + +The first timer capture input is formed from the XOR of the first three timer +input channels 1, 2, 3. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_set_ti1_ch123_xor(uint32_t timer_peripheral) +{ + TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer 1 Input to Channel 1. + +The first timer capture input is taken from the timer input channel 1 only. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_set_ti1_ch1(uint32_t timer_peripheral) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Master Mode + +This sets the Trigger Output TRGO for synchronizing with slave timers or +passing as an internal trigger to the ADC or DAC. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] mode Unsigned int32. Master Mode @ref tim_mastermode +*/ + +void timer_set_master_mode(uint32_t timer_peripheral, uint32_t mode) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK; + TIM_CR2(timer_peripheral) |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer DMA Requests on Capture/Compare Events. + +Capture/compare events will cause DMA requests to be generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_set_dma_on_compare_event(uint32_t timer_peripheral) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer DMA Requests on Update Events. + +Update events will cause DMA requests to be generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_set_dma_on_update_event(uint32_t timer_peripheral) +{ + TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Capture/Compare Control Update with Trigger. + +If the capture/compare control bits CCxE, CCxNE and OCxM are set to be +preloaded, they are updated by software generating the COMG event (@ref +timer_generate_event) or when a rising edge occurs on the trigger input TRGI. + +@note This setting is only valid for the advanced timer channels with +complementary outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_enable_compare_control_update_on_trigger(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Capture/Compare Control Update with Trigger. + +If the capture/compare control bits CCxE, CCxNE and OCxM are set to be +preloaded, they are updated by software generating the COMG event (@ref +timer_generate_event). + +@note This setting is only valid for the advanced timer channels with +complementary outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_disable_compare_control_update_on_trigger(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Capture/Compare Control Preload. + +The capture/compare control bits CCxE, CCxNE and OCxM are set to be preloaded +when a COM event occurs. + +@note This setting is only valid for the advanced timer channels with +complementary outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_enable_preload_complementry_enable_bits(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Capture/Compare Control Preload. + +The capture/compare control bits CCxE, CCxNE and OCxM preload is disabled. + +@note This setting is only valid for the advanced timer channels with +complementary outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +*/ + +void timer_disable_preload_complementry_enable_bits(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Value for the Timer Prescaler. + +The timer clock is prescaled by the 16 bit scale value plus 1. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] value Unsigned int32. Prescaler values 0...0xFFFF. +*/ + +void timer_set_prescaler(uint32_t timer_peripheral, uint32_t value) +{ + TIM_PSC(timer_peripheral) = value; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Value for the Timer Repetition Counter. + +A timer update event is generated only after the specified number of repeat +count cycles have been completed. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] value Unsigned int32. Repetition values 0...0xFF. +*/ + +void timer_set_repetition_counter(uint32_t timer_peripheral, uint32_t value) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_RCR(timer_peripheral) = value; + } +#else + (void)timer_peripheral; + (void)value; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Period + +Specify the timer period in the auto-reload register. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] period Unsigned int32. Period in counter clock ticks. +*/ + +void timer_set_period(uint32_t timer_peripheral, uint32_t period) +{ + TIM_ARR(timer_peripheral) = period; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Clear Function + +When this is enabled, the output compare signal is cleared when a high is +detected on the external trigger input. This works in the output compare and +PWM modes only (not forced mode). +The output compare signal remains off until the next update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + +void timer_enable_oc_clear(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as oc clear enable only applies to the whole + * channel. + */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare Clear Function + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + +void timer_disable_oc_clear(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as oc clear enable only applies to the whole + * channel. + */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Fast Mode + +When this is enabled, the output compare signal is forced to the compare state +by a trigger input, independently of the compare match. This speeds up the +setting of the output compare to 3 clock cycles as opposed to at least 5 in the +slow mode. This works in the PWM1 and PWM2 modes only. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + +void timer_set_oc_fast_mode(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as fast enable only applies to the whole channel. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Slow Mode + +This disables the fast compare mode and the output compare depends on the +counter and compare register values. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + +void timer_set_oc_slow_mode(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Mode + +Specifies how the comparator output will respond to a compare match. The mode +can be: +@li Frozen - the output does not respond to a match. +@li Active - the output assumes the active state on the first match. +@li Inactive - the output assumes the inactive state on the first match. +@li Toggle - The output switches between active and inactive states on each +match. +@li Force inactive. The output is forced low regardless of the compare state. +@li Force active. The output is forced high regardless of the compare state. +@li PWM1 - The output is active when the counter is less than the compare +register contents and inactive otherwise. +@li PWM2 - The output is inactive when the counter is less than the compare +register contents and active otherwise. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +@param[in] oc_mode enum ::tim_oc_mode. OC mode designators. + TIM_OCM_FROZEN, TIM_OCM_ACTIVE, TIM_OCM_INACTIVE, + TIM_OCM_TOGGLE, TIM_OCM_FORCE_LOW, TIM_OCM_FORCE_HIGH, + TIM_OCM_PWM1, TIM_OCM_PWM2 +*/ + +void timer_set_oc_mode(uint32_t timer_peripheral, enum tim_oc_id oc_id, + enum tim_oc_mode oc_mode) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR1(timer_peripheral) |= + TIM_CCMR1_OC1M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2; + break; + } + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR1(timer_peripheral) |= + TIM_CCMR1_OC2M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2; + break; + } + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_CC3S_OUT; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR2(timer_peripheral) |= + TIM_CCMR2_OC3M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2; + break; + } + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_CC4S_OUT; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR2(timer_peripheral) |= + TIM_CCMR2_OC4M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2; + break; + } + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Preload Register + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + +void timer_enable_oc_preload(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare Preload Register + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action) +*/ + +void timer_disable_oc_preload(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set the Output Polarity High + +The polarity of the channel output is set active high. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced + timers 1 and 8) +*/ + +void timer_set_oc_polarity_high(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ +#if ADVANCED_TIMERS + if (!TIMER_IS_ADVANCED(timer_peripheral)) { + return; + } +#else + return; +#endif + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set the Output Polarity Low + +The polarity of the channel output is set active low. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced + timers 1 and 8) +*/ + +void timer_set_oc_polarity_low(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ +#if ADVANCED_TIMERS + if (!TIMER_IS_ADVANCED(timer_peripheral)) { + return; + } +#else + return; +#endif + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare + +The channel output compare functionality is enabled. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced + timers 1 and 8) +*/ + +void timer_enable_oc_output(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ +#if ADVANCED_TIMERS + if (!TIMER_IS_ADVANCED(timer_peripheral)) { + return; + } +#else + return; +#endif + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare + +The channel output compare functionality is disabled. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced + timers 1 and 8) +*/ + +void timer_disable_oc_output(uint32_t timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ +#if ADVANCED_TIMERS + if (!TIMER_IS_ADVANCED(timer_peripheral)) { + return; + } +#else + return; +#endif + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer set Output Compare Idle State High + +@sa Similar function suitable for multiple OC idle state settings +@ref timer_set_output_idle_state + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced + timers 1 and 8) +*/ + +void timer_set_oc_idle_state_set(uint32_t timer_peripheral, + enum tim_oc_id oc_id) +{ +#if ADVANCED_TIMERS + /* Acting for TIM1 and TIM8 only. */ + if (!TIMER_IS_ADVANCED(timer_peripheral)) { + return; + } + + switch (oc_id) { + case TIM_OC1: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1; + break; + case TIM_OC1N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N; + break; + case TIM_OC2: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2; + break; + case TIM_OC2N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N; + break; + case TIM_OC3: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3; + break; + case TIM_OC3N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N; + break; + case TIM_OC4: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4; + break; + } +#else + (void)timer_peripheral; + (void)oc_id; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Idle State Low + +@sa Similar function suitable for multiple OC idle state settings +@ref timer_reset_output_idle_state + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref +tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced + timers 1 and 8) +*/ + +void timer_set_oc_idle_state_unset(uint32_t timer_peripheral, + enum tim_oc_id oc_id) +{ +#if ADVANCED_TIMERS + /* Acting for TIM1 and TIM8 only. */ + if (!TIMER_IS_ADVANCED(timer_peripheral)) { + return; + } + + switch (oc_id) { + case TIM_OC1: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1; + break; + case TIM_OC1N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N; + break; + case TIM_OC2: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2; + break; + case TIM_OC2N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N; + break; + case TIM_OC3: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3; + break; + case TIM_OC3N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N; + break; + case TIM_OC4: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4; + break; + } +#else + (void)timer_peripheral; + (void)oc_id; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Value + +This is a convenience function to set the OC preload register value for loading +to the compare register. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref + tim_reg_base (TIM9 .. TIM14 not yet supported here). +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +@param[in] value Unsigned int32. Compare value. +*/ + +void timer_set_oc_value(uint32_t timer_peripheral, enum tim_oc_id oc_id, + uint32_t value) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCR1(timer_peripheral) = value; + break; + case TIM_OC2: + TIM_CCR2(timer_peripheral) = value; + break; + case TIM_OC3: + TIM_CCR3(timer_peripheral) = value; + break; + case TIM_OC4: + TIM_CCR4(timer_peripheral) = value; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Output in Break + +Enables the output in the Break feature of an advanced timer. This does not +enable the break functionality itself but only sets the Master Output Enable in +the Break and Deadtime Register. + +@note This setting is only valid for the advanced timers. + +@note It is necessary to call this function to enable the output on an advanced +timer even if break or deadtime features are not being used. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_enable_break_main_output(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Output in Break + +Disables the output in the Break feature of an advanced timer. This clears +the Master Output Enable in the Break and Deadtime Register. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_disable_break_main_output(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Automatic Output in Break + +Enables the automatic output feature of the Break function of an advanced +timer so that the output is re-enabled at the next update event following a +break event. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_enable_break_automatic_output(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Automatic Output in Break + +Disables the automatic output feature of the Break function of an advanced +timer so that the output is re-enabled at the next update event following a +break event. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_disable_break_automatic_output(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Activate Break when Input High + +Sets the break function to activate when the break input becomes high. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_set_break_polarity_high(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Activate Break when Input Low + +Sets the break function to activate when the break input becomes low. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_set_break_polarity_low(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Break + +Enables the break function of an advanced timer. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_enable_break(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Break + +Disables the break function of an advanced timer. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_disable_break(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Off-State in Run Mode + +Enables the off-state in run mode for the break function of an advanced +timer in which the complementary outputs have been configured. It has no effect +if no complementary output is present. When the capture-compare output is +disabled while the complementary output is enabled, the output is set to its +inactive level as defined by the output polarity. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_set_enabled_off_state_in_run_mode(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Off-State in Run Mode + +Disables the off-state in run mode for the break function of an advanced +timer in which the complementary outputs have been configured. It has no effect +if no complementary output is present. When the capture-compare output is +disabled, the output is also disabled. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_set_disabled_off_state_in_run_mode(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Off-State in Idle Mode + +Enables the off-state in idle mode for the break function of an advanced +timer. When the master output is disabled the output is set to its +inactive level as defined by the output polarity. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_set_enabled_off_state_in_idle_mode(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Off-State in Idle Mode + +Disables the off-state in idle mode for the break function of an advanced +timer. When the master output is disabled the output is also disabled. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +*/ + +void timer_set_disabled_off_state_in_idle_mode(uint32_t timer_peripheral) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI; + } +#else + (void)timer_peripheral; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Lock Bits + +Set the lock bits for an advanced timer. Three levels of lock providing +protection against software errors. Once written they cannot be changed until a +timer reset has occurred. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +@param[in] lock Unsigned int32. Lock specification @ref tim_lock +*/ + +void timer_set_break_lock(uint32_t timer_peripheral, uint32_t lock) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= lock; + } +#else + (void)timer_peripheral; + (void)lock; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Deadtime + +The deadtime and sampling clock (DTSC) is set in the clock division ratio part +of the timer mode settings. The deadtime count is an 8 bit value defined in +terms of the number of DTSC cycles: + +@li Bit 7 = 0, deadtime = bits(6:0) +@li Bits 7:6 = 10, deadtime = 2x(64+bits(5:0)) +@li Bits 7:5 = 110, deadtime = 8x(32+bits(5:0)) +@li Bits 7:5 = 111, deadtime = 16x(32+bits(5:0)) + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or +TIM8 +@param[in] deadtime Unsigned int32. Deadtime count specification as defined +above. +*/ + +void timer_set_deadtime(uint32_t timer_peripheral, uint32_t deadtime) +{ +#if ADVANCED_TIMERS + if (TIMER_IS_ADVANCED(timer_peripheral)) { + TIM_BDTR(timer_peripheral) |= deadtime; + } +#else + (void)timer_peripheral; + (void)deadtime; +#endif +} + +/*---------------------------------------------------------------------------*/ +/** @brief Force generate a timer event. + +The event specification consists of 8 possible events that can be forced on the +timer. The forced events are automatically cleared by hardware. The UG event is +useful to cause shadow registers to be preloaded before the timer is started to +avoid uncertainties in the first cycle in case an update event may never be +generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] event Unsigned int32. Event specification @ref tim_event_gen +*/ + +void timer_generate_event(uint32_t timer_peripheral, uint32_t event) +{ + TIM_EGR(timer_peripheral) |= event; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read Counter + +Read back the value of a timer's counter register contents + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@returns Unsigned int32. Counter value. +*/ + +uint32_t timer_get_counter(uint32_t timer_peripheral) +{ + return TIM_CNT(timer_peripheral); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Counter + +Set the value of a timer's counter register contents. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] count Unsigned int32. Counter value. +*/ + +void timer_set_counter(uint32_t timer_peripheral, uint32_t count) +{ + TIM_CNT(timer_peripheral) = count; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Capture Filter Parameters + +Set the input filter parameters for an input channel, specifying: +@li the frequency of sampling from the Deadtime and Sampling clock +(@see @ref timer_set_clock_division) +@li the number of events that must occur before a transition is considered +valid. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] flt ::tim_ic_filter. Input Capture Filter identifier. +*/ + +void timer_ic_set_filter(uint32_t timer_peripheral, enum tim_ic_id ic, + enum tim_ic_filter flt) +{ + switch (ic) { + case TIM_IC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1F_MASK; + TIM_CCMR1(timer_peripheral) |= flt << 4; + break; + case TIM_IC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2F_MASK; + TIM_CCMR1(timer_peripheral) |= flt << 12; + break; + case TIM_IC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3F_MASK; + TIM_CCMR2(timer_peripheral) |= flt << 4; + break; + case TIM_IC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4F_MASK; + TIM_CCMR2(timer_peripheral) |= flt << 12; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Capture Prescaler + +Set the number of events between each capture. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. +*/ + +void timer_ic_set_prescaler(uint32_t timer_peripheral, enum tim_ic_id ic, + enum tim_ic_psc psc) +{ + switch (ic) { + case TIM_IC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1PSC_MASK; + TIM_CCMR1(timer_peripheral) |= psc << 2; + break; + case TIM_IC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2PSC_MASK; + TIM_CCMR1(timer_peripheral) |= psc << 10; + break; + case TIM_IC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3PSC_MASK; + TIM_CCMR2(timer_peripheral) |= psc << 2; + break; + case TIM_IC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4PSC_MASK; + TIM_CCMR2(timer_peripheral) |= psc << 10; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Capture/Compare Channel Direction/Input + +The Capture/Compare channel is defined as output (compare) or input with the +input mapping specified: + +@li channel is configured as output +@li channel is configured as input and mapped on corresponding input +@li channel is configured as input and mapped on alternate input +(TI2 for channel 1, TI1 for channel 2, TI4 for channel 3, TI3 for channel 4) +@li channel is configured as input and is mapped on TRC (requires an +internal trigger input selected through TS bit + +@note not all combinations of the input and channel are valid, see datasheets. +@note these parameters are writable only when the channel is off. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] in ::tim_ic_input. Input Capture channel direction and source input. +*/ + +void timer_ic_set_input(uint32_t timer_peripheral, enum tim_ic_id ic, + enum tim_ic_input in) +{ + in &= 3; + + if (((ic == TIM_IC2) || (ic == TIM_IC4)) && + ((in == TIM_IC_IN_TI1) || (in == TIM_IC_IN_TI2))) { + /* Input select bits are flipped for these combinations */ + in ^= 3; + } + + switch (ic) { + case TIM_IC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; + TIM_CCMR1(timer_peripheral) |= in; + break; + case TIM_IC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; + TIM_CCMR1(timer_peripheral) |= in << 8; + break; + case TIM_IC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; + TIM_CCMR2(timer_peripheral) |= in; + break; + case TIM_IC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; + TIM_CCMR2(timer_peripheral) |= in << 8; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Input Capture + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +*/ + +void timer_ic_enable(uint32_t timer_peripheral, enum tim_ic_id ic) +{ + TIM_CCER(timer_peripheral) |= (0x1 << (ic * 4)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Input Capture + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +*/ + +void timer_ic_disable(uint32_t timer_peripheral, enum tim_ic_id ic) +{ + TIM_CCER(timer_peripheral) &= ~(0x1 << (ic * 4)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Filter Parameters for Slave + +Set the input filter parameters for the external trigger, specifying: +@li the frequency of sampling from the Deadtime and Sampling clock +(@see @ref timer_set_clock_division) +@li the number of events that must occur before a transition is considered +valid. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] flt ::tim_ic_filter. Input Capture Filter identifier. +*/ + +void timer_slave_set_filter(uint32_t timer_peripheral, enum tim_ic_filter flt) +{ + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETF_MASK; + TIM_SMCR(timer_peripheral) |= flt << 8; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Prescaler for Slave + +Set the external trigger frequency division ratio. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. +*/ + +void timer_slave_set_prescaler(uint32_t timer_peripheral, enum tim_ic_psc psc) +{ + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETPS_MASK; + TIM_SMCR(timer_peripheral) |= psc << 12; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Polarity for Slave + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] pol ::tim_et_pol. Slave External Trigger polarity. +*/ + +void timer_slave_set_polarity(uint32_t timer_peripheral, enum tim_et_pol pol) +{ + if (pol) { + TIM_SMCR(timer_peripheral) |= TIM_SMCR_ETP; + } else { + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETP; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Slave Mode + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] mode Unsigned int8. Slave mode @ref tim_sms +*/ + +void timer_slave_set_mode(uint32_t timer_peripheral, uint8_t mode) +{ + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_SMS_MASK; + TIM_SMCR(timer_peripheral) |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Slave Trigger Source + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] trigger Unsigned int8. Slave trigger source @ref tim_ts +*/ + +void timer_slave_set_trigger(uint32_t timer_peripheral, uint8_t trigger) +{ + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_TS_MASK; + TIM_SMCR(timer_peripheral) |= trigger; +} + +/* TODO Timer DMA burst */ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f0234.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f0234.c new file mode 100644 index 00000000..1506408c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f0234.c @@ -0,0 +1,58 @@ +/** @addtogroup timer_file + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Polarity + +The timer channel must be set to input capture mode. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] pol ::tim_ic_pol. Input Capture polarity control. +*/ + +void timer_ic_set_polarity(uint32_t timer_peripheral, enum tim_ic_id ic, + enum tim_ic_pol pol) +{ + /* Clear CCxP and CCxNP to zero. For both edge trigger both fields are + * set. Case 10 is invalid. + */ + TIM_CCER(timer_peripheral) &= ~(0xa << (ic * 4)); + switch (pol) { + case TIM_IC_RISING: /* 00 */ + break; + case TIM_IC_BOTH: /* 11 */ + TIM_CCER(timer_peripheral) |= (0xa << (ic * 4)); + break; + case TIM_IC_FALLING: /* 01 */ + TIM_CCER(timer_peripheral) |= (0x2 << (ic * 4)); + } +} +/**@}*/ + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f24.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f24.c new file mode 100644 index 00000000..ce1c1e38 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/timer_common_f24.c @@ -0,0 +1,53 @@ +/** @addtogroup timer_file + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Option + +Set timer options register on TIM2 or TIM5, used for trigger remapping on TIM2, +and similarly for TIM5 for oscillator calibration purposes. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@returns Unsigned int32. Option flags TIM2: @ref tim2_opt_trigger_remap, TIM5: +@ref tim5_opt_trigger_remap. +*/ + +void timer_set_option(uint32_t timer_peripheral, uint32_t option) +{ + if (timer_peripheral == TIM2) { + TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK; + TIM_OR(timer_peripheral) |= option; + } else if (timer_peripheral == TIM5) { + TIM_OR(timer_peripheral) &= ~TIM5_OR_TI4_RMP_MASK; + TIM_OR(timer_peripheral) |= option; + } +} + +/**@}*/ + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_all.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_all.c new file mode 100644 index 00000000..4e42f2a9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_all.c @@ -0,0 +1,367 @@ +/** @addtogroup usart_file + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +This library supports the USART/UART in the STM32F series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Devices can have up to 3 USARTs and 2 UARTs. + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Baudrate. + +The baud rate is computed from the APB high-speed prescaler clock (for +USART1/6) or the APB low-speed prescaler clock (for other USARTs). These values +must be correctly set before calling this function (refer to the +rcc_clock_setup-* functions in RCC). + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] baud unsigned 32 bit. Baud rate specified in Hz. +*/ + +void usart_set_baudrate(uint32_t usart, uint32_t baud) +{ + uint32_t clock = rcc_apb1_frequency; + +#if defined STM32F2 || defined STM32F4 + if ((usart == USART1) || + (usart == USART6)) { + clock = rcc_apb2_frequency; + } +#else + if (usart == USART1) { + clock = rcc_apb2_frequency; + } +#endif + + /* + * Yes it is as simple as that. The reference manual is + * talking about fractional calculation but it seems to be only + * marketing babble to sound awesome. It is nothing else but a + * simple divider to generate the correct baudrate. + * + * Note: We round() the value rather than floor()ing it, for more + * accurate divisor selection. + */ + USART_BRR(usart) = ((2 * clock) + baud) / (2 * baud); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Word Length. + +The word length is set to 8 or 9 bits. Note that the last bit will be a parity +bit if parity is enabled, in which case the data length will be 7 or 8 bits +respectively. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] bits unsigned 32 bit. Word length in bits 8 or 9. +*/ + +void usart_set_databits(uint32_t usart, uint32_t bits) +{ + if (bits == 8) { + USART_CR1(usart) &= ~USART_CR1_M; /* 8 data bits */ + } else { + USART_CR1(usart) |= USART_CR1_M; /* 9 data bits */ + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Stop Bit(s). + +The stop bits are specified as 0.5, 1, 1.5 or 2. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] stopbits unsigned 32 bit. Stop bits @ref usart_cr2_stopbits. +*/ + +void usart_set_stopbits(uint32_t usart, uint32_t stopbits) +{ + uint32_t reg32; + + reg32 = USART_CR2(usart); + reg32 = (reg32 & ~USART_CR2_STOPBITS_MASK) | stopbits; + USART_CR2(usart) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Parity. + +The parity bit can be selected as none, even or odd. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] parity unsigned 32 bit. Parity @ref usart_cr1_parity. +*/ + +void usart_set_parity(uint32_t usart, uint32_t parity) +{ + uint32_t reg32; + + reg32 = USART_CR1(usart); + reg32 = (reg32 & ~USART_PARITY_MASK) | parity; + USART_CR1(usart) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Rx/Tx Mode. + +The mode can be selected as Rx only, Tx only or Rx+Tx. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] mode unsigned 32 bit. Mode @ref usart_cr1_mode. +*/ + +void usart_set_mode(uint32_t usart, uint32_t mode) +{ + uint32_t reg32; + + reg32 = USART_CR1(usart); + reg32 = (reg32 & ~USART_MODE_MASK) | mode; + USART_CR1(usart) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Hardware Flow Control. + +The flow control bit can be selected as none, RTS, CTS or RTS+CTS. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] flowcontrol unsigned 32 bit. Flowcontrol @ref usart_cr3_flowcontrol. +*/ + +void usart_set_flow_control(uint32_t usart, uint32_t flowcontrol) +{ + uint32_t reg32; + + reg32 = USART_CR3(usart); + reg32 = (reg32 & ~USART_FLOWCONTROL_MASK) | flowcontrol; + USART_CR3(usart) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_enable(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_UE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable. + +At the end of the current frame, the USART is disabled to reduce power. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_disable(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_UE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Send Data Word with Blocking + +Blocks until the transmit data buffer becomes empty then writes the next data +word for transmission. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] data unsigned 16 bit. +*/ + +void usart_send_blocking(uint32_t usart, uint16_t data) +{ + usart_wait_send_ready(usart); + usart_send(usart, data); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Received Data Word with Blocking. + +Wait until a data word has been received then return the word. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@returns unsigned 16 bit data word. +*/ + +uint16_t usart_recv_blocking(uint32_t usart) +{ + usart_wait_recv_ready(usart); + + return usart_recv(usart); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver DMA Enable. + +DMA is available on: +@li USART1 Rx DMA1 channel 5. +@li USART2 Rx DMA1 channel 6. +@li USART3 Rx DMA1 channel 3. +@li UART4 Rx DMA2 channel 3. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_enable_rx_dma(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_DMAR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver DMA Disable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_disable_rx_dma(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_DMAR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter DMA Enable. + +DMA is available on: +@li USART1 Tx DMA1 channel 4. +@li USART2 Tx DMA1 channel 7. +@li USART3 Tx DMA1 channel 2. +@li UART4 Tx DMA2 channel 5. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_enable_tx_dma(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_DMAT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter DMA Disable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_disable_tx_dma(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_DMAT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver Interrupt Enable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_enable_rx_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_RXNEIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver Interrupt Disable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_disable_rx_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_RXNEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter Interrupt Enable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_enable_tx_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_TXEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter Interrupt Disable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_disable_tx_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_TXEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Error Interrupt Enable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_enable_error_interrupt(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_EIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Error Interrupt Disable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_disable_error_interrupt(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_EIE; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_f124.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_f124.c new file mode 100644 index 00000000..f567fcb0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_f124.c @@ -0,0 +1,113 @@ +/** @addtogroup usart_file + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +This library supports the USART/UART in the STM32F series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Devices can have up to 3 USARTs and 2 UARTs. + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief USART Send a Data Word. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] data unsigned 16 bit. +*/ + +void usart_send(uint32_t usart, uint16_t data) +{ + /* Send data. */ + USART_DR(usart) = (data & USART_DR_MASK); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Received Data Word. + +If parity is enabled the MSB (bit 7 or 8 depending on the word length) is the +parity bit. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@returns unsigned 16 bit data word. +*/ + +uint16_t usart_recv(uint32_t usart) +{ + /* Receive data. */ + return USART_DR(usart) & USART_DR_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Wait for Transmit Data Buffer Empty + +Blocks until the transmit data buffer becomes empty and is ready to accept the +next data word. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_wait_send_ready(uint32_t usart) +{ + /* Wait until the data has been transferred into the shift register. */ + while ((USART_SR(usart) & USART_SR_TXE) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Wait for Received Data Available + +Blocks until the receive data buffer holds a valid received data word. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_wait_recv_ready(uint32_t usart) +{ + /* Wait until the data is ready to be received. */ + while ((USART_SR(usart) & USART_SR_RXNE) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Status Flag. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@param[in] flag Unsigned int32. Status register flag @ref usart_sr_flags. +@returns boolean: flag set. +*/ + +bool usart_get_flag(uint32_t usart, uint32_t flag) +{ + return ((USART_SR(usart) & flag) != 0); +} + + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_v2.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_v2.c new file mode 100644 index 00000000..dbf16a76 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/common/usart_common_v2.c @@ -0,0 +1,228 @@ +/** @addtogroup usart_file + + @author @htmlonly © @endhtmlonly 2016 Cem Basoglu + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Cem Basoglu + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief USART enable data inversion + + Logical data from the data register are send/received in negative/inverse + logic. (1=L, 0=H). The parity bit is also inverted. + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_data_inversion(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_DATAINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART disable data inversion + + Logical data from the data register are send/received in positive/direct logic. + (1=H, 0=L) + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_data_inversion(uint32_t usart) +{ + USART_CR2(usart) &= ~USART_CR2_DATAINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable TX pin active level inversion + + TX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_tx_inversion(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_TXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable TX pin active level inversion + + TX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_tx_inversion(uint32_t usart) +{ + USART_CR2(usart) &= ~USART_CR2_TXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable RX pin active level inversion + + RX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). + + This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_rx_inversion(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_RXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable RX pin active level inversion + + RX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + + This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_rx_inversion(uint32_t usart) +{ + + USART_CR2(usart) &= ~USART_CR2_RXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable Half-duplex + + - The TX and RX lines are internally connected. + - The RX pin is no longer used + - The TX pin is always released when no data is transmitted. Thus, + it acts as a standard I/O in idle or in reception. It means + that the I/O must be configured so that TX is configured as + alternate function open-drain with an external pull-up. + + Apart from this, the communication protocol is similar to normal USART mode. + Any conflicts on the line must be managed by software + + This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_halfduplex(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_HDSEL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable Half-duplex + + This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_halfduplex(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_HDSEL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set receiver timeout value + + Sets the receive timeout value in terms of number of bit duration. + The RTOF @ref usart_isr_rtof is set if, after the last received character, + no new start bit is detected for more than the receive timeout value. + + @note The timeout value can also be written when USART is enabled. + If the new value is lower/equals the internal hardware counter, + the RTOF flag will be set. + + @param[in] usart USART block register address base @ref usart_reg_base + @param[in] value The receive timeout value in terms of number of bit duration. + */ +void usart_set_rx_timeout_value(uint32_t usart, uint32_t value) +{ + uint32_t reg; + reg = USART_RTOR(usart) & ~USART_RTOR_RTO_MASK; + reg |= (USART_RTOR_RTO_VAL(value) & USART_RTOR_RTO_MASK); + USART_RTOR(usart) = reg; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART enable receive timeout function + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_rx_timeout(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_RTOEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART disable receive timeout function + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_rx_timeout(uint32_t usart) +{ + USART_CR2(usart) &= ~USART_CR2_RTOEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART enable receive timeout interrupt + + An interrupt is generated when the RTOF Flag is set + in the ISR @ref usart_isr register. + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_rx_timeout_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_RTOIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART disable receive timeout interrupt + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_rx_timeout_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_RTOIE; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/desig.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/desig.c new file mode 100644 index 00000000..272bfcb0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/desig.c @@ -0,0 +1,88 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +uint16_t desig_get_flash_size(void) +{ + return DESIG_FLASH_SIZE; +} + +void desig_get_unique_id(uint32_t *result) +{ + *result++ = DESIG_UNIQUE_ID2; + *result++ = DESIG_UNIQUE_ID1; + *result = DESIG_UNIQUE_ID0; +} + +void desig_get_unique_id_as_string(char *string, + unsigned int string_len) +{ + int i, len; + uint32_t dev_id_buf[3]; + uint8_t *device_id = (uint8_t *)dev_id_buf; + const char chars[] = "0123456789ABCDEF"; + + desig_get_unique_id(dev_id_buf); + + /* Each byte produces two characters */ + len = (2 * sizeof(dev_id_buf) < string_len) ? + 2 * sizeof(dev_id_buf) : string_len - 1; + + for (i = 0; i < len; i += 2) { + string[i] = chars[(device_id[i / 2] >> 4) & 0x0F]; + string[i + 1] = chars[(device_id[i / 2] >> 0) & 0x0F]; + } + + string[len] = '\0'; +} + +/** + * Generate a serial number from the unique id registers as the DFU bootloader. + * This document: http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf + * says that the serial number has to be at least 12 digits long and that + * the last 12 digits need to be unique. It also stipulates that the valid + * character set is that of upper-case hexadecimal digits. + * The onboard DFU bootloader produces a 12-digit serial based on the + * 96-bit unique ID. Show the serial with ```dfu-util -l``` while the + * MCU is in DFU mode. + * @see https://my.st.com/52d187b7 for the algorithim used. + * @param string pointer to store serial in, must be at least 13 bytes + */ +void desig_get_unique_id_as_dfu(char *string) { + uint8_t *id = (uint8_t *)DESIG_UNIQUE_ID_BASE; + + uint8_t serial[6]; + serial[0] = id[11]; + serial[1] = id[10] + id[2]; + serial[2] = id[9]; + serial[3] = id[8] + id[0]; + serial[4] = id[7]; + serial[5] = id[6]; + + uint8_t *ser = &serial[0]; + uint8_t *end = &serial[6]; + const char hex_digit[] = "0123456789ABCDEF"; + + for (; ser < end; ser++) { + *string++ = hex_digit[(*ser >> 4) & 0x0f]; + *string++ = hex_digit[(*ser >> 0) & 0x0f]; + } + *string = '\0'; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/Makefile new file mode 100644 index 00000000..cb866b9a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/Makefile @@ -0,0 +1,58 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2013 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32f0 +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m0 $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F0 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) + +ARFLAGS = rcs + +OBJS = can.o flash.o rcc.o usart.o dma.o rtc.o comparator.o crc.o \ + dac.o iwdg.o pwr.o gpio.o timer.o adc.o desig.o + +OBJS += gpio_common_all.o gpio_common_f0234.o crc_common_all.o \ + pwr_common_v1.o iwdg_common_all.o rtc_common_l1f024.o \ + dma_common_l1f013.o exti_common_all.o spi_common_all.o \ + spi_common_f03.o flash_common_f01.o dac_common_all.o \ + timer_common_all.o timer_common_f0234.o rcc_common_all.o +OBJS += adc_common_v2.o +OBJS += crs_common_all.o +OBJS += usart_common_v2.o +OBJS += i2c_common_v2.o + +OBJS += usb.o usb_control.o usb_standard.o +OBJS += st_usbfs_core.o st_usbfs_v2.o + +VPATH += ../../usb:../:../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/adc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/adc.c new file mode 100644 index 00000000..dead3358 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/adc.c @@ -0,0 +1,536 @@ +/** @defgroup adc_file ADC + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx Analog to Digital Converters + * + * based on F3 file + * + * @date 14 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * @defgroup adc_api_opmode ADC Operation mode API + * @ingroup adc_file + * + * @brief ADC Result API + * + *@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Regular Conversions + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_enable_discontinuous_mode(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_DISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Regular Conversions + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_disable_discontinuous_mode(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_DISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** ADC Set operation mode + * + * There are some operation modes, common for entire stm32 branch. In the text + * the braces are describing result to single trigger event. The trigger event + * is described by character T in the description. The ADC is configured to + * convert list of inputs [0, 1, 2, 3]. In Grouped modes, there is used group + * size of 2 conversions in the examples + * + * @li @c ADC_MODE_SEQUENTIAL: T(0) T(1) T(2) T(3)[EOSEQ] T(0) T(1) T(2) ... + * + * In this mode, after the trigger event a single channel is converted and the + * next channel in the list is prepared to convert on next trigger edge. + * + * @note This mode can be emulated by ADC_MODE_GROUPED with group size + * of 1. @par + * + * @li @c ADC_MODE_SCAN: T(0123)[EOSEQ] T(0123)[EOSEQ] T(0123)[EOSEQ] + * + * In this mode, after the trigger event, all channels will be converted once, + * storing results sequentially. + * + * @note The DMA must be configured properly for more than single channel to + * convert. @par + * + * @li @c ADC_MODE_SCAN_INFINITE: T(0123[EOSEQ]0123[EOSEQ]0123[EOSEQ]...) + * + * In this mode, after the trigger event, all channels from the list are + * converted. At the end of list, the conversion continues from the beginning. + * + * @note The DMA must be configured properly to operate in this mode.@par + * + * @li @c ADC_MODE_GROUPED: T(12) T(34)[EOSEQ] T(12) T(34)[EOSEQ] T(12) + * + * In this mode, after the trigger event, a specified group size of channels + * are converted. If the end of channel list occurs, the EOSEQ is generated + * and on the next trigger it wraps to the beginning. + * + * @note The DMA must be configured properly to operate on more than single + * channel conversion groups.@par + * + * @warning not all families supports all modes of operation of ADC. + * + * @par + * + */ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set conversion operation mode + * + * @note on SEQUENTIAL mode, the trigger event is necessary to start conversion. + * @par + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] adc ::adc_opmode. ADC operation mode (@ref adc_opmode) + */ + +void adc_set_operation_mode(uint32_t adc, enum adc_opmode opmode) +{ + switch (opmode) { + case ADC_MODE_SEQUENTIAL: + ADC_CFGR1(adc) &= ~ADC_CFGR1_CONT; + ADC_CFGR1(adc) |= ADC_CFGR1_DISCEN; + break; + + case ADC_MODE_SCAN: + ADC_CFGR1(adc) &= ~(ADC_CFGR1_CONT | ADC_CFGR1_DISCEN); + break; + + case ADC_MODE_SCAN_INFINITE: + ADC_CFGR1(adc) &= ~ADC_CFGR1_DISCEN; + ADC_CFGR1(adc) |= ADC_CFGR1_CONT; + break; + } +} + +/**@}*/ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * @defgroup adc_api_trigger ADC Trigger API + * @ingroup adc_file + * + * @brief ADC Trigger API + * + *@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + * + * This enables an external trigger for set of defined regular channels, and + * sets the polarity of the trigger event: rising or falling edge or both. Note + * that if the trigger polarity is zero, triggering is disabled. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] trigger Unsigned int32. Trigger identifier + * @ref adc_trigger_regular + * @param[in] polarity Unsigned int32. Trigger polarity @ref + * adc_trigger_polarity_regular + */ + +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_EXTSEL) | trigger; + ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_EXTEN_MASK) | polarity; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_disable_external_trigger_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_EXTEN_MASK; +} + +/**@}*/ + + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * @defgroup adc_api_interrupts ADC Interrupt configuration API + * @ingroup adc_file + * + * @brief ADC Interrupt configuration API + * + *@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog Interrupt + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_enable_watchdog_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_AWD1IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Conversion Interrupt + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_disable_watchdog_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_AWD1IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Analog Watchdog Flag + * + * This flag is set when the converted voltage crosses the high or low + * thresholds. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @returns bool true, if the signal is out of defined analog range. + */ + +bool adc_get_watchdog_flag(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_AWD1; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Clear Analog Watchdog Flag + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_clear_watchdog_flag(uint32_t adc) +{ + ADC_ISR(adc) = ADC_ISR_AWD1; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Regular End-Of-Conversion Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_enable_eoc_sequence_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_EOSEQIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Conversion Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_disable_eoc_sequence_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_EOSEQIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Regular End-Of-Conversion Sequence Flag + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +bool adc_get_eoc_sequence_flag(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_EOSEQ; +} + + +/**@}*/ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * @defgroup adc_api_config ADC Basic configuration API + * @ingroup adc_file + * + * @brief ADC Basic configuration API + * + *@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Prescale + * + * The ADC clock taken from the many sources. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] prescale Unsigned int32. Prescale value (@ref adc_api_clksource) + */ + +void adc_set_clk_source(uint32_t adc, uint32_t source) +{ + ADC_CFGR2(adc) = ((ADC_CFGR2(adc) & ~ADC_CFGR2_CKMODE) | source); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set a Regular Channel Conversion Sequence + * + * Define a sequence of channels to be converted as a regular group with a + * length from 1 to 18 channels. If this is called during conversion, the + * current conversion is reset and conversion begins again with the newly + * defined group. + * + * @warning This core doesn't support the random order of ADC conversions. + * The channel list must be ordered by channel number. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] length Unsigned int8. Number of channels in the group. + * @param[in] channel Unsigned int8[]. Set of channels to convert, integers + * 0..18. + */ + +void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + uint32_t reg32 = 0; + uint8_t i = 0; + bool stepup = false, stepdn = false; + + if (length == 0) { + ADC_CHSELR(adc) = 0; + return; + } + + reg32 |= (1 << channel[0]); + + for (i = 1; i < length; i++) { + reg32 |= (1 << channel[i]); + stepup |= channel[i-1] < channel[i]; + stepdn |= channel[i-1] > channel[i]; + } + + /* Check, if the channel list is in order */ + if (stepup && stepdn) { + cm3_assert_not_reached(); + } + + /* Update the scan direction flag */ + if (stepdn) { + ADC_CFGR1(adc) |= ADC_CFGR1_SCANDIR; + } else { + ADC_CFGR1(adc) &= ~ADC_CFGR1_SCANDIR; + } + + ADC_CHSELR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for All Channels + * + * The sampling time can be selected in ADC clock cycles from 1.5 to 239.5, + * same for all channels. + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] time Unsigned int8. Sampling time selection (@ref adc_api_smptime) + */ + +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time) +{ + ADC_SMPR(adc) = time & ADC_SMPR_SMP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable The VBat Sensor + * + * This enables the battery voltage measurements on channel 17. + */ + +void adc_enable_vbat_sensor(void) +{ + ADC_CCR(ADC1) |= ADC_CCR_VBATEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable The VBat Sensor + * + * Disabling this will reduce power consumption from the battery voltage + * measurement. + */ + +void adc_disable_vbat_sensor(void) +{ + ADC_CCR(ADC1) &= ~ADC_CCR_VBATEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Start the calibration procedure + * @deprecated Replaced by adc_calibrate/_async/is_calibrating + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_calibrate_start(uint32_t adc) +{ + ADC_CR(adc) = ADC_CR_ADCAL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Wait to finish the ADC calibration procedure + * @deprecated Replaced by adc_calibrate/_async/is_calibrating + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_calibrate_wait_finish(uint32_t adc) +{ + while (ADC_CR(adc) & ADC_CR_ADCAL); +} + +/**@}*/ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/** + * @defgroup adc_api_wdg ADC Analog watchdog API + * @ingroup adc_file + * + * @brief ADC analog watchdog API definitions. + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Analog watchdog is disabled + * by default. + * + * @warning Comparison is done before data alignment takes place, so the + * thresholds are left-aligned. + * + * Example 1: Enable watchdog checking on all channels + * + * @code + * // in configuration + * adc_enable_analog_watchdog_on_all_channels(ADC1); + * adc_set_watchdog_high_threshold(ADC1, 0xE00); + * adc_set_watchdog_low_threshold(ADC1, 0x200); + * + * // in the main application thread + * if (adc_get_watchdog_flag(ADC1)) { + * // the converted signal is out of AWD ranges + * adc_clear_watchdog_flag(ADC1); + * } + * @endcode + * + * Example 2: Enable watchdog checking on channel 5 + * + * @code + * // in configuration + * adc_enable_analog_watchdog_on_selected_channel(ADC1,5); + * adc_set_watchdog_high_threshold(ADC1, 0xE00); + * adc_set_watchdog_low_threshold(ADC1, 0x200); + * + * // in the main application thread + * if (adc_get_watchdog_flag(ADC1)) { + * // the converted signal is out of AWD ranges + * adc_clear_watchdog_flag(ADC1); + * } + * @endcode + *@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for All Channels + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ + +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1EN; + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1SGL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for a Selected Channel + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] chan Unsigned int8. ADC channel number @ref adc_api_channel + */ + +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, uint8_t chan) +{ + ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_AWD1CH) | + ADC_CFGR1_AWD1CH_VAL(chan); + + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1EN | ADC_CFGR1_AWD1SGL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + */ +void adc_disable_analog_watchdog(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Upper Threshold + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] threshold Unsigned int8. Upper threshold value + */ + +void adc_set_watchdog_high_threshold(uint32_t adc, uint8_t threshold) +{ + ADC_TR1(adc) = (ADC_TR1(adc) & ~ADC_TR1_HT) | ADC_TR1_HT_VAL(threshold); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Lower Threshold + * + * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base) + * @param[in] threshold Unsigned int8. Lower threshold value + */ + +void adc_set_watchdog_low_threshold(uint32_t adc, uint8_t threshold) +{ + ADC_TR1(adc) = (ADC_TR1(adc) & ~ADC_TR1_LT) | ADC_TR1_LT_VAL(threshold); +} + +/**@}*/ + +/*---------------------------------------------------------------------------*/ + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/comparator.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/comparator.c new file mode 100644 index 00000000..51bd0f2f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/comparator.c @@ -0,0 +1,64 @@ +/** @defgroup comp_file COMP + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx COMP + * + * @version 1.0.0 + * + * @date 10 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#include + +void comp_enable(uint8_t id) +{ + COMP_CSR(id) |= COMP_CSR_EN; +} + +void comp_disable(uint8_t id) +{ + COMP_CSR(id) &= ~COMP_CSR_EN; +} + +void comp_select_input(uint8_t id, uint32_t input) +{ + COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_INSEL) | input; +} + +void comp_select_output(uint8_t id, uint32_t output) +{ + COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_OUTSEL) | output; +} + +void comp_select_hyst(uint8_t id, uint32_t hyst) +{ + COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_HYST) | hyst; +} + +void comp_select_speed(uint8_t id, uint32_t speed) +{ + COMP_CSR(id) = (COMP_CSR(id) & ~COMP_CSR_SPEED) | speed; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/crc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/crc.c new file mode 100644 index 00000000..2519b22f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/crc.c @@ -0,0 +1,31 @@ +/** @defgroup crc_file CRC + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx CRC + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dac.c new file mode 100644 index 00000000..55cdd62c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dac.c @@ -0,0 +1,31 @@ +/** @defgroup dac_file DAC + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx DAC + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dma.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dma.c new file mode 100644 index 00000000..8f158a81 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/dma.c @@ -0,0 +1,31 @@ +/** @defgroup dma_file DMA + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx DMA + * + * @version 1.0.0 + * + * @date 10 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/flash.c new file mode 100644 index 00000000..e39b6b15 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/flash.c @@ -0,0 +1,157 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F05x FLASH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2013 + * Frantisek Burian + * + * @date 14 January 2014 + * + * For the STM32F05x, accessing FLASH memory is described in + * section 3 of the STM32F05x Reference Manual. + * + * FLASH memory may be used for data storage as well as code, and may be + * programmatically modified. Note that for firmware upload the STM32F1xx + * provides a built-in bootloader in system memory that can be entered from a + * running program. + * + * FLASH must first be unlocked before programming. In this module a write to + * FLASH is a blocking operation until the end-of-operation flag is asserted. + * + * @note: don't forget to lock it again when all operations are complete. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Program error, end of operation, write protect error, busy. +*/ + +void flash_clear_status_flags(void) +{ + flash_clear_pgerr_flag(); + flash_clear_eop_flag(); + flash_clear_wrprterr_flag(); + flash_clear_bsy_flag(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read All Status Flags + +The programming error, end of operation, write protect error and busy flags +are returned in the order of appearance in the status register. + +@returns uint32_t. bit 0: busy, bit 2: programming error, bit 4: write protect +error, bit 5: end of operation. +*/ + +uint32_t flash_get_status_flags(void) +{ + return FLASH_SR & (FLASH_SR_PGERR | + FLASH_SR_EOP | + FLASH_SR_WRPRTERR | + FLASH_SR_BSY); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a Half Word to FLASH + +This performs all operations necessary to program a 16 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +Status bit polling is used to detect end of operation. + +@param[in] address Full address of flash half word to be programmed. +@param[in] data half word to write +*/ + +void flash_program_half_word(uint32_t address, uint16_t data) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_CR_PG; + + MMIO16(address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_CR_PG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase a Page of FLASH + +This performs all operations necessary to erase a page in FLASH memory. +The page should be checked to ensure that it was properly erased. A page must +first be fully erased before attempting to program it. + +Note that the page sizes differ between devices. See the reference manual or +the FLASH programming manual for details. + +@param[in] page_address Full address of flash page to be erased. +*/ + +void flash_erase_page(uint32_t page_address) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_CR_PER; + FLASH_AR = page_address; + FLASH_CR |= FLASH_CR_STRT; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_CR_PER; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase All FLASH + +This performs all operations necessary to erase all user pages in the FLASH +memory. The information block is unaffected. +*/ + +void flash_erase_all_pages(void) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */ + FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */ + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */ + +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/gpio.c new file mode 100644 index 00000000..f60b4289 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/gpio.c @@ -0,0 +1,31 @@ +/** @defgroup gpio_file GPIO + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx General Purpose I/O + * + * @version 1.0.0 + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/i2c.c new file mode 100644 index 00000000..a39c4be7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/i2c.c @@ -0,0 +1,32 @@ +/** @defgroup i2c_file I2C + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx I2C + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/iwdg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/iwdg.c new file mode 100644 index 00000000..b34a652f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/iwdg.c @@ -0,0 +1,31 @@ +/** @defgroup iwdg_file IWDG + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx Independent Watchdog Timer + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/libopencm3_stm32f0.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/pwr.c new file mode 100644 index 00000000..8a3ffd2e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/pwr.c @@ -0,0 +1,38 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx Power Control + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * This library supports the power control system for the + * STM32F0 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rcc.c new file mode 100644 index 00000000..d3798596 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rcc.c @@ -0,0 +1,606 @@ +/** @defgroup STM32F0xx-rcc-file RCC + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx Reset and Clock Control + * + * @version 1.0.0 + * + * @date 29 Jun 2013 + * + * This library supports the Reset and Clock Control System in the STM32F0xx + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include +#include + +/* Set the default clock frequencies */ +uint32_t rcc_ahb_frequency = 8000000; /* 8MHz after reset */ +uint32_t rcc_apb1_frequency = 8000000; /* 8MHz after reset */ + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Clear the Oscillator Ready Interrupt Flag + * + * Clear the interrupt flag that was set when a clock oscillator became ready + * to use. + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CIR |= RCC_CIR_HSI48RDYC; + break; + case RCC_HSI14: + RCC_CIR |= RCC_CIR_HSI14RDYC; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the Oscillator Ready Interrupt + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CIR |= RCC_CIR_HSI48RDYIE; + break; + case RCC_HSI14: + RCC_CIR |= RCC_CIR_HSI14RDYIE; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the Oscillator Ready Interrupt + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CIR &= ~RCC_CIR_HSI48RDYC; + break; + case RCC_HSI14: + RCC_CIR &= ~RCC_CIR_HSI14RDYC; + break; + case RCC_HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYC; + break; + case RCC_HSE: + RCC_CIR &= ~RCC_CIR_HSERDYC; + break; + case RCC_PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYC; + break; + case RCC_LSE: + RCC_CIR &= ~RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYC; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Read the Oscillator Ready Interrupt Flag + * + * @param[in] osc enum ::osc_t. Oscillator ID + * @returns int. Boolean value for flag set. + */ + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + return (RCC_CIR & RCC_CIR_HSI48RDYF) != 0; + break; + case RCC_HSI14: + return (RCC_CIR & RCC_CIR_HSI14RDYF) != 0; + break; + case RCC_HSI: + return (RCC_CIR & RCC_CIR_HSIRDYF) != 0; + break; + case RCC_HSE: + return (RCC_CIR & RCC_CIR_HSERDYF) != 0; + break; + case RCC_PLL: + return (RCC_CIR & RCC_CIR_PLLRDYF) != 0; + break; + case RCC_LSE: + return (RCC_CIR & RCC_CIR_LSERDYF) != 0; + break; + case RCC_LSI: + return (RCC_CIR & RCC_CIR_LSIRDYF) != 0; + break; + } + + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Clear the Clock Security System Interrupt Flag +*/ + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Read the Clock Security System Interrupt Flag + * + * @returns int. Boolean value for flag set. + */ + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + return RCC_CR2 & RCC_CR2_HSI48RDY; + case RCC_HSI14: + return RCC_CR2 & RCC_CR2_HSI14RDY; + case RCC_HSI: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_LSE: + return RCC_BDCR & RCC_BDCR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Turn on an Oscillator. + * + * Enable an oscillator and power on. Each oscillator requires an amount of + * time to settle to a usable state. Refer to datasheets for time delay + * information. A status flag is available to indicate when the oscillator + * becomes ready (see @ref rcc_osc_ready_int_flag and @ref + * rcc_wait_for_osc_ready). + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CR2 |= RCC_CR2_HSI48ON; + break; + case RCC_HSI14: + RCC_CR2 |= RCC_CR2_HSI14ON; + break; + case RCC_HSI: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Turn off an Oscillator. + * + * Disable an oscillator and power off. + * + * @note An oscillator cannot be turned off if it is selected as the system + * clock. + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CR2 &= ~RCC_CR2_HSI48ON; + break; + case RCC_HSI14: + RCC_CR2 &= ~RCC_CR2_HSI14ON; + break; + case RCC_HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + case RCC_PLL: + /* don't do anything */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the Clock Security System. + */ + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the Clock Security System. + */ + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the System Clock. + * + * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE, LSE and PLL have + * effect. + */ + +void rcc_set_sysclk_source(enum rcc_osc clk) +{ + switch (clk) { + case RCC_HSI: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI; + break; + case RCC_HSE: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSE; + break; + case RCC_PLL: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL; + break; + case RCC_HSI48: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI48; + break; + case RCC_LSI: + case RCC_LSE: + case RCC_HSI14: + /* do nothing */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the USB Clock. + * + * @param[in] osc enum ::osc_t. Oscillator ID. Only HSI48 or PLL have + * effect. + */ +void rcc_set_usbclk_source(enum rcc_osc clk) +{ + switch (clk) { + case RCC_PLL: + RCC_CFGR3 |= RCC_CFGR3_USBSW; + break; + case RCC_HSI48: + RCC_CFGR3 &= ~RCC_CFGR3_USBSW; + break; + case RCC_HSI: + case RCC_HSE: + case RCC_LSI: + case RCC_LSE: + case RCC_HSI14: + /* do nothing */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the RTC clock + +*/ + +void rcc_enable_rtc_clock(void) +{ + RCC_BDCR |= RCC_BDCR_RTCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the RTC clock + +*/ + +void rcc_disable_rtc_clock(void) +{ + RCC_BDCR &= ~RCC_BDCR_RTCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the RTC clock + +@param[in] clock_source ::rcc_osc. RTC clock source. Only HSE/32, LSE and LSI. +*/ + +void rcc_set_rtc_clock_source(enum rcc_osc clk) +{ + switch (clk) { + case RCC_HSE: + RCC_BDCR = (RCC_BDCR & ~RCC_BDCR_RTCSEL) | RCC_BDCR_RTCSEL_HSE; + break; + case RCC_LSE: + RCC_BDCR = (RCC_BDCR & ~RCC_BDCR_RTCSEL) | RCC_BDCR_RTCSEL_LSE; + break; + case RCC_LSI: + RCC_BDCR = (RCC_BDCR & ~RCC_BDCR_RTCSEL) | RCC_BDCR_RTCSEL_LSI; + break; + default: + /* do nothing */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Multiplication Factor. + * + * @note This only has effect when the PLL is disabled. + * + * @param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf + */ + +void rcc_set_pll_multiplication_factor(uint32_t mul) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLMUL) | mul; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllsrc Unsigned int32. PLL clock source @ref rcc_cfgr_pcs +*/ + +void rcc_set_pll_source(uint32_t pllsrc) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLSRC) | + (pllsrc << 16); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the HSE Frequency Divider used as PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllxtpre Unsigned int32. HSE division factor @ref rcc_cfgr_hsepre +*/ + +void rcc_set_pllxtpre(uint32_t pllxtpre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLXTPRE) | + (pllxtpre << 17); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the APB Prescale Factor. + * + * @param[in] ppre1 Unsigned int32. APB prescale factor @ref rcc_cfgr_apb1pre + */ + +void rcc_set_ppre(uint32_t ppre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PPRE) | ppre; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the AHB Prescale Factor. + * + * @param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre + */ + +void rcc_set_hpre(uint32_t hpre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_HPRE) | hpre; +} + +/** + * Set PLL Source pre-divider **CAUTION**. + * On F03x and F05, prediv only applies to HSE source. On others, this + * is _after_ source selection. See also f3. + * @param[in] prediv division by prediv+1 @ref rcc_cfgr2_prediv + */ +void rcc_set_prediv(uint32_t prediv) +{ + RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PREDIV) | prediv; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Get the System Clock Source. + * + * @returns ::osc_t System clock source: + */ + +enum rcc_osc rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + switch (RCC_CFGR & RCC_CFGR_SWS) { + case RCC_CFGR_SWS_HSI: + return RCC_HSI; + case RCC_CFGR_SWS_HSE: + return RCC_HSE; + case RCC_CFGR_SWS_PLL: + return RCC_PLL; + case RCC_CFGR_SWS_HSI48: + return RCC_HSI48; + } + + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Get the USB Clock Source. + * + * @returns ::osc_t USB clock source: + */ + +enum rcc_osc rcc_usb_clock_source(void) +{ + return (RCC_CFGR3 & RCC_CFGR3_USBSW) ? RCC_PLL : RCC_HSI48; +} + +/** + * Set System Clock PLL at 48MHz from HSE at 8MHz. + */ +void rcc_clock_setup_in_hse_8mhz_out_48mhz(void) +{ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + rcc_set_sysclk_source(RCC_HSE); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ); + + /* PLL: 8MHz * 6 = 48MHz */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL6); + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + rcc_set_sysclk_source(RCC_PLL); + + rcc_apb1_frequency = 48000000; + rcc_ahb_frequency = 48000000; +} + +/** + * Set System Clock PLL at 48MHz from HSI + */ +void rcc_clock_setup_in_hsi_out_48mhz(void) +{ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + rcc_set_sysclk_source(RCC_HSI); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ); + + /* 8MHz * 12 / 2 = 48MHz */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL12); + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + rcc_set_sysclk_source(RCC_PLL); + + rcc_apb1_frequency = 48000000; + rcc_ahb_frequency = 48000000; +} + +/** + * Set System Clock HSI48 at 48MHz + */ +void rcc_clock_setup_in_hsi48_out_48mhz(void) +{ + rcc_osc_on(RCC_HSI48); + rcc_wait_for_osc_ready(RCC_HSI48); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ); + + rcc_set_sysclk_source(RCC_HSI48); + + rcc_apb1_frequency = 48000000; + rcc_ahb_frequency = 48000000; +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rtc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rtc.c new file mode 100644 index 00000000..6d55cc71 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/rtc.c @@ -0,0 +1,31 @@ +/** @defgroup rtc_file RTC + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx RTC + * + * @version 1.0.0 + * + * @date 10 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/spi.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/spi.c new file mode 100644 index 00000000..c3410016 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/spi.c @@ -0,0 +1,31 @@ +/** @defgroup spi_file SPI + +@ingroup STM32F0xx + +@brief libopencm3 STM32F0xx SPI + +@version 1.0.0 + +@date 20 February 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f03xz6.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f03xz6.ld new file mode 100644 index 00000000..3cb420d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f03xz6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F03xz6, 32k flash, 4k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f04xz6.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f04xz6.ld new file mode 100644 index 00000000..772b6009 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f04xz6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F04xz6, 32k flash, 6k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz6.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz6.ld new file mode 100644 index 00000000..161bdc88 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F05xz6, 32k flash, 8k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz8.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz8.ld new file mode 100644 index 00000000..f53704cb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f05xz8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F05xz8, 64k flash, 8k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xz8.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xz8.ld new file mode 100644 index 00000000..dda24fdb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xz8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F07xz8, 64k flash, 16k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xzb.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xzb.ld new file mode 100644 index 00000000..0cbe7490 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/stm32f07xzb.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F07xzB, 128k flash, 16k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/syscfg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/syscfg.c new file mode 100644 index 00000000..5067d96f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/syscfg.c @@ -0,0 +1,31 @@ +/** @defgroup syscfg_file SYSCFG + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx SYSCFG + * + * @version 1.0.0 + * + * @date 10 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/timer.c new file mode 100644 index 00000000..88006834 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/timer.c @@ -0,0 +1,34 @@ +/** @defgroup timer_file Timers + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx Timers + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/usart.c new file mode 100644 index 00000000..c47363bd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f0/usart.c @@ -0,0 +1,375 @@ +/** @defgroup usart_file USART + * + * @ingroup STM32F0xx + * + * @brief libopencm3 STM32F0xx USART + * + * @version 1.0.0 + * + * @date 7 Jul 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Baudrate. + * + * @param usart USART block register address base @ref usart_reg_base + * @param baud Baud rate specified in Hz. + */ + +void usart_set_baudrate(uint32_t usart, uint32_t baud) +{ + uint32_t clock = rcc_apb1_frequency; + + if (usart == USART1) { + clock = rcc_apb1_frequency; + /* TODO selective PCLK, SYSCLK, HSI or LSE */ + } + + /* TODO check oversampling 16 */ + USART_BRR(usart) = ((2 * clock) + baud) / (2 * baud); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Word Length. + * + * The word length is set to 8 or 9 bits. Note that the last bit will be a + * parity bit if parity is enabled, in which case the data length will be 7 + * or 8 bits respectively. + * + * @param usart USART block register address base @ref usart_reg_base + * @param bits Word length in bits 8 or 9. + */ + +void usart_set_databits(uint32_t usart, uint32_t bits) +{ + if (bits == 8) { + USART_CR1(usart) &= ~USART_CR1_M; /* 8 data bits */ + } else { + USART_CR1(usart) |= USART_CR1_M; /* 9 data bits */ + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Stop Bit(s). + * + * The stop bits are specified as 0.5, 1, 1.5 or 2. + * + * @param usart USART block register address base @ref usart_reg_base + * @param stopbits Stop bits @ref usart_cr2_stopbits. + */ + +void usart_set_stopbits(uint32_t usart, uint32_t stopbits) +{ + USART_CR2(usart) = (USART_CR2(usart) & ~USART_CR2_STOP) | stopbits; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Parity. + * + * The parity bit can be selected as none, even or odd. + * + * @param usart USART block register address base @ref usart_reg_base + * @param parity Parity @ref usart_cr1_parity. + */ + +void usart_set_parity(uint32_t usart, uint32_t parity) +{ + USART_CR1(usart) = (USART_CR1(usart) & ~USART_PARITY) | parity; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Rx/Tx Mode. + * + * The mode can be selected as Rx only, Tx only or Rx+Tx. + * + * @param usart USART block register address base @ref usart_reg_base + * @param mode Mode @ref usart_cr1_mode. + */ + +void usart_set_mode(uint32_t usart, uint32_t mode) +{ + USART_CR1(usart) = (USART_CR1(usart) & ~USART_MODE) | mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set Hardware Flow Control. + * + * The flow control bit can be selected as none, RTS, CTS or RTS+CTS. + * + * @param usart USART block register address base @ref usart_reg_base + * @param flowcontrol Flowcontrol @ref usart_cr3_flowcontrol. + */ + +void usart_set_flow_control(uint32_t usart, uint32_t flowctrl) +{ + USART_CR3(usart) = (USART_CR3(usart) & ~USART_FLOWCONTROL) | flowctrl; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_enable(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_UE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable. + * + * At the end of the current frame, the USART is disabled to reduce power. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_disable(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_UE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Send a Data Word. + * + * @param usart USART block register address base @ref usart_reg_base + * @param data + */ + +void usart_send(uint32_t usart, uint16_t data) +{ + USART_TDR(usart) = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Received Data Word. + * + * If parity is enabled the MSB (bit 7 or 8 depending on the word length) is + * the parity bit. + * + * @param usart USART block register address base @ref usart_reg_base + * @returns data word. + */ + +uint16_t usart_recv(uint32_t usart) +{ + /* Receive data. */ + return USART_RDR(usart); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Wait for Transmit Data Buffer Empty + * + * Blocks until the transmit data buffer becomes empty and is ready to accept + * the next data word. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_wait_send_ready(uint32_t usart) +{ + /* Wait until the data has been transferred into the shift register. */ + while ((USART_ISR(usart) & USART_ISR_TXE) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Wait for Received Data Available + * + * Blocks until the receive data buffer holds a valid received data word. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_wait_recv_ready(uint32_t usart) +{ + /* Wait until the data is ready to be received. */ + while ((USART_ISR(usart) & USART_ISR_RXNE) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Send Data Word with Blocking + * + * Blocks until the transmit data buffer becomes empty then writes the next + * data word for transmission. + * + * @param usart USART block register address base @ref usart_reg_base + * @param data word to send + */ + +void usart_send_blocking(uint32_t usart, uint16_t data) +{ + usart_wait_send_ready(usart); + usart_send(usart, data); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Received Data Word with Blocking. + * + * Wait until a data word has been received then return the word. + * + * @param usart USART block register address base @ref usart_reg_base + * @returns data word. + */ + +uint16_t usart_recv_blocking(uint32_t usart) +{ + usart_wait_recv_ready(usart); + + return usart_recv(usart); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver DMA Enable. + * + * DMA is available on: + * @li USART1 Rx DMA1 channel 3 or 5. + * @li USART2 Rx DMA1 channel 5. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_enable_rx_dma(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_DMAR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver DMA Disable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_disable_rx_dma(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_DMAR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter DMA Enable. + * + * DMA is available on: + * @li USART1 Tx DMA1 channel 2 or 4. + * @li USART2 Tx DMA1 channel 4. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_enable_tx_dma(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_DMAT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter DMA Disable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_disable_tx_dma(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_DMAT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver Interrupt Enable. + * + * @param usart USART block register address base @ref usart_reg_base + */ +void usart_enable_rx_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_RXNEIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief USART Receiver Interrupt Disable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_disable_rx_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_RXNEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter Interrupt Enable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_enable_tx_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_TXEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Transmitter Interrupt Disable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_disable_tx_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_TXEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Error Interrupt Enable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_enable_error_interrupt(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_EIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Error Interrupt Disable. + * + * @param usart USART block register address base @ref usart_reg_base + */ + +void usart_disable_error_interrupt(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_EIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Status Flag. + * + * @param usart USART block register address base @ref usart_reg_base + * @param flag Status register flag @ref usart_sr_flags. + * @returns boolean: flag set. + */ + +bool usart_get_flag(uint32_t usart, uint32_t flag) +{ + return ((USART_ISR(usart) & flag) != 0); +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/Makefile new file mode 100755 index 00000000..49f5735e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/Makefile @@ -0,0 +1,57 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32f1 +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F1 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs + +OBJS = adc.o adc_common_v1.o can.o desig.o flash.o gpio.o \ + rcc.o rtc.o timer.o +OBJS += mac.o mac_stm32fxx7.o phy.o phy_ksz8051mll.o + +OBJS += crc_common_all.o dac_common_all.o dma_common_l1f013.o \ + gpio_common_all.o i2c_common_v1.o iwdg_common_all.o \ + pwr_common_v1.o spi_common_all.o spi_common_l1f124.o \ + timer_common_all.o usart_common_all.o usart_common_f124.o \ + rcc_common_all.o exti_common_all.o \ + flash_common_f01.o + +OBJS += usb.o usb_control.o usb_standard.o usb_msc.o +OBJS += usb_fx07_common.o usb_f107.o +OBJS += st_usbfs_core.o st_usbfs_v1.o + +VPATH += ../../usb:../:../../cm3:../common:../../ethernet + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/adc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/adc.c new file mode 100644 index 00000000..7a108fc4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/adc.c @@ -0,0 +1,461 @@ +/** @defgroup adc_file ADC + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Analog to Digital Converters + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 +Edward Cheeseman +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +@date 18 August 2012 + +This library supports the A/D Converter Control System in the STM32F1xx series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Devices can have up to three A/D converters each with their own set of +registers. However all the A/D converters share a common clock which is +prescaled from the APB2 clock by default by a minimum factor of 2 to a maximum +of 8. + +Each A/D converter has up to 18 channels: +@li On ADC1 the analog channels 16 and 17 are internally connected to the +temperature +sensor and VREFINT, respectively. +@li On ADC2 the analog channels 16 and 17 are internally connected to +VSS. +@li On ADC3 the analog channels 9, 14, 15, 16 and 17 are internally connected +to VSS. + +The conversions can occur as a one-off conversion whereby the process stops +once conversion is complete. The conversions can also be continuous wherein a +new conversion starts immediately the previous conversion has ended. + +Conversion can occur as a single channel conversion or a scan of a group of +channels in either continuous or one-off mode. If more than one channel is +converted in a scan group, DMA must be used to transfer the data as there is +only one result register available. An interrupt can be set to occur at the end +of conversion, which occurs after all channels have been scanned. + +A discontinuous mode allows a subgroup of group of a channels to be converted +in bursts of a given length. + +Injected conversions allow a second group of channels to be converted +separately from the regular group. An interrupt can be set to occur at the end +of conversion, which occurs after all channels have been scanned. + +@section adc_api_ex Basic ADC Handling API. + +Example 1: Simple single channel conversion polled. Enable the peripheral clock +and ADC, reset ADC and set the prescaler divider. Set dual mode to independent +(default). Enable triggering for a software trigger. + +@code + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + adc_power_off(ADC1); + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); + adc_set_dual_mode(ADC_CR1_DUALMOD_IND); + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); + adc_enable_trigger(ADC1, ADC_CR2_EXTSEL_SWSTART); + adc_power_on(ADC1); + adc_reset_calibration(ADC1); + adc_calibration(ADC1); + adc_start_conversion_regular(ADC1); + while (! adc_eoc(ADC1)); + reg16 = adc_read_regular(ADC1); +@endcode + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Edward Cheeseman + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * Basic ADC handling API. + * + * Examples: + * rcc_peripheral_enable_clock(&RCC_APB2ENR, ADC1EN); + * rcc_peripheral_disable_clock(&RCC_APB2ENR, ADC1EN); + * rcc_peripheral_reset(&RCC_APB2RSTR, ADC1RST); + * rcc_peripheral_clear_reset(&RCC_APB2RSTR, ADC1RST); + * + * rcc_set_adc_clk(ADC_PRE_PLCK2_DIV2); + * adc_set_dual_mode(ADC1, TODO); + * reg16 = adc_read(ADC1, ADC_CH_0); + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Power On + +If the ADC is in power-down mode then it is powered up. The application needs +to wait a time of about 3 microseconds for stabilization before using the ADC. +If the ADC is already on this function call has no effect. + * NOTE Common with F37x + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_power_on(uint32_t adc) +{ + if (!(ADC_CR2(adc) & ADC_CR2_ADON)) { + ADC_CR2(adc) |= ADC_CR2_ADON; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Start a Conversion Without Trigger + +This initiates a conversion by software without a trigger. The ADC needs to be +powered on before this is called, otherwise this function has no effect. + +Note that this is not available in other STM32F families. To ensure code +compatibility, enable triggering and use a software trigger source @see +adc_start_conversion_regular. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_start_conversion_direct(uint32_t adc) +{ + if (ADC_CR2(adc) & ADC_CR2_ADON) { + ADC_CR2(adc) |= ADC_CR2_ADON; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Dual A/D Mode + +The dual mode uses ADC1 as master and ADC2 in a slave arrangement. This setting +is applied to ADC1 only. Start of conversion when triggered can cause +simultaneous conversion with ADC2, or alternate conversion. Regular and +injected conversions can be configured, each one being separately simultaneous +or alternate. + +Fast interleaved mode starts ADC1 immediately on trigger, and ADC2 seven clock +cycles later. + +Slow interleaved mode starts ADC1 immediately on trigger, and ADC2 fourteen +clock cycles later, followed by ADC1 fourteen cycles later again. This can only +be used on a single channel. + +Alternate trigger mode must occur on an injected channel group, and alternates +between the ADCs on each trigger. + +Note that sampling must not overlap between ADCs on the same channel. + +Dual A/D converter modes possible: + +@li IND: Independent mode. +@li CRSISM: Combined regular simultaneous + injected simultaneous mode. +@li CRSATM: Combined regular simultaneous + alternate trigger mode. +@li CISFIM: Combined injected simultaneous + fast interleaved mode. +@li CISSIM: Combined injected simultaneous + slow interleaved mode. +@li ISM: Injected simultaneous mode only. +@li RSM: Regular simultaneous mode only. +@li FIM: Fast interleaved mode only. +@li SIM: Slow interleaved mode only. +@li ATM: Alternate trigger mode only. + +@param[in] mode Unsigned int32. Dual mode selection from @ref adc_cr1_dualmod +*/ + +void adc_set_dual_mode(uint32_t mode) +{ + ADC1_CR1 |= mode; +} + + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable The Temperature Sensor + +This enables both the sensor and the reference voltage measurements on channels +16 and 17. + +*/ + +void adc_enable_temperature_sensor() +{ + ADC_CR2(ADC1) |= ADC_CR2_TSVREFE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable The Temperature Sensor + +Disabling this will reduce power consumption from the sensor and the reference +voltage measurements. +*/ + +void adc_disable_temperature_sensor() +{ + ADC_CR2(ADC1) &= ~ADC_CR2_TSVREFE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + +This enables an external trigger for set of defined regular channels. + +For ADC1 and ADC2 +@li Timer 1 CC1 event +@li Timer 1 CC2 event +@li Timer 1 CC3 event +@li Timer 2 CC2 event +@li Timer 3 TRGO event +@li Timer 4 CC4 event +@li EXTI (TIM8_TRGO is also possible on some devices, see datasheet) +@li Software Start + +For ADC3 +@li Timer 3 CC1 event +@li Timer 2 CC3 event +@li Timer 1 CC3 event +@li Timer 8 CC1 event +@li Timer 8 TRGO event +@li Timer 5 CC1 event +@li Timer 5 CC3 event +@li Software Start + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_regular_12 +for ADC1 and ADC2, or @ref adc_trigger_regular_3 for ADC3. +*/ + +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger) +{ + uint32_t reg32; + + reg32 = (ADC_CR2(adc) & ~(ADC_CR2_EXTSEL_MASK)); + reg32 |= (trigger); + ADC_CR2(adc) = reg32; + ADC_CR2(adc) |= ADC_CR2_EXTTRIG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_disable_external_trigger_regular(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EXTTRIG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + +This enables an external trigger for set of defined injected channels. + +For ADC1 and ADC2 +@li Timer 1 TRGO event +@li Timer 1 CC4 event +@li Timer 2 TRGO event +@li Timer 2 CC1 event +@li Timer 3 CC4 event +@li Timer 4 TRGO event +@li EXTI (TIM8 CC4 is also possible on some devices, see datasheet) +@li Software Start + +For ADC3 +@li Timer 1 TRGO event +@li Timer 1 CC4 event +@li Timer 4 CC3 event +@li Timer 8 CC2 event +@li Timer 8 CC4 event +@li Timer 5 TRGO event +@li Timer 5 CC4 event +@li Software Start + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +@param[in] trigger Unsigned int8. Trigger identifier @ref +adc_trigger_injected_12 for ADC1 and ADC2, or @ref adc_trigger_injected_3 for +ADC3. +*/ +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger) +{ + uint32_t reg32; + + reg32 = (ADC_CR2(adc) & ~(ADC_CR2_JEXTSEL_MASK)); /* Clear bits [12:14] + */ + reg32 |= (trigger); + ADC_CR2(adc) = reg32; + ADC_CR2(adc) |= ADC_CR2_JEXTTRIG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_disable_external_trigger_injected(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_JEXTTRIG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Initialize Calibration Registers + +This resets the calibration registers. It is not clear if this is required to be +done before every calibration operation. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_reset_calibration(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_RSTCAL; + while (ADC_CR2(adc) & ADC_CR2_RSTCAL); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Calibration +@deprecated replaced by adc_calibrate/_async/_is_calibrating +The calibration data for the ADC is recomputed. The hardware clears the +calibration status flag when calibration is complete. This function does not +return until this happens and the ADC is ready for use. + +The ADC must have been powered down for at least 2 ADC clock cycles, then +powered on. before calibration starts + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +*/ + +void adc_calibration(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_CAL; + while (ADC_CR2(adc) & ADC_CR2_CAL); +} + +/** + * Start the ADC calibration and immediately return. + * @sa adc_calibrate + * @sa adc_is_calibrate + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_calibrate_async(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_CAL; +} + +/** + * Is the ADC Calibrating? + * @param adc ADC Block register address base @ref adc_reg_base + * @return true if the adc is currently calibrating + */ +bool adc_is_calibrating(uint32_t adc) +{ + return (ADC_CR2(adc) & ADC_CR2_CAL); +} + +/** + * Start ADC calibration and wait for it to finish. + * The ADC must have been powered down for at least 2 ADC clock cycles, then + * powered on before calibration starts + * @param adc ADC Block register address base @ref adc_reg_base + */ +void adc_calibrate(uint32_t adc) +{ + adc_calibrate_async(adc); + while (adc_is_calibrating(adc)); +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for a Single Channel + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +@param[in] channel Unsigned int8. ADC Channel integer 0..18 or from @ref +adc_channel. +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg. + * * NOTE Common with f2 and f37x and f4 +*/ + +void adc_set_sample_time(uint32_t adc, uint8_t channel, uint8_t time) +{ + uint32_t reg32; + + if (channel < 10) { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0x7 << (channel * 3)); + reg32 |= (time << (channel * 3)); + ADC_SMPR2(adc) = reg32; + } else { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0x7 << ((channel - 10) * 3)); + reg32 |= (time << ((channel - 10) * 3)); + ADC_SMPR1(adc) = reg32; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for All Channels + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5, same +for all channels. + +@param[in] adc Unsigned int32. ADC block register address base @ref +adc_reg_base. +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg. + * * NOTE Common with f2 and f37x and f4 +*/ + +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time) +{ + uint8_t i; + uint32_t reg32 = 0; + + for (i = 0; i <= 9; i++) { + reg32 |= (time << (i * 3)); + } + ADC_SMPR2(adc) = reg32; + + for (i = 10; i <= 17; i++) { + reg32 |= (time << ((i - 10) * 3)); + } + ADC_SMPR1(adc) = reg32; +} + + +/*---------------------------------------------------------------------------*/ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/crc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/crc.c new file mode 100644 index 00000000..027052dc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/crc.c @@ -0,0 +1,31 @@ +/** @defgroup crc_file CRC + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx CRC + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dac.c new file mode 100644 index 00000000..fa599bb7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dac.c @@ -0,0 +1,31 @@ +/** @defgroup dac_file DAC + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx DAC + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dma.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dma.c new file mode 100644 index 00000000..70193659 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/dma.c @@ -0,0 +1,31 @@ +/** @defgroup dma_file DMA + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx DMA + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/flash.c new file mode 100644 index 00000000..31df4b75 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/flash.c @@ -0,0 +1,317 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32F1xx + * + * @brief libopencm3 STM32F1xx FLASH Memory + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * + * @date 14 January 2014 + * + * For the STM32F1xx, accessing FLASH memory is described briefly in + * section 3.3.3 of the STM32F10x Reference Manual. + * For detailed programming information see: + * PM0075 programming manual: STM32F10xxx Flash programming + * August 2010, Doc ID 17863 Rev 1 + * https://github.com/libopencm3/libopencm3-archive/blob/master/st_micro/CD00283419.pdf + * + * FLASH memory may be used for data storage as well as code, and may be + * programmatically modified. Note that for firmware upload the STM32F1xx + * provides a built-in bootloader in system memory that can be entered from a + * running program. + * + * FLASH must first be unlocked before programming. In this module a write to + * FLASH is a blocking operation until the end-of-operation flag is asserted. + * + * @note: don't forget to lock it again when all operations are complete. + * + * For the large memory XL series, with two banks of FLASH, the upper bank is + * accessed with a second set of registers. In principle both banks can be + * written simultaneously, or one read while the other is written. This module + * does not support the simultaneous write feature. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the FLASH Half Cycle Mode + +This mode is used for power saving during read access. It is disabled by default +on reset. + +Note carefully the clock restrictions under which the half cycle mode may be +enabled or disabled. This mode may only be used while the clock is running at +8MHz. See the reference manual for details. +*/ + +void flash_halfcycle_enable(void) +{ + FLASH_ACR |= FLASH_ACR_HLFCYA; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the FLASH Half Cycle Mode + +*/ + +void flash_halfcycle_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_HLFCYA; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock the Flash Program and Erase Controller, upper Bank + +This enables write access to the upper bank of the Flash memory in XL devices. +It is locked by default on reset. +*/ + +void flash_unlock_upper(void) +{ + if (DESIG_FLASH_SIZE > 512) { + + /* Clear the unlock state. */ + FLASH_CR2 |= FLASH_CR_LOCK; + + /* Authorize the FPEC access. */ + FLASH_KEYR2 = FLASH_KEYR_KEY1; + FLASH_KEYR2 = FLASH_KEYR_KEY2; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock the Flash Program and Erase Controller, upper Bank + +Used to prevent spurious writes to FLASH. +*/ + +void flash_lock_upper(void) +{ + FLASH_CR2 |= FLASH_CR_LOCK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Error Status Flag, upper Bank + +*/ + +void flash_clear_pgerr_flag_upper(void) +{ + if (DESIG_FLASH_SIZE > 512) { + FLASH_SR2 |= FLASH_SR_PGERR; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the End of Operation Status Flag, upper Bank + +*/ + +void flash_clear_eop_flag_upper(void) +{ + if (DESIG_FLASH_SIZE > 512) { + FLASH_SR2 |= FLASH_SR_EOP; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Write Protect Error Status Flag, upper Bank + +*/ + +void flash_clear_wrprterr_flag_upper(void) +{ + if (DESIG_FLASH_SIZE > 512) { + FLASH_SR2 |= FLASH_SR_WRPRTERR; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Busy Status Flag, upper Bank + +*/ + +void flash_clear_bsy_flag_upper(void) +{ + if (DESIG_FLASH_SIZE > 512) { + FLASH_SR2 &= ~FLASH_SR_BSY; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Program error, end of operation, write protect error, busy. Both banks cleared. +*/ + +void flash_clear_status_flags(void) +{ + flash_clear_pgerr_flag(); + flash_clear_eop_flag(); + flash_clear_wrprterr_flag(); + flash_clear_bsy_flag(); + if (DESIG_FLASH_SIZE > 512) { + flash_clear_pgerr_flag_upper(); + flash_clear_eop_flag_upper(); + flash_clear_wrprterr_flag_upper(); + flash_clear_bsy_flag_upper(); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read All Status Flags + +The programming error, end of operation, write protect error and busy flags +are returned in the order of appearance in the status register. + +Flags for the upper bank, where appropriate, are combined with those for +the lower bank using bitwise OR, without distinction. + +@returns uint32_t. bit 0: busy, bit 2: programming error, bit 4: write protect +error, bit 5: end of operation. +*/ + +uint32_t flash_get_status_flags(void) +{ + uint32_t flags = (FLASH_SR & (FLASH_SR_PGERR | + FLASH_SR_EOP | + FLASH_SR_WRPRTERR | + FLASH_SR_BSY)); + if (DESIG_FLASH_SIZE > 512) { + flags |= (FLASH_SR2 & (FLASH_SR_PGERR | + FLASH_SR_EOP | + FLASH_SR_WRPRTERR | + FLASH_SR_BSY)); + } + + return flags; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a Half Word to FLASH + +This performs all operations necessary to program a 16 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +Status bit polling is used to detect end of operation. + +@param[in] address Full address of flash half word to be programmed. +@param[in] data half word to write +*/ + +void flash_program_half_word(uint32_t address, uint16_t data) +{ + flash_wait_for_last_operation(); + + if ((DESIG_FLASH_SIZE > 512) && (address >= FLASH_BASE+0x00080000)) { + FLASH_CR2 |= FLASH_CR_PG; + } else { + FLASH_CR |= FLASH_CR_PG; + } + + MMIO16(address) = data; + + flash_wait_for_last_operation(); + + if ((DESIG_FLASH_SIZE > 512) && (address >= FLASH_BASE+0x00080000)) { + FLASH_CR2 &= ~FLASH_CR_PG; + } else { + FLASH_CR &= ~FLASH_CR_PG; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase a Page of FLASH + +This performs all operations necessary to erase a page in FLASH memory. +The page should be checked to ensure that it was properly erased. A page must +first be fully erased before attempting to program it. + +Note that the page sizes differ between devices. See the reference manual or +the FLASH programming manual for details. + +@param[in] page_address Full address of flash page to be erased. +*/ + +void flash_erase_page(uint32_t page_address) +{ + flash_wait_for_last_operation(); + + if ((DESIG_FLASH_SIZE > 512) + && (page_address >= FLASH_BASE+0x00080000)) { + FLASH_CR2 |= FLASH_CR_PER; + FLASH_AR2 = page_address; + FLASH_CR2 |= FLASH_CR_STRT; + } else { + FLASH_CR |= FLASH_CR_PER; + FLASH_AR = page_address; + FLASH_CR |= FLASH_CR_STRT; + } + + flash_wait_for_last_operation(); + + if ((DESIG_FLASH_SIZE > 512) + && (page_address >= FLASH_BASE+0x00080000)) { + FLASH_CR2 &= ~FLASH_CR_PER; + } else { + FLASH_CR &= ~FLASH_CR_PER; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase All FLASH + +This performs all operations necessary to erase all user pages in the FLASH +memory. The information block is unaffected. +*/ + +void flash_erase_all_pages(void) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */ + FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */ + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */ + +/* Repeat for bank 2 */ + FLASH_CR2 |= FLASH_CR_MER; + FLASH_CR2 |= FLASH_CR_STRT; + + flash_wait_for_last_operation(); + FLASH_CR2 &= ~FLASH_CR_MER; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/gpio.c new file mode 100644 index 00000000..669fd46e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/gpio.c @@ -0,0 +1,200 @@ +/** @defgroup gpio_file GPIO + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx General Purpose I/O + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 +Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +@date 18 August 2012 + +Each I/O port has 16 individually configurable bits. Many I/O pins share GPIO +functionality with a number of alternate functions and must be configured to +the alternate function mode if these are to be accessed. A feature is available +to remap alternative functions to a limited set of alternative pins in the +event of a clash of requirements. + +The data registers associated with each port for input and output are 32 bit +with the upper 16 bits unused. The output buffer must be written as a 32 bit +word, but individual bits may be set or reset separately in atomic operations +to avoid race conditions during interrupts. Bits may also be individually +locked to prevent accidental configuration changes. Once locked the +configuration cannot be changed until after the next reset. + +Each port bit can be configured as analog or digital input, the latter can be +floating or pulled up or down. As outputs they can be configured as either +push-pull or open drain, digital I/O or alternate function, and with maximum +output speeds of 2MHz, 10MHz, or 50MHz. + +On reset all ports are configured as digital floating input. + +@section gpio_api_ex Basic GPIO Handling API. + +Example 1: Push-pull digital output actions on ports C2 and C9 + +@code + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO2 | GPIO9); + gpio_set(GPIOC, GPIO2 | GPIO9); + gpio_clear(GPIOC, GPIO2); + gpio_toggle(GPIOC, GPIO2 | GPIO9); + gpio_port_write(GPIOC, 0x204); +@endcode + +Example 1: Digital input on port C12 + +@code + gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT, GPIO12); + reg16 = gpio_port_read(GPIOC); +@endcode + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO Pin Mode + +Sets the mode (input/output) and configuration (analog/digitial and +open drain/push pull), for a set of GPIO pins on a given GPIO port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] mode Unsigned int8. Pin mode @ref gpio_mode +@param[in] cnf Unsigned int8. Pin configuration @ref gpio_cnf +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be set, use bitwise OR '|' to separate + them. +*/ + +void gpio_set_mode(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint16_t gpios) +{ + uint16_t i, offset = 0; + uint32_t crl = 0, crh = 0, tmp32 = 0; + + /* + * We want to set the config only for the pins mentioned in gpios, + * but keeping the others, so read out the actual config first. + */ + crl = GPIO_CRL(gpioport); + crh = GPIO_CRH(gpioport); + + /* Iterate over all bits, use i as the bitnumber. */ + for (i = 0; i < 16; i++) { + /* Only set the config if the bit is set in gpios. */ + if (!((1 << i) & gpios)) { + continue; + } + + /* Calculate bit offset. */ + offset = (i < 8) ? (i * 4) : ((i - 8) * 4); + + /* Use tmp32 to either modify crl or crh. */ + tmp32 = (i < 8) ? crl : crh; + + /* Modify bits are needed. */ + tmp32 &= ~(0xf << offset); /* Clear the bits first. */ + tmp32 |= (mode << offset) | (cnf << (offset + 2)); + + /* Write tmp32 into crl or crh, leave the other unchanged. */ + crl = (i < 8) ? tmp32 : crl; + crh = (i >= 8) ? tmp32 : crh; + } + + GPIO_CRL(gpioport) = crl; + GPIO_CRH(gpioport) = crh; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Map the EVENTOUT signal + +Enable the EVENTOUT signal and select the port and pin to be used. + +@param[in] evoutport Unsigned int8. Port for EVENTOUT signal @ref afio_evcr_port +@param[in] evoutpin Unsigned int8. Pin for EVENTOUT signal @ref afio_evcr_pin +*/ +void gpio_set_eventout(uint8_t evoutport, uint8_t evoutpin) +{ + AFIO_EVCR = AFIO_EVCR_EVOE | evoutport | evoutpin; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Map Alternate Function Port Bits (Main Set) + +A number of alternate function ports can be remapped to defined alternative +port bits to avoid clashes in cases where multiple alternate functions are +present. Refer to the datasheets for the particular mapping desired. This +provides the main set of remap functionality. See @ref gpio_secondary_remap for +a number of lesser used remaps. + +The AFIO remapping feature is used only with the STM32F10x series. + +@note The Serial Wire JTAG disable controls allow certain GPIO ports to become +available in place of some of the SWJ signals. Full SWJ capability is obtained +by setting this to zero. The value of this must be specified for every call to +this function as its current value cannot be ascertained from the hardware. + +@param[in] swjdisable Unsigned int8. Disable parts of the SWJ capability @ref +afio_swj_disable. +@param[in] maps Unsigned int32. Bitwise OR of map enable controls you wish to +enable from @ref afio_remap, @ref afio_remap_can1, @ref afio_remap_tim3, +@ref afio_remap_tim2, @ref afio_remap_tim1, @ref afio_remap_usart3. For +connectivity line devices only @ref afio_remap_cld are also available. +*/ +void gpio_primary_remap(uint32_t swjdisable, uint32_t maps) +{ + /* + * the SWJ_CFG bits are write only. (read is explicitly undefined) + * To be sure we set only the bits we want we must clear them first. + * However, we are still trying to only enable the map bits desired. + */ + uint32_t reg = AFIO_MAPR & ~AFIO_MAPR_SWJ_MASK; + AFIO_MAPR = reg | swjdisable | maps; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Map Alternate Function Port Bits (Secondary Set) + +A number of alternate function ports can be remapped to defined alternative +port bits to avoid clashes in cases where multiple alternate functions are +present. Refer to the datasheets for the particular mapping desired. This +provides the second smaller and less used set of remap functionality. See @ref +gpio_primary_remap for the main set of remaps. + +The AFIO remapping feature is used only with the STM32F10x series. + +@param[in] maps Unsigned int32. Bitwise OR of map enable controls from @ref +afio_remap2 +*/ +void gpio_secondary_remap(uint32_t maps) +{ + AFIO_MAPR2 |= maps; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/i2c.c new file mode 100644 index 00000000..d961736d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/i2c.c @@ -0,0 +1,31 @@ +/** @defgroup i2c_file I2C + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx I2C + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/iwdg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/iwdg.c new file mode 100644 index 00000000..2d9bc3c9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/iwdg.c @@ -0,0 +1,31 @@ +/** @defgroup iwdg_file IWDG + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Independent Watchdog Timer + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/libopencm3_stm32f1.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/libopencm3_stm32f1.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/libopencm3_stm32f1.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/pwr.c new file mode 100644 index 00000000..167f920d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/pwr.c @@ -0,0 +1,43 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32F1xx + * + * @brief libopencm3 STM32F1xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2012 + * Ken Sarkies + * + * @date 18 August 2012 + * + * This library supports the power control system for the + * STM32F1 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rcc.c new file mode 100644 index 00000000..af02d752 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rcc.c @@ -0,0 +1,1107 @@ +/** @defgroup STM32F1xx-rcc-file RCC + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Reset and Clock Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 +Federico Ruiz-Ugalde \ +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +This library supports the Reset and Clock Control System in the STM32F1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +@note Full support for connection line devices is not yet provided. + +Clock settings and resets for many peripherals are given here rather than in +the corresponding peripheral library. + +The library also provides a number of common configurations for the processor +system clock. Not all possible configurations are included. + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include +#include + +/** Set the default clock frequencies */ +uint32_t rcc_apb1_frequency = 8000000; +uint32_t rcc_apb2_frequency = 8000000; +uint32_t rcc_ahb_frequency = 8000000; + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Clear the Oscillator Ready Interrupt Flag + +Clear the interrupt flag that was set when a clock oscillator became ready to +use. + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case RCC_PLL2: + RCC_CIR |= RCC_CIR_PLL2RDYC; + break; + case RCC_PLL3: + RCC_CIR |= RCC_CIR_PLL3RDYC; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the Oscillator Ready Interrupt + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case RCC_PLL2: + RCC_CIR |= RCC_CIR_PLL2RDYIE; + break; + case RCC_PLL3: + RCC_CIR |= RCC_CIR_PLL3RDYIE; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the Oscillator Ready Interrupt + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case RCC_PLL2: + RCC_CIR &= ~RCC_CIR_PLL2RDYIE; + break; + case RCC_PLL3: + RCC_CIR &= ~RCC_CIR_PLL3RDYIE; + break; + case RCC_HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Read the Oscillator Ready Interrupt Flag + +@param[in] osc enum ::osc_t. Oscillator ID +@returns int. Boolean value for flag set. +*/ + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case RCC_PLL2: + return ((RCC_CIR & RCC_CIR_PLL2RDYF) != 0); + break; + case RCC_PLL3: + return ((RCC_CIR & RCC_CIR_PLL3RDYF) != 0); + break; + case RCC_HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case RCC_HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case RCC_LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case RCC_LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + } + + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Clear the Clock Security System Interrupt Flag + +*/ + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Read the Clock Security System Interrupt Flag + +@returns int. Boolean value for flag set. +*/ + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_PLL2: + return RCC_CR & RCC_CR_PLL2RDY; + case RCC_PLL3: + return RCC_CR & RCC_CR_PLL3RDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_LSE: + return RCC_BDCR & RCC_BDCR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Turn on an Oscillator. + +Enable an oscillator and power on. Each oscillator requires an amount of time +to settle to a usable state. Refer to datasheets for time delay information. A +status flag is available to indicate when the oscillator becomes ready (see +@ref rcc_osc_ready_int_flag and @ref rcc_wait_for_osc_ready). + +@note The LSE clock is in the backup domain and cannot be enabled until the +backup domain write protection has been removed (see @ref +pwr_disable_backup_domain_write_protect). + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_PLL2: + RCC_CR |= RCC_CR_PLL2ON; + break; + case RCC_PLL3: + RCC_CR |= RCC_CR_PLL3ON; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Turn off an Oscillator. + +Disable an oscillator and power off. + +@note An oscillator cannot be turned off if it is selected as the system clock. +@note The LSE clock is in the backup domain and cannot be disabled until the +backup domain write protection has been removed (see +@ref pwr_disable_backup_domain_write_protect) or the backup domain has been +(see reset @ref rcc_backupdomain_reset). + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_PLL2: + RCC_CR &= ~RCC_CR_PLL2ON; + break; + case RCC_PLL3: + RCC_CR &= ~RCC_CR_PLL3ON; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the Clock Security System. + +*/ + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the Clock Security System. + +*/ + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the System Clock. + +@param[in] clk Unsigned int32. System Clock Selection @ref rcc_cfgr_scs +*/ + +void rcc_set_sysclk_source(uint32_t clk) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | + (clk << RCC_CFGR_SW_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Multiplication Factor. + +@note This only has effect when the PLL is disabled. + +@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf +*/ + +void rcc_set_pll_multiplication_factor(uint32_t mul) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLMUL) | + (mul << RCC_CFGR_PLLMUL_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL2 Multiplication Factor. + +@note This only has effect when the PLL is disabled. + +@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf +*/ + +void rcc_set_pll2_multiplication_factor(uint32_t mul) +{ + RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PLL2MUL) | + (mul << RCC_CFGR2_PLL2MUL_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL3 Multiplication Factor. + +@note This only has effect when the PLL is disabled. + +@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf +*/ + +void rcc_set_pll3_multiplication_factor(uint32_t mul) +{ + RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PLL3MUL) | + (mul << RCC_CFGR2_PLL3MUL_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllsrc Unsigned int32. PLL clock source @ref rcc_cfgr_pcs +*/ + +void rcc_set_pll_source(uint32_t pllsrc) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLSRC) | + (pllsrc << 16); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the HSE Frequency Divider used as PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllxtpre Unsigned int32. HSE division factor @ref rcc_cfgr_hsepre +*/ + +void rcc_set_pllxtpre(uint32_t pllxtpre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PLLXTPRE) | + (pllxtpre << 17); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC RTC Clock Enabled Flag + +@returns uint32_t. Nonzero if the RTC Clock is enabled. +*/ + +uint32_t rcc_rtc_clock_enabled_flag(void) +{ + return RCC_BDCR & RCC_BDCR_RTCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the RTC clock + +*/ + +void rcc_enable_rtc_clock(void) +{ + RCC_BDCR |= RCC_BDCR_RTCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the RTC clock + +@param[in] clock_source ::rcc_osc. RTC clock source. Only HSE/128, LSE and LSI. +*/ + +void rcc_set_rtc_clock_source(enum rcc_osc clock_source) +{ + uint32_t reg32; + + switch (clock_source) { + case RCC_LSE: + /* Turn the LSE on and wait while it stabilises. */ + RCC_BDCR |= RCC_BDCR_LSEON; + while ((reg32 = (RCC_BDCR & RCC_BDCR_LSERDY)) == 0); + + /* Choose LSE as the RTC clock source. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + RCC_BDCR |= (1 << 8); + break; + case RCC_LSI: + /* Turn the LSI on and wait while it stabilises. */ + RCC_CSR |= RCC_CSR_LSION; + while ((reg32 = (RCC_CSR & RCC_CSR_LSIRDY)) == 0); + + /* Choose LSI as the RTC clock source. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + RCC_BDCR |= (1 << 9); + break; + case RCC_HSE: + /* Turn the HSE on and wait while it stabilises. */ + RCC_CR |= RCC_CR_HSEON; + while ((reg32 = (RCC_CR & RCC_CR_HSERDY)) == 0); + + /* Choose HSE as the RTC clock source. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + RCC_BDCR |= (1 << 9) | (1 << 8); + break; + case RCC_PLL: + case RCC_PLL2: + case RCC_PLL3: + case RCC_HSI: + /* Unusable clock source, here to prevent warnings. */ + /* Turn off clock sources to RTC. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Setup the A/D Clock + +The ADC's have a common clock prescale setting. + +@param[in] adcpre uint32_t. Prescale divider taken from @ref rcc_cfgr_adcpre +*/ + +void rcc_set_adcpre(uint32_t adcpre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_ADCPRE) | + (adcpre << RCC_CFGR_ADCPRE_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the APB2 Prescale Factor. + +@param[in] ppre2 Unsigned int32. APB2 prescale factor @ref rcc_cfgr_apb2pre +*/ + +void rcc_set_ppre2(uint32_t ppre2) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PPRE2) | + (ppre2 << RCC_CFGR_PPRE2_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the APB1 Prescale Factor. + +@note The APB1 clock frequency must not exceed 36MHz. + +@param[in] ppre1 Unsigned int32. APB1 prescale factor @ref rcc_cfgr_apb1pre +*/ + +void rcc_set_ppre1(uint32_t ppre1) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PPRE1) | + (ppre1 << RCC_CFGR_PPRE1_SHIFT); + +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the AHB Prescale Factor. + +@param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre +*/ + +void rcc_set_hpre(uint32_t hpre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_HPRE) | + (hpre << RCC_CFGR_HPRE_SHIFT); + +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the USB Prescale Factor. + +The prescale factor can be set to 1 (no prescale) for use when the PLL clock is +48MHz, or 1.5 to generate the 48MHz USB clock from a 64MHz PLL clock. + +@note This bit cannot be reset while the USB clock is enabled. + +@param[in] usbpre Unsigned int32. USB prescale factor @ref rcc_cfgr_usbpre +*/ + +void rcc_set_usbpre(uint32_t usbpre) +{ + if (usbpre) { + RCC_CFGR |= RCC_CFGR_USBPRE; + } else { + RCC_CFGR &= ~RCC_CFGR_USBPRE; + } +} + +void rcc_set_prediv1(uint32_t prediv) +{ + RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PREDIV1) | + (prediv << RCC_CFGR2_PREDIV1_SHIFT); +} + +void rcc_set_prediv2(uint32_t prediv) +{ + RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PREDIV2) | + (prediv << RCC_CFGR2_PREDIV2_SHIFT); +} + +void rcc_set_prediv1_source(uint32_t rccsrc) +{ + if (rccsrc) { + RCC_CFGR2 |= RCC_CFGR2_PREDIV1SRC; + } else { + RCC_CFGR2 &= ~RCC_CFGR2_PREDIV1SRC; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Get the System Clock Source. + +@returns Unsigned int32. System clock source: +@li 00 indicates HSE +@li 01 indicates LSE +@li 02 indicates PLL +*/ + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR & RCC_CFGR_SWS) >> RCC_CFGR_SWS_SHIFT; +} + +/*---------------------------------------------------------------------------*/ +/* + * These functions are setting up the whole clock system for the most common + * input clock and output clock configurations. + */ +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 64MHz from HSI + +*/ + +void rcc_clock_setup_in_hsi_out_64mhz(void) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 64MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 8MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 32MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 64MHz Max. 72MHz */ + + /* + * Sysclk is running with 64MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 16. + * 8MHz (internal) * 16 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 64MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL16); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 64000000; + rcc_apb1_frequency = 32000000; + rcc_apb2_frequency = 64000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 48MHz from HSI + +*/ + +void rcc_clock_setup_in_hsi_out_48mhz(void) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /*Set.48MHz Max.72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /*Set. 6MHz Max.14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /*Set.24MHz Max.36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /*Set.48MHz Max.72MHz */ + rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_CLK_NODIV); /*Set.48MHz Max.48MHz */ + + /* + * Sysclk runs with 48MHz -> 1 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_1WS); + + /* + * Set the PLL multiplication factor to 12. + * 8MHz (internal) * 12 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 48MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL12); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 48000000; + rcc_apb1_frequency = 24000000; + rcc_apb2_frequency = 48000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSI + +*/ + +void rcc_clock_setup_in_hsi_out_24mhz(void) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 12MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + + /* + * Sysclk is (will be) running with 24MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_0WS); + + /* + * Set the PLL multiplication factor to 6. + * 8MHz (internal) * 6 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 24MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL6); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 24000000; + rcc_apb1_frequency = 24000000; + rcc_apb2_frequency = 24000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSE at 8MHz + +*/ + +void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 72MHz */ + + /* + * Sysclk runs with 24MHz -> 0 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_0WS); + + /* + * Set the PLL multiplication factor to 3. + * 8MHz (external) * 3 (multiplier) = 24MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL3); + + /* Select HSE as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * External frequency undivided before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 24000000; + rcc_apb1_frequency = 24000000; + rcc_apb2_frequency = 24000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 72MHz from HSE at 8MHz + +*/ + +void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 9MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + + /* + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 9. + * 8MHz (external) * 9 (multiplier) = 72MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); + + /* Select HSE as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * External frequency undivided before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 72000000; + rcc_apb1_frequency = 36000000; + rcc_apb2_frequency = 72000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 72MHz from HSE at 12MHz + +*/ + +void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 16MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + + /* + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 9. + * 12MHz (external) * 6 (multiplier) / 1 (PLLXTPRE_HSE_CLK) = 72MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL6); + + /* Select HSI as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * Divide external frequency by 2 before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 72000000; + rcc_apb1_frequency = 36000000; + rcc_apb2_frequency = 72000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 72MHz from HSE at 16MHz + +*/ + +void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 16MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + + /* + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 9. + * 16MHz (external) * 9 (multiplier) / 2 (PLLXTPRE_HSE_CLK_DIV2) = 72MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); + + /* Select HSI as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * Divide external frequency by 2 before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 72000000; + rcc_apb1_frequency = 36000000; + rcc_apb2_frequency = 72000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 72MHz from HSE at 25MHz + +*/ + +void rcc_clock_setup_in_hse_25mhz_out_72mhz(void) +{ + /* Enable external high-speed oscillator 25MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_ACR_LATENCY_2WS); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + + /* Set pll2 prediv and multiplier */ + rcc_set_prediv2(RCC_CFGR2_PREDIV2_DIV5); + rcc_set_pll2_multiplication_factor(RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL8); + + /* Enable PLL2 oscillator and wait for it to stabilize */ + rcc_osc_on(RCC_PLL2); + rcc_wait_for_osc_ready(RCC_PLL2); + + /* Set pll1 prediv/multiplier, prediv1 src, and usb predivider */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + rcc_set_prediv1_source(RCC_CFGR2_PREDIV1SRC_PLL2_CLK); + rcc_set_prediv1(RCC_CFGR2_PREDIV_DIV5); + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); + rcc_set_pll_source(RCC_CFGR_PLLSRC_PREDIV1_CLK); + rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3); + + /* enable PLL1 and wait for it to stabilize */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ahb_frequency = 72000000; + rcc_apb1_frequency = 36000000; + rcc_apb2_frequency = 72000000; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Reset the Backup Domain + +The backup domain registers are reset to disable RTC controls and clear user +data. +*/ + +void rcc_backupdomain_reset(void) +{ + /* Set the backup domain software reset. */ + RCC_BDCR |= RCC_BDCR_BDRST; + + /* Clear the backup domain software reset. */ + RCC_BDCR &= ~RCC_BDCR_BDRST; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rtc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rtc.c new file mode 100644 index 00000000..2743eed9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/rtc.c @@ -0,0 +1,418 @@ +/** @defgroup rtc_file RTC + * + * @ingroup STM32F1xx + * + * @brief libopencm3 STM32F1xx RTC + * + * @author @htmlonly © @endhtmlonly 2010 Uwe Hermann + * @author @htmlonly © @endhtmlonly 2010 Lord James + * + * @version 1.0.0 + * + * @date 4 March 2013 + * + * The Real Time Clock peripheral consists of a set of 16 bit control, status, + * prescaler, counter and alarm registers. Before the latter three can be + * written the RTC must be placed in configuration mode by a call to + * @ref rtc_enter_config_mode(). The functions below handle this implictly. + * + * The RTC is completely reset by performing a Backup Domain reset. Note + * that this can affect unrelated user data contained in the Backup Domain + * registers. Other forms of reset will not affect the RTC registers as they + * are contained within the backup domain. + * + * The RTC clock source to be used is selected by calling + * @ref rcc_set_rtc_clock_source(). + * + * The LSE clock source normally comes from a 32.768kHz external crystal + * This clock is in the backup domain and so continues to run when only the + * V_BAT supply is present. A prescaler value of 7FFF will give a 1 second + * count quantum. + * + * The LSI clock source is a low accuracy internal clock of about 40kHz + * frequency, and the HSE clock source is the external high speed clock + * divided by 128. + * + * Initial configuration of the RTC consists of: + * + * @li perform a Backup Domain reset if appropriate; + * @li select the clock to be used; + * @li set the prescaler, counter and configuration values; + * @li enable the RTC. + * + * @note reading the RTC registers may result in a corrupted value being + * returned in certain cases. Refer to the STM32F1xx Reference Manual. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2010 Lord James + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + + +#include +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Set Operational from the Off state. + +Power up the backup domain clocks, enable write access to the backup domain, +select the clock source, clear the RTC registers and enable the RTC. + +@param[in] clock_source ::rcc_osc. RTC clock source. Only the values HSE, LSE + and LSI are permitted. +*/ + +void rtc_awake_from_off(enum rcc_osc clock_source) +{ + uint32_t reg32; + + /* Enable power and backup interface clocks. */ + rcc_periph_clock_enable(RCC_PWR); + rcc_periph_clock_enable(RCC_BKP); + + /* Enable access to the backup registers and the RTC. */ + pwr_disable_backup_domain_write_protect(); + + /* Set the clock source */ + rcc_set_rtc_clock_source(clock_source); + + /* Clear the RTC Control Register */ + RTC_CRH = 0; + RTC_CRL = 0; + + /* Enable the RTC. */ + rcc_enable_rtc_clock(); + + /* Clear the Registers */ + rtc_enter_config_mode(); + RTC_PRLH = 0; + RTC_PRLL = 0; + RTC_CNTH = 0; + RTC_CNTL = 0; + RTC_ALRH = 0xFFFF; + RTC_ALRL = 0xFFFF; + rtc_exit_config_mode(); + + /* Wait for the RSF bit in RTC_CRL to be set by hardware. */ + RTC_CRL &= ~RTC_CRL_RSF; + while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Enter Configuration Mode. + +Prime the RTC for configuration changes by giving access to the prescaler, +and counter and alarm registers. +*/ + +void rtc_enter_config_mode(void) +{ + uint32_t reg32; + + /* Wait until the RTOFF bit is 1 (no RTC register writes ongoing). */ + while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); + + /* Enter configuration mode. */ + RTC_CRL |= RTC_CRL_CNF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Leave Configuration Mode. + +Revert the RTC to operational state. +*/ + +void rtc_exit_config_mode(void) +{ + uint32_t reg32; + + /* Exit configuration mode. */ + RTC_CRL &= ~RTC_CRL_CNF; + + /* Wait until the RTOFF bit is 1 (our RTC register write finished). */ + while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Set the Alarm Time. + +@param[in] alarm_time uint32_t. time at which the alarm event is triggered. +*/ + +void rtc_set_alarm_time(uint32_t alarm_time) +{ + rtc_enter_config_mode(); + RTC_ALRL = (alarm_time & 0x0000ffff); + RTC_ALRH = (alarm_time & 0xffff0000) >> 16; + rtc_exit_config_mode(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Enable the Alarm. + +*/ + +void rtc_enable_alarm(void) +{ + rtc_enter_config_mode(); + RTC_CRH |= RTC_CRH_ALRIE; + rtc_exit_config_mode(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Disable the Alarm. + +*/ + +void rtc_disable_alarm(void) +{ + rtc_enter_config_mode(); + RTC_CRH &= ~RTC_CRH_ALRIE; + rtc_exit_config_mode(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Set the prescaler Value + +@param[in] prescale_val uint32_t. 20 bit prescale divider. +*/ + +void rtc_set_prescale_val(uint32_t prescale_val) +{ + rtc_enter_config_mode(); + RTC_PRLL = prescale_val & 0x0000ffff; /* PRL[15:0] */ + RTC_PRLH = (prescale_val & 0x000f0000) >> 16; /* PRL[19:16] */ + rtc_exit_config_mode(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC return the Counter Value + +@returns uint32_t: the 32 bit counter value. +*/ + +uint32_t rtc_get_counter_val(void) +{ + return (RTC_CNTH << 16) | RTC_CNTL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC return the prescaler Value + +@returns uint32_t: the 20 bit prescale divider. +*/ + +uint32_t rtc_get_prescale_div_val(void) +{ + return (RTC_DIVH << 16) | RTC_DIVL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC return the Alarm Value + +@returns uint32_t: the 32 bit alarm value. +*/ + +uint32_t rtc_get_alarm_val(void) +{ + return (RTC_ALRH << 16) | RTC_ALRL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC set the Counter + +@param[in] uint32_t counter_val: 32 bit time setting for the counter. +*/ + +void rtc_set_counter_val(uint32_t counter_val) +{ + rtc_enter_config_mode(); + RTC_CNTH = (counter_val & 0xffff0000) >> 16; /* CNT[31:16] */ + RTC_CNTL = counter_val & 0x0000ffff; /* CNT[15:0] */ + rtc_exit_config_mode(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Enable Interrupt + +@param[in] flag_val ::rtcflag_t: The flag to enable. +*/ + +void rtc_interrupt_enable(rtcflag_t flag_val) +{ + rtc_enter_config_mode(); + + /* Set the correct interrupt enable. */ + switch (flag_val) { + case RTC_SEC: + RTC_CRH |= RTC_CRH_SECIE; + break; + case RTC_ALR: + RTC_CRH |= RTC_CRH_ALRIE; + break; + case RTC_OW: + RTC_CRH |= RTC_CRH_OWIE; + break; + } + + rtc_exit_config_mode(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Disable Interrupt + +@param[in] flag_val ::rtcflag_t: The flag to disable. +*/ + +void rtc_interrupt_disable(rtcflag_t flag_val) +{ + rtc_enter_config_mode(); + + /* Disable the correct interrupt enable. */ + switch (flag_val) { + case RTC_SEC: + RTC_CRH &= ~RTC_CRH_SECIE; + break; + case RTC_ALR: + RTC_CRH &= ~RTC_CRH_ALRIE; + break; + case RTC_OW: + RTC_CRH &= ~RTC_CRH_OWIE; + break; + } + + rtc_exit_config_mode(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Clear an Interrupt Flag + +@param[in] flag_val ::rtcflag_t: The flag to clear. +*/ + +void rtc_clear_flag(rtcflag_t flag_val) +{ + /* Configuration mode not needed. */ + + /* Clear the correct flag. */ + switch (flag_val) { + case RTC_SEC: + RTC_CRL &= ~RTC_CRL_SECF; + break; + case RTC_ALR: + RTC_CRL &= ~RTC_CRL_ALRF; + break; + case RTC_OW: + RTC_CRL &= ~RTC_CRL_OWF; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Return a Flag Setting + +@param[in] flag_val ::rtcflag_t: The flag to check. +@returns uint32_t: a nonzero value if the flag is set, zero otherwise. +*/ + +uint32_t rtc_check_flag(rtcflag_t flag_val) +{ + uint32_t reg32; + + /* Read correct flag. */ + switch (flag_val) { + case RTC_SEC: + reg32 = RTC_CRL & RTC_CRL_SECF; + break; + case RTC_ALR: + reg32 = RTC_CRL & RTC_CRL_ALRF; + break; + case RTC_OW: + reg32 = RTC_CRL & RTC_CRL_OWF; + break; + default: + reg32 = 0; + break; + } + + return reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Start RTC after Standby Mode. + +Enable the backup domain clocks, enable write access to the backup +domain and the RTC, and synchronise the RTC register access. +*/ + +void rtc_awake_from_standby(void) +{ + uint32_t reg32; + + /* Enable power and backup interface clocks. */ + rcc_periph_clock_enable(RCC_PWR); + rcc_periph_clock_enable(RCC_BKP); + + /* Enable access to the backup registers and the RTC. */ + pwr_disable_backup_domain_write_protect(); + + /* Wait for the RSF bit in RTC_CRL to be set by hardware. */ + RTC_CRL &= ~RTC_CRL_RSF; + while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0); + + /* Wait for the last write operation to finish. */ + /* TODO: Necessary? */ + while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RTC Configuration on Wakeup + +Enable the backup domain clocks and write access to the backup domain. +If the RTC has not been enabled, set the clock source and prescaler value. +The parameters are not used if the RTC has already been enabled. + +@param[in] clock_source ::rcc_osc. RTC clock source. Only HSE, LSE + and LSI are permitted. +@param[in] prescale_val uint32_t. 20 bit prescale divider. +*/ + +void rtc_auto_awake(enum rcc_osc clock_source, uint32_t prescale_val) +{ + uint32_t reg32; + + /* Enable power and backup interface clocks. */ + rcc_periph_clock_enable(RCC_PWR); + rcc_periph_clock_enable(RCC_BKP); + + reg32 = rcc_rtc_clock_enabled_flag(); + + if (reg32 != 0) { + rtc_awake_from_standby(); + } else { + rtc_awake_from_off(clock_source); + rtc_set_prescale_val(prescale_val); + } +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/spi.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/spi.c new file mode 100644 index 00000000..757f2aea --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/spi.c @@ -0,0 +1,31 @@ +/** @defgroup spi_file SPI + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx SPI + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x4.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x4.ld new file mode 100644 index 00000000..4c86aee8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x4.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x6.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x6.ld new file mode 100644 index 00000000..23f77f3f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x6, 32K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x8.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x8.ld new file mode 100644 index 00000000..e0aa041f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100x8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x8, 64K flash, 8K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xb.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xb.ld new file mode 100644 index 00000000..83d64fdd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xb.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100xB, 128K flash, 8K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xc.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xc.ld new file mode 100644 index 00000000..30a894af --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xc.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100xC, 256K flash, 24K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 24K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xd.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xd.ld new file mode 100644 index 00000000..b5074358 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xd.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100xD, 384K flash, 32K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xe.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xe.ld new file mode 100644 index 00000000..a12d1ff7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f100xe.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100xE, 512K flash, 32K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103x8.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103x8.ld new file mode 100644 index 00000000..c1700de4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103x8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F103x8, 64k flash, 20k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xb.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xb.ld new file mode 100644 index 00000000..67384790 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xb.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F103xB, 128k flash, 20k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xc.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xc.ld new file mode 100644 index 00000000..01801a77 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xc.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F103xC, 256K flash, 48k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xd.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xd.ld new file mode 100644 index 00000000..6b38e3ab --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xd.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F103xD, 384K flash, 64k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xe.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xe.ld new file mode 100644 index 00000000..13094006 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/stm32f103xe.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F103xE, 512K flash, 64k RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/timer.c new file mode 100644 index 00000000..fd46742c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/timer.c @@ -0,0 +1,57 @@ +/* This file is used for documentation purposes. It does not need +to be compiled. All source code is in the common area. +If there is any device specific code required it can be included here, +in which case this file must be added to the compile list. */ + +/** @defgroup timer_file Timers + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Timers + +@version 1.0.0 + +@date 18 August 2012 + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Polarity + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] pol ::tim_ic_pol. Input Capture polarity. +*/ + +void timer_ic_set_polarity(uint32_t timer_peripheral, enum tim_ic_id ic, + enum tim_ic_pol pol) +{ + if (pol) { + TIM_CCER(timer_peripheral) |= (0x2 << (ic * 4)); + } else { + TIM_CCER(timer_peripheral) &= ~(0x2 << (ic * 4)); + } +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/usart.c new file mode 100644 index 00000000..84ae5052 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f1/usart.c @@ -0,0 +1,31 @@ +/** @defgroup usart_file USART + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx USART + +@version 1.0.0 + +@date 30 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/Makefile new file mode 100644 index 00000000..f5cc66c5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/Makefile @@ -0,0 +1,55 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32f2 +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F2 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs + +OBJS = gpio.o rcc.o desig.o + +OBJS += crc_common_all.o dac_common_all.o dma_common_f24.o \ + gpio_common_all.o gpio_common_f0234.o i2c_common_v1.o \ + iwdg_common_all.o rtc_common_l1f024.o spi_common_all.o \ + spi_common_l1f124.o timer_common_all.o timer_common_f0234.o \ + timer_common_f24.o usart_common_all.o usart_common_f124.o \ + flash_common_f234.o flash_common_f24.o hash_common_f24.o \ + crypto_common_f24.o exti_common_all.o rcc_common_all.o +OBJS += rng_common_v1.o + +OBJS += usb.o usb_standard.o usb_control.o usb_fx07_common.o \ + usb_f107.o usb_f207.o usb_msc.o + +VPATH += ../../usb:../:../../cm3:../common + +include ../../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crc.c new file mode 100644 index 00000000..c5ae5d38 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crc.c @@ -0,0 +1,33 @@ +/** @defgroup crc_file CRC + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx CRC + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crypto.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crypto.c new file mode 100644 index 00000000..e44fb632 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/crypto.c @@ -0,0 +1,31 @@ +/** @defgroup crypto_file CRYPTO + * + * @ingroup STM32F2xx + * + * @brief libopencm3 STM32F2xx Cryptographic controller + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dac.c new file mode 100644 index 00000000..635e142b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dac.c @@ -0,0 +1,31 @@ +/** @defgroup dac_file DAC + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx DAC + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dma.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dma.c new file mode 100644 index 00000000..285f1fe7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/dma.c @@ -0,0 +1,31 @@ +/** @defgroup dma_file DMA + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx DMA + +@version 1.0.0 + +@date 30 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/flash.c new file mode 100644 index 00000000..7f8255df --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/flash.c @@ -0,0 +1,53 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32F2xx + * + * @brief libopencm3 STM32F2xx FLASH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * + * @date 14 January 2014 + * + * This library supports the FLASH memory controller in the STM32F2 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * For the STM32F2xx, accessing FLASH memory is described briefly in + * section 2.3.3 of the STM32F2xx Reference Manual. + * For detailed programming information see: + * PM0059 programming manual: STM32F10xxx Flash programming + * June 2013, Doc ID DocID15687 Rev 5 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/gpio.c new file mode 100644 index 00000000..052e306f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/gpio.c @@ -0,0 +1,31 @@ +/** @defgroup gpio_file GPIO + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx General Purpose I/O + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/hash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/hash.c new file mode 100644 index 00000000..ca48d8bb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/hash.c @@ -0,0 +1,31 @@ +/** @defgroup hash_file HASH + * + * @ingroup STM32F2xx + * + * @brief libopencm3 STM32F2xx Hash Processor + * + * @version 1.0.0 + * + * @date 14 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/i2c.c new file mode 100644 index 00000000..e5f6a415 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/i2c.c @@ -0,0 +1,32 @@ +/** @defgroup i2c_file I2C + * + * @ingroup STM32F2xx + * + * @brief libopencm3 STM32F2xx I2C + * + * @version 1.0.0 + * + * @date 15 October 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/iwdg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/iwdg.c new file mode 100644 index 00000000..2d9dc4ac --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/iwdg.c @@ -0,0 +1,31 @@ +/** @defgroup iwdg_file IWDG + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx Independent Watchdog Timer + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/libopencm3_stm32f2.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/libopencm3_stm32f2.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/libopencm3_stm32f2.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/pwr.c new file mode 100644 index 00000000..0e5641eb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/pwr.c @@ -0,0 +1,39 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32F2xx + * + * @brief libopencm3 STM32F2xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Ken Sarkies + * + * @date 13 January 2014 + * + * This library supports the power control system for the + * STM32F4 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rcc.c new file mode 100644 index 00000000..b662cebb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rcc.c @@ -0,0 +1,388 @@ +/** @defgroup rcc_file RCC + * + * @ingroup STM32F2xx + * + * @section rcc_f2_api_ex Reset and Clock Control API. + * + * @brief libopencm3 STM32F2xx Reset and Clock Control + * + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 18 Jun 2013 + * + * This library supports the Reset and Clock Control System in the STM32 series + * of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +/**@{*/ + +/* Set the default clock frequencies after reset. */ +uint32_t rcc_ahb_frequency = 16000000; +uint32_t rcc_apb1_frequency = 16000000; +uint32_t rcc_apb2_frequency = 16000000; + +const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 120MHz */ + .pllm = 8, + .plln = 240, + .pllp = 2, + .pllq = 5, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, +}; + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case RCC_HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case RCC_HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case RCC_LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case RCC_LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + } + + cm3_assert_not_reached(); +} + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_LSE: + return RCC_BDCR & RCC_BDCR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_PLL); + break; + case RCC_HSE: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_HSE); + break; + case RCC_HSI: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_HSI); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +void rcc_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | clk); +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_PLLCFGR; + reg32 &= ~(1 << 22); + RCC_PLLCFGR = (reg32 | (pllsrc << 22)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 13) | (1 << 14) | (1 << 15)); + RCC_CFGR = (reg32 | (ppre2 << 13)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 10) | (1 << 11) | (1 << 12)); + RCC_CFGR = (reg32 | (ppre1 << 10)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); + RCC_CFGR = (reg32 | (hpre << 4)); +} + +void rcc_set_rtcpre(uint32_t rtcpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); + RCC_CFGR = (reg32 | (rtcpre << 16)); +} + +void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq) +{ + RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | + (plln << RCC_PLLCFGR_PLLN_SHIFT) | + (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | + (pllq << RCC_PLLCFGR_PLLQ_SHIFT); +} + +void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq) +{ + RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | + (plln << RCC_PLLCFGR_PLLN_SHIFT) | + (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | + RCC_PLLCFGR_PLLSRC | + (pllq << RCC_PLLCFGR_PLLQ_SHIFT); +} + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR & 0x000c) >> 2; +} + +void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_HSI); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + rcc_set_main_pll_hse(clock->pllm, clock->plln, + clock->pllp, clock->pllq); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Configure flash settings. */ + flash_set_ws(clock->flash_config); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_PLL); + + /* Wait for PLL clock to be selected. */ + rcc_wait_for_sysclk_status(RCC_PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; +} + +void rcc_backupdomain_reset(void) +{ + /* Set the backup domain software reset. */ + RCC_BDCR |= RCC_BDCR_BDRST; + + /* Clear the backup domain software reset. */ + RCC_BDCR &= ~RCC_BDCR_BDRST; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rng.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rng.c new file mode 100644 index 00000000..1b666d88 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rng.c @@ -0,0 +1,31 @@ +/* This file is used for documentation purposes. It does not need +to be compiled. All source code is in the common area. +If there is any device specific code required it can be included here, +in which case this file must be added to the compile list. */ + +/** @defgroup rng_file RNG + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx RNG + +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rtc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rtc.c new file mode 100644 index 00000000..06666ab1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/rtc.c @@ -0,0 +1,31 @@ +/** @defgroup rtc_file RTC + * + * @ingroup STM32F2xx + * + * @brief libopencm3 STM32F2xx RTC + * + * @version 1.0.0 + * + * @date 4 March 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/spi.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/spi.c new file mode 100644 index 00000000..8fb70cd9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/spi.c @@ -0,0 +1,31 @@ +/** @defgroup spi_file SPI + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx SPI + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/timer.c new file mode 100644 index 00000000..6600705a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/timer.c @@ -0,0 +1,38 @@ +/* This file is used for documentation purposes. It does not need +to be compiled. All source code is in the common area. +If there is any device specific code required it can be included here, +in which case this file must be added to the compile list. */ + +/** @defgroup timer_file Timers + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx Timers + +@version 1.0.0 + +@date 18 August 2012 + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/usart.c new file mode 100644 index 00000000..f6de5a84 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f2/usart.c @@ -0,0 +1,31 @@ +/** @defgroup usart_file USART + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx USART + +@version 1.0.0 + +@date 30 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/Makefile new file mode 100644 index 00000000..6e3595f3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/Makefile @@ -0,0 +1,56 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32f3 +SRCLIBDIR ?= ../.. + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m4 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F3 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) + +ARFLAGS = rcs + +OBJS = rcc.o adc.o can.o usart.o dma.o flash.o desig.o + +OBJS += gpio_common_all.o gpio_common_f0234.o \ + dac_common_all.o crc_common_all.o \ + iwdg_common_all.o spi_common_all.o dma_common_l1f013.o\ + timer_common_all.o timer_common_f0234.o flash_common_f234.o \ + flash.o exti_common_all.o rcc_common_all.o spi_common_f03.o +OBJS += adc_common_v2.o adc_common_v2_multi.o +OBJS += usart_common_v2.o usart_common_all.o +OBJS += i2c_common_v2.o + +OBJS += usb.o usb_control.o usb_standard.o +OBJS += st_usbfs_core.o st_usbfs_v1.o + +VPATH += ../../usb:../:../../cm3:../common + +include ../../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/adc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/adc.c new file mode 100644 index 00000000..5715935c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/adc.c @@ -0,0 +1,740 @@ +/** @defgroup adc_file ADC + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx Analog to Digital Converters + * + * @author @htmlonly © @endhtmlonly 2012 + * Ken Sarkies + * + * @date 30 August 2012 + * + * This library supports the A/D Converter Control System in the STM32 series + * of ARM Cortex Microcontrollers by ST Microelectronics. + * + * Devices can have up to three A/D converters each with their own set of + * registers. However all the A/D converters share a common clock which is + * prescaled from the APB2 clock by default by a minimum factor of 2 to a + * maximum of 8. The ADC resolution can be set to 12, 10, 8 or 6 bits. + * + * Each A/D converter has up to 19 channels: + * @li On ADC1 the analog channels 16 is internally connected to the + * temperature sensor, channel 17 to VREFINT, and channel 18 + * to VBATT. + * @li On ADC2 and ADC3 the analog channels 16 - 18 are not used. + * + * The conversions can occur as a one-off conversion whereby the process stops + * once conversion is complete. The conversions can also be continuous wherein + * a new conversion starts immediately the previous conversion has ended. + * + * Conversion can occur as a single channel conversion or a scan of a group of + * channels in either continuous or one-off mode. If more than one channel is + * converted in a scan group, DMA must be used to transfer the data as there is + * only one result register available. An interrupt can be set to occur at the + * end* + * of conversion, which occurs after all channels have been scanned. + * + * A discontinuous mode allows a subgroup of group of a channels to be + * converted in bursts of a given length. + * + * Injected conversions allow a second group of channels to be converted + * separately from the regular group. An interrupt can be set to occur at the + * end of conversion, which occurs after all channels have been scanned. + * + * @section adc_f3_api_ex Basic ADC Handling API. + * + * Example 1: Simple single channel conversion polled. Enable the peripheral + * clock and ADC, reset ADC and set the prescaler divider. Set multiple mode to + * independent. + * + * @code + * gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1); + * rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + * adc_set_clk_prescale(RCC_CFGR_ADCPRE_BY2); + * adc_disable_scan_mode(ADC1); + * adc_set_single_conversion_mode(ADC1); + * adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); + * uint8_t channels[] = ADC_CHANNEL0; + * adc_set_regular_sequence(ADC1, 1, channels); + * adc_set_multi_mode(ADC_CCR_MULTI_INDEPENDENT); + * adc_power_on(ADC1); + * adc_start_conversion_regular(ADC1); + * while (! adc_eoc(ADC1)); + * reg16 = adc_read_regular(ADC1); + * @endcode + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Regular Conversions + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_analog_watchdog_regular(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Regular Conversions + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ +void adc_disable_analog_watchdog_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Injected Conversions + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_analog_watchdog_injected(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_JAWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Injected Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_analog_watchdog_injected(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_JAWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Regular Conversions + * + * In this mode the ADC converts, on each trigger, a subgroup of up to 8 of the + * defined regular channel group. The subgroup is defined by the number of + * consecutive channels to be converted. After a subgroup has been converted + * the next trigger will start conversion of the immediately following subgroup + * of the same length or until the whole group has all been converted. When the + * whole group has been converted, the next trigger will restart conversion of + * the subgroup at the beginning of the whole group. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base @param[in] length Unsigned int8. Number of channels in the + * group @ref adc_cr1_discnum + */ + +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length) +{ + if ((length-1) > 7) { + return; + } + ADC_CFGR1(adc) |= ADC_CFGR1_DISCEN; + ADC_CFGR1(adc) |= ((length-1) << ADC_CFGR1_DISCNUM_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Regular Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_discontinuous_mode_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_DISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Injected Conversions + * + * In this mode the ADC converts sequentially one channel of the defined group + * of injected channels, cycling back to the first channel in the group once + * the entire group has been converted. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_discontinuous_mode_injected(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_JDISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Injected Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_discontinuous_mode_injected(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_JDISCEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Automatic Injected Conversions + * + * The ADC converts a defined injected group of channels immediately after the + * regular channels have been converted. The external trigger on the injected + * channels is disabled as required. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_automatic_injected_group_conversion(uint32_t adc) +{ + adc_disable_external_trigger_injected(adc); + ADC_CFGR1(adc) |= ADC_CFGR1_JAUTO; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Automatic Injected Conversions + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_automatic_injected_group_conversion(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_JAUTO; +} +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for All Regular and/or Injected Channels + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @note The analog watchdog must be enabled for either or both of the regular + * or injected channels. If neither are enabled, the analog watchdog feature + * will be disabled. + * + * @ref adc_enable_analog_watchdog_injected, @ref + * adc_enable_analog_watchdog_regular. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1SGL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for a Selected Channel + * + * The analog watchdog allows the monitoring of an analog signal between two + * threshold levels. The thresholds must be preset. Comparison is done before + * data alignment takes place, so the thresholds are left-aligned. + * + * @note The analog watchdog must be enabled for either or both of the regular + * or injected channels. If neither are enabled, the analog watchdog feature + * will be disabled. If both are enabled, the same channel number is monitored + * @ref adc_enable_analog_watchdog_injected, @ref + * adc_enable_analog_watchdog_regular. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + * @param[in] channel Unsigned int8. ADC channel numbe + * @ref adc_watchdog_channel + */ + +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel) +{ + uint32_t reg32; + + reg32 = (ADC_CFGR1(adc) & ~ADC_CFGR1_AWD1CH); /* Clear bit [4:0]. */ + if (channel < 18) { + reg32 |= channel; + } + ADC_CFGR1(adc) = reg32; + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1SGL; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Conversion Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eoc_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_JEOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Conversion Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eoc_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_JEOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eos_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_JEOSIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eos_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_JEOSIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_all_awd_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_AWD1IE; + ADC_IER(adc) |= ADC_IER_AWD2IE; + ADC_IER(adc) |= ADC_IER_AWD3IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_all_awd_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_AWD1IE; + ADC_IER(adc) &= ~ADC_IER_AWD2IE; + ADC_IER(adc) &= ~ADC_IER_AWD3IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Regular End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eos_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_EOSIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eos_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_EOSIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Injected Channels + * + * This starts conversion on a set of defined injected channels. It is cleared + * by hardware once conversion starts. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_start_conversion_injected(uint32_t adc) +{ + /* Start conversion on injected channels. */ + ADC_CR(adc) |= ADC_CR_JADSTART; + + /* Wait until the ADC starts the conversion. */ + while (ADC_CR(adc) & ADC_CR_JADSTART); +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Upper Threshold + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] threshold Unsigned int8. Upper threshold value + */ + +void adc_set_watchdog_high_threshold(uint32_t adc, uint8_t threshold) +{ + uint32_t reg32 = 0; + + reg32 |= (threshold << 16); + reg32 &= ~0xff00ffff; /* Clear all bits above 8. */ + ADC_TR1(adc) = reg32; + ADC_TR2(adc) = reg32; + ADC_TR3(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Lower Threshold + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] threshold Unsigned int8. Lower threshold value + */ + +void adc_set_watchdog_low_threshold(uint32_t adc, uint8_t threshold) +{ + uint32_t reg32 = 0; + + reg32 = (uint32_t)threshold; + reg32 &= ~0xffffff00; /* Clear all bits above 8. */ + ADC_TR1(adc) = reg32; + ADC_TR2(adc) = reg32; + ADC_TR3(adc) = reg32; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set an Injected Channel Conversion Sequence + * + * Defines a sequence of channels to be converted as an injected group with a + * length from 1 to 4 channels. If this is called during conversion, the current + * conversion is reset and conversion begins again with the newly defined group. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] length Unsigned int8. Number of channels in the group. + * @param[in] channel Unsigned int8[]. Set of channels in sequence, integers + * 0..18 + */ + +void adc_set_injected_sequence(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + uint32_t reg32 = 0; + uint8_t i = 0; + + /* Maximum sequence length is 4 channels. Minimum sequence is 1.*/ + if ((length - 1) > 3) { + return; + } + + for (i = 0; i < length; i++) { + reg32 |= ADC_JSQR_JSQ_VAL(4 - i, channel[length - i - 1]); + } + + reg32 |= ADC_JSQR_JL_VAL(length); + + ADC_JSQR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion + * + * This flag is set by hardware at the end of each injected conversion of a + * channel when a new data is available in the corresponding ADCx_JDRy register. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. End of conversion flag. + */ + +bool adc_eoc_injected(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_JEOC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Sequence Flag for Injected Conversions + * + * This flag is set after all channels of an injected group have been + * converted. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. End of conversion flag. + */ +bool adc_eos_injected(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_JEOS; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read from an Injected Conversion Result Register + * + * The result read back from the selected injected result register (one of four) + * is 12 bits, right or left aligned within the first 16 bits. The result can + * have a negative value if the injected channel offset has been set @see + * adc_set_injected_offset. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + * @param[in] reg Unsigned int8. Register number (1 ... 4). + * @returns Unsigned int32 conversion result. + */ + +uint32_t adc_read_injected(uint32_t adc, uint8_t reg) +{ + switch (reg) { + case 1: + return ADC_JDR1(adc); + case 2: + return ADC_JDR2(adc); + case 3: + return ADC_JDR3(adc); + case 4: + return ADC_JDR4(adc); + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Injected Channel Data Offset + * + * This value is subtracted from the injected channel results after conversion + * is complete, and can result in negative results. A separate value can be + * specified for each injected data register. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] reg Unsigned int8. Register number (1 ... 4). + * @param[in] offset Unsigned int32. +*/ + +void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset) +{ + switch (reg) { + case 1: + ADC_OFR1(adc) |= ADC_OFR1_OFFSET1_EN; + ADC_OFR1(adc) |= offset; + break; + case 2: + ADC_OFR2(adc) |= ADC_OFR2_OFFSET2_EN; + ADC_OFR2(adc) |= offset; + break; + case 3: + ADC_OFR3(adc) |= ADC_OFR3_OFFSET3_EN; + ADC_OFR3(adc) |= offset; + break; + case 4: + ADC_OFR4(adc) |= ADC_OFR4_OFFSET4_EN; + ADC_OFR4(adc) |= offset; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Prescale + * + * The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + * + * @param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref + * adc_ccr_adcpre +*/ + +void adc_set_clk_prescale(uint32_t adc, uint32_t prescale) +{ + uint32_t reg32 = ((ADC_CCR(adc) & ~ADC_CCR_CKMODE_MASK) | prescale); + ADC_CCR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Dual/Triple Mode + * + * The multiple mode uses ADC1 as master, ADC2 and optionally ADC3 in a slave + * arrangement. This setting is applied to ADC1 only. + * + * The various modes possible are described in the reference manual. + * + * @param[in] mode Unsigned int32. Multiple mode selection from @ref + * adc_multi_mode +*/ + +void adc_set_multi_mode(uint32_t adc, uint32_t mode) +{ + ADC_CCR(adc) |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + * + * This enables an external trigger for set of defined regular channels, and + * sets the polarity of the trigger event: rising or falling edge or both. Note + * that if the trigger polarity is zero, triggering is disabled. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + * @param[in] trigger Unsigned int32. Trigger identifier + * @ref adc_trigger_regular + * @param[in] polarity Unsigned int32. Trigger polarity @ref + * adc_trigger_polarity_regular + */ + +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CFGR1(adc); + + reg32 &= ~(ADC_CFGR1_EXTSEL_MASK | ADC_CFGR1_EXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CFGR1(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + */ + +void adc_disable_external_trigger_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_EXTEN_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + * + * This enables an external trigger for set of defined injected channels, and + * sets the polarity of the trigger event: rising or falling edge or both. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @param[in] trigger Unsigned int8. Trigger identifier + * @ref adc_trigger_injected + * @param[in] polarity Unsigned int32. Trigger polarity + * @ref adc_trigger_polarity_injected +*/ + +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_JSQR(adc); + + reg32 &= ~(ADC_JSQR_JEXTSEL_MASK | ADC_JSQR_JEXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_JSQR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_external_trigger_injected(uint32_t adc) +{ + ADC_JSQR(adc) &= ~ADC_JSQR_JEXTEN_MASK; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Analog Watchdog Flag + * + * This flag is set when the converted voltage crosses the high or low + * thresholds. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. AWD flag. + */ + +bool adc_awd(uint32_t adc) +{ + return (ADC_ISR(adc) & ADC_ISR_AWD1) && + (ADC_ISR(adc) & ADC_ISR_AWD2) && + (ADC_ISR(adc) & ADC_ISR_AWD3); +} + + +/** + * Enable the ADC Voltage regulator + * Before any use of the ADC, the ADC Voltage regulator must be enabled. + * You must wait up to 10uSecs afterwards before trying anything else. + * @param[in] adc ADC block register address base + * @sa adc_disable_regulator + */ +void adc_enable_regulator(uint32_t adc) +{ + ADC_CR(adc) &= ~ADC_CR_ADVREGEN_MASK; + ADC_CR(adc) |= ADC_CR_ADVREGEN_ENABLE; +} + +/** + * Disable the ADC Voltage regulator + * You can disable the adc vreg when not in use to save power + * @param[in] adc ADC block register address base + * @sa adc_enable_regulator + */ +void adc_disable_regulator(uint32_t adc) +{ + ADC_CR(adc) &= ~ADC_CR_ADVREGEN_MASK; + ADC_CR(adc) |= ADC_CR_ADVREGEN_DISABLE; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/crc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/crc.c new file mode 100644 index 00000000..eb3c14be --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/crc.c @@ -0,0 +1,33 @@ +/** @defgroup crc_file CRC + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx CRC + * + * @version 1.0.0 + * + * @date 15 October 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dac.c new file mode 100644 index 00000000..2d8021e0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dac.c @@ -0,0 +1,31 @@ +/** @defgroup dac_file DAC + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx DAC + * + * @version 1.0.0 + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dma.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dma.c new file mode 100644 index 00000000..c5d82b13 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/dma.c @@ -0,0 +1,31 @@ +/** @defgroup dma_file DMA + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx Direct Memory Access + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/flash.c new file mode 100644 index 00000000..58687161 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/flash.c @@ -0,0 +1,62 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx FLASH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * + * @date 14 January 2014 + * + * This library supports the FLASH memory controller in the STM32F3 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * For the STM32F3xx, accessing FLASH memory is described in + * section 3 of the STM32F3xx Reference Manual. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Clears program error, end of operation, busy flags. +*/ + +void flash_clear_status_flags(void) +{ + flash_clear_pgperr_flag(); + flash_clear_eop_flag(); + flash_clear_bsy_flag(); +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/i2c.c new file mode 100644 index 00000000..cc92957b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/i2c.c @@ -0,0 +1,32 @@ +/** @defgroup i2c_file I2C + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx I2C + * + * @version 1.0.0 + * + * @date 15 October 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/iwdg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/iwdg.c new file mode 100644 index 00000000..cf0045c5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/iwdg.c @@ -0,0 +1,31 @@ +/** @defgroup iwdg_file IWDG + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx Independent Watchdog Timer + * + * @version 1.0.0 + * + * @date 18 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/libopencm3_stm32f3.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/libopencm3_stm32f3.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/libopencm3_stm32f3.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/pwr.c new file mode 100644 index 00000000..3c1a84bd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/pwr.c @@ -0,0 +1,40 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx Power Control + * + * @author @htmlonly © @endhtmlonly 2014 + * Ken Sarkies + * + * @date 13 January 2014 + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rcc.c new file mode 100644 index 00000000..0a69efee --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rcc.c @@ -0,0 +1,446 @@ +/** @defgroup rcc_file RCC + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx Reset and Clock Control + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * Modified by 2013 Fernando Cortes (stm32f3) + * Modified by 2013 Guillermo Rivera (stm32f3) + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#include +#include +#include +#include + +/* Set the default clock frequencies after reset. */ +uint32_t rcc_ahb_frequency = 8000000; +uint32_t rcc_apb1_frequency = 8000000; +uint32_t rcc_apb2_frequency = 8000000; + +const struct rcc_clock_scale rcc_hsi_8mhz[RCC_CLOCK_END] = { + { /* 44MHz */ + .pll = RCC_CFGR_PLLMUL_PLL_IN_CLK_X11, + .pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE1_DIV_2, + .ppre2 = RCC_CFGR_PPRE2_DIV_NONE, + .flash_config = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1WS, + .ahb_frequency = 44000000, + .apb1_frequency = 22000000, + .apb2_frequency = 44000000, + }, + { /* 48MHz */ + .pll = RCC_CFGR_PLLMUL_PLL_IN_CLK_X12, + .pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE1_DIV_2, + .ppre2 = RCC_CFGR_PPRE2_DIV_NONE, + .flash_config = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1WS, + .ahb_frequency = 48000000, + .apb1_frequency = 24000000, + .apb2_frequency = 48000000, + }, + { /* 64MHz */ + .pll = RCC_CFGR_PLLMUL_PLL_IN_CLK_X16, + .pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE1_DIV_2, + .ppre2 = RCC_CFGR_PPRE2_DIV_NONE, + .flash_config = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2WS, + .ahb_frequency = 64000000, + .apb1_frequency = 32000000, + .apb2_frequency = 64000000, + } +}; + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case RCC_HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case RCC_HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case RCC_LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case RCC_LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + } + + cm3_assert_not_reached(); +} + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_LSE: + return RCC_BDCR & RCC_BDCR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + + +void rcc_wait_for_osc_not_ready(enum rcc_osc osc) +{ + while (rcc_is_osc_ready(osc)); +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_PLL); + break; + case RCC_HSE: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_HSE); + break; + case RCC_HSI: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_HSI); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +void rcc_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | clk); +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~RCC_CFGR_PLLSRC; + RCC_CFGR = (reg32 | (pllsrc << 16)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE2_MASK << RCC_CFGR_PPRE2_SHIFT); + RCC_CFGR = (reg32 | (ppre2 << RCC_CFGR_PPRE2_SHIFT)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE1_MASK << RCC_CFGR_PPRE1_SHIFT); + RCC_CFGR = (reg32 | (ppre1 << RCC_CFGR_PPRE1_SHIFT)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_HPRE_MASK << RCC_CFGR_HPRE_SHIFT); + RCC_CFGR = (reg32 | (hpre << RCC_CFGR_HPRE_SHIFT)); +} + +/** + * Set PLL Source pre-divider **CAUTION**. + * On some F3 devices, prediv only applies to HSE source. On others, + * this is _after_ source selection. See also f0. + * @param[in] prediv division by prediv+1 @ref rcc_cfgr2_prediv + */ +void rcc_set_prediv(uint32_t prediv) +{ + RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PREDIV) | prediv; +} + +void rcc_set_pll_multiplier(uint32_t pll) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PLLMUL_MASK << RCC_CFGR_PLLMUL_SHIFT); + RCC_CFGR = (reg32 | (pll << RCC_CFGR_PLLMUL_SHIFT)); +} + + +uint32_t rcc_get_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR & 0x000c) >> 2; +} + + +void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_HSI); /* XXX: se cayo */ + rcc_wait_for_sysclk_status(RCC_HSI); + + rcc_osc_off(RCC_PLL); + rcc_wait_for_osc_not_ready(RCC_PLL); + rcc_set_pll_source(clock->pllsrc); + rcc_set_pll_multiplier(clock->pll); + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre2(clock->ppre2); + rcc_set_ppre1(clock->ppre1); + /* Configure flash settings. */ + flash_set_ws(clock->flash_config); + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_PLL); /* XXX: se cayo */ + /* Wait for PLL clock to be selected. */ + rcc_wait_for_sysclk_status(RCC_PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; +} + + +void rcc_backupdomain_reset(void) +{ + /* Set the backup domain software reset. */ + RCC_BDCR |= RCC_BDCR_BDRST; + + /* Clear the backup domain software reset. */ + RCC_BDCR &= ~RCC_BDCR_BDRST; +} + +void rcc_set_i2c_clock_hsi(uint32_t i2c) +{ + if (i2c == I2C1) { + RCC_CFGR3 &= ~RCC_CFGR3_I2C1SW; + } + if (i2c == I2C2) { + RCC_CFGR3 &= ~RCC_CFGR3_I2C2SW; + } +} + +void rcc_set_i2c_clock_sysclk(uint32_t i2c) +{ + if (i2c == I2C1) { + RCC_CFGR3 |= RCC_CFGR3_I2C1SW; + } + if (i2c == I2C2) { + RCC_CFGR3 |= RCC_CFGR3_I2C2SW; + } +} + +uint32_t rcc_get_i2c_clocks(void) +{ + return RCC_CFGR3 & (RCC_CFGR3_I2C1SW | RCC_CFGR3_I2C2SW); +} + +void rcc_usb_prescale_1_5(void) +{ + RCC_CFGR &= ~RCC_CFGR_USBPRES; +} + +void rcc_usb_prescale_1(void) +{ + RCC_CFGR |= RCC_CFGR_USBPRES; +} + +void rcc_adc_prescale(uint32_t prescale1, uint32_t prescale2) +{ + uint32_t clear_mask = (RCC_CFGR2_ADCxPRES_MASK + << RCC_CFGR2_ADC12PRES_SHIFT) + | (RCC_CFGR2_ADCxPRES_MASK + << RCC_CFGR2_ADC34PRES_SHIFT); + uint32_t set = (prescale1 << RCC_CFGR2_ADC12PRES_SHIFT) | + (prescale2 << RCC_CFGR2_ADC34PRES_SHIFT); + RCC_CFGR2 &= ~(clear_mask); + RCC_CFGR2 |= (set); +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rtc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rtc.c new file mode 100644 index 00000000..f332765a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/rtc.c @@ -0,0 +1,38 @@ +/** @defgroup rtc_file RTC + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx Real Time Clock + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Ken Sarkies + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/spi.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/spi.c new file mode 100644 index 00000000..3dcc5240 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/spi.c @@ -0,0 +1,31 @@ +/** @defgroup spi_file SPI + +@ingroup STM32F3xx + +@brief libopencm3 STM32F3xx SPI + +@version 1.0.0 + +@date 20 February 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/stm32f303xc.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/stm32f303xc.ld new file mode 100644 index 00000000..9069bf3f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/stm32f303xc.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for the STM32F303xC chip. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 40K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f3.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/timer.c new file mode 100644 index 00000000..0e9ac3d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/timer.c @@ -0,0 +1,33 @@ +/** @defgroup timer_file TIMER + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx Timers + * + * @version 1.0.0 + * + * @date 11 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/usart.c new file mode 100644 index 00000000..456701dd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/usart.c @@ -0,0 +1,110 @@ +/** @defgroup usart_file USART + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx USART + * + * @version 1.0.0 + * + * @date 30 August 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief USART Send a Data Word. + * + * @param[in] usart unsigned 32 bit. USART block register address base @ref + * usart_reg_base + * @param[in] data unsigned 16 bit. + */ + +void usart_send(uint32_t usart, uint16_t data) +{ + /* Send data. */ + USART_TDR(usart) = (data & USART_TDR_MASK); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Received Data Word. + * + * If parity is enabled the MSB (bit 7 or 8 depending on the word length) is + * the parity bit. + * + * @param[in] usart unsigned 32 bit. USART block register address base @ref + * usart_reg_base + * @returns unsigned 16 bit data word. + */ + +uint16_t usart_recv(uint32_t usart) +{ + /* Receive data. */ + return USART_RDR(usart) & USART_RDR_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Wait for Transmit Data Buffer Empty + * + * Blocks until the transmit data buffer becomes empty and is ready to accept + * the next data word. + * + * @param[in] usart unsigned 32 bit. USART block register address base @ref + * usart_reg_base + */ + +void usart_wait_send_ready(uint32_t usart) +{ + /* Wait until the data has been transferred into the shift register. */ + while ((USART_ISR(usart) & USART_ISR_TXE) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Wait for Received Data Available + * + * Blocks until the receive data buffer holds a valid received data word. + * + * @param[in] usart unsigned 32 bit. USART block register address base @ref + * usart_reg_base + */ + +void usart_wait_recv_ready(uint32_t usart) +{ + /* Wait until the data is ready to be received. */ + while ((USART_ISR(usart) & USART_ISR_RXNE) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Read a Status Flag. + * + * @param[in] usart unsigned 32 bit. USART block register address base @ref + * usart_reg_base + * @param[in] flag Unsigned int32. Status register flag @ref usart_sr_flags. + * @returns boolean: flag set. + */ + +bool usart_get_flag(uint32_t usart, uint32_t flag) +{ + return ((USART_ISR(usart) & flag) != 0); +} + + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/vector_chipset.c new file mode 100644 index 00000000..145be057 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f3/vector_chipset.c @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +static void pre_main(void) +{ + /* Enable access to Floating-Point coprocessor. */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/Makefile new file mode 100644 index 00000000..9225838c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/Makefile @@ -0,0 +1,65 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2013 Alexandru Gagniuc +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32f4 +SRCLIBDIR ?= ../.. + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m4 -mthumb $(FP_FLAGS) \ + -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F4 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs + +OBJS = adc.o adc_common_v1.o can.o desig.o gpio.o pwr.o rcc.o \ + rtc.o crypto.o + +OBJS += crc_common_all.o dac_common_all.o dma_common_f24.o \ + gpio_common_all.o gpio_common_f0234.o i2c_common_v1.o \ + iwdg_common_all.o pwr_common_v1.o rtc_common_l1f024.o \ + spi_common_all.o spi_common_l1f124.o timer_common_all.o \ + timer_common_f0234.o timer_common_f24.o usart_common_all.o \ + usart_common_f124.o flash_common_f234.o flash_common_f24.o \ + hash_common_f24.o crypto_common_f24.o exti_common_all.o \ + rcc_common_all.o +OBJS += rng_common_v1.o + +OBJS += usb.o usb_standard.o usb_control.o usb_fx07_common.o \ + usb_f107.o usb_f207.o usb_msc.o + +OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz8051mll.o fmc.o + +OBJS += ltdc.o + +VPATH += ../../usb:../:../../cm3:../common +VPATH += ../../ethernet + +include ../../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/adc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/adc.c new file mode 100644 index 00000000..fba88de6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/adc.c @@ -0,0 +1,437 @@ +/** @defgroup adc_file ADC + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx Analog to Digital Converters + +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies + +@date 30 August 2012 + +This library supports the A/D Converter Control System in the STM32 series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Devices can have up to three A/D converters each with their own set of +registers. However all the A/D converters share a common clock which is +prescaled from the APB2 clock by default by a minimum factor of 2 to a maximum +of 8. The ADC resolution can be set to 12, 10, 8 or 6 bits. + +Each A/D converter has up to 19 channels: +@li On ADC1 the analog channels 16 is internally connected to the temperature +sensor, channel 17 to VREFINT, and channel 18 to VBATT. +@li On ADC2 and ADC3 the analog channels 16 - 18 are not used. + +The conversions can occur as a one-off conversion whereby the process stops +once conversion is complete. The conversions can also be continuous wherein a +new conversion starts immediately the previous conversion has ended. + +Conversion can occur as a single channel conversion or a scan of a group of +channels in either continuous or one-off mode. If more than one channel is +converted in a scan group, DMA must be used to transfer the data as there is +only one result register available. An interrupt can be set to occur at the end +of conversion, which occurs after all channels have been scanned. + +A discontinuous mode allows a subgroup of group of a channels to be converted +in bursts of a given length. + +Injected conversions allow a second group of channels to be converted +separately from the regular group. An interrupt can be set to occur at the end +of conversion, which occurs after all channels have been scanned. + +@section adc_f4_api_ex Basic ADC Handling API. + +Example 1: Simple single channel conversion polled. Enable the peripheral clock +and ADC, reset ADC and set the prescaler divider. Set multiple mode to +independent. + +@code +gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1); +rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); +adc_set_clk_prescale(RCC_CFGR_ADCPRE_BY2); +adc_disable_scan_mode(ADC1); +adc_set_single_conversion_mode(ADC1); +adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); +uint8_t channels[] = ADC_CHANNEL0; +adc_set_regular_sequence(ADC1, 1, channels); +adc_set_multi_mode(ADC_CCR_MULTI_INDEPENDENT); +adc_power_on(ADC1); +adc_start_conversion_regular(ADC1); +while (! adc_eoc(ADC1)); +reg16 = adc_read_regular(ADC1); +@endcode + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for a Single Channel + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] channel Unsigned int8. ADC Channel integer 0..18 or from @ref +adc_channel +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg + * NOTE Common with f1, f2 and f37x +*/ + +void adc_set_sample_time(uint32_t adc, uint8_t channel, uint8_t time) +{ + uint32_t reg32; + + if (channel < 10) { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0x7 << (channel * 3)); + reg32 |= (time << (channel * 3)); + ADC_SMPR2(adc) = reg32; + } else { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0x7 << ((channel - 10) * 3)); + reg32 |= (time << ((channel - 10) * 3)); + ADC_SMPR1(adc) = reg32; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for All Channels + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5, same +for all channels. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg + * NOTE Common with f1, f2 and f37x +*/ + +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time) +{ + uint8_t i; + uint32_t reg32 = 0; + + for (i = 0; i <= 9; i++) { + reg32 |= (time << (i * 3)); + } + ADC_SMPR2(adc) = reg32; + + for (i = 10; i <= 17; i++) { + reg32 |= (time << ((i - 10) * 3)); + } + ADC_SMPR1(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Power On + +If the ADC is in power-down mode then it is powered up. The application needs +to wait a time of about 3 microseconds for stabilization before using the ADC. +If the ADC is already on this function call will have no effect. + * NOTE Common with L1 and F2 + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_power_on(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_ADON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Prescale + +The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + +@param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref +adc_ccr_adcpre +*/ + +void adc_set_clk_prescale(uint32_t prescale) +{ + uint32_t reg32 = ((ADC_CCR & ~ADC_CCR_ADCPRE_MASK) | prescale); + ADC_CCR = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Dual/Triple Mode + +The multiple mode uses ADC1 as master, ADC2 and optionally ADC3 in a slave +arrangement. This setting is applied to ADC1 only. + +The various modes possible are described in the reference manual. + +@param[in] mode Unsigned int32. Multiple mode selection from @ref adc_multi_mode +*/ + +void adc_set_multi_mode(uint32_t mode) +{ + ADC_CCR |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + +This enables an external trigger for set of defined regular channels, and sets +the polarity of the trigger event: rising or falling edge or both. Note that if +the trigger polarity is zero, triggering is disabled. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int32. Trigger identifier @ref adc_trigger_regular +@param[in] polarity Unsigned int32. Trigger polarity @ref +adc_trigger_polarity_regular +*/ + +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_EXTSEL_MASK | ADC_CR2_EXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_external_trigger_regular(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EXTEN_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + +This enables an external trigger for set of defined injected channels, and sets +the polarity of the trigger event: rising or falling edge or both. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected +@param[in] polarity Unsigned int32. Trigger polarity @ref +adc_trigger_polarity_injected +*/ + +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_JEXTSEL_MASK | ADC_CR2_JEXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_external_trigger_injected(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_JEXTEN_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Resolution + +ADC Resolution can be reduced from 12 bits to 10, 8 or 6 bits for a +corresponding reduction in conversion time (resolution + 3 ADC clock cycles). + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] resolution Unsigned int32. Resolution value @ref adc_cr1_res +*/ + +void adc_set_resolution(uint32_t adc, uint32_t resolution) +{ + uint32_t reg32 = ADC_CR1(adc); + + reg32 &= ~ADC_CR1_RES_MASK; + reg32 |= resolution; + ADC_CR1(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable the Overrun Interrupt + +The overrun interrupt is generated when data is not read from a result register +before the next conversion is written. If DMA is enabled, all transfers are +terminated and any conversion sequence is aborted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_overrun_interrupt(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_OVRIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable the Overrun Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_overrun_interrupt(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_OVRIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Overrun Flag + +The overrun flag is set when data is not read from a result register before the +next conversion is written. If DMA is enabled, all transfers are terminated and +any conversion sequence is aborted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +bool adc_get_overrun_flag(uint32_t adc) +{ + return ADC_SR(adc) & ADC_SR_OVR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Clear Overrun Flags + +The overrun flag is cleared. Note that if an overrun occurs, DMA is terminated. +The flag must be cleared and the DMA stream and ADC reinitialised to resume +conversions (see the reference manual). + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +void adc_clear_overrun_flag(uint32_t adc) +{ +/* need to write zero to clear this */ + ADC_SR(adc) &= ~ADC_SR_OVR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an EOC for Each Conversion + +The EOC is set after each conversion in a sequence rather than at the end of the +sequence. Overrun detection is enabled only if DMA is enabled. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_eoc_after_each(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_EOCS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable the EOC for Each Conversion + +The EOC is set at the end of each sequence rather than after each conversion in +the sequence. Overrun detection is enabled always. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_eoc_after_group(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EOCS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set DMA to Continue + +This must be set to allow DMA to continue to operate after the last conversion +in the DMA sequence. This allows DMA to be used in continuous circular mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_dma_continue(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_DDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set DMA to Terminate + +This must be set to allow DMA to terminate after the last conversion in the DMA +sequence. This can avoid overrun errors. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_dma_terminate(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_DDS; +} +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Analog Watchdog Flag + +This flag is set when the converted voltage crosses the high or low thresholds. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. AWD flag. +*/ + +bool adc_awd(uint32_t adc) +{ + return ADC_SR(adc) & ADC_SR_AWD; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable The Temperature Sensor + +This enables both the sensor and the reference voltage measurements on channels +16 and 17. These are only available on ADC1 channel 16 and 17 respectively. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_temperature_sensor() +{ + ADC_CCR |= ADC_CCR_TSVREFE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable The Temperature Sensor + +Disabling this will reduce power consumption from the sensor and the reference +voltage measurements. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_temperature_sensor() +{ + ADC_CCR &= ~ADC_CCR_TSVREFE; +} + +/*---------------------------------------------------------------------------*/ + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crc.c new file mode 100644 index 00000000..6bc9456b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crc.c @@ -0,0 +1,33 @@ +/** @defgroup crc_file CRC + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx CRC + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crypto.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crypto.c new file mode 100644 index 00000000..651f3659 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/crypto.c @@ -0,0 +1,66 @@ +/** @defgroup crypto_file CRYPTO + * + * @ingroup STM32F4xx + * + * @brief libopencm3 STM32F4xx CRYPTO + * + * @version 1.0.0 + * + * @date 18 Jun 2013 + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ + +/** @brief Set the MAC algorithm + */ +void crypto_set_mac_algorithm(enum crypto_mode_mac mode) +{ + crypto_set_algorithm((enum crypto_mode) mode); +} + +/** + * @brief Swap context + * + *@param[in] buf uint32_t Memory space for swap (16 items length) + */ +void crypto_context_swap(uint32_t *buf) +{ + int i; + /* Apply exact order of ? */ + for (i = 0; i < 8; i++) { + uint32_t save = *buf; + *buf++ = CRYP_CSGCMCCMR(i); + CRYP_CSGCMCCMR(i) = save; + }; + + for (i = 0; i < 8; i++) { + uint32_t save = *buf; + *buf++ = CRYP_CSGCMR(i); + CRYP_CSGCMCCMR(i) = save; + }; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dac.c new file mode 100644 index 00000000..c5397b62 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dac.c @@ -0,0 +1,31 @@ +/** @defgroup dac_file DAC + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx DAC + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dma.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dma.c new file mode 100644 index 00000000..6616621a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/dma.c @@ -0,0 +1,31 @@ +/** @defgroup dma_file DMA + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx DMA + +@version 1.0.0 + +@date 30 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/flash.c new file mode 100644 index 00000000..5353605a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/flash.c @@ -0,0 +1,53 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32F4xx + * + * @brief libopencm3 STM32F4xx FLASH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * + * @date 14 January 2014 + * + * This library supports the FLASH memory controller in the STM32F4 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * For the STM32F4xx, accessing FLASH memory is described briefly in + * section 2.3.3 of the STM32F4xx Reference Manual. + * For detailed programming information see: + * PM0081 programming manual: STM32F10xxx Flash programming + * September 2011, Doc ID 018520 Rev 1 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/fmc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/fmc.c new file mode 100644 index 00000000..1c30dd67 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/fmc.c @@ -0,0 +1,99 @@ +/* + * + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Utility functions for the SDRAM component of the FMC */ + +#include +#include + +/* + * Install various timing values into the correct place in the + * SDRAM Timing Control Register format. + * + * Note that the register is 'zero' based to save bits so 1 cycle + * is stored as '0'. This command takes actual cycles and adjusts + * by subtracting 1. + */ +uint32_t +sdram_timing(struct sdram_timing *t) { + uint32_t result; + + result = 0; + result |= ((t->trcd - 1) & 0xf) << FMC_SDTR_TRCD_SHIFT; + result |= ((t->trp - 1) & 0xf) << FMC_SDTR_TRP_SHIFT; + result |= ((t->twr - 1) & 0xf) << FMC_SDTR_TWR_SHIFT; + result |= ((t->trc - 1) & 0xf) << FMC_SDTR_TRC_SHIFT; + result |= ((t->tras - 1) & 0xf) << FMC_SDTR_TRAS_SHIFT; + result |= ((t->txsr - 1) & 0xf) << FMC_SDTR_TXSR_SHIFT; + result |= ((t->tmrd - 1) & 0xf) << FMC_SDTR_TMRD_SHIFT; + return result; +} + +/* + * Send a command to the SDRAM controller, wait until it is not + * busy before sending. This allows you to chain sending commands + * and the code will pause as needed between them. + */ +void +sdram_command(enum fmc_sdram_bank bank, + enum fmc_sdram_command cmd, int autorefresh, int modereg) { + uint32_t tmp_reg = 0; + + switch (bank) { + case SDRAM_BANK1: + tmp_reg = FMC_SDCMR_CTB1; + break; + case SDRAM_BANK2: + tmp_reg = FMC_SDCMR_CTB2; + break; + case SDRAM_BOTH_BANKS: + tmp_reg = FMC_SDCMR_CTB1 | FMC_SDCMR_CTB2; + break; + } + tmp_reg |= autorefresh << FMC_SDCMR_NRFS_SHIFT; + tmp_reg |= modereg << FMC_SDCMR_MRD_SHIFT; + switch (cmd) { + case SDRAM_CLK_CONF: + tmp_reg |= FMC_SDCMR_MODE_CLOCK_CONFIG_ENA; + break; + case SDRAM_AUTO_REFRESH: + tmp_reg |= FMC_SDCMR_MODE_AUTO_REFRESH; + break; + case SDRAM_LOAD_MODE: + tmp_reg |= FMC_SDCMR_MODE_LOAD_MODE_REGISTER; + break; + case SDRAM_PALL: + tmp_reg |= FMC_SDCMR_MODE_PALL; + break; + case SDRAM_SELF_REFRESH: + tmp_reg |= FMC_SDCMR_MODE_SELF_REFRESH; + break; + case SDRAM_POWER_DOWN: + tmp_reg |= FMC_SDCMR_MODE_POWER_DOWN; + break; + case SDRAM_NORMAL: + default: + break; + } + + /* Wait for the next chance to talk to the controller */ + while (FMC_SDSR & FMC_SDSR_BUSY); + + /* Send the next command */ + FMC_SDCMR = tmp_reg; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/gpio.c new file mode 100644 index 00000000..ea59ae79 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/gpio.c @@ -0,0 +1,31 @@ +/** @defgroup gpio_file GPIO + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx General Purpose I/O + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/hash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/hash.c new file mode 100644 index 00000000..cd791bff --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/hash.c @@ -0,0 +1,31 @@ +/** @defgroup hash_file HASH + * + * @ingroup STM32F4xx + * + * @brief libopencm3 STM32F4xx Hash Processor + * + * @version 1.0.0 + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/i2c.c new file mode 100644 index 00000000..67df9b15 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/i2c.c @@ -0,0 +1,31 @@ +/** @defgroup i2c_file I2C + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx I2C + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/iwdg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/iwdg.c new file mode 100644 index 00000000..3985657f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/iwdg.c @@ -0,0 +1,31 @@ +/** @defgroup iwdg_file IWDG + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx Independent Watchdog Timer + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/ltdc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/ltdc.c new file mode 100644 index 00000000..83a13961 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/ltdc.c @@ -0,0 +1,89 @@ +/** @defgroup ltdc_file LTDC + * + * @ingroup STM32F4xx + * + * @brief libopencm3 STM32F4xx LTDC + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2014 + * Oliver Meier + * + * @date 5 December 2014 + * + * This library supports the LCD controller (LTDC) in the STM32F4 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * For the STM32F4xx, LTDC is described in LCD-TFT Controller (LTDC) + * section 16 of the STM32F4xx Reference Manual (RM0090,Rev8). + * + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Oliver Meier + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void ltdc_set_tft_sync_timings(uint16_t sync_width, uint16_t sync_height, + uint16_t h_back_porch, uint16_t v_back_porch, + uint16_t active_width, uint16_t active_height, + uint16_t h_front_porch, uint16_t v_front_porch) +{ + /*assert((active_width <= 0x400) && (active_height <= 0x300));*/ + + uint16_t w, h; + w = sync_width - 1; + h = sync_height - 1; + /*assert((w&0xfff == w) && (h&0x7ff == h));*/ + LTDC_SSCR = (w << 16) | (h << 0); + + w += h_back_porch; + h += v_back_porch; + /*assert((w&0xfff == w) && (h&0x7ff == h));*/ + LTDC_BPCR = (w << 16) | (h << 0); + + w += active_width; + h += active_height; + /*assert((w&0xfff == w) && (h&0x7ff == h));*/ + LTDC_AWCR = (w << 16) | (h << 0); + + w += h_front_porch; + h += v_front_porch; + /*assert((w&0xfff == w) && (h&0x7ff == h));*/ + LTDC_TWCR = (w << 16) | (h << 0); +} + +void ltdc_setup_windowing(uint8_t layer_number, + uint16_t h_back_porch, uint16_t v_back_porch, + uint16_t active_width, uint16_t active_height) +{ + active_width += h_back_porch - 1; + active_height += v_back_porch - 1; + /*assert((h_back_porch & 0xfff == h_back_porch) && + (v_back_porch & 0xfff == v_back_porch) && + (active_width & 0xfff == active_width) && + (active_height & 0xfff == active_height));*/ + LTDC_LxWHPCR(layer_number) = (active_width << 16) | + (h_back_porch << 0); + LTDC_LxWVPCR(layer_number) = (active_height << 16) | + (v_back_porch << 0); +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/pwr.c new file mode 100644 index 00000000..499152b1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/pwr.c @@ -0,0 +1,46 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32F4xx + * + * @brief libopencm3 STM32F4xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2011 Stephen Caudle + * + * @date 4 March 2013 + * + * This library supports the power control system for the + * STM32F4 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void pwr_set_vos_scale(enum pwr_vos_scale scale) +{ + if (scale == PWR_SCALE1) { + PWR_CR |= PWR_CR_VOS; + } else if (scale == PWR_SCALE2) { + PWR_CR &= PWR_CR_VOS; + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rcc.c new file mode 100644 index 00000000..be15a80c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rcc.c @@ -0,0 +1,732 @@ +/** @defgroup rcc_file RCC + * + * @ingroup STM32F4xx + * + * @section rcc_f4_api_ex Reset and Clock Control API. + * + * @brief libopencm3 STM32F4xx Reset and Clock Control + * + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * + * @date 18 Jun 2013 + * + * This library supports the Reset and Clock Control System in the STM32 series + * of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include + +/**@{*/ + +/* Set the default clock frequencies after reset. */ +uint32_t rcc_ahb_frequency = 16000000; +uint32_t rcc_apb1_frequency = 16000000; +uint32_t rcc_apb2_frequency = 16000000; + +const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 48MHz */ + .pllm = 8, + .plln = 96, + .pllp = 2, + .pllq = 2, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 48000000, + .apb1_frequency = 12000000, + .apb2_frequency = 24000000, + }, + { /* 84MHz */ + .pllm = 8, + .plln = 336, + .pllp = 4, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_2WS, + .ahb_frequency = 84000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, + { /* 120MHz */ + .pllm = 8, + .plln = 240, + .pllp = 2, + .pllq = 5, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 120000000, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, + { /* 168MHz */ + .pllm = 8, + .plln = 336, + .pllp = 2, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_5WS, + .ahb_frequency = 168000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, +}; + +const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 48MHz */ + .pllm = 12, + .plln = 96, + .pllp = 2, + .pllq = 2, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 48000000, + .apb1_frequency = 12000000, + .apb2_frequency = 24000000, + }, + { /* 84MHz */ + .pllm = 12, + .plln = 336, + .pllp = 4, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_2WS, + .ahb_frequency = 84000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, + { /* 120MHz */ + .pllm = 12, + .plln = 240, + .pllp = 2, + .pllq = 5, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 120000000, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, + { /* 168MHz */ + .pllm = 12, + .plln = 336, + .pllp = 2, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_5WS, + .ahb_frequency = 168000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, +}; + +const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 48MHz */ + .pllm = 16, + .plln = 96, + .pllp = 2, + .pllq = 2, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 48000000, + .apb1_frequency = 12000000, + .apb2_frequency = 24000000, + }, + { /* 84MHz */ + .pllm = 16, + .plln = 336, + .pllp = 4, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_2WS, + .ahb_frequency = 84000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, + { /* 120MHz */ + .pllm = 16, + .plln = 240, + .pllp = 2, + .pllq = 5, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 120000000, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, + { /* 168MHz */ + .pllm = 16, + .plln = 336, + .pllp = 2, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_5WS, + .ahb_frequency = 168000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, +}; + +const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 48MHz */ + .pllm = 25, + .plln = 96, + .pllp = 2, + .pllq = 2, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 48000000, + .apb1_frequency = 12000000, + .apb2_frequency = 24000000, + }, + { /* 84MHz */ + .pllm = 25, + .plln = 336, + .pllp = 4, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_2WS, + .ahb_frequency = 84000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, + { /* 120MHz */ + .pllm = 25, + .plln = 240, + .pllp = 2, + .pllq = 5, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 120000000, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, + { /* 168MHz */ + .pllm = 25, + .plln = 336, + .pllp = 2, + .pllq = 7, + .pllr = 0, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_5WS, + .ahb_frequency = 168000000, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, +}; + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + case RCC_PLLSAI: + RCC_CIR |= RCC_CIR_PLLSAIRDYC; + break; + case RCC_PLLI2S: + RCC_CIR |= RCC_CIR_PLLI2SRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + case RCC_PLLSAI: + RCC_CIR |= RCC_CIR_PLLSAIRDYIE; + break; + case RCC_PLLI2S: + RCC_CIR |= RCC_CIR_PLLI2SRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + case RCC_PLLSAI: + RCC_CIR &= ~RCC_CIR_PLLSAIRDYIE; + break; + case RCC_PLLI2S: + RCC_CIR &= ~RCC_CIR_PLLI2SRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + case RCC_HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + case RCC_HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + case RCC_LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + case RCC_LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + case RCC_PLLSAI: + return ((RCC_CIR & RCC_CIR_PLLSAIRDYF) != 0); + case RCC_PLLI2S: + return ((RCC_CIR & RCC_CIR_PLLI2SRDYF) != 0); + } + return 0; +} + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_LSE: + return RCC_BDCR & RCC_BDCR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + case RCC_PLLSAI: + return RCC_CR & RCC_CR_PLLSAIRDY; + case RCC_PLLI2S: + return RCC_CR & RCC_CR_PLLI2SRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_PLL); + break; + case RCC_HSE: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_HSE); + break; + case RCC_HSI: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_HSI); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + case RCC_PLLSAI: + RCC_CR |= RCC_CR_PLLSAION; + break; + case RCC_PLLI2S: + RCC_CR |= RCC_CR_PLLI2SON; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + case RCC_PLLSAI: + RCC_CR &= ~RCC_CR_PLLSAION; + break; + case RCC_PLLI2S: + RCC_CR &= ~RCC_CR_PLLI2SON; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +/** + * Set the dividers for the PLLSAI clock outputs + * divider p is only available on F4x9 parts, pass 0 for other parts. + * @param n valid range is 49..432 + * @param p 0 if unused, @ref rcc_pllsaicfgr_pllsaip + * @param q valid range is 2..15 + * @param r valid range is 2..7 + * @sa rcc_pllsai_postscalers + */ +void rcc_pllsai_config(uint16_t n, uint16_t p, uint16_t q, uint16_t r) +{ + RCC_PLLSAICFGR = ( + ((n & RCC_PLLSAICFGR_PLLSAIN_MASK) << RCC_PLLSAICFGR_PLLSAIN_SHIFT) | + ((p & RCC_PLLSAICFGR_PLLSAIP_MASK) << RCC_PLLSAICFGR_PLLSAIP_SHIFT) | + ((q & RCC_PLLSAICFGR_PLLSAIQ_MASK) << RCC_PLLSAICFGR_PLLSAIQ_SHIFT) | + ((r & RCC_PLLSAICFGR_PLLSAIR_MASK) << RCC_PLLSAICFGR_PLLSAIR_SHIFT)); +} + + +/** + * Set the dedicated dividers after the PLLSAI configuration. + * + * @param q dedicated PLLSAI divider, for either A or B + * @param r dedicated LCD-TFT divider, see LTDC + * @sa rcc_pllsai_config + */ +void rcc_pllsai_postscalers(uint8_t q, uint8_t r) +{ + uint32_t reg32 = RCC_DCKCFGR; + reg32 &= ((RCC_DCKCFGR_PLLSAIDIVR_MASK << RCC_DCKCFGR_PLLSAIDIVR_SHIFT) + | (RCC_DCKCFGR_PLLSAIDIVQ_MASK << RCC_DCKCFGR_PLLSAIDIVQ_SHIFT)); + RCC_DCKCFGR = reg32 | ((q << RCC_DCKCFGR_PLLSAIDIVQ_SHIFT) | + (r << RCC_DCKCFGR_PLLSAIDIVR_SHIFT)); +} + + +void rcc_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | clk); +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_PLLCFGR; + reg32 &= ~(1 << 22); + RCC_PLLCFGR = (reg32 | (pllsrc << 22)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 13) | (1 << 14) | (1 << 15)); + RCC_CFGR = (reg32 | (ppre2 << 13)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 10) | (1 << 11) | (1 << 12)); + RCC_CFGR = (reg32 | (ppre1 << 10)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); + RCC_CFGR = (reg32 | (hpre << 4)); +} + +void rcc_set_rtcpre(uint32_t rtcpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); + RCC_CFGR = (reg32 | (rtcpre << 16)); +} + +/** + * Reconfigures the main PLL for a HSI source. + * Any reserved bits are kept at their reset values. + * @param pllm Divider for the main PLL input clock + * @param plln Main PLL multiplication factor for VCO + * @param pllp Main PLL divider for main system clock + * @param pllq Main PLL divider for USB OTG FS, SDMMC & RNG + * @param pllr Main PLL divider for DSI (for parts without DSI, provide 0 here) + */ +void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq, uint32_t pllr) +{ + /* Use reset value if not legal, for parts without pllr */ + if (pllr < 2) { + pllr = 2; + } + RCC_PLLCFGR = 0 | /* HSI */ + ((pllm & RCC_PLLCFGR_PLLM_MASK) << RCC_PLLCFGR_PLLM_SHIFT) | + ((plln & RCC_PLLCFGR_PLLN_MASK) << RCC_PLLCFGR_PLLN_SHIFT) | + ((((pllp >> 1) - 1) & RCC_PLLCFGR_PLLP_MASK) << RCC_PLLCFGR_PLLP_SHIFT) | + ((pllq & RCC_PLLCFGR_PLLQ_MASK) << RCC_PLLCFGR_PLLQ_SHIFT) | + ((pllr & RCC_PLLCFGR_PLLR_MASK) << RCC_PLLCFGR_PLLR_SHIFT); +} + +/** + * Reconfigures the main PLL for a HSE source. + * Any reserved bits are kept at their reset values. + * @param pllm Divider for the main PLL input clock + * @param plln Main PLL multiplication factor for VCO + * @param pllp Main PLL divider for main system clock + * @param pllq Main PLL divider for USB OTG FS, SDMMC & RNG + * @param pllr Main PLL divider for DSI (for parts without DSI, provide 0 here) + */ +void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq, uint32_t pllr) +{ + /* Use reset value if not legal, for parts without pllr */ + if (pllr < 2) { + pllr = 2; + } + RCC_PLLCFGR = RCC_PLLCFGR_PLLSRC | /* HSE */ + ((pllm & RCC_PLLCFGR_PLLM_MASK) << RCC_PLLCFGR_PLLM_SHIFT) | + ((plln & RCC_PLLCFGR_PLLN_MASK) << RCC_PLLCFGR_PLLN_SHIFT) | + ((((pllp >> 1) - 1) & RCC_PLLCFGR_PLLP_MASK) << RCC_PLLCFGR_PLLP_SHIFT) | + ((pllq & RCC_PLLCFGR_PLLQ_MASK) << RCC_PLLCFGR_PLLQ_SHIFT) | + ((pllr & RCC_PLLCFGR_PLLR_MASK) << RCC_PLLCFGR_PLLR_SHIFT); +} + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR & 0x000c) >> 2; +} + +void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_HSI); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + + /* Enable/disable high performance mode */ + if (!clock->power_save) { + pwr_set_vos_scale(PWR_SCALE1); + } else { + pwr_set_vos_scale(PWR_SCALE2); + } + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + rcc_set_main_pll_hse(clock->pllm, clock->plln, + clock->pllp, clock->pllq, clock->pllr); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Configure flash settings. */ + flash_set_ws(clock->flash_config); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_PLL); + + /* Wait for PLL clock to be selected. */ + rcc_wait_for_sysclk_status(RCC_PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; + + /* Disable internal high-speed oscillator. */ + rcc_osc_off(RCC_HSI); +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rng.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rng.c new file mode 100644 index 00000000..9adcd75a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rng.c @@ -0,0 +1,31 @@ +/* This file is used for documentation purposes. It does not need +to be compiled. All source code is in the common area. +If there is any device specific code required it can be included here, +in which case this file must be added to the compile list. */ + +/** @defgroup rng_file RNG + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx RNG + +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rtc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rtc.c new file mode 100644 index 00000000..f08ac2bc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/rtc.c @@ -0,0 +1,97 @@ +/** @defgroup rtc_file RTC + * + * @ingroup STM32F4xx + * + * @brief libopencm3 STM32F4xx RTC + * + * @version 1.0.0 + * + * @date 4 March 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the wakeup timer + @warning You must unlock the registers before using this function + +*/ +void rtc_enable_wakeup_timer(void) +{ + RTC_CR |= RTC_CR_WUTE | (RTC_CR_OSEL_WAKEUP << RTC_CR_OSEL_SHIFT); + rtc_enable_wakeup_timer_interrupt(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the wakeup timer + @warning You must unlock the registers before using this function + +*/ +void rtc_disable_wakeup_timer(void) +{ + RTC_CR &= ~RTC_CR_WUTE; + rtc_disable_wakeup_timer_interrupt(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the wakeup timer interrupt + @warning You must unlock the registers before using this function + +*/ +void rtc_enable_wakeup_timer_interrupt(void) +{ + /* FTFM: + * To enable the RTC Wakeup interrupt, the following sequence is + * required: + * 1. Configure and enable the EXTI Line 22 in interrupt mode and + * select the rising edge sensitivity. + */ + exti_enable_request(EXTI22); + exti_set_trigger(EXTI22, EXTI_TRIGGER_RISING); + + /* 2. Configure and enable the RTC_WKUP IRQ channel in the NVIC. */ + nvic_enable_irq(NVIC_RTC_WKUP_IRQ); + nvic_set_priority(NVIC_RTC_WKUP_IRQ, 1); + + /* 3. Configure the RTC to generate the RTC wakeup timer event. */ + RTC_CR |= RTC_CR_WUTIE; /* Enable the interrupt */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the wakeup timer interrupt + @warning You must unlock the registers before using this function + +*/ +void rtc_disable_wakeup_timer_interrupt(void) +{ + /* 1. Disable EXTI Line 22 */ + exti_disable_request(EXTI22); + + /* 2. Disable RTC_WKUP IRQ channel in the NVIC. */ + nvic_disable_irq(NVIC_RTC_WKUP_IRQ); + + /* 3. Disable RTC wakeup timer event. */ + RTC_CR &= ~RTC_CR_WUTIE; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/spi.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/spi.c new file mode 100644 index 00000000..c8a6b411 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/spi.c @@ -0,0 +1,31 @@ +/** @defgroup spi_file SPI + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx SPI + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/stm32f405x6.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/stm32f405x6.ld new file mode 100644 index 00000000..7ce3932e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/stm32f405x6.ld @@ -0,0 +1,34 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2011 Stephen Caudle + * Copyright (C) 2013 Sergey Krukowski + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for the STM32F40xxG chip (1024K flash, 128K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + ccm (rwx) : ORIGIN = 0x10000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f4.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/timer.c new file mode 100644 index 00000000..72ecd8df --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/timer.c @@ -0,0 +1,38 @@ +/* This file is used for documentation purposes. It does not need +to be compiled. All source code is in the common area. +If there is any device specific code required it can be included here, +in which case this file must be added to the compile list. */ + +/** @defgroup timer_file Timers + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx Timers + +@version 1.0.0 + +@date 18 August 2012 + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/usart.c new file mode 100644 index 00000000..06254c99 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/usart.c @@ -0,0 +1,31 @@ +/** @defgroup usart_file USART + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx USART + +@version 1.0.0 + +@date 30 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/vector_chipset.c new file mode 100644 index 00000000..145be057 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f4/vector_chipset.c @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +static void pre_main(void) +{ + /* Enable access to Floating-Point coprocessor. */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/Makefile new file mode 100644 index 00000000..97c31d6a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/Makefile @@ -0,0 +1,76 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2013 Alexandru Gagniuc +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32f7 +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar + +# STM32F7 only supports single precision FPU +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv5-sp-d16 + +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m7 -mthumb $(FP_FLAGS) \ + -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F7 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) + +ARFLAGS = rcs + +OBJS = pwr.o rcc.o gpio.o gpio_common_all.o gpio_common_f0234.o + +OBJS += rcc_common_all.o flash_common_f234.o flash_common_f24.o + +OBJS += rng_common_v1.o + +VPATH += ../../usb:../:../../cm3:../common +VPATH += ../../ethernet + +############################################################################### +# Checking CPU support in the toolchain +############################################################################### +# TODO: This check and silent skip of build should be removed, when it will be +# sure that first compatible toolchain (g-a-e 4.8 2014q3) will be sufficiently +# penetrated in majority of user stations. +define MISSING_CPU +Your toolchain doesn't support -mcpu=cortex-m7. +Please use gcc-arm-embedded 4.8 2014q3 or newer. Skipping this sub-library. +endef + +ifneq ($(shell $(CC) --help=target | grep -q '\'; echo $$?),0) + $(warning $(MISSING_CPU)) + +all clean: + @true + +$(SRCLIBDIR)/$(LIBNAME).a: + @true + +else + include ../../Makefile.include +endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/gpio.c new file mode 100644 index 00000000..a5fb4afc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/gpio.c @@ -0,0 +1,31 @@ +/** @defgroup gpio_file GPIO + +@ingroup STM32F7xx + +@brief libopencm3 STM32F7xx General Purpose I/O + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/libopencm3_stm32f7.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/libopencm3_stm32f7.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/libopencm3_stm32f7.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/pwr.c new file mode 100644 index 00000000..93bb845d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/pwr.c @@ -0,0 +1,66 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32F7xx + * + * @brief libopencm3 STM32F7xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2011 Stephen Caudle + * @author @htmlonly © @endhtmlonly 2017 Matthew Lai + * + * @date 12 March 2017 + * + * This library supports the power control system for the + * STM32F7 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle + * Copyright (C) 2017 Matthew Lai + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void pwr_set_vos_scale(enum pwr_vos_scale scale) +{ + PWR_CR1 &= ~PWR_CR1_VOS_MASK; + + if (scale == PWR_SCALE1) { + PWR_CR1 |= PWR_CR1_VOS_SCALE_1; + } else if (scale == PWR_SCALE2) { + PWR_CR1 |= PWR_CR1_VOS_SCALE_2; + } else if (scale == PWR_SCALE3) { + PWR_CR1 |= PWR_CR1_VOS_SCALE_3; + } +} + +void pwr_enable_overdrive(void) +{ + PWR_CR1 |= PWR_CR1_ODEN; + while (!(PWR_CSR1 & PWR_CSR1_ODRDY)); + PWR_CR1 |= PWR_CR1_ODSWEN; + while (!(PWR_CSR1 & PWR_CSR1_ODSWRDY)); +} + +void pwr_disable_overdrive(void) +{ + PWR_CR1 &= ~(PWR_CR1_ODEN | PWR_CR1_ODSWEN); + while (!(PWR_CSR1 & PWR_CSR1_ODSWRDY)); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/rcc.c new file mode 100644 index 00000000..4ef198e8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/rcc.c @@ -0,0 +1,345 @@ +#include +#include +#include +#include + +uint32_t rcc_ahb_frequency = 16000000; +uint32_t rcc_apb1_frequency = 16000000; +uint32_t rcc_apb2_frequency = 16000000; + +const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 216MHz */ + .pllm = 25, + .plln = 432, + .pllp = 2, + .pllq = 9, + .flash_config = FLASH_ACR_ICEN | FLASH_ACR_DCEN | + FLASH_ACR_LATENCY_7WS, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .vos_scale = PWR_SCALE1, + .overdrive = 1, + .apb1_frequency = 108000000, + .apb2_frequency = 216000000, + }, +}; + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case RCC_HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case RCC_HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case RCC_LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case RCC_LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + } + + cm3_assert_not_reached(); +} + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while ((RCC_CR & RCC_CR_PLLRDY) == 0); + break; + case RCC_HSE: + while ((RCC_CR & RCC_CR_HSERDY) == 0); + break; + case RCC_HSI: + while ((RCC_CR & RCC_CR_HSIRDY) == 0); + break; + case RCC_LSE: + while ((RCC_BDCR & RCC_BDCR_LSERDY) == 0); + break; + case RCC_LSI: + while ((RCC_CSR & RCC_CSR_LSIRDY) == 0); + break; + } +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_PLL); + break; + case RCC_HSE: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSE); + break; + case RCC_HSI: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSI); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +void rcc_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_SW_MASK << RCC_CFGR_SW_SHIFT); + RCC_CFGR = (reg32 | (clk << RCC_CFGR_SW_SHIFT)); +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_PLLCFGR; + reg32 &= ~(1 << 22); + RCC_PLLCFGR = (reg32 | (pllsrc << 22)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE2_MASK << RCC_CFGR_PPRE2_SHIFT); + RCC_CFGR = (reg32 | (ppre2 << RCC_CFGR_PPRE2_SHIFT)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE1_MASK << RCC_CFGR_PPRE1_SHIFT); + RCC_CFGR = (reg32 | (ppre1 << RCC_CFGR_PPRE1_SHIFT)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_HPRE_MASK << RCC_CFGR_HPRE_SHIFT); + RCC_CFGR = (reg32 | (hpre << RCC_CFGR_HPRE_SHIFT)); +} + +void rcc_set_rtcpre(uint32_t rtcpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_RTCPRE_MASK << RCC_CFGR_RTCPRE_SHIFT); + RCC_CFGR = (reg32 | (rtcpre << RCC_CFGR_RTCPRE_SHIFT)); +} + +void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq) +{ + RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | + (plln << RCC_PLLCFGR_PLLN_SHIFT) | + (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | + (pllq << RCC_PLLCFGR_PLLQ_SHIFT); +} + +void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq) +{ + RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | + (plln << RCC_PLLCFGR_PLLN_SHIFT) | + (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | + RCC_PLLCFGR_PLLSRC | + (pllq << RCC_PLLCFGR_PLLQ_SHIFT); +} + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK; +} + + +void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_HSI); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + + rcc_periph_clock_enable(RCC_PWR); + pwr_set_vos_scale(clock->vos_scale); + + if (clock->overdrive) { + pwr_enable_overdrive(); + } + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + rcc_set_main_pll_hse(clock->pllm, clock->plln, + clock->pllp, clock->pllq); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Configure flash settings. */ + flash_set_ws(clock->flash_config); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_PLL); + + /* Wait for PLL clock to be selected. */ + rcc_wait_for_sysclk_status(RCC_PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; + + /* Disable internal high-speed oscillator. */ + rcc_osc_off(RCC_HSI); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/vector_chipset.c new file mode 100644 index 00000000..145be057 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/f7/vector_chipset.c @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +static void pre_main(void) +{ + /* Enable access to Floating-Point coprocessor. */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/Makefile new file mode 100644 index 00000000..d2a7a6b3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/Makefile @@ -0,0 +1,57 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2013 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32l0 +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m0plus $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32L0 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) + +ARFLAGS = rcs + +OBJS = gpio.o rcc.o desig.o +OBJS += pwr_common_v1.o pwr_common_v2.o +OBJS += timer_common_all.o + +OBJS += gpio_common_all.o gpio_common_f0234.o rcc_common_all.o +OBJS += adc_common_v2.o +OBJS += crs_common_all.o +OBJS += exti_common_all.o +OBJS += flash.o flash_common_l01.o +OBJS += i2c_common_v2.o +OBJS += rng_common_v1.o + +OBJS += usb.o usb_control.o usb_standard.o +OBJS += st_usbfs_core.o st_usbfs_v2.o + +VPATH += ../../usb:../:../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/flash.c new file mode 100644 index 00000000..b1ba6420 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/flash.c @@ -0,0 +1,27 @@ +/** @defgroup gpio_file GPIO + * + * @ingroup STM32L0xx + * + * @brief libopencm3 STM32L0xx General Purpose I/O + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/gpio.c new file mode 100644 index 00000000..9382ece2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/gpio.c @@ -0,0 +1,31 @@ +/** @defgroup gpio_file GPIO + * + * @ingroup STM32L0xx + * + * @brief libopencm3 STM32L0xx General Purpose I/O + * + * @version 1.0.0 + * + * @date 8 September 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/i2c.c new file mode 100644 index 00000000..0880f4d0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/i2c.c @@ -0,0 +1,32 @@ +/** @defgroup i2c_file I2C + * + * @ingroup STM32L0xx + * + * @brief libopencm3 STM32L0xx I2C + * + * @version 1.0.0 + * + * @date 1 December 2016 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/libopencm3_stm32l0.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/libopencm3_stm32l0.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/libopencm3_stm32l0.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rcc.c new file mode 100644 index 00000000..d851c39a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rcc.c @@ -0,0 +1,423 @@ +/** @defgroup STM32L0xx-rcc-file RCC + * + * @ingroup STM32L0xx + * + * @brief libopencm3 STM32L0xx Reset and Clock Control + * + * @version 1.0.0 + * + * @date November 2014 + * + * This library supports the Reset and Clock Control System in the STM32F0xx + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include +#include +#include + +/* Set the default clock frequencies after reset. */ +uint32_t rcc_ahb_frequency = 2097000; +uint32_t rcc_apb1_frequency = 2097000; +uint32_t rcc_apb2_frequency = 2097000; + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_MSI: + RCC_CR |= RCC_CR_MSION; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI48: + RCC_CRRCR |= RCC_CRRCR_HSI48ON; + break; + case RCC_HSI16: + RCC_CR |= RCC_CR_HSI16ON; + break; + case RCC_LSE: + RCC_CSR |= RCC_CSR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_MSI: + RCC_CR &= ~RCC_CR_MSION; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI48: + RCC_CRRCR &= ~RCC_CRRCR_HSI48ON; + break; + case RCC_HSI16: + RCC_CR &= ~RCC_CR_HSI16ON; + break; + case RCC_LSE: + RCC_CSR &= ~RCC_CSR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Clear the Oscillator Ready Interrupt Flag + * + * Clear the interrupt flag that was set when a clock oscillator became ready + * to use. + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CICR |= RCC_CICR_PLLRDYC; + break; + case RCC_HSE: + RCC_CICR |= RCC_CICR_HSERDYC; + break; + case RCC_HSI48: + RCC_CICR |= RCC_CICR_HSI48RDYC; + break; + case RCC_HSI16: + RCC_CICR |= RCC_CICR_HSI16RDYC; + break; + case RCC_MSI: + RCC_CICR |= RCC_CICR_MSIRDYC; + break; + case RCC_LSE: + RCC_CICR |= RCC_CICR_LSERDYC; + break; + case RCC_LSI: + RCC_CICR |= RCC_CICR_LSIRDYC; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the Oscillator Ready Interrupt + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIER |= RCC_CIER_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIER |= RCC_CIER_HSERDYIE; + break; + case RCC_HSI48: + RCC_CIER |= RCC_CIER_HSI48RDYIE; + break; + case RCC_HSI16: + RCC_CIER |= RCC_CIER_HSI16RDYIE; + break; + case RCC_MSI: + RCC_CIER |= RCC_CIER_MSIRDYIE; + break; + case RCC_LSE: + RCC_CIER |= RCC_CIER_LSERDYIE; + break; + case RCC_LSI: + RCC_CIER |= RCC_CIER_LSIRDYIE; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the Oscillator Ready Interrupt + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIER &= ~RCC_CIER_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIER &= ~RCC_CIER_HSERDYIE; + break; + case RCC_HSI48: + RCC_CIER &= ~RCC_CIER_HSI48RDYIE; + break; + case RCC_HSI16: + RCC_CIER &= ~RCC_CIER_HSI16RDYIE; + break; + case RCC_MSI: + RCC_CIER &= ~RCC_CIER_MSIRDYIE; + break; + case RCC_LSE: + RCC_CIER &= ~RCC_CIER_LSERDYIE; + break; + case RCC_LSI: + RCC_CIER &= ~RCC_CIER_LSIRDYIE; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Read the Oscillator Ready Interrupt Flag + * + * @param[in] osc enum ::osc_t. Oscillator ID + * @returns int. Boolean value for flag set. + */ +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIFR & RCC_CIFR_PLLRDYF) != 0); + break; + case RCC_HSE: + return ((RCC_CIFR & RCC_CIFR_HSERDYF) != 0); + break; + case RCC_HSI48: + return ((RCC_CIFR & RCC_CIFR_HSI48RDYF) != 0); + break; + case RCC_HSI16: + return ((RCC_CIFR & RCC_CIFR_HSI16RDYF) != 0); + break; + case RCC_MSI: + return ((RCC_CIFR & RCC_CIFR_MSIRDYF) != 0); + break; + case RCC_LSE: + return ((RCC_CIFR & RCC_CIFR_LSERDYF) != 0); + break; + case RCC_LSI: + return ((RCC_CIFR & RCC_CIFR_LSIRDYF) != 0); + break; + } + + cm3_assert_not_reached(); +} + + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI16: + return RCC_CR & RCC_CR_HSI16RDY; + case RCC_HSI48: + return RCC_CRRCR & RCC_CRRCR_HSI48RDY; + case RCC_MSI: + return RCC_CR & RCC_CR_MSIRDY; + case RCC_LSE: + return RCC_CSR & RCC_CSR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set HSI48 clock source to the RC48 (CRS) + */ +void rcc_set_hsi48_source_rc48(void) +{ + RCC_CCIPR |= RCC_CCIPR_HSI48SEL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set HSI48 clock source to the PLL + */ +void rcc_set_hsi48_source_pll(void) +{ + RCC_CCIPR &= ~RCC_CCIPR_HSI48SEL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the System Clock. + * + * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE, HSI16, MSI and PLL have + * effect. + */ + +void rcc_set_sysclk_source(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CFGR |= RCC_CFGR_SW_PLL; + break; + case RCC_HSE: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW_MASK) | RCC_CFGR_SW_HSE; + break; + case RCC_HSI16: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW_MASK) | RCC_CFGR_SW_HSI16; + break; + case RCC_MSI: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW_MASK) | RCC_CFGR_SW_MSI; + break; + case RCC_HSI48: + case RCC_LSE: + case RCC_LSI: + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Multiplication Factor. + * + * @note This only has effect when the PLL is disabled. + * + * @param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf + */ + +void rcc_set_pll_multiplier(uint32_t factor) +{ + uint32_t reg = RCC_CFGR + & ~(RCC_CFGR_PLLMUL_MASK << RCC_CFGR_PLLMUL_SHIFT); + RCC_CFGR = reg | (factor << RCC_CFGR_PLLMUL_SHIFT); +} + + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Division Factor. + * + * @note This only has effect when the PLL is disabled. + * + * @param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pdf + */ + +void rcc_set_pll_divider(uint32_t factor) +{ + uint32_t reg = RCC_CFGR + & ~(RCC_CFGR_PLLDIV_MASK << RCC_CFGR_PLLDIV_SHIFT); + RCC_CFGR = reg | (factor << RCC_CFGR_PLLDIV_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the APB1 Prescale Factor. + * + * @note The APB1 clock frequency must not exceed 32MHz. + * + * @param[in] ppre1 Unsigned int32. APB prescale factor @ref rcc_cfgr_apb1pre + */ + +void rcc_set_ppre1(uint32_t ppre) +{ + uint32_t reg = RCC_CFGR + & ~(RCC_CFGR_PPRE1_MASK << RCC_CFGR_PPRE1_SHIFT); + RCC_CFGR = reg | (ppre << RCC_CFGR_PPRE1_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the APB2 Prescale Factor. + * + * @note The APB2 clock frequency must not exceed 32MHz. + * + * @param[in] ppre1 Unsigned int32. APB prescale factor @ref rcc_cfgr_apb2pre + */ + +void rcc_set_ppre2(uint32_t ppre) +{ + uint32_t reg = RCC_CFGR + & ~(RCC_CFGR_PPRE2_MASK << RCC_CFGR_PPRE2_SHIFT); + RCC_CFGR = reg | (ppre << RCC_CFGR_PPRE2_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the AHB Prescale Factor. + * + * @param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre + */ + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg = RCC_CFGR & ~(RCC_CFGR_HPRE_MASK << RCC_CFGR_HPRE_SHIFT); + RCC_CFGR = reg | (hpre << RCC_CFGR_HPRE_SHIFT); +} + +/** + * Set up sysclock with PLL from HSI16 + * @param clock full struct with desired parameters + */ +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) +{ + /* Turn on the appropriate source for the PLL */ + if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) { + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + } else { + rcc_osc_on(RCC_HSI16); + rcc_wait_for_osc_ready(RCC_HSI16); + } + + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + rcc_periph_clock_enable(RCC_PWR); + pwr_set_vos_scale(clock->voltage_scale); + + rcc_osc_off(RCC_PLL); + while (rcc_is_osc_ready(RCC_PLL)); + + flash_prefetch_enable(); + flash_set_ws(clock->flash_waitstates); + + /* Set up the PLL */ + rcc_set_pll_multiplier(clock->pll_mul); + rcc_set_pll_divider(clock->pll_div); + + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + rcc_set_sysclk_source(RCC_PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rng.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rng.c new file mode 100644 index 00000000..cae99c74 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/rng.c @@ -0,0 +1,31 @@ +/* This file is used for documentation purposes. It does not need +to be compiled. All source code is in the common area. +If there is any device specific code required it can be included here, +in which case this file must be added to the compile list. */ + +/** @defgroup rng_file RNG + +@ingroup STM32L0xx + +@brief libopencm3 STM32L0xx RNG + +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx6.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx6.ld new file mode 100644 index 00000000..bdb5fc16 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx6.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L0xx6, 32K flash, 8K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K + eep (r) : ORIGIN = 0x08080000, LENGTH = 2K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx8.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx8.ld new file mode 100644 index 00000000..948a26d3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l0/stm32l0xx8.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L0xx8, 64K flash, 8K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K + eep (r) : ORIGIN = 0x08080000, LENGTH = 2K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l0.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/Makefile new file mode 100644 index 00000000..3ca80605 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/Makefile @@ -0,0 +1,57 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32l1 +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32L1 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = crc.o desig.o flash.o rcc.o usart.o dma.o lcd.o +OBJS += crc_common_all.o dac_common_all.o +OBJS += dma_common_l1f013.o +OBJS += flash_common_l01.o +OBJS += gpio_common_all.o gpio_common_f0234.o +OBJS += i2c_common_v1.o iwdg_common_all.o +OBJS += pwr_common_v1.o pwr_common_v2.o rtc_common_l1f024.o +OBJS += spi_common_all.o spi_common_l1f124.o timer_common_all.o +OBJS += usart_common_all.o usart_common_f124.o +OBJS += exti_common_all.o +OBJS += rcc_common_all.o +OBJS += adc.o adc_common_v1.o + +OBJS += usb.o usb_control.o usb_standard.o +OBJS += st_usbfs_core.o st_usbfs_v1.o + +VPATH += ../../usb:../:../../cm3:../common + +include ../../Makefile.include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/adc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/adc.c new file mode 100644 index 00000000..b3ca8a68 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/adc.c @@ -0,0 +1,201 @@ +/** @defgroup adc_file ADC + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx Analog to Digital Converters + +@author @htmlonly © @endhtmlonly 2014 Karl Palsson + + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Power On + +If the ADC is in power-down mode then it is powered up. The application needs +to wait a time of about 3 microseconds for stabilization before using the ADC. +If the ADC is already on this function call will have no effect. + * NOTE Common with F4 and F2 + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_power_on(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_ADON; +} + + +/*----------------------------------------------------------------------------*/ + +/** @brief ADC Set the Sample Time for a Single Channel + +The sampling time can be selected in ADC clock cycles from 4 to 384. + +@param[in] adc Unsigned int32. ADC block base address @ref adc_reg_base. +@param[in] channel uint8. ADC Channel integer 0..18 or from @ref adc_channel. +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg. + */ +void adc_set_sample_time(uint32_t adc, uint8_t channel, uint8_t time) +{ + uint32_t reg32; + + if (channel < 10) { + reg32 = ADC_SMPR3(adc); + reg32 &= ~(0x7 << (channel * 3)); + reg32 |= (time << (channel * 3)); + ADC_SMPR3(adc) = reg32; + } else if (channel < 20) { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0x7 << ((channel - 10) * 3)); + reg32 |= (time << ((channel - 10) * 3)); + ADC_SMPR2(adc) = reg32; + } else { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0x7 << ((channel - 20) * 3)); + reg32 |= (time << ((channel - 20) * 3)); + ADC_SMPR1(adc) = reg32; + } +} + +/*----------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for All Channels + +The sampling time can be selected in ADC clock cycles, same for +all channels. + +@param[in] adc Unsigned int32. ADC block base address @ref adc_reg_base. +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg. +*/ + +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time) +{ + uint8_t i; + uint32_t reg32 = 0; + + for (i = 0; i <= 9; i++) { + reg32 |= (time << (i * 3)); + } + ADC_SMPR0(adc) = reg32; + ADC_SMPR1(adc) = reg32; + ADC_SMPR2(adc) = reg32; + ADC_SMPR3(adc) = reg32; +} + +/*----------------------------------------------------------------------------*/ +/** @brief ADC Enable The Temperature Sensor + +This enables both the sensor and the reference voltage measurements on channels +16 and 17. + +*/ +void adc_enable_temperature_sensor() +{ + ADC_CCR |= ADC_CCR_TSVREFE; +} + +/*----------------------------------------------------------------------------*/ +/** @brief ADC Disable The Temperature Sensor + +Disabling this will reduce power consumption from the sensor and the reference +voltage measurements. + +*/ +void adc_disable_temperature_sensor() +{ + ADC_CCR &= ~ADC_CCR_TSVREFE; +} + +/*----------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_external_trigger_regular(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EXTEN_MASK; +} + +/*----------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + +@param[in] adc Unsigned int32. ADC block base address @ref adc_reg_base. +*/ + +void adc_disable_external_trigger_injected(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_JEXTEN_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + +This enables an external trigger for set of defined regular channels, and sets +the polarity of the trigger event: rising or falling edge or both. Note that if +the trigger polarity is zero, triggering is disabled. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int32. Trigger identifier @ref adc_trigger_regular +@param[in] polarity Unsigned int32. Trigger polarity @ref +adc_trigger_polarity_regular +*/ + +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_EXTSEL_MASK | ADC_CR2_EXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + +This enables an external trigger for set of defined injected channels, and sets +the polarity of the trigger event: rising or falling edge or both. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected +@param[in] polarity Unsigned int32. Trigger polarity @ref +adc_trigger_polarity_injected +*/ + +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_JEXTSEL_MASK | ADC_CR2_JEXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/**@}*/ + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/crc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/crc.c new file mode 100644 index 00000000..8a71c899 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/crc.c @@ -0,0 +1,33 @@ +/** @defgroup crc_file CRC + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx CRC + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dac.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dac.c new file mode 100644 index 00000000..ed118b4d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dac.c @@ -0,0 +1,31 @@ +/** @defgroup dac_file DAC + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx DAC + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dma.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dma.c new file mode 100644 index 00000000..6f4622d2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/dma.c @@ -0,0 +1,31 @@ +/** @defgroup dma_file DMA + * + * @ingroup STM32L1xx + * + * @brief libopencm3 STM32L1xx DMA + * + * @version 1.0.0 + * + * @date 10 July 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/flash.c new file mode 100644 index 00000000..5e176b05 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/flash.c @@ -0,0 +1,74 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32L1xx + * + * @brief libopencm3 STM32L1xx FLASH + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * @author @htmlonly © @endhtmlonly 2012 + * Karl Palsson + * + * @date 14 January 2014 + * + * For the STM32L1xx, accessing FLASH memory is described briefly in + * section 2.3.3 of the STM32L1xx Reference Manual. + * For detailed programming information see: + * PM0062 programming manual: STM32L1xxxx Flash and EEPROM programming + * March 2012, Doc ID 16024 Rev 5 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * Copyright (C) 2012-13 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Enable 64 Bit Programming Mode + +*/ + +void flash_64bit_enable(void) +{ + FLASH_ACR |= FLASH_ACR_ACC64; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable 32 Bit Programming Mode + +This mode is a low power mode. It must be used at low frequencies and does not +allow prefetch or wait states to be used. +*/ + +void flash_64bit_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_ACC64; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/gpio.c new file mode 100644 index 00000000..46ea658a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/gpio.c @@ -0,0 +1,31 @@ +/** @defgroup gpio_file GPIO + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx General Purpose I/O + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/i2c.c new file mode 100644 index 00000000..2390c968 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/i2c.c @@ -0,0 +1,31 @@ +/** @defgroup i2c_file I2C + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx I2C + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/iwdg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/iwdg.c new file mode 100644 index 00000000..1f37fe88 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/iwdg.c @@ -0,0 +1,31 @@ +/** @defgroup iwdg_file IWDG + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx Independent Watchdog Timer + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/lcd.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/lcd.c new file mode 100644 index 00000000..68173ab8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/lcd.c @@ -0,0 +1,154 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Nikolay Merinov + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +void lcd_enable(void) +{ + LCD_CR |= LCD_CR_LCDEN; +} + +void lcd_update(void) +{ + LCD_SR |= LCD_SR_UDR; +} + +void lcd_wait_for_lcd_enabled(void) +{ + while ((LCD_SR & LCD_SR_ENS) == 0); +} + +void lcd_wait_for_step_up_ready(void) +{ + while ((LCD_SR & LCD_SR_RDY) == 0); +} + +void lcd_wait_for_update_ready(void) +{ + while ((LCD_SR & LCD_SR_UDR) != 0); +} + +int lcd_is_enabled(void) +{ + return ((LCD_SR & LCD_SR_ENS) != 0); +} + +int lcd_is_step_up_ready(void) +{ + return ((LCD_SR & LCD_SR_RDY) != 0); +} + +int lcd_is_for_update_ready(void) +{ + return ((LCD_SR & LCD_SR_UDR) == 0); +} + +void lcd_set_contrast(uint8_t contrast) +{ + LCD_FCR &= ~(LCD_FCR_CC_MASK << LCD_FCR_CC_SHIFT); + LCD_FCR |= contrast << LCD_FCR_CC_SHIFT; +} + +void lcd_set_bias(uint8_t bias) +{ + LCD_CR &= ~(LCD_CR_BIAS_MASK << LCD_CR_BIAS_SHIFT); + LCD_CR |= bias << LCD_CR_BIAS_SHIFT; +} + +void lcd_set_duty(uint8_t duty) +{ + LCD_CR &= ~(LCD_CR_DUTY_MASK << LCD_CR_DUTY_SHIFT); + LCD_CR |= duty << LCD_CR_DUTY_SHIFT; +} + +void lcd_set_prescaler(uint8_t ps) +{ + LCD_FCR &= ~(LCD_FCR_PS_MASK << LCD_FCR_PS_SHIFT); + LCD_FCR |= ps << LCD_FCR_PS_SHIFT; +} + +void lcd_set_divider(uint8_t div) +{ + LCD_FCR &= ~(LCD_FCR_DIV_MASK << LCD_FCR_DIV_SHIFT); + LCD_FCR |= div << LCD_FCR_DIV_SHIFT; +} + +void lcd_enable_segment_multiplexing(void) +{ + LCD_CR |= LCD_CR_MUX_SEG; +} + +void lcd_disable_segment_multiplexing(void) +{ + LCD_CR &= ~LCD_CR_MUX_SEG; +} + +void lcd_set_refresh_frequency(uint32_t frequency) +{ + uint32_t duty, lcd_clock; + switch ((LCD_CR >> LCD_CR_DUTY_SHIFT) & LCD_CR_DUTY_MASK) { + case LCD_CR_DUTY_STATIC: + duty = 1; + break; + case LCD_CR_DUTY_1_2: + duty = 2; + break; + case LCD_CR_DUTY_1_3: + duty = 3; + break; + case LCD_CR_DUTY_1_4: + duty = 4; + break; + case LCD_CR_DUTY_1_8: + duty = 8; + break; + default: + /* Incorrect duty */ + return; + } + + switch ((RCC_CSR >> RCC_CSR_RTCSEL_SHIFT) & RCC_CSR_RTCSEL_MASK) { + case RCC_CSR_RTCSEL_LSE: + lcd_clock = 32786; + break; + case RCC_CSR_RTCSEL_LSI: + lcd_clock = 37000; + break; + case RCC_CSR_RTCSEL_HSI: + lcd_clock = 16000000; + break; + default: + /* RCC Clock not selected */ + return; + } + + /* PS * DIV = lcd_clock/(duty * freq) */ + uint32_t ps_mul_div = lcd_clock / (duty * frequency); + + int div, ps = 0; + while (ps_mul_div > 32) { + ps_mul_div >>= 1; + ps++; + } + div = ps_mul_div - 16; + + lcd_set_prescaler(ps); + lcd_set_divider(div); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/libopencm3_stm32l1.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/libopencm3_stm32l1.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/libopencm3_stm32l1.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rcc.c new file mode 100644 index 00000000..e9f7bd68 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rcc.c @@ -0,0 +1,554 @@ +/** @defgroup STM32L1xx-rcc-file RCC + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx Reset and Clock Control + +@version 1.0.0 + +This library supports the Reset and Clock Control System in the STM32L1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +Clock settings and resets for many peripherals are given here rather than in +the corresponding peripheral library. + +The library also provides a number of common configurations for the processor +system clock. Not all possible configurations are included. + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * Based on the F4 code... + */ +/**@{*/ + +#include +#include +#include + +/* Set the default clock frequencies after reset. */ +uint32_t rcc_ahb_frequency = 2097000; +uint32_t rcc_apb1_frequency = 2097000; +uint32_t rcc_apb2_frequency = 2097000; + +const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END] = { + { /* 24MHz PLL from HSI */ + .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, + .pll_mul = RCC_CFGR_PLLMUL_MUL3, + .pll_div = RCC_CFGR_PLLDIV_DIV2, + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_waitstates = 1, + .ahb_frequency = 24000000, + .apb1_frequency = 24000000, + .apb2_frequency = 24000000, + }, + { /* 32MHz PLL from HSI */ + .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, + .pll_mul = RCC_CFGR_PLLMUL_MUL6, + .pll_div = RCC_CFGR_PLLDIV_DIV3, + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_waitstates = 1, + .ahb_frequency = 32000000, + .apb1_frequency = 32000000, + .apb2_frequency = 32000000, + }, + { /* 16MHz HSI raw */ + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_waitstates = 0, + .ahb_frequency = 16000000, + .apb1_frequency = 16000000, + .apb2_frequency = 16000000, + }, + { /* 4MHz HSI raw */ + .hpre = RCC_CFGR_HPRE_SYSCLK_DIV4, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_waitstates = 0, + .ahb_frequency = 4000000, + .apb1_frequency = 4000000, + .apb2_frequency = 4000000, + }, + { /* 4MHz MSI raw */ + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_waitstates = 0, + .ahb_frequency = 4194000, + .apb1_frequency = 4194000, + .apb2_frequency = 4194000, + .msi_range = RCC_ICSCR_MSIRANGE_4MHZ, + }, + { /* 2MHz MSI raw */ + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_waitstates = 0, + .ahb_frequency = 2097000, + .apb1_frequency = 2097000, + .apb2_frequency = 2097000, + .msi_range = RCC_ICSCR_MSIRANGE_2MHZ, + }, +}; + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + case RCC_MSI: + RCC_CIR |= RCC_CIR_MSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + case RCC_MSI: + RCC_CIR |= RCC_CIR_MSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case RCC_HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case RCC_LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + case RCC_MSI: + RCC_CIR &= ~RCC_CIR_MSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case RCC_HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case RCC_HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case RCC_LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case RCC_LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + case RCC_MSI: + return ((RCC_CIR & RCC_CIR_MSIRDYF) != 0); + break; + } + + /* Shouldn't be reached. */ + return -1; +} + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_MSI: + return RCC_CR & RCC_CR_MSIRDY; + case RCC_LSE: + return RCC_CSR & RCC_CSR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_SYSCLKSEL_PLLCLK); + break; + case RCC_HSE: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_SYSCLKSEL_HSECLK); + break; + case RCC_HSI: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_SYSCLKSEL_HSICLK); + break; + case RCC_MSI: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_SYSCLKSEL_MSICLK); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_MSI: + RCC_CR |= RCC_CR_MSION; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_LSE: + RCC_CSR |= RCC_CSR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_MSI: + RCC_CR &= ~RCC_CR_MSION; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_LSE: + RCC_CSR &= ~RCC_CSR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +/** + * Set the range of the MSI oscillator + * @param range desired range @ref rcc_icscr_msirange + */ +void rcc_set_msi_range(uint32_t range) +{ + uint32_t reg = RCC_ICSCR; + reg &= ~(RCC_ICSCR_MSIRANGE_MASK << RCC_ICSCR_MSIRANGE_SHIFT); + reg |= (range << RCC_ICSCR_MSIRANGE_SHIFT); + RCC_ICSCR = reg; +} + +void rcc_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_SW_MASK << RCC_CFGR_SW_SHIFT); + RCC_CFGR = (reg32 | clk << RCC_CFGR_SW_SHIFT); +} + +void rcc_set_pll_configuration(uint32_t source, uint32_t multiplier, + uint32_t divisor) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PLLDIV_MASK << RCC_CFGR_PLLDIV_SHIFT); + reg32 &= ~(RCC_CFGR_PLLMUL_MASK << RCC_CFGR_PLLMUL_SHIFT); + reg32 &= ~(1 << 16); + reg32 |= (source << 16); + reg32 |= (multiplier << RCC_CFGR_PLLMUL_SHIFT); + reg32 |= (divisor << RCC_CFGR_PLLDIV_SHIFT); + RCC_CFGR = reg32; +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(1 << 16); + RCC_CFGR = (reg32 | (pllsrc << 16)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE2_MASK << RCC_CFGR_PPRE2_SHIFT); + RCC_CFGR = (reg32 | (ppre2 << RCC_CFGR_PPRE2_SHIFT)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE1_MASK << RCC_CFGR_PPRE1_SHIFT); + RCC_CFGR = (reg32 | (ppre1 << RCC_CFGR_PPRE1_SHIFT)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_HPRE_MASK << RCC_CFGR_HPRE_SHIFT); + RCC_CFGR = (reg32 | (hpre << RCC_CFGR_HPRE_SHIFT)); +} + +void rcc_set_rtcpre(uint32_t rtcpre) +{ + uint32_t reg32; + + reg32 = RCC_CR; + reg32 &= ~(RCC_CR_RTCPRE_MASK << RCC_CR_RTCPRE_SHIFT); + RCC_CR = (reg32 | (rtcpre << RCC_CR_RTCPRE_SHIFT)); +} + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR & 0x000c) >> 2; +} + +void rcc_rtc_select_clock(uint32_t clock) +{ + RCC_CSR &= ~(RCC_CSR_RTCSEL_MASK << RCC_CSR_RTCSEL_SHIFT); + RCC_CSR |= (clock << RCC_CSR_RTCSEL_SHIFT); +} + +void rcc_clock_setup_msi(const struct rcc_clock_scale *clock) +{ + /* Enable internal multi-speed oscillator. */ + rcc_set_msi_range(clock->msi_range); + rcc_osc_on(RCC_MSI); + rcc_wait_for_osc_ready(RCC_MSI); + + /* Select MSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_MSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + rcc_periph_clock_enable(RCC_PWR); + pwr_set_vos_scale(clock->voltage_scale); + + /* I guess this should be in the settings? */ + flash_64bit_enable(); + flash_prefetch_enable(); + flash_set_ws(clock->flash_waitstates); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; +} + + +/** + * Switch sysclock to HSI with the given parameters. + * This should be usable from any point in time, but only if you have used + * library functions to manage clocks. It relies on the global + * @ref rcc_ahb_frequency to ensure that it reliably scales voltage up or down + * as appropriate. + * @param clock full struct with desired parameters + */ +void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(RCC_HSI); + rcc_periph_clock_enable(RCC_PWR); + + /* I guess this should be in the settings? */ + flash_64bit_enable(); + flash_prefetch_enable(); + + /* Don't try and go to fast for a voltage range! */ + if (clock->ahb_frequency > rcc_ahb_frequency) { + /* Going up, power up first */ + pwr_set_vos_scale(clock->voltage_scale); + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + flash_set_ws(clock->flash_waitstates); + } else { + /* going down, slow down before cutting power */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + flash_set_ws(clock->flash_waitstates); + pwr_set_vos_scale(clock->voltage_scale); + } + + rcc_wait_for_osc_ready(RCC_HSI); + while (PWR_CSR & PWR_CSR_VOSF) { + ; + } + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; +} + +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) +{ + /* Turn on the appropriate source for the PLL */ + if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) { + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + } else { + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + } + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + rcc_periph_clock_enable(RCC_PWR); + pwr_set_vos_scale(clock->voltage_scale); + + /* I guess this should be in the settings? */ + flash_64bit_enable(); + flash_prefetch_enable(); + flash_set_ws(clock->flash_waitstates); + + rcc_set_pll_configuration(clock->pll_source, clock->pll_mul, + clock->pll_div); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rtc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rtc.c new file mode 100644 index 00000000..5628aa7e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/rtc.c @@ -0,0 +1,31 @@ +/** @defgroup rtc_file RTC + * + * @ingroup STM32L1xx + * + * @brief libopencm3 STM32L1xx RTC + * + * @version 1.0.0 + * + * @date 4 March 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/spi.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/spi.c new file mode 100644 index 00000000..05969fb8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/spi.c @@ -0,0 +1,31 @@ +/** @defgroup spi_file SPI + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx SPI + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l100xc.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l100xc.ld new file mode 100644 index 00000000..55476200 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l100xc.ld @@ -0,0 +1,33 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Karl Palsson + * Copyright (C) 2015 Joost Rijneveld + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L100xC, 256K flash, 16K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K + eep (r) : ORIGIN = 0x08080000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx6.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx6.ld new file mode 100644 index 00000000..a72a5d8a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx6.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L15xx6, 32K flash, 10K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K + eep (r) : ORIGIN = 0x08080000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx8.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx8.ld new file mode 100644 index 00000000..656779be --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xx8.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L15xx8, 64K flash, 10K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K + eep (r) : ORIGIN = 0x08080000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxb.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxb.ld new file mode 100644 index 00000000..be81f37e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxb.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L15xxB, 128K flash, 16K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K + eep (r) : ORIGIN = 0x08080000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxc.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxc.ld new file mode 100644 index 00000000..651aed39 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxc.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L15xxC, 256k flash, 32K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K + eep (r) : ORIGIN = 0x08080000, LENGTH = 8K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxd.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxd.ld new file mode 100644 index 00000000..4b93c9b1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/stm32l15xxd.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32L15xxD, 384K flash, 38K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K + eep (r) : ORIGIN = 0x08080000, LENGTH = 12K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/timer.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/timer.c new file mode 100644 index 00000000..ab69c622 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/timer.c @@ -0,0 +1,59 @@ +/** @defgroup timer_file Timers + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx Timers + +@version 1.0.0 + +@date 18 August 2012 + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Option + +Set timer options register on TIM2 or TIM3, used for trigger remapping. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@returns Unsigned int32. Option flags TIM2: @ref tim2_opt_trigger_remap, TIM3: +@ref tim3_opt_trigger_remap. +*/ + +void timer_set_option(uint32_t timer_peripheral, uint32_t option) +{ + if (timer_peripheral == TIM2) { + TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK; + TIM_OR(timer_peripheral) |= option; + } else if (timer_peripheral == TIM3) { + TIM_OR(timer_peripheral) &= ~TIM3_OR_ITR2_RMP_MASK; + TIM_OR(timer_peripheral) |= option; + } +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/usart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/usart.c new file mode 100644 index 00000000..5e357bfe --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l1/usart.c @@ -0,0 +1,31 @@ +/** @defgroup usart_file USART + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx USART + +@version 1.0.0 + +@date 30 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/Makefile new file mode 100644 index 00000000..4c63b1cb --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/Makefile @@ -0,0 +1,54 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2015 Karl Palsson +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32l4 +SRCLIBDIR ?= ../.. + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m4 -mthumb $(FP_FLAGS) \ + -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32L4 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +ARFLAGS = rcs + +# Specific objs +OBJS = adc.o flash.o pwr.o rcc.o + +# common/shared objs +OBJS += rcc_common_all.o +OBJS += gpio_common_all.o gpio_common_f0234.o +OBJS += adc_common_v2.o adc_common_v2_multi.o +OBJS += rng_common_v1.o +OBJS += timer_common_all.o +OBJS += i2c_common_v2.o + +VPATH += ../../usb:../:../../cm3:../common +VPATH += ../../ethernet + +include ../../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/adc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/adc.c new file mode 100644 index 00000000..988d79ef --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/adc.c @@ -0,0 +1,59 @@ +/** @defgroup adc_file ADC + +@ingroup STM32L4xx + +@brief libopencm3 STM32L4xx Analog to Digital Converters + +@author @htmlonly © @endhtmlonly 2016 Karl Palsson + + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/** + * Enable the ADC Voltage regulator + * Before any use of the ADC, the ADC Voltage regulator must be enabled. + * You must wait up to 10uSecs afterwards before trying anything else. + * @param[in] adc ADC block register address base + * @sa adc_disable_regulator + */ +void adc_enable_regulator(uint32_t adc) +{ + ADC_CR(adc) |= ADC_CR_ADVREGEN; +} + +/** + * Disable the ADC Voltage regulator + * You can disable the adc vreg when not in use to save power + * @param[in] adc ADC block register address base + * @sa adc_enable_regulator + */ +void adc_disable_regulator(uint32_t adc) +{ + ADC_CR(adc) &= ~ADC_CR_ADVREGEN; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/flash.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/flash.c new file mode 100644 index 00000000..9e2878a0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/flash.c @@ -0,0 +1,344 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32L4xx + * + * @brief libopencm3 STM32L4xx FLASH + * + * @version 1.0.0 + * + * Benjamin Levine + * + * @date 12 February 2016 + * + * This library supports the FLASH memory controller in the STM32L4 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * For the STM32L4xx, accessing FLASH memory is described briefly in + * section 3 of the STM32L4x6 Reference Manual. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/** @brief Enable the FLASH Prefetch Buffer + +This buffer is used for instruction fetches and is enabled by default after +reset. + +Note carefully the clock restrictions under which the prefetch buffer may be +enabled or disabled. Changes are normally made while the clock is running in +the power-on low frequency mode before being set to a higher speed mode. +See the reference manual for details. +*/ +void flash_prefetch_enable(void) +{ + FLASH_ACR |= FLASH_ACR_PRFTEN; +} + +/** @brief Disable the FLASH Prefetch Buffer + +Note carefully the clock restrictions under which the prefetch buffer may be +set to disabled. See the reference manual for details. +*/ +void flash_prefetch_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_PRFTEN; +} + +/** @brief Set the Number of Wait States + +Used to match the system clock to the FLASH memory access time. See the +programming manual for more information on clock speed ranges. The latency must +be changed to the appropriate value before any increase in clock +speed, or after any decrease in clock speed. + +@param[in] ws values from @ref flash_latency. +*/ +void flash_set_ws(uint32_t ws) +{ + uint32_t reg32; + + reg32 = FLASH_ACR; + reg32 &= ~(FLASH_ACR_LATENCY_MASK << FLASH_ACR_LATENCY_SHIFT); + reg32 |= (ws << FLASH_ACR_LATENCY_SHIFT); + FLASH_ACR = reg32; +} + +/** @brief Unlock the Flash Program and Erase Controller + * This enables write access to the Flash memory. It is locked by default on + * reset. + */ +void flash_unlock(void) +{ + /* Clear the unlock sequence state. */ + FLASH_CR |= FLASH_CR_LOCK; + + /* Authorize the FPEC access. */ + FLASH_KEYR = FLASH_KEYR_KEY1; + FLASH_KEYR = FLASH_KEYR_KEY2; +} + +/** @brief Lock the Flash Program and Erase Controller + * Used to prevent spurious writes to FLASH. + */ +void flash_lock(void) +{ + FLASH_CR |= FLASH_CR_LOCK; +} + +/** @brief Clear the Programming Error Status Flag + */ +void flash_clear_pgperr_flag(void) +{ + FLASH_SR |= FLASH_SR_PROGERR; +} + +/** @brief Clear the End of Operation Status Flag + */ +void flash_clear_eop_flag(void) +{ + FLASH_SR |= FLASH_SR_EOP; +} + +/** @brief Clear the Busy Status Flag + */ +void flash_clear_bsy_flag(void) +{ + FLASH_SR &= ~FLASH_SR_BSY; +} + + +/** @brief Wait until Last Operation has Ended + * This loops indefinitely until an operation (write or erase) has completed + * by testing the busy flag. + */ +void flash_wait_for_last_operation(void) +{ + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); +} + +/** @brief Enable the Data Cache + */ +void flash_dcache_enable(void) +{ + FLASH_ACR |= FLASH_ACR_DCEN; +} + +/** @brief Disable the Data Cache + */ +void flash_dcache_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_DCEN; +} + +/** @brief Enable the Instruction Cache + */ +void flash_icache_enable(void) +{ + FLASH_ACR |= FLASH_ACR_ICEN; +} + +/** @brief Disable the Instruction Cache + */ +void flash_icache_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_ICEN; +} + + +/** @brief Reset the Data Cache + * The data cache must be disabled for this to have effect. + */ +void flash_dcache_reset(void) +{ + FLASH_ACR |= FLASH_ACR_DCRST; +} + +/** @brief Reset the Instruction Cache + * The instruction cache must be disabled for this to have effect. + */ +void flash_icache_reset(void) +{ + FLASH_ACR |= FLASH_ACR_ICRST; +} + +/** @brief Clear the Programming Sequence Error Flag + * This flag is set when incorrect programming configuration has been made. + */ +void flash_clear_pgserr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGSERR; +} + +/** @brief Clear the Programming Alignment Error Flag + */ +void flash_clear_pgaerr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGAERR; +} + +/** @brief Clear the Write Protect Error Flag + */ +void flash_clear_wrperr_flag(void) +{ + FLASH_SR |= FLASH_SR_WRPERR; +} + +/** @brief Clear All Status Flags + * Program error, end of operation, write protect error, busy. + */ +void flash_clear_status_flags(void) +{ + flash_clear_pgserr_flag(); + flash_clear_pgaerr_flag(); + flash_clear_wrperr_flag(); + flash_clear_pgperr_flag(); + flash_clear_eop_flag(); + flash_clear_bsy_flag(); +} + +/** @brief Unlock the Option Byte Access + * This enables write access to the option bytes. It is locked by default on + * reset. + */ +void flash_unlock_option_bytes(void) +{ + /* Clear the unlock state. */ + FLASH_CR |= FLASH_CR_OPTLOCK; + + /* Unlock option bytes. */ + FLASH_OPTKEYR = FLASH_OPTKEYR_KEY1; + FLASH_OPTKEYR = FLASH_OPTKEYR_KEY2; +} + +/** @brief Lock the Option Byte Access + * This disables write access to the option bytes. It is locked by default on + * reset. + */ +void flash_lock_option_bytes(void) +{ + FLASH_CR |= FLASH_CR_OPTLOCK; +} + +/** @brief Program a 32 bit Word to FLASH + * This performs all operations necessary to program a 32 bit word to FLASH + * memory. The program error flag should be checked separately for the event + * that memory was not properly erased. + * + * @param[in] address Starting address in Flash. + * @param[in] data word to write + */ +void flash_program_word(uint32_t address, uint32_t data) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_CR_PG; + + /* Program the word. */ + MMIO32(address) = data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_CR_PG; +} + +/** @brief Program a Data Block to FLASH + * This programs an arbitrary length data block to FLASH memory. + * The program error flag should be checked separately for the event that + * memory was not properly erased. + * @param[in] address Starting address in Flash. + * @param[in] data Pointer to start of data block. + * @param[in] len Length of data block. + */ +void flash_program(uint32_t address, uint8_t *data, uint32_t len) +{ + /* TODO: Use dword and word size program operations where possible for + * turbo speed. + */ + uint32_t i; + for (i = 0; i < len; i++) { + flash_program_word(address+i, data[i]); + } +} + +/** @brief Erase a Sector of FLASH + * This performs all operations necessary to erase a sector in FLASH memory. + * The page should be checked to ensure that it was properly erased. A sector + * must first be fully erased before attempting to program it. + * See the reference manual or the FLASH programming manual for details. + * @param[in] sector (0 - 11 for some parts, 0-23 on others) + */ +void flash_erase_sector(uint8_t sector) +{ + flash_wait_for_last_operation(); + + FLASH_CR &= ~(FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT); + FLASH_CR |= (sector & FLASH_CR_PNB_MASK) << FLASH_CR_PNB_SHIFT; + FLASH_CR |= FLASH_CR_PER; + FLASH_CR |= FLASH_CR_START; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_PER; + FLASH_CR &= ~(FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT); +} + +/** @brief Erase All FLASH + * This performs all operations necessary to erase all sectors in the FLASH + * memory. + */ +void flash_erase_all_sectors(void) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_CR_MER1 | FLASH_CR_MER2; + FLASH_CR |= FLASH_CR_START; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_MER1 & ~FLASH_CR_MER2; +} + +/** @brief Program the Option Bytes + * This performs all operations necessary to program the option bytes. + * The option bytes do not need to be erased first. + * @param[in] data value to be programmed. + */ +void flash_program_option_bytes(uint32_t data) +{ + flash_wait_for_last_operation(); + + if (FLASH_CR & FLASH_CR_OPTLOCK) { + flash_unlock_option_bytes(); + } + + FLASH_OPTR = data & ~0x3; + FLASH_OPTR |= FLASH_CR_OPTSTRT; + flash_wait_for_last_operation(); +} +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/i2c.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/i2c.c new file mode 100644 index 00000000..40df10ca --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/i2c.c @@ -0,0 +1,32 @@ +/** @defgroup i2c_file I2C + * + * @ingroup STM32L4xx + * + * @brief libopencm3 STM32L4xx I2C + * + * @version 1.0.0 + * + * @date 1 December 2016 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/libopencm3_stm32l4.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/libopencm3_stm32l4.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/libopencm3_stm32l4.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/pwr.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/pwr.c new file mode 100644 index 00000000..7bfc8361 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/pwr.c @@ -0,0 +1,55 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32L4xx + * + * @brief libopencm3 STM32L4xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2016 Benjamin Levine + * + * @date 4 March 2013 + * + * This library supports the power control system for the + * STM32L4 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ +#include + +void pwr_set_vos_scale(enum pwr_vos_scale scale) +{ + uint32_t reg32; + + reg32 = PWR_CR1; + reg32 &= ~(PWR_CR1_VOS_MASK << PWR_CR1_VOS_SHIFT); + switch (scale) { + case PWR_SCALE1: + reg32 |= (PWR_CR1_VOS_RANGE_1 << PWR_CR1_VOS_SHIFT); + break; + case PWR_SCALE2: + reg32 |= (PWR_CR1_VOS_RANGE_2 << PWR_CR1_VOS_SHIFT); + break; + } + PWR_CR1 = reg32; +} +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/rcc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/rcc.c new file mode 100644 index 00000000..3259a001 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/rcc.c @@ -0,0 +1,352 @@ +/** @defgroup rcc_file RCC + * + * @ingroup STM32L4xx + * + * @section rcc_l4_api_ex Reset and Clock Control API. + * + * @brief libopencm3 STM32L4xx Reset and Clock Control + * + * @author @htmlonly © @endhtmlonly 2016 Karl Palsson + * + * @date 12 Feb 2016 + * + * This library supports the Reset and Clock Control System in the STM32 series + * of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ +#include + +/* Set the default clock frequencies after reset. */ +uint32_t rcc_ahb_frequency = 4000000; +uint32_t rcc_apb1_frequency = 4000000; +uint32_t rcc_apb2_frequency = 4000000; + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CICR |= RCC_CICR_PLLRDYC; + break; + case RCC_HSE: + RCC_CICR |= RCC_CICR_HSERDYC; + break; + case RCC_HSI16: + RCC_CICR |= RCC_CICR_HSIRDYC; + break; + case RCC_MSI: + RCC_CICR |= RCC_CICR_MSIRDYC; + break; + case RCC_LSE: + RCC_CICR |= RCC_CICR_LSERDYC; + break; + case RCC_LSI: + RCC_CICR |= RCC_CICR_LSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIER |= RCC_CIER_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIER |= RCC_CIER_HSERDYIE; + break; + case RCC_HSI16: + RCC_CIER |= RCC_CIER_HSIRDYIE; + break; + case RCC_MSI: + RCC_CIER |= RCC_CIER_MSIRDYIE; + break; + case RCC_LSE: + RCC_CIER |= RCC_CIER_LSERDYIE; + break; + case RCC_LSI: + RCC_CIER |= RCC_CIER_LSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CIER &= ~RCC_CIER_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIER &= ~RCC_CIER_HSERDYIE; + break; + case RCC_HSI16: + RCC_CIER &= ~RCC_CIER_HSIRDYIE; + break; + case RCC_MSI: + RCC_CIER &= ~RCC_CIER_MSIRDYIE; + break; + case RCC_LSE: + RCC_CIER &= ~RCC_CIER_LSERDYIE; + break; + case RCC_LSI: + RCC_CIER &= ~RCC_CIER_LSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return ((RCC_CIFR & RCC_CIFR_PLLRDYF) != 0); + break; + case RCC_HSE: + return ((RCC_CIFR & RCC_CIFR_HSERDYF) != 0); + break; + case RCC_HSI16: + return ((RCC_CIFR & RCC_CIFR_HSIRDYF) != 0); + break; + case RCC_MSI: + return ((RCC_CIFR & RCC_CIFR_MSIRDYF) != 0); + break; + case RCC_LSE: + return ((RCC_CIFR & RCC_CIFR_LSERDYF) != 0); + break; + case RCC_LSI: + return ((RCC_CIFR & RCC_CIFR_LSIRDYF) != 0); + break; + } + return false; + +} + +void rcc_css_int_clear(void) +{ + RCC_CICR |= RCC_CICR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIFR & RCC_CIFR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI16: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_MSI: + return RCC_CR & RCC_CR_MSIRDY; + case RCC_LSE: + return RCC_BDCR & RCC_BDCR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) + != RCC_CFGR_SWS_PLL); + break; + case RCC_HSE: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) + != RCC_CFGR_SWS_HSE); + break; + case RCC_HSI16: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) + != RCC_CFGR_SWS_HSI16); + break; + case RCC_MSI: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) + != RCC_CFGR_SWS_MSI); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI16: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_MSI: + RCC_CR |= RCC_CR_MSION; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI16: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_MSI: + RCC_CR &= ~RCC_CR_MSION; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +void rcc_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_SW_MASK << RCC_CFGR_SW_SHIFT); + RCC_CFGR = (reg32 | (clk << RCC_CFGR_SW_SHIFT)); +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_PLLCFGR; + reg32 &= ~(RCC_PLLCFGR_PLLSRC_MASK << RCC_PLLCFGR_PLLSRC_SHIFT); + RCC_PLLCFGR = (reg32 | (pllsrc << RCC_PLLCFGR_PLLSRC_SHIFT)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE2_MASK << RCC_CFGR_PPRE2_SHIFT); + RCC_CFGR = (reg32 | (ppre2 << RCC_CFGR_PPRE2_SHIFT)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE1_MASK << RCC_CFGR_PPRE1_SHIFT); + RCC_CFGR = (reg32 | (ppre1 << RCC_CFGR_PPRE1_SHIFT)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_HPRE_MASK << RCC_CFGR_HPRE_SHIFT); + RCC_CFGR = (reg32 | (hpre << RCC_CFGR_HPRE_SHIFT)); +} + +void rcc_set_main_pll(uint32_t source, uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq, uint32_t pllr) +{ + RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | + (plln << RCC_PLLCFGR_PLLN_SHIFT) | + (pllp) | + (source << RCC_PLLCFGR_PLLSRC_SHIFT) | + (pllq << RCC_PLLCFGR_PLLQ_SHIFT) | + (pllr << RCC_PLLCFGR_PLLR_SHIFT) | RCC_PLLCFGR_PLLREN; +} + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK; +} + +/** + * Set the msi run time range. + * Can only be called when MSI is either OFF, or when MSI is on _and_ + * ready. (RCC_CR_MSIRDY bit). @sa rcc_set_msi_range_standby + * @param msi_range range number @ref rcc_cr_msirange + */ +void rcc_set_msi_range(uint32_t msi_range) +{ + uint32_t reg = RCC_CR; + reg &= ~(RCC_CR_MSIRANGE_MASK << RCC_CR_MSIRANGE_SHIFT); + reg |= msi_range << RCC_CR_MSIRANGE_SHIFT; + RCC_CR = reg | RCC_CR_MSIRGSEL; +} + +/** + * Set the msi range after reset/standby. + * Until MSIRGSEl bit is set, this defines the MSI range. + * Note that not all MSI range values are allowed here! + * @sa rcc_set_msi_range + * @param msi_range range number valid for post standby @ref rcc_csr_msirange + */ +void rcc_set_msi_range_standby(uint32_t msi_range) +{ + uint32_t reg = RCC_CSR; + reg &= ~(RCC_CSR_MSIRANGE_MASK << RCC_CSR_MSIRANGE_SHIFT); + reg |= msi_range << RCC_CSR_MSIRANGE_SHIFT; + RCC_CSR = reg; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/vector_chipset.c new file mode 100644 index 00000000..145be057 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/l4/vector_chipset.c @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2011 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +static void pre_main(void) +{ + /* Enable access to Floating-Point coprocessor. */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v1.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v1.c new file mode 100644 index 00000000..b6503596 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v1.c @@ -0,0 +1,86 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include "../usb/usb_private.h" +#include "common/st_usbfs_core.h" + +static usbd_device *st_usbfs_v1_usbd_init(void); + +const struct _usbd_driver st_usbfs_v1_usb_driver = { + .init = st_usbfs_v1_usbd_init, + .set_address = st_usbfs_set_address, + .ep_setup = st_usbfs_ep_setup, + .ep_reset = st_usbfs_endpoints_reset, + .ep_stall_set = st_usbfs_ep_stall_set, + .ep_stall_get = st_usbfs_ep_stall_get, + .ep_nak_set = st_usbfs_ep_nak_set, + .ep_write_packet = st_usbfs_ep_write_packet, + .ep_read_packet = st_usbfs_ep_read_packet, + .poll = st_usbfs_poll, +}; + +/** Initialize the USB device controller hardware of the STM32. */ +static usbd_device *st_usbfs_v1_usbd_init(void) +{ + rcc_periph_clock_enable(RCC_USB); + SET_REG(USB_CNTR_REG, 0); + SET_REG(USB_BTABLE_REG, 0); + SET_REG(USB_ISTR_REG, 0); + + /* Enable RESET, SUSPEND, RESUME and CTR interrupts. */ + SET_REG(USB_CNTR_REG, USB_CNTR_RESETM | USB_CNTR_CTRM | + USB_CNTR_SUSPM | USB_CNTR_WKUPM); + return &st_usbfs_dev; +} + +void st_usbfs_copy_to_pm(volatile void *vPM, const void *buf, uint16_t len) +{ + const uint16_t *lbuf = buf; + volatile uint32_t *PM = vPM; + for (len = (len + 1) >> 1; len; len--) { + *PM++ = *lbuf++; + } +} + +/** + * Copy a data buffer from packet memory. + * + * @param buf Source pointer to data buffer. + * @param vPM Destination pointer into packet memory. + * @param len Number of bytes to copy. + */ +void st_usbfs_copy_from_pm(void *buf, const volatile void *vPM, uint16_t len) +{ + uint16_t *lbuf = buf; + const volatile uint16_t *PM = vPM; + uint8_t odd = len & 1; + + for (len >>= 1; len; PM += 2, lbuf++, len--) { + *lbuf = *PM; + } + + if (odd) { + *(uint8_t *) lbuf = *(uint8_t *) PM; + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v2.c b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v2.c new file mode 100644 index 00000000..f6a41783 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/stm32/st_usbfs_v2.c @@ -0,0 +1,101 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * Copyright (C) 2014 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include "../usb/usb_private.h" +#include "common/st_usbfs_core.h" + +static usbd_device *st_usbfs_v2_usbd_init(void); + +const struct _usbd_driver st_usbfs_v2_usb_driver = { + .init = st_usbfs_v2_usbd_init, + .set_address = st_usbfs_set_address, + .ep_setup = st_usbfs_ep_setup, + .ep_reset = st_usbfs_endpoints_reset, + .ep_stall_set = st_usbfs_ep_stall_set, + .ep_stall_get = st_usbfs_ep_stall_get, + .ep_nak_set = st_usbfs_ep_nak_set, + .ep_write_packet = st_usbfs_ep_write_packet, + .ep_read_packet = st_usbfs_ep_read_packet, + .poll = st_usbfs_poll, +}; + +/** Initialize the USB device controller hardware of the STM32. */ +static usbd_device *st_usbfs_v2_usbd_init(void) +{ + rcc_periph_clock_enable(RCC_USB); + SET_REG(USB_CNTR_REG, 0); + SET_REG(USB_BTABLE_REG, 0); + SET_REG(USB_ISTR_REG, 0); + + /* Enable RESET, SUSPEND, RESUME and CTR interrupts. */ + SET_REG(USB_CNTR_REG, USB_CNTR_RESETM | USB_CNTR_CTRM | + USB_CNTR_SUSPM | USB_CNTR_WKUPM); + SET_REG(USB_BCDR_REG, USB_BCDR_DPPU); + return &st_usbfs_dev; +} + +void st_usbfs_copy_to_pm(volatile void *vPM, const void *buf, uint16_t len) +{ + /* + * This is a bytewise copy, so it always works, even on CM0(+) + * that don't support unaligned accesses. + */ + const uint8_t *lbuf = buf; + volatile uint16_t *PM = vPM; + uint32_t i; + for (i = 0; i < len; i += 2) { + *PM++ = (uint16_t)lbuf[i+1] << 8 | lbuf[i]; + } +} + +/** + * Copy a data buffer from packet memory. + * + * @param buf Destination pointer for data buffer. + * @param vPM Source pointer into packet memory. + * @param len Number of bytes to copy. + */ +void st_usbfs_copy_from_pm(void *buf, const volatile void *vPM, uint16_t len) +{ + const volatile uint16_t *PM = vPM; + uint8_t odd = len & 1; + len >>= 1; + + if (((uintptr_t) buf) & 0x01) { + for (; len; PM++, len--) { + uint16_t value = *PM; + *(uint8_t *) buf++ = value; + *(uint8_t *) buf++ = value >> 8; + } + } else { + for (; len; PM++, buf += 2, len--) { + *(uint16_t *) buf = *PM; + } + } + + if (odd) { + *(uint8_t *) buf = *(uint8_t *) PM; + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb.c new file mode 100644 index 00000000..a073bc76 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb.c @@ -0,0 +1,157 @@ +/** @defgroup usb_drivers_file Generic USB Drivers + +@ingroup USB + +@brief Generic USB Drivers + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include +#include "usb_private.h" + +usbd_device *usbd_init(const usbd_driver *driver, + const struct usb_device_descriptor *dev, + const struct usb_config_descriptor *conf, + const char **strings, int num_strings, + uint8_t *control_buffer, uint16_t control_buffer_size) +{ + usbd_device *usbd_dev; + + usbd_dev = driver->init(); + + usbd_dev->driver = driver; + usbd_dev->desc = dev; + usbd_dev->config = conf; + usbd_dev->strings = strings; + usbd_dev->num_strings = num_strings; + usbd_dev->ctrl_buf = control_buffer; + usbd_dev->ctrl_buf_len = control_buffer_size; + + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_SETUP] = + _usbd_control_setup; + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_OUT] = + _usbd_control_out; + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_IN] = + _usbd_control_in; + + int i; + for (i = 0; i < MAX_USER_SET_CONFIG_CALLBACK; i++) { + usbd_dev->user_callback_set_config[i] = NULL; + } + + return usbd_dev; +} + +void usbd_register_reset_callback(usbd_device *usbd_dev, void (*callback)(void)) +{ + usbd_dev->user_callback_reset = callback; +} + +void usbd_register_suspend_callback(usbd_device *usbd_dev, + void (*callback)(void)) +{ + usbd_dev->user_callback_suspend = callback; +} + +void usbd_register_resume_callback(usbd_device *usbd_dev, + void (*callback)(void)) +{ + usbd_dev->user_callback_resume = callback; +} + +void usbd_register_sof_callback(usbd_device *usbd_dev, void (*callback)(void)) +{ + usbd_dev->user_callback_sof = callback; +} + +void _usbd_reset(usbd_device *usbd_dev) +{ + usbd_dev->current_address = 0; + usbd_dev->current_config = 0; + usbd_ep_setup(usbd_dev, 0, USB_ENDPOINT_ATTR_CONTROL, usbd_dev->desc->bMaxPacketSize0, NULL); + usbd_dev->driver->set_address(usbd_dev, 0); + + if (usbd_dev->user_callback_reset) { + usbd_dev->user_callback_reset(); + } +} + +/* Functions to wrap the low-level driver */ +void usbd_poll(usbd_device *usbd_dev) +{ + usbd_dev->driver->poll(usbd_dev); +} + +void usbd_disconnect(usbd_device *usbd_dev, bool disconnected) +{ + /* not all drivers support disconnection */ + if (usbd_dev->driver->disconnect) { + usbd_dev->driver->disconnect(usbd_dev, disconnected); + } +} + +void usbd_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, + uint16_t max_size, usbd_endpoint_callback callback) +{ + usbd_dev->driver->ep_setup(usbd_dev, addr, type, max_size, callback); +} + +uint16_t usbd_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len) +{ + return usbd_dev->driver->ep_write_packet(usbd_dev, addr, buf, len); +} + +uint16_t usbd_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, void *buf, + uint16_t len) +{ + return usbd_dev->driver->ep_read_packet(usbd_dev, addr, buf, len); +} + +void usbd_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, uint8_t stall) +{ + usbd_dev->driver->ep_stall_set(usbd_dev, addr, stall); +} + +uint8_t usbd_ep_stall_get(usbd_device *usbd_dev, uint8_t addr) +{ + return usbd_dev->driver->ep_stall_get(usbd_dev, addr); +} + +void usbd_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak) +{ + usbd_dev->driver->ep_nak_set(usbd_dev, addr, nak); +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_control.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_control.c new file mode 100644 index 00000000..5bd45a35 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_control.c @@ -0,0 +1,320 @@ +/** @defgroup usb_control_file Generic USB Control Requests + +@ingroup USB + +@brief Generic USB Control Requests + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include +#include "usb_private.h" + +/* + * According to the USB 2.0 specification, section 8.5.3, when a control + * transfer is stalled, the pipe becomes idle. We provide one utility to stall + * a transaction to reduce boilerplate code. + */ +static void stall_transaction(usbd_device *usbd_dev) +{ + usbd_ep_stall_set(usbd_dev, 0, 1); + usbd_dev->control_state.state = IDLE; +} + +/** + * If we're replying with _some_ data, but less than the host is expecting, + * then we normally just do a short transfer. But if it's short, but a + * multiple of the endpoint max packet size, we need an explicit ZLP. + * @param len how much data we want to transfer + * @param wLength how much the host asked for + * @param ep_size + * @return + */ +static bool needs_zlp(uint16_t len, uint16_t wLength, uint8_t ep_size) +{ + if (len < wLength) { + if (len && (len % ep_size == 0)) { + return true; + } + } + return false; +} + +/* Register application callback function for handling USB control requests. */ +int usbd_register_control_callback(usbd_device *usbd_dev, uint8_t type, + uint8_t type_mask, + usbd_control_callback callback) +{ + int i; + + for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) { + if (usbd_dev->user_control_callback[i].cb) { + continue; + } + + usbd_dev->user_control_callback[i].type = type; + usbd_dev->user_control_callback[i].type_mask = type_mask; + usbd_dev->user_control_callback[i].cb = callback; + return 0; + } + + return -1; +} + +static void usb_control_send_chunk(usbd_device *usbd_dev) +{ + if (usbd_dev->desc->bMaxPacketSize0 < + usbd_dev->control_state.ctrl_len) { + /* Data stage, normal transmission */ + usbd_ep_write_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf, + usbd_dev->desc->bMaxPacketSize0); + usbd_dev->control_state.state = DATA_IN; + usbd_dev->control_state.ctrl_buf += + usbd_dev->desc->bMaxPacketSize0; + usbd_dev->control_state.ctrl_len -= + usbd_dev->desc->bMaxPacketSize0; + } else { + /* Data stage, end of transmission */ + usbd_ep_write_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf, + usbd_dev->control_state.ctrl_len); + + usbd_dev->control_state.state = + usbd_dev->control_state.needs_zlp ? + DATA_IN : LAST_DATA_IN; + usbd_dev->control_state.needs_zlp = false; + usbd_dev->control_state.ctrl_len = 0; + usbd_dev->control_state.ctrl_buf = NULL; + } +} + +static int usb_control_recv_chunk(usbd_device *usbd_dev) +{ + uint16_t packetsize = MIN(usbd_dev->desc->bMaxPacketSize0, + usbd_dev->control_state.req.wLength - + usbd_dev->control_state.ctrl_len); + uint16_t size = usbd_ep_read_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf + + usbd_dev->control_state.ctrl_len, + packetsize); + + if (size != packetsize) { + stall_transaction(usbd_dev); + return -1; + } + + usbd_dev->control_state.ctrl_len += size; + + return packetsize; +} + +static int usb_control_request_dispatch(usbd_device *usbd_dev, + struct usb_setup_data *req) +{ + int i, result = 0; + struct user_control_callback *cb = usbd_dev->user_control_callback; + + /* Call user command hook function. */ + for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) { + if (cb[i].cb == NULL) { + break; + } + + if ((req->bmRequestType & cb[i].type_mask) == cb[i].type) { + result = cb[i].cb(usbd_dev, req, + &(usbd_dev->control_state.ctrl_buf), + &(usbd_dev->control_state.ctrl_len), + &(usbd_dev->control_state.complete)); + if (result == USBD_REQ_HANDLED || + result == USBD_REQ_NOTSUPP) { + return result; + } + } + } + + /* Try standard request if not already handled. */ + return _usbd_standard_request(usbd_dev, req, + &(usbd_dev->control_state.ctrl_buf), + &(usbd_dev->control_state.ctrl_len)); +} + +/* Handle commands and read requests. */ +static void usb_control_setup_read(usbd_device *usbd_dev, + struct usb_setup_data *req) +{ + usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf; + usbd_dev->control_state.ctrl_len = req->wLength; + + if (usb_control_request_dispatch(usbd_dev, req)) { + if (req->wLength) { + usbd_dev->control_state.needs_zlp = + needs_zlp(usbd_dev->control_state.ctrl_len, + req->wLength, + usbd_dev->desc->bMaxPacketSize0); + /* Go to data out stage if handled. */ + usb_control_send_chunk(usbd_dev); + } else { + /* Go to status stage if handled. */ + usbd_ep_write_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = STATUS_IN; + } + } else { + /* Stall endpoint on failure. */ + stall_transaction(usbd_dev); + } +} + +static void usb_control_setup_write(usbd_device *usbd_dev, + struct usb_setup_data *req) +{ + if (req->wLength > usbd_dev->ctrl_buf_len) { + stall_transaction(usbd_dev); + return; + } + + /* Buffer into which to write received data. */ + usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf; + usbd_dev->control_state.ctrl_len = 0; + /* Wait for DATA OUT stage. */ + if (req->wLength > usbd_dev->desc->bMaxPacketSize0) { + usbd_dev->control_state.state = DATA_OUT; + } else { + usbd_dev->control_state.state = LAST_DATA_OUT; + } + + usbd_ep_nak_set(usbd_dev, 0, 0); +} + +/* Do not appear to belong to the API, so are omitted from docs */ +/**@}*/ + +void _usbd_control_setup(usbd_device *usbd_dev, uint8_t ea) +{ + struct usb_setup_data *req = &usbd_dev->control_state.req; + (void)ea; + + usbd_dev->control_state.complete = NULL; + + usbd_ep_nak_set(usbd_dev, 0, 1); + + if (usbd_ep_read_packet(usbd_dev, 0, req, 8) != 8) { + stall_transaction(usbd_dev); + return; + } + + if (req->wLength == 0) { + usb_control_setup_read(usbd_dev, req); + } else if (req->bmRequestType & 0x80) { + usb_control_setup_read(usbd_dev, req); + } else { + usb_control_setup_write(usbd_dev, req); + } +} + +void _usbd_control_out(usbd_device *usbd_dev, uint8_t ea) +{ + (void)ea; + + switch (usbd_dev->control_state.state) { + case DATA_OUT: + if (usb_control_recv_chunk(usbd_dev) < 0) { + break; + } + if ((usbd_dev->control_state.req.wLength - + usbd_dev->control_state.ctrl_len) <= + usbd_dev->desc->bMaxPacketSize0) { + usbd_dev->control_state.state = LAST_DATA_OUT; + } + break; + case LAST_DATA_OUT: + if (usb_control_recv_chunk(usbd_dev) < 0) { + break; + } + /* + * We have now received the full data payload. + * Invoke callback to process. + */ + if (usb_control_request_dispatch(usbd_dev, + &(usbd_dev->control_state.req))) { + /* Go to status stage on success. */ + usbd_ep_write_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = STATUS_IN; + } else { + stall_transaction(usbd_dev); + } + break; + case STATUS_OUT: + usbd_ep_read_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = IDLE; + if (usbd_dev->control_state.complete) { + usbd_dev->control_state.complete(usbd_dev, + &(usbd_dev->control_state.req)); + } + usbd_dev->control_state.complete = NULL; + break; + default: + stall_transaction(usbd_dev); + } +} + +void _usbd_control_in(usbd_device *usbd_dev, uint8_t ea) +{ + (void)ea; + struct usb_setup_data *req = &(usbd_dev->control_state.req); + + switch (usbd_dev->control_state.state) { + case DATA_IN: + usb_control_send_chunk(usbd_dev); + break; + case LAST_DATA_IN: + usbd_dev->control_state.state = STATUS_OUT; + usbd_ep_nak_set(usbd_dev, 0, 0); + break; + case STATUS_IN: + if (usbd_dev->control_state.complete) { + usbd_dev->control_state.complete(usbd_dev, + &(usbd_dev->control_state.req)); + } + + /* Exception: Handle SET ADDRESS function here... */ + if ((req->bmRequestType == 0) && + (req->bRequest == USB_REQ_SET_ADDRESS)) { + usbd_dev->driver->set_address(usbd_dev, req->wValue); + } + usbd_dev->control_state.state = IDLE; + break; + default: + stall_transaction(usbd_dev); + } +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_efm32lg.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_efm32lg.c new file mode 100644 index 00000000..5768947c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_efm32lg.c @@ -0,0 +1,426 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * Copyright (C) 2015 Kuldeep Singh Dhaka + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "usb_private.h" + +/* Receive FIFO size in 32-bit words. */ +#define RX_FIFO_SIZE 256 + +/* FIME: EFM32LG have 6 bidirectonal-endpoint + * problem is "uint32_t doeptsiz[4];" in usb_private.h + * doeptsiz is fixed size of length 4, + * if we it to be of length 6 + * possibly, same with "uint8_t force_nak[4];" + * + * solution: remove everything driver specific from usb_private.h + * and move that to there specific driver files. + * maybe a pointer to driver specific data will do the task. */ + +#define ENDPOINT_COUNT 4 + +static struct _usbd_device _usbd_dev; + +/** Initialize the USB_FS device controller hardware of the STM32. */ +static usbd_device *efm32lg_usbd_init(void) +{ + /* Enable clock */ + CMU_HFCORECLKEN0 |= CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC; + CMU_CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV; + + /* wait till clock not selected */ + while (!(CMU_STATUS & CMU_STATUS_USBCHFCLKSEL)); + + USB_GINTSTS = USB_GINTSTS_MMIS; + + USB_CTRL &= ~USB_CTRL_DMPUAP; + USB_ROUTE = USB_ROUTE_DMPUPEN | USB_ROUTE_PHYPEN; + + /* Wait for AHB idle. */ + while (!(USB_GRSTCTL & USB_GRSTCTL_AHBIDL)); + /* Do core soft reset. */ + USB_GRSTCTL |= USB_GRSTCTL_CSRST; + while (USB_GRSTCTL & USB_GRSTCTL_CSRST); + + /* Force peripheral only mode. */ + USB_GUSBCFG |= USB_GUSBCFG_FDMOD | USB_GUSBCFG_TRDT_16BIT; + + /* Full speed device. */ + USB_DCFG |= USB_DCFG_DSPD; + + /* Restart the PHY clock. */ + USB_PCGCCTL = 0; + + USB_GRXFSIZ = efm32lg_usb_driver.rx_fifo_size; + _usbd_dev.fifo_mem_top = efm32lg_usb_driver.rx_fifo_size; + + /* Unmask interrupts for TX and RX. */ + USB_GAHBCFG |= USB_GAHBCFG_GLBLINTRMSK; + USB_GINTMSK = USB_GINTMSK_ENUMDNEM | + USB_GINTMSK_RXFLVLM | + USB_GINTMSK_IEPINT | + USB_GINTMSK_USBSUSPM | + USB_GINTMSK_WUIM; + USB_DAINTMSK = 0xF; + USB_DIEPMSK = USB_DIEPMSK_XFRCM; + + return &_usbd_dev; +} + +static void efm32lg_set_address(usbd_device *usbd_dev, uint8_t addr) +{ + (void)usbd_dev; + + USB_DCFG = (USB_DCFG & ~USB_DCFG_DAD) | (addr << 4); +} + +static void efm32lg_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, + uint16_t max_size, + void (*callback) (usbd_device *usbd_dev, uint8_t ep)) +{ + /* + * Configure endpoint address and type. Allocate FIFO memory for + * endpoint. Install callback function. + */ + uint8_t dir = addr & 0x80; + addr &= 0x7f; + + if (addr == 0) { /* For the default control endpoint */ + /* Configure IN part. */ + if (max_size >= 64) { + USB_DIEP0CTL = USB_DIEP0CTL_MPSIZ_64; + } else if (max_size >= 32) { + USB_DIEP0CTL = USB_DIEP0CTL_MPSIZ_32; + } else if (max_size >= 16) { + USB_DIEP0CTL = USB_DIEP0CTL_MPSIZ_16; + } else { + USB_DIEP0CTL = USB_DIEP0CTL_MPSIZ_8; + } + + USB_DIEP0TSIZ = + (max_size & USB_DIEP0TSIZ_XFRSIZ_MASK); + USB_DIEP0CTL |= + USB_DIEP0CTL_EPENA | USB_DIEP0CTL_SNAK; + + /* Configure OUT part. */ + usbd_dev->doeptsiz[0] = USB_DIEP0TSIZ_STUPCNT_1 | + USB_DIEP0TSIZ_PKTCNT | + (max_size & USB_DIEP0TSIZ_XFRSIZ_MASK); + USB_DOEPx_TSIZ(0) = usbd_dev->doeptsiz[0]; + USB_DOEPx_CTL(0) |= + USB_DOEP0CTL_EPENA | USB_DIEP0CTL_SNAK; + + USB_GNPTXFSIZ = ((max_size / 4) << 16) | + usbd_dev->driver->rx_fifo_size; + usbd_dev->fifo_mem_top += max_size / 4; + usbd_dev->fifo_mem_top_ep0 = usbd_dev->fifo_mem_top; + + return; + } + + if (dir) { + USB_DIEPTXF(addr) = ((max_size / 4) << 16) | + usbd_dev->fifo_mem_top; + usbd_dev->fifo_mem_top += max_size / 4; + + USB_DIEPx_TSIZ(addr) = + (max_size & USB_DIEP0TSIZ_XFRSIZ_MASK); + USB_DIEPx_CTL(addr) |= + USB_DIEP0CTL_EPENA | USB_DIEP0CTL_SNAK | (type << 18) + | USB_DIEP0CTL_USBAEP | USB_DIEP0CTL_SD0PID + | (addr << 22) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = + (void *)callback; + } + } + + if (!dir) { + usbd_dev->doeptsiz[addr] = USB_DIEP0TSIZ_PKTCNT | + (max_size & USB_DIEP0TSIZ_XFRSIZ_MASK); + USB_DOEPx_TSIZ(addr) = usbd_dev->doeptsiz[addr]; + USB_DOEPx_CTL(addr) |= USB_DOEP0CTL_EPENA | + USB_DOEP0CTL_USBAEP | USB_DIEP0CTL_CNAK | + USB_DOEP0CTL_SD0PID | (type << 18) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = + (void *)callback; + } + } +} + +static void efm32lg_endpoints_reset(usbd_device *usbd_dev) +{ + /* The core resets the endpoints automatically on reset. */ + usbd_dev->fifo_mem_top = usbd_dev->fifo_mem_top_ep0; +} + +static void efm32lg_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, + uint8_t stall) +{ + (void)usbd_dev; + if (addr == 0) { + if (stall) { + USB_DIEPx_CTL(addr) |= USB_DIEP0CTL_STALL; + } else { + USB_DIEPx_CTL(addr) &= ~USB_DIEP0CTL_STALL; + } + } + + if (addr & 0x80) { + addr &= 0x7F; + + if (stall) { + USB_DIEPx_CTL(addr) |= USB_DIEP0CTL_STALL; + } else { + USB_DIEPx_CTL(addr) &= ~USB_DIEP0CTL_STALL; + USB_DIEPx_CTL(addr) |= USB_DIEP0CTL_SD0PID; + } + } else { + if (stall) { + USB_DOEPx_CTL(addr) |= USB_DOEP0CTL_STALL; + } else { + USB_DOEPx_CTL(addr) &= ~USB_DOEP0CTL_STALL; + USB_DOEPx_CTL(addr) |= USB_DOEP0CTL_SD0PID; + } + } +} + +static uint8_t efm32lg_ep_stall_get(usbd_device *usbd_dev, uint8_t addr) +{ + (void)usbd_dev; + + /* Return non-zero if STALL set. */ + if (addr & 0x80) { + return (USB_DIEPx_CTL(addr & 0x7f) & + USB_DIEP0CTL_STALL) ? 1 : 0; + } else { + return (USB_DOEPx_CTL(addr) & + USB_DOEP0CTL_STALL) ? 1 : 0; + } +} + +static void efm32lg_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak) +{ + /* It does not make sence to force NAK on IN endpoints. */ + if (addr & 0x80) { + return; + } + + usbd_dev->force_nak[addr] = nak; + + if (nak) { + USB_DOEPx_CTL(addr) |= USB_DOEP0CTL_SNAK; + } else { + USB_DOEPx_CTL(addr) |= USB_DOEP0CTL_CNAK; + } +} + +static uint16_t efm32lg_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len) +{ + (void)usbd_dev; + const uint32_t *buf32 = buf; + int i; + + addr &= 0x7F; + + /* Return if endpoint is already enabled. */ + if (USB_DIEPx_TSIZ(addr) & USB_DIEP0TSIZ_PKTCNT) { + return 0; + } + + /* Enable endpoint for transmission. */ + USB_DIEPx_TSIZ(addr) = USB_DIEP0TSIZ_PKTCNT | len; + USB_DIEPx_CTL(addr) |= USB_DIEP0CTL_EPENA | + USB_DIEP0CTL_CNAK; + volatile uint32_t *fifo = USB_FIFOxD(addr); + + /* Copy buffer to endpoint FIFO, note - memcpy does not work */ + for (i = len; i > 0; i -= 4) { + *fifo++ = *buf32++; + } + + return len; +} + +static uint16_t efm32lg_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, + void *buf, uint16_t len) +{ + int i; + uint32_t *buf32 = buf; + uint32_t extra; + + len = MIN(len, usbd_dev->rxbcnt); + usbd_dev->rxbcnt -= len; + + volatile uint32_t *fifo = USB_FIFOxD(addr); + for (i = len; i >= 4; i -= 4) { + *buf32++ = *fifo++; + } + + if (i) { + extra = *fifo++; + memcpy(buf32, &extra, i); + } + + USB_DOEPx_TSIZ(addr) = usbd_dev->doeptsiz[addr]; + USB_DOEPx_CTL(addr) |= USB_DOEP0CTL_EPENA | + (usbd_dev->force_nak[addr] ? + USB_DOEP0CTL_SNAK : USB_DOEP0CTL_CNAK); + + return len; +} + +static void efm32lg_poll(usbd_device *usbd_dev) +{ + /* Read interrupt status register. */ + uint32_t intsts = USB_GINTSTS; + int i; + + if (intsts & USB_GINTSTS_ENUMDNE) { + /* Handle USB RESET condition. */ + USB_GINTSTS = USB_GINTSTS_ENUMDNE; + usbd_dev->fifo_mem_top = usbd_dev->driver->rx_fifo_size; + _usbd_reset(usbd_dev); + return; + } + + /* Note: RX and TX handled differently in this device. */ + if (intsts & USB_GINTSTS_RXFLVL) { + /* Receive FIFO non-empty. */ + uint32_t rxstsp = USB_GRXSTSP; + uint32_t pktsts = rxstsp & USB_GRXSTSP_PKTSTS_MASK; + if ((pktsts != USB_GRXSTSP_PKTSTS_OUT) && + (pktsts != USB_GRXSTSP_PKTSTS_SETUP)) { + return; + } + + uint8_t ep = rxstsp & USB_GRXSTSP_EPNUM_MASK; + uint8_t type; + if (pktsts == USB_GRXSTSP_PKTSTS_SETUP) { + type = USB_TRANSACTION_SETUP; + } else { + type = USB_TRANSACTION_OUT; + } + + /* Save packet size for stm32f107_ep_read_packet(). */ + usbd_dev->rxbcnt = (rxstsp & USB_GRXSTSP_BCNT_MASK) >> 4; + + /* + * FIXME: Why is a delay needed here? + * This appears to fix a problem where the first 4 bytes + * of the DATA OUT stage of a control transaction are lost. + */ + for (i = 0; i < 1000; i++) { + __asm__("nop"); + } + + if (usbd_dev->user_callback_ctr[ep][type]) { + usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep); + } + + /* Discard unread packet data. */ + for (i = 0; i < usbd_dev->rxbcnt; i += 4) { + (void)*USB_FIFOxD(ep); + } + + usbd_dev->rxbcnt = 0; + } + + /* + * There is no global interrupt flag for transmit complete. + * The XFRC bit must be checked in each USB_DIEPx_INT(x). + */ + for (i = 0; i < ENDPOINT_COUNT; i++) { /* Iterate over endpoints. */ + if (USB_DIEPx_INT(i) & USB_DIEP_INT_XFRC) { + /* Transfer complete. */ + if (usbd_dev->user_callback_ctr[i] + [USB_TRANSACTION_IN]) { + usbd_dev->user_callback_ctr[i] + [USB_TRANSACTION_IN](usbd_dev, i); + } + + USB_DIEPx_INT(i) = USB_DIEP_INT_XFRC; + } + } + + if (intsts & USB_GINTSTS_USBSUSP) { + if (usbd_dev->user_callback_suspend) { + usbd_dev->user_callback_suspend(); + } + USB_GINTSTS = USB_GINTSTS_USBSUSP; + } + + if (intsts & USB_GINTSTS_WKUPINT) { + if (usbd_dev->user_callback_resume) { + usbd_dev->user_callback_resume(); + } + USB_GINTSTS = USB_GINTSTS_WKUPINT; + } + + if (intsts & USB_GINTSTS_SOF) { + if (usbd_dev->user_callback_sof) { + usbd_dev->user_callback_sof(); + } + USB_GINTSTS = USB_GINTSTS_SOF; + } + + if (usbd_dev->user_callback_sof) { + USB_GINTMSK |= USB_GINTMSK_SOFM; + } else { + USB_GINTMSK &= ~USB_GINTMSK_SOFM; + } +} + +static void efm32lg_disconnect(usbd_device *usbd_dev, bool disconnected) +{ + (void)usbd_dev; + + if (disconnected) { + USB_DCTL |= USB_DCTL_SDIS; + } else { + USB_DCTL &= ~USB_DCTL_SDIS; + } +} + +const struct _usbd_driver efm32lg_usb_driver = { + .init = efm32lg_usbd_init, + .set_address = efm32lg_set_address, + .ep_setup = efm32lg_ep_setup, + .ep_reset = efm32lg_endpoints_reset, + .ep_stall_set = efm32lg_ep_stall_set, + .ep_stall_get = efm32lg_ep_stall_get, + .ep_nak_set = efm32lg_ep_nak_set, + .ep_write_packet = efm32lg_ep_write_packet, + .ep_read_packet = efm32lg_ep_read_packet, + .poll = efm32lg_poll, + .disconnect = efm32lg_disconnect, + .base_address = USB_BASE, + .set_address_before_status = 1, + .rx_fifo_size = RX_FIFO_SIZE, +}; diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f107.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f107.c new file mode 100644 index 00000000..7f7902cc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f107.c @@ -0,0 +1,100 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "usb_private.h" +#include "usb_fx07_common.h" + +/* Receive FIFO size in 32-bit words. */ +#define RX_FIFO_SIZE 128 + +static usbd_device *stm32f107_usbd_init(void); + +static struct _usbd_device usbd_dev; + +const struct _usbd_driver stm32f107_usb_driver = { + .init = stm32f107_usbd_init, + .set_address = stm32fx07_set_address, + .ep_setup = stm32fx07_ep_setup, + .ep_reset = stm32fx07_endpoints_reset, + .ep_stall_set = stm32fx07_ep_stall_set, + .ep_stall_get = stm32fx07_ep_stall_get, + .ep_nak_set = stm32fx07_ep_nak_set, + .ep_write_packet = stm32fx07_ep_write_packet, + .ep_read_packet = stm32fx07_ep_read_packet, + .poll = stm32fx07_poll, + .disconnect = stm32fx07_disconnect, + .base_address = USB_OTG_FS_BASE, + .set_address_before_status = 1, + .rx_fifo_size = RX_FIFO_SIZE, +}; + +/** Initialize the USB device controller hardware of the STM32. */ +static usbd_device *stm32f107_usbd_init(void) +{ + rcc_periph_clock_enable(RCC_OTGFS); + OTG_FS_GUSBCFG |= OTG_GUSBCFG_PHYSEL; + + /* Wait for AHB idle. */ + while (!(OTG_FS_GRSTCTL & OTG_GRSTCTL_AHBIDL)); + /* Do core soft reset. */ + OTG_FS_GRSTCTL |= OTG_GRSTCTL_CSRST; + while (OTG_FS_GRSTCTL & OTG_GRSTCTL_CSRST); + + if (OTG_FS_CID >= OTG_CID_HAS_VBDEN) { + /* Enable VBUS detection in device mode and power up the PHY. */ + OTG_FS_GCCFG |= OTG_GCCFG_VBDEN | OTG_GCCFG_PWRDWN; + } else { + /* Enable VBUS sensing in device mode and power up the PHY. */ + OTG_FS_GCCFG |= OTG_GCCFG_VBUSBSEN | OTG_GCCFG_PWRDWN; + } + /* Explicitly enable DP pullup (not all cores do this by default) */ + OTG_FS_DCTL &= ~OTG_DCTL_SDIS; + + /* Force peripheral only mode. */ + OTG_FS_GUSBCFG |= OTG_GUSBCFG_FDMOD | OTG_GUSBCFG_TRDT_MASK; + + OTG_FS_GINTSTS = OTG_GINTSTS_MMIS; + + /* Full speed device. */ + OTG_FS_DCFG |= OTG_DCFG_DSPD; + + /* Restart the PHY clock. */ + OTG_FS_PCGCCTL = 0; + + OTG_FS_GRXFSIZ = stm32f107_usb_driver.rx_fifo_size; + usbd_dev.fifo_mem_top = stm32f107_usb_driver.rx_fifo_size; + + /* Unmask interrupts for TX and RX. */ + OTG_FS_GAHBCFG |= OTG_GAHBCFG_GINT; + OTG_FS_GINTMSK = OTG_GINTMSK_ENUMDNEM | + OTG_GINTMSK_RXFLVLM | + OTG_GINTMSK_IEPINT | + OTG_GINTMSK_USBSUSPM | + OTG_GINTMSK_WUIM; + OTG_FS_DAINTMSK = 0xF; + OTG_FS_DIEPMSK = OTG_DIEPMSK_XFRCM; + + return &usbd_dev; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f207.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f207.c new file mode 100644 index 00000000..40f1efce --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_f207.c @@ -0,0 +1,92 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "usb_private.h" +#include "usb_fx07_common.h" + +/* Receive FIFO size in 32-bit words. */ +#define RX_FIFO_SIZE 512 + +static usbd_device *stm32f207_usbd_init(void); + +static struct _usbd_device usbd_dev; + +const struct _usbd_driver stm32f207_usb_driver = { + .init = stm32f207_usbd_init, + .set_address = stm32fx07_set_address, + .ep_setup = stm32fx07_ep_setup, + .ep_reset = stm32fx07_endpoints_reset, + .ep_stall_set = stm32fx07_ep_stall_set, + .ep_stall_get = stm32fx07_ep_stall_get, + .ep_nak_set = stm32fx07_ep_nak_set, + .ep_write_packet = stm32fx07_ep_write_packet, + .ep_read_packet = stm32fx07_ep_read_packet, + .poll = stm32fx07_poll, + .disconnect = stm32fx07_disconnect, + .base_address = USB_OTG_HS_BASE, + .set_address_before_status = 1, + .rx_fifo_size = RX_FIFO_SIZE, +}; + +/** Initialize the USB device controller hardware of the STM32. */ +static usbd_device *stm32f207_usbd_init(void) +{ + rcc_periph_clock_enable(RCC_OTGHS); + OTG_HS_GINTSTS = OTG_GINTSTS_MMIS; + + OTG_HS_GUSBCFG |= OTG_GUSBCFG_PHYSEL; + /* Enable VBUS sensing in device mode and power down the PHY. */ + OTG_HS_GCCFG |= OTG_GCCFG_VBUSBSEN | OTG_GCCFG_PWRDWN; + + /* Wait for AHB idle. */ + while (!(OTG_HS_GRSTCTL & OTG_GRSTCTL_AHBIDL)); + /* Do core soft reset. */ + OTG_HS_GRSTCTL |= OTG_GRSTCTL_CSRST; + while (OTG_HS_GRSTCTL & OTG_GRSTCTL_CSRST); + + /* Force peripheral only mode. */ + OTG_HS_GUSBCFG |= OTG_GUSBCFG_FDMOD | OTG_GUSBCFG_TRDT_MASK; + + /* Full speed device. */ + OTG_HS_DCFG |= OTG_DCFG_DSPD; + + /* Restart the PHY clock. */ + OTG_HS_PCGCCTL = 0; + + OTG_HS_GRXFSIZ = stm32f207_usb_driver.rx_fifo_size; + usbd_dev.fifo_mem_top = stm32f207_usb_driver.rx_fifo_size; + + /* Unmask interrupts for TX and RX. */ + OTG_HS_GAHBCFG |= OTG_GAHBCFG_GINT; + OTG_HS_GINTMSK = OTG_GINTMSK_ENUMDNEM | + OTG_GINTMSK_RXFLVLM | + OTG_GINTMSK_IEPINT | + OTG_GINTMSK_USBSUSPM | + OTG_GINTMSK_WUIM; + OTG_HS_DAINTMSK = 0xF; + OTG_HS_DIEPMSK = OTG_DIEPMSK_XFRCM; + + return &usbd_dev; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.c new file mode 100644 index 00000000..dae91409 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.c @@ -0,0 +1,395 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "usb_private.h" +#include "usb_fx07_common.h" + +/* The FS core and the HS core have the same register layout. + * As the code can be used on both cores, the registers offset is modified + * according to the selected cores base address. */ +#define dev_base_address (usbd_dev->driver->base_address) +#define REBASE(x) MMIO32((x) + (dev_base_address)) + +void stm32fx07_set_address(usbd_device *usbd_dev, uint8_t addr) +{ + REBASE(OTG_DCFG) = (REBASE(OTG_DCFG) & ~OTG_DCFG_DAD) | (addr << 4); +} + +void stm32fx07_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, + uint16_t max_size, + void (*callback) (usbd_device *usbd_dev, uint8_t ep)) +{ + /* + * Configure endpoint address and type. Allocate FIFO memory for + * endpoint. Install callback function. + */ + uint8_t dir = addr & 0x80; + addr &= 0x7f; + + if (addr == 0) { /* For the default control endpoint */ + /* Configure IN part. */ + if (max_size >= 64) { + REBASE(OTG_DIEPCTL0) = OTG_DIEPCTL0_MPSIZ_64; + } else if (max_size >= 32) { + REBASE(OTG_DIEPCTL0) = OTG_DIEPCTL0_MPSIZ_32; + } else if (max_size >= 16) { + REBASE(OTG_DIEPCTL0) = OTG_DIEPCTL0_MPSIZ_16; + } else { + REBASE(OTG_DIEPCTL0) = OTG_DIEPCTL0_MPSIZ_8; + } + + REBASE(OTG_DIEPTSIZ0) = + (max_size & OTG_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DIEPCTL0) |= + OTG_DIEPCTL0_EPENA | OTG_DIEPCTL0_SNAK; + + /* Configure OUT part. */ + usbd_dev->doeptsiz[0] = OTG_DIEPSIZ0_STUPCNT_1 | + OTG_DIEPSIZ0_PKTCNT | + (max_size & OTG_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DOEPTSIZ(0)) = usbd_dev->doeptsiz[0]; + REBASE(OTG_DOEPCTL(0)) |= + OTG_DOEPCTL0_EPENA | OTG_DIEPCTL0_SNAK; + + REBASE(OTG_GNPTXFSIZ) = ((max_size / 4) << 16) | + usbd_dev->driver->rx_fifo_size; + usbd_dev->fifo_mem_top += max_size / 4; + usbd_dev->fifo_mem_top_ep0 = usbd_dev->fifo_mem_top; + + return; + } + + if (dir) { + REBASE(OTG_DIEPTXF(addr)) = ((max_size / 4) << 16) | + usbd_dev->fifo_mem_top; + usbd_dev->fifo_mem_top += max_size / 4; + + REBASE(OTG_DIEPTSIZ(addr)) = + (max_size & OTG_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DIEPCTL(addr)) |= + OTG_DIEPCTL0_EPENA | OTG_DIEPCTL0_SNAK | (type << 18) + | OTG_DIEPCTL0_USBAEP | OTG_DIEPCTLX_SD0PID + | (addr << 22) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = + (void *)callback; + } + } + + if (!dir) { + usbd_dev->doeptsiz[addr] = OTG_DIEPSIZ0_PKTCNT | + (max_size & OTG_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr]; + REBASE(OTG_DOEPCTL(addr)) |= OTG_DOEPCTL0_EPENA | + OTG_DOEPCTL0_USBAEP | OTG_DIEPCTL0_CNAK | + OTG_DOEPCTLX_SD0PID | (type << 18) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = + (void *)callback; + } + } +} + +void stm32fx07_endpoints_reset(usbd_device *usbd_dev) +{ + int i; + /* The core resets the endpoints automatically on reset. */ + usbd_dev->fifo_mem_top = usbd_dev->fifo_mem_top_ep0; + + /* Disable any currently active endpoints */ + for (i = 1; i < 4; i++) { + if (REBASE(OTG_DOEPCTL(i)) & OTG_DOEPCTL0_EPENA) { + REBASE(OTG_DOEPCTL(i)) |= OTG_DOEPCTL0_EPDIS; + } + if (REBASE(OTG_DIEPCTL(i)) & OTG_DIEPCTL0_EPENA) { + REBASE(OTG_DIEPCTL(i)) |= OTG_DIEPCTL0_EPDIS; + } + } + + /* Flush all tx/rx fifos */ + REBASE(OTG_GRSTCTL) = OTG_GRSTCTL_TXFFLSH | OTG_GRSTCTL_TXFNUM_ALL + | OTG_GRSTCTL_RXFFLSH; +} + +void stm32fx07_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, uint8_t stall) +{ + if (addr == 0) { + if (stall) { + REBASE(OTG_DIEPCTL(addr)) |= OTG_DIEPCTL0_STALL; + } else { + REBASE(OTG_DIEPCTL(addr)) &= ~OTG_DIEPCTL0_STALL; + } + } + + if (addr & 0x80) { + addr &= 0x7F; + + if (stall) { + REBASE(OTG_DIEPCTL(addr)) |= OTG_DIEPCTL0_STALL; + } else { + REBASE(OTG_DIEPCTL(addr)) &= ~OTG_DIEPCTL0_STALL; + REBASE(OTG_DIEPCTL(addr)) |= OTG_DIEPCTLX_SD0PID; + } + } else { + if (stall) { + REBASE(OTG_DOEPCTL(addr)) |= OTG_DOEPCTL0_STALL; + } else { + REBASE(OTG_DOEPCTL(addr)) &= ~OTG_DOEPCTL0_STALL; + REBASE(OTG_DOEPCTL(addr)) |= OTG_DOEPCTLX_SD0PID; + } + } +} + +uint8_t stm32fx07_ep_stall_get(usbd_device *usbd_dev, uint8_t addr) +{ + /* Return non-zero if STALL set. */ + if (addr & 0x80) { + return (REBASE(OTG_DIEPCTL(addr & 0x7f)) & + OTG_DIEPCTL0_STALL) ? 1 : 0; + } else { + return (REBASE(OTG_DOEPCTL(addr)) & + OTG_DOEPCTL0_STALL) ? 1 : 0; + } +} + +void stm32fx07_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak) +{ + /* It does not make sense to force NAK on IN endpoints. */ + if (addr & 0x80) { + return; + } + + usbd_dev->force_nak[addr] = nak; + + if (nak) { + REBASE(OTG_DOEPCTL(addr)) |= OTG_DOEPCTL0_SNAK; + } else { + REBASE(OTG_DOEPCTL(addr)) |= OTG_DOEPCTL0_CNAK; + } +} + +uint16_t stm32fx07_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len) +{ + const uint32_t *buf32 = buf; + int i; + + addr &= 0x7F; + + /* Return if endpoint is already enabled. */ + if (REBASE(OTG_DIEPTSIZ(addr)) & OTG_DIEPSIZ0_PKTCNT) { + return 0; + } + + /* Enable endpoint for transmission. */ + REBASE(OTG_DIEPTSIZ(addr)) = OTG_DIEPSIZ0_PKTCNT | len; + REBASE(OTG_DIEPCTL(addr)) |= OTG_DIEPCTL0_EPENA | + OTG_DIEPCTL0_CNAK; + + /* Copy buffer to endpoint FIFO, note - memcpy does not work */ + for (i = len; i > 0; i -= 4) { + REBASE(OTG_FIFO(addr)) = *buf32++; + } + + return len; +} + +uint16_t stm32fx07_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, + void *buf, uint16_t len) +{ + int i; + uint32_t *buf32 = buf; + uint32_t extra; + + /* We do not need to know the endpoint address since there is only one + * receive FIFO for all endpoints. + */ + (void) addr; + len = MIN(len, usbd_dev->rxbcnt); + + for (i = len; i >= 4; i -= 4) { + *buf32++ = REBASE(OTG_FIFO(0)); + usbd_dev->rxbcnt -= 4; + } + + if (i) { + extra = REBASE(OTG_FIFO(0)); + /* we read 4 bytes from the fifo, so update rxbcnt */ + if (usbd_dev->rxbcnt < 4) { + /* Be careful not to underflow (rxbcnt is unsigned) */ + usbd_dev->rxbcnt = 0; + } else { + usbd_dev->rxbcnt -= 4; + } + memcpy(buf32, &extra, i); + } + + return len; +} + +static void stm32fx07_flush_txfifo(usbd_device *usbd_dev, int ep) +{ + uint32_t fifo; + /* set IN endpoint NAK */ + REBASE(OTG_DIEPCTL(ep)) |= OTG_DIEPCTL0_SNAK; + /* wait for core to respond */ + while (!(REBASE(OTG_DIEPINT(ep)) & OTG_DIEPINTX_INEPNE)) { + /* idle */ + } + /* get fifo for this endpoint */ + fifo = (REBASE(OTG_DIEPCTL(ep)) & OTG_DIEPCTL0_TXFNUM_MASK) >> 22; + /* wait for core to idle */ + while (!(REBASE(OTG_GRSTCTL) & OTG_GRSTCTL_AHBIDL)) { + /* idle */ + } + /* flush tx fifo */ + REBASE(OTG_GRSTCTL) = (fifo << 6) | OTG_GRSTCTL_TXFFLSH; + /* reset packet counter */ + REBASE(OTG_DIEPTSIZ(ep)) = 0; + while ((REBASE(OTG_GRSTCTL) & OTG_GRSTCTL_TXFFLSH)) { + /* idle */ + } +} + +void stm32fx07_poll(usbd_device *usbd_dev) +{ + /* Read interrupt status register. */ + uint32_t intsts = REBASE(OTG_GINTSTS); + int i; + + if (intsts & OTG_GINTSTS_ENUMDNE) { + /* Handle USB RESET condition. */ + REBASE(OTG_GINTSTS) = OTG_GINTSTS_ENUMDNE; + usbd_dev->fifo_mem_top = usbd_dev->driver->rx_fifo_size; + _usbd_reset(usbd_dev); + return; + } + + /* + * There is no global interrupt flag for transmit complete. + * The XFRC bit must be checked in each OTG_DIEPINT(x). + */ + for (i = 0; i < 4; i++) { /* Iterate over endpoints. */ + if (REBASE(OTG_DIEPINT(i)) & OTG_DIEPINTX_XFRC) { + /* Transfer complete. */ + if (usbd_dev->user_callback_ctr[i] + [USB_TRANSACTION_IN]) { + usbd_dev->user_callback_ctr[i] + [USB_TRANSACTION_IN](usbd_dev, i); + } + + REBASE(OTG_DIEPINT(i)) = OTG_DIEPINTX_XFRC; + } + } + + /* Note: RX and TX handled differently in this device. */ + if (intsts & OTG_GINTSTS_RXFLVL) { + /* Receive FIFO non-empty. */ + uint32_t rxstsp = REBASE(OTG_GRXSTSP); + uint32_t pktsts = rxstsp & OTG_GRXSTSP_PKTSTS_MASK; + uint8_t ep = rxstsp & OTG_GRXSTSP_EPNUM_MASK; + if (pktsts == OTG_GRXSTSP_PKTSTS_OUT_COMP + || pktsts == OTG_GRXSTSP_PKTSTS_SETUP_COMP) { + REBASE(OTG_DOEPTSIZ(ep)) = usbd_dev->doeptsiz[ep]; + REBASE(OTG_DOEPCTL(ep)) |= OTG_DOEPCTL0_EPENA | + (usbd_dev->force_nak[ep] ? + OTG_DOEPCTL0_SNAK : OTG_DOEPCTL0_CNAK); + return; + } + + if ((pktsts != OTG_GRXSTSP_PKTSTS_OUT) && + (pktsts != OTG_GRXSTSP_PKTSTS_SETUP)) { + return; + } + + uint8_t type; + if (pktsts == OTG_GRXSTSP_PKTSTS_SETUP) { + type = USB_TRANSACTION_SETUP; + } else { + type = USB_TRANSACTION_OUT; + } + + if (type == USB_TRANSACTION_SETUP + && (REBASE(OTG_DIEPTSIZ(ep)) & OTG_DIEPSIZ0_PKTCNT)) { + /* SETUP received but there is still something stuck + * in the transmit fifo. Flush it. + */ + stm32fx07_flush_txfifo(usbd_dev, ep); + } + + /* Save packet size for stm32f107_ep_read_packet(). */ + usbd_dev->rxbcnt = (rxstsp & OTG_GRXSTSP_BCNT_MASK) >> 4; + + if (usbd_dev->user_callback_ctr[ep][type]) { + usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep); + } + + /* Discard unread packet data. */ + for (i = 0; i < usbd_dev->rxbcnt; i += 4) { + /* There is only one receive FIFO, so use OTG_FIFO(0) */ + (void)REBASE(OTG_FIFO(0)); + } + + usbd_dev->rxbcnt = 0; + } + + if (intsts & OTG_GINTSTS_USBSUSP) { + if (usbd_dev->user_callback_suspend) { + usbd_dev->user_callback_suspend(); + } + REBASE(OTG_GINTSTS) = OTG_GINTSTS_USBSUSP; + } + + if (intsts & OTG_GINTSTS_WKUPINT) { + if (usbd_dev->user_callback_resume) { + usbd_dev->user_callback_resume(); + } + REBASE(OTG_GINTSTS) = OTG_GINTSTS_WKUPINT; + } + + if (intsts & OTG_GINTSTS_SOF) { + if (usbd_dev->user_callback_sof) { + usbd_dev->user_callback_sof(); + } + REBASE(OTG_GINTSTS) = OTG_GINTSTS_SOF; + } + + if (usbd_dev->user_callback_sof) { + REBASE(OTG_GINTMSK) |= OTG_GINTMSK_SOFM; + } else { + REBASE(OTG_GINTMSK) &= ~OTG_GINTMSK_SOFM; + } +} + +void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected) +{ + if (disconnected) { + REBASE(OTG_DCTL) |= OTG_DCTL_SDIS; + } else { + REBASE(OTG_DCTL) &= ~OTG_DCTL_SDIS; + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.h b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.h new file mode 100644 index 00000000..31c40304 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_fx07_common.h @@ -0,0 +1,39 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __USB_FX07_COMMON_H_ +#define __USB_FX07_COMMON_H_ + +void stm32fx07_set_address(usbd_device *usbd_dev, uint8_t addr); +void stm32fx07_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, + uint16_t max_size, + void (*callback)(usbd_device *usbd_dev, uint8_t ep)); +void stm32fx07_endpoints_reset(usbd_device *usbd_dev); +void stm32fx07_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, uint8_t stall); +uint8_t stm32fx07_ep_stall_get(usbd_device *usbd_dev, uint8_t addr); +void stm32fx07_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak); +uint16_t stm32fx07_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len); +uint16_t stm32fx07_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, + void *buf, uint16_t len); +void stm32fx07_poll(usbd_device *usbd_dev); +void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected); + + +#endif /* __USB_FX07_COMMON_H_ */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_lm4f.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_lm4f.c new file mode 100644 index 00000000..e70e6047 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_lm4f.c @@ -0,0 +1,651 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Alexandru Gagniuc + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** + * @defgroup usb_file USB + * + * @ingroup LM4Fxx + * + * @author @htmlonly © @endhtmlonly 2013 + * Alexandru Gagniuc + * + * \brief libopencm3 LM4F Universal Serial Bus controller + * + * The LM4F USB driver is integrated with the libopencm3 USB stack. You should + * use the generic stack. + * + * To use this driver, tell the linker to look for it: + * @code{.c} + * extern usbd_driver lm4f_usb_driver; + * @endcode + * + * And pass this driver as an argument when initializing the USB stack: + * @code{.c} + * usbd_device *usbd_dev; + * usbd_dev = usbd_init(&lm4f_usb_driver, ...); + * @endcode + * + * Polling or interrupt-driven? + * + * The LM4F USB driver will work fine regardless of whether it is called from an + * interrupt service routine, or from the main program loop. + * + * Polling USB from the main loop requires calling @ref usbd_poll() from the + * main program loop. + * For example: + * @code{.c} + * // Main program loop + * while(1) { + * usbd_poll(usb_dev); + * do_other_stuff(); + * ... + * @endcode + * + * Running @ref usbd_poll() from an interrupt has the advantage that it is only + * called when needed, saving CPU cycles for the main program. + * + * RESET, DISCON, RESUME, and SUSPEND interrupts must be enabled, along with the + * interrupts for any endpoint that is used. The EP0_TX interrupt must be + * enabled for the control endpoint to function correctly. + * For example, if EP1IN and EP2OUT are used, then the EP0_TX, EP1_TX, and + * EP2_RX interrupts should be enabled: + * @code{.c} + * // Enable USB interrupts for EP0, EP1IN, and EP2OUT + * ints = USB_INT_RESET | USB_INT_DISCON | USB_INT_RESUME | + * USB_INT_SUSPEND; + * usb_enable_interrupts(ints, USB_EP2_INT, USB_EP0_INT | USB_EP1_INT); + * // Route the interrupts through the NVIC + * nvic_enable_irq(NVIC_USB0_IRQ); + * @endcode + * + * The USB ISR only has to call @ref usbd_poll(). + * + * @code{.c} + * void usb0_isr(void) + * { + * usbd_poll(usb_dev); + * } + * @endcode + * @{ + */ + +/* + * TODO list: + * + * 1) Driver works by reading and writing to the FIFOs one byte at a time. It + * has no knowledge of DMA. + * 2) Double-buffering is supported. How can we take advantage of it to speed + * up endpoint transfers. + * 3) No benchmarks as to the endpoint's performance has been done. + */ +/* + * The following are resources referenced in comments: + * [1] http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/238784.aspx + */ + +#include +#include +#include +#include +#include "../../lib/usb/usb_private.h" + +#include + + +#define MAX_FIFO_RAM (4 * 1024) + +const struct _usbd_driver lm4f_usb_driver; + +/** + * \brief Enable Specific USB Interrupts + * + * Enable any combination of interrupts. Interrupts may be OR'ed together to + * enable them with one call. For example, to enable both the RESUME and RESET + * interrupts, pass (USB_INT_RESUME | USB_INT_RESET) + * + * Note that the NVIC must be enabled and properly configured for the interrupt + * to be routed to the CPU. + * + * @param[in] ints Interrupts which to enable. Any combination of interrupts may + * be specified by OR'ing then together + * @param[in] rx_ints Endpoints for which to generate an interrupt when a packet + * packet is received. + * @param[in] tx_ints Endpoints for which to generate an interrupt when a packet + * packet is finished transmitting. + */ +void usb_enable_interrupts(enum usb_interrupt ints, + enum usb_ep_interrupt rx_ints, + enum usb_ep_interrupt tx_ints) +{ + USB_IE |= ints; + USB_RXIE |= rx_ints; + USB_TXIE |= tx_ints; +} + +/** + * \brief Disable Specific USB Interrupts + * + * Disable any combination of interrupts. Interrupts may be OR'ed together to + * enable them with one call. For example, to disable both the RESUME and RESET + * interrupts, pass (USB_INT_RESUME | USB_INT_RESET) + * + * Note that the NVIC must be enabled and properly configured for the interrupt + * to be routed to the CPU. + * + * @param[in] ints Interrupts which to disable. Any combination of interrupts + * may be specified by OR'ing then together + * @param[in] rx_ints Endpoints for which to stop generating an interrupt when a + * packet packet is received. + * @param[in] tx_ints Endpoints for which to stop generating an interrupt when a + * packet packet is finished transmitting. + */ +void usb_disable_interrupts(enum usb_interrupt ints, + enum usb_ep_interrupt rx_ints, + enum usb_ep_interrupt tx_ints) +{ + USB_IE &= ~ints; + USB_RXIE &= ~rx_ints; + USB_TXIE &= ~tx_ints; +} + +/** + * @cond private + */ +static inline void lm4f_usb_soft_disconnect(void) +{ + USB_POWER &= ~USB_POWER_SOFTCONN; +} + +static inline void lm4f_usb_soft_connect(void) +{ + USB_POWER |= USB_POWER_SOFTCONN; +} + +static void lm4f_set_address(usbd_device *usbd_dev, uint8_t addr) +{ + (void)usbd_dev; + + USB_FADDR = addr & USB_FADDR_FUNCADDR_MASK; +} + +static void lm4f_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, + uint16_t max_size, + void (*callback) (usbd_device *usbd_dev, uint8_t ep)) +{ + (void)usbd_dev; + (void)type; + + uint8_t reg8; + uint16_t fifo_size; + + const bool dir_tx = addr & 0x80; + const uint8_t ep = addr & 0x0f; + + /* + * We do not mess with the maximum packet size, but we can only allocate + * the FIFO in power-of-two increments. + */ + if (max_size > 1024) { + fifo_size = 2048; + reg8 = USB_FIFOSZ_SIZE_2048; + } else if (max_size > 512) { + fifo_size = 1024; + reg8 = USB_FIFOSZ_SIZE_1024; + } else if (max_size > 256) { + fifo_size = 512; + reg8 = USB_FIFOSZ_SIZE_512; + } else if (max_size > 128) { + fifo_size = 256; + reg8 = USB_FIFOSZ_SIZE_256; + } else if (max_size > 64) { + fifo_size = 128; + reg8 = USB_FIFOSZ_SIZE_128; + } else if (max_size > 32) { + fifo_size = 64; + reg8 = USB_FIFOSZ_SIZE_64; + } else if (max_size > 16) { + fifo_size = 32; + reg8 = USB_FIFOSZ_SIZE_32; + } else if (max_size > 8) { + fifo_size = 16; + reg8 = USB_FIFOSZ_SIZE_16; + } else { + fifo_size = 8; + reg8 = USB_FIFOSZ_SIZE_8; + } + + /* Endpoint 0 is more special */ + if (addr == 0) { + USB_EPIDX = 0; + + if (reg8 > USB_FIFOSZ_SIZE_64) { + reg8 = USB_FIFOSZ_SIZE_64; + } + + /* The RX and TX FIFOs are shared for EP0 */ + USB_RXFIFOSZ = reg8; + USB_TXFIFOSZ = reg8; + + /* + * Regardless of how much we allocate, the first 64 bytes + * are always reserved for EP0. + */ + usbd_dev->fifo_mem_top_ep0 = 64; + return; + } + + /* Are we out of FIFO space? */ + if (usbd_dev->fifo_mem_top + fifo_size > MAX_FIFO_RAM) { + return; + } + + USB_EPIDX = addr & USB_EPIDX_MASK; + + /* FIXME: What about double buffering? */ + if (dir_tx) { + USB_TXMAXP(ep) = max_size; + USB_TXFIFOSZ = reg8; + USB_TXFIFOADD = ((usbd_dev->fifo_mem_top) >> 3); + if (callback) { + usbd_dev->user_callback_ctr[ep][USB_TRANSACTION_IN] = + (void *)callback; + } + if (type == USB_ENDPOINT_ATTR_ISOCHRONOUS) { + USB_TXCSRH(ep) |= USB_TXCSRH_ISO; + } else { + USB_TXCSRH(ep) &= ~USB_TXCSRH_ISO; + } + } else { + USB_RXMAXP(ep) = max_size; + USB_RXFIFOSZ = reg8; + USB_RXFIFOADD = ((usbd_dev->fifo_mem_top) >> 3); + if (callback) { + usbd_dev->user_callback_ctr[ep][USB_TRANSACTION_OUT] = + (void *)callback; + } + if (type == USB_ENDPOINT_ATTR_ISOCHRONOUS) { + USB_RXCSRH(ep) |= USB_RXCSRH_ISO; + } else { + USB_RXCSRH(ep) &= ~USB_RXCSRH_ISO; + } + } + + usbd_dev->fifo_mem_top += fifo_size; +} + +static void lm4f_endpoints_reset(usbd_device *usbd_dev) +{ + /* + * The core resets the endpoints automatically on reset. + * The first 64 bytes are always reserved for EP0 + */ + usbd_dev->fifo_mem_top = 64; +} + +static void lm4f_ep_stall_set(usbd_device *usbd_dev, uint8_t addr, + uint8_t stall) +{ + (void)usbd_dev; + + const uint8_t ep = addr & 0x0f; + const bool dir_tx = addr & 0x80; + + if (ep == 0) { + if (stall) { + USB_CSRL0 |= USB_CSRL0_STALL; + } else { + USB_CSRL0 &= ~USB_CSRL0_STALL; + } + return; + } + + if (dir_tx) { + if (stall) { + (USB_TXCSRL(ep)) |= USB_TXCSRL_STALL; + } else { + (USB_TXCSRL(ep)) &= ~USB_TXCSRL_STALL; + } + } else { + if (stall) { + (USB_RXCSRL(ep)) |= USB_RXCSRL_STALL; + } else { + (USB_RXCSRL(ep)) &= ~USB_RXCSRL_STALL; + } + } +} + +static uint8_t lm4f_ep_stall_get(usbd_device *usbd_dev, uint8_t addr) +{ + (void)usbd_dev; + + const uint8_t ep = addr & 0x0f; + const bool dir_tx = addr & 0x80; + + if (ep == 0) { + return USB_CSRL0 & USB_CSRL0_STALLED; + } + + if (dir_tx) { + return USB_TXCSRL(ep) & USB_TXCSRL_STALLED; + } else { + return USB_RXCSRL(ep) & USB_RXCSRL_STALLED; + } +} + +static void lm4f_ep_nak_set(usbd_device *usbd_dev, uint8_t addr, uint8_t nak) +{ + (void)usbd_dev; + (void)addr; + (void)nak; + + /* NAK's are handled automatically by hardware. Move along. */ +} + +static uint16_t lm4f_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len) +{ + const uint8_t ep = addr & 0xf; + uint16_t i; + + (void)usbd_dev; + + /* Don't touch the FIFO if there is still a packet being transmitted */ + if (ep == 0 && (USB_CSRL0 & USB_CSRL0_TXRDY)) { + return 0; + } else if (USB_TXCSRL(ep) & USB_TXCSRL_TXRDY) { + return 0; + } + + /* + * We don't need to worry about buf not being aligned. If it's not, + * the reads are downgraded to 8-bit in hardware. We lose a bit of + * performance, but we don't crash. + */ + for (i = 0; i < (len & ~0x3); i += 4) { + USB_FIFO32(ep) = *((uint32_t *)(buf + i)); + } + if (len & 0x2) { + USB_FIFO16(ep) = *((uint16_t *)(buf + i)); + i += 2; + } + if (len & 0x1) { + USB_FIFO8(ep) = *((uint8_t *)(buf + i)); + i += 1; + } + + if (ep == 0) { + /* + * EP0 is very special. We should only set DATAEND when we + * transmit the last packet in the transaction. A transaction + * that is a multiple of 64 bytes will end with a zero-length + * packet, so our check is sane. + */ + if (len != 64) { + USB_CSRL0 |= USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + } else { + USB_CSRL0 |= USB_CSRL0_TXRDY; + } + } else { + USB_TXCSRL(ep) |= USB_TXCSRL_TXRDY; + } + + return i; +} + +static uint16_t lm4f_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, + void *buf, uint16_t len) +{ + (void)usbd_dev; + + uint16_t rlen; + uint8_t ep = addr & 0xf; + + uint16_t fifoin = USB_RXCOUNT(ep); + + rlen = (fifoin > len) ? len : fifoin; + + /* + * We don't need to worry about buf not being aligned. If it's not, + * the writes are downgraded to 8-bit in hardware. We lose a bit of + * performance, but we don't crash. + */ + for (len = 0; len < (rlen & ~0x3); len += 4) { + *((uint32_t *)(buf + len)) = USB_FIFO32(ep); + } + if (rlen & 0x2) { + *((uint16_t *)(buf + len)) = USB_FIFO16(ep); + len += 2; + } + if (rlen & 0x1) { + *((uint8_t *)(buf + len)) = USB_FIFO8(ep); + } + + if (ep == 0) { + /* + * Clear RXRDY + * Datasheet says that DATAEND must also be set when clearing + * RXRDY. We don't do that. If did this when transmitting a + * packet larger than 64 bytes, only the first 64 bytes would + * be transmitted, followed by a handshake. The host would only + * get 64 bytes, seeing it as a malformed packet. Usually, we + * would not get past enumeration. + */ + USB_CSRL0 |= USB_CSRL0_RXRDYC; + + } else { + USB_RXCSRL(ep) &= ~USB_RXCSRL_RXRDY; + } + + return rlen; +} + +static void lm4f_poll(usbd_device *usbd_dev) +{ + void (*tx_cb)(usbd_device *usbd_dev, uint8_t ea); + void (*rx_cb)(usbd_device *usbd_dev, uint8_t ea); + int i; + + /* + * The initial state of these registers might change, as we process the + * interrupt, but we need the initial state in order to decide how to + * handle events. + */ + const uint8_t usb_is = USB_IS; + const uint8_t usb_rxis = USB_RXIS; + const uint8_t usb_txis = USB_TXIS; + const uint8_t usb_csrl0 = USB_CSRL0; + + if ((usb_is & USB_IM_SUSPEND) && (usbd_dev->user_callback_suspend)) { + usbd_dev->user_callback_suspend(); + } + + if ((usb_is & USB_IM_RESUME) && (usbd_dev->user_callback_resume)) { + usbd_dev->user_callback_resume(); + } + + if (usb_is & USB_IM_RESET) { + _usbd_reset(usbd_dev); + } + + if ((usb_is & USB_IM_SOF) && (usbd_dev->user_callback_sof)) { + usbd_dev->user_callback_sof(); + } + + if (usb_txis & USB_EP0) { + /* + * The EP0 bit in USB_TXIS is special. It tells us that + * something happened on EP0, but does not tell us what. This + * bit does not necessarily tell us that a packet was + * transmitted, so we have to go through all the possibilities + * to figure out exactly what did. Only after we've exhausted + * all other possibilities, can we assume this is a EPO + * "transmit complete" interrupt. + */ + if (usb_csrl0 & USB_CSRL0_RXRDY) { + enum _usbd_transaction type; + type = (usbd_dev->control_state.state != DATA_OUT && + usbd_dev->control_state.state != LAST_DATA_OUT) + ? USB_TRANSACTION_SETUP : + USB_TRANSACTION_OUT; + + if (usbd_dev->user_callback_ctr[0][type]) { + usbd_dev-> + user_callback_ctr[0][type](usbd_dev, 0); + } + + + } else { + tx_cb = usbd_dev->user_callback_ctr[0] + [USB_TRANSACTION_IN]; + + /* + * EP0 bit in TXIS is set not only when a packet is + * finished transmitting, but also when RXRDY is set, or + * when we set TXRDY to transmit a packet. If any of + * those are the case, then we do not want to call our + * IN callback, since the state machine will be in the + * wrong state, and we'll just stall our control + * endpoint. + * In fact, the only way to know if it's time to call + * our TX callback is to know what to expect. The + * hardware does not tell us what sort of transaction + * this is. We need to work with the state machine to + * figure it all out. See [1] for details. + */ + if ((usbd_dev->control_state.state != DATA_IN) && + (usbd_dev->control_state.state != LAST_DATA_IN) && + (usbd_dev->control_state.state != STATUS_IN)) { + return; + } + + if (tx_cb) { + tx_cb(usbd_dev, 0); + } + } + } + + /* See which interrupt occurred */ + for (i = 1; i < 8; i++) { + tx_cb = usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN]; + rx_cb = usbd_dev->user_callback_ctr[i][USB_TRANSACTION_OUT]; + + if ((usb_txis & (1 << i)) && tx_cb) { + tx_cb(usbd_dev, i); + } + + if ((usb_rxis & (1 << i)) && rx_cb) { + rx_cb(usbd_dev, i); + } + } + + +} + +static void lm4f_disconnect(usbd_device *usbd_dev, bool disconnected) +{ + (void)usbd_dev; + + /* + * This is all it takes: + * usbd_disconnect(dev, 1) followed by usbd_disconnect(dev, 0) + * causes the device to re-enumerate and re-configure properly. + */ + if (disconnected) { + lm4f_usb_soft_disconnect(); + } else { + lm4f_usb_soft_connect(); + } +} + +/* + * A static struct works as long as we have only one USB peripheral. If we + * meet LM4Fs with more than one USB, then we need to rework this approach. + */ +static struct _usbd_device usbd_dev; + +/** Initialize the USB device controller hardware of the LM4F. */ +static usbd_device *lm4f_usbd_init(void) +{ + int i; + + /* Start the USB clock */ + periph_clock_enable(RCC_USB0); + /* Enable the USB PLL interrupts - used to assert PLL lock */ + SYSCTL_IMC |= (SYSCTL_IMC_USBPLLLIM | SYSCTL_IMC_PLLLIM); + rcc_usb_pll_on(); + + /* Make sure we're disconnected. We'll reconnect later */ + lm4f_usb_soft_disconnect(); + + /* Software reset USB */ + SYSCTL_SRUSB = 1; + for (i = 0; i < 1000; i++) { + __asm__("nop"); + } + SYSCTL_SRUSB = 0; + + /* + * Wait for the PLL to lock before soft connecting + * This will result in a deadlock if the system clock is not setup + * correctly (clock from main oscillator). + */ + /* Wait for it */ + i = 0; + while ((SYSCTL_RIS & SYSCTL_RIS_USBPLLLRIS) == 0) { + i++; + if (i > 0xffff) { + return 0; + } + } + + /* Now connect to USB */ + lm4f_usb_soft_connect(); + + /* No FIFO allocated yet, but the first 64 bytes are still reserved */ + usbd_dev.fifo_mem_top = 64; + + return &usbd_dev; +} + +/* What is this thing even good for */ +#define RX_FIFO_SIZE 512 + +const struct _usbd_driver lm4f_usb_driver = { + .init = lm4f_usbd_init, + .set_address = lm4f_set_address, + .ep_setup = lm4f_ep_setup, + .ep_reset = lm4f_endpoints_reset, + .ep_stall_set = lm4f_ep_stall_set, + .ep_stall_get = lm4f_ep_stall_get, + .ep_nak_set = lm4f_ep_nak_set, + .ep_write_packet = lm4f_ep_write_packet, + .ep_read_packet = lm4f_ep_read_packet, + .poll = lm4f_poll, + .disconnect = lm4f_disconnect, + .base_address = USB_BASE, + .set_address_before_status = false, + .rx_fifo_size = RX_FIFO_SIZE, +}; +/** + * @endcond + */ + +/** + * @} + */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_msc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_msc.c new file mode 100644 index 00000000..ba18b49c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_msc.c @@ -0,0 +1,829 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Weston Schmidt + * Copyright (C) 2013 Pavol Rusnak + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "usb_private.h" + +/* Definitions of Mass Storage Class from: + * + * (A) "Universal Serial Bus Mass Storage Class Bulk-Only Transport + * Revision 1.0" + * + * (B) "Universal Serial Bus Mass Storage Class Specification Overview + * Revision 1.0" + */ + +/* Command Block Wrapper */ +#define CBW_SIGNATURE 0x43425355 +#define CBW_STATUS_SUCCESS 0 +#define CBW_STATUS_FAILED 1 +#define CBW_STATUS_PHASE_ERROR 2 + +/* Command Status Wrapper */ +#define CSW_SIGNATURE 0x53425355 +#define CSW_STATUS_SUCCESS 0 +#define CSW_STATUS_FAILED 1 +#define CSW_STATUS_PHASE_ERROR 2 + +/* Implemented SCSI Commands */ +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_READ_6 0x08 +#define SCSI_WRITE_6 0x0A +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SENSE_6 0x1A +#define SCSI_SEND_DIAGNOSTIC 0x1D +#define SCSI_READ_CAPACITY 0x25 +#define SCSI_READ_10 0x28 + + +/* Required SCSI Commands */ + +/* Optional SCSI Commands */ +#define SCSI_REPORT_LUNS 0xA0 +#define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E +#define SCSI_MODE_SELECT_6 0x15 +#define SCSI_MODE_SELECT_10 0x55 +#define SCSI_MODE_SENSE_10 0x5A +#define SCSI_READ_12 0xA8 +#define SCSI_READ_FORMAT_CAPACITIES 0x23 +#define SCSI_READ_TOC_PMA_ATIP 0x43 +#define SCSI_START_STOP_UNIT 0x1B +#define SCSI_SYNCHRONIZE_CACHE 0x35 +#define SCSI_VERIFY 0x2F +#define SCSI_WRITE_10 0x2A +#define SCSI_WRITE_12 0xAA + +/* The sense codes */ +enum sbc_sense_key { + SBC_SENSE_KEY_NO_SENSE = 0x00, + SBC_SENSE_KEY_RECOVERED_ERROR = 0x01, + SBC_SENSE_KEY_NOT_READY = 0x02, + SBC_SENSE_KEY_MEDIUM_ERROR = 0x03, + SBC_SENSE_KEY_HARDWARE_ERROR = 0x04, + SBC_SENSE_KEY_ILLEGAL_REQUEST = 0x05, + SBC_SENSE_KEY_UNIT_ATTENTION = 0x06, + SBC_SENSE_KEY_DATA_PROTECT = 0x07, + SBC_SENSE_KEY_BLANK_CHECK = 0x08, + SBC_SENSE_KEY_VENDOR_SPECIFIC = 0x09, + SBC_SENSE_KEY_COPY_ABORTED = 0x0A, + SBC_SENSE_KEY_ABORTED_COMMAND = 0x0B, + SBC_SENSE_KEY_VOLUME_OVERFLOW = 0x0D, + SBC_SENSE_KEY_MISCOMPARE = 0x0E +}; + +enum sbc_asc { + SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION = 0x00, + SBC_ASC_PERIPHERAL_DEVICE_WRITE_FAULT = 0x03, + SBC_ASC_LOGICAL_UNIT_NOT_READY = 0x04, + SBC_ASC_UNRECOVERED_READ_ERROR = 0x11, + SBC_ASC_INVALID_COMMAND_OPERATION_CODE = 0x20, + SBC_ASC_LBA_OUT_OF_RANGE = 0x21, + SBC_ASC_INVALID_FIELD_IN_CDB = 0x24, + SBC_ASC_WRITE_PROTECTED = 0x27, + SBC_ASC_NOT_READY_TO_READY_CHANGE = 0x28, + SBC_ASC_FORMAT_ERROR = 0x31, + SBC_ASC_MEDIUM_NOT_PRESENT = 0x3A +}; + +enum sbc_ascq { + SBC_ASCQ_NA = 0x00, + SBC_ASCQ_FORMAT_COMMAND_FAILED = 0x01, + SBC_ASCQ_INITIALIZING_COMMAND_REQUIRED = 0x02, + SBC_ASCQ_OPERATION_IN_PROGRESS = 0x07 +}; + +enum trans_event { + EVENT_CBW_VALID, + EVENT_NEED_STATUS +}; + +struct usb_msc_cbw { + uint32_t dCBWSignature; + uint32_t dCBWTag; + uint32_t dCBWDataTransferLength; + uint8_t bmCBWFlags; + uint8_t bCBWLUN; + uint8_t bCBWCBLength; + uint8_t CBWCB[16]; +} __attribute__((packed)); + +struct usb_msc_csw { + uint32_t dCSWSignature; + uint32_t dCSWTag; + uint32_t dCSWDataResidue; + uint8_t bCSWStatus; +} __attribute__((packed)); + +struct sbc_sense_info { + uint8_t key; + uint8_t asc; + uint8_t ascq; +}; + +struct usb_msc_trans { + uint8_t cbw_cnt; /* Read until 31 bytes */ + union { + struct usb_msc_cbw cbw; + uint8_t buf[1]; + } cbw; + + uint32_t bytes_to_read; + uint32_t bytes_to_write; + uint32_t byte_count; /* Either read until equal to + bytes_to_read or write until equal + to bytes_to_write. */ + uint32_t lba_start; + uint32_t block_count; + uint32_t current_block; + + uint8_t msd_buf[512]; + + bool csw_valid; + uint8_t csw_sent; /* Write until 13 bytes */ + union { + struct usb_msc_csw csw; + uint8_t buf[1]; + } csw; +}; + +struct _usbd_mass_storage { + usbd_device *usbd_dev; + uint8_t ep_in; + uint8_t ep_in_size; + uint8_t ep_out; + uint8_t ep_out_size; + + const char *vendor_id; + const char *product_id; + const char *product_revision_level; + uint32_t block_count; + + int (*read_block)(uint32_t lba, uint8_t *copy_to); + int (*write_block)(uint32_t lba, const uint8_t *copy_from); + + void (*lock)(void); + void (*unlock)(void); + + struct usb_msc_trans trans; + struct sbc_sense_info sense; +}; + +static usbd_mass_storage _mass_storage; + +/*-- SCSI Base Responses -----------------------------------------------------*/ + +static const uint8_t _spc3_inquiry_response[36] = { + 0x00, /* Byte 0: Peripheral Qualifier = 0, Peripheral Device Type = 0 */ + 0x80, /* Byte 1: RMB = 1, Reserved = 0 */ + 0x04, /* Byte 2: Version = 0 */ + 0x02, /* Byte 3: Obsolete = 0, NormACA = 0, HiSup = 0, Response Data Format = 2 */ + 0x20, /* Byte 4: Additional Length (n-4) = 31 + 4 */ + 0x00, /* Byte 5: SCCS = 0, ACC = 0, TPGS = 0, 3PC = 0, Reserved = 0, Protect = 0 */ + 0x00, /* Byte 6: BQue = 0, EncServ = 0, VS = 0, MultiP = 0, MChngr = 0, Obsolete = 0, Addr16 = 0 */ + 0x00, /* Byte 7: Obsolete = 0, Wbus16 = 0, Sync = 0, Linked = 0, CmdQue = 0, VS = 0 */ + /* Byte 8 - Byte 15: Vendor Identification */ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + /* Byte 16 - Byte 31: Product Identification */ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + /* Byte 32 - Byte 35: Product Revision Level */ + 0x20, 0x20, 0x20, 0x20 +}; + +static const uint8_t _spc3_request_sense[18] = { + 0x70, /* Byte 0: VALID = 0, Response Code = 112 */ + 0x00, /* Byte 1: Obsolete = 0 */ + 0x00, /* Byte 2: Filemark = 0, EOM = 0, ILI = 0, Reserved = 0, Sense Key = 0 */ + /* Byte 3 - Byte 6: Information = 0 */ + 0, 0, 0, 0, + 0x0a, /* Byte 7: Additional Sense Length = 10 */ + /* Byte 8 - Byte 11: Command Specific Info = 0 */ + 0, 0, 0, 0, + 0x00, /* Byte 12: Additional Sense Code (ASC) = 0 */ + 0x00, /* Byte 13: Additional Sense Code Qualifier (ASCQ) = 0 */ + 0x00, /* Byte 14: Field Replaceable Unit Code (FRUC) = 0 */ + 0x00, /* Byte 15: SKSV = 0, SenseKeySpecific[0] = 0 */ + 0x00, /* Byte 16: SenseKeySpecific[0] = 0 */ + 0x00 /* Byte 17: SenseKeySpecific[0] = 0 */ +}; + +/*-- SCSI Layer --------------------------------------------------------------*/ + +static void set_sbc_status(usbd_mass_storage *ms, + enum sbc_sense_key key, + enum sbc_asc asc, + enum sbc_ascq ascq) +{ + ms->sense.key = (uint8_t) key; + ms->sense.asc = (uint8_t) asc; + ms->sense.ascq = (uint8_t) ascq; +} + +static void set_sbc_status_good(usbd_mass_storage *ms) +{ + set_sbc_status(ms, + SBC_SENSE_KEY_NO_SENSE, + SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, + SBC_ASCQ_NA); +} + +static uint8_t *get_cbw_buf(struct usb_msc_trans *trans) +{ + return &trans->cbw.cbw.CBWCB[0]; +} + +static void scsi_read_6(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + if (EVENT_CBW_VALID == event) { + uint8_t *buf; + + buf = get_cbw_buf(trans); + + trans->lba_start = (buf[2] << 8) | buf[3]; + trans->block_count = buf[4]; + trans->current_block = 0; + + /* TODO: Check the lba & block_count for range. */ + + /* both are in terms of 512 byte blocks, so shift by 9 */ + trans->bytes_to_write = trans->block_count << 9; + + set_sbc_status_good(ms); + } +} + +static void scsi_write_6(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + (void) ms; + + if (EVENT_CBW_VALID == event) { + uint8_t *buf; + + buf = get_cbw_buf(trans); + + trans->lba_start = ((0x1f & buf[1]) << 16) + | (buf[2] << 8) | buf[3]; + trans->block_count = buf[4]; + trans->current_block = 0; + + trans->bytes_to_read = trans->block_count << 9; + } +} + +static void scsi_write_10(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + (void) ms; + + if (EVENT_CBW_VALID == event) { + uint8_t *buf; + + buf = get_cbw_buf(trans); + + trans->lba_start = (buf[2] << 24) | (buf[3] << 16) | + (buf[4] << 8) | buf[5]; + trans->block_count = (buf[7] << 8) | buf[8]; + trans->current_block = 0; + + trans->bytes_to_read = trans->block_count << 9; + } +} + +static void scsi_read_10(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + if (EVENT_CBW_VALID == event) { + uint8_t *buf; + + buf = get_cbw_buf(trans); + + trans->lba_start = (buf[2] << 24) | (buf[3] << 16) + | (buf[4] << 8) | buf[5]; + trans->block_count = (buf[7] << 8) | buf[8]; + + /* TODO: Check the lba & block_count for range. */ + + /* both are in terms of 512 byte blocks, so shift by 9 */ + trans->bytes_to_write = trans->block_count << 9; + + set_sbc_status_good(ms); + } +} + +static void scsi_read_capacity(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + if (EVENT_CBW_VALID == event) { + trans->msd_buf[0] = ms->block_count >> 24; + trans->msd_buf[1] = 0xff & (ms->block_count >> 16); + trans->msd_buf[2] = 0xff & (ms->block_count >> 8); + trans->msd_buf[3] = 0xff & ms->block_count; + + /* Block size: 512 */ + trans->msd_buf[4] = 0; + trans->msd_buf[5] = 0; + trans->msd_buf[6] = 2; + trans->msd_buf[7] = 0; + trans->bytes_to_write = 8; + set_sbc_status_good(ms); + } +} + +static void scsi_format_unit(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + if (EVENT_CBW_VALID == event) { + uint32_t i; + + memset(trans->msd_buf, 0, 512); + + for (i = 0; i < ms->block_count; i++) { + (*ms->write_block)(i, trans->msd_buf); + } + + set_sbc_status_good(ms); + } +} + +static void scsi_request_sense(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + if (EVENT_CBW_VALID == event) { + uint8_t *buf; + + buf = &trans->cbw.cbw.CBWCB[0]; + + trans->bytes_to_write = buf[4]; /* allocation length */ + memcpy(trans->msd_buf, _spc3_request_sense, + sizeof(_spc3_request_sense)); + + trans->msd_buf[2] = ms->sense.key; + trans->msd_buf[12] = ms->sense.asc; + trans->msd_buf[13] = ms->sense.ascq; + } +} + +static void scsi_mode_sense_6(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + (void) ms; + + if (EVENT_CBW_VALID == event) { +#if 0 + uint8_t *buf; + uint8_t page_code; + uint8_t allocation_length; + + buf = &trans->cbw.cbw.CBWCB[0]; + page_code = buf[2]; + allocation_length = buf[4]; + + if (0x1C == page_code) { /* Informational Exceptions */ +#endif + trans->bytes_to_write = 4; + + trans->msd_buf[0] = 3; /* Num bytes that follow */ + trans->msd_buf[1] = 0; /* Medium Type */ + trans->msd_buf[2] = 0; /* Device specific param */ + trans->csw.csw.dCSWDataResidue = 4; +#if 0 + } else if (0x01 == page_code) { /* Error recovery */ + } else if (0x3F == page_code) { /* All */ + } else { + /* Error */ + trans->csw.csw.bCSWStatus = CSW_STATUS_FAILED; + set_sbc_status(ms, + SBC_SENSE_KEY_ILLEGAL_REQUEST, + SBC_ASC_INVALID_FIELD_IN_CDB, + SBC_ASCQ_NA); + } +#endif + } +} + +static void scsi_inquiry(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + if (EVENT_CBW_VALID == event) { + uint8_t evpd; + uint8_t *buf; + + buf = get_cbw_buf(trans); + evpd = 1 & buf[1]; + + if (0 == evpd) { + size_t len; + trans->bytes_to_write = sizeof(_spc3_inquiry_response); + memcpy(trans->msd_buf, _spc3_inquiry_response, + sizeof(_spc3_inquiry_response)); + + len = strlen(ms->vendor_id); + len = MIN(len, 8); + memcpy(&trans->msd_buf[8], ms->vendor_id, len); + + len = strlen(ms->product_id); + len = MIN(len, 16); + memcpy(&trans->msd_buf[16], ms->product_id, len); + + len = strlen(ms->product_revision_level); + len = MIN(len, 4); + memcpy(&trans->msd_buf[32], ms->product_revision_level, + len); + + trans->csw.csw.dCSWDataResidue = + sizeof(_spc3_inquiry_response); + + set_sbc_status_good(ms); + } else { + /* TODO: Add VPD 0x83 support */ + /* TODO: Add VPD 0x00 support */ + } + } +} + +static void scsi_command(usbd_mass_storage *ms, + struct usb_msc_trans *trans, + enum trans_event event) +{ + if (EVENT_CBW_VALID == event) { + /* Setup the default success */ + trans->csw_sent = 0; + trans->csw.csw.dCSWSignature = CSW_SIGNATURE; + trans->csw.csw.dCSWTag = trans->cbw.cbw.dCBWTag; + trans->csw.csw.dCSWDataResidue = 0; + trans->csw.csw.bCSWStatus = CSW_STATUS_SUCCESS; + + trans->bytes_to_write = 0; + trans->bytes_to_read = 0; + trans->byte_count = 0; + } + + switch (trans->cbw.cbw.CBWCB[0]) { + case SCSI_TEST_UNIT_READY: + case SCSI_SEND_DIAGNOSTIC: + /* Do nothing, just send the success. */ + set_sbc_status_good(ms); + break; + case SCSI_FORMAT_UNIT: + scsi_format_unit(ms, trans, event); + break; + case SCSI_REQUEST_SENSE: + scsi_request_sense(ms, trans, event); + break; + case SCSI_MODE_SENSE_6: + scsi_mode_sense_6(ms, trans, event); + break; + case SCSI_READ_6: + scsi_read_6(ms, trans, event); + break; + case SCSI_INQUIRY: + scsi_inquiry(ms, trans, event); + break; + case SCSI_READ_CAPACITY: + scsi_read_capacity(ms, trans, event); + break; + case SCSI_READ_10: + scsi_read_10(ms, trans, event); + break; + case SCSI_WRITE_6: + scsi_write_6(ms, trans, event); + break; + case SCSI_WRITE_10: + scsi_write_10(ms, trans, event); + break; + default: + set_sbc_status(ms, SBC_SENSE_KEY_ILLEGAL_REQUEST, + SBC_ASC_INVALID_COMMAND_OPERATION_CODE, + SBC_ASCQ_NA); + + trans->bytes_to_write = 0; + trans->bytes_to_read = 0; + trans->csw.csw.bCSWStatus = CSW_STATUS_FAILED; + break; + } +} + +/*-- USB Mass Storage Layer --------------------------------------------------*/ + +/** @brief Handle the USB 'OUT' requests. */ +static void msc_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) +{ + usbd_mass_storage *ms; + struct usb_msc_trans *trans; + int len, max_len, left; + void *p; + + ms = &_mass_storage; + trans = &ms->trans; + + /* RX only */ + left = sizeof(struct usb_msc_cbw) - trans->cbw_cnt; + if (0 < left) { + max_len = MIN(ms->ep_out_size, left); + p = &trans->cbw.buf[0x1ff & trans->cbw_cnt]; + len = usbd_ep_read_packet(usbd_dev, ep, p, max_len); + trans->cbw_cnt += len; + + if (sizeof(struct usb_msc_cbw) == trans->cbw_cnt) { + scsi_command(ms, trans, EVENT_CBW_VALID); + if (trans->byte_count < trans->bytes_to_read) { + /* We must wait until there is something to + * read again. */ + return; + } + } + } + + if (trans->byte_count < trans->bytes_to_read) { + if (0 < trans->block_count) { + if ((0 == trans->byte_count) && (NULL != ms->lock)) { + (*ms->lock)(); + } + } + + left = trans->bytes_to_read - trans->byte_count; + max_len = MIN(ms->ep_out_size, left); + p = &trans->msd_buf[0x1ff & trans->byte_count]; + len = usbd_ep_read_packet(usbd_dev, ep, p, max_len); + trans->byte_count += len; + + if (0 < trans->block_count) { + if (0 == (0x1ff & trans->byte_count)) { + uint32_t lba; + + lba = trans->lba_start + trans->current_block; + if (0 != (*ms->write_block)(lba, + trans->msd_buf)) { + /* Error */ + } + trans->current_block++; + } + } + } else if (trans->byte_count < trans->bytes_to_write) { + if (0 < trans->block_count) { + if ((0 == trans->byte_count) && (NULL != ms->lock)) { + (*ms->lock)(); + } + + if (0 == (0x1ff & trans->byte_count)) { + uint32_t lba; + + lba = trans->lba_start + trans->current_block; + if (0 != (*ms->read_block)(lba, + trans->msd_buf)) { + /* Error */ + } + trans->current_block++; + } + } + + left = trans->bytes_to_write - trans->byte_count; + max_len = MIN(ms->ep_out_size, left); + p = &trans->msd_buf[0x1ff & trans->byte_count]; + len = usbd_ep_write_packet(usbd_dev, ms->ep_in, p, max_len); + trans->byte_count += len; + } else { + if (0 < trans->block_count) { + if (trans->current_block == trans->block_count) { + uint32_t lba; + + lba = trans->lba_start + trans->current_block; + if (0 != (*ms->write_block)(lba, + trans->msd_buf)) { + /* Error */ + } + + trans->current_block = 0; + if (NULL != ms->unlock) { + (*ms->unlock)(); + } + } + } + if (false == trans->csw_valid) { + scsi_command(ms, trans, EVENT_NEED_STATUS); + trans->csw_valid = true; + } + + left = sizeof(struct usb_msc_csw) - trans->csw_sent; + if (0 < left) { + max_len = MIN(ms->ep_out_size, left); + p = &trans->csw.buf[trans->csw_sent]; + len = usbd_ep_write_packet(usbd_dev, ms->ep_in, p, + max_len); + trans->csw_sent += len; + } + } +} + +/** @brief Handle the USB 'IN' requests. */ +static void msc_data_tx_cb(usbd_device *usbd_dev, uint8_t ep) +{ + usbd_mass_storage *ms; + struct usb_msc_trans *trans; + int len, max_len, left; + void *p; + + ms = &_mass_storage; + trans = &ms->trans; + + if (trans->byte_count < trans->bytes_to_write) { + if (0 < trans->block_count) { + if (0 == (0x1ff & trans->byte_count)) { + uint32_t lba; + + lba = trans->lba_start + trans->current_block; + if (0 != (*ms->read_block)(lba, + trans->msd_buf)) { + /* Error */ + } + trans->current_block++; + } + } + + left = trans->bytes_to_write - trans->byte_count; + max_len = MIN(ms->ep_out_size, left); + p = &trans->msd_buf[0x1ff & trans->byte_count]; + len = usbd_ep_write_packet(usbd_dev, ep, p, max_len); + trans->byte_count += len; + } else { + if (0 < trans->block_count) { + if (trans->current_block == trans->block_count) { + trans->current_block = 0; + if (NULL != ms->unlock) { + (*ms->unlock)(); + } + } + } + if (false == trans->csw_valid) { + scsi_command(ms, trans, EVENT_NEED_STATUS); + trans->csw_valid = true; + } + + left = sizeof(struct usb_msc_csw) - trans->csw_sent; + if (0 < left) { + max_len = MIN(ms->ep_out_size, left); + p = &trans->csw.buf[trans->csw_sent]; + len = usbd_ep_write_packet(usbd_dev, ep, p, max_len); + trans->csw_sent += len; + } else if (sizeof(struct usb_msc_csw) == trans->csw_sent) { + /* End of transaction */ + trans->lba_start = 0xffffffff; + trans->block_count = 0; + trans->current_block = 0; + trans->cbw_cnt = 0; + trans->bytes_to_read = 0; + trans->bytes_to_write = 0; + trans->byte_count = 0; + trans->csw_sent = 0; + trans->csw_valid = false; + } + } +} + +/** @brief Handle various control requests related to the msc storage + * interface. + */ +static int msc_control_request(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len, + usbd_control_complete_callback *complete) +{ + (void)complete; + (void)usbd_dev; + + switch (req->bRequest) { + case USB_MSC_REQ_BULK_ONLY_RESET: + /* Do any special reset code here. */ + return USBD_REQ_HANDLED; + case USB_MSC_REQ_GET_MAX_LUN: + /* Return the number of LUNs. We use 0. */ + *buf[0] = 0; + *len = 1; + return USBD_REQ_HANDLED; + } + + return USBD_REQ_NOTSUPP; +} + +/** @brief Setup the endpoints to be bulk & register the callbacks. */ +static void msc_set_config(usbd_device *usbd_dev, uint16_t wValue) +{ + usbd_mass_storage *ms = &_mass_storage; + + (void)wValue; + + usbd_ep_setup(usbd_dev, ms->ep_in, USB_ENDPOINT_ATTR_BULK, + ms->ep_in_size, msc_data_tx_cb); + usbd_ep_setup(usbd_dev, ms->ep_out, USB_ENDPOINT_ATTR_BULK, + ms->ep_out_size, msc_data_rx_cb); + + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + msc_control_request); +} + +/** @addtogroup usb_msc */ +/** @{ */ + +/** @brief Initializes the USB Mass Storage subsystem. + +@note Currently you can only have this profile active. + +@param[in] usbd_dev The USB device to associate the Mass Storage with. +@param[in] ep_in The USB 'IN' endpoint. +@param[in] ep_in_size The maximum endpoint size. Valid values: 8, 16, 32 or 64 +@param[in] ep_out The USB 'OUT' endpoint. +@param[in] ep_out_size The maximum endpoint size. Valid values: 8, 16, 32 or 64 +@param[in] vendor_id The SCSI vendor ID to return. Maximum used length is 8. +@param[in] product_id The SCSI product ID to return. Maximum used length is 16. +@param[in] product_revision_level The SCSI product revision level to return. + Maximum used length is 4. +@param[in] block_count The number of 512-byte blocks available. +@param[in] read_block The function called when the host requests to read a LBA + block. Must _NOT_ be NULL. +@param[in] write_block The function called when the host requests to write a + LBA block. Must _NOT_ be NULL. + +@return Pointer to the usbd_mass_storage struct. +*/ +usbd_mass_storage *usb_msc_init(usbd_device *usbd_dev, + uint8_t ep_in, uint8_t ep_in_size, + uint8_t ep_out, uint8_t ep_out_size, + const char *vendor_id, + const char *product_id, + const char *product_revision_level, + const uint32_t block_count, + int (*read_block)(uint32_t lba, + uint8_t *copy_to), + int (*write_block)(uint32_t lba, + const uint8_t *copy_from)) +{ + _mass_storage.usbd_dev = usbd_dev; + _mass_storage.ep_in = ep_in; + _mass_storage.ep_in_size = ep_in_size; + _mass_storage.ep_out = ep_out; + _mass_storage.ep_out_size = ep_out_size; + _mass_storage.vendor_id = vendor_id; + _mass_storage.product_id = product_id; + _mass_storage.product_revision_level = product_revision_level; + _mass_storage.block_count = block_count - 1; + _mass_storage.read_block = read_block; + _mass_storage.write_block = write_block; + _mass_storage.lock = NULL; + _mass_storage.unlock = NULL; + + _mass_storage.trans.lba_start = 0xffffffff; + _mass_storage.trans.block_count = 0; + _mass_storage.trans.current_block = 0; + _mass_storage.trans.cbw_cnt = 0; + _mass_storage.trans.bytes_to_read = 0; + _mass_storage.trans.bytes_to_write = 0; + _mass_storage.trans.byte_count = 0; + _mass_storage.trans.csw_valid = false; + _mass_storage.trans.csw_sent = 0; + + set_sbc_status_good(&_mass_storage); + + usbd_register_set_config_callback(usbd_dev, msc_set_config); + + return &_mass_storage; +} + +/** @} */ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_private.h b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_private.h new file mode 100644 index 00000000..4a3b9e0b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_private.h @@ -0,0 +1,163 @@ +/** @defgroup usb_private_defines USB Private Structures + +@brief Defined Constants and Types for the USB Private Structures + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __USB_PRIVATE_H +#define __USB_PRIVATE_H + +#define MAX_USER_CONTROL_CALLBACK 4 +#define MAX_USER_SET_CONFIG_CALLBACK 4 + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +/** Internal collection of device information. */ +struct _usbd_device { + const struct usb_device_descriptor *desc; + const struct usb_config_descriptor *config; + const char **strings; + int num_strings; + + uint8_t *ctrl_buf; /**< Internal buffer used for control transfers */ + uint16_t ctrl_buf_len; + + uint8_t current_address; + uint8_t current_config; + + uint16_t pm_top; /**< Top of allocated endpoint buffer memory */ + + /* User callback functions for various USB events */ + void (*user_callback_reset)(void); + void (*user_callback_suspend)(void); + void (*user_callback_resume)(void); + void (*user_callback_sof)(void); + + struct usb_control_state { + enum { + IDLE, STALLED, + DATA_IN, LAST_DATA_IN, STATUS_IN, + DATA_OUT, LAST_DATA_OUT, STATUS_OUT, + } state; + struct usb_setup_data req __attribute__((aligned(4))); + uint8_t *ctrl_buf; + uint16_t ctrl_len; + usbd_control_complete_callback complete; + bool needs_zlp; + } control_state; + + struct user_control_callback { + usbd_control_callback cb; + uint8_t type; + uint8_t type_mask; + } user_control_callback[MAX_USER_CONTROL_CALLBACK]; + + usbd_endpoint_callback user_callback_ctr[8][3]; + + /* User callback function for some standard USB function hooks */ + usbd_set_config_callback user_callback_set_config[MAX_USER_SET_CONFIG_CALLBACK]; + + usbd_set_altsetting_callback user_callback_set_altsetting; + + const struct _usbd_driver *driver; + + /* private driver data */ + + uint16_t fifo_mem_top; + uint16_t fifo_mem_top_ep0; + uint8_t force_nak[4]; + /* + * We keep a backup copy of the out endpoint size registers to restore + * them after a transaction. + */ + uint32_t doeptsiz[4]; + /* + * Received packet size for each endpoint. This is assigned in + * stm32f107_poll() which reads the packet status push register GRXSTSP + * for use in stm32f107_ep_read_packet(). + */ + uint16_t rxbcnt; +}; + +enum _usbd_transaction { + USB_TRANSACTION_IN, + USB_TRANSACTION_OUT, + USB_TRANSACTION_SETUP, +}; + +/* Do not appear to belong to the API, so are omitted from docs */ +/**@}*/ + +void _usbd_control_in(usbd_device *usbd_dev, uint8_t ea); +void _usbd_control_out(usbd_device *usbd_dev, uint8_t ea); +void _usbd_control_setup(usbd_device *usbd_dev, uint8_t ea); + +int _usbd_standard_request_device(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len); +int _usbd_standard_request_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len); +int _usbd_standard_request_endpoint(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len); +int _usbd_standard_request(usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len); + +void _usbd_reset(usbd_device *usbd_dev); + +/* Functions provided by the hardware abstraction. */ +struct _usbd_driver { + usbd_device *(*init)(void); + void (*set_address)(usbd_device *usbd_dev, uint8_t addr); + void (*ep_setup)(usbd_device *usbd_dev, uint8_t addr, uint8_t type, + uint16_t max_size, usbd_endpoint_callback cb); + void (*ep_reset)(usbd_device *usbd_dev); + void (*ep_stall_set)(usbd_device *usbd_dev, uint8_t addr, + uint8_t stall); + void (*ep_nak_set)(usbd_device *usbd_dev, uint8_t addr, uint8_t nak); + uint8_t (*ep_stall_get)(usbd_device *usbd_dev, uint8_t addr); + uint16_t (*ep_write_packet)(usbd_device *usbd_dev, uint8_t addr, + const void *buf, uint16_t len); + uint16_t (*ep_read_packet)(usbd_device *usbd_dev, uint8_t addr, + void *buf, uint16_t len); + void (*poll)(usbd_device *usbd_dev); + void (*disconnect)(usbd_device *usbd_dev, bool disconnected); + uint32_t base_address; + bool set_address_before_status; + uint16_t rx_fifo_size; +}; + +#endif + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_standard.c b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_standard.c new file mode 100644 index 00000000..d94ceed9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/usb/usb_standard.c @@ -0,0 +1,600 @@ +/** @defgroup usb_standard_file Generic USB Standard Request Interface + +@ingroup USB + +@brief Generic USB Standard Request Interface + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include +#include "usb_private.h" + +int usbd_register_set_config_callback(usbd_device *usbd_dev, + usbd_set_config_callback callback) +{ + int i; + + for (i = 0; i < MAX_USER_SET_CONFIG_CALLBACK; i++) { + if (usbd_dev->user_callback_set_config[i]) { + continue; + } + + usbd_dev->user_callback_set_config[i] = callback; + return 0; + } + + return -1; +} + +void usbd_register_set_altsetting_callback(usbd_device *usbd_dev, + usbd_set_altsetting_callback callback) +{ + usbd_dev->user_callback_set_altsetting = callback; +} + +static uint16_t build_config_descriptor(usbd_device *usbd_dev, + uint8_t index, uint8_t *buf, uint16_t len) +{ + uint8_t *tmpbuf = buf; + const struct usb_config_descriptor *cfg = &usbd_dev->config[index]; + uint16_t count, total = 0, totallen = 0; + uint16_t i, j, k; + + memcpy(buf, cfg, count = MIN(len, cfg->bLength)); + buf += count; + len -= count; + total += count; + totallen += cfg->bLength; + + /* For each interface... */ + for (i = 0; i < cfg->bNumInterfaces; i++) { + /* Interface Association Descriptor, if any */ + if (cfg->interface[i].iface_assoc) { + const struct usb_iface_assoc_descriptor *assoc = + cfg->interface[i].iface_assoc; + memcpy(buf, assoc, count = MIN(len, assoc->bLength)); + buf += count; + len -= count; + total += count; + totallen += assoc->bLength; + } + /* For each alternate setting... */ + for (j = 0; j < cfg->interface[i].num_altsetting; j++) { + const struct usb_interface_descriptor *iface = + &cfg->interface[i].altsetting[j]; + /* Copy interface descriptor. */ + memcpy(buf, iface, count = MIN(len, iface->bLength)); + buf += count; + len -= count; + total += count; + totallen += iface->bLength; + /* Copy extra bytes (function descriptors). */ + if (iface->extra) { + memcpy(buf, iface->extra, + count = MIN(len, iface->extralen)); + buf += count; + len -= count; + total += count; + totallen += iface->extralen; + } + /* For each endpoint... */ + for (k = 0; k < iface->bNumEndpoints; k++) { + const struct usb_endpoint_descriptor *ep = + &iface->endpoint[k]; + memcpy(buf, ep, count = MIN(len, ep->bLength)); + buf += count; + len -= count; + total += count; + totallen += ep->bLength; + /* Copy extra bytes (class specific). */ + if (ep->extra) { + memcpy(buf, ep->extra, + count = MIN(len, ep->extralen)); + buf += count; + len -= count; + total += count; + totallen += ep->extralen; + } + } + } + } + + /* Fill in wTotalLength. */ + *(uint16_t *)(tmpbuf + 2) = totallen; + + return total; +} + +static int usb_descriptor_type(uint16_t wValue) +{ + return wValue >> 8; +} + +static int usb_descriptor_index(uint16_t wValue) +{ + return wValue & 0xFF; +} + +static int usb_standard_get_descriptor(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + int i, array_idx, descr_idx; + struct usb_string_descriptor *sd; + + descr_idx = usb_descriptor_index(req->wValue); + + switch (usb_descriptor_type(req->wValue)) { + case USB_DT_DEVICE: + *buf = (uint8_t *) usbd_dev->desc; + *len = MIN(*len, usbd_dev->desc->bLength); + return USBD_REQ_HANDLED; + case USB_DT_CONFIGURATION: + *buf = usbd_dev->ctrl_buf; + *len = build_config_descriptor(usbd_dev, descr_idx, *buf, *len); + return USBD_REQ_HANDLED; + case USB_DT_STRING: + sd = (struct usb_string_descriptor *)usbd_dev->ctrl_buf; + + if (descr_idx == 0) { + /* Send sane Language ID descriptor... */ + sd->wData[0] = USB_LANGID_ENGLISH_US; + sd->bLength = sizeof(sd->bLength) + + sizeof(sd->bDescriptorType) + + sizeof(sd->wData[0]); + + *len = MIN(*len, sd->bLength); + } else { + array_idx = descr_idx - 1; + + if (!usbd_dev->strings) { + /* Device doesn't support strings. */ + return USBD_REQ_NOTSUPP; + } + + /* Check that string index is in range. */ + if (array_idx >= usbd_dev->num_strings) { + return USBD_REQ_NOTSUPP; + } + + /* Strings with Language ID differnet from + * USB_LANGID_ENGLISH_US are not supported */ + if (req->wIndex != USB_LANGID_ENGLISH_US) { + return USBD_REQ_NOTSUPP; + } + + /* This string is returned as UTF16, hence the + * multiplication + */ + sd->bLength = strlen(usbd_dev->strings[array_idx]) * 2 + + sizeof(sd->bLength) + + sizeof(sd->bDescriptorType); + + *len = MIN(*len, sd->bLength); + + for (i = 0; i < (*len / 2) - 1; i++) { + sd->wData[i] = + usbd_dev->strings[array_idx][i]; + } + } + + sd->bDescriptorType = USB_DT_STRING; + *buf = (uint8_t *)sd; + + return USBD_REQ_HANDLED; + } + return USBD_REQ_NOTSUPP; +} + +static int usb_standard_set_address(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len) +{ + (void)req; + (void)buf; + (void)len; + + /* The actual address is only latched at the STATUS IN stage. */ + if ((req->bmRequestType != 0) || (req->wValue >= 128)) { + return 0; + } + + usbd_dev->current_address = req->wValue; + + /* + * Special workaround for STM32F10[57] that require the address + * to be set here. This is undocumented! + */ + if (usbd_dev->driver->set_address_before_status) { + usbd_dev->driver->set_address(usbd_dev, req->wValue); + } + + return 1; +} + +static int usb_standard_set_configuration(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + unsigned i; + int found_index = -1; + const struct usb_config_descriptor *cfg; + + (void)req; + (void)buf; + (void)len; + + if (req->wValue > 0) { + for (i = 0; i < usbd_dev->desc->bNumConfigurations; i++) { + if (req->wValue + == usbd_dev->config[i].bConfigurationValue) { + found_index = i; + break; + } + } + if (found_index < 0) { + return USBD_REQ_NOTSUPP; + } + } + + usbd_dev->current_config = found_index + 1; + + if (usbd_dev->current_config > 0) { + cfg = &usbd_dev->config[usbd_dev->current_config - 1]; + + /* reset all alternate settings configuration */ + for (i = 0; i < cfg->bNumInterfaces; i++) { + if (cfg->interface[i].cur_altsetting) { + *cfg->interface[i].cur_altsetting = 0; + } + } + } + + /* Reset all endpoints. */ + usbd_dev->driver->ep_reset(usbd_dev); + + if (usbd_dev->user_callback_set_config[0]) { + /* + * Flush control callbacks. These will be reregistered + * by the user handler. + */ + for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) { + usbd_dev->user_control_callback[i].cb = NULL; + } + + for (i = 0; i < MAX_USER_SET_CONFIG_CALLBACK; i++) { + if (usbd_dev->user_callback_set_config[i]) { + usbd_dev->user_callback_set_config[i](usbd_dev, + req->wValue); + } + } + } + + return 1; +} + +static int usb_standard_get_configuration(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + (void)req; + + if (*len > 1) { + *len = 1; + } + if (usbd_dev->current_config > 0) { + const struct usb_config_descriptor *cfg = + &usbd_dev->config[usbd_dev->current_config - 1]; + (*buf)[0] = cfg->bConfigurationValue; + } else { + (*buf)[0] = 0; + } + + return 1; +} + +static int usb_standard_set_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + const struct usb_config_descriptor *cfx = + &usbd_dev->config[usbd_dev->current_config - 1]; + const struct usb_interface *iface; + + (void)buf; + + if (req->wIndex >= cfx->bNumInterfaces) { + return USBD_REQ_NOTSUPP; + } + + iface = &cfx->interface[req->wIndex]; + + if (req->wValue >= iface->num_altsetting) { + return USBD_REQ_NOTSUPP; + } + + if (iface->cur_altsetting) { + *iface->cur_altsetting = req->wValue; + } else if (req->wValue > 0) { + return USBD_REQ_NOTSUPP; + } + + if (usbd_dev->user_callback_set_altsetting) { + usbd_dev->user_callback_set_altsetting(usbd_dev, + req->wIndex, + req->wValue); + } + + *len = 0; + + return USBD_REQ_HANDLED; +} + +static int usb_standard_get_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + uint8_t *cur_altsetting; + const struct usb_config_descriptor *cfx = + &usbd_dev->config[usbd_dev->current_config - 1]; + + if (req->wIndex >= cfx->bNumInterfaces) { + return USBD_REQ_NOTSUPP; + } + + *len = 1; + cur_altsetting = cfx->interface[req->wIndex].cur_altsetting; + (*buf)[0] = (cur_altsetting) ? *cur_altsetting : 0; + + return USBD_REQ_HANDLED; +} + +static int usb_standard_device_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + (void)usbd_dev; + (void)req; + + /* bit 0: self powered */ + /* bit 1: remote wakeup */ + if (*len > 2) { + *len = 2; + } + (*buf)[0] = 0; + (*buf)[1] = 0; + + return 1; +} + +static int usb_standard_interface_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + (void)usbd_dev; + (void)req; + /* not defined */ + + if (*len > 2) { + *len = 2; + } + (*buf)[0] = 0; + (*buf)[1] = 0; + + return 1; +} + +static int usb_standard_endpoint_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + (void)req; + + if (*len > 2) { + *len = 2; + } + (*buf)[0] = usbd_ep_stall_get(usbd_dev, req->wIndex) ? 1 : 0; + (*buf)[1] = 0; + + return 1; +} + +static int usb_standard_endpoint_stall(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + (void)buf; + (void)len; + + usbd_ep_stall_set(usbd_dev, req->wIndex, 1); + + return 1; +} + +static int usb_standard_endpoint_unstall(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + (void)buf; + (void)len; + + usbd_ep_stall_set(usbd_dev, req->wIndex, 0); + + return 1; +} + +/* Do not appear to belong to the API, so are omitted from docs */ +/**@}*/ + +int _usbd_standard_request_device(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len) +{ + int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) = NULL; + + switch (req->bRequest) { + case USB_REQ_CLEAR_FEATURE: + case USB_REQ_SET_FEATURE: + if (req->wValue == USB_FEAT_DEVICE_REMOTE_WAKEUP) { + /* Device wakeup code goes here. */ + } + + if (req->wValue == USB_FEAT_TEST_MODE) { + /* Test mode code goes here. */ + } + + break; + case USB_REQ_SET_ADDRESS: + /* + * SET ADDRESS is an exception. + * It is only processed at STATUS stage. + */ + command = usb_standard_set_address; + break; + case USB_REQ_SET_CONFIGURATION: + command = usb_standard_set_configuration; + break; + case USB_REQ_GET_CONFIGURATION: + command = usb_standard_get_configuration; + break; + case USB_REQ_GET_DESCRIPTOR: + command = usb_standard_get_descriptor; + break; + case USB_REQ_GET_STATUS: + /* + * GET_STATUS always responds with zero reply. + * The application may override this behaviour. + */ + command = usb_standard_device_get_status; + break; + case USB_REQ_SET_DESCRIPTOR: + /* SET_DESCRIPTOR is optional and not implemented. */ + break; + } + + if (!command) { + return 0; + } + + return command(usbd_dev, req, buf, len); +} + +int _usbd_standard_request_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len) +{ + int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) = NULL; + + switch (req->bRequest) { + case USB_REQ_CLEAR_FEATURE: + case USB_REQ_SET_FEATURE: + /* not defined */ + break; + case USB_REQ_GET_INTERFACE: + command = usb_standard_get_interface; + break; + case USB_REQ_SET_INTERFACE: + command = usb_standard_set_interface; + break; + case USB_REQ_GET_STATUS: + command = usb_standard_interface_get_status; + break; + } + + if (!command) { + return 0; + } + + return command(usbd_dev, req, buf, len); +} + +int _usbd_standard_request_endpoint(usbd_device *usbd_dev, + struct usb_setup_data *req, uint8_t **buf, + uint16_t *len) +{ + int (*command) (usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) = NULL; + + switch (req->bRequest) { + case USB_REQ_CLEAR_FEATURE: + if (req->wValue == USB_FEAT_ENDPOINT_HALT) { + command = usb_standard_endpoint_unstall; + } + break; + case USB_REQ_SET_FEATURE: + if (req->wValue == USB_FEAT_ENDPOINT_HALT) { + command = usb_standard_endpoint_stall; + } + break; + case USB_REQ_GET_STATUS: + command = usb_standard_endpoint_get_status; + break; + case USB_REQ_SET_SYNCH_FRAME: + /* FIXME: SYNCH_FRAME is not implemented. */ + /* + * SYNCH_FRAME is used for synchronization of isochronous + * endpoints which are not yet implemented. + */ + break; + } + + if (!command) { + return 0; + } + + return command(usbd_dev, req, buf, len); +} + +int _usbd_standard_request(usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len) +{ + /* FIXME: Have class/vendor requests as well. */ + if ((req->bmRequestType & USB_REQ_TYPE_TYPE) != USB_REQ_TYPE_STANDARD) { + return 0; + } + + switch (req->bmRequestType & USB_REQ_TYPE_RECIPIENT) { + case USB_REQ_TYPE_DEVICE: + return _usbd_standard_request_device(usbd_dev, req, buf, len); + case USB_REQ_TYPE_INTERFACE: + return _usbd_standard_request_interface(usbd_dev, req, + buf, len); + case USB_REQ_TYPE_ENDPOINT: + return _usbd_standard_request_endpoint(usbd_dev, req, buf, len); + default: + return 0; + } +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/Makefile b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/Makefile new file mode 100644 index 00000000..d87247be --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/Makefile @@ -0,0 +1,43 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2014 Stefan Agner +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_vf6xx +SRCLIBDIR ?= .. + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../include -fno-common \ + -mcpu=cortex-m4 -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DVF6XX +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +ARFLAGS = rcs +OBJS = ccm.o uart.o gpio.o iomuxc.o + +VPATH += ../cm3 + +include ../Makefile.include diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/ccm.c b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/ccm.c new file mode 100644 index 00000000..417d4a46 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/ccm.c @@ -0,0 +1,202 @@ +/** @defgroup ccm_file CCM + * + * @ingroup VF6xx + * + * @section vf6xx_ccm_api_ex Clock Controller Module API. + * + * @brief VF6xx Clock Controller Module + * + * @author @htmlonly © @endhtmlonly 2014 Stefan Agner + * + * @date 30 Jun 2014 + * + * This library supports the Clock Controller Module in the VF6xx SoCs + * by Freescale. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +/**@{*/ +static const uint32_t pll1_main_clk = 528000000; +static const uint32_t pll2_main_clk = 528000000; +static const uint32_t pll3_main_clk = 480000000; + +/* ARM Cortex-A5 clock, core clock */ +uint32_t ccm_core_clk; + +/* Platform bus clock and Cortex-M4 core clock */ +uint32_t ccm_platform_bus_clk; + +/* IPS bus clock */ +uint32_t ccm_ipg_bus_clk; + + +uint32_t ccm_get_pll_pfd(uint32_t pfd_sel, uint32_t pll_pfd, uint32_t pll_clk); + + +/*---------------------------------------------------------------------------*/ +/** @brief Enable clock of given device + +This enables (gates) the clock for the given device. +@param[in] gr enum ccm_clock_gate. Device +*/ +void ccm_clock_gate_enable(enum ccm_clock_gate gr) +{ + uint32_t offset = (uint32_t)gr / 16; + uint32_t gr_mask = 0x3 << ((gr % 16) * 2); + CCM_CCGR(offset * 4) |= gr_mask; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable clock of given device + +This disables (ungates) the clock for the given device. +@param[in] gr enum ccm_clock_gate. Device +*/ + +void ccm_clock_gate_disable(enum ccm_clock_gate gr) +{ + uint32_t offset = (uint32_t)gr / 16; + uint32_t gr_mask = 0x3 << ((gr % 16) * 2); + CCM_CCGR(offset * 4) &= ~gr_mask; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Calculate PFD clock + +This function calculates the PFD clock for PLL1/2 or 3. All those PLLs +have the same PFD clock muxing/calculating logic, hence we can use one +function for all of them + +@param[in] pfd_sel uint32_t. The PFD selection (muxing) value +@param[in] pll_pfd uint32_t. The ANADIG PFD register containing the fractions +for all possible PFDs +@param[in] pll_clk uint32_t. PLLs main clock (which the PFDs are derived from) +*/ + +uint32_t ccm_get_pll_pfd(uint32_t pfd_sel, uint32_t pll_pfd, uint32_t pll_clk) +{ + uint64_t pll_pfd_clk; + uint32_t pll_pfd_frac = pll_pfd; + + switch (pfd_sel) { + case CCM_CCSR_PLL_PFD_CLK_SEL_MAIN: + return pll_clk; + case CCM_CCSR_PLL_PFD_CLK_SEL_PFD1: + pll_pfd_frac &= ANADIG_PLL_PFD1_FRAC_MASK; + pll_pfd_frac >>= ANADIG_PLL_PFD1_FRAC_SHIFT; + break; + case CCM_CCSR_PLL_PFD_CLK_SEL_PFD2: + pll_pfd_frac &= ANADIG_PLL_PFD2_FRAC_MASK; + pll_pfd_frac >>= ANADIG_PLL_PFD2_FRAC_SHIFT; + break; + case CCM_CCSR_PLL_PFD_CLK_SEL_PFD3: + pll_pfd_frac &= ANADIG_PLL_PFD3_FRAC_MASK; + pll_pfd_frac >>= ANADIG_PLL_PFD3_FRAC_SHIFT; + break; + case CCM_CCSR_PLL_PFD_CLK_SEL_PFD4: + pll_pfd_frac &= ANADIG_PLL_PFD4_FRAC_MASK; + pll_pfd_frac >>= ANADIG_PLL_PFD4_FRAC_SHIFT; + break; + } + + /* Calculate using to PLL PFD fraction */ + pll_pfd_clk = pll_clk; + pll_pfd_clk *= 18; + pll_pfd_clk /= pll_pfd_frac; + + return (uint32_t)pll_pfd_clk; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Calculate clocks + +This function calculates the root clocks from the registers. On Vybrid, we +assume that the clocks/device is setup by the main operating system running +on the Cortex-A5 (for instance Linux). However, in order to calculate clocks +for peripherals its important to know the current value of those clocks. + +This are mainly the @ref ccm_core_clk which the Cortex-A5 is running with +and lots of other clocks derive from. +The @ref ccm_platform_bus_clk is the clock which the Cortex-M4 is running +with. +And the @ref ccm_ipg_bus_clk is the clock most peripherals run with. + +*/ + +void ccm_calculate_clocks() +{ + uint32_t ccsr = CCM_CCSR; + uint32_t cacrr = CCM_CACRR; + uint32_t arm_clk_div = (cacrr & CCM_CACRR_ARM_CLK_DIV_MASK) + 1; + uint32_t bus_clk_div = cacrr & CCM_CACRR_BUS_CLK_DIV_MASK; + uint32_t ipg_clk_div = cacrr & CCM_CACRR_IPG_CLK_DIV_MASK; + uint32_t pll_pfd_sel; + + bus_clk_div >>= CCM_CACRR_BUS_CLK_DIV_SHIFT; + bus_clk_div += 1; + + ipg_clk_div >>= CCM_CACRR_IPG_CLK_DIV_SHIFT; + ipg_clk_div += 1; + + /* Get Cortex-A5 core clock from system clock selection */ + switch (ccsr & CCM_CCSR_SYS_CLK_SEL_MASK) { + case CCM_CCSR_SYS_CLK_SEL_FAST: + ccm_core_clk = 24000000; + break; + case CCM_CCSR_SYS_CLK_SEL_SLOW: + ccm_core_clk = 32000; + break; + case CCM_CCSR_SYS_CLK_SEL_PLL2_PFD: + pll_pfd_sel = ccsr & CCM_CCSR_PLL2_PFD_CLK_SEL_MASK; + pll_pfd_sel >>= CCM_CCSR_PLL2_PFD_CLK_SEL_SHIFT; + + ccm_core_clk = ccm_get_pll_pfd(pll_pfd_sel, ANADIG_PLL2_PFD, + pll2_main_clk); + break; + case CCM_CCSR_SYS_CLK_SEL_PLL2: + ccm_core_clk = pll2_main_clk; + break; + case CCM_CCSR_SYS_CLK_SEL_PLL1_PFD: + pll_pfd_sel = ccsr & CCM_CCSR_PLL1_PFD_CLK_SEL_MASK; + pll_pfd_sel >>= CCM_CCSR_PLL1_PFD_CLK_SEL_SHIFT; + + ccm_core_clk = ccm_get_pll_pfd(pll_pfd_sel, ANADIG_PLL1_PFD, + pll1_main_clk); + break; + case CCM_CCSR_SYS_CLK_SEL_PLL3: + ccm_core_clk = pll3_main_clk; + break; + } + + ccm_core_clk /= arm_clk_div; + ccm_platform_bus_clk = ccm_core_clk / bus_clk_div; + ccm_ipg_bus_clk = ccm_platform_bus_clk / ipg_clk_div; + + return; +} + +/**@}*/ diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/gpio.c b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/gpio.c new file mode 100644 index 00000000..01bde899 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/gpio.c @@ -0,0 +1,131 @@ +/** @defgroup VF6xx_gpio GPIO + * + * @ingroup VF6xx + * + * @section vf6xx_gpio_api_ex GPIO API. + * + * @brief VF6xx General-Purpose Input/Output (GPIO) + * + * @author @htmlonly © @endhtmlonly 2014 Stefan Agner + * + * @date 03 July 2014 + * + * This library supports the GPIO module in the VF6xx SoC of Freescale. + * Access is provided by GPIO number according to the Pinmux list of the + * Reference Manual, similar as GPIOs are available on Linux. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO + +Set GPIO by GPIO number according to MUX list + +@param[in] gpio unsigned 32 bit. GPIO number +*/ + +void gpio_set(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + GPIO_PSOR(port) = GPIO_OFFSET(gpio); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO + +Clears GPIO by GPIO number according to MUX list + +@param[in] gpio unsigned 32 bit. GPIO number +*/ + +void gpio_clear(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + GPIO_PCOR(port) = GPIO_OFFSET(gpio); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get GPIOs logic state + +Get logic level of GPIO given by GPIO number according to MUX list. Reading +a GPIO value is possible even if the port is not muxed for GPIO. + +@param[in] gpio unsigned 32 bit. GPIO number +@returns the logic state of the given GPIO. +*/ + +bool gpio_get(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + return !!(GPIO_PDIR(port) & GPIO_OFFSET(gpio)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Toggles GPIO + +Toggles GPIO by GPIO number according to MUX list + +@param[in] gpio unsigned 32 bit. GPIO number +*/ + +void gpio_toggle(uint32_t gpio) +{ + uint32_t port = GPIO(gpio / 32); + GPIO_PTOR(port) = GPIO_OFFSET(gpio); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read a whole GPIO Port + +Gets all 32 GPIOs of a Port. + +@param[in] gpioport unsigned 32 bit. GPIO port @ref gpio_reg_base +@returns the logic states of the given GPIO port. +*/ + +uint32_t gpio_port_read(uint32_t gpioport) +{ + return GPIO_PDIR(gpioport); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Write a whole GPIO Port + +Sets all 32 GPIOs of a Port. + +@param[in] gpioport unsigned 32 bit. GPIO port @ref gpio_reg_base +@param[in] gpio unsigned 32 bit. 1 for a logic 1 driven at port, 0 for a logic +0 driven at port. +*/ + +void gpio_port_write(uint32_t gpioport, uint32_t data) +{ + GPIO_PDOR(gpioport) = data; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/iomuxc.c b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/iomuxc.c new file mode 100644 index 00000000..12105751 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/iomuxc.c @@ -0,0 +1,57 @@ +/** @defgroup VF6xx_iomuxc IOMUX-Control + * + * @ingroup VF6xx + * + * @section vf6xx_gpio_api_ex GPIO API. + * + * @brief VF6xx IO Pad MUX Controller + * + * @author @htmlonly © @endhtmlonly 2014 Stefan Agner + * + * @date 07 July 2014 + * + * This library supports the GPIO module in the VF6xx SoC of Freescale. + * Access is provided by GPIO number according to the Pinmux list of the + * Reference Manual, similar as GPIOs are available on Linux. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set GPIO + +Set GPIO by GPIO number according to MUX list + +@param[in] gpio unsigned 32 bit. GPIO number +*/ + +void iomuxc_mux(enum vf6xx_pad pad, uint32_t muxc) +{ + IOMUXC(pad) = muxc; +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/libopencm3_vf6xx.ld b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/libopencm3_vf6xx.ld new file mode 100644 index 00000000..eb8201de --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/libopencm3_vf6xx.ld @@ -0,0 +1,109 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for VF6xx targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN(vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + . = ALIGN(0x400); + *(.text.reset_handler) /* Force reset handler at start */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >pc_ram + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >pc_ram + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >pc_ram + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >pc_ram + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >pc_ram + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >pc_ram + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ps_ram AT >pc_ram + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ps_ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ps_ram) + LENGTH(ps_ram)); + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/uart.c b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/uart.c new file mode 100644 index 00000000..0c5f16c2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/uart.c @@ -0,0 +1,225 @@ +/** @defgroup VF6xx_uart UART + * + * @ingroup VF6xx + * + * @section vf6xx_uart_api_ex UART API. + * + * @brief VF6xx Universal Asynchronous Receiver/Transmitter (UART) + * + * @author @htmlonly © @endhtmlonly 2014 Stefan Agner + * + * @date 03 July 2014 + * + * This library supports the UART in the VF6xx SoC of Freescale. + * Devices can have up to 6 UARTs. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief UART Set Baudrate. + +The baud rate is computed from the IPG bus clock. The bus clock must be +calculated by using @ref ccm_calculate_clocks before calling this function. + +@param[in] uart unsigned 32 bit. UART block register address base @ref +uart_reg_base +@param[in] baud unsigned 32 bit. Baud rate specified in Hz. +*/ + +void uart_set_baudrate(uint32_t uart, uint32_t baud) +{ + uint32_t bd_clk = ccm_ipg_bus_clk / baud; + uint32_t sbr; + + /* Round up if LSB is one... */ + bd_clk /= 8; + sbr = bd_clk / 2 + (bd_clk & 0x1); + + UART_BDL(uart) = sbr & UART_BDL_SBR_MASK; + UART_BDH(uart) = (sbr >> 8) & UART_BDH_SBR_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Set Parity. + +The parity bit can be selected as none, even or odd. + +@param[in] uart unsigned 32 bit. UART block register address base @ref +uart_reg_base +@param[in] parity unsigned 8 bit. Parity @ref uart_parity. +*/ + +void uart_set_parity(uint32_t uart, uint8_t parity) +{ + uint8_t reg8; + + reg8 = UART_C1(uart); + reg8 = (reg8 & ~UART_PARITY_MASK) | parity; + UART_C1(uart) = reg8; +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Set Hardware Flow Control. + +The flow control bit can be selected as none, RTS, CTS or RTS+CTS. + +@param[in] uart unsigned 32 bit. UART block register address base @ref +uart_reg_base +@param[in] flowcontrol unsigned 8 bit. Flowcontrol @ref uart_cr3_flowcontrol. +*/ + +void uart_set_flow_control(uint32_t uart, uint8_t flowcontrol) +{ + uint8_t reg8; + + reg8 = UART_MODEM(uart); + reg8 = (reg8 & ~UART_FLOWCONTROL_MASK) | flowcontrol; + UART_MODEM(uart) = reg8; +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Enable. + +Enable Tramitter and Receiver + +@param[in] uart unsigned 32 bit. UART block register address base @ref +uart_reg_base +*/ + +void uart_enable(uint32_t uart) +{ + UART_C2(uart) |= (UART_C2_TE | UART_C2_RE); +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Disable. + +At the end of the current frame, the UART is disabled to reduce power. + +@param[in] uart unsigned 32 bit. UART block register address base @ref +uart_reg_base +*/ + +void uart_disable(uint32_t uart) +{ + UART_C2(uart) &= ~(UART_C2_TE | UART_C2_RE); +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Send a Data Word. + * + * @param[in] uart unsigned 32 bit. UART block register address base @ref + * uart_reg_base + * @param[in] data unsigned 8 bit. + */ + +void uart_send(uint32_t uart, uint8_t data) +{ + UART_D(uart) = data; +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Wait for Transmit Data Buffer Empty + * + * Blocks until the transmit data buffer becomes empty and is ready to accept + * the next data word. + * + * @param[in] uart unsigned 32 bit. UART block register address base @ref + * uart_reg_base + */ + +void uart_wait_send_ready(uint32_t uart) +{ + /* Wait until the data has been transferred into the shift register. */ + while ((UART_S1(uart) & UART_S1_TC) == 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Send Data byte blocking + * + * Blocks until the transmit data buffer becomes empty before sending the + * next (given) byte. + * @param[in] uart unsigned 32 bit. UART block register address base @ref + * uart_reg_base + * @param[in] data unsigned 8 bit. + */ + +void uart_send_blocking(uint32_t uart, uint8_t data) +{ + uart_wait_send_ready(uart); + uart_send(uart, data); +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Read a Received Data Word. + * + * @param[in] uart unsigned 32 bit. UART block register address base @ref + * uart_reg_base + * @returns unsigned 8 bit data word. + */ + +uint8_t uart_recv(uint32_t uart) +{ + /* Receive data. */ + return UART_D(uart); +} + +/*---------------------------------------------------------------------------*/ +/** @brief UART Wait for Received Data Available + * + * Blocks until the receive data buffer holds a valid received data word. + * + * @param[in] uart unsigned 32 bit. UART block register address base @ref + * uart_reg_base + */ + +void uart_wait_recv_ready(uint32_t uart) +{ + /* Wait until the data is ready to be received. */ + while ((UART_S1(uart) & UART_S1_RDRF) == 0); +} + + +/*---------------------------------------------------------------------------*/ +/** @brief UART Read a Received Data Word with Blocking. + +Wait until a data word has been received then return the word. + +@param[in] uart unsigned 32 bit. UART block register address base @ref +uart_reg_base +@returns unsigned 16 bit data word. +*/ + +uint8_t uart_recv_blocking(uint32_t uart) +{ + uart_wait_recv_ready(uart); + + return uart_recv(uart); +} + +/**@}*/ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/vector_chipset.c b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/vector_chipset.c new file mode 100644 index 00000000..1c377015 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/lib/vf6xx/vector_chipset.c @@ -0,0 +1,39 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Stefan Agner + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +extern vector_table_t vector_table; + +static inline void pre_main(void) +{ + /* + * For Vybrid we need to set the stack pointer manually + * since the boot ROM has its own stack + */ + __asm__ ( \ + "ldr sp,=_stack;" \ + ); + + /* Set Vector Table Offset to our memory based vector table */ + SCB_VTOR = (uint32_t)&vector_table; + + /* Enable access to Floating-Point coprocessor. */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/locm3.sublime-project b/hardware-wallet/firmware/vendor/libopencm3/locm3.sublime-project new file mode 100644 index 00000000..19e61279 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/locm3.sublime-project @@ -0,0 +1,35 @@ +{ + "folders": + [ + { + "path": ".", + "file_exclude_patterns": + [ + "*.o", + "*.a", + "*.d", + "*.sublime-project", + "*.sublime-workspace", + "*.swp" + ], + "folder_exclude_patterns": + [ + ] + } + ], + "settings": + { + "tab_size": 8, + "translate_tabs_to_spaces": false, + "rulers": [80] + }, + "build_systems": + [ + { + "name": "libopencm3", + "working_dir": "${project_path}", + "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", + "cmd": ["make"] + } + ] +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/mk/README b/hardware-wallet/firmware/vendor/libopencm3/mk/README new file mode 100644 index 00000000..87e37e01 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/mk/README @@ -0,0 +1,121 @@ +------------------------------------------------------------------------------- +README +------------------------------------------------------------------------------- + + This directory contains makefile modular support files, that can be used in +your project. + + Each module is packaged with two inclusion makefiles, -config.mk and +-rules.mk. The first one defines some new variables for the make, or +appends values to the existing variables for the make. The second defines rules +for support building. + + So in your project, the -config.mk should be included at some place, +where you are defining variables (near the beginning of the file), and file +-rules.mk should be included in the rules part of makefile (somewhere +near to the end of file). + +Example makefile using the gcc compiler module together with the linker script +generator module: + +>>>>>> +DEVICE = +OPENCM3_DIR = +OBJS += foo.o + +CFLAGS += -Os -ggdb3 +CPPFLAGS += -MD +LDFLAGS += -static -nostartfiles +LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group + +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/gcc-config.mk + +.PHONY: clean all + +all: binary.elf binary.hex + +clean: + $(Q)$(RM) -rf binary.* *.o + +include $(OPENCM3_DIR)/mk/genlink-rules.mk +include $(OPENCM3_DIR)/mk/gcc-rules.mk +<<<<<< + + +MODULES +======= + +------------------------------------------------------------------------------- +gcc +------------------------------------------------------------------------------- + + This module adds an extended support for GCC toolchain. This adds rules, +necessary for compiling C and C++ files into elf binary, and rules for +generation of bin, hex, or srec output files for flashing. + +Variables to control the build process (should be set in your makefile): +------------------------------------------------------------------------ + +CFLAGS C compiler flags +CXXFLAGS C++ compiler flags +CPPFLAGS C preprocessor flags (used for C and for C++ compiler) +LDFLAGS Linker flags +ARCH_FLAGS Architecture specification flags (-mcpu, -march etc ) + +Variables to tell gcc about project dependencies and input files +---------------------------------------------------------------- + +LDSCRIPT Linker script file name (can be generated or fixed) +LIBDEPS Array of library filenames that shoud be rebuilt if needed +LDLIBS Array of libraries to be linked with (array of -l) +OBJS Array of object files to be built + + +------------------------------------------------------------------------------- +genlink +------------------------------------------------------------------------------- + + This module adds an support for the user to the linker script generator. The +linker script will be generated as the file $(DEVICE).ld in the project folder, +and automatically be used for the linking process. +Additionally the matching library is added to the LDLIBS variable. + +Variables to control the build process (should be set in your makefile): +------------------------------------------------------------------------ + +DEVICE The full device part name used for the compilation process. +OPENCM3_DIR The root path of libopencm3 library. + +Output variables from this module: +---------------------------------- + +CPPFLAGS (appended) + - Appends the chip family to the CPPFLAGS. For example -DSTM32F1 + - Appends the include path for libopencm3 + +ARCH_FLAGS (replaced) + - Architecture build flags for specified chip. + * No needed to handle this variable if you use module too. + +LDSCRIPT (replaced) + - Linker script generated file. + * No needed to handle this variable if you use module too. + +LDLIBS (appended) + - LDLIBS += -lopencm3_$(family) is appended to link against the + matching library. + +LDFLAGS (appended) + - LDFLAGS += -L$(OPENCM3_DIR)/lib is appended to make sure the + matching library can be found. + +family,cpu,fpu (replaced) + - these are used internally to create the above variables + +Temporary variables that you should not use in your makefile: +------------------------------------------------------------- + +GENLINK_DEFS +GENLINK_ARCH +GENLINK_LIB diff --git a/hardware-wallet/firmware/vendor/libopencm3/mk/gcc-config.mk b/hardware-wallet/firmware/vendor/libopencm3/mk/gcc-config.mk new file mode 100644 index 00000000..8c924244 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/mk/gcc-config.mk @@ -0,0 +1,37 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2014 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +############################################################################### +# The support makefile for GCC compiler toolchain, the rules part. +# +# please read mk/README for specification how to use this file in your project + + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf + +CC := $(PREFIX)-gcc +CXX := $(PREFIX)-g++ +LD := $(PREFIX)-gcc +AR := $(PREFIX)-ar +AS := $(PREFIX)-as +OBJCOPY := $(PREFIX)-objcopy +OBJDUMP := $(PREFIX)-objdump +GDB := $(PREFIX)-gdb +SIZE := $(PREFIX)-size diff --git a/hardware-wallet/firmware/vendor/libopencm3/mk/gcc-rules.mk b/hardware-wallet/firmware/vendor/libopencm3/mk/gcc-rules.mk new file mode 100644 index 00000000..821912b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/mk/gcc-rules.mk @@ -0,0 +1,56 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2014 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +############################################################################### +# The support makefile for GCC compiler toolchain, the rules part. +# +# please read mk/README for specification how to use this file in your project +# + +%.bin: %.elf + @printf " OBJCOPY $@\n" + $(Q)$(OBJCOPY) -Obinary $< $@ + +%.hex: %.elf + @printf " OBJCOPY $@\n" + $(Q)$(OBJCOPY) -Oihex $< $@ + +%.srec: %.elf + @printf " OBJCOPY $@\n" + $(Q)$(OBJCOPY) -Osrec $< $@ + +%.list: %.elf + @printf " OBJDUMP $@\n" + $(Q)$(OBJDUMP) -S $< > $@ + +%.elf: $(OBJS) $(LDSCRIPT) $(LIBDEPS) + @printf " LD $(*).elf\n" + $(Q)$(LD) $(OBJS) $(LDLIBS) $(LDFLAGS) -T$(LDSCRIPT) $(ARCH_FLAGS) -o $@ + +%.o: %.c + @printf " CC $<\n" + $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $< + +%.o: %.cxx + @printf " CXX $<\n" + $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $< + +%.o: %.cpp + @printf " CXX $(*).cpp\n" + $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $< diff --git a/hardware-wallet/firmware/vendor/libopencm3/mk/genlink-config.mk b/hardware-wallet/firmware/vendor/libopencm3/mk/genlink-config.mk new file mode 100644 index 00000000..a08636ef --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/mk/genlink-config.mk @@ -0,0 +1,79 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2014 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +ifeq ($(DEVICE),) +$(warning no DEVICE specified for linker script generator) +endif + +LDSCRIPT = generated.$(DEVICE).ld +DEVICES_DATA = $(OPENCM3_DIR)/ld/devices.data + +genlink_family :=$(shell awk -v PAT="$(DEVICE)" -v MODE="FAMILY" -f $(OPENCM3_DIR)/scripts/genlink.awk $(DEVICES_DATA)) +genlink_subfamily :=$(shell awk -v PAT="$(DEVICE)" -v MODE="SUBFAMILY" -f $(OPENCM3_DIR)/scripts/genlink.awk $(DEVICES_DATA)) +genlink_cpu :=$(shell awk -v PAT="$(DEVICE)" -v MODE="CPU" -f $(OPENCM3_DIR)/scripts/genlink.awk $(DEVICES_DATA)) +genlink_fpu :=$(shell awk -v PAT="$(DEVICE)" -v MODE="FPU" -f $(OPENCM3_DIR)/scripts/genlink.awk $(DEVICES_DATA)) +genlink_cppflags :=$(shell awk -v PAT="$(DEVICE)" -v MODE="CPPFLAGS" -f $(OPENCM3_DIR)/scripts/genlink.awk $(DEVICES_DATA)) + +CPPFLAGS += $(genlink_cppflags) + +ARCH_FLAGS :=-mcpu=$(genlink_cpu) +ifeq ($(genlink_cpu),$(filter $(genlink_cpu),cortex-m0 cortex-m0plus cortex-m3 cortex-m4 cortex-m7)) +ARCH_FLAGS +=-mthumb +endif + +ifeq ($(genlink_fpu),soft) +ARCH_FLAGS += -msoft-float +else ifeq ($(genlink_fpu),hard-fpv4-sp-d16) +ARCH_FLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 +else ifeq ($(genlink_fpu),hard-fpv5-sp-d16) +ARCH_FLAGS += -mfloat-abi=hard -mfpu=fpv5-sp-d16 +else +$(warning No match for the FPU flags) +endif + + +ifeq ($(genlink_family),) +$(warning $(DEVICE) not found in $(DEVICES_DATA)) +endif + +# only append to LDFLAGS if the library file exists to not break builds +# where those are provided by different means +ifneq (,$(wildcard $(OPENCM3_DIR)/lib/libopencm3_$(genlink_family).a)) +LDLIBS += -lopencm3_$(genlink_family) +else +ifneq (,$(wildcard $(OPENCM3_DIR)/lib/libopencm3_$(genlink_subfamily).a)) +LDLIBS += -lopencm3_$(genlink_subfamily) +else +$(warning $(OPENCM3_DIR)/lib/libopencm3_$(genlink_family).a library variant for the selected device does not exist.) +endif +endif + +# only append to LDLIBS if the directory exists +ifneq (,$(wildcard $(OPENCM3_DIR)/lib)) +LDFLAGS += -L$(OPENCM3_DIR)/lib +else +$(warning $(OPENCM3_DIR)/lib as given be OPENCM3_DIR does not exist.) +endif + +# only append include path to CPPFLAGS if the directory exists +ifneq (,$(wildcard $(OPENCM3_DIR)/include)) +CPPFLAGS += -I$(OPENCM3_DIR)/include +else +$(warning $(OPENCM3_DIR)/include as given be OPENCM3_DIR does not exist.) +endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/mk/genlink-rules.mk b/hardware-wallet/firmware/vendor/libopencm3/mk/genlink-rules.mk new file mode 100644 index 00000000..efd0f68c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/mk/genlink-rules.mk @@ -0,0 +1,22 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2014 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +$(LDSCRIPT):$(OPENCM3_DIR)/ld/linker.ld.S + @printf " GENLNK $(DEVICE)\n" + $(Q)$(CPP) $(ARCH_FLAGS) $(shell awk -v PAT="$(DEVICE)" -v MODE="DEFS" -f $(OPENCM3_DIR)/scripts/genlink.awk $(OPENCM3_DIR)/ld/devices.data 2>/dev/null) -P -E $< > $@ diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/checkpatch.pl b/hardware-wallet/firmware/vendor/libopencm3/scripts/checkpatch.pl new file mode 100755 index 00000000..54026fb9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/checkpatch.pl @@ -0,0 +1,3731 @@ +#!/usr/bin/perl -w +# (c) 2001, Dave Jones. (the file handling bit) +# (c) 2005, Joel Schopp (the ugly bit) +# (c) 2007,2008, Andy Whitcroft (new conditions, test suite) +# (c) 2008-2010 Andy Whitcroft +# Licensed under the terms of the GNU GPL License version 2 + +use strict; + +my $P = $0; +$P =~ s@.*/@@g; + +my $V = '0.32'; + +use Getopt::Long qw(:config no_auto_abbrev); + +my $quiet = 0; +my $tree = 1; +my $chk_signoff = 1; +my $chk_patch = 1; +my $tst_only; +my $emacs = 0; +my $terse = 0; +my $file = 0; +my $check = 0; +my $summary = 1; +my $mailback = 0; +my $summary_file = 0; +my $show_types = 0; +my $root; +my %debug; +my %ignore_type = (); +my @ignore = (); +my $help = 0; +my $configuration_file = ".checkpatch.conf"; +my $max_line_length = 80; + +sub help { + my ($exitcode) = @_; + + print << "EOM"; +Usage: $P [OPTION]... [FILE]... +Version: $V + +Options: + -q, --quiet quiet + --no-tree run without a kernel tree + --no-signoff do not check for 'Signed-off-by' line + --patch treat FILE as patchfile (default) + --emacs emacs compile window format + --terse one line per report + -f, --file treat FILE as regular source file + --subjective, --strict enable more subjective tests + --ignore TYPE(,TYPE2...) ignore various comma separated message types + --max-line-length=n set the maximum line length, if exceeded, warn + --show-types show the message "types" in the output + --root=PATH PATH to the kernel tree root + --no-summary suppress the per-file summary + --mailback only produce a report in case of warnings/errors + --summary-file include the filename in summary + --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of + 'values', 'possible', 'type', and 'attr' (default + is all off) + --test-only=WORD report only warnings/errors containing WORD + literally + -h, --help, --version display this help and exit + +When FILE is - read standard input. +EOM + + exit($exitcode); +} + +my $conf = which_conf($configuration_file); +if (-f $conf) { + my @conf_args; + open(my $conffile, '<', "$conf") + or warn "$P: Can't find a readable $configuration_file file $!\n"; + + while (<$conffile>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + $line =~ s/\s+/ /g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + + my @words = split(" ", $line); + foreach my $word (@words) { + last if ($word =~ m/^#/); + push (@conf_args, $word); + } + } + close($conffile); + unshift(@ARGV, @conf_args) if @conf_args; +} + +GetOptions( + 'q|quiet+' => \$quiet, + 'tree!' => \$tree, + 'signoff!' => \$chk_signoff, + 'patch!' => \$chk_patch, + 'emacs!' => \$emacs, + 'terse!' => \$terse, + 'f|file!' => \$file, + 'subjective!' => \$check, + 'strict!' => \$check, + 'ignore=s' => \@ignore, + 'show-types!' => \$show_types, + 'max-line-length=i' => \$max_line_length, + 'root=s' => \$root, + 'summary!' => \$summary, + 'mailback!' => \$mailback, + 'summary-file!' => \$summary_file, + + 'debug=s' => \%debug, + 'test-only=s' => \$tst_only, + 'h|help' => \$help, + 'version' => \$help +) or help(1); + +help(0) if ($help); + +my $exit = 0; + +if ($#ARGV < 0) { + print "$P: no input files\n"; + exit(1); +} + +@ignore = split(/,/, join(',',@ignore)); +foreach my $word (@ignore) { + $word =~ s/\s*\n?$//g; + $word =~ s/^\s*//g; + $word =~ s/\s+/ /g; + $word =~ tr/[a-z]/[A-Z]/; + + next if ($word =~ m/^\s*#/); + next if ($word =~ m/^\s*$/); + + $ignore_type{$word}++; +} + +my $dbg_values = 0; +my $dbg_possible = 0; +my $dbg_type = 0; +my $dbg_attr = 0; +for my $key (keys %debug) { + ## no critic + eval "\${dbg_$key} = '$debug{$key}';"; + die "$@" if ($@); +} + +my $rpt_cleaners = 0; + +if ($terse) { + $emacs = 1; + $quiet++; +} + +if ($tree) { + if (defined $root) { + if (!top_of_kernel_tree($root)) { + die "$P: $root: --root does not point at a valid tree\n"; + } + } else { + if (top_of_kernel_tree('.')) { + $root = '.'; + } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && + top_of_kernel_tree($1)) { + $root = $1; + } + } + + if (!defined $root) { + print "Must be run from the top-level dir. of a kernel tree\n"; + exit(2); + } +} + +my $emitted_corrupt = 0; + +our $Ident = qr{ + [A-Za-z_][A-Za-z\d_]* + (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* + }x; +our $Storage = qr{extern|static|asmlinkage}; +our $Sparse = qr{ + __user| + __kernel| + __force| + __iomem| + __must_check| + __init_refok| + __kprobes| + __ref| + __rcu + }x; + +# Notes to $Attribute: +# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check +our $Attribute = qr{ + const| + __percpu| + __nocast| + __safe| + __bitwise__| + __packed__| + __packed2__| + __naked| + __maybe_unused| + __always_unused| + __noreturn| + __used| + __cold| + __noclone| + __deprecated| + __read_mostly| + __kprobes| + __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| + ____cacheline_aligned| + ____cacheline_aligned_in_smp| + ____cacheline_internodealigned_in_smp| + __weak + }x; +our $Modifier; +our $Inline = qr{inline|__always_inline|noinline}; +our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; +our $Lval = qr{$Ident(?:$Member)*}; + +our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; +our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; +our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; +our $Float = qr{$Float_hex|$Float_dec|$Float_int}; +our $Constant = qr{$Float|(?i)(?:0x[0-9a-f]+|[0-9]+)[ul]*}; +our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; +our $Compare = qr{<=|>=|==|!=|<|>}; +our $Operators = qr{ + <=|>=|==|!=| + =>|->|<<|>>|<|>|!|~| + &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% + }x; + +our $NonptrType; +our $Type; +our $Declare; + +our $NON_ASCII_UTF8 = qr{ + [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 +}x; + +our $UTF8 = qr{ + [\x09\x0A\x0D\x20-\x7E] # ASCII + | $NON_ASCII_UTF8 +}x; + +our $typeTypedefs = qr{(?x: + (?:__)?(?:u|s|be|le)(?:8|16|32|64)| + atomic_t +)}; + +our $logFunctions = qr{(?x: + printk(?:_ratelimited|_once|)| + [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| + WARN(?:_RATELIMIT|_ONCE|)| + panic| + MODULE_[A-Z_]+ +)}; + +our $signature_tags = qr{(?xi: + Signed-off-by:| + Acked-by:| + Tested-by:| + Reviewed-by:| + Reported-by:| + Suggested-by:| + To:| + Cc: +)}; + +our @typeList = ( + qr{void}, + qr{(?:unsigned\s+)?char}, + qr{(?:unsigned\s+)?short}, + qr{(?:unsigned\s+)?int}, + qr{(?:unsigned\s+)?long}, + qr{(?:unsigned\s+)?long\s+int}, + qr{(?:unsigned\s+)?long\s+long}, + qr{(?:unsigned\s+)?long\s+long\s+int}, + qr{unsigned}, + qr{float}, + qr{double}, + qr{bool}, + qr{struct\s+$Ident}, + qr{union\s+$Ident}, + qr{enum\s+$Ident}, + qr{${Ident}_t}, + qr{${Ident}_handler}, + qr{${Ident}_handler_fn}, +); +our @modifierList = ( + qr{fastcall}, +); + +our $allowed_asm_includes = qr{(?x: + irq| + memory +)}; +# memory.h: ARM has a custom one + +sub build_types { + my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; + my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; + $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; + $NonptrType = qr{ + (?:$Modifier\s+|const\s+)* + (?: + (?:typeof|__typeof__)\s*\([^\)]*\)| + (?:$typeTypedefs\b)| + (?:${all}\b) + ) + (?:\s+$Modifier|\s+const)* + }x; + $Type = qr{ + $NonptrType + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)? + (?:\s+$Inline|\s+$Modifier)* + }x; + $Declare = qr{(?:$Storage\s+)?$Type}; +} +build_types(); + + +our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; + +# Using $balanced_parens, $LvalOrFunc, or $FuncArg +# requires at least perl version v5.10.0 +# Any use must be runtime checked with $^V + +our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; +our $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*}; +our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; + +sub deparenthesize { + my ($string) = @_; + return "" if (!defined($string)); + $string =~ s@^\s*\(\s*@@g; + $string =~ s@\s*\)\s*$@@g; + $string =~ s@\s+@ @g; + return $string; +} + +$chk_signoff = 0 if ($file); + +my @rawlines = (); +my @lines = (); +my $vname; +for my $filename (@ARGV) { + my $FILE; + if ($file) { + open($FILE, '-|', "diff -u /dev/null $filename") || + die "$P: $filename: diff failed - $!\n"; + } elsif ($filename eq '-') { + open($FILE, '<&STDIN'); + } else { + open($FILE, '<', "$filename") || + die "$P: $filename: open failed - $!\n"; + } + if ($filename eq '-') { + $vname = 'Your patch'; + } else { + $vname = $filename; + } + while (<$FILE>) { + chomp; + push(@rawlines, $_); + } + close($FILE); + if (!process($filename)) { + $exit = 1; + } + @rawlines = (); + @lines = (); +} + +exit($exit); + +sub top_of_kernel_tree { + my ($root) = @_; + + my @tree_check = ( + "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", + "README", "Documentation", "arch", "include", "drivers", + "fs", "init", "ipc", "kernel", "lib", "scripts", + ); + + foreach my $check (@tree_check) { + if (! -e $root . '/' . $check) { + return 0; + } + } + return 1; +} + +sub parse_email { + my ($formatted_email) = @_; + + my $name = ""; + my $address = ""; + my $comment = ""; + + if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { + $name = $1; + $address = $2; + $comment = $3 if defined $3; + } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + $formatted_email =~ s/$address.*$//; + $name = $formatted_email; + $name =~ s/^\s+|\s+$//g; + $name =~ s/^\"|\"$//g; + # If there's a name left after stripping spaces and + # leading quotes, and the address doesn't have both + # leading and trailing angle brackets, the address + # is invalid. ie: + # "joe smith joe@smith.com" bad + # "joe smith ]+>$/) { + $name = ""; + $address = ""; + $comment = ""; + } + } + + $name =~ s/^\s+|\s+$//g; + $name =~ s/^\"|\"$//g; + $address =~ s/^\s+|\s+$//g; + $address =~ s/^\<|\>$//g; + + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars + $name =~ s/(?"; + } + + return $formatted_email; +} + +sub which_conf { + my ($conf) = @_; + + foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { + if (-e "$path/$conf") { + return "$path/$conf"; + } + } + + return ""; +} + +sub expand_tabs { + my ($str) = @_; + + my $res = ''; + my $n = 0; + for my $c (split(//, $str)) { + if ($c eq "\t") { + $res .= ' '; + $n++; + for (; ($n % 8) != 0; $n++) { + $res .= ' '; + } + next; + } + $res .= $c; + $n++; + } + + return $res; +} +sub copy_spacing { + (my $res = shift) =~ tr/\t/ /c; + return $res; +} + +sub line_stats { + my ($line) = @_; + + # Drop the diff line leader and expand tabs + $line =~ s/^.//; + $line = expand_tabs($line); + + # Pick the indent from the front of the line. + my ($white) = ($line =~ /^(\s*)/); + + return (length($line), length($white)); +} + +my $sanitise_quote = ''; + +sub sanitise_line_reset { + my ($in_comment) = @_; + + if ($in_comment) { + $sanitise_quote = '*/'; + } else { + $sanitise_quote = ''; + } +} +sub sanitise_line { + my ($line) = @_; + + my $res = ''; + my $l = ''; + + my $qlen = 0; + my $off = 0; + my $c; + + # Always copy over the diff marker. + $res = substr($line, 0, 1); + + for ($off = 1; $off < length($line); $off++) { + $c = substr($line, $off, 1); + + # Comments we are wacking completly including the begin + # and end, all to $;. + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { + $sanitise_quote = '*/'; + + substr($res, $off, 2, "$;$;"); + $off++; + next; + } + if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { + $sanitise_quote = ''; + substr($res, $off, 2, "$;$;"); + $off++; + next; + } + if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { + $sanitise_quote = '//'; + + substr($res, $off, 2, $sanitise_quote); + $off++; + next; + } + + # A \ in a string means ignore the next character. + if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && + $c eq "\\") { + substr($res, $off, 2, 'XX'); + $off++; + next; + } + # Regular quotes. + if ($c eq "'" || $c eq '"') { + if ($sanitise_quote eq '') { + $sanitise_quote = $c; + + substr($res, $off, 1, $c); + next; + } elsif ($sanitise_quote eq $c) { + $sanitise_quote = ''; + } + } + + #print "c<$c> SQ<$sanitise_quote>\n"; + if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { + substr($res, $off, 1, $;); + } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { + substr($res, $off, 1, $;); + } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { + substr($res, $off, 1, 'X'); + } else { + substr($res, $off, 1, $c); + } + } + + if ($sanitise_quote eq '//') { + $sanitise_quote = ''; + } + + # The pathname on a #include may be surrounded by '<' and '>'. + if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { + my $clean = 'X' x length($1); + $res =~ s@\<.*\>@<$clean>@; + + # The whole of a #error is a string. + } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { + my $clean = 'X' x length($1); + $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; + } + + return $res; +} + +sub get_quoted_string { + my ($line, $rawline) = @_; + + return "" if ($line !~ m/(\"[X]+\")/g); + return substr($rawline, $-[0], $+[0] - $-[0]); +} + +sub ctx_statement_block { + my ($linenr, $remain, $off) = @_; + my $line = $linenr - 1; + my $blk = ''; + my $soff = $off; + my $coff = $off - 1; + my $coff_set = 0; + + my $loff = 0; + + my $type = ''; + my $level = 0; + my @stack = (); + my $p; + my $c; + my $len = 0; + + my $remainder; + while (1) { + @stack = (['', 0]) if ($#stack == -1); + + #warn "CSB: blk<$blk> remain<$remain>\n"; + # If we are about to drop off the end, pull in more + # context. + if ($off >= $len) { + for (; $remain > 0; $line++) { + last if (!defined $lines[$line]); + next if ($lines[$line] =~ /^-/); + $remain--; + $loff = $len; + $blk .= $lines[$line] . "\n"; + $len = length($blk); + $line++; + last; + } + # Bail if there is no further context. + #warn "CSB: blk<$blk> off<$off> len<$len>\n"; + if ($off >= $len) { + last; + } + if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { + $level++; + $type = '#'; + } + } + $p = $c; + $c = substr($blk, $off, 1); + $remainder = substr($blk, $off); + + #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; + + # Handle nested #if/#else. + if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { + push(@stack, [ $type, $level ]); + } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { + ($type, $level) = @{$stack[$#stack - 1]}; + } elsif ($remainder =~ /^#\s*endif\b/) { + ($type, $level) = @{pop(@stack)}; + } + + # Statement ends at the ';' or a close '}' at the + # outermost level. + if ($level == 0 && $c eq ';') { + last; + } + + # An else is really a conditional as long as its not else if + if ($level == 0 && $coff_set == 0 && + (!defined($p) || $p =~ /(?:\s|\}|\+)/) && + $remainder =~ /^(else)(?:\s|{)/ && + $remainder !~ /^else\s+if\b/) { + $coff = $off + length($1) - 1; + $coff_set = 1; + #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; + #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; + } + + if (($type eq '' || $type eq '(') && $c eq '(') { + $level++; + $type = '('; + } + if ($type eq '(' && $c eq ')') { + $level--; + $type = ($level != 0)? '(' : ''; + + if ($level == 0 && $coff < $soff) { + $coff = $off; + $coff_set = 1; + #warn "CSB: mark coff<$coff>\n"; + } + } + if (($type eq '' || $type eq '{') && $c eq '{') { + $level++; + $type = '{'; + } + if ($type eq '{' && $c eq '}') { + $level--; + $type = ($level != 0)? '{' : ''; + + if ($level == 0) { + if (substr($blk, $off + 1, 1) eq ';') { + $off++; + } + last; + } + } + # Preprocessor commands end at the newline unless escaped. + if ($type eq '#' && $c eq "\n" && $p ne "\\") { + $level--; + $type = ''; + $off++; + last; + } + $off++; + } + # We are truly at the end, so shuffle to the next line. + if ($off == $len) { + $loff = $len + 1; + $line++; + $remain--; + } + + my $statement = substr($blk, $soff, $off - $soff + 1); + my $condition = substr($blk, $soff, $coff - $soff + 1); + + #warn "STATEMENT<$statement>\n"; + #warn "CONDITION<$condition>\n"; + + #print "coff<$coff> soff<$off> loff<$loff>\n"; + + return ($statement, $condition, + $line, $remain + 1, $off - $loff + 1, $level); +} + +sub statement_lines { + my ($stmt) = @_; + + # Strip the diff line prefixes and rip blank lines at start and end. + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_rawlines { + my ($stmt) = @_; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_block_size { + my ($stmt) = @_; + + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*{//; + $stmt =~ s/}\s*$//; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + my @stmt_statements = ($stmt =~ /;/g); + + my $stmt_lines = $#stmt_lines + 2; + my $stmt_statements = $#stmt_statements + 1; + + if ($stmt_lines > $stmt_statements) { + return $stmt_lines; + } else { + return $stmt_statements; + } +} + +sub ctx_statement_full { + my ($linenr, $remain, $off) = @_; + my ($statement, $condition, $level); + + my (@chunks); + + # Grab the first conditional/block pair. + ($statement, $condition, $linenr, $remain, $off, $level) = + ctx_statement_block($linenr, $remain, $off); + #print "F: c<$condition> s<$statement> remain<$remain>\n"; + push(@chunks, [ $condition, $statement ]); + if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { + return ($level, $linenr, @chunks); + } + + # Pull in the following conditional/block pairs and see if they + # could continue the statement. + for (;;) { + ($statement, $condition, $linenr, $remain, $off, $level) = + ctx_statement_block($linenr, $remain, $off); + #print "C: c<$condition> s<$statement> remain<$remain>\n"; + last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); + #print "C: push\n"; + push(@chunks, [ $condition, $statement ]); + } + + return ($level, $linenr, @chunks); +} + +sub ctx_block_get { + my ($linenr, $remain, $outer, $open, $close, $off) = @_; + my $line; + my $start = $linenr - 1; + my $blk = ''; + my @o; + my @c; + my @res = (); + + my $level = 0; + my @stack = ($level); + for ($line = $start; $remain > 0; $line++) { + next if ($rawlines[$line] =~ /^-/); + $remain--; + + $blk .= $rawlines[$line]; + + # Handle nested #if/#else. + if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { + push(@stack, $level); + } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { + $level = $stack[$#stack - 1]; + } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { + $level = pop(@stack); + } + + foreach my $c (split(//, $lines[$line])) { + ##print "C<$c>L<$level><$open$close>O<$off>\n"; + if ($off > 0) { + $off--; + next; + } + + if ($c eq $close && $level > 0) { + $level--; + last if ($level == 0); + } elsif ($c eq $open) { + $level++; + } + } + + if (!$outer || $level <= 1) { + push(@res, $rawlines[$line]); + } + + last if ($level == 0); + } + + return ($level, @res); +} +sub ctx_block_outer { + my ($linenr, $remain) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); + return @r; +} +sub ctx_block { + my ($linenr, $remain) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); + return @r; +} +sub ctx_statement { + my ($linenr, $remain, $off) = @_; + + my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); + return @r; +} +sub ctx_block_level { + my ($linenr, $remain) = @_; + + return ctx_block_get($linenr, $remain, 0, '{', '}', 0); +} +sub ctx_statement_level { + my ($linenr, $remain, $off) = @_; + + return ctx_block_get($linenr, $remain, 0, '(', ')', $off); +} + +sub ctx_locate_comment { + my ($first_line, $end_line) = @_; + + # Catch a comment on the end of the line itself. + my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); + return $current_comment if (defined $current_comment); + + # Look through the context and try and figure out if there is a + # comment. + my $in_comment = 0; + $current_comment = ''; + for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { + my $line = $rawlines[$linenr - 1]; + #warn " $line\n"; + if ($linenr == $first_line and $line =~ m@^.\s*\*@) { + $in_comment = 1; + } + if ($line =~ m@/\*@) { + $in_comment = 1; + } + if (!$in_comment && $current_comment ne '') { + $current_comment = ''; + } + $current_comment .= $line . "\n" if ($in_comment); + if ($line =~ m@\*/@) { + $in_comment = 0; + } + } + + chomp($current_comment); + return($current_comment); +} +sub ctx_has_comment { + my ($first_line, $end_line) = @_; + my $cmt = ctx_locate_comment($first_line, $end_line); + + ##print "LINE: $rawlines[$end_line - 1 ]\n"; + ##print "CMMT: $cmt\n"; + + return ($cmt ne ''); +} + +sub raw_line { + my ($linenr, $cnt) = @_; + + my $offset = $linenr - 1; + $cnt++; + + my $line; + while ($cnt) { + $line = $rawlines[$offset++]; + next if (defined($line) && $line =~ /^-/); + $cnt--; + } + + return $line; +} + +sub cat_vet { + my ($vet) = @_; + my ($res, $coded); + + $res = ''; + while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { + $res .= $1; + if ($2 ne '') { + $coded = sprintf("^%c", unpack('C', $2) + 64); + $res .= $coded; + } + } + $res =~ s/$/\$/; + + return $res; +} + +my $av_preprocessor = 0; +my $av_pending; +my @av_paren_type; +my $av_pend_colon; + +sub annotate_reset { + $av_preprocessor = 0; + $av_pending = '_'; + @av_paren_type = ('E'); + $av_pend_colon = 'O'; +} + +sub annotate_values { + my ($stream, $type) = @_; + + my $res; + my $var = '_' x length($stream); + my $cur = $stream; + + print "$stream\n" if ($dbg_values > 1); + + while (length($cur)) { + @av_paren_type = ('E') if ($#av_paren_type < 0); + print " <" . join('', @av_paren_type) . + "> <$type> <$av_pending>" if ($dbg_values > 1); + if ($cur =~ /^(\s+)/o) { + print "WS($1)\n" if ($dbg_values > 1); + if ($1 =~ /\n/ && $av_preprocessor) { + $type = pop(@av_paren_type); + $av_preprocessor = 0; + } + + } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { + print "CAST($1)\n" if ($dbg_values > 1); + push(@av_paren_type, $type); + $type = 'c'; + + } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { + print "DECLARE($1)\n" if ($dbg_values > 1); + $type = 'T'; + + } elsif ($cur =~ /^($Modifier)\s*/) { + print "MODIFIER($1)\n" if ($dbg_values > 1); + $type = 'T'; + + } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { + print "DEFINE($1,$2)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + push(@av_paren_type, $type); + if ($2 ne '') { + $av_pending = 'N'; + } + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { + print "UNDEF($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + push(@av_paren_type, $type); + + } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { + print "PRE_START($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + + push(@av_paren_type, $type); + push(@av_paren_type, $type); + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { + print "PRE_RESTART($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + + push(@av_paren_type, $av_paren_type[$#av_paren_type]); + + $type = 'E'; + + } elsif ($cur =~ /^(\#\s*(?:endif))/o) { + print "PRE_END($1)\n" if ($dbg_values > 1); + + $av_preprocessor = 1; + + # Assume all arms of the conditional end as this + # one does, and continue as if the #endif was not here. + pop(@av_paren_type); + push(@av_paren_type, $type); + $type = 'E'; + + } elsif ($cur =~ /^(\\\n)/o) { + print "PRECONT($1)\n" if ($dbg_values > 1); + + } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { + print "ATTR($1)\n" if ($dbg_values > 1); + $av_pending = $type; + $type = 'N'; + + } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { + print "SIZEOF($1)\n" if ($dbg_values > 1); + if (defined $2) { + $av_pending = 'V'; + } + $type = 'N'; + + } elsif ($cur =~ /^(if|while|for)\b/o) { + print "COND($1)\n" if ($dbg_values > 1); + $av_pending = 'E'; + $type = 'N'; + + } elsif ($cur =~/^(case)/o) { + print "CASE($1)\n" if ($dbg_values > 1); + $av_pend_colon = 'C'; + $type = 'N'; + + } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { + print "KEYWORD($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(\()/o) { + print "PAREN('$1')\n" if ($dbg_values > 1); + push(@av_paren_type, $av_pending); + $av_pending = '_'; + $type = 'N'; + + } elsif ($cur =~ /^(\))/o) { + my $new_type = pop(@av_paren_type); + if ($new_type ne '_') { + $type = $new_type; + print "PAREN('$1') -> $type\n" + if ($dbg_values > 1); + } else { + print "PAREN('$1')\n" if ($dbg_values > 1); + } + + } elsif ($cur =~ /^($Ident)\s*\(/o) { + print "FUNC($1)\n" if ($dbg_values > 1); + $type = 'V'; + $av_pending = 'V'; + + } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { + if (defined $2 && $type eq 'C' || $type eq 'T') { + $av_pend_colon = 'B'; + } elsif ($type eq 'E') { + $av_pend_colon = 'L'; + } + print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); + $type = 'V'; + + } elsif ($cur =~ /^($Ident|$Constant)/o) { + print "IDENT($1)\n" if ($dbg_values > 1); + $type = 'V'; + + } elsif ($cur =~ /^($Assignment)/o) { + print "ASSIGN($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~/^(;|{|})/) { + print "END($1)\n" if ($dbg_values > 1); + $type = 'E'; + $av_pend_colon = 'O'; + + } elsif ($cur =~/^(,)/) { + print "COMMA($1)\n" if ($dbg_values > 1); + $type = 'C'; + + } elsif ($cur =~ /^(\?)/o) { + print "QUESTION($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(:)/o) { + print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); + + substr($var, length($res), 1, $av_pend_colon); + if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { + $type = 'E'; + } else { + $type = 'N'; + } + $av_pend_colon = 'O'; + + } elsif ($cur =~ /^(\[)/o) { + print "CLOSE($1)\n" if ($dbg_values > 1); + $type = 'N'; + + } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { + my $variant; + + print "OPV($1)\n" if ($dbg_values > 1); + if ($type eq 'V') { + $variant = 'B'; + } else { + $variant = 'U'; + } + + substr($var, length($res), 1, $variant); + $type = 'N'; + + } elsif ($cur =~ /^($Operators)/o) { + print "OP($1)\n" if ($dbg_values > 1); + if ($1 ne '++' && $1 ne '--') { + $type = 'N'; + } + + } elsif ($cur =~ /(^.)/o) { + print "C($1)\n" if ($dbg_values > 1); + } + if (defined $1) { + $cur = substr($cur, length($1)); + $res .= $type x length($1); + } + } + + return ($res, $var); +} + +sub possible { + my ($possible, $line) = @_; + my $notPermitted = qr{(?: + ^(?: + $Modifier| + $Storage| + $Type| + DEFINE_\S+ + )$| + ^(?: + goto| + return| + case| + else| + asm|__asm__| + do| + \#| + \#\#| + )(?:\s|$)| + ^(?:typedef|struct|enum)\b + )}x; + warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); + if ($possible !~ $notPermitted) { + # Check for modifiers. + $possible =~ s/\s*$Storage\s*//g; + $possible =~ s/\s*$Sparse\s*//g; + if ($possible =~ /^\s*$/) { + + } elsif ($possible =~ /\s/) { + $possible =~ s/\s*$Type\s*//g; + for my $modifier (split(' ', $possible)) { + if ($modifier !~ $notPermitted) { + warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); + push(@modifierList, $modifier); + } + } + + } else { + warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); + push(@typeList, $possible); + } + build_types(); + } else { + warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); + } +} + +my $prefix = ''; + +sub show_type { + return !defined $ignore_type{$_[0]}; +} + +sub report { + if (!show_type($_[1]) || + (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) { + return 0; + } + my $line; + if ($show_types) { + $line = "$prefix$_[0]:$_[1]: $_[2]\n"; + } else { + $line = "$prefix$_[0]: $_[2]\n"; + } + $line = (split('\n', $line))[0] . "\n" if ($terse); + + push(our @report, $line); + + return 1; +} +sub report_dump { + our @report; +} + +sub ERROR { + if (report("ERROR", $_[0], $_[1])) { + our $clean = 0; + our $cnt_error++; + } +} +sub WARN { + if (report("WARNING", $_[0], $_[1])) { + our $clean = 0; + our $cnt_warn++; + } +} +sub CHK { + if ($check && report("CHECK", $_[0], $_[1])) { + our $clean = 0; + our $cnt_chk++; + } +} + +sub check_absolute_file { + my ($absolute, $herecurr) = @_; + my $file = $absolute; + + ##print "absolute<$absolute>\n"; + + # See if any suffix of this path is a path within the tree. + while ($file =~ s@^[^/]*/@@) { + if (-f "$root/$file") { + ##print "file<$file>\n"; + last; + } + } + if (! -f _) { + return 0; + } + + # It is, so see if the prefix is acceptable. + my $prefix = $absolute; + substr($prefix, -length($file)) = ''; + + ##print "prefix<$prefix>\n"; + if ($prefix ne ".../") { + WARN("USE_RELATIVE_PATH", + "use relative pathname instead of absolute in changelog text\n" . $herecurr); + } +} + +sub pos_last_openparen { + my ($line) = @_; + + my $pos = 0; + + my $opens = $line =~ tr/\(/\(/; + my $closes = $line =~ tr/\)/\)/; + + my $last_openparen = 0; + + if (($opens == 0) || ($closes >= $opens)) { + return -1; + } + + my $len = length($line); + + for ($pos = 0; $pos < $len; $pos++) { + my $string = substr($line, $pos); + if ($string =~ /^($FuncArg|$balanced_parens)/) { + $pos += length($1) - 1; + } elsif (substr($line, $pos, 1) eq '(') { + $last_openparen = $pos; + } elsif (index($string, '(') == -1) { + last; + } + } + + return $last_openparen + 1; +} + +sub process { + my $filename = shift; + + my $linenr=0; + my $prevline=""; + my $prevrawline=""; + my $stashline=""; + my $stashrawline=""; + + my $length; + my $indent; + my $previndent=0; + my $stashindent=0; + + our $clean = 1; + my $signoff = 0; + my $is_patch = 0; + + my $in_header_lines = 1; + my $in_commit_log = 0; #Scanning lines before patch + + my $non_utf8_charset = 0; + + our @report = (); + our $cnt_lines = 0; + our $cnt_error = 0; + our $cnt_warn = 0; + our $cnt_chk = 0; + + # Trace the real file/line as we go. + my $realfile = ''; + my $realline = 0; + my $realcnt = 0; + my $here = ''; + my $in_comment = 0; + my $comment_edge = 0; + my $first_line = 0; + my $p1_prefix = ''; + + my $prev_values = 'E'; + + # suppression flags + my %suppress_ifbraces; + my %suppress_whiletrailers; + my %suppress_export; + my $suppress_statement = 0; + + my %camelcase = (); + + # Pre-scan the patch sanitizing the lines. + # Pre-scan the patch looking for any __setup documentation. + # + my @setup_docs = (); + my $setup_docs = 0; + + sanitise_line_reset(); + my $line; + foreach my $rawline (@rawlines) { + $linenr++; + $line = $rawline; + + if ($rawline=~/^\+\+\+\s+(\S+)/) { + $setup_docs = 0; + if ($1 =~ m@Documentation/kernel-parameters.txt$@) { + $setup_docs = 1; + } + #next; + } + if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { + $realline=$1-1; + if (defined $2) { + $realcnt=$3+1; + } else { + $realcnt=1+1; + } + $in_comment = 0; + + # Guestimate if this is a continuing comment. Run + # the context looking for a comment "edge". If this + # edge is a close comment then we must be in a comment + # at context start. + my $edge; + my $cnt = $realcnt; + for (my $ln = $linenr + 1; $cnt > 0; $ln++) { + next if (defined $rawlines[$ln - 1] && + $rawlines[$ln - 1] =~ /^-/); + $cnt--; + #print "RAW<$rawlines[$ln - 1]>\n"; + last if (!defined $rawlines[$ln - 1]); + if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && + $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { + ($edge) = $1; + last; + } + } + if (defined $edge && $edge eq '*/') { + $in_comment = 1; + } + + # Guestimate if this is a continuing comment. If this + # is the start of a diff block and this line starts + # ' *' then it is very likely a comment. + if (!defined $edge && + $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) + { + $in_comment = 1; + } + + ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; + sanitise_line_reset($in_comment); + + } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { + # Standardise the strings and chars within the input to + # simplify matching -- only bother with positive lines. + $line = sanitise_line($rawline); + } + push(@lines, $line); + + if ($realcnt > 1) { + $realcnt-- if ($line =~ /^(?:\+| |$)/); + } else { + $realcnt = 0; + } + + #print "==>$rawline\n"; + #print "-->$line\n"; + + if ($setup_docs && $line =~ /^\+/) { + push(@setup_docs, $line); + } + } + + $prefix = ''; + + $realcnt = 0; + $linenr = 0; + foreach my $line (@lines) { + $linenr++; + + my $rawline = $rawlines[$linenr - 1]; + +#extract the line range in the file after the patch is applied + if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { + $is_patch = 1; + $first_line = $linenr + 1; + $realline=$1-1; + if (defined $2) { + $realcnt=$3+1; + } else { + $realcnt=1+1; + } + annotate_reset(); + $prev_values = 'E'; + + %suppress_ifbraces = (); + %suppress_whiletrailers = (); + %suppress_export = (); + $suppress_statement = 0; + next; + +# track the line number as we move through the hunk, note that +# new versions of GNU diff omit the leading space on completely +# blank context lines so we need to count that too. + } elsif ($line =~ /^( |\+|$)/) { + $realline++; + $realcnt-- if ($realcnt != 0); + + # Measure the line length and indent. + ($length, $indent) = line_stats($rawline); + + # Track the previous line. + ($prevline, $stashline) = ($stashline, $line); + ($previndent, $stashindent) = ($stashindent, $indent); + ($prevrawline, $stashrawline) = ($stashrawline, $rawline); + + #warn "line<$line>\n"; + + } elsif ($realcnt == 1) { + $realcnt--; + } + + my $hunk_line = ($realcnt != 0); + +#make up the handle for any error we report on this line + $prefix = "$filename:$realline: " if ($emacs && $file); + $prefix = "$filename:$linenr: " if ($emacs && !$file); + + $here = "#$linenr: " if (!$file); + $here = "#$realline: " if ($file); + + # extract the filename as it passes + if ($line =~ /^diff --git.*?(\S+)$/) { + $realfile = $1; + $realfile =~ s@^([^/]*)/@@; + $in_commit_log = 0; + } elsif ($line =~ /^\+\+\+\s+(\S+)/) { + $realfile = $1; + $realfile =~ s@^([^/]*)/@@; + $in_commit_log = 0; + + $p1_prefix = $1; + if (!$file && $tree && $p1_prefix ne '' && + -e "$root/$p1_prefix") { + WARN("PATCH_PREFIX", + "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); + } + + if ($realfile =~ m@^include/asm/@) { + ERROR("MODIFIED_INCLUDE_ASM", + "do not modify files in include/asm, change architecture specific files in include/asm-\n" . "$here$rawline\n"); + } + next; + } + + $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); + + my $hereline = "$here\n$rawline\n"; + my $herecurr = "$here\n$rawline\n"; + my $hereprev = "$here\n$prevrawline\n$rawline\n"; + + $cnt_lines++ if ($realcnt != 0); + +# Check for incorrect file permissions + if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { + my $permhere = $here . "FILE: $realfile\n"; + if ($realfile !~ m@scripts/@ && + $realfile !~ /\.(py|pl|awk|sh)$/) { + ERROR("EXECUTE_PERMISSIONS", + "do not set execute permissions for source files\n" . $permhere); + } + } + +# Check the patch for a signoff: + if ($line =~ /^\s*signed-off-by:/i) { + $signoff++; + $in_commit_log = 0; + } + +# Check signature styles + if (!$in_header_lines && + $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { + my $space_before = $1; + my $sign_off = $2; + my $space_after = $3; + my $email = $4; + my $ucfirst_sign_off = ucfirst(lc($sign_off)); + + if ($sign_off !~ /$signature_tags/) { + WARN("BAD_SIGN_OFF", + "Non-standard signature: $sign_off\n" . $herecurr); + } + if (defined $space_before && $space_before ne "") { + WARN("BAD_SIGN_OFF", + "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr); + } + if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { + WARN("BAD_SIGN_OFF", + "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr); + } + if (!defined $space_after || $space_after ne " ") { + WARN("BAD_SIGN_OFF", + "Use a single space after $ucfirst_sign_off\n" . $herecurr); + } + + my ($email_name, $email_address, $comment) = parse_email($email); + my $suggested_email = format_email(($email_name, $email_address)); + if ($suggested_email eq "") { + ERROR("BAD_SIGN_OFF", + "Unrecognized email address: '$email'\n" . $herecurr); + } else { + my $dequoted = $suggested_email; + $dequoted =~ s/^"//; + $dequoted =~ s/" $comment" ne $email && + "$suggested_email$comment" ne $email) { + WARN("BAD_SIGN_OFF", + "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); + } + } + } + +# Check for wrappage within a valid hunk of the file + if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { + ERROR("CORRUPTED_PATCH", + "patch seems to be corrupt (line wrapped?)\n" . + $herecurr) if (!$emitted_corrupt++); + } + +# Check for absolute kernel paths. + if ($tree) { + while ($line =~ m{(?:^|\s)(/\S*)}g) { + my $file = $1; + + if ($file =~ m{^(.*?)(?::\d+)+:?$} && + check_absolute_file($1, $herecurr)) { + # + } else { + check_absolute_file($file, $herecurr); + } + } + } + +# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php + if (($realfile =~ /^$/ || $line =~ /^\+/) && + $rawline !~ m/^$UTF8*$/) { + my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); + + my $blank = copy_spacing($rawline); + my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; + my $hereptr = "$hereline$ptr\n"; + + CHK("INVALID_UTF8", + "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); + } + +# Check if it's the start of a commit log +# (not a header line and we haven't seen the patch filename) + if ($in_header_lines && $realfile =~ /^$/ && + $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) { + $in_header_lines = 0; + $in_commit_log = 1; + } + +# Check if there is UTF-8 in a commit log when a mail header has explicitly +# declined it, i.e defined some charset where it is missing. + if ($in_header_lines && + $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && + $1 !~ /utf-8/i) { + $non_utf8_charset = 1; + } + + if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && + $rawline =~ /$NON_ASCII_UTF8/) { + WARN("UTF8_BEFORE_PATCH", + "8-bit UTF-8 used in possible commit log\n" . $herecurr); + } + +# ignore non-hunk lines and lines being removed + next if (!$hunk_line || $line =~ /^-/); + +#trailing whitespace + if ($line =~ /^\+.*\015/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + ERROR("DOS_LINE_ENDINGS", + "DOS line endings\n" . $herevet); + + } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + ERROR("TRAILING_WHITESPACE", + "trailing whitespace\n" . $herevet); + $rpt_cleaners = 1; + } + +# check for Kconfig help text having a real description +# Only applies when adding the entry originally, after that we do not have +# sufficient context to determine whether it is indeed long enough. + if ($realfile =~ /Kconfig/ && + $line =~ /.\s*config\s+/) { + my $length = 0; + my $cnt = $realcnt; + my $ln = $linenr + 1; + my $f; + my $is_start = 0; + my $is_end = 0; + for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { + $f = $lines[$ln - 1]; + $cnt-- if ($lines[$ln - 1] !~ /^-/); + $is_end = $lines[$ln - 1] =~ /^\+/; + + next if ($f =~ /^-/); + + if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) { + $is_start = 1; + } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) { + $length = -1; + } + + $f =~ s/^.//; + $f =~ s/#.*//; + $f =~ s/^\s+//; + next if ($f =~ /^$/); + if ($f =~ /^\s*config\s/) { + $is_end = 1; + last; + } + $length++; + } + WARN("CONFIG_DESCRIPTION", + "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); + #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; + } + +# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. + if ($realfile =~ /Kconfig/ && + $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { + WARN("CONFIG_EXPERIMENTAL", + "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); + } + + if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && + ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { + my $flag = $1; + my $replacement = { + 'EXTRA_AFLAGS' => 'asflags-y', + 'EXTRA_CFLAGS' => 'ccflags-y', + 'EXTRA_CPPFLAGS' => 'cppflags-y', + 'EXTRA_LDFLAGS' => 'ldflags-y', + }; + + WARN("DEPRECATED_VARIABLE", + "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); + } + +# check we are in a valid source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); + +#line length limit + if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && + $rawline !~ /^.\s*\*\s*\@$Ident\s/ && + !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || + $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && + $length > $max_line_length) + { + WARN("LONG_LINE", + "line over $max_line_length characters\n" . $herecurr); + } + +# Check for user-visible strings broken across lines, which breaks the ability +# to grep for the string. Limited to strings used as parameters (those +# following an open parenthesis), which almost completely eliminates false +# positives, as well as warning only once per parameter rather than once per +# line of the string. Make an exception when the previous string ends in a +# newline (multiple lines in one string constant) or \n\t (common in inline +# assembly to indent the instruction on the following line). + if ($line =~ /^\+\s*"/ && + $prevline =~ /"\s*$/ && + $prevline =~ /\(/ && + $prevrawline !~ /\\n(?:\\t)*"\s*$/) { + WARN("SPLIT_STRING", + "quoted string split across lines\n" . $hereprev); + } + +# check for spaces before a quoted newline + if ($rawline =~ /^.*\".*\s\\n/) { + WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", + "unnecessary whitespace before a quoted newline\n" . $herecurr); + } + +# check for adding lines without a newline. + if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { + WARN("MISSING_EOF_NEWLINE", + "adding a line without newline at end of file\n" . $herecurr); + } + +# Blackfin: use hi/lo macros + if ($realfile =~ m@arch/blackfin/.*\.S$@) { + if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("LO_MACRO", + "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); + } + if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("HI_MACRO", + "use the HI() macro, not (... >> 16)\n" . $herevet); + } + } + +# check we are in a valid source file C or perl if not then ignore this hunk + next if ($realfile !~ /\.(h|c|pl)$/); + +# at the beginning of a line any tabs must come first and anything +# more than 8 must use tabs. + if ($rawline =~ /^\+\s* \t\s*\S/ || + $rawline =~ /^\+\s* \s*/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + ERROR("CODE_INDENT", + "code indent should use tabs where possible\n" . $herevet); + $rpt_cleaners = 1; + } + +# check for space before tabs. + if ($rawline =~ /^\+/ && $rawline =~ / \t/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + WARN("SPACE_BEFORE_TAB", + "please, no space before tabs\n" . $herevet); + } + +# check for && or || at the start of a line + if ($rawline =~ /^\+\s*(&&|\|\|)/) { + CHK("LOGICAL_CONTINUATIONS", + "Logical continuations should be on the previous line\n" . $hereprev); + } + +# check multi-line statement indentation matches previous line + if ($^V && $^V ge 5.10.0 && + $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) { + $prevline =~ /^\+(\t*)(.*)$/; + my $oldindent = $1; + my $rest = $2; + + my $pos = pos_last_openparen($rest); + if ($pos >= 0) { + $line =~ /^(\+| )([ \t]*)/; + my $newindent = $2; + + my $goodtabindent = $oldindent . + "\t" x ($pos / 8) . + " " x ($pos % 8); + my $goodspaceindent = $oldindent . " " x $pos; + + if ($newindent ne $goodtabindent && + $newindent ne $goodspaceindent) { + CHK("PARENTHESIS_ALIGNMENT", + "Alignment should match open parenthesis\n" . $hereprev); + } + } + } + + if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) { + CHK("SPACING", + "No space is necessary after a cast\n" . $hereprev); + } + + if ($realfile =~ m@^(drivers/net/|net/)@ && + $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && + $prevrawline =~ /^\+[ \t]*$/) { + WARN("NETWORKING_BLOCK_COMMENT_STYLE", + "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); + } + + if ($realfile =~ m@^(drivers/net/|net/)@ && + $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ + $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ + $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ + WARN("NETWORKING_BLOCK_COMMENT_STYLE", + "networking block comments put the trailing */ on a separate line\n" . $herecurr); + } + +# check for spaces at the beginning of a line. +# Exceptions: +# 1) within comments +# 2) indented preprocessor commands +# 3) hanging labels + if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) { + my $herevet = "$here\n" . cat_vet($rawline) . "\n"; + WARN("LEADING_SPACE", + "please, no spaces at the start of a line\n" . $herevet); + } + +# check we are in a valid C source file if not then ignore this hunk + next if ($realfile !~ /\.(h|c)$/); + +# discourage the addition of CONFIG_EXPERIMENTAL in #if(def). + if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { + WARN("CONFIG_EXPERIMENTAL", + "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); + } + +# check for RCS/CVS revision markers + if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { + WARN("CVS_KEYWORD", + "CVS style keyword markers, these will _not_ be updated\n". $herecurr); + } + +# Blackfin: don't use __builtin_bfin_[cs]sync + if ($line =~ /__builtin_bfin_csync/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("CSYNC", + "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); + } + if ($line =~ /__builtin_bfin_ssync/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("SSYNC", + "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); + } + +# check for old HOTPLUG __dev section markings + if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { + WARN("HOTPLUG_SECTION", + "Using $1 is unnecessary\n" . $herecurr); + } + +# Check for potential 'bare' types + my ($stat, $cond, $line_nr_next, $remain_next, $off_next, + $realline_next); +#print "LINE<$line>\n"; + if ($linenr >= $suppress_statement && + $realcnt && $line =~ /.\s*\S/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0); + $stat =~ s/\n./\n /g; + $cond =~ s/\n./\n /g; + +#print "linenr<$linenr> <$stat>\n"; + # If this statement has no statement boundaries within + # it there is no point in retrying a statement scan + # until we hit end of it. + my $frag = $stat; $frag =~ s/;+\s*$//; + if ($frag !~ /(?:{|;)/) { +#print "skip<$line_nr_next>\n"; + $suppress_statement = $line_nr_next; + } + + # Find the real next line. + $realline_next = $line_nr_next; + if (defined $realline_next && + (!defined $lines[$realline_next - 1] || + substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { + $realline_next++; + } + + my $s = $stat; + $s =~ s/{.*$//s; + + # Ignore goto labels. + if ($s =~ /$Ident:\*$/s) { + + # Ignore functions being called + } elsif ($s =~ /^.\s*$Ident\s*\(/s) { + + } elsif ($s =~ /^.\s*else\b/s) { + + # declarations always start with types + } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { + my $type = $1; + $type =~ s/\s+/ /g; + possible($type, "A:" . $s); + + # definitions in global scope can only start with types + } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { + possible($1, "B:" . $s); + } + + # any (foo ... *) is a pointer cast, and foo is a type + while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { + possible($1, "C:" . $s); + } + + # Check for any sort of function declaration. + # int foo(something bar, other baz); + # void (*store_gdt)(x86_descr_ptr *); + if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { + my ($name_len) = length($1); + + my $ctx = $s; + substr($ctx, 0, $name_len + 1, ''); + $ctx =~ s/\)[^\)]*$//; + + for my $arg (split(/\s*,\s*/, $ctx)) { + if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { + + possible($1, "D:" . $s); + } + } + } + + } + +# +# Checks which may be anchored in the context. +# + +# Check for switch () and associated case and default +# statements should be at the same indent. + if ($line=~/\bswitch\s*\(.*\)/) { + my $err = ''; + my $sep = ''; + my @ctx = ctx_block_outer($linenr, $realcnt); + shift(@ctx); + for my $ctx (@ctx) { + my ($clen, $cindent) = line_stats($ctx); + if ($ctx =~ /^\+\s*(case\s+|default:)/ && + $indent != $cindent) { + $err .= "$sep$ctx\n"; + $sep = ''; + } else { + $sep = "[...]\n"; + } + } + if ($err ne '') { + ERROR("SWITCH_CASE_INDENT_LEVEL", + "switch and case should be at the same indent\n$hereline$err"); + } + } + +# if/while/etc brace do not go on next line, unless defining a do while loop, +# or if that brace on the next line is for something else + if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { + my $pre_ctx = "$1$2"; + + my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); + + if ($line =~ /^\+\t{6,}/) { + WARN("DEEP_INDENTATION", + "Too many leading tabs - consider code refactoring\n" . $herecurr); + } + + my $ctx_cnt = $realcnt - $#ctx - 1; + my $ctx = join("\n", @ctx); + + my $ctx_ln = $linenr; + my $ctx_skip = $realcnt; + + while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && + defined $lines[$ctx_ln - 1] && + $lines[$ctx_ln - 1] =~ /^-/)) { + ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; + $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); + $ctx_ln++; + } + + #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; + #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; + + if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { + ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); + } + if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && + $ctx =~ /\)\s*\;\s*$/ && + defined $lines[$ctx_ln - 1]) + { + my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); + if ($nindent > $indent) { + WARN("TRAILING_SEMICOLON", + "trailing semicolon indicates no statements, indent implies otherwise\n" . + "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); + } + } + } + +# Check relative indent for conditionals and blocks. + if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0) + if (!defined $stat); + my ($s, $c) = ($stat, $cond); + + substr($s, 0, length($c), ''); + + # Make sure we remove the line prefixes as we have + # none on the first line, and are going to readd them + # where necessary. + $s =~ s/\n./\n/gs; + + # Find out how long the conditional actually is. + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; + + # We want to check the first line inside the block + # starting at the end of the conditional, so remove: + # 1) any blank line termination + # 2) any opening brace { on end of the line + # 3) any do (...) { + my $continuation = 0; + my $check = 0; + $s =~ s/^.*\bdo\b//; + $s =~ s/^\s*{//; + if ($s =~ s/^\s*\\//) { + $continuation = 1; + } + if ($s =~ s/^\s*?\n//) { + $check = 1; + $cond_lines++; + } + + # Also ignore a loop construct at the end of a + # preprocessor statement. + if (($prevline =~ /^.\s*#\s*define\s/ || + $prevline =~ /\\\s*$/) && $continuation == 0) { + $check = 0; + } + + my $cond_ptr = -1; + $continuation = 0; + while ($cond_ptr != $cond_lines) { + $cond_ptr = $cond_lines; + + # If we see an #else/#elif then the code + # is not linear. + if ($s =~ /^\s*\#\s*(?:else|elif)/) { + $check = 0; + } + + # Ignore: + # 1) blank lines, they should be at 0, + # 2) preprocessor lines, and + # 3) labels. + if ($continuation || + $s =~ /^\s*?\n/ || + $s =~ /^\s*#\s*?/ || + $s =~ /^\s*$Ident\s*:/) { + $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; + if ($s =~ s/^.*?\n//) { + $cond_lines++; + } + } + } + + my (undef, $sindent) = line_stats("+" . $s); + my $stat_real = raw_line($linenr, $cond_lines); + + # Check if either of these lines are modified, else + # this is not this patch's fault. + if (!defined($stat_real) || + $stat !~ /^\+/ && $stat_real !~ /^\+/) { + $check = 0; + } + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; + + if ($check && (($sindent % 8) != 0 || + ($sindent <= $indent && $s ne ''))) { + WARN("SUSPECT_CODE_INDENT", + "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); + } + } + + # Track the 'values' across context and added lines. + my $opline = $line; $opline =~ s/^./ /; + my ($curr_values, $curr_vars) = + annotate_values($opline . "\n", $prev_values); + $curr_values = $prev_values . $curr_values; + if ($dbg_values) { + my $outline = $opline; $outline =~ s/\t/ /g; + print "$linenr > .$outline\n"; + print "$linenr > $curr_values\n"; + print "$linenr > $curr_vars\n"; + } + $prev_values = substr($curr_values, -1); + +#ignore lines not being added + if ($line=~/^[^\+]/) {next;} + +# TEST: allow direct testing of the type matcher. + if ($dbg_type) { + if ($line =~ /^.\s*$Declare\s*$/) { + ERROR("TEST_TYPE", + "TEST: is type\n" . $herecurr); + } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { + ERROR("TEST_NOT_TYPE", + "TEST: is not type ($1 is)\n". $herecurr); + } + next; + } +# TEST: allow direct testing of the attribute matcher. + if ($dbg_attr) { + if ($line =~ /^.\s*$Modifier\s*$/) { + ERROR("TEST_ATTR", + "TEST: is attr\n" . $herecurr); + } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { + ERROR("TEST_NOT_ATTR", + "TEST: is not attr ($1 is)\n". $herecurr); + } + next; + } + +# check for initialisation to aggregates open brace on the next line + if ($line =~ /^.\s*{/ && + $prevline =~ /(?:^|[^=])=\s*$/) { + ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . $hereprev); + } + +# +# Checks which are anchored on the added line. +# + +# check for malformed paths in #include statements (uses RAW line) + if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { + my $path = $1; + if ($path =~ m{//}) { + ERROR("MALFORMED_INCLUDE", + "malformed #include filename\n" . $herecurr); + } + if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { + ERROR("UAPI_INCLUDE", + "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); + } + } + +# no C99 // comments + if ($line =~ m{//}) { + ERROR("C99_COMMENTS", + "do not use C99 // comments\n" . $herecurr); + } + # Remove C99 comments. + $line =~ s@//.*@@; + $opline =~ s@//.*@@; + +# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider +# the whole statement. +#print "APW <$lines[$realline_next - 1]>\n"; + if (defined $realline_next && + exists $lines[$realline_next - 1] && + !defined $suppress_export{$realline_next} && + ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || + $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { + # Handle definitions which produce identifiers with + # a prefix: + # XXX(foo); + # EXPORT_SYMBOL(something_foo); + my $name = $1; + if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && + $name =~ /^${Ident}_$2/) { +#print "FOO C name<$name>\n"; + $suppress_export{$realline_next} = 1; + + } elsif ($stat !~ /(?: + \n.}\s*$| + ^.DEFINE_$Ident\(\Q$name\E\)| + ^.DECLARE_$Ident\(\Q$name\E\)| + ^.LIST_HEAD\(\Q$name\E\)| + ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| + \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() + )/x) { +#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; + $suppress_export{$realline_next} = 2; + } else { + $suppress_export{$realline_next} = 1; + } + } + if (!defined $suppress_export{$linenr} && + $prevline =~ /^.\s*$/ && + ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || + $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { +#print "FOO B <$lines[$linenr - 1]>\n"; + $suppress_export{$linenr} = 2; + } + if (defined $suppress_export{$linenr} && + $suppress_export{$linenr} == 2) { + WARN("EXPORT_SYMBOL", + "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); + } + +# check for global initialisers. + if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { + ERROR("GLOBAL_INITIALISERS", + "do not initialise globals to 0 or NULL\n" . + $herecurr); + } +# check for static initialisers. + if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) { + ERROR("INITIALISED_STATIC", + "do not initialise statics to 0 or NULL\n" . + $herecurr); + } + +# check for static const char * arrays. + if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { + WARN("STATIC_CONST_CHAR_ARRAY", + "static const char * array should probably be static const char * const\n" . + $herecurr); + } + +# check for static char foo[] = "bar" declarations. + if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { + WARN("STATIC_CONST_CHAR_ARRAY", + "static char array declaration should probably be static const char\n" . + $herecurr); + } + +# check for declarations of struct pci_device_id + if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { + WARN("DEFINE_PCI_DEVICE_TABLE", + "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); + } + +# check for new typedefs, only function parameters and sparse annotations +# make sense. + if ($line =~ /\btypedef\s/ && + $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && + $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && + $line !~ /\b$typeTypedefs\b/ && + $line !~ /\b__bitwise(?:__|)\b/) { + WARN("NEW_TYPEDEFS", + "do not add new typedefs\n" . $herecurr); + } + +# * goes on variable not on type + # (char*[ const]) + while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { + #print "AA<$1>\n"; + my ($from, $to) = ($2, $2); + + # Should start with a space. + $to =~ s/^(\S)/ $1/; + # Should not end with a space. + $to =~ s/\s+$//; + # '*'s should not have spaces between. + while ($to =~ s/\*\s+\*/\*\*/) { + } + + #print "from<$from> to<$to>\n"; + if ($from ne $to) { + ERROR("POINTER_LOCATION", + "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); + } + } + while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { + #print "BB<$1>\n"; + my ($from, $to, $ident) = ($2, $2, $3); + + # Should start with a space. + $to =~ s/^(\S)/ $1/; + # Should not end with a space. + $to =~ s/\s+$//; + # '*'s should not have spaces between. + while ($to =~ s/\*\s+\*/\*\*/) { + } + # Modifiers should have spaces. + $to =~ s/(\b$Modifier$)/$1 /; + + #print "from<$from> to<$to> ident<$ident>\n"; + if ($from ne $to && $ident !~ /^$Modifier$/) { + ERROR("POINTER_LOCATION", + "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); + } + } + +# # no BUG() or BUG_ON() +# if ($line =~ /\b(BUG|BUG_ON)\b/) { +# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; +# print "$herecurr"; +# $clean = 0; +# } + + if ($line =~ /\bLINUX_VERSION_CODE\b/) { + WARN("LINUX_VERSION_CODE", + "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); + } + +# check for uses of printk_ratelimit + if ($line =~ /\bprintk_ratelimit\s*\(/) { + WARN("PRINTK_RATELIMITED", +"Prefer printk_ratelimited or pr__ratelimited to printk_ratelimit\n" . $herecurr); + } + +# printk should use KERN_* levels. Note that follow on printk's on the +# same line do not need a level, so we use the current block context +# to try and find and validate the current printk. In summary the current +# printk includes all preceding printk's which have no newline on the end. +# we assume the first bad printk is the one to report. + if ($line =~ /\bprintk\((?!KERN_)\s*"/) { + my $ok = 0; + for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { + #print "CHECK<$lines[$ln - 1]\n"; + # we have a preceding printk if it ends + # with "\n" ignore it, else it is to blame + if ($lines[$ln - 1] =~ m{\bprintk\(}) { + if ($rawlines[$ln - 1] !~ m{\\n"}) { + $ok = 1; + } + last; + } + } + if ($ok == 0) { + WARN("PRINTK_WITHOUT_KERN_LEVEL", + "printk() should include KERN_ facility level\n" . $herecurr); + } + } + + if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { + my $orig = $1; + my $level = lc($orig); + $level = "warn" if ($level eq "warning"); + my $level2 = $level; + $level2 = "dbg" if ($level eq "debug"); + WARN("PREFER_PR_LEVEL", + "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); + } + + if ($line =~ /\bpr_warning\s*\(/) { + WARN("PREFER_PR_LEVEL", + "Prefer pr_warn(... to pr_warning(...\n" . $herecurr); + } + + if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { + my $orig = $1; + my $level = lc($orig); + $level = "warn" if ($level eq "warning"); + $level = "dbg" if ($level eq "debug"); + WARN("PREFER_DEV_LEVEL", + "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); + } + +# function brace can't be on same line, except for #defines of do while, +# or if closed on same line + if (($line=~/$Type\s*$Ident\(.*\).*\s\{/) and + !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { + ERROR("OPEN_BRACE", + "open brace '{' following function declarations go on the next line\n" . $herecurr); + } + +# open braces for enum, union and struct go on the same line. + if ($line =~ /^.\s*{/ && + $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { + ERROR("OPEN_BRACE", + "open brace '{' following $1 go on the same line\n" . $hereprev); + } + +# missing space after union, struct or enum definition + if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { + WARN("SPACING", + "missing space after $1 definition\n" . $herecurr); + } + +# check for spacing round square brackets; allowed: +# 1. with a type on the left -- int [] a; +# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, +# 3. inside a curly brace -- = { [0...10] = 5 } + while ($line =~ /(.*?\s)\[/g) { + my ($where, $prefix) = ($-[1], $1); + if ($prefix !~ /$Type\s+$/ && + ($where != 0 || $prefix !~ /^.\s+$/) && + $prefix !~ /[{,]\s+$/) { + ERROR("BRACKET_SPACE", + "space prohibited before open square bracket '['\n" . $herecurr); + } + } + +# check for spaces between functions and their parentheses. + while ($line =~ /($Ident)\s+\(/g) { + my $name = $1; + my $ctx_before = substr($line, 0, $-[1]); + my $ctx = "$ctx_before$name"; + + # Ignore those directives where spaces _are_ permitted. + if ($name =~ /^(?: + if|for|while|switch|return|case| + volatile|__volatile__| + __attribute__|format|__extension__| + asm|__asm__)$/x) + { + + # cpp #define statements have non-optional spaces, ie + # if there is a space between the name and the open + # parenthesis it is simply not a parameter group. + } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { + + # cpp #elif statement condition may start with a ( + } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { + + # If this whole things ends with a type its most + # likely a typedef for a function. + } elsif ($ctx =~ /$Type$/) { + + } else { + WARN("SPACING", + "space prohibited between function name and open parenthesis '('\n" . $herecurr); + } + } + +# check for whitespace before a non-naked semicolon + if ($line =~ /^\+.*\S\s+;/) { + WARN("SPACING", + "space prohibited before semicolon\n" . $herecurr); + } + +# Check operator spacing. + if (!($line=~/\#\s*include/)) { + my $ops = qr{ + <<=|>>=|<=|>=|==|!=| + \+=|-=|\*=|\/=|%=|\^=|\|=|&=| + =>|->|<<|>>|<|>|=|!|~| + &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| + \?|: + }x; + my @elements = split(/($ops|;)/, $opline); + my $off = 0; + + my $blank = copy_spacing($opline); + + for (my $n = 0; $n < $#elements; $n += 2) { + $off += length($elements[$n]); + + # Pick up the preceding and succeeding characters. + my $ca = substr($opline, 0, $off); + my $cc = ''; + if (length($opline) >= ($off + length($elements[$n + 1]))) { + $cc = substr($opline, $off + length($elements[$n + 1])); + } + my $cb = "$ca$;$cc"; + + my $a = ''; + $a = 'V' if ($elements[$n] ne ''); + $a = 'W' if ($elements[$n] =~ /\s$/); + $a = 'C' if ($elements[$n] =~ /$;$/); + $a = 'B' if ($elements[$n] =~ /(\[|\()$/); + $a = 'O' if ($elements[$n] eq ''); + $a = 'E' if ($ca =~ /^\s*$/); + + my $op = $elements[$n + 1]; + + my $c = ''; + if (defined $elements[$n + 2]) { + $c = 'V' if ($elements[$n + 2] ne ''); + $c = 'W' if ($elements[$n + 2] =~ /^\s/); + $c = 'C' if ($elements[$n + 2] =~ /^$;/); + $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); + $c = 'O' if ($elements[$n + 2] eq ''); + $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); + } else { + $c = 'E'; + } + + my $ctx = "${a}x${c}"; + + my $at = "(ctx:$ctx)"; + + my $ptr = substr($blank, 0, $off) . "^"; + my $hereptr = "$hereline$ptr\n"; + + # Pull out the value of this operator. + my $op_type = substr($curr_values, $off + 1, 1); + + # Get the full operator variant. + my $opv = $op . substr($curr_vars, $off, 1); + + # Ignore operators passed as parameters. + if ($op_type ne 'V' && + $ca =~ /\s$/ && $cc =~ /^\s*,/) { + +# # Ignore comments +# } elsif ($op =~ /^$;+$/) { + + # ; should have either the end of line or a space or \ after it + } elsif ($op eq ';') { + if ($ctx !~ /.x[WEBC]/ && + $cc !~ /^\\/ && $cc !~ /^;/) { + ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr); + } + + # // is a comment + } elsif ($op eq '//') { + + # No spaces for: + # -> + # : when part of a bitfield + } elsif ($op eq '->' || $opv eq ':B') { + if ($ctx =~ /Wx.|.xW/) { + ERROR("SPACING", + "spaces prohibited around that '$op' $at\n" . $hereptr); + } + + # , must have a space on the right. + } elsif ($op eq ',') { + if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { + ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr); + } + + # '*' as part of a type definition -- reported already. + } elsif ($opv eq '*_') { + #warn "'*' is part of type\n"; + + # unary operators should have a space before and + # none after. May be left adjacent to another + # unary operator, or a cast + } elsif ($op eq '!' || $op eq '~' || + $opv eq '*U' || $opv eq '-U' || + $opv eq '&U' || $opv eq '&&U') { + if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { + ERROR("SPACING", + "space required before that '$op' $at\n" . $hereptr); + } + if ($op eq '*' && $cc =~/\s*$Modifier\b/) { + # A unary '*' may be const + + } elsif ($ctx =~ /.xW/) { + ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr); + } + + # unary ++ and unary -- are allowed no space on one side. + } elsif ($op eq '++' or $op eq '--') { + if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { + ERROR("SPACING", + "space required one side of that '$op' $at\n" . $hereptr); + } + if ($ctx =~ /Wx[BE]/ || + ($ctx =~ /Wx./ && $cc =~ /^;/)) { + ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr); + } + if ($ctx =~ /ExW/) { + ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr); + } + + + # << and >> may either have or not have spaces both sides + } elsif ($op eq '<<' or $op eq '>>' or + $op eq '&' or $op eq '^' or $op eq '|' or + $op eq '+' or $op eq '-' or + $op eq '*' or $op eq '/' or + $op eq '%') + { + if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { + ERROR("SPACING", + "need consistent spacing around '$op' $at\n" . + $hereptr); + } + + # A colon needs no spaces before when it is + # terminating a case value or a label. + } elsif ($opv eq ':C' || $opv eq ':L') { + if ($ctx =~ /Wx./) { + ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr); + } + + # All the others need spaces both sides. + } elsif ($ctx !~ /[EWC]x[CWE]/) { + my $ok = 0; + + # Ignore email addresses + if (($op eq '<' && + $cc =~ /^\S+\@\S+>/) || + ($op eq '>' && + $ca =~ /<\S+\@\S+$/)) + { + $ok = 1; + } + + # Ignore ?: + if (($opv eq ':O' && $ca =~ /\?$/) || + ($op eq '?' && $cc =~ /^:/)) { + $ok = 1; + } + + if ($ok == 0) { + ERROR("SPACING", + "spaces required around that '$op' $at\n" . $hereptr); + } + } + $off += length($elements[$n + 1]); + } + } + +# check for multiple assignments + if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { + CHK("MULTIPLE_ASSIGNMENTS", + "multiple assignments should be avoided\n" . $herecurr); + } + +## # check for multiple declarations, allowing for a function declaration +## # continuation. +## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && +## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { +## +## # Remove any bracketed sections to ensure we do not +## # falsly report the parameters of functions. +## my $ln = $line; +## while ($ln =~ s/\([^\(\)]*\)//g) { +## } +## if ($ln =~ /,/) { +## WARN("MULTIPLE_DECLARATION", +## "declaring multiple variables together should be avoided\n" . $herecurr); +## } +## } + +#need space before brace following if, while, etc + if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || + $line =~ /do\{/) { + ERROR("SPACING", + "space required before the open brace '{'\n" . $herecurr); + } + +# closing brace should have a space following it when it has anything +# on the line + if ($line =~ /\}(?!(?:,|;|\)))\S/) { + ERROR("SPACING", + "space required after that close brace '}'\n" . $herecurr); + } + +# check spacing on square brackets + if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { + ERROR("SPACING", + "space prohibited after that open square bracket '['\n" . $herecurr); + } + if ($line =~ /\s\]/) { + ERROR("SPACING", + "space prohibited before that close square bracket ']'\n" . $herecurr); + } + +# check spacing on parentheses + if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && + $line !~ /for\s*\(\s+;/) { + ERROR("SPACING", + "space prohibited after that open parenthesis '('\n" . $herecurr); + } + if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && + $line !~ /for\s*\(.*;\s+\)/ && + $line !~ /:\s+\)/) { + ERROR("SPACING", + "space prohibited before that close parenthesis ')'\n" . $herecurr); + } + +#goto labels aren't indented, allow a single space however + if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and + !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { + WARN("INDENTED_LABEL", + "labels should not be indented\n" . $herecurr); + } + +# Return is not a function. + if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { + my $spacing = $1; + my $value = $2; + + # Flatten any parentheses + $value =~ s/\(/ \(/g; + $value =~ s/\)/\) /g; + while ($value =~ s/\[[^\[\]]*\]/1/ || + $value !~ /(?:$Ident|-?$Constant)\s* + $Compare\s* + (?:$Ident|-?$Constant)/x && + $value =~ s/\([^\(\)]*\)/1/) { + } +#print "value<$value>\n"; + if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { + ERROR("RETURN_PARENTHESES", + "return is not a function, parentheses are not required\n" . $herecurr); + + } elsif ($spacing !~ /\s+/) { + ERROR("SPACING", + "space required before the open parenthesis '('\n" . $herecurr); + } + } +# Return of what appears to be an errno should normally be -'ve + if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { + my $name = $1; + if ($name ne 'EOF' && $name ne 'ERROR') { + WARN("USE_NEGATIVE_ERRNO", + "return of an errno should typically be -ve (return -$1)\n" . $herecurr); + } + } + +# Need a space before open parenthesis after if, while etc + if ($line=~/\b(if|while|for|switch)\(/) { + ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr); + } + +# Check for illegal assignment in if conditional -- and check for trailing +# statements after the conditional. + if ($line =~ /do\s*(?!{)/) { + ($stat, $cond, $line_nr_next, $remain_next, $off_next) = + ctx_statement_block($linenr, $realcnt, 0) + if (!defined $stat); + my ($stat_next) = ctx_statement_block($line_nr_next, + $remain_next, $off_next); + $stat_next =~ s/\n./\n /g; + ##print "stat<$stat> stat_next<$stat_next>\n"; + + if ($stat_next =~ /^\s*while\b/) { + # If the statement carries leading newlines, + # then count those as offsets. + my ($whitespace) = + ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); + my $offset = + statement_rawlines($whitespace) - 1; + + $suppress_whiletrailers{$line_nr_next + + $offset} = 1; + } + } + if (!defined $suppress_whiletrailers{$linenr} && + $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { + my ($s, $c) = ($stat, $cond); + + if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { + ERROR("ASSIGN_IN_IF", + "do not use assignment in if condition\n" . $herecurr); + } + + # Find out what is on the end of the line after the + # conditional. + substr($s, 0, length($c), ''); + $s =~ s/\n.*//g; + $s =~ s/$;//g; # Remove any comments + if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && + $c !~ /}\s*while\s*/ && !($c =~ /while/ && $s eq ";")) + { + # Find out how long the conditional actually is. + my @newlines = ($c =~ /\n/gs); + my $cond_lines = 1 + $#newlines; + my $stat_real = ''; + + $stat_real = raw_line($linenr, $cond_lines) + . "\n" if ($cond_lines); + if (defined($stat_real) && $cond_lines > 1) { + $stat_real = "[...]\n$stat_real"; + } + + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr . $stat_real); + } + } + +# Check for bitwise tests written as boolean + if ($line =~ / + (?: + (?:\[|\(|\&\&|\|\|) + \s*0[xX][0-9]+\s* + (?:\&\&|\|\|) + | + (?:\&\&|\|\|) + \s*0[xX][0-9]+\s* + (?:\&\&|\|\||\)|\]) + )/x) + { + WARN("HEXADECIMAL_BOOLEAN_TEST", + "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); + } + +# if and else should not have general statements after it + if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { + my $s = $1; + $s =~ s/$;//g; # Remove any comments + if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr); + } + } +# if should not continue a brace + if ($line =~ /}\s*if\b/) { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . + $herecurr); + } +# case and default should not have general statements after them + if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && + $line !~ /\G(?: + (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| + \s*return\s+ + )/xg) + { + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr); + } + + # Check for }else {, these must be at the same + # indent level to be relevant to each other. + if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and + $previndent == $indent) { + ERROR("ELSE_AFTER_BRACE", + "else should follow close brace '}'\n" . $hereprev); + } + + #if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and + # $previndent == $indent) { + # my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); + + # # Find out what is on the end of the line after the + # # conditional. + # substr($s, 0, length($c), ''); + # $s =~ s/\n.*//g; + + # if ($s =~ /^\s*;/) { + # ERROR("WHILE_AFTER_BRACE", + # "while should follow close brace '}'\n" . $hereprev); + # } + #} + +#CamelCase + while ($line =~ m{($Constant|$Lval)}g) { + my $var = $1; + if ($var !~ /$Constant/ && + $var =~ /[A-Z]\w*[a-z]|[a-z]\w*[A-Z]/ && + $var !~ /"^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && + !defined $camelcase{$var} && + $var !~ /[A-Z][A-Z0-9_]*x[A-Z0-9_]*\b/) { + $camelcase{$var} = 1; + #print "Camelcase line <<$line>> <<$var>>\n"; + WARN("CAMELCASE", + "Avoid CamelCase: <$var>\n" . $herecurr); + } + } + +#no spaces allowed after \ in define + if ($line=~/\#\s*define.*\\\s$/) { + WARN("WHITESPACE_AFTER_LINE_CONTINUATION", + "Whitepspace after \\ makes next lines useless\n" . $herecurr); + } + +#warn if is #included and is available (uses RAW line) + if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\}) { + my $file = "$1.h"; + my $checkfile = "include/linux/$file"; + if (-f "$root/$checkfile" && + $realfile ne $checkfile && + $1 !~ /$allowed_asm_includes/) + { + if ($realfile =~ m{^arch/}) { + CHK("ARCH_INCLUDE_LINUX", + "Consider using #include instead of \n" . $herecurr); + } else { + WARN("INCLUDE_LINUX", + "Use #include instead of \n" . $herecurr); + } + } + } + +# multi-statement macros should be enclosed in a do while loop, grab the +# first statement and ensure its the whole macro if its not enclosed +# in a known good container + if ($realfile !~ m@/vmlinux.lds.h$@ && + $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { + my $ln = $linenr; + my $cnt = $realcnt; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $realcnt, 0); + $ctx = $dstat; + #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; + #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; + + $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; + $dstat =~ s/$;//g; + $dstat =~ s/\\\n.//g; + $dstat =~ s/^\s*//s; + $dstat =~ s/\s*$//s; + + # Flatten any parentheses and braces + while ($dstat =~ s/\([^\(\)]*\)/1/ || + $dstat =~ s/\{[^\{\}]*\}/1/ || + $dstat =~ s/\[[^\[\]]*\]/1/) + { + } + + # Flatten any obvious string concatentation. + while ($dstat =~ s/("X*")\s*$Ident/$1/ || + $dstat =~ s/$Ident\s*("X*")/$1/) + { + } + + my $exceptions = qr{ + $Declare| + module_param_named| + MODULE_PARM_DESC| + DECLARE_PER_CPU| + DEFINE_PER_CPU| + __typeof__\(| + union| + struct| + \.$Ident\s*=\s*| + ^\"|\"$ + }x; + #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; + if ($dstat ne '' && + $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), + $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); + $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo + $dstat !~ /^'X'$/ && # character constants + $dstat !~ /$exceptions/ && + $dstat !~ /^\.$Ident\s*=/ && # .foo = + $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo + $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) + $dstat !~ /^for\s*$Constant$/ && # for (...) + $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() + $dstat !~ /^do\s*\{/ && # do {... + $dstat !~ /^\(\{/) # ({... + { + $ctx =~ s/\n*$//; + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($ctx); + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + if ($dstat =~ /;/) { + ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", + "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); + } else { + ERROR("COMPLEX_MACRO", + "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); + } + } + +# check for line continuations outside of #defines, preprocessor #, and asm + + } else { + if ($prevline !~ /^..*\\$/ && + $line !~ /^\+\s*\#.*\\$/ && # preprocessor + $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm + $line =~ /^\+.*\\$/) { + WARN("LINE_CONTINUATIONS", + "Avoid unnecessary line continuations\n" . $herecurr); + } + } + +# do {} while (0) macro tests: +# single-statement macros do not need to be enclosed in do while (0) loop, +# macro should not end with a semicolon + if ($^V && $^V ge 5.10.0 && + $realfile !~ m@/vmlinux.lds.h$@ && + $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { + my $ln = $linenr; + my $cnt = $realcnt; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $realcnt, 0); + $ctx = $dstat; + + $dstat =~ s/\\\n.//g; + + if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { + my $stmts = $2; + my $semis = $3; + + $ctx =~ s/\n*$//; + my $cnt = statement_rawlines($ctx); + my $herectx = $here . "\n"; + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + if (($stmts =~ tr/;/;/) == 1 && + $stmts !~ /^\s*(if|while|for|switch)\b/) { + WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", + "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); + } + if (defined $semis && $semis ne "") { + WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", + "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); + } + } + } + +# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... +# all assignments may have only one of the following with an assignment: +# . +# ALIGN(...) +# VMLINUX_SYMBOL(...) + if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { + WARN("MISSING_VMLINUX_SYMBOL", + "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); + } + +# check for redundant bracing round if etc + if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { + my ($level, $endln, @chunks) = + ctx_statement_full($linenr, $realcnt, 1); + #if ($#chunks > 0) { + # print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; + # my $count = 0; + # for my $chunk (@chunks) { + # my ($cond, $block) = @{$chunk}; + # print "APW: count<$count> <<$cond>><<$block>>\n"; + # $count++; + # } + #} + if ($#chunks > 0 && $level == 0) { + my @allowed = (); + my $allow = 0; + my $seen = 0; + my $herectx = $here . "\n"; + my $ln = $linenr - 1; + for my $chunk (@chunks) { + my ($cond, $block) = @{$chunk}; + + # If the condition carries leading newlines, then count those as offsets. + my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); + my $offset = statement_rawlines($whitespace) - 1; + + $allowed[$allow] = 0; + #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; + + # We have looked at and allowed this specific line. + $suppress_ifbraces{$ln + $offset} = 1; + + $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; + $ln += statement_rawlines($block) - 1; + + substr($block, 0, length($cond), ''); + + $seen++ if ($block =~ /^\s*{/); + + #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; + #if (statement_lines($cond) > 1) { + # #print "APW: ALLOWED: cond<$cond>\n"; + # $allowed[$allow] = 1; + #} + #if ($block =~/\b(?:if|for|while)\b/) { + # #print "APW: ALLOWED: block<$block>\n"; + # $allowed[$allow] = 1; + #} + #if (statement_block_size($block) > 1) { + # #print "APW: ALLOWED: lines block<$block>\n"; + # $allowed[$allow] = 1; + #} + #$allow++; + } + if (!$seen) { + ERROR("BRACES", + "braces {} are necessary for all arms of this statement\n" . $herectx); + } + #if ($seen) { + # my $sum_allowed = 0; + # foreach (@allowed) { + # $sum_allowed += $_; + # } + # if ($sum_allowed == 0) { + # WARN("BRACES", + # "braces {} are not necessary for any arm of this statement\n" . $herectx); + # } elsif ($sum_allowed != $allow && + # $seen != $allow) { + # CHK("BRACES", + # "braces {} should be used on all arms of this statement\n" . $herectx); + # } + #} + } + } + if (!defined $suppress_ifbraces{$linenr - 1} && + $line =~ /\b(if|while|for|else)\b/) { + my $allowed = 0; + + # Check the pre-context. + if (substr($line, 0, $-[0]) =~ /(#\s*)$/) { + #print "APW: ALLOWED: pre<$1>\n"; + $allowed = 1; + } + + my ($level, $endln, @chunks) = + ctx_statement_full($linenr, $realcnt, $-[0]); + + # Check the condition. + my ($cond, $block) = @{$chunks[0]}; + #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; + if (defined $cond) { + substr($block, 0, length($cond), ''); + } + if ($cond =~ /\bwhile/ && $block =~ /^;/) { + #print "APW: ALLOWED: block<$block>"; + $allowed = 1; + } + #if ($block =~/\b(?:if|for|while)\b/) { + # print "APW: ALLOWED: block<$block>\n"; + # $allowed = 1; + #} + + # Check the post-context. + if (defined $chunks[1]) { + my ($cond, $block) = @{$chunks[1]}; + if (defined $cond) { + substr($block, 0, length($cond), ''); + } + if ($block =~ /^\s*\{/) { + #print "APW: ALLOWED: chunk-1 block<$block>\n"; + #$allowed = 1; + } + } + if ($level == 0 && !($block =~ /^\s*\{/) && !$allowed) { + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($block); + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + WARN("BRACES", + "braces {} are needed for every statement block\n" . $herectx); + } + } + +# check for unnecessary blank lines around braces + if (($line =~ /^.\s*}\s*$/ && $prevline =~ /^.\s*$/)) { + CHK("BRACES", + "Blank lines aren't necessary before a close brace '}'\n" . $hereprev); + } + if (($line =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { + CHK("BRACES", + "Blank lines aren't necessary after an open brace '{'\n" . $hereprev); + } + +# no volatiles please + my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; + if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { + WARN("VOLATILE", + "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); + } + +# warn about #if 0 + if ($line =~ /^.\s*\#\s*if\s+0\b/) { + CHK("REDUNDANT_CODE", + "if this code is redundant consider removing it\n" . + $herecurr); + } + +# check for needless "if () fn()" uses + if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { + my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;'; + if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) { + WARN('NEEDLESS_IF', + "$1(NULL) is safe this check is probably not required\n" . $hereprev); + } + } + +# prefer usleep_range over udelay + if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { + # ignore udelay's < 10, however + if (! ($1 < 10) ) { + CHK("USLEEP_RANGE", + "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line); + } + } + +# warn about unexpectedly long msleep's + if ($line =~ /\bmsleep\s*\((\d+)\);/) { + if ($1 < 20) { + WARN("MSLEEP", + "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line); + } + } + +# warn about #ifdefs in C files +# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { +# print "#ifdef in C files should be avoided\n"; +# print "$herecurr"; +# $clean = 0; +# } + +# warn about spacing in #ifdefs + if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { + ERROR("SPACING", + "exactly one space required after that #$1\n" . $herecurr); + } + +# check for spinlock_t definitions without a comment. + if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || + $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { + my $which = $1; + if (!ctx_has_comment($first_line, $linenr)) { + CHK("UNCOMMENTED_DEFINITION", + "$1 definition without comment\n" . $herecurr); + } + } +# check for memory barriers without a comment. + if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { + if (!ctx_has_comment($first_line, $linenr)) { + CHK("MEMORY_BARRIER", + "memory barrier without comment\n" . $herecurr); + } + } +# check of hardware specific defines + if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { + CHK("ARCH_DEFINES", + "architecture specific defines should be avoided\n" . $herecurr); + } + +# Check that the storage class is at the beginning of a declaration + if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { + WARN("STORAGE_CLASS", + "storage class should be at the beginning of the declaration\n" . $herecurr) + } + +# check the location of the inline attribute, that it is between +# storage class and type. + if ($line =~ /\b$Type\s+$Inline\b/ || + $line =~ /\b$Inline\s+$Storage\b/) { + ERROR("INLINE_LOCATION", + "inline keyword should sit between storage class and type\n" . $herecurr); + } + +# Check for __inline__ and __inline, prefer inline + if ($line =~ /\b(__inline__|__inline)\b/) { + WARN("INLINE", + "plain inline is preferred over $1\n" . $herecurr); + } + +# Check for __attribute__ format(printf, prefer __printf + if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { + WARN("PREFER_PRINTF", + "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr); + } + +# Check for __attribute__ format(scanf, prefer __scanf + if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { + WARN("PREFER_SCANF", + "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr); + } + +# check for sizeof(&) + if ($line =~ /\bsizeof\s*\(\s*\&/) { + WARN("SIZEOF_ADDRESS", + "sizeof(& should be avoided\n" . $herecurr); + } + +# check for sizeof without parenthesis + if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { + WARN("SIZEOF_PARENTHESIS", + "sizeof $1 should be sizeof($1)\n" . $herecurr); + } + +# check for line continuations in quoted strings with odd counts of " + if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { + WARN("LINE_CONTINUATIONS", + "Avoid line continuations in quoted strings\n" . $herecurr); + } + +# check for struct spinlock declarations + if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { + WARN("USE_SPINLOCK_T", + "struct spinlock should be spinlock_t\n" . $herecurr); + } + +# check for seq_printf uses that could be seq_puts + if ($line =~ /\bseq_printf\s*\(/) { + my $fmt = get_quoted_string($line, $rawline); + if ($fmt !~ /[^\\]\%/) { + WARN("PREFER_SEQ_PUTS", + "Prefer seq_puts to seq_printf\n" . $herecurr); + } + } + +# Check for misused memsets + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { + + my $ms_addr = $2; + my $ms_val = $7; + my $ms_size = $12; + + if ($ms_size =~ /^(0x|)0$/i) { + ERROR("MEMSET", + "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); + } elsif ($ms_size =~ /^(0x|)1$/i) { + WARN("MEMSET", + "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); + } + } + +# typecasts on min/max could be min_t/max_t + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { + if (defined $2 || defined $7) { + my $call = $1; + my $cast1 = deparenthesize($2); + my $arg1 = $3; + my $cast2 = deparenthesize($7); + my $arg2 = $8; + my $cast; + + if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { + $cast = "$cast1 or $cast2"; + } elsif ($cast1 ne "") { + $cast = $cast1; + } else { + $cast = $cast2; + } + WARN("MINMAX", + "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); + } + } + +# check usleep_range arguments + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { + my $min = $1; + my $max = $7; + if ($min eq $max) { + WARN("USLEEP_RANGE", + "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && + $min > $max) { + WARN("USLEEP_RANGE", + "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + } + } + +# check for new externs in .c files. + if ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) + { + my $function_name = $1; + my $paren_space = $2; + + my $s = $stat; + if (defined $cond) { + substr($s, 0, length($cond), ''); + } + if ($s =~ /^\s*;/ && + $function_name ne 'uninitialized_var') + { + WARN("AVOID_EXTERNS", + "externs should be avoided in .c files\n" . $herecurr); + } + + if ($paren_space =~ /\n/) { + WARN("FUNCTION_ARGUMENTS", + "arguments for function declarations should follow identifier\n" . $herecurr); + } + + } elsif ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*extern\s+/) + { + WARN("AVOID_EXTERNS", + "externs should be avoided in .c files\n" . $herecurr); + } + +# checks for new __setup's + if ($rawline =~ /\b__setup\("([^"]*)"/) { + my $name = $1; + + if (!grep(/$name/, @setup_docs)) { + CHK("UNDOCUMENTED_SETUP", + "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); + } + } + +# check for pointless casting of kmalloc return + if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { + WARN("UNNECESSARY_CASTS", + "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); + } + +# check for krealloc arg reuse + if ($^V && $^V ge 5.10.0 && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { + WARN("KREALLOC_ARG_REUSE", + "Reusing the krealloc arg is almost always a bug\n" . $herecurr); + } + +# check for alloc argument mismatch + if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { + WARN("ALLOC_ARRAY_ARGS", + "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); + } + +# check for multiple semicolons + if ($line =~ /;\s*;\s*$/) { + WARN("ONE_SEMICOLON", + "Statements terminations use 1 semicolon\n" . $herecurr); + } + +# check for switch/default statements without a break; + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { + my $ctx = ''; + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($stat); + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + WARN("DEFAULT_NO_BREAK", + "switch default: should use break\n" . $herectx); + } + +# check for gcc specific __FUNCTION__ + if ($line =~ /__FUNCTION__/) { + WARN("USE_FUNC", + "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); + } + +# check for use of yield() + if ($line =~ /\byield\s*\(\s*\)/) { + WARN("YIELD", + "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); + } + +# check for semaphores initialized locked + if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { + WARN("CONSIDER_COMPLETION", + "consider using a completion\n" . $herecurr); + } + +# recommend kstrto* over simple_strto* and strict_strto* + if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { + WARN("CONSIDER_KSTRTO", + "$1 is obsolete, use k$3 instead\n" . $herecurr); + } + +# check for __initcall(), use device_initcall() explicitly please + if ($line =~ /^.\s*__initcall\s*\(/) { + WARN("USE_DEVICE_INITCALL", + "please use device_initcall() instead of __initcall()\n" . $herecurr); + } + +# check for various ops structs, ensure they are const. + my $struct_ops = qr{acpi_dock_ops| + address_space_operations| + backlight_ops| + block_device_operations| + dentry_operations| + dev_pm_ops| + dma_map_ops| + extent_io_ops| + file_lock_operations| + file_operations| + hv_ops| + ide_dma_ops| + intel_dvo_dev_ops| + item_operations| + iwl_ops| + kgdb_arch| + kgdb_io| + kset_uevent_ops| + lock_manager_operations| + microcode_ops| + mtrr_ops| + neigh_ops| + nlmsvc_binding| + pci_raw_ops| + pipe_buf_operations| + platform_hibernation_ops| + platform_suspend_ops| + proto_ops| + rpc_pipe_ops| + seq_operations| + snd_ac97_build_ops| + soc_pcmcia_socket_ops| + stacktrace_ops| + sysfs_ops| + tty_operations| + usb_mon_operations| + wd_ops}x; + if ($line !~ /\bconst\b/ && + $line =~ /\bstruct\s+($struct_ops)\b/) { + WARN("CONST_STRUCT", + "struct $1 should normally be const\n" . + $herecurr); + } + +# use of NR_CPUS is usually wrong +# ignore definitions of NR_CPUS and usage to define arrays as likely right + if ($line =~ /\bNR_CPUS\b/ && + $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) + { + WARN("NR_CPUS", + "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); + } + +# check for %L{u,d,i} in strings + my $string; + while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { + $string = substr($rawline, $-[1], $+[1] - $-[1]); + $string =~ s/%%/__/g; + if ($string =~ /(?mutex.\n" . $herecurr); + } + } + + if ($line =~ /debugfs_create_file.*S_IWUGO/ || + $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { + WARN("EXPORTED_WORLD_WRITABLE", + "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); + } + } + + # If we have no input at all, then there is nothing to report on + # so just keep quiet. + if ($#rawlines == -1) { + exit(0); + } + + # In mailback mode only produce a report in the negative, for + # things that appear to be patches. + if ($mailback && ($clean == 1 || !$is_patch)) { + exit(0); + } + + # This is not a patch, and we are are in 'no-patch' mode so + # just keep quiet. + if (!$chk_patch && !$is_patch) { + exit(0); + } + + if (!$is_patch) { + ERROR("NOT_UNIFIED_DIFF", + "Does not appear to be a unified-diff format patch\n"); + } + if ($is_patch && $chk_signoff && $signoff == 0) { + ERROR("MISSING_SIGN_OFF", + "Missing Signed-off-by: line(s)\n"); + } + + print report_dump(); + if ($summary && !($clean == 1 && $quiet == 1)) { + print "$filename " if ($summary_file); + print "total: $cnt_error errors, $cnt_warn warnings, " . + (($check)? "$cnt_chk checks, " : "") . + "$cnt_lines lines checked\n"; + print "\n" if ($quiet == 0); + } + + if ($quiet == 0) { + + if ($^V lt 5.10.0) { + print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); + print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); + } + + # If there were whitespace errors which cleanpatch can fix + # then suggest that. + if ($rpt_cleaners) { + print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; + print " scripts/cleanfile\n\n"; + $rpt_cleaners = 0; + } + } + + if ($quiet == 0 && keys %ignore_type) { + print "NOTE: Ignored message types:"; + foreach my $ignore (sort keys %ignore_type) { + print " $ignore"; + } + print "\n\n"; + } + + if ($clean == 1 && $quiet == 0) { + print "$vname has no obvious style problems and is ready for submission.\n" + } + if ($clean == 0 && $quiet == 0) { + print << "EOM"; +$vname has style problems, please review. + +If any of these errors are false positives, please report +them to the maintainer, see CHECKPATCH in MAINTAINERS. +EOM + } + + return $clean; +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/README b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/README new file mode 100644 index 00000000..b7689366 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/README @@ -0,0 +1,23 @@ +These files contain information derived from the LPC43xx user manual (UM10503). +They are intended to be used by scripts for the generation of header files and +functions. + +Each line describes a field within a register. The comma separated values are: + register name (as found in include/lpc43xx/*.h), + bit position, + length in bits, + field name, + description/comment (may be empty if not specified in data sheet), + reset value (may be empty if not specified in data sheet), + access (may be empty if not specified in data sheet) + +The access field may consist of any of the following codes: + r: read only + rw: read/write + rwc: read/write one to clear + rwo: read/write once + rws: read/write one to set + w: write only + ws: write one to set + +Descriptions containing commas are quoted. diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/adc.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/adc.yaml new file mode 100644 index 00000000..9256e2a7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/adc.yaml @@ -0,0 +1,607 @@ +!!omap +- ADC0_CR: + fields: !!omap + - SEL: + access: rw + description: Selects which of the ADCn_[7:0] inputs are to be sampled and + converted + lsb: 0 + reset_value: '0' + width: 8 + - CLKDIV: + access: rw + description: The ADC clock is divided by the CLKDIV value plus one to produce + the clock for the A/D converter + lsb: 8 + reset_value: '0' + width: 8 + - BURST: + access: rw + description: Controls Burst mode + lsb: 16 + reset_value: '0' + width: 1 + - CLKS: + access: rw + description: This field selects the number of clocks used for each conversion + in Burst mode and the number of bits of accuracy of the result in the LS + bits of ADDR, between 11 clocks (10 bits) and 4 clocks (3 bits). + lsb: 17 + reset_value: '0' + width: 3 + - PDN: + access: rw + description: Power mode + lsb: 21 + reset_value: '0' + width: 1 + - START: + access: rw + description: Controls the start of an A/D conversion when the BURST bit is + 0 + lsb: 24 + reset_value: '0' + width: 3 + - EDGE: + access: rw + description: Controls rising or falling edge on the selected signal for the + start of a conversion + lsb: 27 + reset_value: '0' + width: 1 +- ADC1_CR: + fields: !!omap + - SEL: + access: rw + description: Selects which of the ADCn_[7:0] inputs are to be sampled and + converted + lsb: 0 + reset_value: '0' + width: 8 + - CLKDIV: + access: rw + description: The ADC clock is divided by the CLKDIV value plus one to produce + the clock for the A/D converter + lsb: 8 + reset_value: '0' + width: 8 + - BURST: + access: rw + description: Controls Burst mode + lsb: 16 + reset_value: '0' + width: 1 + - CLKS: + access: rw + description: This field selects the number of clocks used for each conversion + in Burst mode and the number of bits of accuracy of the result in the LS + bits of ADDR, between 11 clocks (10 bits) and 4 clocks (3 bits). + lsb: 17 + reset_value: '0' + width: 3 + - PDN: + access: rw + description: Power mode + lsb: 21 + reset_value: '0' + width: 1 + - START: + access: rw + description: Controls the start of an A/D conversion when the BURST bit is + 0 + lsb: 24 + reset_value: '0' + width: 3 + - EDGE: + access: rw + description: Controls rising or falling edge on the selected signal for the + start of a conversion + lsb: 27 + reset_value: '0' + width: 1 +- ADC0_GDR: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADCn pin selected by the SEL field, divided by the reference + voltage on the VDDA pin + lsb: 6 + reset_value: '0' + width: 10 + - CHN: + access: r + description: These bits contain the channel from which the LS bits were converted + lsb: 24 + reset_value: '0' + width: 3 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an analog-to-digital conversion completes. + It is cleared when this register is read and when the AD0/1CR register is + written + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_GDR: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADCn pin selected by the SEL field, divided by the reference + voltage on the VDDA pin + lsb: 6 + reset_value: '0' + width: 10 + - CHN: + access: r + description: These bits contain the channel from which the LS bits were converted + lsb: 24 + reset_value: '0' + width: 3 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an analog-to-digital conversion completes. + It is cleared when this register is read and when the AD0/1CR register is + written + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_INTEN: + fields: !!omap + - ADINTEN: + access: rw + description: These bits allow control over which A/D channels generate interrupts + for conversion completion + lsb: 0 + reset_value: '0' + width: 8 + - ADGINTEN: + access: rw + description: When 1, enables the global DONE flag in ADDR to generate an interrupt. + When 0, only the individual A/D channels enabled by ADINTEN 7:0 will generate + interrupts. + lsb: 8 + reset_value: '1' + width: 1 +- ADC1_INTEN: + fields: !!omap + - ADINTEN: + access: rw + description: These bits allow control over which A/D channels generate interrupts + for conversion completion + lsb: 0 + reset_value: '0' + width: 8 + - ADGINTEN: + access: rw + description: When 1, enables the global DONE flag in ADDR to generate an interrupt. + When 0, only the individual A/D channels enabled by ADINTEN 7:0 will generate + interrupts. + lsb: 8 + reset_value: '1' + width: 1 +- ADC0_DR0: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC0 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR0: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC0 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_DR1: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC1 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR1: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC1 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_DR2: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC2 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR2: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC2 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_DR3: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC3 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR3: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC3 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_DR4: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC4 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR4: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC4 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_DR5: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC5 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR5: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC5 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_DR6: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC6 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR6: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC6 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_DR7: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC7 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC1_DR7: + fields: !!omap + - V_VREF: + access: r + description: When DONE is 1, this field contains a binary fraction representing + the voltage on the ADC7 pin divided by the reference voltage on the VDDA + pin + lsb: 6 + reset_value: '0' + width: 10 + - OVERRUN: + access: r + description: This bit is 1 in burst mode if the results of one or more conversions + was (were) lost and overwritten before the conversion that produced the + result in the V_VREF bits in this register. + lsb: 30 + reset_value: '0' + width: 1 + - DONE: + access: r + description: This bit is set to 1 when an A/D conversion completes. + lsb: 31 + reset_value: '0' + width: 1 +- ADC0_STAT: + fields: !!omap + - DONE: + access: r + description: These bits mirror the DONE status flags that appear in the result + register for each A/D channel. + lsb: 0 + reset_value: '0' + width: 8 + - OVERRUN: + access: r + description: These bits mirror the OVERRRUN status flags that appear in the + result register for each A/D channel. + lsb: 8 + reset_value: '0' + width: 8 + - ADINT: + access: r + description: This bit is the A/D interrupt flag. It is one when any of the + individual A/D channel Done flags is asserted and enabled to contribute + to the A/D interrupt via the ADINTEN register. + lsb: 16 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/atimer.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/atimer.yaml new file mode 100644 index 00000000..010a25db --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/atimer.yaml @@ -0,0 +1,71 @@ +!!omap +- ATIMER_DOWNCOUNTER: + fields: !!omap + - CVAL: + access: rw + description: When equal to zero an interrupt is raised + lsb: 0 + reset_value: '0' + width: 16 +- ATIMER_PRESET: + fields: !!omap + - PRESETVAL: + access: rw + description: Value loaded in DOWNCOUNTER when DOWNCOUNTER equals zero + lsb: 0 + reset_value: '0' + width: 16 +- ATIMER_CLR_EN: + fields: !!omap + - CLR_EN: + access: w + description: Writing a 1 to this bit clears the interrupt enable bit in the + ENABLE register + lsb: 0 + reset_value: '0' + width: 1 +- ATIMER_SET_EN: + fields: !!omap + - SET_EN: + access: w + description: Writing a 1 to this bit sets the interrupt enable bit in the + ENABLE register + lsb: 0 + reset_value: '0' + width: 1 +- ATIMER_STATUS: + fields: !!omap + - STAT: + access: r + description: A 1 in this bit shows that the STATUS interrupt has been raised + lsb: 0 + reset_value: '0' + width: 1 +- ATIMER_ENABLE: + fields: !!omap + - ENA: + access: r + description: A 1 in this bit shows that the STATUS interrupt has been enabled + and that the STATUS interrupt request signal is asserted when STAT = 1 in + the STATUS register + lsb: 0 + reset_value: '0' + width: 1 +- ATIMER_CLR_STAT: + fields: !!omap + - CSTAT: + access: w + description: Writing a 1 to this bit clears the STATUS interrupt bit in the + STATUS register + lsb: 0 + reset_value: '0' + width: 1 +- ATIMER_SET_STAT: + fields: !!omap + - SSTAT: + access: w + description: Writing a 1 to this bit sets the STATUS interrupt bit in the + STATUS register + lsb: 0 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ccu.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ccu.yaml new file mode 100644 index 00000000..b2d225fe --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ccu.yaml @@ -0,0 +1,2391 @@ +!!omap +- CCU1_PM: + fields: !!omap + - PD: + access: rw + description: Initiate power-down mode + lsb: 0 + reset_value: '0' + width: 1 +- CCU1_BASE_STAT: + fields: !!omap + - BASE_APB3_CLK_IND: + access: r + description: Base clock indicator for BASE_APB3_CLK + lsb: 0 + reset_value: '1' + width: 1 + - BASE_APB1_CLK_IND: + access: r + description: Base clock indicator for BASE_APB1_CLK + lsb: 1 + reset_value: '1' + width: 1 + - BASE_SPIFI_CLK_IND: + access: r + description: Base clock indicator for BASE_SPIFI_CLK + lsb: 2 + reset_value: '1' + width: 1 + - BASE_M4_CLK_IND: + access: r + description: Base clock indicator for BASE_M4_CLK + lsb: 3 + reset_value: '1' + width: 1 + - BASE_PERIPH_CLK_IND: + access: r + description: Base clock indicator for BASE_PERIPH_CLK + lsb: 6 + reset_value: '1' + width: 1 + - BASE_USB0_CLK_IND: + access: r + description: Base clock indicator for BASE_USB0_CLK + lsb: 7 + reset_value: '1' + width: 1 + - BASE_USB1_CLK_IND: + access: r + description: Base clock indicator for BASE_USB1_CLK + lsb: 8 + reset_value: '1' + width: 1 + - BASE_SPI_CLK_IND: + access: r + description: Base clock indicator for BASE_SPI_CLK + lsb: 9 + reset_value: '1' + width: 1 +- CCU1_CLK_APB3_BUS_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_BUS_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_I2C1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_I2C1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_DAC_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_DAC_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_ADC0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_ADC0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_ADC1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_ADC1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_CAN0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB3_CAN0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_BUS_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_BUS_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_MOTOCONPWM_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_MOTOCONPWM_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_I2C0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_I2C0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_I2S_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_I2S_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_CAN1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_APB1_CAN1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_SPIFI_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_SPIFI_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_BUS_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_BUS_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SPIFI_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SPIFI_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_GPIO_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_GPIO_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_LCD_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_LCD_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_ETHERNET_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_ETHERNET_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USB0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USB0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_EMC_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_EMC_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SDIO_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SDIO_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_DMA_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_DMA_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_M4CORE_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_M4CORE_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SCT_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SCT_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USB1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USB1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_EMCDIV_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 + - DIV: + access: rw + description: Clock divider value + lsb: 5 + reset_value: '0' + width: 3 +- CCU1_CLK_M4_EMCDIV_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_M0APP_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_M0APP_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_VADC_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_VADC_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_WWDT_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_WWDT_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USART0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USART0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_UART1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_UART1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SSP0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SSP0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SCU_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SCU_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_CREG_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_CREG_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_RITIMER_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_RITIMER_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USART2_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USART2_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USART3_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_USART3_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER2_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER2_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER3_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_TIMER3_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SSP1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_SSP1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_QEI_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_M4_QEI_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_PERIPH_BUS_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_PERIPH_BUS_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_PERIPH_CORE_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_PERIPH_CORE_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_PERIPH_SGPIO_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_PERIPH_SGPIO_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_USB0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_USB0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_USB1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_USB1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_SPI_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_SPI_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_VADC_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU1_CLK_VADC_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_PM: + fields: !!omap + - PD: + access: rw + description: Initiate power-down mode + lsb: 0 + reset_value: '0' + width: 1 +- CCU2_BASE_STAT: + fields: !!omap + - BASE_UART3_CLK_IND: + access: r + description: Base clock indicator for BASE_UART3_CLK + lsb: 1 + reset_value: '1' + width: 1 + - BASE_UART2_CLK_IND: + access: r + description: Base clock indicator for BASE_UART2_CLK + lsb: 2 + reset_value: '1' + width: 1 + - BASE_UART1_CLK_IND: + access: r + description: Base clock indicator for BASE_UART1_CLK + lsb: 3 + reset_value: '1' + width: 1 + - BASE_UART0_CLK_IND: + access: r + description: Base clock indicator for BASE_UART0_CLK + lsb: 4 + reset_value: '1' + width: 1 + - BASE_SSP1_CLK_IND: + access: r + description: Base clock indicator for BASE_SSP1_CLK + lsb: 5 + reset_value: '1' + width: 1 + - BASE_SSP0_CLK_IND: + access: r + description: Base clock indicator for BASE_SSP0_CLK + lsb: 6 + reset_value: '1' + width: 1 +- CCU2_CLK_APLL_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APLL_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB2_USART3_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB2_USART3_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB2_USART2_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB2_USART2_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB0_UART1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB0_UART1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB0_USART0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB0_USART0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB2_SSP1_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB2_SSP1_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB0_SSP0_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_APB0_SSP0_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_SDIO_CFG: + fields: !!omap + - RUN: + access: rw + description: Run enable + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: rw + description: Auto (AHB disable mechanism) enable + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: rw + description: Wake-up mechanism enable + lsb: 2 + reset_value: '0' + width: 1 +- CCU2_CLK_SDIO_STAT: + fields: !!omap + - RUN: + access: r + description: Run enable status + lsb: 0 + reset_value: '1' + width: 1 + - AUTO: + access: r + description: Auto (AHB disable mechanism) enable status + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP: + access: r + description: Wake-up mechanism enable status + lsb: 2 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/cgu.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/cgu.yaml new file mode 100644 index 00000000..f55b8d0f --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/cgu.yaml @@ -0,0 +1,937 @@ +!!omap +- CGU_FREQ_MON: + fields: !!omap + - RCNT: + access: rw + description: 9-bit reference clock-counter value + lsb: 0 + reset_value: '0' + width: 9 + - FCNT: + access: r + description: 14-bit selected clock-counter value + lsb: 9 + reset_value: '0' + width: 14 + - MEAS: + access: rw + description: Measure frequency + lsb: 23 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock-source selection for the clock to be measured + lsb: 24 + reset_value: '0' + width: 5 +- CGU_XTAL_OSC_CTRL: + fields: !!omap + - ENABLE: + access: rw + description: Oscillator-pad enable + lsb: 0 + reset_value: '1' + width: 1 + - BYPASS: + access: rw + description: Configure crystal operation or external-clock input pin XTAL1 + lsb: 1 + reset_value: '0' + width: 1 + - HF: + access: rw + description: Select frequency range + lsb: 2 + reset_value: '1' + width: 1 +- CGU_PLL0USB_STAT: + fields: !!omap + - LOCK: + access: r + description: PLL0 lock indicator + lsb: 0 + reset_value: '0' + width: 1 + - FR: + access: r + description: PLL0 free running indicator + lsb: 1 + reset_value: '0' + width: 1 +- CGU_PLL0USB_CTRL: + fields: !!omap + - PD: + access: rw + description: PLL0 power down + lsb: 0 + reset_value: '1' + width: 1 + - BYPASS: + access: rw + description: Input clock bypass control + lsb: 1 + reset_value: '1' + width: 1 + - DIRECTI: + access: rw + description: PLL0 direct input + lsb: 2 + reset_value: '0' + width: 1 + - DIRECTO: + access: rw + description: PLL0 direct output + lsb: 3 + reset_value: '0' + width: 1 + - CLKEN: + access: rw + description: PLL0 clock enable + lsb: 4 + reset_value: '0' + width: 1 + - FRM: + access: rw + description: Free running mode + lsb: 6 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_PLL0USB_MDIV: + fields: !!omap + - MDEC: + access: rw + description: Decoded M-divider coefficient value + lsb: 0 + reset_value: '0x5B6A' + width: 17 + - SELP: + access: rw + description: Bandwidth select P value + lsb: 17 + reset_value: '0x1C' + width: 5 + - SELI: + access: rw + description: Bandwidth select I value + lsb: 22 + reset_value: '0x17' + width: 6 + - SELR: + access: rw + description: Bandwidth select R value + lsb: 28 + reset_value: '0x0' + width: 4 +- CGU_PLL0USB_NP_DIV: + fields: !!omap + - PDEC: + access: rw + description: Decoded P-divider coefficient value + lsb: 0 + reset_value: '0x02' + width: 7 + - NDEC: + access: rw + description: Decoded N-divider coefficient value + lsb: 12 + reset_value: '0xB1' + width: 10 +- CGU_PLL0AUDIO_STAT: + fields: !!omap + - LOCK: + access: r + description: PLL0 lock indicator + lsb: 0 + reset_value: '0' + width: 1 + - FR: + access: r + description: PLL0 free running indicator + lsb: 1 + reset_value: '0' + width: 1 +- CGU_PLL0AUDIO_CTRL: + fields: !!omap + - PD: + access: rw + description: PLL0 power down + lsb: 0 + reset_value: '1' + width: 1 + - BYPASS: + access: rw + description: Input clock bypass control + lsb: 1 + reset_value: '1' + width: 1 + - DIRECTI: + access: rw + description: PLL0 direct input + lsb: 2 + reset_value: '0' + width: 1 + - DIRECTO: + access: rw + description: PLL0 direct output + lsb: 3 + reset_value: '0' + width: 1 + - CLKEN: + access: rw + description: PLL0 clock enable + lsb: 4 + reset_value: '0' + width: 1 + - FRM: + access: rw + description: Free running mode + lsb: 6 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - PLLFRACT_REQ: + access: rw + description: Fractional PLL word write request + lsb: 12 + reset_value: '0' + width: 1 + - SEL_EXT: + access: rw + description: Select fractional divider + lsb: 13 + reset_value: '0' + width: 1 + - MOD_PD: + access: rw + description: Sigma-Delta modulator power-down + lsb: 14 + reset_value: '1' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_PLL0AUDIO_MDIV: + fields: !!omap + - MDEC: + access: rw + description: Decoded M-divider coefficient value + lsb: 0 + reset_value: '0x5B6A' + width: 17 +- CGU_PLL0AUDIO_NP_DIV: + fields: !!omap + - PDEC: + access: rw + description: Decoded P-divider coefficient value + lsb: 0 + reset_value: '0x02' + width: 7 + - NDEC: + access: rw + description: Decoded N-divider coefficient value + lsb: 12 + reset_value: '0xB1' + width: 10 +- CGU_PLLAUDIO_FRAC: + fields: !!omap + - PLLFRACT_CTRL: + access: rw + description: PLL fractional divider control word + lsb: 0 + reset_value: '0x00' + width: 22 +- CGU_PLL1_STAT: + fields: !!omap + - LOCK: + access: r + description: PLL1 lock indicator + lsb: 0 + reset_value: '0' + width: 1 +- CGU_PLL1_CTRL: + fields: !!omap + - PD: + access: rw + description: PLL1 power down + lsb: 0 + reset_value: '1' + width: 1 + - BYPASS: + access: rw + description: Input clock bypass control + lsb: 1 + reset_value: '1' + width: 1 + - FBSEL: + access: rw + description: PLL feedback select + lsb: 6 + reset_value: '0' + width: 1 + - DIRECT: + access: rw + description: PLL direct CCO output + lsb: 7 + reset_value: '0' + width: 1 + - PSEL: + access: rw + description: Post-divider division ratio P + lsb: 8 + reset_value: '0x1' + width: 2 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - NSEL: + access: rw + description: Pre-divider division ratio N + lsb: 12 + reset_value: '0x2' + width: 2 + - MSEL: + access: rw + description: Feedback-divider division ratio (M) + lsb: 16 + reset_value: '0x18' + width: 8 + - CLK_SEL: + access: rw + description: Clock-source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_IDIVA_CTRL: + fields: !!omap + - PD: + access: rw + description: Integer divider power down + lsb: 0 + reset_value: '0' + width: 1 + - IDIV: + access: rw + description: Integer divider A divider value (1/(IDIV + 1)) + lsb: 2 + reset_value: '0x0' + width: 2 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_IDIVB_CTRL: + fields: !!omap + - PD: + access: rw + description: Integer divider power down + lsb: 0 + reset_value: '0' + width: 1 + - IDIV: + access: rw + description: Integer divider B divider value (1/(IDIV + 1)) + lsb: 2 + reset_value: '0x0' + width: 4 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_IDIVC_CTRL: + fields: !!omap + - PD: + access: rw + description: Integer divider power down + lsb: 0 + reset_value: '0' + width: 1 + - IDIV: + access: rw + description: Integer divider C divider value (1/(IDIV + 1)) + lsb: 2 + reset_value: '0x0' + width: 4 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_IDIVD_CTRL: + fields: !!omap + - PD: + access: rw + description: Integer divider power down + lsb: 0 + reset_value: '0' + width: 1 + - IDIV: + access: rw + description: Integer divider D divider value (1/(IDIV + 1)) + lsb: 2 + reset_value: '0x0' + width: 4 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_IDIVE_CTRL: + fields: !!omap + - PD: + access: rw + description: Integer divider power down + lsb: 0 + reset_value: '0' + width: 1 + - IDIV: + access: rw + description: Integer divider E divider value (1/(IDIV + 1)) + lsb: 2 + reset_value: '0x00' + width: 8 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_SAFE_CLK: + fields: !!omap + - PD: + access: r + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: r + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: r + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_USB0_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x07' + width: 5 +- CGU_BASE_PERIPH_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_USB1_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_M4_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_SPIFI_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_SPI_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_PHY_RX_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_PHY_TX_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_APB1_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_APB3_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_LCD_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_VADC_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_SDIO_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_SSP0_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_SSP1_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_UART0_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_UART1_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_UART2_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_UART3_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_OUT_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_APLL_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_CGU_OUT0_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 +- CGU_BASE_CGU_OUT1_CLK: + fields: !!omap + - PD: + access: rw + description: Output stage power down + lsb: 0 + reset_value: '0' + width: 1 + - AUTOBLOCK: + access: rw + description: Block clock automatically during frequency change + lsb: 11 + reset_value: '0' + width: 1 + - CLK_SEL: + access: rw + description: Clock source selection + lsb: 24 + reset_value: '0x01' + width: 5 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/creg.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/creg.yaml new file mode 100644 index 00000000..3fb8ab78 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/creg.yaml @@ -0,0 +1,312 @@ +!!omap +- CREG_CREG0: + fields: !!omap + - EN1KHZ: + access: rw + description: Enable 1 kHz output + lsb: 0 + reset_value: '0' + width: 1 + - EN32KHZ: + access: rw + description: Enable 32 kHz output + lsb: 1 + reset_value: '0' + width: 1 + - RESET32KHZ: + access: rw + description: 32 kHz oscillator reset + lsb: 2 + reset_value: '1' + width: 1 + - PD32KHZ: + access: rw + description: 32 kHz power control + lsb: 3 + reset_value: '1' + width: 1 + - USB0PHY: + access: rw + description: USB0 PHY power control + lsb: 5 + reset_value: '1' + width: 1 + - ALARMCTRL: + access: rw + description: RTC_ALARM pin output control + lsb: 6 + reset_value: '0' + width: 2 + - BODLVL1: + access: rw + description: BOD trip level to generate an interrupt + lsb: 8 + reset_value: '0x3' + width: 2 + - BODLVL2: + access: rw + description: BOD trip level to generate a reset + lsb: 10 + reset_value: '0x3' + width: 2 + - SAMPLECTRL: + access: rw + description: SAMPLE pin input/output control + lsb: 12 + reset_value: '0' + width: 2 + - WAKEUP0CTRL: + access: rw + description: WAKEUP0 pin input/output control + lsb: 14 + reset_value: '0' + width: 2 + - WAKEUP1CTRL: + access: rw + description: WAKEUP1 pin input/output control + lsb: 16 + reset_value: '0' + width: 2 +- CREG_M4MEMMAP: + fields: !!omap + - M4MAP: + access: rw + description: Shadow address when accessing memory at address 0x00000000 + lsb: 12 + reset_value: '0x10400000' + width: 20 +- CREG_CREG5: + fields: !!omap + - M4TAPSEL: + access: rw + description: JTAG debug select for M4 core + lsb: 6 + reset_value: '1' + width: 1 + - M0APPTAPSEL: + access: rw + description: JTAG debug select for M0 co-processor + lsb: 9 + reset_value: '1' + width: 1 +- CREG_DMAMUX: + fields: !!omap + - DMAMUXPER0: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 0 + lsb: 0 + reset_value: '0' + width: 2 + - DMAMUXPER1: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 1 + lsb: 2 + reset_value: '0' + width: 2 + - DMAMUXPER2: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 2 + lsb: 4 + reset_value: '0' + width: 2 + - DMAMUXPER3: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 3 + lsb: 6 + reset_value: '0' + width: 2 + - DMAMUXPER4: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 4 + lsb: 8 + reset_value: '0' + width: 2 + - DMAMUXPER5: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 5 + lsb: 10 + reset_value: '0' + width: 2 + - DMAMUXPER6: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 6 + lsb: 12 + reset_value: '0' + width: 2 + - DMAMUXPER7: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 7 + lsb: 14 + reset_value: '0' + width: 2 + - DMAMUXPER8: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 8 + lsb: 16 + reset_value: '0' + width: 2 + - DMAMUXPER9: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 9 + lsb: 18 + reset_value: '0' + width: 2 + - DMAMUXPER10: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 10 + lsb: 20 + reset_value: '0' + width: 2 + - DMAMUXPER11: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 11 + lsb: 22 + reset_value: '0' + width: 2 + - DMAMUXPER12: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 12 + lsb: 24 + reset_value: '0' + width: 2 + - DMAMUXPER13: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 13 + lsb: 26 + reset_value: '0' + width: 2 + - DMAMUXPER14: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 14 + lsb: 28 + reset_value: '0' + width: 2 + - DMAMUXPER15: + access: rw + description: Select DMA to peripheral connection for DMA peripheral 15 + lsb: 30 + reset_value: '0' + width: 2 +- CREG_FLASHCFGA: + fields: !!omap + - FLASHTIM: + access: rw + description: Flash access time. The value of this field plus 1 gives the number + of BASE_M4_CLK clocks used for a flash access + lsb: 12 + reset_value: '' + width: 4 + - POW: + access: rw + description: Flash bank A power control + lsb: 31 + reset_value: '1' + width: 1 +- CREG_FLASHCFGB: + fields: !!omap + - FLASHTIM: + access: rw + description: Flash access time. The value of this field plus 1 gives the number + of BASE_M4_CLK clocks used for a flash access + lsb: 12 + reset_value: '' + width: 4 + - POW: + access: rw + description: Flash bank B power control + lsb: 31 + reset_value: '1' + width: 1 +- CREG_ETBCFG: + fields: !!omap + - ETB: + access: rw + description: Select SRAM interface + lsb: 0 + reset_value: '1' + width: 1 +- CREG_CREG6: + fields: !!omap + - ETHMODE: + access: rw + description: Selects the Ethernet mode. Reset the ethernet after changing + the PHY interface + lsb: 0 + reset_value: '' + width: 3 + - CTOUTCTRL: + access: rw + description: Selects the functionality of the SCT outputs + lsb: 4 + reset_value: '0' + width: 1 + - I2S0_TX_SCK_IN_SEL: + access: rw + description: I2S0_TX_SCK input select + lsb: 12 + reset_value: '0' + width: 1 + - I2S0_RX_SCK_IN_SEL: + access: rw + description: I2S0_RX_SCK input select + lsb: 13 + reset_value: '0' + width: 1 + - I2S1_TX_SCK_IN_SEL: + access: rw + description: I2S1_TX_SCK input select + lsb: 14 + reset_value: '0' + width: 1 + - I2S1_RX_SCK_IN_SEL: + access: rw + description: I2S1_RX_SCK input select + lsb: 15 + reset_value: '0' + width: 1 + - EMC_CLK_SEL: + access: rw + description: EMC_CLK divided clock select + lsb: 16 + reset_value: '0' + width: 1 +- CREG_M4TXEVENT: + fields: !!omap + - TXEVCLR: + access: rw + description: Cortex-M4 TXEV event + lsb: 0 + reset_value: '0' + width: 1 +- CREG_M0TXEVENT: + fields: !!omap + - TXEVCLR: + access: rw + description: Cortex-M0 TXEV event + lsb: 0 + reset_value: '0' + width: 1 +- CREG_M0APPMEMMAP: + fields: !!omap + - M0APPMAP: + access: rw + description: Shadow address when accessing memory at address 0x00000000 + lsb: 12 + reset_value: '0x20000000' + width: 20 +- CREG_USB0FLADJ: + fields: !!omap + - FLTV: + access: rw + description: Frame length timing value + lsb: 0 + reset_value: '0x20' + width: 6 +- CREG_USB1FLADJ: + fields: !!omap + - FLTV: + access: rw + description: Frame length timing value + lsb: 0 + reset_value: '0x20' + width: 6 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/csv2yaml.py b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/csv2yaml.py new file mode 100755 index 00000000..7b2f8c6d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/csv2yaml.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +import sys +import yaml +import csv +from collections import OrderedDict + +def convert_file(fname): + reader = csv.reader(open(fname, 'r')) + + registers = OrderedDict() + for register_name, lsb, width, field_name, description, reset_value, access in reader: + if register_name not in registers: + registers[register_name] = { + 'fields': OrderedDict(), + } + + register = registers[register_name] + fields = register['fields'] + if field_name in fields: + raise RuntimeError('Duplicate field name "%s" in register "%s"' % + field_name, register_name) + else: + fields[field_name] = { + 'lsb': int(lsb), + 'width': int(width), + 'description': description, + 'reset_value': reset_value, + 'access': access, + } + + with open(fname.replace('.csv', '.yaml'), 'w') as out_file: + yaml.dump(registers, out_file, default_flow_style=False) + +for fname in sys.argv[1:]: + convert_file(fname) diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/eventrouter.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/eventrouter.yaml new file mode 100644 index 00000000..677b0d95 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/eventrouter.yaml @@ -0,0 +1,959 @@ +!!omap +- EVENTROUTER_HILO: + fields: !!omap + - WAKEUP0_L: + access: rw + description: Level detect mode for WAKEUP0 event + lsb: 0 + reset_value: '0' + width: 1 + - WAKEUP1_L: + access: rw + description: Level detect mode for WAKEUP1 event + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP2_L: + access: rw + description: Level detect mode for WAKEUP2 event + lsb: 2 + reset_value: '0' + width: 1 + - WAKEUP3_L: + access: rw + description: Level detect mode for WAKEUP3 event + lsb: 3 + reset_value: '0' + width: 1 + - ATIMER_L: + access: rw + description: Level detect mode for alarm timer event + lsb: 4 + reset_value: '0' + width: 1 + - RTC_L: + access: rw + description: Level detect mode for RTC event + lsb: 5 + reset_value: '0' + width: 1 + - BOD_L: + access: rw + description: Level detect mode for BOD event + lsb: 6 + reset_value: '0' + width: 1 + - WWDT_L: + access: rw + description: Level detect mode for WWDT event + lsb: 7 + reset_value: '0' + width: 1 + - ETH_L: + access: rw + description: Level detect mode for Ethernet event + lsb: 8 + reset_value: '0' + width: 1 + - USB0_L: + access: rw + description: Level detect mode for USB0 event + lsb: 9 + reset_value: '0' + width: 1 + - USB1_L: + access: rw + description: Level detect mode for USB1 event + lsb: 10 + reset_value: '0' + width: 1 + - SDMMC_L: + access: rw + description: Level detect mode for SD/MMC event + lsb: 11 + reset_value: '0' + width: 1 + - CAN_L: + access: rw + description: Level detect mode for C_CAN event + lsb: 12 + reset_value: '0' + width: 1 + - TIM2_L: + access: rw + description: Level detect mode for combined timer output 2 event + lsb: 13 + reset_value: '0' + width: 1 + - TIM6_L: + access: rw + description: Level detect mode for combined timer output 6 event + lsb: 14 + reset_value: '0' + width: 1 + - QEI_L: + access: rw + description: Level detect mode for QEI event + lsb: 15 + reset_value: '0' + width: 1 + - TIM14_L: + access: rw + description: Level detect mode for combined timer output 14 event + lsb: 16 + reset_value: '0' + width: 1 + - RESET_L: + access: rw + description: Level detect mode for Reset + lsb: 19 + reset_value: '0' + width: 1 +- EVENTROUTER_EDGE: + fields: !!omap + - WAKEUP0_E: + access: rw + description: Edge/Level detect mode for WAKEUP0 event + lsb: 0 + reset_value: '0' + width: 1 + - WAKEUP1_E: + access: rw + description: Edge/Level detect mode for WAKEUP1 event + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP2_E: + access: rw + description: Edge/Level detect mode for WAKEUP2 event + lsb: 2 + reset_value: '0' + width: 1 + - WAKEUP3_E: + access: rw + description: Edge/Level detect mode for WAKEUP3 event + lsb: 3 + reset_value: '0' + width: 1 + - ATIMER_E: + access: rw + description: Edge/Level detect mode for alarm timer event + lsb: 4 + reset_value: '0' + width: 1 + - RTC_E: + access: rw + description: Edge/Level detect mode for RTC event + lsb: 5 + reset_value: '0' + width: 1 + - BOD_E: + access: rw + description: Edge/Level detect mode for BOD event + lsb: 6 + reset_value: '0' + width: 1 + - WWDT_E: + access: rw + description: Edge/Level detect mode for WWDT event + lsb: 7 + reset_value: '0' + width: 1 + - ETH_E: + access: rw + description: Edge/Level detect mode for Ethernet event + lsb: 8 + reset_value: '0' + width: 1 + - USB0_E: + access: rw + description: Edge/Level detect mode for USB0 event + lsb: 9 + reset_value: '0' + width: 1 + - USB1_E: + access: rw + description: Edge/Level detect mode for USB1 event + lsb: 10 + reset_value: '0' + width: 1 + - SDMMC_E: + access: rw + description: Edge/Level detect mode for SD/MMC event + lsb: 11 + reset_value: '0' + width: 1 + - CAN_E: + access: rw + description: Edge/Level detect mode for C_CAN event + lsb: 12 + reset_value: '0' + width: 1 + - TIM2_E: + access: rw + description: Edge/Level detect mode for combined timer output 2 event + lsb: 13 + reset_value: '0' + width: 1 + - TIM6_E: + access: rw + description: Edge/Level detect mode for combined timer output 6 event + lsb: 14 + reset_value: '0' + width: 1 + - QEI_E: + access: rw + description: Edge/Level detect mode for QEI event + lsb: 15 + reset_value: '0' + width: 1 + - TIM14_E: + access: rw + description: Edge/Level detect mode for combined timer output 14 event + lsb: 16 + reset_value: '0' + width: 1 + - RESET_E: + access: rw + description: Edge/Level detect mode for Reset + lsb: 19 + reset_value: '0' + width: 1 +- EVENTROUTER_CLR_EN: + fields: !!omap + - WAKEUP0_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 0 in the + ENABLE register + lsb: 0 + reset_value: '0' + width: 1 + - WAKEUP1_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 1 in the + ENABLE register + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP2_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 2 in the + ENABLE register + lsb: 2 + reset_value: '0' + width: 1 + - WAKEUP3_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 3 in the + ENABLE register + lsb: 3 + reset_value: '0' + width: 1 + - ATIMER_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 4 in the + ENABLE register + lsb: 4 + reset_value: '0' + width: 1 + - RTC_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 5 in the + ENABLE register + lsb: 5 + reset_value: '0' + width: 1 + - BOD_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 6 in the + ENABLE register + lsb: 6 + reset_value: '0' + width: 1 + - WWDT_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 7 in the + ENABLE register + lsb: 7 + reset_value: '0' + width: 1 + - ETH_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 8 in the + ENABLE register + lsb: 8 + reset_value: '0' + width: 1 + - USB0_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 9 in the + ENABLE register + lsb: 9 + reset_value: '0' + width: 1 + - USB1_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 10 in the + ENABLE register + lsb: 10 + reset_value: '0' + width: 1 + - SDMCC_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 11 in the + ENABLE register + lsb: 11 + reset_value: '0' + width: 1 + - CAN_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 12 in the + ENABLE register + lsb: 12 + reset_value: '0' + width: 1 + - TIM2_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 13 in the + ENABLE register + lsb: 13 + reset_value: '0' + width: 1 + - TIM6_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 14 in the + ENABLE register + lsb: 14 + reset_value: '0' + width: 1 + - QEI_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 15 in the + ENABLE register + lsb: 15 + reset_value: '0' + width: 1 + - TIM14_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 16 in the + ENABLE register + lsb: 16 + reset_value: '0' + width: 1 + - RESET_CLREN: + access: w + description: Writing a 1 to this bit clears the event enable bit 19 in the + ENABLE register + lsb: 19 + reset_value: '0' + width: 1 +- EVENTROUTER_SET_EN: + fields: !!omap + - WAKEUP0_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 0 in the ENABLE + register + lsb: 0 + reset_value: '0' + width: 1 + - WAKEUP1_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 1 in the ENABLE + register + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP2_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 2 in the ENABLE + register + lsb: 2 + reset_value: '0' + width: 1 + - WAKEUP3_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 3 in the ENABLE + register + lsb: 3 + reset_value: '0' + width: 1 + - ATIMER_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 4 in the ENABLE + register + lsb: 4 + reset_value: '0' + width: 1 + - RTC_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 5 in the ENABLE + register + lsb: 5 + reset_value: '0' + width: 1 + - BOD_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 6 in the ENABLE + register + lsb: 6 + reset_value: '0' + width: 1 + - WWDT_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 7 in the ENABLE + register + lsb: 7 + reset_value: '0' + width: 1 + - ETH_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 8 in the ENABLE + register + lsb: 8 + reset_value: '0' + width: 1 + - USB0_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 9 in the ENABLE + register + lsb: 9 + reset_value: '0' + width: 1 + - USB1_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 10 in the ENABLE + register + lsb: 10 + reset_value: '0' + width: 1 + - SDMCC_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 11 in the ENABLE + register + lsb: 11 + reset_value: '0' + width: 1 + - CAN_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 12 in the ENABLE + register + lsb: 12 + reset_value: '0' + width: 1 + - TIM2_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 13 in the ENABLE + register + lsb: 13 + reset_value: '0' + width: 1 + - TIM6_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 14 in the ENABLE + register + lsb: 14 + reset_value: '0' + width: 1 + - QEI_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 15 in the ENABLE + register + lsb: 15 + reset_value: '0' + width: 1 + - TIM14_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 16 in the ENABLE + register + lsb: 16 + reset_value: '0' + width: 1 + - RESET_SETEN: + access: w + description: Writing a 1 to this bit sets the event enable bit 19 in the ENABLE + register + lsb: 19 + reset_value: '0' + width: 1 +- EVENTROUTER_STATUS: + fields: !!omap + - WAKEUP0_ST: + access: r + description: A 1 in this bit shows that the WAKEUP0 event has been raised + lsb: 0 + reset_value: '1' + width: 1 + - WAKEUP1_ST: + access: r + description: A 1 in this bit shows that the WAKEUP1 event has been raised + lsb: 1 + reset_value: '1' + width: 1 + - WAKEUP2_ST: + access: r + description: A 1 in this bit shows that the WAKEUP2 event has been raised + lsb: 2 + reset_value: '1' + width: 1 + - WAKEUP3_ST: + access: r + description: A 1 in this bit shows that the WAKEUP3 event has been raised + lsb: 3 + reset_value: '1' + width: 1 + - ATIMER_ST: + access: r + description: A 1 in this bit shows that the ATIMER event has been raised + lsb: 4 + reset_value: '1' + width: 1 + - RTC_ST: + access: r + description: A 1 in this bit shows that the RTC event has been raised + lsb: 5 + reset_value: '1' + width: 1 + - BOD_ST: + access: r + description: A 1 in this bit shows that the BOD event has been raised + lsb: 6 + reset_value: '1' + width: 1 + - WWDT_ST: + access: r + description: A 1 in this bit shows that the WWDT event has been raised + lsb: 7 + reset_value: '1' + width: 1 + - ETH_ST: + access: r + description: A 1 in this bit shows that the ETH event has been raised + lsb: 8 + reset_value: '1' + width: 1 + - USB0_ST: + access: r + description: A 1 in this bit shows that the USB0 event has been raised + lsb: 9 + reset_value: '1' + width: 1 + - USB1_ST: + access: r + description: A 1 in this bit shows that the USB1 event has been raised + lsb: 10 + reset_value: '1' + width: 1 + - SDMMC_ST: + access: r + description: A 1 in this bit shows that the SDMMC event has been raised + lsb: 11 + reset_value: '1' + width: 1 + - CAN_ST: + access: r + description: A 1 in this bit shows that the CAN event has been raised + lsb: 12 + reset_value: '1' + width: 1 + - TIM2_ST: + access: r + description: A 1 in this bit shows that the combined timer 2 output event + has been raised + lsb: 13 + reset_value: '1' + width: 1 + - TIM6_ST: + access: r + description: A 1 in this bit shows that the combined timer 6 output event + has been raised + lsb: 14 + reset_value: '1' + width: 1 + - QEI_ST: + access: r + description: A 1 in this bit shows that the QEI event has been raised + lsb: 15 + reset_value: '1' + width: 1 + - TIM14_ST: + access: r + description: A 1 in this bit shows that the combined timer 14 output event + has been raised + lsb: 16 + reset_value: '1' + width: 1 + - RESET_ST: + access: r + description: A 1 in this bit shows that the reset event has been raised + lsb: 19 + reset_value: '1' + width: 1 +- EVENTROUTER_ENABLE: + fields: !!omap + - WAKEUP0_EN: + access: r + description: A 1 in this bit shows that the WAKEUP0 event has been enabled + lsb: 0 + reset_value: '0' + width: 1 + - WAKEUP1_EN: + access: r + description: A 1 in this bit shows that the WAKEUP1 event has been enabled + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP2_EN: + access: r + description: A 1 in this bit shows that the WAKEUP2 event has been enabled + lsb: 2 + reset_value: '0' + width: 1 + - WAKEUP3_EN: + access: r + description: A 1 in this bit shows that the WAKEUP3 event has been enabled + lsb: 3 + reset_value: '0' + width: 1 + - ATIMER_EN: + access: r + description: A 1 in this bit shows that the ATIMER event has been enabled + lsb: 4 + reset_value: '0' + width: 1 + - RTC_EN: + access: r + description: A 1 in this bit shows that the RTC event has been enabled + lsb: 5 + reset_value: '0' + width: 1 + - BOD_EN: + access: r + description: A 1 in this bit shows that the BOD event has been enabled + lsb: 6 + reset_value: '0' + width: 1 + - WWDT_EN: + access: r + description: A 1 in this bit shows that the WWDT event has been enabled + lsb: 7 + reset_value: '0' + width: 1 + - ETH_EN: + access: r + description: A 1 in this bit shows that the ETH event has been enabled + lsb: 8 + reset_value: '0' + width: 1 + - USB0_EN: + access: r + description: A 1 in this bit shows that the USB0 event has been enabled + lsb: 9 + reset_value: '0' + width: 1 + - USB1_EN: + access: r + description: A 1 in this bit shows that the USB1 event has been enabled + lsb: 10 + reset_value: '0' + width: 1 + - SDMMC_EN: + access: r + description: A 1 in this bit shows that the SDMMC event has been enabled + lsb: 11 + reset_value: '0' + width: 1 + - CAN_EN: + access: r + description: A 1 in this bit shows that the CAN event has been enabled + lsb: 12 + reset_value: '0' + width: 1 + - TIM2_EN: + access: r + description: A 1 in this bit shows that the combined timer 2 output event + has been enabled + lsb: 13 + reset_value: '0' + width: 1 + - TIM6_EN: + access: r + description: A 1 in this bit shows that the combined timer 6 output event + has been enabled + lsb: 14 + reset_value: '0' + width: 1 + - QEI_EN: + access: r + description: A 1 in this bit shows that the QEI event has been enabled + lsb: 15 + reset_value: '0' + width: 1 + - TIM14_EN: + access: r + description: A 1 in this bit shows that the combined timer 14 output event + has been enabled + lsb: 16 + reset_value: '0' + width: 1 + - RESET_EN: + access: r + description: A 1 in this bit shows that the reset event has been enabled + lsb: 19 + reset_value: '0' + width: 1 +- EVENTROUTER_CLR_STAT: + fields: !!omap + - WAKEUP0_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 0 in the + STATUS register + lsb: 0 + reset_value: '0' + width: 1 + - WAKEUP1_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 1 in the + STATUS register + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP2_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 2 in the + STATUS register + lsb: 2 + reset_value: '0' + width: 1 + - WAKEUP3_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 3 in the + STATUS register + lsb: 3 + reset_value: '0' + width: 1 + - ATIMER_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 4 in the + STATUS register + lsb: 4 + reset_value: '0' + width: 1 + - RTC_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 5 in the + STATUS register + lsb: 5 + reset_value: '0' + width: 1 + - BOD_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 6 in the + STATUS register + lsb: 6 + reset_value: '0' + width: 1 + - WWDT_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 7 in the + STATUS register + lsb: 7 + reset_value: '0' + width: 1 + - ETH_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 8 in the + STATUS register + lsb: 8 + reset_value: '0' + width: 1 + - USB0_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 9 in the + STATUS register + lsb: 9 + reset_value: '0' + width: 1 + - USB1_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 10 in the + STATUS register + lsb: 10 + reset_value: '0' + width: 1 + - SDMCC_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 11 in the + STATUS register + lsb: 11 + reset_value: '0' + width: 1 + - CAN_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 12 in the + STATUS register + lsb: 12 + reset_value: '0' + width: 1 + - TIM2_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 13 in the + STATUS register + lsb: 13 + reset_value: '0' + width: 1 + - TIM6_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 14 in the + STATUS register + lsb: 14 + reset_value: '0' + width: 1 + - QEI_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 15 in the + STATUS register + lsb: 15 + reset_value: '0' + width: 1 + - TIM14_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 16 in the + STATUS register + lsb: 16 + reset_value: '0' + width: 1 + - RESET_CLRST: + access: w + description: Writing a 1 to this bit clears the STATUS event bit 19 in the + STATUS register + lsb: 19 + reset_value: '0' + width: 1 +- EVENTROUTER_SET_STAT: + fields: !!omap + - WAKEUP0_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 0 in the STATUS + register + lsb: 0 + reset_value: '0' + width: 1 + - WAKEUP1_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 1 in the STATUS + register + lsb: 1 + reset_value: '0' + width: 1 + - WAKEUP2_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 2 in the STATUS + register + lsb: 2 + reset_value: '0' + width: 1 + - WAKEUP3_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 3 in the STATUS + register + lsb: 3 + reset_value: '0' + width: 1 + - ATIMER_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 4 in the STATUS + register + lsb: 4 + reset_value: '0' + width: 1 + - RTC_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 5 in the STATUS + register + lsb: 5 + reset_value: '0' + width: 1 + - BOD_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 6 in the STATUS + register + lsb: 6 + reset_value: '0' + width: 1 + - WWDT_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 7 in the STATUS + register + lsb: 7 + reset_value: '0' + width: 1 + - ETH_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 8 in the STATUS + register + lsb: 8 + reset_value: '0' + width: 1 + - USB0_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 9 in the STATUS + register + lsb: 9 + reset_value: '0' + width: 1 + - USB1_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 10 in the STATUS + register + lsb: 10 + reset_value: '0' + width: 1 + - SDMCC_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 11 in the STATUS + register + lsb: 11 + reset_value: '0' + width: 1 + - CAN_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 12 in the STATUS + register + lsb: 12 + reset_value: '0' + width: 1 + - TIM2_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 13 in the STATUS + register + lsb: 13 + reset_value: '0' + width: 1 + - TIM6_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 14 in the STATUS + register + lsb: 14 + reset_value: '0' + width: 1 + - QEI_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 15 in the STATUS + register + lsb: 15 + reset_value: '0' + width: 1 + - TIM14_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 16 in the STATUS + register + lsb: 16 + reset_value: '0' + width: 1 + - RESET_SETST: + access: w + description: Writing a 1 to this bit sets the STATUS event bit 19 in the STATUS + register + lsb: 19 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gen.py b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gen.py new file mode 100755 index 00000000..af253ddc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gen.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import sys +import yaml + +registers = yaml.load(open(sys.argv[1], 'r')) + +for register_name, register in registers.iteritems(): + print('/* --- %s values %s */' % (register_name, '-' * (50 - len(register_name)))) + print + fields = register['fields'] + #for field_name, field in sorted(fields.items(), lambda x, y: cmp(x[1]['lsb'], y[1]['lsb'])): + for field_name, field in fields.items(): + mask_bits = (1 << field['width']) - 1 + print('/* %s: %s */' % (field_name, field['description'])) + print('#define %s_%s_SHIFT (%d)' % ( + register_name, field_name, field['lsb'], + )) + print('#define %s_%s_MASK (0x%x << %s_%s_SHIFT)' % ( + register_name, field_name, mask_bits, register_name, field_name, + )) + print('#define %s_%s(x) ((x) << %s_%s_SHIFT)' % ( + register_name, field_name, register_name, field_name, + )) + print diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gima.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gima.yaml new file mode 100644 index 00000000..d34086dc --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gima.yaml @@ -0,0 +1,961 @@ +!!omap +- GIMA_CAP0_0_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP0_1_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP0_2_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP0_3_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP1_0_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP1_1_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP1_2_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP1_3_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP2_0_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP2_1_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP2_2_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP2_3_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP3_0_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP3_1_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP3_2_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CAP3_3_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_0_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_1_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_2_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_3_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_4_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_5_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_6_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_CTIN_7_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_VADC_TRIGGER_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_EVENTROUTER_13_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_EVENTROUTER_14_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_EVENTROUTER_16_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_ADCSTART0_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 +- GIMA_ADCSTART1_IN: + fields: !!omap + - INV: + access: rw + description: Invert input + lsb: 0 + reset_value: '0' + width: 1 + - EDGE: + access: rw + description: Enable rising edge detection + lsb: 1 + reset_value: '0' + width: 1 + - SYNCH: + access: rw + description: Enable synchronization + lsb: 2 + reset_value: '0' + width: 1 + - PULSE: + access: rw + description: Enable single pulse generation + lsb: 3 + reset_value: '0' + width: 1 + - SELECT: + access: rw + description: Select input + lsb: 4 + reset_value: '0' + width: 4 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpdma.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpdma.yaml new file mode 100644 index 00000000..b53ea85b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpdma.yaml @@ -0,0 +1,1498 @@ +!!omap +- GPDMA_INTSTAT: + fields: !!omap + - INTSTAT: + access: r + description: Status of DMA channel interrupts after masking + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_INTTCSTAT: + fields: !!omap + - INTTCSTAT: + access: r + description: Terminal count interrupt request status for DMA channels + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_INTTCCLEAR: + fields: !!omap + - INTTCCLEAR: + access: w + description: Allows clearing the Terminal count interrupt request (IntTCStat) + for DMA channels + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_INTERRSTAT: + fields: !!omap + - INTERRSTAT: + access: r + description: Interrupt error status for DMA channels + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_INTERRCLR: + fields: !!omap + - INTERRCLR: + access: w + description: Writing a 1 clears the error interrupt request (IntErrStat) for + DMA channels + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_RAWINTTCSTAT: + fields: !!omap + - RAWINTTCSTAT: + access: r + description: Status of the terminal count interrupt for DMA channels prior + to masking + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_RAWINTERRSTAT: + fields: !!omap + - RAWINTERRSTAT: + access: r + description: Status of the error interrupt for DMA channels prior to masking + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_ENBLDCHNS: + fields: !!omap + - ENABLEDCHANNELS: + access: r + description: Enable status for DMA channels + lsb: 0 + reset_value: '0x00' + width: 8 +- GPDMA_SOFTBREQ: + fields: !!omap + - SOFTBREQ: + access: rw + description: Software burst request flags for each of 16 possible sources + lsb: 0 + reset_value: '0x00' + width: 16 +- GPDMA_SOFTSREQ: + fields: !!omap + - SOFTSREQ: + access: rw + description: Software single transfer request flags for each of 16 possible + sources + lsb: 0 + reset_value: '0x00' + width: 16 +- GPDMA_SOFTLBREQ: + fields: !!omap + - SOFTLBREQ: + access: rw + description: Software last burst request flags for each of 16 possible sources + lsb: 0 + reset_value: '0x00' + width: 16 +- GPDMA_SOFTLSREQ: + fields: !!omap + - SOFTLSREQ: + access: rw + description: Software last single transfer request flags for each of 16 possible + sources + lsb: 0 + reset_value: '0x00' + width: 16 +- GPDMA_CONFIG: + fields: !!omap + - E: + access: rw + description: DMA Controller enable + lsb: 0 + reset_value: '0' + width: 1 + - M0: + access: rw + description: AHB Master 0 endianness configuration + lsb: 1 + reset_value: '0' + width: 1 + - M1: + access: rw + description: AHB Master 1 endianness configuration + lsb: 2 + reset_value: '0' + width: 1 +- GPDMA_SYNC: + fields: !!omap + - DMACSYNC: + access: rw + description: Controls the synchronization logic for DMA request signals + lsb: 0 + reset_value: '0x00' + width: 16 +- GPDMA_C0SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C1SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C2SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C3SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C4SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C5SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C6SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C7SRCADDR: + fields: !!omap + - SRCADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C0DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C1DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C2DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C3DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C4DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C5DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C6DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C7DESTADDR: + fields: !!omap + - DESTADDR: + access: rw + description: DMA source address + lsb: 0 + reset_value: '0x00000000' + width: 32 +- GPDMA_C0LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C1LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C2LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C3LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C4LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C5LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C6LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C7LLI: + fields: !!omap + - LM: + access: rw + description: AHB master select for loading the next LLI + lsb: 0 + reset_value: '0' + width: 1 + - LLI: + access: rw + description: Linked list item + lsb: 2 + reset_value: '0x00000000' + width: 30 +- GPDMA_C0CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C1CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C2CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C3CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C4CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C5CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C6CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C7CONTROL: + fields: !!omap + - TRANSFERSIZE: + access: rw + description: Transfer size in number of transfers + lsb: 0 + reset_value: '0x00' + width: 12 + - SBSIZE: + access: rw + description: Source burst size + lsb: 12 + reset_value: '0x0' + width: 3 + - DBSIZE: + access: rw + description: Destination burst size + lsb: 15 + reset_value: '0x0' + width: 3 + - SWIDTH: + access: rw + description: Source transfer width + lsb: 18 + reset_value: '0x0' + width: 3 + - DWIDTH: + access: rw + description: Destination transfer width + lsb: 21 + reset_value: '0x0' + width: 3 + - S: + access: rw + description: Source AHB master select + lsb: 24 + reset_value: '0' + width: 1 + - D: + access: rw + description: Destination AHB master select + lsb: 25 + reset_value: '0' + width: 1 + - SI: + access: rw + description: Source increment + lsb: 26 + reset_value: '0' + width: 1 + - DI: + access: rw + description: Destination increment + lsb: 27 + reset_value: '0' + width: 1 + - PROT1: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates that the access is in user mode or privileged mode + lsb: 28 + reset_value: '0' + width: 1 + - PROT2: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is bufferable or + not bufferable + lsb: 29 + reset_value: '0' + width: 1 + - PROT3: + access: rw + description: This information is provided to the peripheral during a DMA bus + access and indicates to the peripheral that the access is cacheable or not + cacheable + lsb: 30 + reset_value: '0' + width: 1 + - I: + access: rw + description: Terminal count interrupt enable bit + lsb: 31 + reset_value: '0' + width: 1 +- GPDMA_C0CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 +- GPDMA_C1CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 +- GPDMA_C2CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 +- GPDMA_C3CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 +- GPDMA_C4CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 +- GPDMA_C5CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 +- GPDMA_C6CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 +- GPDMA_C7CONFIG: + fields: !!omap + - E: + access: rw + description: Channel enable + lsb: 0 + reset_value: '0' + width: 1 + - SRCPERIPHERAL: + access: rw + description: Source peripheral + lsb: 1 + reset_value: '' + width: 5 + - DESTPERIPHERAL: + access: rw + description: Destination peripheral + lsb: 6 + reset_value: '' + width: 5 + - FLOWCNTRL: + access: rw + description: Flow control and transfer type + lsb: 11 + reset_value: '' + width: 3 + - IE: + access: rw + description: Interrupt error mask + lsb: 14 + reset_value: '' + width: 1 + - ITC: + access: rw + description: Terminal count interrupt mask + lsb: 15 + reset_value: '' + width: 1 + - L: + access: rw + description: Lock + lsb: 16 + reset_value: '' + width: 1 + - A: + access: r + description: Active + lsb: 17 + reset_value: '' + width: 1 + - H: + access: rw + description: Halt + lsb: 18 + reset_value: '' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpio.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpio.yaml new file mode 100644 index 00000000..b76e37f0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/gpio.yaml @@ -0,0 +1,4926 @@ +!!omap +- GPIO_PIN_INTERRUPT_ISEL: + fields: !!omap + - PMODE: + access: rw + description: Selects the interrupt mode for each pin interrupt + lsb: 0 + reset_value: '0' + width: 8 +- GPIO_PIN_INTERRUPT_IENR: + fields: !!omap + - ENRL: + access: rw + description: Enables the rising edge or level interrupt for each pin interrupt + lsb: 0 + reset_value: '0' + width: 8 +- GPIO_PIN_INTERRUPT_SIENR: + fields: !!omap + - SETENRL: + access: w + description: Ones written to this address set bits in the IENR, thus enabling + interrupts + lsb: 0 + reset_value: '' + width: 8 +- GPIO_PIN_INTERRUPT_CIENR: + fields: !!omap + - CENRL: + access: w + description: Ones written to this address clear bits in the IENR, thus disabling + the interrupts + lsb: 0 + reset_value: '' + width: 8 +- GPIO_PIN_INTERRUPT_IENF: + fields: !!omap + - ENAF: + access: rw + description: Enables the falling edge or configures the active level interrupt + for each pin interrupt + lsb: 0 + reset_value: '0' + width: 8 +- GPIO_PIN_INTERRUPT_SIENF: + fields: !!omap + - SETENAF: + access: w + description: Ones written to this address set bits in the IENF, thus enabling + interrupts + lsb: 0 + reset_value: '' + width: 8 +- GPIO_PIN_INTERRUPT_CIENF: + fields: !!omap + - CENAF: + access: w + description: Ones written to this address clears bits in the IENF, thus disabling + interrupts + lsb: 0 + reset_value: '' + width: 8 +- GPIO_PIN_INTERRUPT_RISE: + fields: !!omap + - RDET: + access: rw + description: Rising edge detect + lsb: 0 + reset_value: '0' + width: 8 +- GPIO_PIN_INTERRUPT_FALL: + fields: !!omap + - FDET: + access: rw + description: Falling edge detect + lsb: 0 + reset_value: '0' + width: 8 +- GPIO_PIN_INTERRUPT_IST: + fields: !!omap + - PSTAT: + access: rw + description: Pin interrupt status + lsb: 0 + reset_value: '0' + width: 8 +- GPIO_GROUP0_INTERRUPT_CTRL: + fields: !!omap + - INT: + access: rw + description: Group interrupt status + lsb: 0 + reset_value: '0' + width: 1 + - COMB: + access: rw + description: Combine enabled inputs for group interrupt + lsb: 1 + reset_value: '0' + width: 1 + - TRIG: + access: rw + description: Group interrupt trigger + lsb: 2 + reset_value: '0' + width: 1 +- GPIO_GROUP0_INTERRUPT_PORT_POL0: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 0 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_POL1: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 1 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_POL2: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 2 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_POL3: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 3 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_POL4: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 4 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_POL5: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 5 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_POL6: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 6 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_POL7: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 7 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA0: + fields: !!omap + - ENA: + access: rw + description: Enable port 0 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA1: + fields: !!omap + - ENA: + access: rw + description: Enable port 1 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA2: + fields: !!omap + - ENA: + access: rw + description: Enable port 2 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA3: + fields: !!omap + - ENA: + access: rw + description: Enable port 3 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA4: + fields: !!omap + - ENA: + access: rw + description: Enable port 4 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA5: + fields: !!omap + - ENA: + access: rw + description: Enable port 5 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA6: + fields: !!omap + - ENA: + access: rw + description: Enable port 6 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP0_INTERRUPT_PORT_ENA7: + fields: !!omap + - ENA: + access: rw + description: Enable port 7 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_CTRL: + fields: !!omap + - INT: + access: rw + description: Group interrupt status + lsb: 0 + reset_value: '0' + width: 1 + - COMB: + access: rw + description: Combine enabled inputs for group interrupt + lsb: 1 + reset_value: '0' + width: 1 + - TRIG: + access: rw + description: Group interrupt trigger + lsb: 2 + reset_value: '0' + width: 1 +- GPIO_GROUP1_INTERRUPT_PORT_POL0: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 0 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_POL1: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 1 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_POL2: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 2 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_POL3: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 3 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_POL4: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 4 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_POL5: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 5 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_POL6: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 6 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_POL7: + fields: !!omap + - POL: + access: rw + description: Configure pin polarity of port 7 pins for group interrupt + lsb: 0 + reset_value: '1' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA0: + fields: !!omap + - ENA: + access: rw + description: Enable port 0 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA1: + fields: !!omap + - ENA: + access: rw + description: Enable port 1 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA2: + fields: !!omap + - ENA: + access: rw + description: Enable port 2 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA3: + fields: !!omap + - ENA: + access: rw + description: Enable port 3 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA4: + fields: !!omap + - ENA: + access: rw + description: Enable port 4 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA5: + fields: !!omap + - ENA: + access: rw + description: Enable port 5 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA6: + fields: !!omap + - ENA: + access: rw + description: Enable port 6 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_GROUP1_INTERRUPT_PORT_ENA7: + fields: !!omap + - ENA: + access: rw + description: Enable port 7 pin for group interrupt + lsb: 0 + reset_value: '0' + width: 32 +- GPIO_B0: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B1: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B2: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B3: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B4: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B5: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B6: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B7: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B8: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B9: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B10: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B11: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B12: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B13: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B14: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B15: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B16: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B17: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B18: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B19: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B20: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B21: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B22: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B23: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B24: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B25: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B26: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B27: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B28: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B29: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B30: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B31: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B32: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B33: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B34: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B35: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B36: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B37: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B38: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B39: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B40: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B41: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B42: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B43: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B44: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B45: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B46: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B47: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B48: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B49: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B50: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B51: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B52: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B53: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B54: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B55: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B56: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B57: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B58: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B59: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B60: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B61: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B62: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B63: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B64: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B65: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B66: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B67: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B68: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B69: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B70: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B71: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B72: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B73: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B74: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B75: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B76: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B77: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B78: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B79: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B80: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B81: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B82: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B83: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B84: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B85: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B86: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B87: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B88: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B89: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B90: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B91: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B92: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B93: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B94: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B95: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B96: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B97: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B98: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B99: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B100: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B101: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B102: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B103: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B104: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B105: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B106: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B107: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B108: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B109: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B110: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B111: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B112: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B113: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B114: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B115: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B116: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B117: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B118: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B119: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B120: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B121: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B122: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B123: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B124: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B125: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B126: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B127: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B128: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B129: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B130: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B131: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B132: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B133: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B134: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B135: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B136: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B137: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B138: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B139: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B140: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B141: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B142: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B143: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B144: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B145: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B146: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B147: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B148: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B149: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B150: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B151: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B152: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B153: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B154: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B155: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B156: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B157: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B158: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B159: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B160: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B161: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B162: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B163: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B164: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B165: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B166: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B167: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B168: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B169: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B170: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B171: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B172: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B173: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B174: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B175: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B176: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B177: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B178: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B179: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B180: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B181: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B182: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B183: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B184: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B185: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B186: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B187: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B188: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B189: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B190: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B191: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B192: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B193: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B194: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B195: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B196: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B197: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B198: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B199: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B200: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B201: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B202: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B203: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B204: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B205: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B206: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B207: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B208: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B209: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B210: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B211: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B212: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B213: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B214: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B215: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B216: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B217: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B218: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B219: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B220: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B221: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B222: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B223: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B224: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B225: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B226: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B227: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B228: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B229: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B230: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B231: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B232: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B233: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B234: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B235: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B236: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B237: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B238: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B239: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B240: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B241: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B242: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B243: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B244: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B245: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B246: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B247: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B248: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B249: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B250: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B251: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B252: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B253: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B254: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_B255: + fields: !!omap + - PBYTE: + access: rw + description: GPIO port byte pin register + lsb: 0 + reset_value: '' + width: 1 +- GPIO_W0: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W1: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W2: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W3: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W4: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W5: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W6: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W7: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W8: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W9: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W10: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W11: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W12: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W13: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W14: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W15: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W16: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W17: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W18: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W19: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W20: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W21: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W22: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W23: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W24: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W25: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W26: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W27: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W28: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W29: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W30: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W31: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W32: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W33: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W34: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W35: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W36: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W37: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W38: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W39: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W40: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W41: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W42: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W43: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W44: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W45: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W46: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W47: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W48: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W49: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W50: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W51: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W52: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W53: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W54: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W55: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W56: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W57: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W58: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W59: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W60: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W61: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W62: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W63: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W64: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W65: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W66: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W67: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W68: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W69: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W70: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W71: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W72: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W73: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W74: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W75: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W76: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W77: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W78: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W79: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W80: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W81: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W82: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W83: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W84: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W85: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W86: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W87: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W88: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W89: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W90: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W91: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W92: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W93: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W94: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W95: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W96: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W97: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W98: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W99: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W100: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W101: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W102: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W103: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W104: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W105: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W106: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W107: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W108: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W109: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W110: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W111: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W112: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W113: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W114: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W115: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W116: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W117: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W118: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W119: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W120: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W121: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W122: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W123: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W124: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W125: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W126: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W127: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W128: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W129: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W130: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W131: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W132: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W133: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W134: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W135: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W136: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W137: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W138: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W139: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W140: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W141: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W142: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W143: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W144: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W145: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W146: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W147: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W148: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W149: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W150: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W151: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W152: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W153: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W154: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W155: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W156: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W157: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W158: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W159: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W160: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W161: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W162: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W163: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W164: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W165: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W166: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W167: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W168: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W169: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W170: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W171: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W172: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W173: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W174: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W175: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W176: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W177: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W178: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W179: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W180: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W181: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W182: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W183: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W184: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W185: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W186: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W187: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W188: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W189: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W190: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W191: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W192: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W193: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W194: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W195: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W196: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W197: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W198: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W199: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W200: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W201: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W202: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W203: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W204: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W205: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W206: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W207: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W208: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W209: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W210: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W211: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W212: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W213: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W214: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W215: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W216: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W217: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W218: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W219: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W220: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W221: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W222: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W223: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W224: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W225: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W226: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W227: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W228: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W229: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W230: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W231: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W232: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W233: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W234: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W235: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W236: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W237: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W238: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W239: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W240: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W241: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W242: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W243: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W244: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W245: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W246: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W247: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W248: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W249: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W250: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W251: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W252: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W253: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W254: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO_W255: + fields: !!omap + - PWORD: + access: rw + description: GPIO port word pin register + lsb: 0 + reset_value: '' + width: 32 +- GPIO0_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO0 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO1_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO1 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO2_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO2 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO3_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO3 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO4_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO4 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO5_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO5 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO6_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO6 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO7_DIR: + fields: !!omap + - DIR: + access: rw + description: Selects pin direction for GPIO7 + lsb: 0 + reset_value: '0' + width: 32 +- GPIO0_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO1_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO2_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO3_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO4_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO5_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO6_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO7_MASK: + fields: !!omap + - MASK: + access: rw + description: Controls which pins are active in the MPORT register + lsb: 0 + reset_value: '0' + width: 32 +- GPIO0_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO1_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO2_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO3_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO4_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO5_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO6_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO7_PIN: + fields: !!omap + - PORT: + access: rw + description: Reads pin states or loads output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO0_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO1_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO2_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO3_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO4_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO5_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO6_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO7_MPIN: + fields: !!omap + - MPORT: + access: rw + description: Masked port register + lsb: 0 + reset_value: '' + width: 32 +- GPIO0_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO1_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO2_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO3_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO4_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO5_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO6_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO7_SET: + fields: !!omap + - SET: + access: rw + description: Read or set output bits + lsb: 0 + reset_value: '0' + width: 32 +- GPIO0_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO1_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO2_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO3_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO4_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO5_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO6_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO7_CLR: + fields: !!omap + - CLR: + access: w + description: Clear output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO0_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO1_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO2_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO3_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO4_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO5_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO6_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 +- GPIO7_NOT: + fields: !!omap + - NOT: + access: w + description: Toggle output bits + lsb: 0 + reset_value: '' + width: 32 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2c.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2c.yaml new file mode 100644 index 00000000..0e59a6a5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2c.yaml @@ -0,0 +1,415 @@ +!!omap +- I2C0_CONSET: + fields: !!omap + - AA: + access: rw + description: Assert acknowledge flag + lsb: 2 + reset_value: '0' + width: 1 + - SI: + access: rw + description: I2C interrupt flag + lsb: 3 + reset_value: '0' + width: 1 + - STO: + access: rw + description: STOP flag + lsb: 4 + reset_value: '0' + width: 1 + - STA: + access: rw + description: START flag + lsb: 5 + reset_value: '0' + width: 1 + - I2EN: + access: rw + description: I2C interface enable + lsb: 6 + reset_value: '0' + width: 1 +- I2C1_CONSET: + fields: !!omap + - AA: + access: rw + description: Assert acknowledge flag + lsb: 2 + reset_value: '0' + width: 1 + - SI: + access: rw + description: I2C interrupt flag + lsb: 3 + reset_value: '0' + width: 1 + - STO: + access: rw + description: STOP flag + lsb: 4 + reset_value: '0' + width: 1 + - STA: + access: rw + description: START flag + lsb: 5 + reset_value: '0' + width: 1 + - I2EN: + access: rw + description: I2C interface enable + lsb: 6 + reset_value: '0' + width: 1 +- I2C0_STAT: + fields: !!omap + - STATUS: + access: r + description: These bits give the actual status information about the I2C interface + lsb: 3 + reset_value: '0x1f' + width: 5 +- I2C1_STAT: + fields: !!omap + - STATUS: + access: r + description: These bits give the actual status information about the I2C interface + lsb: 3 + reset_value: '0x1f' + width: 5 +- I2C0_DAT: + fields: !!omap + - DATA: + access: rw + description: This register holds data values that have been received or are + to be transmitted + lsb: 0 + reset_value: '0' + width: 8 +- I2C1_DAT: + fields: !!omap + - DATA: + access: rw + description: This register holds data values that have been received or are + to be transmitted + lsb: 0 + reset_value: '0' + width: 8 +- I2C0_ADR0: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_ADR0: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C0_SCLH: + fields: !!omap + - SCLH: + access: rw + description: Count for SCL HIGH time period selection + lsb: 0 + reset_value: '0x0004' + width: 16 +- I2C1_SCLH: + fields: !!omap + - SCLH: + access: rw + description: Count for SCL HIGH time period selection + lsb: 0 + reset_value: '0x0004' + width: 16 +- I2C0_SCLL: + fields: !!omap + - SCLL: + access: rw + description: Count for SCL LOW time period selection + lsb: 0 + reset_value: '0x0004' + width: 16 +- I2C1_SCLL: + fields: !!omap + - SCLL: + access: rw + description: Count for SCL LOW time period selection + lsb: 0 + reset_value: '0x0004' + width: 16 +- I2C0_CONCLR: + fields: !!omap + - AAC: + access: w + description: Assert acknowledge Clear bit + lsb: 2 + reset_value: '0' + width: 1 + - SIC: + access: w + description: I2C interrupt Clear bit + lsb: 3 + reset_value: '0' + width: 1 + - STAC: + access: w + description: START flag Clear bit + lsb: 5 + reset_value: '0' + width: 1 + - I2ENC: + access: w + description: I2C interface Disable bit + lsb: 6 + reset_value: '0' + width: 1 +- I2C1_CONCLR: + fields: !!omap + - AAC: + access: w + description: Assert acknowledge Clear bit + lsb: 2 + reset_value: '0' + width: 1 + - SIC: + access: w + description: I2C interrupt Clear bit + lsb: 3 + reset_value: '0' + width: 1 + - STAC: + access: w + description: START flag Clear bit + lsb: 5 + reset_value: '0' + width: 1 + - I2ENC: + access: w + description: I2C interface Disable bit + lsb: 6 + reset_value: '0' + width: 1 +- I2C0_MMCTRL: + fields: !!omap + - MM_ENA: + access: rw + description: Monitor mode enable + lsb: 0 + reset_value: '0' + width: 1 + - ENA_SCL: + access: rw + description: SCL output enable + lsb: 1 + reset_value: '0' + width: 1 + - MATCH_ALL: + access: rw + description: Select interrupt register match + lsb: 2 + reset_value: '0' + width: 1 +- I2C1_MMCTRL: + fields: !!omap + - MM_ENA: + access: rw + description: Monitor mode enable + lsb: 0 + reset_value: '0' + width: 1 + - ENA_SCL: + access: rw + description: SCL output enable + lsb: 1 + reset_value: '0' + width: 1 + - MATCH_ALL: + access: rw + description: Select interrupt register match + lsb: 2 + reset_value: '0' + width: 1 +- I2C0_ADR1: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_ADR1: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C0_ADR2: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_ADR2: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C0_ADR3: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_ADR3: + fields: !!omap + - GC: + access: rw + description: General Call enable bit + lsb: 0 + reset_value: '0' + width: 1 + - ADDRESS: + access: rw + description: The I2C device address for slave mode + lsb: 1 + reset_value: '0' + width: 7 +- I2C0_DATA_BUFFER: + fields: !!omap + - DATA: + access: r + description: This register holds contents of the 8 MSBs of the DAT shift register + lsb: 0 + reset_value: '0' + width: 8 +- I2C1_DATA_BUFFER: + fields: !!omap + - DATA: + access: r + description: This register holds contents of the 8 MSBs of the DAT shift register + lsb: 0 + reset_value: '0' + width: 8 +- I2C0_MASK0: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_MASK0: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 +- I2C0_MASK1: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_MASK1: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 +- I2C0_MASK2: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_MASK2: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 +- I2C0_MASK3: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 +- I2C1_MASK3: + fields: !!omap + - MASK: + access: rw + description: Mask bits + lsb: 1 + reset_value: '0' + width: 7 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2s.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2s.yaml new file mode 100644 index 00000000..833e5b5c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/i2s.yaml @@ -0,0 +1,619 @@ +!!omap +- I2S0_DAO: + fields: !!omap + - WORDWIDTH: + access: rw + description: Selects the number of bytes in data + lsb: 0 + reset_value: '1' + width: 2 + - MONO: + access: rw + description: When 1, data is of monaural format. When 0, the data is in stereo + format + lsb: 2 + reset_value: '0' + width: 1 + - STOP: + access: rw + description: When 1, disables accesses on FIFOs, places the transmit channel + in mute mode + lsb: 3 + reset_value: '0' + width: 1 + - RESET: + access: rw + description: When 1, asynchronously resets the transmit channel and FIFO + lsb: 4 + reset_value: '0' + width: 1 + - WS_SEL: + access: rw + description: When 0, the interface is in master mode. When 1, the interface + is in slave mode + lsb: 5 + reset_value: '1' + width: 1 + - WS_HALFPERIOD: + access: rw + description: Word select half period minus 1, i.e. WS 64clk period -> ws_halfperiod + = 31. + lsb: 6 + reset_value: '0x1f' + width: 9 + - MUTE: + access: rw + description: When 1, the transmit channel sends only zeroes + lsb: 15 + reset_value: '1' + width: 1 +- I2S1_DAO: + fields: !!omap + - WORDWIDTH: + access: rw + description: Selects the number of bytes in data + lsb: 0 + reset_value: '1' + width: 2 + - MONO: + access: rw + description: When 1, data is of monaural format. When 0, the data is in stereo + format + lsb: 2 + reset_value: '0' + width: 1 + - STOP: + access: rw + description: When 1, disables accesses on FIFOs, places the transmit channel + in mute mode + lsb: 3 + reset_value: '0' + width: 1 + - RESET: + access: rw + description: When 1, asynchronously resets the transmit channel and FIFO + lsb: 4 + reset_value: '0' + width: 1 + - WS_SEL: + access: rw + description: When 0, the interface is in master mode. When 1, the interface + is in slave mode + lsb: 5 + reset_value: '1' + width: 1 + - WS_HALFPERIOD: + access: rw + description: Word select half period minus 1, i.e. WS 64clk period -> ws_halfperiod + = 31. + lsb: 6 + reset_value: '0x1f' + width: 9 + - MUTE: + access: rw + description: When 1, the transmit channel sends only zeroes + lsb: 15 + reset_value: '1' + width: 1 +- I2S0_DAI: + fields: !!omap + - WORDWIDTH: + access: rw + description: Selects the number of bytes in data + lsb: 0 + reset_value: '1' + width: 2 + - MONO: + access: rw + description: When 1, data is of monaural format. When 0, the data is in stereo + format + lsb: 2 + reset_value: '0' + width: 1 + - STOP: + access: rw + description: When 1, disables accesses on FIFOs, places the transmit channel + in mute mode + lsb: 3 + reset_value: '0' + width: 1 + - RESET: + access: rw + description: When 1, asynchronously resets the transmit channel and FIFO + lsb: 4 + reset_value: '0' + width: 1 + - WS_SEL: + access: rw + description: When 0, the interface is in master mode. When 1, the interface + is in slave mode + lsb: 5 + reset_value: '1' + width: 1 + - WS_HALFPERIOD: + access: rw + description: Word select half period minus 1, i.e. WS 64clk period -> ws_halfperiod + = 31. + lsb: 6 + reset_value: '0x1f' + width: 9 + - MUTE: + access: rw + description: When 1, the transmit channel sends only zeroes + lsb: 15 + reset_value: '1' + width: 1 +- I2S1_DAI: + fields: !!omap + - WORDWIDTH: + access: rw + description: Selects the number of bytes in data + lsb: 0 + reset_value: '1' + width: 2 + - MONO: + access: rw + description: When 1, data is of monaural format. When 0, the data is in stereo + format + lsb: 2 + reset_value: '0' + width: 1 + - STOP: + access: rw + description: When 1, disables accesses on FIFOs, places the transmit channel + in mute mode + lsb: 3 + reset_value: '0' + width: 1 + - RESET: + access: rw + description: When 1, asynchronously resets the transmit channel and FIFO + lsb: 4 + reset_value: '0' + width: 1 + - WS_SEL: + access: rw + description: When 0, the interface is in master mode. When 1, the interface + is in slave mode + lsb: 5 + reset_value: '1' + width: 1 + - WS_HALFPERIOD: + access: rw + description: Word select half period minus 1, i.e. WS 64clk period -> ws_halfperiod + = 31. + lsb: 6 + reset_value: '0x1f' + width: 9 + - MUTE: + access: rw + description: When 1, the transmit channel sends only zeroes + lsb: 15 + reset_value: '1' + width: 1 +- I2S0_TXFIFO: + fields: !!omap + - I2STXFIFO: + access: w + description: 8 x 32-bit transmit FIFO + lsb: 0 + reset_value: '0' + width: 32 +- I2S1_TXFIFO: + fields: !!omap + - I2STXFIFO: + access: w + description: 8 x 32-bit transmit FIFO + lsb: 0 + reset_value: '0' + width: 32 +- I2S0_RXFIFO: + fields: !!omap + - I2SRXFIFO: + access: r + description: 8 x 32-bit receive FIFO + lsb: 0 + reset_value: '0' + width: 32 +- I2S1_RXFIFO: + fields: !!omap + - I2SRXFIFO: + access: r + description: 8 x 32-bit receive FIFO + lsb: 0 + reset_value: '0' + width: 32 +- I2S0_STATE: + fields: !!omap + - IRQ: + access: r + description: This bit reflects the presence of Receive Interrupt or Transmit + Interrupt + lsb: 0 + reset_value: '1' + width: 1 + - DMAREQ1: + access: r + description: This bit reflects the presence of Receive or Transmit DMA Request + 1 + lsb: 1 + reset_value: '1' + width: 1 + - DMAREQ2: + access: r + description: This bit reflects the presence of Receive or Transmit DMA Request + 2 + lsb: 2 + reset_value: '1' + width: 1 + - RX_LEVEL: + access: r + description: Reflects the current level of the Receive FIFO + lsb: 8 + reset_value: '0' + width: 4 + - TX_LEVEL: + access: r + description: Reflects the current level of the Transmit FIFO + lsb: 16 + reset_value: '0' + width: 4 +- I2S1_STATE: + fields: !!omap + - IRQ: + access: r + description: This bit reflects the presence of Receive Interrupt or Transmit + Interrupt + lsb: 0 + reset_value: '1' + width: 1 + - DMAREQ1: + access: r + description: This bit reflects the presence of Receive or Transmit DMA Request + 1 + lsb: 1 + reset_value: '1' + width: 1 + - DMAREQ2: + access: r + description: This bit reflects the presence of Receive or Transmit DMA Request + 2 + lsb: 2 + reset_value: '1' + width: 1 + - RX_LEVEL: + access: r + description: Reflects the current level of the Receive FIFO + lsb: 8 + reset_value: '0' + width: 4 + - TX_LEVEL: + access: r + description: Reflects the current level of the Transmit FIFO + lsb: 16 + reset_value: '0' + width: 4 +- I2S0_DMA1: + fields: !!omap + - RX_DMA1_ENABLE: + access: rw + description: When 1, enables DMA1 for I2S receive + lsb: 0 + reset_value: '0' + width: 1 + - TX_DMA1_ENABLE: + access: rw + description: When 1, enables DMA1 for I2S transmit + lsb: 1 + reset_value: '0' + width: 1 + - RX_DEPTH_DMA1: + access: rw + description: Set the FIFO level that triggers a receive DMA request on DMA1 + lsb: 8 + reset_value: '0' + width: 4 + - TX_DEPTH_DMA1: + access: rw + description: Set the FIFO level that triggers a transmit DMA request on DMA1 + lsb: 16 + reset_value: '0' + width: 4 +- I2S1_DMA1: + fields: !!omap + - RX_DMA1_ENABLE: + access: rw + description: When 1, enables DMA1 for I2S receive + lsb: 0 + reset_value: '0' + width: 1 + - TX_DMA1_ENABLE: + access: rw + description: When 1, enables DMA1 for I2S transmit + lsb: 1 + reset_value: '0' + width: 1 + - RX_DEPTH_DMA1: + access: rw + description: Set the FIFO level that triggers a receive DMA request on DMA1 + lsb: 8 + reset_value: '0' + width: 4 + - TX_DEPTH_DMA1: + access: rw + description: Set the FIFO level that triggers a transmit DMA request on DMA1 + lsb: 16 + reset_value: '0' + width: 4 +- I2S0_DMA2: + fields: !!omap + - RX_DMA2_ENABLE: + access: rw + description: When 1, enables DMA2 for I2S receive + lsb: 0 + reset_value: '0' + width: 1 + - TX_DMA2_ENABLE: + access: rw + description: When 1, enables DMA2 for I2S transmit + lsb: 1 + reset_value: '0' + width: 1 + - RX_DEPTH_DMA2: + access: rw + description: Set the FIFO level that triggers a receive DMA request on DMA2 + lsb: 8 + reset_value: '0' + width: 4 + - TX_DEPTH_DMA2: + access: rw + description: Set the FIFO level that triggers a transmit DMA request on DMA2 + lsb: 16 + reset_value: '0' + width: 4 +- I2S1_DMA2: + fields: !!omap + - RX_DMA2_ENABLE: + access: rw + description: When 1, enables DMA2 for I2S receive + lsb: 0 + reset_value: '0' + width: 1 + - TX_DMA2_ENABLE: + access: rw + description: When 1, enables DMA2 for I2S transmit + lsb: 1 + reset_value: '0' + width: 1 + - RX_DEPTH_DMA2: + access: rw + description: Set the FIFO level that triggers a receive DMA request on DMA2 + lsb: 8 + reset_value: '0' + width: 4 + - TX_DEPTH_DMA2: + access: rw + description: Set the FIFO level that triggers a transmit DMA request on DMA2 + lsb: 16 + reset_value: '0' + width: 4 +- I2S0_IRQ: + fields: !!omap + - RX_IRQ_ENABLE: + access: rw + description: When 1, enables I2S receive interrupt + lsb: 0 + reset_value: '0' + width: 1 + - TX_IRQ_ENABLE: + access: rw + description: When 1, enables I2S transmit interrupt + lsb: 1 + reset_value: '0' + width: 1 + - RX_DEPTH_IRQ: + access: rw + description: Set the FIFO level on which to create an irq request. + lsb: 8 + reset_value: '0' + width: 4 + - TX_DEPTH_IRQ: + access: rw + description: Set the FIFO level on which to create an irq request. + lsb: 16 + reset_value: '0' + width: 4 +- I2S1_IRQ: + fields: !!omap + - RX_IRQ_ENABLE: + access: rw + description: When 1, enables I2S receive interrupt + lsb: 0 + reset_value: '0' + width: 1 + - TX_IRQ_ENABLE: + access: rw + description: When 1, enables I2S transmit interrupt + lsb: 1 + reset_value: '0' + width: 1 + - RX_DEPTH_IRQ: + access: rw + description: Set the FIFO level on which to create an irq request. + lsb: 8 + reset_value: '0' + width: 4 + - TX_DEPTH_IRQ: + access: rw + description: Set the FIFO level on which to create an irq request. + lsb: 16 + reset_value: '0' + width: 4 +- I2S0_TXRATE: + fields: !!omap + - Y_DIVIDER: + access: rw + description: I2S transmit MCLK rate denominator + lsb: 0 + reset_value: '0' + width: 8 + - X_DIVIDER: + access: rw + description: I2S transmit MCLK rate numerator + lsb: 8 + reset_value: '0' + width: 8 +- I2S1_TXRATE: + fields: !!omap + - Y_DIVIDER: + access: rw + description: I2S transmit MCLK rate denominator + lsb: 0 + reset_value: '0' + width: 8 + - X_DIVIDER: + access: rw + description: I2S transmit MCLK rate numerator + lsb: 8 + reset_value: '0' + width: 8 +- I2S0_RXRATE: + fields: !!omap + - Y_DIVIDER: + access: rw + description: I2S receive MCLK rate denominator + lsb: 0 + reset_value: '0' + width: 8 + - X_DIVIDER: + access: rw + description: I2S receive MCLK rate numerator + lsb: 8 + reset_value: '0' + width: 8 +- I2S1_RXRATE: + fields: !!omap + - Y_DIVIDER: + access: rw + description: I2S receive MCLK rate denominator + lsb: 0 + reset_value: '0' + width: 8 + - X_DIVIDER: + access: rw + description: I2S receive MCLK rate numerator + lsb: 8 + reset_value: '0' + width: 8 +- I2S0_TXBITRATE: + fields: !!omap + - TX_BITRATE: + access: rw + description: I2S transmit bit rate + lsb: 0 + reset_value: '0' + width: 6 +- I2S1_TXBITRATE: + fields: !!omap + - TX_BITRATE: + access: rw + description: I2S transmit bit rate + lsb: 0 + reset_value: '0' + width: 6 +- I2S0_RXBITRATE: + fields: !!omap + - RX_BITRATE: + access: rw + description: I2S receive bit rate + lsb: 0 + reset_value: '0' + width: 6 +- I2S1_RXBITRATE: + fields: !!omap + - RX_BITRATE: + access: rw + description: I2S receive bit rate + lsb: 0 + reset_value: '0' + width: 6 +- I2S0_TXMODE: + fields: !!omap + - TXCLKSEL: + access: rw + description: Clock source selection for the transmit bit clock divider + lsb: 0 + reset_value: '0' + width: 2 + - TX4PIN: + access: rw + description: Transmit 4-pin mode selection + lsb: 2 + reset_value: '0' + width: 1 + - TXMCENA: + access: rw + description: Enable for the TX_MCLK output + lsb: 3 + reset_value: '0' + width: 1 +- I2S1_TXMODE: + fields: !!omap + - TXCLKSEL: + access: rw + description: Clock source selection for the transmit bit clock divider + lsb: 0 + reset_value: '0' + width: 2 + - TX4PIN: + access: rw + description: Transmit 4-pin mode selection + lsb: 2 + reset_value: '0' + width: 1 + - TXMCENA: + access: rw + description: Enable for the TX_MCLK output + lsb: 3 + reset_value: '0' + width: 1 +- I2S0_RXMODE: + fields: !!omap + - RXCLKSEL: + access: rw + description: Clock source selection for the receive bit clock divider + lsb: 0 + reset_value: '0' + width: 2 + - RX4PIN: + access: rw + description: Receive 4-pin mode selection + lsb: 2 + reset_value: '0' + width: 1 + - RXMCENA: + access: rw + description: Enable for the RX_MCLK output + lsb: 3 + reset_value: '0' + width: 1 +- I2S1_RXMODE: + fields: !!omap + - RXCLKSEL: + access: rw + description: Clock source selection for the receive bit clock divider + lsb: 0 + reset_value: '0' + width: 2 + - RX4PIN: + access: rw + description: Receive 4-pin mode selection + lsb: 2 + reset_value: '0' + width: 1 + - RXMCENA: + access: rw + description: Enable for the RX_MCLK output + lsb: 3 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/rgu.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/rgu.yaml new file mode 100644 index 00000000..6561d32b --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/rgu.yaml @@ -0,0 +1,1199 @@ +!!omap +- RESET_CTRL0: + fields: !!omap + - CORE_RST: + access: w + description: Writing a one activates the reset + lsb: 0 + reset_value: '0' + width: 1 + - PERIPH_RST: + access: w + description: Writing a one activates the reset + lsb: 1 + reset_value: '0' + width: 1 + - MASTER_RST: + access: w + description: Writing a one activates the reset + lsb: 2 + reset_value: '0' + width: 1 + - WWDT_RST: + access: '' + description: Writing a one to this bit has no effect + lsb: 4 + reset_value: '0' + width: 1 + - CREG_RST: + access: '' + description: Writing a one to this bit has no effect + lsb: 5 + reset_value: '0' + width: 1 + - BUS_RST: + access: w + description: Writing a one activates the reset + lsb: 8 + reset_value: '0' + width: 1 + - SCU_RST: + access: w + description: Writing a one activates the reset + lsb: 9 + reset_value: '0' + width: 1 + - M4_RST: + access: w + description: Writing a one activates the reset + lsb: 13 + reset_value: '0' + width: 1 + - LCD_RST: + access: w + description: Writing a one activates the reset + lsb: 16 + reset_value: '0' + width: 1 + - USB0_RST: + access: w + description: Writing a one activates the reset + lsb: 17 + reset_value: '0' + width: 1 + - USB1_RST: + access: w + description: Writing a one activates the reset + lsb: 18 + reset_value: '0' + width: 1 + - DMA_RST: + access: w + description: Writing a one activates the reset + lsb: 19 + reset_value: '0' + width: 1 + - SDIO_RST: + access: w + description: Writing a one activates the reset + lsb: 20 + reset_value: '0' + width: 1 + - EMC_RST: + access: w + description: Writing a one activates the reset + lsb: 21 + reset_value: '0' + width: 1 + - ETHERNET_RST: + access: w + description: Writing a one activates the reset + lsb: 22 + reset_value: '0' + width: 1 + - FLASHA_RST: + access: w + description: Writing a one activates the reset + lsb: 25 + reset_value: '0' + width: 1 + - EEPROM_RST: + access: w + description: Writing a one activates the reset + lsb: 27 + reset_value: '0' + width: 1 + - GPIO_RST: + access: w + description: Writing a one activates the reset + lsb: 28 + reset_value: '0' + width: 1 + - FLASHB_RST: + access: w + description: Writing a one activates the reset + lsb: 29 + reset_value: '0' + width: 1 +- RESET_CTRL1: + fields: !!omap + - TIMER0_RST: + access: w + description: Writing a one activates the reset + lsb: 0 + reset_value: '0' + width: 1 + - TIMER1_RST: + access: w + description: Writing a one activates the reset + lsb: 1 + reset_value: '0' + width: 1 + - TIMER2_RST: + access: w + description: Writing a one activates the reset + lsb: 2 + reset_value: '0' + width: 1 + - TIMER3_RST: + access: w + description: Writing a one activates the reset + lsb: 3 + reset_value: '0' + width: 1 + - RTIMER_RST: + access: w + description: Writing a one activates the reset + lsb: 4 + reset_value: '0' + width: 1 + - SCT_RST: + access: w + description: Writing a one activates the reset + lsb: 5 + reset_value: '0' + width: 1 + - MOTOCONPWM_RST: + access: w + description: Writing a one activates the reset + lsb: 6 + reset_value: '0' + width: 1 + - QEI_RST: + access: w + description: Writing a one activates the reset + lsb: 7 + reset_value: '0' + width: 1 + - ADC0_RST: + access: w + description: Writing a one activates the reset + lsb: 8 + reset_value: '0' + width: 1 + - ADC1_RST: + access: w + description: Writing a one activates the reset + lsb: 9 + reset_value: '0' + width: 1 + - DAC_RST: + access: w + description: Writing a one activates the reset + lsb: 10 + reset_value: '0' + width: 1 + - UART0_RST: + access: w + description: Writing a one activates the reset + lsb: 12 + reset_value: '0' + width: 1 + - UART1_RST: + access: w + description: Writing a one activates the reset + lsb: 13 + reset_value: '0' + width: 1 + - UART2_RST: + access: w + description: Writing a one activates the reset + lsb: 14 + reset_value: '0' + width: 1 + - UART3_RST: + access: w + description: Writing a one activates the reset + lsb: 15 + reset_value: '0' + width: 1 + - I2C0_RST: + access: w + description: Writing a one activates the reset + lsb: 16 + reset_value: '0' + width: 1 + - I2C1_RST: + access: w + description: Writing a one activates the reset + lsb: 17 + reset_value: '0' + width: 1 + - SSP0_RST: + access: w + description: Writing a one activates the reset + lsb: 18 + reset_value: '0' + width: 1 + - SSP1_RST: + access: w + description: Writing a one activates the reset + lsb: 19 + reset_value: '0' + width: 1 + - I2S_RST: + access: w + description: Writing a one activates the reset + lsb: 20 + reset_value: '0' + width: 1 + - SPIFI_RST: + access: w + description: Writing a one activates the reset + lsb: 21 + reset_value: '0' + width: 1 + - CAN1_RST: + access: w + description: Writing a one activates the reset + lsb: 22 + reset_value: '0' + width: 1 + - CAN0_RST: + access: w + description: Writing a one activates the reset + lsb: 23 + reset_value: '0' + width: 1 + - M0APP_RST: + access: w + description: Writing a one activates the reset + lsb: 24 + reset_value: '1' + width: 1 + - SGPIO_RST: + access: w + description: Writing a one activates the reset + lsb: 25 + reset_value: '0' + width: 1 + - SPI_RST: + access: w + description: Writing a one activates the reset + lsb: 26 + reset_value: '0' + width: 1 +- RESET_STATUS0: + fields: !!omap + - CORE_RST: + access: rw + description: Status of the CORE_RST reset generator output + lsb: 0 + reset_value: '0x0' + width: 2 + - PERIPH_RST: + access: rw + description: Status of the PERIPH_RST reset generator output + lsb: 2 + reset_value: '0x0' + width: 2 + - MASTER_RST: + access: rw + description: Status of the MASTER_RST reset generator output + lsb: 4 + reset_value: '0x1' + width: 2 + - WWDT_RST: + access: rw + description: Status of the WWDT_RST reset generator output + lsb: 8 + reset_value: '0x0' + width: 2 + - CREG_RST: + access: rw + description: Status of the CREG_RST reset generator output + lsb: 10 + reset_value: '0x0' + width: 2 + - BUS_RST: + access: rw + description: Status of the BUS_RST reset generator output + lsb: 16 + reset_value: '0x1' + width: 2 + - SCU_RST: + access: rw + description: Status of the SCU_RST reset generator output + lsb: 18 + reset_value: '0x1' + width: 2 + - M4_RST: + access: rw + description: Status of the M4_RST reset generator output + lsb: 26 + reset_value: '0x1' + width: 2 +- RESET_STATUS1: + fields: !!omap + - LCD_RST: + access: rw + description: Status of the LCD_RST reset generator output + lsb: 0 + reset_value: '0x1' + width: 2 + - USB0_RST: + access: rw + description: Status of the USB0_RST reset generator output + lsb: 2 + reset_value: '0x1' + width: 2 + - USB1_RST: + access: rw + description: Status of the USB1_RST reset generator output + lsb: 4 + reset_value: '0x1' + width: 2 + - DMA_RST: + access: rw + description: Status of the DMA_RST reset generator output + lsb: 6 + reset_value: '0x1' + width: 2 + - SDIO_RST: + access: rw + description: Status of the SDIO_RST reset generator output + lsb: 8 + reset_value: '0x1' + width: 2 + - EMC_RST: + access: rw + description: Status of the EMC_RST reset generator output + lsb: 10 + reset_value: '0x1' + width: 2 + - ETHERNET_RST: + access: rw + description: Status of the ETHERNET_RST reset generator output + lsb: 12 + reset_value: '0x1' + width: 2 + - FLASHA_RST: + access: '' + description: Status of the FLASHA_RST reset generator output + lsb: 18 + reset_value: '0x1' + width: 2 + - EEPROM_RST: + access: '' + description: Status of the EEPROM_RST reset generator output + lsb: 22 + reset_value: '0x1' + width: 2 + - GPIO_RST: + access: rw + description: Status of the GPIO_RST reset generator output + lsb: 24 + reset_value: '0x1' + width: 2 + - FLASHB_RST: + access: rw + description: Status of the FLASHB_RST reset generator output + lsb: 26 + reset_value: '0x1' + width: 2 +- RESET_STATUS2: + fields: !!omap + - TIMER0_RST: + access: rw + description: Status of the TIMER0_RST reset generator output + lsb: 0 + reset_value: '0x1' + width: 2 + - TIMER1_RST: + access: rw + description: Status of the TIMER1_RST reset generator output + lsb: 2 + reset_value: '0x1' + width: 2 + - TIMER2_RST: + access: rw + description: Status of the TIMER2_RST reset generator output + lsb: 4 + reset_value: '0x1' + width: 2 + - TIMER3_RST: + access: rw + description: Status of the TIMER3_RST reset generator output + lsb: 6 + reset_value: '0x1' + width: 2 + - RITIMER_RST: + access: rw + description: Status of the RITIMER_RST reset generator output + lsb: 8 + reset_value: '0x1' + width: 2 + - SCT_RST: + access: rw + description: Status of the SCT_RST reset generator output + lsb: 10 + reset_value: '0x1' + width: 2 + - MOTOCONPWM_RST: + access: rw + description: Status of the MOTOCONPWM_RST reset generator output + lsb: 12 + reset_value: '0x1' + width: 2 + - QEI_RST: + access: rw + description: Status of the QEI_RST reset generator output + lsb: 14 + reset_value: '0x1' + width: 2 + - ADC0_RST: + access: rw + description: Status of the ADC0_RST reset generator output + lsb: 16 + reset_value: '0x1' + width: 2 + - ADC1_RST: + access: rw + description: Status of the ADC1_RST reset generator output + lsb: 18 + reset_value: '0x1' + width: 2 + - DAC_RST: + access: rw + description: Status of the DAC_RST reset generator output + lsb: 20 + reset_value: '0x1' + width: 2 + - UART0_RST: + access: rw + description: Status of the UART0_RST reset generator output + lsb: 24 + reset_value: '0x1' + width: 2 + - UART1_RST: + access: rw + description: Status of the UART1_RST reset generator output + lsb: 26 + reset_value: '0x1' + width: 2 + - UART2_RST: + access: rw + description: Status of the UART2_RST reset generator output + lsb: 28 + reset_value: '0x1' + width: 2 + - UART3_RST: + access: rw + description: Status of the UART3_RST reset generator output + lsb: 30 + reset_value: '0x1' + width: 2 +- RESET_STATUS3: + fields: !!omap + - I2C0_RST: + access: rw + description: Status of the I2C0_RST reset generator output + lsb: 0 + reset_value: '0x1' + width: 2 + - I2C1_RST: + access: rw + description: Status of the I2C1_RST reset generator output + lsb: 2 + reset_value: '0x1' + width: 2 + - SSP0_RST: + access: rw + description: Status of the SSP0_RST reset generator output + lsb: 4 + reset_value: '0x1' + width: 2 + - SSP1_RST: + access: rw + description: Status of the SSP1_RST reset generator output + lsb: 6 + reset_value: '0x1' + width: 2 + - I2S_RST: + access: rw + description: Status of the I2S_RST reset generator output + lsb: 8 + reset_value: '0x1' + width: 2 + - SPIFI_RST: + access: rw + description: Status of the SPIFI_RST reset generator output + lsb: 10 + reset_value: '0x1' + width: 2 + - CAN1_RST: + access: rw + description: Status of the CAN1_RST reset generator output + lsb: 12 + reset_value: '0x1' + width: 2 + - CAN0_RST: + access: rw + description: Status of the CAN0_RST reset generator output + lsb: 14 + reset_value: '0x1' + width: 2 + - M0APP_RST: + access: rw + description: Status of the M0APP_RST reset generator output + lsb: 16 + reset_value: '0x3' + width: 2 + - SGPIO_RST: + access: rw + description: Status of the SGPIO_RST reset generator output + lsb: 18 + reset_value: '0x1' + width: 2 + - SPI_RST: + access: rw + description: Status of the SPI_RST reset generator output + lsb: 20 + reset_value: '0x1' + width: 2 +- RESET_ACTIVE_STATUS0: + fields: !!omap + - CORE_RST: + access: r + description: Current status of the CORE_RST + lsb: 0 + reset_value: '0' + width: 1 + - PERIPH_RST: + access: r + description: Current status of the PERIPH_RST + lsb: 1 + reset_value: '0' + width: 1 + - MASTER_RST: + access: r + description: Current status of the MASTER_RST + lsb: 2 + reset_value: '0' + width: 1 + - WWDT_RST: + access: r + description: Current status of the WWDT_RST + lsb: 4 + reset_value: '0' + width: 1 + - CREG_RST: + access: r + description: Current status of the CREG_RST + lsb: 5 + reset_value: '0' + width: 1 + - BUS_RST: + access: r + description: Current status of the BUS_RST + lsb: 8 + reset_value: '0' + width: 1 + - SCU_RST: + access: r + description: Current status of the SCU_RST + lsb: 9 + reset_value: '0' + width: 1 + - M4_RST: + access: r + description: Current status of the M4_RST + lsb: 13 + reset_value: '0' + width: 1 + - LCD_RST: + access: r + description: Current status of the LCD_RST + lsb: 16 + reset_value: '0' + width: 1 + - USB0_RST: + access: r + description: Current status of the USB0_RST + lsb: 17 + reset_value: '0' + width: 1 + - USB1_RST: + access: r + description: Current status of the USB1_RST + lsb: 18 + reset_value: '0' + width: 1 + - DMA_RST: + access: r + description: Current status of the DMA_RST + lsb: 19 + reset_value: '0' + width: 1 + - SDIO_RST: + access: r + description: Current status of the SDIO_RST + lsb: 20 + reset_value: '0' + width: 1 + - EMC_RST: + access: r + description: Current status of the EMC_RST + lsb: 21 + reset_value: '0' + width: 1 + - ETHERNET_RST: + access: r + description: Current status of the ETHERNET_RST + lsb: 22 + reset_value: '0' + width: 1 + - FLASHA_RST: + access: r + description: Current status of the FLASHA_RST + lsb: 25 + reset_value: '0' + width: 1 + - EEPROM_RST: + access: r + description: Current status of the EEPROM_RST + lsb: 27 + reset_value: '0' + width: 1 + - GPIO_RST: + access: r + description: Current status of the GPIO_RST + lsb: 28 + reset_value: '0' + width: 1 + - FLASHB_RST: + access: r + description: Current status of the FLASHB_RST + lsb: 29 + reset_value: '0' + width: 1 +- RESET_ACTIVE_STATUS1: + fields: !!omap + - TIMER0_RST: + access: r + description: Current status of the TIMER0_RST + lsb: 0 + reset_value: '0' + width: 1 + - TIMER1_RST: + access: r + description: Current status of the TIMER1_RST + lsb: 1 + reset_value: '0' + width: 1 + - TIMER2_RST: + access: r + description: Current status of the TIMER2_RST + lsb: 2 + reset_value: '0' + width: 1 + - TIMER3_RST: + access: r + description: Current status of the TIMER3_RST + lsb: 3 + reset_value: '0' + width: 1 + - RITIMER_RST: + access: r + description: Current status of the RITIMER_RST + lsb: 4 + reset_value: '0' + width: 1 + - SCT_RST: + access: r + description: Current status of the SCT_RST + lsb: 5 + reset_value: '0' + width: 1 + - MOTOCONPWM_RST: + access: r + description: Current status of the MOTOCONPWM_RST + lsb: 6 + reset_value: '0' + width: 1 + - QEI_RST: + access: r + description: Current status of the QEI_RST + lsb: 7 + reset_value: '0' + width: 1 + - ADC0_RST: + access: r + description: Current status of the ADC0_RST + lsb: 8 + reset_value: '0' + width: 1 + - ADC1_RST: + access: r + description: Current status of the ADC1_RST + lsb: 9 + reset_value: '0' + width: 1 + - DAC_RST: + access: r + description: Current status of the DAC_RST + lsb: 10 + reset_value: '0' + width: 1 + - UART0_RST: + access: r + description: Current status of the UART0_RST + lsb: 12 + reset_value: '0' + width: 1 + - UART1_RST: + access: r + description: Current status of the UART1_RST + lsb: 13 + reset_value: '0' + width: 1 + - UART2_RST: + access: r + description: Current status of the UART2_RST + lsb: 14 + reset_value: '0' + width: 1 + - UART3_RST: + access: r + description: Current status of the UART3_RST + lsb: 15 + reset_value: '0' + width: 1 + - I2C0_RST: + access: r + description: Current status of the I2C0_RST + lsb: 16 + reset_value: '0' + width: 1 + - I2C1_RST: + access: r + description: Current status of the I2C1_RST + lsb: 17 + reset_value: '0' + width: 1 + - SSP0_RST: + access: r + description: Current status of the SSP0_RST + lsb: 18 + reset_value: '0' + width: 1 + - SSP1_RST: + access: r + description: Current status of the SSP1_RST + lsb: 19 + reset_value: '0' + width: 1 + - I2S_RST: + access: r + description: Current status of the I2S_RST + lsb: 20 + reset_value: '0' + width: 1 + - SPIFI_RST: + access: r + description: Current status of the SPIFI_RST + lsb: 21 + reset_value: '0' + width: 1 + - CAN1_RST: + access: r + description: Current status of the CAN1_RST + lsb: 22 + reset_value: '0' + width: 1 + - CAN0_RST: + access: r + description: Current status of the CAN0_RST + lsb: 23 + reset_value: '0' + width: 1 + - M0APP_RST: + access: r + description: Current status of the M0APP_RST + lsb: 24 + reset_value: '0' + width: 1 + - SGPIO_RST: + access: r + description: Current status of the SGPIO_RST + lsb: 25 + reset_value: '0' + width: 1 + - SPI_RST: + access: r + description: Current status of the SPI_RST + lsb: 26 + reset_value: '0' + width: 1 +- RESET_EXT_STAT0: + fields: !!omap + - EXT_RESET: + access: rw + description: Reset activated by external reset from reset pin + lsb: 0 + reset_value: '0' + width: 1 + - BOD_RESET: + access: rw + description: Reset activated by BOD reset + lsb: 4 + reset_value: '0' + width: 1 + - WWDT_RESET: + access: rw + description: Reset activated by WWDT time-out + lsb: 5 + reset_value: '0' + width: 1 +- RESET_EXT_STAT1: + fields: !!omap + - CORE_RESET: + access: rw + description: Reset activated by CORE_RST output + lsb: 1 + reset_value: '0' + width: 1 +- RESET_EXT_STAT2: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT4: + fields: !!omap + - CORE_RESET: + access: rw + description: Reset activated by CORE_RST output + lsb: 1 + reset_value: '0' + width: 1 +- RESET_EXT_STAT5: + fields: !!omap + - CORE_RESET: + access: rw + description: Reset activated by CORE_RST output + lsb: 1 + reset_value: '0' + width: 1 +- RESET_EXT_STAT8: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT9: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT13: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT16: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT17: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT18: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT19: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT20: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT21: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT22: + fields: !!omap + - MASTER_RESET: + access: rw + description: Reset activated by MASTER_RST output + lsb: 3 + reset_value: '0' + width: 1 +- RESET_EXT_STAT25: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT27: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT28: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT29: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT32: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT33: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT34: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT35: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT36: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT37: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT38: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT39: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT40: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT41: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT42: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT44: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT45: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT46: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT47: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT48: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT49: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT50: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT51: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT52: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT53: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT54: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT55: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT56: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '' + width: 1 +- RESET_EXT_STAT57: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 +- RESET_EXT_STAT58: + fields: !!omap + - PERIPHERAL_RESET: + access: rw + description: Reset activated by PERIPHERAL_RST output + lsb: 2 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ritimer.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ritimer.yaml new file mode 100644 index 00000000..9c4da5c1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ritimer.yaml @@ -0,0 +1,51 @@ +!!omap +- RITIMER_COMPVAL: + fields: !!omap + - RICOMP: + access: rw + description: Compare register + lsb: 0 + reset_value: '0xFFFFFFFF' + width: 32 +- RITIMER_MASK: + fields: !!omap + - RIMASK: + access: rw + description: Mask register + lsb: 0 + reset_value: '0' + width: 32 +- RITIMER_CTRL: + fields: !!omap + - RITINT: + access: rw + description: Interrupt flag + lsb: 0 + reset_value: '0' + width: 1 + - RITENCLR: + access: rw + description: Timer enable clear + lsb: 1 + reset_value: '0' + width: 1 + - RITENBR: + access: rw + description: Timer enable for debug + lsb: 2 + reset_value: '1' + width: 1 + - RITEN: + access: rw + description: Timer enable + lsb: 3 + reset_value: '1' + width: 1 +- RITIMER_COUNTER: + fields: !!omap + - RICOUNTER: + access: rw + description: 32-bit up counter + lsb: 0 + reset_value: '0' + width: 32 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/scu.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/scu.yaml new file mode 100644 index 00000000..447ce242 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/scu.yaml @@ -0,0 +1,7063 @@ +!!omap +- SCU_SFSP0_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP0_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_11: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_12: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_13: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_14: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_15: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_16: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_18: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_19: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_20: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_11: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_12: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP2_13: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP3_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP4_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP5_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_11: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP6_12: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP7_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP8_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP8_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP8_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP8_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP8_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP8_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP9_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP9_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP9_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP9_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP9_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP9_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP9_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPA_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPA_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPB_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPB_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPB_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPB_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPB_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPB_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPB_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_11: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_12: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_13: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPC_14: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_11: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_12: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_13: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_14: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_15: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPD_16: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_11: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_12: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_13: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_14: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPE_15: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_6: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_7: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_8: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_9: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_10: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSPF_11: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSP1_17: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSP2_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSP2_4: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSP2_5: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSP8_0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSP8_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSP8_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSPA_1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSPA_2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSPA_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 + - EHD: + access: rw + description: Select drive strength + lsb: 8 + reset_value: '0' + width: 2 +- SCU_SFSP3_3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSCLK0: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSCLK1: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSCLK2: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSCLK3: + fields: !!omap + - MODE: + access: rw + description: Select pin function + lsb: 0 + reset_value: '0' + width: 3 + - EPD: + access: rw + description: Enable pull-down resistor at pad + lsb: 3 + reset_value: '0' + width: 1 + - EPUN: + access: rw + description: Disable pull-up resistor at pad + lsb: 4 + reset_value: '0' + width: 1 + - EHS: + access: rw + description: Select Slew rate + lsb: 5 + reset_value: '0' + width: 1 + - EZI: + access: rw + description: Input buffer enable + lsb: 6 + reset_value: '0' + width: 1 + - ZIF: + access: rw + description: Input glitch filter + lsb: 7 + reset_value: '0' + width: 1 +- SCU_SFSUSB: + fields: !!omap + - USB_AIM: + access: rw + description: Differential data input AIP/AIM + lsb: 0 + reset_value: '0' + width: 1 + - USB_ESEA: + access: rw + description: Control signal for differential input or single input + lsb: 1 + reset_value: '1' + width: 1 + - USB_EPD: + access: rw + description: Enable pull-down connect + lsb: 2 + reset_value: '0' + width: 1 + - USB_EPWR: + access: rw + description: Power mode + lsb: 4 + reset_value: '0' + width: 1 + - USB_VBUS: + access: rw + description: Enable the vbus_valid signal + lsb: 5 + reset_value: '0' + width: 1 +- SCU_SFSI2C0: + fields: !!omap + - SCL_EFP: + access: rw + description: Select input glitch filter time constant for the SCL pin + lsb: 0 + reset_value: '0' + width: 1 + - SCL_EHD: + access: rw + description: Select I2C mode for the SCL pin + lsb: 2 + reset_value: '0' + width: 1 + - SCL_EZI: + access: rw + description: Enable the input receiver for the SCL pin + lsb: 3 + reset_value: '0' + width: 1 + - SCL_ZIF: + access: rw + description: Enable or disable input glitch filter for the SCL pin + lsb: 7 + reset_value: '0' + width: 1 + - SDA_EFP: + access: rw + description: Select input glitch filter time constant for the SDA pin + lsb: 8 + reset_value: '0' + width: 1 + - SDA_EHD: + access: rw + description: Select I2C mode for the SDA pin + lsb: 10 + reset_value: '0' + width: 1 + - SDA_EZI: + access: rw + description: Enable the input receiver for the SDA pin + lsb: 11 + reset_value: '0' + width: 1 + - SDA_ZIF: + access: rw + description: Enable or disable input glitch filter for the SDA pin + lsb: 15 + reset_value: '0' + width: 1 +- SCU_ENAIO0: + fields: !!omap + - ADC0_0: + access: rw + description: Select ADC0_0 + lsb: 0 + reset_value: '0' + width: 1 + - ADC0_1: + access: rw + description: Select ADC0_1 + lsb: 1 + reset_value: '0' + width: 1 + - ADC0_2: + access: rw + description: Select ADC0_2 + lsb: 2 + reset_value: '0' + width: 1 + - ADC0_3: + access: rw + description: Select ADC0_3 + lsb: 3 + reset_value: '0' + width: 1 + - ADC0_4: + access: rw + description: Select ADC0_4 + lsb: 4 + reset_value: '0' + width: 1 + - ADC0_5: + access: rw + description: Select ADC0_5 + lsb: 5 + reset_value: '0' + width: 1 + - ADC0_6: + access: rw + description: Select ADC0_6 + lsb: 6 + reset_value: '0' + width: 1 +- SCU_ENAIO1: + fields: !!omap + - ADC1_0: + access: rw + description: Select ADC1_0 + lsb: 0 + reset_value: '0' + width: 1 + - ADC1_1: + access: rw + description: Select ADC1_1 + lsb: 1 + reset_value: '0' + width: 1 + - ADC1_2: + access: rw + description: Select ADC1_2 + lsb: 2 + reset_value: '0' + width: 1 + - ADC1_3: + access: rw + description: Select ADC1_3 + lsb: 3 + reset_value: '0' + width: 1 + - ADC1_4: + access: rw + description: Select ADC1_4 + lsb: 4 + reset_value: '0' + width: 1 + - ADC1_5: + access: rw + description: Select ADC1_5 + lsb: 5 + reset_value: '0' + width: 1 + - ADC1_6: + access: rw + description: Select ADC1_6 + lsb: 6 + reset_value: '0' + width: 1 + - ADC1_7: + access: rw + description: Select ADC1_7 + lsb: 7 + reset_value: '0' + width: 1 +- SCU_ENAIO2: + fields: !!omap + - DAC: + access: rw + description: Select DAC + lsb: 0 + reset_value: '0' + width: 1 + - BG: + access: rw + description: Select band gap output + lsb: 4 + reset_value: '0' + width: 1 +- SCU_EMCDELAYCLK: + fields: !!omap + - CLK_DELAY: + access: rw + description: EMC_CLKn SDRAM clock output delay + lsb: 0 + reset_value: '0' + width: 16 +- SCU_PINTSEL0: + fields: !!omap + - INTPIN0: + access: '' + description: pin number for interrupt 0 source + lsb: 0 + reset_value: '0' + width: 5 + - PORTSEL0: + access: '' + description: port for interrupt 0 source + lsb: 5 + reset_value: '0' + width: 3 + - INTPIN1: + access: '' + description: pin number for interrupt 1 source + lsb: 8 + reset_value: '0' + width: 5 + - PORTSEL1: + access: '' + description: port for interrupt 1 source + lsb: 13 + reset_value: '0' + width: 3 + - INTPIN2: + access: '' + description: pin number for interrupt 2 source + lsb: 16 + reset_value: '0' + width: 5 + - PORTSEL2: + access: '' + description: port for interrupt 2 source + lsb: 21 + reset_value: '0' + width: 3 + - INTPIN3: + access: '' + description: pin number for interrupt 3 source + lsb: 24 + reset_value: '0' + width: 5 + - PORTSEL3: + access: '' + description: port for interrupt 3 source + lsb: 29 + reset_value: '0' + width: 3 +- SCU_PINTSEL1: + fields: !!omap + - INTPIN4: + access: '' + description: pin number for interrupt 4 source + lsb: 0 + reset_value: '0' + width: 5 + - PORTSEL4: + access: '' + description: port for interrupt 4 source + lsb: 5 + reset_value: '0' + width: 3 + - INTPIN5: + access: '' + description: pin number for interrupt 5 source + lsb: 8 + reset_value: '0' + width: 5 + - PORTSEL5: + access: '' + description: port for interrupt 5 source + lsb: 13 + reset_value: '0' + width: 3 + - INTPIN6: + access: '' + description: pin number for interrupt 6 source + lsb: 16 + reset_value: '0' + width: 5 + - PORTSEL6: + access: '' + description: port for interrupt 6 source + lsb: 21 + reset_value: '0' + width: 3 + - INTPIN7: + access: '' + description: pin number for interrupt 7 source + lsb: 24 + reset_value: '0' + width: 5 + - PORTSEL7: + access: '' + description: port for interrupt 7 source + lsb: 29 + reset_value: '0' + width: 3 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/sgpio.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/sgpio.yaml new file mode 100644 index 00000000..fab91b66 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/sgpio.yaml @@ -0,0 +1,1953 @@ +!!omap +- SGPIO_OUT_MUX_CFG0: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG1: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG2: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG3: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG4: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG5: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG6: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG7: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG8: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG9: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG10: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG11: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG12: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG13: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG14: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_OUT_MUX_CFG15: + fields: !!omap + - P_OUT_CFG: + access: rw + description: Output control of output SGPIOn + lsb: 0 + reset_value: '0' + width: 4 + - P_OE_CFG: + access: rw + description: Output enable source + lsb: 4 + reset_value: '0' + width: 3 +- SGPIO_MUX_CFG0: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG1: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG2: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG3: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG4: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG5: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG6: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG7: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG8: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG9: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG10: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG11: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG12: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG13: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG14: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_MUX_CFG15: + fields: !!omap + - EXT_CLK_ENABLE: + access: rw + description: Select clock signal + lsb: 0 + reset_value: '0' + width: 1 + - CLK_SOURCE_PIN_MODE: + access: rw + description: Select source clock pin + lsb: 1 + reset_value: '0' + width: 2 + - CLK_SOURCE_SLICE_MODE: + access: rw + description: Select clock source slice + lsb: 3 + reset_value: '0' + width: 2 + - QUALIFIER_MODE: + access: rw + description: Select qualifier mode + lsb: 5 + reset_value: '0' + width: 2 + - QUALIFIER_PIN_MODE: + access: rw + description: Select qualifier pin + lsb: 7 + reset_value: '0' + width: 2 + - QUALIFIER_SLICE_MODE: + access: rw + description: Select qualifier slice + lsb: 9 + reset_value: '0' + width: 2 + - CONCAT_ENABLE: + access: rw + description: Enable concatenation + lsb: 11 + reset_value: '0' + width: 1 + - CONCAT_ORDER: + access: rw + description: Select concatenation order + lsb: 12 + reset_value: '0' + width: 2 +- SGPIO_SLICE_MUX_CFG0: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG1: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG2: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG3: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG4: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG5: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG6: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG7: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG8: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG9: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG10: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG11: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG12: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG13: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG14: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_SLICE_MUX_CFG15: + fields: !!omap + - MATCH_MODE: + access: rw + description: Match mode + lsb: 0 + reset_value: '0' + width: 1 + - CLK_CAPTURE_MODE: + access: rw + description: Capture clock mode + lsb: 1 + reset_value: '0' + width: 1 + - CLKGEN_MODE: + access: rw + description: Clock generation mode + lsb: 2 + reset_value: '0' + width: 1 + - INV_OUT_CLK: + access: rw + description: Invert output clock + lsb: 3 + reset_value: '0' + width: 1 + - DATA_CAPTURE_MODE: + access: rw + description: Condition for input bit match interrupt + lsb: 4 + reset_value: '0' + width: 2 + - PARALLEL_MODE: + access: rw + description: Parallel mode + lsb: 6 + reset_value: '0' + width: 2 + - INV_QUALIFIER: + access: rw + description: Inversion qualifier + lsb: 8 + reset_value: '0' + width: 1 +- SGPIO_POS0: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS1: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS2: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS3: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS4: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS5: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS6: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS7: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS8: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS9: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS10: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS11: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS12: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS13: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS14: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 +- SGPIO_POS15: + fields: !!omap + - POS: + access: rw + description: Each time COUNT reaches 0x0 POS counts down + lsb: 0 + reset_value: '0' + width: 8 + - POS_RESET: + access: rw + description: Reload value for POS after POS reaches 0x0 + lsb: 8 + reset_value: '0' + width: 8 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ssp.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ssp.yaml new file mode 100644 index 00000000..54b440b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/ssp.yaml @@ -0,0 +1,445 @@ +!!omap +- SSP0_CR0: + fields: !!omap + - DSS: + access: rw + description: Data Size Select + lsb: 0 + reset_value: '0' + width: 4 + - FRF: + access: rw + description: Frame Format + lsb: 4 + reset_value: '0' + width: 2 + - CPOL: + access: rw + description: Clock Out Polarity + lsb: 6 + reset_value: '0' + width: 1 + - CPHA: + access: rw + description: Clock Out Phase + lsb: 7 + reset_value: '0' + width: 1 + - SCR: + access: rw + description: Serial Clock Rate + lsb: 8 + reset_value: '0' + width: 8 +- SSP1_CR0: + fields: !!omap + - DSS: + access: rw + description: Data Size Select + lsb: 0 + reset_value: '0' + width: 4 + - FRF: + access: rw + description: Frame Format + lsb: 4 + reset_value: '0' + width: 2 + - CPOL: + access: rw + description: Clock Out Polarity + lsb: 6 + reset_value: '0' + width: 1 + - CPHA: + access: rw + description: Clock Out Phase + lsb: 7 + reset_value: '0' + width: 1 + - SCR: + access: rw + description: Serial Clock Rate + lsb: 8 + reset_value: '0' + width: 8 +- SSP0_CR1: + fields: !!omap + - LBM: + access: rw + description: Loop Back Mode + lsb: 0 + reset_value: '0' + width: 1 + - SSE: + access: rw + description: SSP Enable + lsb: 1 + reset_value: '0' + width: 1 + - MS: + access: rw + description: Master/Slave Mode + lsb: 2 + reset_value: '0' + width: 1 + - SOD: + access: rw + description: Slave Output Disable + lsb: 3 + reset_value: '0' + width: 1 +- SSP1_CR1: + fields: !!omap + - SSE: + access: rw + description: SSP Enable + lsb: 1 + reset_value: '0' + width: 1 + - MS: + access: rw + description: Master/Slave Mode + lsb: 2 + reset_value: '0' + width: 1 + - SOD: + access: rw + description: Slave Output Disable + lsb: 3 + reset_value: '0' + width: 1 +- SSP0_DR: + fields: !!omap + - DATA: + access: rw + description: Software can write data to be transmitted to this register, and + read data that has been + lsb: 0 + reset_value: '0' + width: 16 +- SSP1_DR: + fields: !!omap + - DATA: + access: rw + description: Software can write data to be transmitted to this register, and + read data that has been + lsb: 0 + reset_value: '0' + width: 16 +- SSP0_SR: + fields: !!omap + - TFE: + access: r + description: Transmit FIFO Empty + lsb: 0 + reset_value: '1' + width: 1 + - TNF: + access: r + description: Transmit FIFO Not Full + lsb: 1 + reset_value: '1' + width: 1 + - RNE: + access: r + description: Receive FIFO Not Empty + lsb: 2 + reset_value: '0' + width: 1 + - RFF: + access: r + description: Receive FIFO Full + lsb: 3 + reset_value: '0' + width: 1 + - BSY: + access: r + description: Busy. + lsb: 4 + reset_value: '0' + width: 1 +- SSP1_SR: + fields: !!omap + - TFE: + access: r + description: Transmit FIFO Empty + lsb: 0 + reset_value: '1' + width: 1 + - TNF: + access: r + description: Transmit FIFO Not Full + lsb: 1 + reset_value: '1' + width: 1 + - RNE: + access: r + description: Receive FIFO Not Empty + lsb: 2 + reset_value: '0' + width: 1 + - RFF: + access: r + description: Receive FIFO Full + lsb: 3 + reset_value: '0' + width: 1 + - BSY: + access: r + description: Busy. + lsb: 4 + reset_value: '0' + width: 1 +- SSP0_CPSR: + fields: !!omap + - CPSDVSR: + access: rw + description: SSP Clock Prescale Register + lsb: 0 + reset_value: '0' + width: 8 +- SSP1_CPSR: + fields: !!omap + - CPSDVSR: + access: rw + description: SSP Clock Prescale Register + lsb: 0 + reset_value: '0' + width: 8 +- SSP0_IMSC: + fields: !!omap + - RORIM: + access: rw + description: Software should set this bit to enable interrupt when a Receive + Overrun occurs + lsb: 0 + reset_value: '0' + width: 1 + - RTIM: + access: rw + description: Software should set this bit to enable interrupt when a Receive + Time-out condition occurs + lsb: 1 + reset_value: '0' + width: 1 + - RXIM: + access: rw + description: Software should set this bit to enable interrupt when the Rx + FIFO is at least half full + lsb: 2 + reset_value: '0' + width: 1 + - TXIM: + access: rw + description: Software should set this bit to enable interrupt when the Tx + FIFO is at least half empty + lsb: 3 + reset_value: '0' + width: 1 +- SSP1_IMSC: + fields: !!omap + - RORIM: + access: rw + description: Software should set this bit to enable interrupt when a Receive + Overrun occurs + lsb: 0 + reset_value: '0' + width: 1 + - RTIM: + access: rw + description: Software should set this bit to enable interrupt when a Receive + Time-out condition occurs + lsb: 1 + reset_value: '0' + width: 1 + - RXIM: + access: rw + description: Software should set this bit to enable interrupt when the Rx + FIFO is at least half full + lsb: 2 + reset_value: '0' + width: 1 + - TXIM: + access: rw + description: Software should set this bit to enable interrupt when the Tx + FIFO is at least half empty + lsb: 3 + reset_value: '0' + width: 1 +- SSP0_RIS: + fields: !!omap + - RORRIS: + access: r + description: This bit is 1 if another frame was completely received while + the RxFIFO was full + lsb: 0 + reset_value: '0' + width: 1 + - RTRIS: + access: r + description: This bit is 1 if the Rx FIFO is not empty, and has not been read + for a time-out period + lsb: 1 + reset_value: '0' + width: 1 + - RXRIS: + access: r + description: This bit is 1 if the Rx FIFO is at least half full + lsb: 2 + reset_value: '0' + width: 1 + - TXRIS: + access: r + description: This bit is 1 if the Tx FIFO is at least half empty + lsb: 3 + reset_value: '1' + width: 1 +- SSP1_RIS: + fields: !!omap + - RORRIS: + access: r + description: This bit is 1 if another frame was completely received while + the RxFIFO was full + lsb: 0 + reset_value: '0' + width: 1 + - RTRIS: + access: r + description: This bit is 1 if the Rx FIFO is not empty, and has not been read + for a time-out period + lsb: 1 + reset_value: '0' + width: 1 + - RXRIS: + access: r + description: This bit is 1 if the Rx FIFO is at least half full + lsb: 2 + reset_value: '0' + width: 1 + - TXRIS: + access: r + description: This bit is 1 if the Tx FIFO is at least half empty + lsb: 3 + reset_value: '1' + width: 1 +- SSP0_MIS: + fields: !!omap + - RORMIS: + access: r + description: This bit is 1 if another frame was completely received while + the RxFIFO was full, and this interrupt is enabled + lsb: 0 + reset_value: '0' + width: 1 + - RTMIS: + access: r + description: This bit is 1 if the Rx FIFO is not empty, has not been read + for a time-out period, and this interrupt is enabled + lsb: 1 + reset_value: '0' + width: 1 + - RXMIS: + access: r + description: This bit is 1 if the Rx FIFO is at least half full, and this + interrupt is enabled + lsb: 2 + reset_value: '0' + width: 1 + - TXMIS: + access: r + description: This bit is 1 if the Tx FIFO is at least half empty, and this + interrupt is enabled + lsb: 3 + reset_value: '0' + width: 1 +- SSP1_MIS: + fields: !!omap + - RORMIS: + access: r + description: This bit is 1 if another frame was completely received while + the RxFIFO was full, and this interrupt is enabled + lsb: 0 + reset_value: '0' + width: 1 + - RTMIS: + access: r + description: This bit is 1 if the Rx FIFO is not empty, has not been read + for a time-out period, and this interrupt is enabled + lsb: 1 + reset_value: '0' + width: 1 + - RXMIS: + access: r + description: This bit is 1 if the Rx FIFO is at least half full, and this + interrupt is enabled + lsb: 2 + reset_value: '0' + width: 1 + - TXMIS: + access: r + description: This bit is 1 if the Tx FIFO is at least half empty, and this + interrupt is enabled + lsb: 3 + reset_value: '0' + width: 1 +- SSP0_ICR: + fields: !!omap + - RORIC: + access: w + description: Writing a 1 to this bit clears the 'frame was received when RxFIFO + was full' interrupt + lsb: 0 + reset_value: '' + width: 1 + - RTIC: + access: w + description: Writing a 1 to this bit clears the Rx FIFO was not empty and + has not been read for a time-out period interrupt + lsb: 1 + reset_value: '' + width: 1 +- SSP1_ICR: + fields: !!omap + - RORIC: + access: w + description: Writing a 1 to this bit clears the 'frame was received when RxFIFO + was full' interrupt + lsb: 0 + reset_value: '' + width: 1 + - RTIC: + access: w + description: Writing a 1 to this bit clears the Rx FIFO was not empty and + has not been read for a time-out period interrupt + lsb: 1 + reset_value: '' + width: 1 +- SSP0_DMACR: + fields: !!omap + - RXDMAE: + access: rw + description: Receive DMA Enable + lsb: 0 + reset_value: '0' + width: 1 + - TXDMAE: + access: rw + description: Transmit DMA Enable + lsb: 1 + reset_value: '0' + width: 1 +- SSP1_DMACR: + fields: !!omap + - RXDMAE: + access: rw + description: Receive DMA Enable + lsb: 0 + reset_value: '0' + width: 1 + - TXDMAE: + access: rw + description: Transmit DMA Enable + lsb: 1 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/usb.yaml b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/usb.yaml new file mode 100644 index 00000000..658a8063 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/usb.yaml @@ -0,0 +1,1416 @@ +!!omap +- USB0_CAPLENGTH: + fields: !!omap + - CAPLENGTH: + access: r + description: Indicates offset to add to the register base address at the beginning + of the Operational Register + lsb: 0 + reset_value: '0x40' + width: 8 + - HCIVERSION: + access: r + description: BCD encoding of the EHCI revision number supported by this host + controller + lsb: 8 + reset_value: '0x100' + width: 16 +- USB0_HCSPARAMS: + fields: !!omap + - N_PORTS: + access: r + description: Number of downstream ports + lsb: 0 + reset_value: '0x1' + width: 4 + - PPC: + access: r + description: Port Power Control + lsb: 4 + reset_value: '0x1' + width: 1 + - N_PCC: + access: r + description: Number of Ports per Companion Controller + lsb: 8 + reset_value: '0x0' + width: 4 + - N_CC: + access: r + description: Number of Companion Controller + lsb: 12 + reset_value: '0x0' + width: 4 + - PI: + access: r + description: Port indicators + lsb: 16 + reset_value: '0x1' + width: 1 + - N_PTT: + access: r + description: Number of Ports per Transaction Translator + lsb: 20 + reset_value: '0x0' + width: 4 + - N_TT: + access: r + description: Number of Transaction Translators + lsb: 24 + reset_value: '0x0' + width: 4 +- USB0_HCCPARAMS: + fields: !!omap + - ADC: + access: r + description: 64-bit Addressing Capability + lsb: 0 + reset_value: '0' + width: 1 + - PFL: + access: r + description: Programmable Frame List Flag + lsb: 1 + reset_value: '1' + width: 1 + - ASP: + access: r + description: Asynchronous Schedule Park Capability + lsb: 2 + reset_value: '1' + width: 1 + - IST: + access: r + description: Isochronous Scheduling Threshold + lsb: 4 + reset_value: '0' + width: 4 + - EECP: + access: r + description: EHCI Extended Capabilities Pointer + lsb: 8 + reset_value: '0' + width: 4 +- USB0_DCCPARAMS: + fields: !!omap + - DEN: + access: r + description: Device Endpoint Number + lsb: 0 + reset_value: '0x4' + width: 5 + - DC: + access: r + description: Device Capable + lsb: 7 + reset_value: '0x1' + width: 1 + - HC: + access: r + description: Host Capable + lsb: 8 + reset_value: '0x1' + width: 1 +- USB0_USBCMD_D: + fields: !!omap + - RS: + access: rw + description: Run/Stop + lsb: 0 + reset_value: '0' + width: 1 + - RST: + access: rw + description: Controller reset + lsb: 1 + reset_value: '0' + width: 1 + - SUTW: + access: rw + description: Setup trip wire + lsb: 13 + reset_value: '0' + width: 1 + - ATDTW: + access: rw + description: Add dTD trip wire + lsb: 14 + reset_value: '0' + width: 1 + - ITC: + access: rw + description: Interrupt threshold control + lsb: 16 + reset_value: '0x8' + width: 8 +- USB0_USBCMD_H: + fields: !!omap + - RS: + access: rw + description: Run/Stop + lsb: 0 + reset_value: '0' + width: 1 + - RST: + access: rw + description: Controller reset + lsb: 1 + reset_value: '0' + width: 1 + - FS0: + access: '' + description: Bit 0 of the Frame List Size bits + lsb: 2 + reset_value: '0' + width: 1 + - FS1: + access: '' + description: Bit 1 of the Frame List Size bits + lsb: 3 + reset_value: '0' + width: 1 + - PSE: + access: rw + description: This bit controls whether the host controller skips processing + the periodic schedule + lsb: 4 + reset_value: '0' + width: 1 + - ASE: + access: rw + description: This bit controls whether the host controller skips processing + the asynchronous schedule + lsb: 5 + reset_value: '0' + width: 1 + - IAA: + access: rw + description: This bit is used as a doorbell by software to tell the host controller + to issue an interrupt the next time it advances asynchronous schedule + lsb: 6 + reset_value: '0' + width: 1 + - ASP1_0: + access: rw + description: Asynchronous schedule park mode + lsb: 8 + reset_value: '0x3' + width: 2 + - ASPE: + access: rw + description: Asynchronous Schedule Park Mode Enable + lsb: 11 + reset_value: '1' + width: 1 + - FS2: + access: '' + description: Bit 2 of the Frame List Size bits + lsb: 15 + reset_value: '0' + width: 1 + - ITC: + access: rw + description: Interrupt threshold control + lsb: 16 + reset_value: '0x8' + width: 8 +- USB0_USBSTS_D: + fields: !!omap + - UI: + access: rwc + description: USB interrupt + lsb: 0 + reset_value: '0' + width: 1 + - UEI: + access: rwc + description: USB error interrupt + lsb: 1 + reset_value: '0' + width: 1 + - PCI: + access: rwc + description: Port change detect + lsb: 2 + reset_value: '0' + width: 1 + - URI: + access: rwc + description: USB reset received + lsb: 6 + reset_value: '0' + width: 1 + - SRI: + access: rwc + description: SOF received + lsb: 7 + reset_value: '0' + width: 1 + - SLI: + access: rwc + description: DCSuspend + lsb: 8 + reset_value: '0' + width: 1 + - NAKI: + access: r + description: NAK interrupt bit + lsb: 16 + reset_value: '0' + width: 1 +- USB0_USBSTS_H: + fields: !!omap + - UI: + access: rwc + description: USB interrupt + lsb: 0 + reset_value: '0' + width: 1 + - UEI: + access: rwc + description: USB error interrupt + lsb: 1 + reset_value: '0' + width: 1 + - PCI: + access: rwc + description: Port change detect + lsb: 2 + reset_value: '0' + width: 1 + - FRI: + access: rwc + description: Frame list roll-over + lsb: 3 + reset_value: '0' + width: 1 + - AAI: + access: rwc + description: Interrupt on async advance + lsb: 5 + reset_value: '0' + width: 1 + - SRI: + access: rwc + description: SOF received + lsb: 7 + reset_value: '0' + width: 1 + - HCH: + access: r + description: HCHalted + lsb: 12 + reset_value: '1' + width: 1 + - RCL: + access: r + description: Reclamation + lsb: 13 + reset_value: '0' + width: 1 + - PS: + access: r + description: Periodic schedule status + lsb: 14 + reset_value: '0' + width: 1 + - AS: + access: '' + description: Asynchronous schedule status + lsb: 15 + reset_value: '0' + width: 1 + - UAI: + access: rwc + description: USB host asynchronous interrupt (USBHSTASYNCINT) + lsb: 18 + reset_value: '0' + width: 1 + - UPI: + access: rwc + description: USB host periodic interrupt (USBHSTPERINT) + lsb: 19 + reset_value: '0' + width: 1 +- USB0_USBINTR_D: + fields: !!omap + - UE: + access: rw + description: USB interrupt enable + lsb: 0 + reset_value: '0' + width: 1 + - UEE: + access: rw + description: USB error interrupt enable + lsb: 1 + reset_value: '0' + width: 1 + - PCE: + access: rw + description: Port change detect enable + lsb: 2 + reset_value: '0' + width: 1 + - URE: + access: rw + description: USB reset enable + lsb: 6 + reset_value: '0' + width: 1 + - SRE: + access: rw + description: SOF received enable + lsb: 7 + reset_value: '0' + width: 1 + - SLE: + access: rw + description: Sleep enable + lsb: 8 + reset_value: '0' + width: 1 + - NAKE: + access: rw + description: NAK interrupt enable + lsb: 16 + reset_value: '0' + width: 1 +- USB0_USBINTR_H: + fields: !!omap + - UE: + access: rw + description: USB interrupt enable + lsb: 0 + reset_value: '0' + width: 1 + - UEE: + access: rw + description: USB error interrupt enable + lsb: 1 + reset_value: '0' + width: 1 + - PCE: + access: rw + description: Port change detect enable + lsb: 2 + reset_value: '0' + width: 1 + - FRE: + access: rw + description: Frame list rollover enable + lsb: 3 + reset_value: '0' + width: 1 + - AAE: + access: rw + description: Interrupt on asynchronous advance enable + lsb: 5 + reset_value: '0' + width: 1 + - SRE: + access: '' + description: SOF received enable + lsb: 7 + reset_value: '0' + width: 1 + - UAIE: + access: rw + description: USB host asynchronous interrupt enable + lsb: 18 + reset_value: '0' + width: 1 + - UPIA: + access: rw + description: USB host periodic interrupt enable + lsb: 19 + reset_value: '0' + width: 1 +- USB0_FRINDEX_D: + fields: !!omap + - FRINDEX2_0: + access: r + description: Current micro frame number + lsb: 0 + reset_value: '' + width: 3 + - FRINDEX13_3: + access: r + description: Current frame number of the last frame transmitted + lsb: 3 + reset_value: '' + width: 11 +- USB0_FRINDEX_H: + fields: !!omap + - FRINDEX2_0: + access: rw + description: Current micro frame number + lsb: 0 + reset_value: '' + width: 3 + - FRINDEX12_3: + access: rw + description: Frame list current index + lsb: 3 + reset_value: '' + width: 10 +- USB0_DEVICEADDR: + fields: !!omap + - USBADRA: + access: '' + description: Device address advance + lsb: 24 + reset_value: '0' + width: 1 + - USBADR: + access: rw + description: USB device address + lsb: 25 + reset_value: '0' + width: 7 +- USB0_PERIODICLISTBASE: + fields: !!omap + - PERBASE31_12: + access: rw + description: Base Address (Low) + lsb: 12 + reset_value: '' + width: 20 +- USB0_ENDPOINTLISTADDR: + fields: !!omap + - EPBASE31_11: + access: rw + description: Endpoint list pointer (low) + lsb: 11 + reset_value: '' + width: 21 +- USB0_ASYNCLISTADDR: + fields: !!omap + - ASYBASE31_5: + access: rw + description: Link pointer (Low) LPL + lsb: 5 + reset_value: '' + width: 27 +- USB0_TTCTRL: + fields: !!omap + - TTHA: + access: rw + description: Hub address when FS or LS device are connected directly + lsb: 24 + reset_value: '' + width: 7 +- USB0_BURSTSIZE: + fields: !!omap + - RXPBURST: + access: rw + description: Programmable RX burst length + lsb: 0 + reset_value: '0x10' + width: 8 + - TXPBURST: + access: rw + description: Programmable TX burst length + lsb: 8 + reset_value: '0x10' + width: 8 +- USB0_TXFILLTUNING: + fields: !!omap + - TXSCHOH: + access: rw + description: FIFO burst threshold + lsb: 0 + reset_value: '0x2' + width: 8 + - TXSCHEATLTH: + access: rw + description: Scheduler health counter + lsb: 8 + reset_value: '0x0' + width: 5 + - TXFIFOTHRES: + access: rw + description: Scheduler overhead + lsb: 16 + reset_value: '0x0' + width: 6 +- USB0_BINTERVAL: + fields: !!omap + - BINT: + access: rw + description: bInterval value + lsb: 0 + reset_value: '0x00' + width: 4 +- USB0_ENDPTNAK: + fields: !!omap + - EPRN: + access: rwc + description: Rx endpoint NAK + lsb: 0 + reset_value: '0x00' + width: 6 + - EPTN: + access: rwc + description: Tx endpoint NAK + lsb: 16 + reset_value: '0x00' + width: 6 +- USB0_ENDPTNAKEN: + fields: !!omap + - EPRNE: + access: rw + description: Rx endpoint NAK enable + lsb: 0 + reset_value: '0x00' + width: 6 + - EPTNE: + access: rw + description: Tx endpoint NAK + lsb: 16 + reset_value: '0x00' + width: 6 +- USB0_PORTSC1_D: + fields: !!omap + - CCS: + access: r + description: Current connect status + lsb: 0 + reset_value: '0' + width: 1 + - PE: + access: r + description: Port enable + lsb: 2 + reset_value: '1' + width: 1 + - PEC: + access: r + description: Port enable/disable change + lsb: 3 + reset_value: '0' + width: 1 + - FPR: + access: rw + description: Force port resume + lsb: 6 + reset_value: '0' + width: 1 + - SUSP: + access: r + description: Suspend + lsb: 7 + reset_value: '0' + width: 1 + - PR: + access: r + description: Port reset + lsb: 8 + reset_value: '0' + width: 1 + - HSP: + access: r + description: High-speed status + lsb: 9 + reset_value: '0' + width: 1 + - PIC1_0: + access: rw + description: Port indicator control + lsb: 14 + reset_value: '0' + width: 2 + - PTC3_0: + access: rw + description: Port test control + lsb: 16 + reset_value: '0' + width: 4 + - PHCD: + access: rw + description: PHY low power suspend - clock disable (PLPSCD) + lsb: 23 + reset_value: '0' + width: 1 + - PFSC: + access: rw + description: Port force full speed connect + lsb: 24 + reset_value: '0' + width: 1 + - PSPD: + access: r + description: Port speed + lsb: 26 + reset_value: '0' + width: 2 +- USB0_PORTSC1_H: + fields: !!omap + - CCS: + access: rwc + description: Current connect status + lsb: 0 + reset_value: '0' + width: 1 + - CSC: + access: rwc + description: Connect status change + lsb: 1 + reset_value: '0' + width: 1 + - PE: + access: rw + description: Port enable + lsb: 2 + reset_value: '0' + width: 1 + - PEC: + access: rwc + description: Port disable/enable change + lsb: 3 + reset_value: '0' + width: 1 + - OCA: + access: r + description: Over-current active + lsb: 4 + reset_value: '0' + width: 1 + - OCC: + access: rwc + description: Over-current change + lsb: 5 + reset_value: '0' + width: 1 + - FPR: + access: rw + description: Force port resume + lsb: 6 + reset_value: '0' + width: 1 + - SUSP: + access: rw + description: Suspend + lsb: 7 + reset_value: '0' + width: 1 + - PR: + access: rw + description: Port reset + lsb: 8 + reset_value: '0' + width: 1 + - HSP: + access: r + description: High-speed status + lsb: 9 + reset_value: '0' + width: 1 + - LS: + access: r + description: Line status + lsb: 10 + reset_value: '0x3' + width: 2 + - PP: + access: rw + description: Port power control + lsb: 12 + reset_value: '0' + width: 1 + - PIC1_0: + access: rw + description: Port indicator control + lsb: 14 + reset_value: '0' + width: 2 + - PTC3_0: + access: rw + description: Port test control + lsb: 16 + reset_value: '0' + width: 4 + - WKCN: + access: rw + description: Wake on connect enable (WKCNNT_E) + lsb: 20 + reset_value: '0' + width: 1 + - WKDC: + access: rw + description: Wake on disconnect enable (WKDSCNNT_E) + lsb: 21 + reset_value: '0' + width: 1 + - WKOC: + access: rw + description: Wake on over-current enable (WKOC_E) + lsb: 22 + reset_value: '0' + width: 1 + - PHCD: + access: rw + description: PHY low power suspend - clock disable (PLPSCD) + lsb: 23 + reset_value: '0' + width: 1 + - PFSC: + access: rw + description: Port force full speed connect + lsb: 24 + reset_value: '0' + width: 1 + - PSPD: + access: r + description: Port speed + lsb: 26 + reset_value: '0' + width: 2 +- USB0_OTGSC: + fields: !!omap + - VD: + access: rw + description: VBUS_Discharge + lsb: 0 + reset_value: '0' + width: 1 + - VC: + access: rw + description: VBUS_Charge + lsb: 1 + reset_value: '0' + width: 1 + - HAAR: + access: rw + description: Hardware assist auto_reset + lsb: 2 + reset_value: '0' + width: 1 + - OT: + access: rw + description: OTG termination + lsb: 3 + reset_value: '0' + width: 1 + - DP: + access: rw + description: Data pulsing + lsb: 4 + reset_value: '0' + width: 1 + - IDPU: + access: rw + description: ID pull-up + lsb: 5 + reset_value: '1' + width: 1 + - HADP: + access: rw + description: Hardware assist data pulse + lsb: 6 + reset_value: '0' + width: 1 + - HABA: + access: rw + description: Hardware assist B-disconnect to A-connect + lsb: 7 + reset_value: '0' + width: 1 + - ID: + access: r + description: USB ID + lsb: 8 + reset_value: '0' + width: 1 + - AVV: + access: r + description: A-VBUS valid + lsb: 9 + reset_value: '0' + width: 1 + - ASV: + access: r + description: A-session valid + lsb: 10 + reset_value: '0' + width: 1 + - BSV: + access: r + description: B-session valid + lsb: 11 + reset_value: '0' + width: 1 + - BSE: + access: r + description: B-session end + lsb: 12 + reset_value: '0' + width: 1 + - MS1T: + access: r + description: 1 millisecond timer toggle + lsb: 13 + reset_value: '0' + width: 1 + - DPS: + access: r + description: Data bus pulsing status + lsb: 14 + reset_value: '0' + width: 1 + - IDIS: + access: rwc + description: USB ID interrupt status + lsb: 16 + reset_value: '0' + width: 1 + - AVVIS: + access: rwc + description: A-VBUS valid interrupt status + lsb: 17 + reset_value: '0' + width: 1 + - ASVIS: + access: rwc + description: A-Session valid interrupt status + lsb: 18 + reset_value: '0' + width: 1 + - BSVIS: + access: rwc + description: B-Session valid interrupt status + lsb: 19 + reset_value: '0' + width: 1 + - BSEIS: + access: rwc + description: B-Session end interrupt status + lsb: 20 + reset_value: '0' + width: 1 + - MS1S: + access: rwc + description: 1 millisecond timer interrupt status + lsb: 21 + reset_value: '0' + width: 1 + - DPIS: + access: rwc + description: Data pulse interrupt status + lsb: 22 + reset_value: '0' + width: 1 + - IDIE: + access: rw + description: USB ID interrupt enable + lsb: 24 + reset_value: '0' + width: 1 + - AVVIE: + access: rw + description: A-VBUS valid interrupt enable + lsb: 25 + reset_value: '0' + width: 1 + - ASVIE: + access: rw + description: A-session valid interrupt enable + lsb: 26 + reset_value: '0' + width: 1 + - BSVIE: + access: rw + description: B-session valid interrupt enable + lsb: 27 + reset_value: '0' + width: 1 + - BSEIE: + access: rw + description: B-session end interrupt enable + lsb: 28 + reset_value: '0' + width: 1 + - MS1E: + access: rw + description: 1 millisecond timer interrupt enable + lsb: 29 + reset_value: '0' + width: 1 + - DPIE: + access: rw + description: Data pulse interrupt enable + lsb: 30 + reset_value: '0' + width: 1 +- USB0_USBMODE_D: + fields: !!omap + - CM1_0: + access: rwo + description: Controller mode + lsb: 0 + reset_value: '0' + width: 2 + - ES: + access: rw + description: Endian select + lsb: 2 + reset_value: '0' + width: 1 + - SLOM: + access: rw + description: Setup Lockout mode + lsb: 3 + reset_value: '0' + width: 1 + - SDIS: + access: rw + description: Setup Lockout mode + lsb: 4 + reset_value: '0' + width: 1 +- USB0_USBMODE_H: + fields: !!omap + - CM: + access: rwo + description: Controller mode + lsb: 0 + reset_value: '0' + width: 2 + - ES: + access: rw + description: Endian select + lsb: 2 + reset_value: '0' + width: 1 + - SDIS: + access: rw + description: Stream disable mode + lsb: 4 + reset_value: '0' + width: 1 + - VBPS: + access: rwo + description: VBUS power select + lsb: 5 + reset_value: '0' + width: 1 +- USB0_ENDPTSETUPSTAT: + fields: !!omap + - ENDPTSETUPSTAT: + access: rwc + description: Setup endpoint status for logical endpoints 0 to 5 + lsb: 0 + reset_value: '0' + width: 6 +- USB0_ENDPTPRIME: + fields: !!omap + - PERB: + access: rws + description: Prime endpoint receive buffer for physical OUT endpoints 5 to + 0 + lsb: 0 + reset_value: '0' + width: 6 + - PETB: + access: rws + description: Prime endpoint transmit buffer for physical IN endpoints 5 to + 0 + lsb: 16 + reset_value: '0' + width: 6 +- USB0_ENDPTFLUSH: + fields: !!omap + - FERB: + access: rwc + description: Flush endpoint receive buffer for physical OUT endpoints 5 to + 0 + lsb: 0 + reset_value: '0' + width: 6 + - FETB: + access: rwc + description: Flush endpoint transmit buffer for physical IN endpoints 5 to + 0 + lsb: 16 + reset_value: '0' + width: 6 +- USB0_ENDPTSTAT: + fields: !!omap + - ERBR: + access: r + description: Endpoint receive buffer ready for physical OUT endpoints 5 to + 0 + lsb: 0 + reset_value: '0' + width: 6 + - ETBR: + access: r + description: Endpoint transmit buffer ready for physical IN endpoints 3 to + 0 + lsb: 16 + reset_value: '0' + width: 6 +- USB0_ENDPTCOMPLETE: + fields: !!omap + - ERCE: + access: rwc + description: Endpoint receive complete event for physical OUT endpoints 5 + to 0 + lsb: 0 + reset_value: '0' + width: 6 + - ETCE: + access: rwc + description: Endpoint transmit complete event for physical IN endpoints 5 + to 0 + lsb: 16 + reset_value: '0' + width: 6 +- USB0_ENDPTCTRL0: + fields: !!omap + - RXS: + access: rw + description: Rx endpoint stall + lsb: 0 + reset_value: '0' + width: 1 + - RXT1_0: + access: rw + description: Endpoint type + lsb: 2 + reset_value: '0' + width: 2 + - RXE: + access: r + description: Rx endpoint enable + lsb: 7 + reset_value: '1' + width: 1 + - TXS: + access: rw + description: Tx endpoint stall + lsb: 16 + reset_value: '' + width: 1 + - TXT1_0: + access: r + description: Endpoint type + lsb: 18 + reset_value: '0' + width: 2 + - TXE: + access: r + description: Tx endpoint enable + lsb: 23 + reset_value: '1' + width: 1 +- USB0_ENDPTCTRL1: + fields: !!omap + - RXS: + access: rw + description: Rx endpoint stall + lsb: 0 + reset_value: '0' + width: 1 + - RXT: + access: rw + description: Endpoint type + lsb: 2 + reset_value: '0' + width: 2 + - RXI: + access: rw + description: Rx data toggle inhibit + lsb: 5 + reset_value: '0' + width: 1 + - RXR: + access: ws + description: Rx data toggle reset + lsb: 6 + reset_value: '0' + width: 1 + - RXE: + access: rw + description: Rx endpoint enable + lsb: 7 + reset_value: '0' + width: 1 + - TXS: + access: rw + description: Tx endpoint stall + lsb: 16 + reset_value: '0' + width: 1 + - TXT1_0: + access: r + description: Tx Endpoint type + lsb: 18 + reset_value: '0' + width: 2 + - TXI: + access: rw + description: Tx data toggle inhibit + lsb: 21 + reset_value: '0' + width: 1 + - TXR: + access: ws + description: Tx data toggle reset + lsb: 22 + reset_value: '1' + width: 1 + - TXE: + access: r + description: Tx endpoint enable + lsb: 23 + reset_value: '0' + width: 1 +- USB0_ENDPTCTRL2: + fields: !!omap + - RXS: + access: rw + description: Rx endpoint stall + lsb: 0 + reset_value: '0' + width: 1 + - RXT: + access: rw + description: Endpoint type + lsb: 2 + reset_value: '0' + width: 2 + - RXI: + access: rw + description: Rx data toggle inhibit + lsb: 5 + reset_value: '0' + width: 1 + - RXR: + access: ws + description: Rx data toggle reset + lsb: 6 + reset_value: '0' + width: 1 + - RXE: + access: rw + description: Rx endpoint enable + lsb: 7 + reset_value: '0' + width: 1 + - TXS: + access: rw + description: Tx endpoint stall + lsb: 16 + reset_value: '0' + width: 1 + - TXT1_0: + access: r + description: Tx Endpoint type + lsb: 18 + reset_value: '0' + width: 2 + - TXI: + access: rw + description: Tx data toggle inhibit + lsb: 21 + reset_value: '0' + width: 1 + - TXR: + access: ws + description: Tx data toggle reset + lsb: 22 + reset_value: '1' + width: 1 + - TXE: + access: r + description: Tx endpoint enable + lsb: 23 + reset_value: '0' + width: 1 +- USB0_ENDPTCTRL3: + fields: !!omap + - RXS: + access: rw + description: Rx endpoint stall + lsb: 0 + reset_value: '0' + width: 1 + - RXT: + access: rw + description: Endpoint type + lsb: 2 + reset_value: '0' + width: 2 + - RXI: + access: rw + description: Rx data toggle inhibit + lsb: 5 + reset_value: '0' + width: 1 + - RXR: + access: ws + description: Rx data toggle reset + lsb: 6 + reset_value: '0' + width: 1 + - RXE: + access: rw + description: Rx endpoint enable + lsb: 7 + reset_value: '0' + width: 1 + - TXS: + access: rw + description: Tx endpoint stall + lsb: 16 + reset_value: '0' + width: 1 + - TXT1_0: + access: r + description: Tx Endpoint type + lsb: 18 + reset_value: '0' + width: 2 + - TXI: + access: rw + description: Tx data toggle inhibit + lsb: 21 + reset_value: '0' + width: 1 + - TXR: + access: ws + description: Tx data toggle reset + lsb: 22 + reset_value: '1' + width: 1 + - TXE: + access: r + description: Tx endpoint enable + lsb: 23 + reset_value: '0' + width: 1 +- USB0_ENDPTCTRL4: + fields: !!omap + - RXS: + access: rw + description: Rx endpoint stall + lsb: 0 + reset_value: '0' + width: 1 + - RXT: + access: rw + description: Endpoint type + lsb: 2 + reset_value: '0' + width: 2 + - RXI: + access: rw + description: Rx data toggle inhibit + lsb: 5 + reset_value: '0' + width: 1 + - RXR: + access: ws + description: Rx data toggle reset + lsb: 6 + reset_value: '0' + width: 1 + - RXE: + access: rw + description: Rx endpoint enable + lsb: 7 + reset_value: '0' + width: 1 + - TXS: + access: rw + description: Tx endpoint stall + lsb: 16 + reset_value: '0' + width: 1 + - TXT1_0: + access: r + description: Tx Endpoint type + lsb: 18 + reset_value: '0' + width: 2 + - TXI: + access: rw + description: Tx data toggle inhibit + lsb: 21 + reset_value: '0' + width: 1 + - TXR: + access: ws + description: Tx data toggle reset + lsb: 22 + reset_value: '1' + width: 1 + - TXE: + access: r + description: Tx endpoint enable + lsb: 23 + reset_value: '0' + width: 1 +- USB0_ENDPTCTRL5: + fields: !!omap + - RXS: + access: rw + description: Rx endpoint stall + lsb: 0 + reset_value: '0' + width: 1 + - RXT: + access: rw + description: Endpoint type + lsb: 2 + reset_value: '0' + width: 2 + - RXI: + access: rw + description: Rx data toggle inhibit + lsb: 5 + reset_value: '0' + width: 1 + - RXR: + access: ws + description: Rx data toggle reset + lsb: 6 + reset_value: '0' + width: 1 + - RXE: + access: rw + description: Rx endpoint enable + lsb: 7 + reset_value: '0' + width: 1 + - TXS: + access: rw + description: Tx endpoint stall + lsb: 16 + reset_value: '0' + width: 1 + - TXT1_0: + access: r + description: Tx Endpoint type + lsb: 18 + reset_value: '0' + width: 2 + - TXI: + access: rw + description: Tx data toggle inhibit + lsb: 21 + reset_value: '0' + width: 1 + - TXR: + access: ws + description: Tx data toggle reset + lsb: 22 + reset_value: '1' + width: 1 + - TXE: + access: r + description: Tx endpoint enable + lsb: 23 + reset_value: '0' + width: 1 diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/yaml_odict.py b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/yaml_odict.py new file mode 100644 index 00000000..05aa2697 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/data/lpc43xx/yaml_odict.py @@ -0,0 +1,81 @@ +import yaml +from collections import OrderedDict +def construct_odict(load, node): + """This is the same as SafeConstructor.construct_yaml_omap(), + except the data type is changed to OrderedDict() and setitem is + used instead of append in the loop. + + >>> yaml.load(''' + ... !!omap + ... - foo: bar + ... - mumble: quux + ... - baz: gorp + ... ''') + OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')]) + + >>> yaml.load('''!!omap [ foo: bar, mumble: quux, baz : gorp ]''') + OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')]) + """ + + omap = OrderedDict() + yield omap + if not isinstance(node, yaml.SequenceNode): + raise yaml.constructor.ConstructorError( + "while constructing an ordered map", + node.start_mark, + "expected a sequence, but found %s" % node.id, node.start_mark + ) + for subnode in node.value: + if not isinstance(subnode, yaml.MappingNode): + raise yaml.constructor.ConstructorError( + "while constructing an ordered map", node.start_mark, + "expected a mapping of length 1, but found %s" % subnode.id, + subnode.start_mark + ) + if len(subnode.value) != 1: + raise yaml.constructor.ConstructorError( + "while constructing an ordered map", node.start_mark, + "expected a single mapping item, but found %d items" % len(subnode.value), + subnode.start_mark + ) + key_node, value_node = subnode.value[0] + key = load.construct_object(key_node) + value = load.construct_object(value_node) + omap[key] = value + +yaml.add_constructor(u'tag:yaml.org,2002:omap', construct_odict) + +def repr_pairs(dump, tag, sequence, flow_style=None): + """This is the same code as BaseRepresenter.represent_sequence(), + but the value passed to dump.represent_data() in the loop is a + dictionary instead of a tuple.""" + + value = [] + node = yaml.SequenceNode(tag, value, flow_style=flow_style) + if dump.alias_key is not None: + dump.represented_objects[dump.alias_key] = node + best_style = True + for (key, val) in sequence: + item = dump.represent_data({key: val}) + if not (isinstance(item, yaml.ScalarNode) and not item.style): + best_style = False + value.append(item) + if flow_style is None: + if dump.default_flow_style is not None: + node.flow_style = dump.default_flow_style + else: + node.flow_style = best_style + return node + +def repr_odict(dumper, data): + """ + >>> data = OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')]) + >>> yaml.dump(data, default_flow_style=False) + '!!omap\\n- foo: bar\\n- mumble: quux\\n- baz: gorp\\n' + >>> yaml.dump(data, default_flow_style=True) + '!!omap [foo: bar, mumble: quux, baz: gorp]\\n' + """ + return repr_pairs(dumper, u'tag:yaml.org,2002:omap', data.iteritems()) + +yaml.add_representer(OrderedDict, repr_odict) + diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/genlink.awk b/hardware-wallet/firmware/vendor/libopencm3/scripts/genlink.awk new file mode 100644 index 00000000..2b7e9d12 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/genlink.awk @@ -0,0 +1,77 @@ +# This awk program generates parameters for the linker script generator feature. +# +# See ld/README file for more info. +# + +# This file is part of the libopencm3 project. +# +# Copyright (C) 2013 Frantisek Burian +# Copyright (C) 2013 Werner Almesberger +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +BEGIN { + PAT = tolower(PAT); + family = PAT; +} +!/^#/{ + #remove cr on windows + gsub(/\r$/,""); + + tmp = "^"$1"$"; + gsub(/\?/, ".", tmp); + gsub(/\*/, ".*", tmp); + gsub(/\+/, ".+", tmp); + tolower(tmp); + + if (PAT ~ tmp) { + if ("CPPFLAGS" == MODE) + printf "-D%s ",toupper(PAT); + if ($2 != "+") + PAT=$2; + for (i = 3; i <= NF; i = i + 1) { + if ($i ~ /^CPU=/) { + if ("CPU" == MODE){ + sub(/[^=]*=/,"",$i); + printf "%s",$i; + exit; + } + } + else if ($i ~ /^FPU=/) { + if ("FPU" == MODE){ + sub(/[^=]*=/,"",$i); + printf "%s",$i; + exit; + } + } + else if ($i ~ /[[:upper:]]*=/) { + if ("DEFS" == MODE) + printf "-D_%s ",$i; + } + } + if (PAT=="END"){ + if ("FAMILY" == MODE) + printf "%s",family; + else if ("SUBFAMILY" == MODE) + printf "%s",subfamily; + exit; + } + else{ + subfamily = family; + family = PAT; + if("DEFS" == MODE) + printf "-D%s ",toupper(PAT); + } + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/genlinktest.sh b/hardware-wallet/firmware/vendor/libopencm3/scripts/genlinktest.sh new file mode 100755 index 00000000..51176205 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/genlinktest.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# This script is intended to test the awk program genlink.awk for the linker +# script generator feature. +# +# See ld/README file for more info. +# + +# This file is part of the libopencm3 project. +# +# Copyright (C) 2013 Frantisek Burian +# Copyright (C) 2013 Werner Almesberger +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# run test +PAAT=`basename $1`; +awk -v PAT="$PAAT" -f scripts/genlink.awk $1.data > $1.out; + +#check test +if ! diff -q $1.out $1.result >/dev/null; then + exit 1; +fi + +#remove workout only if it is OK +rm -f $1.out + +exit 0 \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/irq2nvic_h b/hardware-wallet/firmware/vendor/libopencm3/scripts/irq2nvic_h new file mode 100755 index 00000000..0a99603c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/irq2nvic_h @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +# This file is part of the libopencm3 project. +# +# Copyright (C) 2012 chrysn +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +"""Generate an nvic.h header from a small JSON file describing the interrupt +numbers. + +Code generation is chosen here because the resulting C code needs to be very +repetetive (definition of the IRQ numbers, function prototypes, weak fallback +definition and vector table definition), all being very repetitive. No portable +method to achieve the same thing with C preprocessor is known to the author. +(Neither is any non-portable method, for that matter.)""" + +import sys +import os +import os.path +import json + +template_nvic_h = '''\ +/* This file is part of the libopencm3 project. + * + * It was generated by the irq2nvic_h script. + */ + +#ifndef {includeguard} +#define {includeguard} + +#include + +/** @defgroup CM3_nvic_defines_{partname_doxygen} User interrupts for {partname_humanreadable} + @ingroup CM3_nvic_defines + + @{{*/ + +{irqdefinitions} + +#define NVIC_IRQ_COUNT {irqcount} + +/**@}}*/ + +/** @defgroup CM3_nvic_isrprototypes_{partname_doxygen} User interrupt service routines (ISR) prototypes for {partname_humanreadable} + @ingroup CM3_nvic_isrprototypes + + @{{*/ + +BEGIN_DECLS + +{isrprototypes} + +END_DECLS + +/**@}}*/ + +#endif /* {includeguard} */ +''' + +template_vector_nvic_c = '''\ +/* This file is part of the libopencm3 project. + * + * It was generated by the irq2nvic_h script. + * + * This part needs to get included in the compilation unit where + * blocking_handler gets defined due to the way #pragma works. + */ + + +/** @defgroup CM3_nvic_isrpragmas_{partname_doxygen} User interrupt service routines (ISR) defaults for {partname_humanreadable} + @ingroup CM3_nvic_isrpragmas + + @{{*/ + +{isrpragmas} + +/**@}}*/ + +/* Initialization template for the interrupt vector table. This definition is + * used by the startup code generator (vector.c) to set the initial values for + * the interrupt handling routines to the chip family specific _isr weak + * symbols. */ + +#define IRQ_HANDLERS \\ + {vectortableinitialization} +''' + +template_cmsis_h = '''\ +/* This file is part of the libopencm3 project. + * + * It was generated by the irq2nvic_h script. + * + * These definitions bend every interrupt handler that is defined CMSIS style + * to the weak symbol exported by libopencm3. + */ + +{cmsisbends} +''' + +def convert(infile, outfile_nvic, outfile_vectornvic, outfile_cmsis): + data = json.load(infile) + + irq2name = list(enumerate(data['irqs']) if isinstance(data['irqs'], list) else data['irqs'].items()) + irqnames = [v for (k,v) in irq2name] + + if isinstance(data['irqs'], list): + data['irqcount'] = len(irq2name) + else: + data['irqcount'] = max([int(x) for x in data['irqs'].keys()]) + 1 + + data['irqdefinitions'] = "\n".join('#define NVIC_%s_IRQ %d'%(v.upper(),int(k)) for (k,v) in irq2name) + data['isrprototypes'] = "\n".join('void %s_isr(void);'%name.lower() for name in irqnames) + data['isrpragmas'] = "\n".join('#pragma weak %s_isr = blocking_handler'%name.lower() for name in irqnames) + data['vectortableinitialization'] = ', \\\n '.join('[NVIC_%s_IRQ] = %s_isr'%(name.upper(), name.lower()) for name in irqnames) + data['cmsisbends'] = "\n".join("#define %s_IRQHandler %s_isr"%(name.upper(), name.lower()) for name in irqnames) + + outfile_nvic.write(template_nvic_h.format(**data)) + outfile_vectornvic.write(template_vector_nvic_c.format(**data)) + outfile_cmsis.write(template_cmsis_h.format(**data)) + +def makeparentdir(filename): + try: + os.makedirs(os.path.dirname(filename)) + except OSError: + # where is my 'mkdir -p'? + pass + +def needs_update(infiles, outfiles): + timestamp = lambda filename: os.stat(filename).st_mtime + return any(not os.path.exists(o) for o in outfiles) or max(map(timestamp, infiles)) > min(map(timestamp, outfiles)) + +def main(): + if sys.argv[1] == '--remove': + remove = True + del sys.argv[1] + else: + remove = False + infile = sys.argv[1] + if not infile.startswith('./include/libopencm3/') or not infile.endswith('/irq.json'): + raise ValueError("Argument must match ./include/libopencm3/**/irq.json") + nvic_h = infile.replace('irq.json', 'nvic.h') + vector_nvic_c = infile.replace('./include/libopencm3/', './lib/').replace('irq.json', 'vector_nvic.c') + cmsis = infile.replace('irq.json', 'irqhandlers.h').replace('/libopencm3/', '/libopencmsis/') + + if remove: + if os.path.exists(nvic_h): + os.unlink(nvic_h) + if os.path.exists(vector_nvic_c): + os.unlink(vector_nvic_c) + if os.path.exists(cmsis): + os.unlink(cmsis) + sys.exit(0) + + if not needs_update([__file__, infile], [nvic_h, vector_nvic_c]): + sys.exit(0) + + makeparentdir(nvic_h) + makeparentdir(vector_nvic_c) + makeparentdir(cmsis) + + convert(open(infile), open(nvic_h, 'w'), open(vector_nvic_c, 'w'), open(cmsis, 'w')) + +if __name__ == "__main__": + main() diff --git a/hardware-wallet/firmware/vendor/libopencm3/scripts/lpcvtcksum b/hardware-wallet/firmware/vendor/libopencm3/scripts/lpcvtcksum new file mode 100755 index 00000000..27dc8a77 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/scripts/lpcvtcksum @@ -0,0 +1,51 @@ +#!/usr/bin/python +# +# Compute and insert the vector table checksum required for booting the +# LPC43xx and some other NXP ARM microcontrollers. +# +# usage: lpcvtcksum firmware.bin +# +# This file is part of the libopencm3 project. +# +# Copyright (C) 2012 Michael Ossmann +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +import sys, struct + +binfile = open(sys.argv[1], 'r+b') +rawvectors = binfile.read(32) +vectors = list(struct.unpack('. +## + +BOARD = stm32f072disco +PROJECT = usb-gadget0-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../shared + +CFILES = main-$(BOARD).c +CFILES += usb-gadget0.c +CFILES += delay.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../.. + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../lib/stm32/f0/stm32f07xzb.ld +OPENCM3_LIB = opencm3_stm32f0 +OPENCM3_DEFS = -DSTM32F0 +#FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +ARCH_FLAGS = -mthumb -mcpu=cortex-m0 $(FP_FLAGS) +#OOCD_INTERFACE = stlink-v2 +#OOCD_TARGET = stm32f4x +OOCD_FILE = openocd.stm32f072disco.cfg + +include ../rules.mk diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f103-generic b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f103-generic new file mode 100644 index 00000000..a27dd607 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f103-generic @@ -0,0 +1,43 @@ +## +## This file is part of the libopencm3 project. +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BOARD = stm32f103-generic +PROJECT = usb-gadget0-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../shared + +CFILES = main-$(BOARD).c +CFILES += usb-gadget0.c trace.c trace_stdio.c +CFILES += delay.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../../ + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../lib/stm32/f1/stm32f103x8.ld +OPENCM3_LIB = opencm3_stm32f1 +OPENCM3_DEFS = -DSTM32F1 +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 +#OOCD_INTERFACE = jlink +#OOCD_TARGET = stm32f1x +OOCD_FILE = openocd.stm32f103-generic.cfg + +include ../rules.mk diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f429i-disco b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f429i-disco new file mode 100644 index 00000000..d1c432fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f429i-disco @@ -0,0 +1,44 @@ +## +## This file is part of the libopencm3 project. +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BOARD = stm32f429i-disco +PROJECT = usb-gadget0-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../shared + +CFILES = main-$(BOARD).c +CFILES += usb-gadget0.c trace.c trace_stdio.c +CFILES += delay.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../.. + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../lib/stm32/f4/stm32f405x6.ld +OPENCM3_LIB = opencm3_stm32f4 +OPENCM3_DEFS = -DSTM32F4 +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) +#OOCD_INTERFACE = stlink-v2 +#OOCD_TARGET = stm32f4x +OOCD_FILE = openocd.$(BOARD).cfg + +include ../rules.mk diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f4disco b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f4disco new file mode 100644 index 00000000..ca737cb3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32f4disco @@ -0,0 +1,44 @@ +## +## This file is part of the libopencm3 project. +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BOARD = stm32f4disco +PROJECT = usb-gadget0-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../shared + +CFILES = main-$(BOARD).c +CFILES += usb-gadget0.c trace.c trace_stdio.c +CFILES += delay.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../.. + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../lib/stm32/f4/stm32f405x6.ld +OPENCM3_LIB = opencm3_stm32f4 +OPENCM3_DEFS = -DSTM32F4 +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) +#OOCD_INTERFACE = stlink-v2 +#OOCD_TARGET = stm32f4x +OOCD_FILE = openocd.stm32f4disco.cfg + +include ../rules.mk diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l053disco b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l053disco new file mode 100644 index 00000000..9c79127d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l053disco @@ -0,0 +1,44 @@ +## +## This file is part of the libopencm3 project. +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BOARD = stm32l053disco +PROJECT = usb-gadget0-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../shared + +CFILES = main-$(BOARD).c +CFILES += usb-gadget0.c +CFILES += delay.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../.. + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../lib/stm32/l0/stm32l0xx8.ld +OPENCM3_LIB = opencm3_stm32l0 +OPENCM3_DEFS = -DSTM32L0 +#FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +ARCH_FLAGS = -mthumb -mcpu=cortex-m0plus $(FP_FLAGS) +#OOCD_INTERFACE = stlink-v2-1 +#OOCD_TARGET = stm32l0 +OOCD_FILE = openocd.stm32l053disco.cfg + +include ../rules.mk diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l1-generic b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l1-generic new file mode 100644 index 00000000..17496378 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/Makefile.stm32l1-generic @@ -0,0 +1,43 @@ +## +## This file is part of the libopencm3 project. +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BOARD = stm32l1-generic +PROJECT = usb-gadget0-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../shared + +CFILES = main-$(BOARD).c +CFILES += usb-gadget0.c trace.c trace_stdio.c +CFILES += delay.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../.. + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../lib/stm32/l1/stm32l15xxb.ld +OPENCM3_LIB = opencm3_stm32l1 +OPENCM3_DEFS = -DSTM32L1 +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 +#OOCD_INTERFACE = jlink +#OOCD_TARGET = stm32l1x +OOCD_FILE = openocd.stm32l1-generic.cfg + +include ../rules.mk diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/README.md b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/README.md new file mode 100644 index 00000000..de30b242 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/README.md @@ -0,0 +1,51 @@ +This project, inspired by [usbtest](http://www.linux-usb.org/usbtest/) and +the linux usb gadget zero driver is used for regression testing changes to the +libopencm3 usb stack. + +The firmware itself is meant to be portable to any supported hardware, and then +identical unit test code is run against all platforms. This project can and +should be built for multiple devices. + +## Requirements: + * [pyusb](https://walac.github.io/pyusb/) for running the tests. + * [openocd](http://openocd.org/) >= 0.9 for automated flashing of specific boards + * python3 for running the tests at the command line. + +### Example using virtual environments +``` +pyvenv .env # ensures a python3 virtual env +. .env/bin/activate +pip install pyusb +``` + +You _will_ need to modify the openocd config files, as they contain specific +serial numbers of programming hardware. You should set these up for the set of +available boards at your disposal. + +Tests marked as @unittest.skip are either for functionality that is known to be +broken, and are awaiting code fixes, or are long running performance tests + +## Running the tests +Below is an example of running the full suite of tests from the command line. +The argument specifies the serial number to look for in the usb gadget, if +you have more than one. No argument will the tests against all +gadget-zero's found. +``` +$ python test_gadget0.py +Running tests for DUT: stm32f072disco +.........ss................ +---------------------------------------------------------------------- +Ran 27 tests in 0.388s + +OK (skipped=2) +``` + +To be even more brutal, run this in a shell loop. +``` +$ while true; do python test_gadget0.py stm32f072disco; done +``` + +You can also run individual tests, or individual sets of tests, see the [unittest documentation](https://docs.python.org/3/library/unittest.html) for more information. + +Many development environments, such as [PyCharm](https://www.jetbrains.com/pycharm/) can +also be used to edit and run the tests, in whole or individually, with a nice visual test runner. diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.c new file mode 100644 index 00000000..616c4823 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.c @@ -0,0 +1,50 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * This file implements some simple busy timers. They are designed to be + * portable, not performant. + * TIM6 is appropriated for usage. + */ +#include +#include +#include + +#include "delay.h" + +void delay_setup(void) +{ + /* set up a microsecond free running timer for ... things... */ + rcc_periph_clock_enable(RCC_TIM6); + /* microsecond counter */ + timer_set_prescaler(TIM6, rcc_apb1_frequency / 1e6 - 1); + timer_set_period(TIM6, 0xffff); + timer_one_shot_mode(TIM6); +} + +void delay_us(uint16_t us) +{ + TIM_ARR(TIM6) = us; + TIM_EGR(TIM6) = TIM_EGR_UG; + TIM_CR1(TIM6) |= TIM_CR1_CEN; + //timer_enable_counter(TIM6); + while (TIM_CR1(TIM6) & TIM_CR1_CEN); +} + + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.h b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.h new file mode 100644 index 00000000..b0915547 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/delay.h @@ -0,0 +1,39 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Initialize the timers used for delays. + */ + void delay_setup(void); + + /** + * busy wait for a number of usecs. + * @param us number of usecs to delay. + */ + void delay_us(uint16_t us); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f072disco.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f072disco.c new file mode 100644 index 00000000..4ee02b8d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f072disco.c @@ -0,0 +1,66 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include + +#include +#include "usb-gadget0.h" + +/* no trace on cm0 #define ER_DEBUG */ +#ifdef ER_DEBUG +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +#include "trace.h" +void trace_send_blocking8(int stimulus_port, char c) +{ + (void)stimulus_port; + (void)c; +} + + +int main(void) +{ + rcc_clock_setup_in_hsi48_out_48mhz(); + crs_autotrim_usb_enable(); + rcc_set_usbclk_source(RCC_HSI48); + + /* LED on for boot progress */ + rcc_periph_clock_enable(RCC_GPIOC); + gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7); + gpio_set(GPIOC, GPIO7); + + usbd_device *usbd_dev = gadget0_init(&st_usbfs_v2_usb_driver, + "stm32f072disco"); + + ER_DPRINTF("bootup complete\n"); + gpio_clear(GPIOC, GPIO7); + while (1) { + gadget0_run(usbd_dev); + } + +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f103-generic.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f103-generic.c new file mode 100644 index 00000000..27148806 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f103-generic.c @@ -0,0 +1,71 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +#include +#include "usb-gadget0.h" + +#define ER_DEBUG +#ifdef ER_DEBUG +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +int main(void) +{ + rcc_clock_setup_in_hse_8mhz_out_72mhz(); + /* LED to indicate boot process */ + rcc_periph_clock_enable(RCC_GPIOC); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); + gpio_set(GPIOC, GPIO13); + + rcc_periph_clock_enable(RCC_GPIOA); + /* + * Vile hack to reenumerate, physically _drag_ d+ low. + * do NOT do this if you're board has proper usb pull up control! + * (need at least 2.5us to trigger usb disconnect) + */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); + gpio_clear(GPIOA, GPIO11); + for (unsigned int i = 0; i < 800000; i++) { + __asm__("nop"); + } + + rcc_periph_clock_enable(RCC_OTGFS); + + + usbd_device *usbd_dev = gadget0_init(&st_usbfs_v1_usb_driver, + "stm32f103-generic"); + + ER_DPRINTF("bootup complete\n"); + gpio_clear(GPIOC, GPIO13); + while (1) { + gadget0_run(usbd_dev); + } + +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f429i-disco.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f429i-disco.c new file mode 100644 index 00000000..9109d927 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f429i-disco.c @@ -0,0 +1,59 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +#include +#include "usb-gadget0.h" + +#define ER_DEBUG +#ifdef ER_DEBUG +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +int main(void) +{ + rcc_clock_setup_hse_3v3(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]); + rcc_periph_clock_enable(RCC_GPIOB); + rcc_periph_clock_enable(RCC_OTGHS); + + gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, + GPIO13 | GPIO14 | GPIO15); + gpio_set_af(GPIOB, GPIO_AF12, GPIO13 | GPIO14 | GPIO15); + + /* LEDS on discovery board */ + rcc_periph_clock_enable(RCC_GPIOD); + gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, + GPIO_PUPD_NONE, GPIO12 | GPIO13 | GPIO14 | GPIO15); + + usbd_device *usbd_dev = gadget0_init(&otghs_usb_driver, "stm32f429i-disco"); + + ER_DPRINTF("bootup complete\n"); + while (1) { + gadget0_run(usbd_dev); + } + +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f4disco.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f4disco.c new file mode 100644 index 00000000..aea0598c --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32f4disco.c @@ -0,0 +1,59 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +#include +#include "usb-gadget0.h" + +#define ER_DEBUG +#ifdef ER_DEBUG +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +int main(void) +{ + rcc_clock_setup_hse_3v3(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]); + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_OTGFS); + + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, + GPIO9 | GPIO11 | GPIO12); + gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12); + + /* LEDS on discovery board */ + rcc_periph_clock_enable(RCC_GPIOD); + gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, + GPIO_PUPD_NONE, GPIO12 | GPIO13 | GPIO14 | GPIO15); + + usbd_device *usbd_dev = gadget0_init(&otgfs_usb_driver, "stm32f4disco"); + + ER_DPRINTF("bootup complete\n"); + while (1) { + gadget0_run(usbd_dev); + } + +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l053disco.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l053disco.c new file mode 100644 index 00000000..c90d739a --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l053disco.c @@ -0,0 +1,90 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include + +#include +#include "usb-gadget0.h" + +/* no trace on cm0 #define ER_DEBUG */ +#ifdef ER_DEBUG +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +#include "trace.h" +void trace_send_blocking8(int stimulus_port, char c) +{ + (void)stimulus_port; + (void)c; +} + +int main(void) +{ + /* LED for boot progress */ + rcc_periph_clock_enable(RCC_GPIOA); + gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO5); + gpio_set(GPIOA, GPIO5); + + /* PLL from HSI16, just to exercise that code */ + struct rcc_clock_scale myclock = { + .ahb_frequency = 32e6, + .apb1_frequency = 32e6, + .apb2_frequency = 32e6, + .flash_waitstates = 1, + .pll_source = RCC_CFGR_PLLSRC_HSI16_CLK, /* not even sure there's hse on l053 disco */ + /* .msi_range doesn't matter */ + .pll_mul = RCC_CFGR_PLLMUL_MUL4, + .pll_div = RCC_CFGR_PLLDIV_DIV2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE1_NODIV, + .ppre2 = RCC_CFGR_PPRE2_NODIV, + }; + rcc_clock_setup_pll(&myclock); + + /* HSI48 needs the vrefint turned on */ + rcc_periph_clock_enable(RCC_SYSCFG); + SYSCFG_CFGR3 |= SYSCFG_CFGR3_ENREF_HSI48 | SYSCFG_CFGR3_EN_VREFINT; + while (!(SYSCFG_CFGR3 & SYSCFG_CFGR3_REF_HSI48_RDYF)); + + /* For USB, but can't use HSI48 as a sysclock on L0 */ + crs_autotrim_usb_enable(); + rcc_set_hsi48_source_rc48(); + + rcc_osc_on(RCC_HSI48); + rcc_wait_for_osc_ready(RCC_HSI48); + + usbd_device *usbd_dev = gadget0_init(&st_usbfs_v2_usb_driver, + "stm32l053disco"); + + ER_DPRINTF("bootup complete\n"); + gpio_clear(GPIOA, GPIO5); + while (1) { + gadget0_run(usbd_dev); + } + +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l1-generic.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l1-generic.c new file mode 100644 index 00000000..28d1c600 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/main-stm32l1-generic.c @@ -0,0 +1,70 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include + +#include +#include "usb-gadget0.h" + +#define ER_DEBUG +#ifdef ER_DEBUG +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +const struct rcc_clock_scale this_clock_config = { + /* 32MHz PLL from 8MHz HSE */ + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .pll_mul = RCC_CFGR_PLLMUL_MUL12, + .pll_div = RCC_CFGR_PLLDIV_DIV3, + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_LATENCY_1WS, + .apb1_frequency = 32000000, + .apb2_frequency = 32000000, + }; + + +int main(void) +{ + rcc_clock_setup_pll(&this_clock_config); + /* LED on custom board for boot progress */ + rcc_periph_clock_enable(RCC_GPIOB); + gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO1); + gpio_set(GPIOB, GPIO1); + + usbd_device *usbd_dev = gadget0_init(&st_usbfs_v1_usb_driver, + "stm32l1-generic"); + + ER_DPRINTF("bootup complete\n"); + gpio_clear(GPIOB, GPIO1); + while (1) { + gadget0_run(usbd_dev); + } + +} + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.common.cfg b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.common.cfg new file mode 100644 index 00000000..b601cde2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.common.cfg @@ -0,0 +1,10 @@ +# Shared openocd script helpers + +# put things like "hla_serial 'asdfadfa'" in openocd..local.cfg to support +# multiple simultaneously connected boards. +proc optional_local { LOCAL_FILE } { + if { [ file exists $LOCAL_FILE ] } { + puts "Loading custom local settings from $LOCAL_FILE" + source $LOCAL_FILE + } +} diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f072disco.cfg b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f072disco.cfg new file mode 100644 index 00000000..b7cc25be --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f072disco.cfg @@ -0,0 +1,14 @@ +source [find interface/stlink-v2.cfg] +set WORKAREASIZE 0x4000 +source [find target/stm32f0x.cfg] + +source openocd.common.cfg +optional_local "openocd.stm32f072disco.local.cfg" + +# no trace on cm0 +#tpiu config internal swodump.stm32f4disco.log uart off 168000000 + +# Uncomment to reset on connect, for grabbing under WFI et al +reset_config srst_only srst_nogate +# reset_config srst_only srst_nogate connect_assert_srst + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f103-generic.cfg b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f103-generic.cfg new file mode 100644 index 00000000..c4d1183e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f103-generic.cfg @@ -0,0 +1,15 @@ +# Unfortunately, with no f103 disco, we're currently +# using a separate disco board +source [find interface/stlink-v2.cfg] +set WORKAREASIZE 0x2000 +source [find target/stm32f1x.cfg] + +source openocd.common.cfg +optional_local "openocd.stm32f103-generic.local.cfg" + +tpiu config internal swodump.stm32f103-generic.log uart off 72000000 + +# Uncomment to reset on connect, for grabbing under WFI et al +reset_config srst_only srst_nogate +# reset_config srst_only srst_nogate connect_assert_srst + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f429i-disco.cfg b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f429i-disco.cfg new file mode 100644 index 00000000..a0b99e6e --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f429i-disco.cfg @@ -0,0 +1,13 @@ +source [find interface/stlink-v2.cfg] +set WORKAREASIZE 0x4000 +source [find target/stm32f4x.cfg] + +source openocd.common.cfg +optional_local "openocd.stm32f429i-disco.local.cfg" + +tpiu config internal swodump.stm32f429i-disco.log uart off 168000000 + +# Uncomment to reset on connect, for grabbing under WFI et al +reset_config srst_only srst_nogate +# reset_config srst_only srst_nogate connect_assert_srst + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f4disco.cfg b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f4disco.cfg new file mode 100644 index 00000000..f2f5406d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32f4disco.cfg @@ -0,0 +1,13 @@ +source [find interface/stlink-v2.cfg] +set WORKAREASIZE 0x4000 +source [find target/stm32f4x.cfg] + +source openocd.common.cfg +optional_local "openocd.stm32f4disco.local.cfg" + +tpiu config internal swodump.stm32f4disco.log uart off 168000000 + +# Uncomment to reset on connect, for grabbing under WFI et al +reset_config srst_only srst_nogate +# reset_config srst_only srst_nogate connect_assert_srst + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l053disco.cfg b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l053disco.cfg new file mode 100644 index 00000000..b1173e08 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l053disco.cfg @@ -0,0 +1,14 @@ +source [find interface/stlink-v2-1.cfg] +set WORKAREASIZE 0x1000 +source [find target/stm32l0.cfg] + +source openocd.common.cfg +optional_local "openocd.stm32l053disco.local.cfg" + +# no trace on cm0 +#tpiu config internal swodump.stm32f4disco.log uart off 168000000 + +# Uncomment to reset on connect, for grabbing under WFI et al +reset_config srst_only srst_nogate +# reset_config srst_only srst_nogate connect_assert_srst + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l1-generic.cfg b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l1-generic.cfg new file mode 100644 index 00000000..33b032e9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/openocd.stm32l1-generic.cfg @@ -0,0 +1,13 @@ +# l1 generic, using a l4 disco board +source [find interface/stlink-v2-1.cfg] +set WORKAREASIZE 0x2000 +source [find target/stm32l1.cfg] + +source openocd.common.cfg +optional_local "openocd.stm32l1-generic.local.cfg" + +tpiu config internal swodump.stm32l1-generic.log uart off 32000000 + +# Uncomment to reset on connect, for grabbing under WFI et al +reset_config srst_only srst_nogate +# reset_config srst_only srst_nogate connect_assert_srst diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/stub.py b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/stub.py new file mode 100644 index 00000000..de0439ee --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/stub.py @@ -0,0 +1,4 @@ +__author__ = 'karlp' + +def config_switch(): + pass diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/test_gadget0.py b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/test_gadget0.py new file mode 100644 index 00000000..9d773895 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/test_gadget0.py @@ -0,0 +1,397 @@ +import array +import datetime +import usb.core +import usb.util as uu +import sys + +import unittest + +VENDOR_ID=0xcafe +PRODUCT_ID=0xcafe + +# you only need to worry about these if you are trying to explicitly test +# a single target. Normally, the test will autofind the attached target +#DUT_SERIAL = "stm32f429i-disco" +DUT_SERIAL = "stm32f4disco" +#DUT_SERIAL = "stm32f103-generic" +#DUT_SERIAL = "stm32l1-generic" +#DUT_SERIAL = "stm32f072disco" +#DUT_SERIAL = "stm32l053disco" + +GZ_REQ_SET_PATTERN=1 +GZ_REQ_PRODUCE=2 +GZ_REQ_SET_ALIGNED=3 +GZ_REQ_SET_UNALIGNED=4 +GZ_REQ_WRITE_LOOPBACK_BUFFER=10 +GZ_REQ_READ_LOOPBACK_BUFFER=11 + +class find_by_serial(object): + def __init__(self, serial): + self._serial = serial + + def __call__(self, device): + return device.serial_number == self._serial + + +class TestGadget0(unittest.TestCase): + # TODO - parameterize this with serial numbers so we can find + # gadget 0 code for different devices. (or use different PIDs?) + def setUp(self): + self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) + self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") + self.longMessage = True + + def tearDown(self): + uu.dispose_resources(self.dev) + + def test_sanity(self): + self.assertEqual(2, self.dev.bNumConfigurations, "Should have 2 configs") + + def test_config_switch_2(self): + """ + Uses the API if you're interested in the cfg block + """ + cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) + self.assertIsNotNone(cfg, "Config 2 should exist") + self.dev.set_configuration(cfg) + + def test_config_switch_3(self): + """ + Uses the simple API + """ + self.dev.set_configuration(3) + + def test_config_zero_addressed(self): + self.dev.set_configuration(0) + x = self.dev.ctrl_transfer(0x80, 0x08, 0, 0, 1) + self.assertEqual(0, x[0], "Should be configuration 0 before configuration is set") + + + def test_fetch_config(self): + self.dev.set_configuration(3) + # FIXME - find a way to get the defines for these from pyusb + x = self.dev.ctrl_transfer(0x80, 0x08, 0, 0, 1) + self.assertEqual(3, x[0], "Should get the actual bConfigurationValue back") + + def test_invalid_config(self): + try: + # FIXME - find a way to get the defines for these from pyusb + self.dev.ctrl_transfer(0x00, 0x09, 99) + self.fail("Request of invalid cfg should have failed") + except usb.core.USBError as e: + # Note, this might not be as portable as we'd like. + self.assertIn("Pipe", e.strerror) + + +class TestConfigSourceSink(unittest.TestCase): + """ + We could inherit, but it doesn't save much, and this saves me from remembering how to call super. + """ + + def setUp(self): + self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) + self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") + + self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) + self.assertIsNotNone(self.cfg, "Config 2 should exist") + self.dev.set_configuration(self.cfg) + self.intf = self.cfg[(0, 0)] + # heh, kinda gross... + self.ep_out = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_OUT][0] + self.ep_in = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_IN][0] + + def tearDown(self): + uu.dispose_resources(self.dev) + + def test_write_simple(self): + """ + here we go, start off with just a simple write of < bMaxPacketSize and just make sure it's accepted + :return: + """ + data = [x for x in range(int(self.ep_out.wMaxPacketSize / 2))] + written = self.dev.write(self.ep_out, data) + self.assertEqual(written, len(data), "Should have written all bytes plz") + + def test_write_zlp(self): + written = self.ep_out.write([]) + self.assertEqual(0, written, "should have written zero for a zero length write y0") + + def test_write_batch(self): + """ + Write 50 max sized packets. Should not stall. Will stall if firmware isn't consuming data properly + :return: + """ + for i in range(50): + data = [x for x in range(int(self.ep_out.wMaxPacketSize))] + written = self.dev.write(self.ep_out, data) + self.assertEqual(written, len(data), "Should have written all bytes plz") + + def test_write_mixed(self): + for i in range(int(self.ep_out.wMaxPacketSize / 4), self.ep_out.wMaxPacketSize * 10, 11): + data = [x & 0xff for x in range(i)] + written = self.ep_out.write(data) + self.assertEqual(written, len(data), "should have written all bytes plz") + + def test_read_zeros(self): + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, GZ_REQ_SET_PATTERN, 0) + self.ep_in.read(self.ep_in.wMaxPacketSize) # Clear out any prior pattern data + # unless, you know _exactly_ how much will be written by the device, always read + # an integer multiple of max packet size, to avoid overflows. + # the returned data will have the actual length. + # You can't just magically read out less than the device wrote. + read_size = self.ep_in.wMaxPacketSize * 10 + data = self.dev.read(self.ep_in, read_size) + self.assertEqual(len(data), read_size, "Should have read as much as we asked for") + expected = array.array('B', [0 for x in range(read_size)]) + self.assertEqual(data, expected, "In pattern 0, all source data should be zeros: ") + + def test_read_sequence(self): + # switching to the mod63 pattern requires resynching carefully to read out any zero frames already + # queued, but still make sure we start the sequence at zero. + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, GZ_REQ_SET_PATTERN, 1) + self.ep_in.read(self.ep_in.wMaxPacketSize) # Potentially queued zeros, or would have been safe. + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, GZ_REQ_SET_PATTERN, 1) + self.ep_in.read(self.ep_in.wMaxPacketSize) # definitely right pattern now, but need to restart at zero. + read_size = self.ep_in.wMaxPacketSize * 3 + data = self.dev.read(self.ep_in, read_size) + self.assertEqual(len(data), read_size, "Should have read as much as we asked for") + expected = array.array('B', [x % 63 for x in range(read_size)]) + self.assertEqual(data, expected, "In pattern 1, Should be % 63") + + def test_read_write_interleaved(self): + for i in range(1, 20): + ii = self.ep_in.read(self.ep_in.wMaxPacketSize * i) + dd = [x & 0xff for x in range(i * 20 + 3)] + oo = self.ep_out.write(dd) + self.assertEqual(len(ii), self.ep_in.wMaxPacketSize * i, "should have read full packet") + self.assertEqual(oo, len(dd), "should have written full packet") + + def test_control_known(self): + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, GZ_REQ_SET_PATTERN, 0) + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, GZ_REQ_SET_PATTERN, 1) + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, GZ_REQ_SET_PATTERN, 99) + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, GZ_REQ_SET_PATTERN, 0) + + def test_control_unknown(self): + try: + self.dev.ctrl_transfer(uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE, 42, 69) + self.fail("Should have got a stall") + except usb.core.USBError as e: + # Note, this might not be as portable as we'd like. + self.assertIn("Pipe", e.strerror) + + +@unittest.skip("Perf tests only on demand (comment this line!)") +class TestConfigSourceSinkPerformance(unittest.TestCase): + """ + Read/write throughput, roughly + """ + + def setUp(self): + self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) + self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") + + self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) + self.assertIsNotNone(self.cfg, "Config 2 should exist") + self.dev.set_configuration(self.cfg) + self.intf = self.cfg[(0, 0)] + # heh, kinda gross... + self.ep_out = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_OUT][0] + self.ep_in = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_IN][0] + + def tearDown(self): + uu.dispose_resources(self.dev) + + def tput(self, xc, te): + return (xc / 1024 / max(1, te.seconds + te.microseconds / + 1000000.0)) + + def test_read_perf(self): + # I get around 990kps here... + ts = datetime.datetime.now() + rxc = 0 + while rxc < 5 * 1024 * 1024: + desired = 100 * 1024 + data = self.ep_in.read(desired, timeout=0) + self.assertEqual(desired, len(data), "Should have read all bytes plz") + rxc += len(data) + te = datetime.datetime.now() - ts + print("read %s bytes in %s for %s kps" % (rxc, te, self.tput(rxc, te))) + + def test_write_perf(self): + # caps out around 420kps? + ts = datetime.datetime.now() + txc = 0 + data = [x & 0xff for x in range(100 * 1024)] + while txc < 5 * 1024 * 1024: + w = self.ep_out.write(data, timeout=0) + self.assertEqual(w, len(data), "Should have written all bytes plz") + txc += w + te = datetime.datetime.now() - ts + print("wrote %s bytes in %s for %s kps" % (txc, te, self.tput(txc, te))) + + +class TestControlTransfer_Reads(unittest.TestCase): + """ + https://github.com/libopencm3/libopencm3/pull/194 + and + https://github.com/libopencm3/libopencm3/pull/505 + """ + + def setUp(self): + self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) + self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") + + self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) + self.assertIsNotNone(self.cfg, "Config 2 should exist") + self.dev.set_configuration(self.cfg) + self.req = uu.CTRL_IN | uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE + + def inner_t(self, wVal, read_len): + wVal = int(wVal) + read_len = int(read_len) + q = self.dev.ctrl_transfer(self.req, GZ_REQ_PRODUCE, wVal, 0, read_len) + self.assertEqual(len(q), wVal, "Should have read as much as we asked for?") + + def tearDown(self): + uu.dispose_resources(self.dev) + + def test_basic(self): + x = self.dev.ctrl_transfer(self.req, GZ_REQ_PRODUCE, 32, 0, 32) + self.assertEqual(32, len(x)) + + def test_matching_sizes(self): + """ + Can we request x control in when we tell the device to produce x? + :return: + """ + def inner(x): + x = int(x) + q = self.dev.ctrl_transfer(self.req, GZ_REQ_PRODUCE, x, 0, x) + self.assertEqual(len(q), x, "Should have read as much as we asked for") + + ep0_size = self.dev.bMaxPacketSize0 + inner(ep0_size) + inner(ep0_size * 3) + inner(ep0_size / 3) + inner(ep0_size - 7) + inner(ep0_size + 11) + inner(ep0_size * 4 + 11) + + def test_waytoobig(self): + """ + monster reads should fail, but not fatally. + (Don't make them too, big, or libusb will reject you outright, see MAX_CTRL_BUFFER_LENGTH in libusb sources) + """ + try: + self.dev.ctrl_transfer(self.req, GZ_REQ_PRODUCE, 10 * self.dev.bMaxPacketSize0, 0, 10 * self.dev.bMaxPacketSize0) + self.fail("Should have got a stall") + except usb.core.USBError as e: + # Note, this might not be as portable as we'd like. + self.assertIn("Pipe", e.strerror) + + def test_read_longer(self): + """ + Attempt to read more than the device replied with. + This is explicitly allowed by spec: + "On an input request, a device must never return more data than is indicated + by the wLength value; it may return less" + """ + + ep0_size = self.dev.bMaxPacketSize0 + self.inner_t(ep0_size / 2, ep0_size) + self.inner_t(ep0_size / 2, ep0_size * 2) + self.inner_t(ep0_size + 31, ep0_size * 5) + + def test_read_needs_zlp(self): + ep0_size = self.dev.bMaxPacketSize0 + self.inner_t(ep0_size, ep0_size + 10) + self.inner_t(ep0_size * 2, ep0_size * 5) + + def test_read_zero(self): + """ + try and read > 0, but have the device only produce 0 + """ + self.inner_t(0, self.dev.bMaxPacketSize0) + self.inner_t(0, 200) + + def test_read_nothing(self): + """ + Don't read anything, don't create anything (no data stage) + """ + self.inner_t(0, 0) + + def test_mean_limits(self): + """ + tell the device to produce more than we ask for. + Note, this doesn't test the usb stack, it tests the application code behaves. + """ + q = self.dev.ctrl_transfer(self.req, GZ_REQ_PRODUCE, 100, 0, 10) + self.assertEqual(len(q), 10, "In this case, should have gotten wLen back") + + +class TestUnaligned(unittest.TestCase): + """ + M0 and M0+ cores don't support unaligned memory accesses. These test + how the stack behaves with aligned vs unaligned buffers. + https://github.com/libopencm3/libopencm3/issues/401 + https://github.com/libopencm3/libopencm3/issues/461 + """ + + def setUp(self): + self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) + self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") + + self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) + self.assertIsNotNone(self.cfg, "Config 2 should exist") + self.dev.set_configuration(self.cfg); + self.req = uu.CTRL_OUT | uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE + self.intf = self.cfg[(0, 0)] + # heh, kinda gross... + self.ep_out = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_OUT][0] + self.ep_in = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_IN][0] + + def tearDown(self): + uu.dispose_resources(self.dev) + + def set_unaligned(self): + # GZ_REQ_SET_UNALIGNED + self.dev.ctrl_transfer(self.req, GZ_REQ_SET_UNALIGNED, 0, 0) + + def set_aligned(self): + # GZ_REQ_SET_ALIGNED + self.dev.ctrl_transfer(self.req, GZ_REQ_SET_ALIGNED, 0, 0) + + def do_readwrite(self): + """ + transfer garbage data to/from bulk EP; alignment issues will hardfault the target + """ + data = [x for x in range(int(self.ep_out.wMaxPacketSize / 2))] + written = self.dev.write(self.ep_out, data) + self.assertEqual(written, len(data), "Should have written all bytes plz") + + read_size = self.ep_in.wMaxPacketSize * 10 + data = self.dev.read(self.ep_in, read_size) + self.assertEqual(len(data), read_size, "Should have read as much as we asked for") + + def test_aligned(self): + self.set_aligned() + self.do_readwrite() + + def test_unaligned(self): + self.set_unaligned() + self.do_readwrite() + + +if __name__ == "__main__": + if len(sys.argv) > 1: + DUT_SERIAL = sys.argv.pop() + print("Running tests for DUT: ", DUT_SERIAL) + unittest.main() + else: + # scan for available and try them all! + devs = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, find_all=True) + for dev in devs: + DUT_SERIAL = dev.serial_number + print("Running tests for DUT: ", DUT_SERIAL) + unittest.main(exit=False) diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.c b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.c new file mode 100644 index 00000000..ad4d83b5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.c @@ -0,0 +1,357 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * This file implements linux's "Gadget zero" functionality, both the + * "source sink" functional interface, and the "loopback" interface. + * It _only_ uses usb includes, do _not_ include any target specific code here! + */ +#include +#include +#include +#include + +#include "trace.h" +#include "delay.h" +#include "usb-gadget0.h" + +#define ER_DEBUG +#ifdef ER_DEBUG +#include +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +/* + * USB Vendor:Interface control requests. + */ +#define GZ_REQ_SET_PATTERN 1 +#define GZ_REQ_PRODUCE 2 +#define GZ_REQ_SET_ALIGNED 3 +#define GZ_REQ_SET_UNALIGNED 4 +#define INTEL_COMPLIANCE_WRITE 0x5b +#define INTEL_COMPLIANCE_READ 0x5c + +/* USB configurations */ +#define GZ_CFG_SOURCESINK 2 +#define GZ_CFG_LOOPBACK 3 + +#define BULK_EP_MAXPACKET 64 + +static const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = USB_CLASS_VENDOR, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = BULK_EP_MAXPACKET, + + /* when we're compatible with gadget 0 + * #define DRIVER_VENDOR_NUM 0x0525 + * #define DRIVER_PRODUCT_NUM 0xa4a0 + */ + .idVendor = 0xcafe, + .idProduct = 0xcafe, + .bcdDevice = 0x0001, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 2, +}; + +static const struct usb_endpoint_descriptor endp_bulk[] = { + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = BULK_EP_MAXPACKET, + .bInterval = 1, + }, + { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = BULK_EP_MAXPACKET, + .bInterval = 1, + } +}; + +static const struct usb_interface_descriptor iface_sourcesink[] = { + { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_VENDOR, + .iInterface = 0, + .endpoint = endp_bulk, + } +}; + +static const struct usb_interface_descriptor iface_loopback[] = { + { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, /* still 0, as it's a different config...? */ + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_VENDOR, + .iInterface = 0, + .endpoint = endp_bulk, + } +}; + +static const struct usb_interface ifaces_sourcesink[] = { + { + .num_altsetting = 1, + .altsetting = iface_sourcesink, + } +}; + +static const struct usb_interface ifaces_loopback[] = { + { + .num_altsetting = 1, + .altsetting = iface_loopback, + } +}; + +static const struct usb_config_descriptor config[] = { + { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 1, + .bConfigurationValue = GZ_CFG_SOURCESINK, + .iConfiguration = 4, /* string index */ + .bmAttributes = 0x80, + .bMaxPower = 0x32, + .interface = ifaces_sourcesink, + }, + { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 1, + .bConfigurationValue = GZ_CFG_LOOPBACK, + .iConfiguration = 5, /* string index */ + .bmAttributes = 0x80, + .bMaxPower = 0x32, + .interface = ifaces_loopback, + } +}; + +static char serial[] = "0123456789.0123456789.0123456789"; +static const char *usb_strings[] = { + "libopencm3", + "Gadget-Zero", + serial, + "source and sink data", + "loop input to output" +}; + +/* Buffer to be used for control requests. */ +static uint8_t usbd_control_buffer[5*BULK_EP_MAXPACKET]; +static usbd_device *our_dev; + +/* Private global for state */ +static struct { + uint8_t pattern; + int pattern_counter; + int test_unaligned; /* If 0 (default), use 16-bit aligned buffers. This should not be declared as bool */ +} state = { + .pattern = 0, + .pattern_counter = 0, + .test_unaligned = 0, +}; + +static void gadget0_ss_out_cb(usbd_device *usbd_dev, uint8_t ep) +{ + (void) ep; + uint16_t x; + /* TODO - if you're really keen, perf test this. tiva implies it matters */ + /* char buf[64] __attribute__ ((aligned(4))); */ + uint8_t buf[BULK_EP_MAXPACKET + 1] __attribute__ ((aligned(2))); + uint8_t *dest; + + trace_send_blocking8(0, 'O'); + if (state.test_unaligned) { + dest = buf + 1; + } else { + dest = buf; + } + x = usbd_ep_read_packet(usbd_dev, ep, dest, BULK_EP_MAXPACKET); + trace_send_blocking8(1, x); +} + +static void gadget0_ss_in_cb(usbd_device *usbd_dev, uint8_t ep) +{ + (void) usbd_dev; + uint8_t buf[BULK_EP_MAXPACKET + 1] __attribute__ ((aligned(2))); + uint8_t *src; + + trace_send_blocking8(0, 'I'); + if (state.test_unaligned) { + src = buf + 1; + } else { + src = buf; + } + + switch (state.pattern) { + case 0: + memset(src, 0, BULK_EP_MAXPACKET); + break; + case 1: + for (unsigned i = 0; i < BULK_EP_MAXPACKET; i++) { + src[i] = state.pattern_counter++ % 63; + } + break; + } + + uint16_t x = usbd_ep_write_packet(usbd_dev, ep, src, BULK_EP_MAXPACKET); + /* As we are calling write in the callback, this should never fail */ + trace_send_blocking8(2, x); + if (x != BULK_EP_MAXPACKET) { + ER_DPRINTF("failed to write?: %d\n", x); + } + /*assert(x == sizeof(buf));*/ +} + +static void gadget0_rx_cb_loopback(usbd_device *usbd_dev, uint8_t ep) +{ + (void) usbd_dev; + ER_DPRINTF("loop rx %x\n", ep); + /* TODO - unimplemented - consult linux source on proper behaviour */ +} + +static void gadget0_tx_cb_loopback(usbd_device *usbd_dev, uint8_t ep) +{ + (void) usbd_dev; + ER_DPRINTF("loop tx %x\n", ep); + /* TODO - unimplemented - consult linux source on proper behaviour */ +} + +static int gadget0_control_request(usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, + uint16_t *len, + usbd_control_complete_callback *complete) +{ + (void) usbd_dev; + (void) complete; + (void) buf; + (void) len; + ER_DPRINTF("ctrl breq: %x, bmRT: %x, windex :%x, wlen: %x, wval :%x\n", + req->bRequest, req->bmRequestType, req->wIndex, req->wLength, + req->wValue); + + /* TODO - what do the return values mean again? */ + switch (req->bRequest) { + case GZ_REQ_SET_PATTERN: + state.pattern_counter = 0; + state.pattern = req->wValue; + return USBD_REQ_HANDLED; + case INTEL_COMPLIANCE_WRITE: + case INTEL_COMPLIANCE_READ: + ER_DPRINTF("unimplemented!"); + return USBD_REQ_NOTSUPP; + case GZ_REQ_SET_UNALIGNED: + state.test_unaligned = 1; + return USBD_REQ_HANDLED; + case GZ_REQ_SET_ALIGNED: + state.test_unaligned = 0; + return USBD_REQ_HANDLED; + case GZ_REQ_PRODUCE: + ER_DPRINTF("fake loopback of %d\n", req->wValue); + if (req->wValue > sizeof(usbd_control_buffer)) { + ER_DPRINTF("Can't write more than out control buffer! %d > %d\n", + req->wValue, sizeof(usbd_control_buffer)); + return USBD_REQ_NOTSUPP; + } + /* Don't produce more than asked for! */ + if (req->wValue > req->wLength) { + ER_DPRINTF("Truncating reply to match wLen\n"); + *len = req->wLength; + } else { + *len = req->wValue; + } + return USBD_REQ_HANDLED; + } + return USBD_REQ_NEXT_CALLBACK; +} + +static void gadget0_set_config(usbd_device *usbd_dev, uint16_t wValue) +{ + ER_DPRINTF("set cfg %d\n", wValue); + switch (wValue) { + case GZ_CFG_SOURCESINK: + state.test_unaligned = 0; + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, BULK_EP_MAXPACKET, + gadget0_ss_out_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, BULK_EP_MAXPACKET, + gadget0_ss_in_cb); + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + gadget0_control_request); + /* Prime source for IN data. */ + gadget0_ss_in_cb(usbd_dev, 0x82); + break; + case GZ_CFG_LOOPBACK: + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, BULK_EP_MAXPACKET, + gadget0_rx_cb_loopback); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, BULK_EP_MAXPACKET, + gadget0_tx_cb_loopback); + break; + default: + ER_DPRINTF("set configuration unknown: %d\n", wValue); + } +} + +usbd_device *gadget0_init(const usbd_driver *driver, const char *userserial) +{ +#ifdef ER_DEBUG + setbuf(stdout, NULL); +#endif + if (userserial) { + usb_strings[2] = userserial; + } + our_dev = usbd_init(driver, &dev, config, + usb_strings, 5, + usbd_control_buffer, sizeof(usbd_control_buffer)); + + usbd_register_set_config_callback(our_dev, gadget0_set_config); + delay_setup(); + + return our_dev; +} + +void gadget0_run(usbd_device *usbd_dev) +{ + usbd_poll(usbd_dev); + /* This should be more than allowable! */ + delay_us(100); +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.h b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.h new file mode 100644 index 00000000..9ed332af --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/gadget-zero/usb-gadget0.h @@ -0,0 +1,42 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef USB_GADGET0_H +#define USB_GADGET0_H + +#include + +/** + * Start up the gadget0 framework. + * @param driver which usbd hardware driver to use. + * @param userserial if non-null, will become the serial number. + * You should provide this to help the test code find something particular + * to the hardware. + * @return the usbd_device created. +*/ +usbd_device *gadget0_init(const usbd_driver *driver, const char *userserial); + +/** + * Call this forever. + * @param usbd_dev the object returned in _init. + * @sa gadget0_init + */ +void gadget0_run(usbd_device *usbd_dev); + +#endif diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/rules.mk b/hardware-wallet/firmware/vendor/libopencm3/tests/rules.mk new file mode 100644 index 00000000..fe1051c0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/rules.mk @@ -0,0 +1,171 @@ +## +## This file is part of the libopencm3 project. +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +# This version of rules.mk expects the following to be defined before +# inclusion.. +### REQUIRED ### +# OPENCM3_DIR - duh +# OPENCM3_LIB - the basename, eg: opencm3_stm32f4 +# OPENCM3_DEFS - the target define eg: -DSTM32F4 +# ARCH_FLAGS - eg, -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 +# (ie, the full set of cpu arch flags, _none_ are defined in this file) +# PROJECT - will be the basename of the output elf, eg usb-gadget0-stm32f4disco +# CFILES - basenames only, eg main.c blah.c +# LDSCRIPT - full path, eg ../../examples/stm32/f4/stm32f4-discovery/stm32f4-discovery.ld +# +### OPTIONAL ### +# INCLUDES - fully formed -I paths, if you want extra, eg -I../shared +# BUILD_DIR - defaults to bin, should set this if you are building multiarch +# OPT - full -O flag, defaults to -Os +# CSTD - defaults -std=c99 +# CXXSTD - no default. +# OOCD_INTERFACE - eg stlink-v2 +# OOCD_TARGET - eg stm32f4x +# both only used if you use the "make flash" target. +# OOCD_FILE - eg my.openocd.cfg +# This overrides interface/target above, and is used as just -f FILE +### TODO/FIXME/notes ### +# No support for stylecheck. +# No support for BMP/texane/random flash methods, no plans either +# No support for magically finding the library. +# C++ hasn't been actually tested with this..... sorry bout that. ;) +# Second expansion/secondary not set, add this if you need them. + +BUILD_DIR ?= bin +OPT ?= -Os +CSTD ?= -std=c99 + +# Be silent per default, but 'make V=1' will show all compiler calls. +# If you're insane, V=99 will print out all sorts of things. +V?=0 +ifeq ($(V),0) +Q := @ +NULL := 2>/dev/null +endif + +# Tool paths. +PREFIX ?= arm-none-eabi- +CC = $(PREFIX)gcc +LD = $(PREFIX)gcc +OBJCOPY = $(PREFIX)objcopy +OBJDUMP = $(PREFIX)objdump +OOCD ?= openocd + +OPENCM3_INC = $(OPENCM3_DIR)/include + +# Inclusion of library header files +INCLUDES += $(patsubst %,-I%, . $(OPENCM3_INC) ) + +OBJS = $(CFILES:%.c=$(BUILD_DIR)/%.o) + +TGT_CPPFLAGS += -MD +TGT_CPPFLAGS += -Wall -Wundef $(INCLUDES) +TGT_CPPFLAGS += $(INCLUDES) $(OPENCM3_DEFS) + +TGT_CFLAGS += $(OPT) $(CSTD) -ggdb3 +TGT_CFLAGS += $(ARCH_FLAGS) +TGT_CFLAGS += -fno-common +TGT_CFLAGS += -ffunction-sections -fdata-sections +TGT_CFLAGS += -Wextra -Wshadow -Wno-unused-variable -Wimplicit-function-declaration +TGT_CFLAGS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes + +TGT_CXXFLAGS += $(OPT) $(CXXSTD) -ggdb3 +TGT_CXXFLAGS += $(ARCH_FLAGS) +TGT_CXXFLAGS += -fno-common +TGT_CXXFLAGS += -ffunction-sections -fdata-sections +TGT_CXXFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++ + +TGT_LDFLAGS += -T$(LDSCRIPT) -L$(OPENCM3_DIR)/lib -nostartfiles +TGT_LDFLAGS += $(ARCH_FLAGS) +TGT_LDFLAGS += -specs=nano.specs +TGT_LDFLAGS += -Wl,--gc-sections +# OPTIONAL +#TGT_LDFLAGS += -Wl,-Map=$(PROJECT).map +ifeq ($(V),99) +TGT_LDFLAGS += -Wl,--print-gc-sections +endif + +LDLIBS += -l$(OPENCM3_LIB) +# nosys is only in newer gcc-arm-embedded... +#LDLIBS += -specs=nosys.specs +LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group + +# Burn in legacy hell fortran modula pascal yacc idontevenwat +.SUFFIXES: +.SUFFIXES: .c .h .o .cxx .elf .bin .list .lss + +# Bad make, never *ever* try to get a file out of source control by yourself. +%: %,v +%: RCS/%,v +%: RCS/% +%: s.% +%: SCCS/s.% + +all: $(PROJECT).elf $(PROJECT).bin +flash: $(PROJECT).flash + +$(LDSCRIPT): +ifeq (,$(wildcard $(LDSCRIPT))) + $(error Unable to find specified linker script: $(LDSCRIPT)) +endif + +# Need a special rule to have a bin dir +$(BUILD_DIR)/%.o: %.c + @printf " CC\t$<\n" + @mkdir -p $(dir $@) + $(Q)$(CC) $(TGT_CFLAGS) $(CFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $< + +$(BUILD_DIR)/%.o: %.cxx + @printf " CXX\t$<\n" + @mkdir -p $(dir $@) + $(Q)$(CC) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $< + +$(PROJECT).elf: $(OBJS) $(LDSCRIPT) + @printf " LD\t$@\n" + $(Q)$(LD) $(TGT_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ + +%.bin: %.elf + @printf " OBJCOPY\t$@\n" + $(Q)$(OBJCOPY) -O binary $< $@ + +%.lss: %.elf + $(OBJDUMP) -h -S $< > $@ + +%.list: %.elf + $(OBJDUMP) -S $< > $@ + +%.flash: %.elf + @printf " FLASH\t$<\n" +ifeq (,$(OOCD_FILE)) + $(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \ + $(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ + -f target/$(OOCD_TARGET).cfg \ + -c "program $(realpath $(*).elf) verify reset exit" \ + $(NULL) +else + $(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \ + $(Q)$(OOCD) -f $(OOCD_FILE) \ + -c "program $(realpath $(*).elf) verify reset exit" \ + $(NULL) +endif + +clean: + rm -rf $(BUILD_DIR) $(PROJECT).{elf,bin} $(PROJECT).{list,lss,map} + +.PHONY: all clean flash +-include $(OBJS:.o=.d) + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace.c b/hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace.c new file mode 100644 index 00000000..54bee45d --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include "trace.h" + +void trace_send_blocking8(int stimulus_port, char c) +{ + if (!(ITM_TER[0] & (1< + +#ifdef __cplusplus +extern "C" { +#endif + +void trace_send_blocking8(int stimulus_port, char c); +void trace_send8(int stimulus_port, char c); + +void trace_send_blocking16(int stimulus_port, uint16_t val); +void trace_send16(int stimulus_port, uint16_t val); + +void trace_send_blocking32(int stimulus_port, uint32_t val); +void trace_send32(int stimulus_port, uint32_t val); + + +#ifdef __cplusplus +} +#endif + +#endif /* TRACE_H */ + diff --git a/hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace_stdio.c b/hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace_stdio.c new file mode 100644 index 00000000..27109428 --- /dev/null +++ b/hardware-wallet/firmware/vendor/libopencm3/tests/shared/trace_stdio.c @@ -0,0 +1,34 @@ +/* + * support for stdio output to a trace port + * Karl Palsson, 2014 + */ + +#include +#include +#include + +#include "trace.h" + +#ifndef STIMULUS_STDIO +#define STIMULUS_STDIO 0 +#endif + +int _write(int file, char *ptr, int len); +int _write(int file, char *ptr, int len) +{ + int i; + + if (file == STDOUT_FILENO || file == STDERR_FILENO) { + for (i = 0; i < len; i++) { + if (ptr[i] == '\n') { + trace_send_blocking8(STIMULUS_STDIO, '\r'); + } + trace_send_blocking8(STIMULUS_STDIO, ptr[i]); + } + return i; + } + errno = EIO; + return -1; +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/.gitignore b/hardware-wallet/firmware/vendor/nanopb/.gitignore new file mode 100644 index 00000000..3bb09db1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/.gitignore @@ -0,0 +1,28 @@ +*.gcda +*.gcno +*.gcov +*.o +*.pb.c +*.pb.h +*.pb +*.pyc +*_pb2.py +*~ +*.tar.gz +.sconsign.dblite +config.log +.sconf_temp +tests/build +julkaisu.txt +dist +docs/*.html +docs/generator_flow.png +examples/simple/simple +examples/network_server/client +examples/network_server/server +examples/using_double_on_avr/decode_double +examples/using_double_on_avr/encode_double +examples/using_double_on_avr/test_conversions +examples/using_union_messages/decode +examples/using_union_messages/encode +generator/nanopb_pb2.pyc diff --git a/hardware-wallet/firmware/vendor/nanopb/.travis.yml b/hardware-wallet/firmware/vendor/nanopb/.travis.yml new file mode 100644 index 00000000..e8eca0f8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/.travis.yml @@ -0,0 +1,60 @@ +# Travis CI has no ability to handle 3 langauges (c, c++, python) +# and it overrides $CC/$CXX if language is set to c/c++ (only one, not both). +# +# Set language to python since at least the result of that is something useful. +language: python + +python: + - "2.7" + - "3.4" + +# Manage the C/C++ compiler manually +env: + - CC=gcc CXX=g++ + - CC=gcc-4.8 CXX=g++-4.8 + - CC=gcc-4.9 CXX=g++-4.9 + - CC=gcc-5 CXX=g++-5 + - CC=clang CXX=clang++ + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-4.8 + - g++-4.8 + - gcc-4.9 + - g++-4.9 + - gcc-5 + - g++-5 + + +before_install: + - export PATH=$HOME/.local/bin:$HOME/protobuf/bin:$PATH + - export MAKEFLAGS=-j$(nproc) + - $CC --version + - $CXX --version + - python --version + - lsb_release -a + +# Seems to be issues with concurrent builds +#cache: +# directories: +# - $HOME/protobuf + +# Rather then compile protobuf 3 from source, use the binaries now available +# to speed up build time and reduce surprises until Ubuntu adds protobuf3 +# packages to the repository. +install: + - mkdir -p $HOME/protobuf && pushd $HOME/protobuf + && curl -LO 'https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-linux-x86_64.zip' + && unzip protoc-3.4.0-linux-x86_64.zip + && popd + - curl -L 'https://github.com/google/protobuf/releases/download/v3.4.0/protobuf-python-3.4.0.tar.gz' | tar xzf - + && pushd protobuf-3.4.0/python + && python setup.py build && python setup.py install + && popd + +script: + - pushd generator/proto && make && popd + - pushd tests && scons CC=$CC CXX=$CXX && popd diff --git a/hardware-wallet/firmware/vendor/nanopb/AUTHORS.txt b/hardware-wallet/firmware/vendor/nanopb/AUTHORS.txt new file mode 100644 index 00000000..347c133a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/AUTHORS.txt @@ -0,0 +1,39 @@ +Petteri Aimonen +Michael Poole +Daniel Kan +Stan Hu +David Hotham +Steffen Siering +Jens Steinhauser +Pavel Ilin +Kent Ryhorchuk +Martin Donath +Oliver Lee +Michael Haberler +Nicolas Colomer +Ivan Kravets +Kyle Manna +Benjamin Kamath +Andrew Ruder +Kenshi Kawaguchi +isotes +Maxim Khitrov +Yaniv Mordekhay +Ming Zhao +Google, Inc. +Tom Roeder +Piotr Sikora +Bernhard Krämer +Konstantin Podsvirov +William A. Kennington III +Guillaume Lager +Tobias Haegermarck +Justin DeMartino +Constantine Grantcharov +Nick Ewalt +Harald Fernengel +Alice Wang +Kevin Fitch +Kamal Marhubi +Elco Jacobs + diff --git a/hardware-wallet/firmware/vendor/nanopb/BUILD b/hardware-wallet/firmware/vendor/nanopb/BUILD new file mode 100644 index 00000000..f9fc57f5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/BUILD @@ -0,0 +1,21 @@ +licenses(["notice"]) + +exports_files(["LICENSE.txt"]) + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "nanopb", + visibility = ["//visibility:public"], + hdrs = [ + "pb.h", + "pb_common.h", + "pb_decode.h", + "pb_encode.h", + ], + srcs = [ + "pb_common.c", + "pb_decode.c", + "pb_encode.c", + ], +) diff --git a/hardware-wallet/firmware/vendor/nanopb/CHANGELOG.txt b/hardware-wallet/firmware/vendor/nanopb/CHANGELOG.txt new file mode 100644 index 00000000..a654e446 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/CHANGELOG.txt @@ -0,0 +1,288 @@ +nanopb-0.3.9 (2017-09-23) + Fix bugs in proto3 encoding of submessages (#256) + Fix message size calculation for arrays of size 1 (#253) + Fix segfault with FT_CALLBACK inside FT_POINTER (#259) + Properly detect truncated tags in corrupted messages (#277) + Make pb_decode_varint32 overflow checks exact (#258) + Add option to build without 64-bit support (#86) + Add options to define source and header file extensions (#264) + Add pb_en/decode_nullterminated() (part of #278) + Add pb_decode_delimited_noinit (#284) + CMake: add dependency for .options file (#265) + CMake: change use of relative paths (#250,#271,#273) + Better error message for missing max_size option (#281) + Travis-CI build fixes (#283) + Add Bazel build system file (#266) + +nanopb-0.3.8 (2017-03-05) + Fix problems with multiple oneofs in same message (#229) + Zero-valued extension fields were mistakenly ignored by encoder (#242) + Multiple fixes related to proto3 mode (#242, #245, #247, #249) + Fix potential unaligned access (#226, #227) + Fix documentation for protoc --plugin argument (#239) + Extend inline / fixed length bytes array support (#244) + Add new option max_length for strings (#107) + Make string substream API more robust (#230) + Make pb_decode_varint32 public API (#231) + Allow overriding proto3 mode (#228) + Add optional enum->string mapping function (#223) + Add transitional options.proto file (#241) + Add better error message on Python library version imcompatibility (#240) + Include version number in PlatformIO library.json (#222) + CMake build script changes (#236, #237) + Change download links to https + Improvements to test cases. + +nanopb-0.3.7 (2016-10-30) + Add support for proto3-style singular fields (#182, #206, #216) + Updated binary package protoc to version 3.1.0 + Add FT_INLINE allocation of bytes fields (#211) + Include package name in include guard (#207) + Fix missing warning with large bytes fields (issue #220) + Added CMake project (#208) + Add bazel BUILD file for nanopb (#209) + Added an AUTHORS file (#211) + Documentation updates + Improvements to test cases. + +nanopb-0.3.6 (2016-06-19) + Protect against corrupted _count fields in pb_release (#205) + Fix error in STATIC_ASSERT with multiple files (#203) + Add -D option to specify output directory (#193) + Generate MIN/MAX/ARRAYSIZE defines for enums (#194) + Generate comments about uncalculable message sizes (#195) + Documentation updates (#196, #201) + Improvements to test cases. + +nanopb-0.3.5 (2016-02-13) + NOTE: If you are using pb_syshdr.h, you will need to add uint_least8_t + definition. See docs/migration.rst for details. + + Fix generator crash with Enum inside Oneof (#188) + Fix some generator regressions related to .options file path (#172) + Add support for platforms without uint8_t (#191) + Allow const parameter to pb_istream_from_buffer (#152) + Ignore null pointers in pb_release() (#183) + Add support for anonymous unions (#184) + Add Python3 support to the generator (#169) + Add code generator insertion points to generated files (#178) + Improvements to CMake script (#181) + Improvements to test cases. + +nanopb-0.3.4 (2015-09-26) + Fix handling of unsigned 8- and 16-bit enums (issue 164) + Fix generator on systems where python = python3. (issue 155) + Fix compiler warning on GCC 5.x (issue 171) + Make the generator better handle imported .protos (issue 165) + Add packed_enum option to generator. + Add syntax= line to .proto files (issue 167) + Add PlatformIO registry manifest file. (pr 156) + +nanopb-0.3.3 (2015-04-10) + Fix missing files in Linux binary package (issue 146) + Fix generator bug when oneof is first field in a message. (issue 142) + Fix generator error when long_names:false is combined with Oneofs. (issue 147) + Fix oneof submessage initialization bug. (issue 149) + Fix problem with plugin options on Python 2.7.2 and older. (issue 153) + Fix crash when callback is inside oneof field. (issue 148) + Switch to .tar.gz format for Mac OS X packages. (issue 154) + Always define enum long names so that cross-file references work. (issue 118) + Add msgid generator option. (issue 151) + Improve comment support in .options files. (issue 145) + Updates for the CMake rule file, add cmake example. + Better error messages for syntax errors in .options file + +nanopb-0.3.2 (2015-01-24) + Fix memory leaks with PB_ENABLE_MALLOC with some submessage hierarchies (issue 138) + Implement support for oneofs (C unions). (issues 131, 141) + Add int_size option for generator (issue 139) + Add compilation option to disable struct packing. (issue 136) + Change PB_RETURN_ERROR() macro to avoid compiler warnings (issue 140) + Fix build problems with protoc 3.0.0 + Add support for POINTER type in extensions + Initialize also extension fields to defaults in pb_decode(). + Detect too large varint values when decoding. + +nanopb-0.3.1 (2014-09-11) + Fix security issue due to size_t overflows. (issue 132) + Fix memory leak with duplicated fields and PB_ENABLE_MALLOC + Fix crash if pb_release() is called twice. + Fix cyclic message support (issue 130) + Fix error in generated initializers for repeated pointer fields. + Improve tests (issues 113, 126) + +nanopb-0.3.0 (2014-08-26) + NOTE: See docs/migration.html or online at + http://koti.kapsi.fi/~jpa/nanopb/docs/migration.html + for changes in this version. Most importantly, you need to add + pb_common.c to the list of files to compile. + + Separated field iterator logic to pb_common.c (issue 128) + Change the _count fields to use pb_size_t datatype (issue 82) + Added PB_ prefix to macro names (issue 106) + Added #if version guard to generated files (issue 129) + Added migration document + +nanopb-0.2.9 (2014-08-09) + NOTE: If you are using the -e option with the generator, you have + to prepend . to the argument to get the same behaviour as before. + + Do not automatically add a dot with generator -e option. (issue 122) + Fix problem with .options file and extension fields. (issue 125) + Don't use SIZE_MAX macro, as it is not in C89. (issue 120) + Generate #defines for initializing message structures. (issue 79) + Add skip_message option to generator. (issue 121) + Add PB_PACKED_STRUCT support for Keil MDK-ARM toolchain (issue 119) + Give better messages about the .options file path. (issue 124) + Improved tests + +nanopb-0.2.8 (2014-05-20) + Fix security issue with PB_ENABLE_MALLOC. (issue 117) + Add option to not add timestamps to .pb.h and .pb.c preambles. (issue 115) + Documentation updates + Improved tests + +nanopb-0.2.7 (2014-04-07) + Fix bug with default values for extension fields (issue 111) + Fix some MISRA-C warnings (issue 91) + Implemented optional malloc() support (issue 80) + Changed pointer-type bytes field datatype + Add a "found" field to pb_extension_t (issue 112) + Add convenience function pb_get_encoded_size() (issue 16) + +nanopb-0.2.6 (2014-02-15) + Fix generator error with bytes callback fields (issue 99) + Fix warnings about large integer constants (issue 102) + Add comments to where STATIC_ASSERT is used (issue 96) + Add warning about unknown field names on .options (issue 105) + Move descriptor.proto to google/protobuf subdirectory (issue 104) + Improved tests + +nanopb-0.2.5 (2014-01-01) + Fix a bug with encoding negative values in int32 fields (issue 97) + Create binary packages of the generator + dependencies (issue 47) + Add support for pointer-type fields to the encoder (part of issue 80) + Fixed path in FindNanopb.cmake (issue 94) + Improved tests + +nanopb-0.2.4 (2013-11-07) + Remove the deprecated NANOPB_INTERNALS functions from public API. + Document the security model. + Check array and bytes max sizes when encoding (issue 90) + Add #defines for maximum encoded message size (issue 89) + Add #define tags for extension fields (issue 93) + Fix MISRA C violations (issue 91) + Clean up pb_field_t definition with typedefs. + +nanopb-0.2.3 (2013-09-18) + Improve compatibility by removing ternary operator from initializations (issue 88) + Fix build error on Visual C++ (issue 84, patch by Markus Schwarzenberg) + Don't stop on unsupported extension fields (issue 83) + Add an example pb_syshdr.h file for non-C99 compilers + Reorganize tests and examples into subfolders (issue 63) + Switch from Makefiles to scons for building the tests + Make the tests buildable on Windows + +nanopb-0.2.2 (2013-08-18) + Add support for extension fields (issue 17) + Fix unknown fields in empty message (issue 78) + Include the field tags in the generated .pb.h file. + Add pb_decode_delimited and pb_encode_delimited wrapper functions (issue 74) + Add a section in top of pb.h for changing compilation settings (issue 76) + Documentation improvements (issues 12, 77 and others) + Improved tests + +nanopb-0.2.1 (2013-04-14) + NOTE: The default callback function signature has changed. + If you don't want to update your code, define PB_OLD_CALLBACK_STYLE. + + Change the callback function to use void** (issue 69) + Add support for defining the nanopb options in a separate file (issue 12) + Add support for packed structs in IAR and MSVC (in addition to GCC) (issue 66) + Implement error message support for the encoder side (issue 7) + Handle unterminated strings when encoding (issue 68) + Fix bug with empty strings in repeated string callbacks (issue 73) + Fix regression in 0.2.0 with optional callback fields (issue 70) + Fix bugs with empty message types (issues 64, 65) + Fix some compiler warnings on clang (issue 67) + Some portability improvements (issues 60, 62) + Various new generator options + Improved tests + +nanopb-0.2.0 (2013-03-02) + NOTE: This release requires you to regenerate all .pb.c + files. Files generated by older versions will not + compile anymore. + + Reformat generated .pb.c files using macros (issue 58) + Rename PB_HTYPE_ARRAY -> PB_HTYPE_REPEATED + Separate PB_HTYPE to PB_ATYPE and PB_HTYPE + Move STATIC_ASSERTs to .pb.c file + Added CMake file (by Pavel Ilin) + Add option to give file extension to generator (by Michael Haberler) + Documentation updates + +nanopb-0.1.9 (2013-02-13) + Fixed error message bugs (issues 52, 56) + Sanitize #ifndef filename (issue 50) + Performance improvements + Add compile-time option PB_BUFFER_ONLY + Add Java package name to nanopb.proto + Check for sizeof(double) == 8 (issue 54) + Added generator option to ignore some fields. (issue 51) + Added generator option to make message structs packed. (issue 49) + Add more test cases. + +nanopb-0.1.8 (2012-12-13) + Fix bugs in the enum short names introduced in 0.1.7 (issues 42, 43) + Fix STATIC_ASSERT macro when using multiple .proto files. (issue 41) + Fix missing initialization of istream.errmsg + Make tests/Makefile work for non-gcc compilers (issue 40) + +nanopb-0.1.7 (2012-11-11) + Remove "skip" mode from pb_istream_t callbacks. Example implementation had a bug. (issue 37) + Add option to use shorter names for enum values (issue 38) + Improve options support in generator (issues 12, 30) + Add nanopb version number to generated files (issue 36) + Add extern "C" to generated headers (issue 35) + Add names for structs to allow forward declaration (issue 39) + Add buffer size check in example (issue 34) + Fix build warnings on MS compilers (issue 33) + +nanopb-0.1.6 (2012-09-02) + Reorganize the field decoder interface (issue 2) + Improve performance in submessage decoding (issue 28) + Implement error messages in the decoder side (issue 7) + Extended testcases (alltypes test is now complete). + Fix some compiler warnings (issues 25, 26, 27, 32). + +nanopb-0.1.5 (2012-08-04) + Fix bug in decoder with packed arrays (issue 23). + Extended testcases. + Fix some compiler warnings. + +nanopb-0.1.4 (2012-07-05) + Add compile-time options for easy-to-use >255 field support. + Improve the detection of missing required fields. + Added example on how to handle union messages. + Fix generator error with .proto without messages. + Fix problems that stopped the code from compiling with some compilers. + Fix some compiler warnings. + +nanopb-0.1.3 (2012-06-12) + Refactor the field encoder interface. + Improve generator error messages (issue 5) + Add descriptor.proto into the #include exclusion list + Fix some compiler warnings. + +nanopb-0.1.2 (2012-02-15) + Make the generator to generate include for other .proto files (issue 4). + Fixed generator not working on Windows (issue 3) + +nanopb-0.1.1 (2012-01-14) + Fixed bug in encoder with 'bytes' fields (issue 1). + Fixed a bug in the generator that caused a compiler error on sfixed32 and sfixed64 fields. + Extended testcases. + +nanopb-0.1.0 (2012-01-06) + First stable release. diff --git a/hardware-wallet/firmware/vendor/nanopb/CMakeLists.txt b/hardware-wallet/firmware/vendor/nanopb/CMakeLists.txt new file mode 100644 index 00000000..c013d377 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/CMakeLists.txt @@ -0,0 +1,90 @@ +cmake_minimum_required(VERSION 2.8) + +project(nanopb C) + +set(nanopb_VERSION_STRING nanopb-0.3.9) + +string(REPLACE "nanopb-" "" nanopb_VERSION ${nanopb_VERSION_STRING}) + +option(nanopb_BUILD_RUNTIME "Build the headers and libraries needed at runtime" ON) +option(nanopb_BUILD_GENERATOR "Build the protoc plugin for code generation" ON) +option(nanopb_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON) + +if(NOT DEFINED CMAKE_DEBUG_POSTFIX) + set(CMAKE_DEBUG_POSTFIX "d") +endif() + +include(GNUInstallDirs) + +if(MSVC AND nanopb_MSVC_STATIC_RUNTIME) + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif(${flag_var} MATCHES "/MD") + endforeach(flag_var) +endif() + +if(NOT DEFINED CMAKE_INSTALL_CMAKEDIR) + set(CMAKE_INSTALL_CMAKEDIR "lib/cmake/nanopb") +endif() + +if(nanopb_BUILD_GENERATOR) + set(generator_protos nanopb plugin) + + find_package(PythonInterp 2.7 REQUIRED) + execute_process( + COMMAND ${PYTHON_EXECUTABLE} -c + "from distutils import sysconfig; print(sysconfig.get_python_lib(prefix='${CMAKE_INSTALL_PREFIX}'))" + OUTPUT_VARIABLE PYTHON_INSTDIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + foreach(generator_proto IN LISTS generator_protos) + string(REGEX REPLACE "([^;]+)" "${PROJECT_SOURCE_DIR}/generator/proto/\\1.proto" generator_proto_file "${generator_proto}") + string(REGEX REPLACE "([^;]+)" "\\1_pb2.py" generator_proto_py_file "${generator_proto}") + add_custom_command( + OUTPUT ${generator_proto_py_file} + COMMAND protoc --python_out=${PROJECT_BINARY_DIR} -I${PROJECT_SOURCE_DIR}/generator/proto ${generator_proto_file} + DEPENDS ${generator_proto_file} + ) + add_custom_target("generate_${generator_proto_py_file}" ALL DEPENDS ${generator_proto_py_file}) + install( + FILES ${PROJECT_BINARY_DIR}/${generator_proto_py_file} + DESTINATION ${PYTHON_INSTDIR} + ) + endforeach() +endif() + +if(nanopb_BUILD_RUNTIME) + add_library(protobuf-nanopb STATIC + pb.h + pb_common.h + pb_common.c + pb_encode.h + pb_encode.c + pb_decode.h + pb_decode.c) + + target_include_directories(protobuf-nanopb INTERFACE + $ + ) + + configure_file(extra/nanopb-config-version.cmake.in + nanopb-config-version.cmake @ONLY) + + install(TARGETS protobuf-nanopb EXPORT nanopb-targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + + install(EXPORT nanopb-targets + DESTINATION ${CMAKE_INSTALL_CMAKEDIR} + NAMESPACE nanopb::) + + install(FILES extra/nanopb-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/nanopb-config-version.cmake + DESTINATION ${CMAKE_INSTALL_CMAKEDIR}) + + install(FILES pb.h pb_common.h pb_encode.h pb_decode.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +endif() diff --git a/hardware-wallet/firmware/vendor/nanopb/CONTRIBUTING.md b/hardware-wallet/firmware/vendor/nanopb/CONTRIBUTING.md new file mode 100644 index 00000000..4041bc3c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/CONTRIBUTING.md @@ -0,0 +1,32 @@ +Contributing to Nanopb development +================================== + +Reporting issues and requesting features +---------------------------------------- + +Feel free to report any issues you see or features you would like +to see in the future to the Github issue tracker. Using the templates +below is preferred: + +* [Report a bug](https://github.com/nanopb/nanopb/issues/new?body=**Steps%20to%20reproduce%20the%20issue**%0a%0a1.%0a2.%0a3.%0a%0a**What%20happens?**%0A%0A**What%20should%20happen?**&labels=Type-Defect) +* [Request a feature](https://github.com/nanopb/nanopb/issues/new?body=**What%20should%20the%20feature%20do?**%0A%0A**In%20what%20situation%20would%20the%20feature%20be%20useful?**&labels=Type-Enhancement) + +Requesting help +--------------- + +If there is something strange going on, but you do not know if +it is actually a bug in nanopb, try asking first on the +[discussion forum](https://groups.google.com/forum/#!forum/nanopb). + +Pull requests +------------- + +Pull requests are welcome! + +If it is not obvious from the commit message, please indicate the +same information as you would for an issue report: + +* What functionality it fixes/adds. +* How can the problem be reproduced / when would the feature be useful. + + diff --git a/hardware-wallet/firmware/vendor/nanopb/LICENSE.txt b/hardware-wallet/firmware/vendor/nanopb/LICENSE.txt new file mode 100644 index 00000000..d11c9af1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Petteri Aimonen + +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. diff --git a/hardware-wallet/firmware/vendor/nanopb/README.md b/hardware-wallet/firmware/vendor/nanopb/README.md new file mode 100644 index 00000000..07860f06 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/README.md @@ -0,0 +1,71 @@ +Nanopb - Protocol Buffers for Embedded Systems +============================================== + +[![Build Status](https://travis-ci.org/nanopb/nanopb.svg?branch=master)](https://travis-ci.org/nanopb/nanopb) + +Nanopb is a small code-size Protocol Buffers implementation in ansi C. It is +especially suitable for use in microcontrollers, but fits any memory +restricted system. + +* **Homepage:** https://jpa.kapsi.fi/nanopb/ +* **Documentation:** https://jpa.kapsi.fi/nanopb/docs/ +* **Downloads:** https://jpa.kapsi.fi/nanopb/download/ +* **Forum:** https://groups.google.com/forum/#!forum/nanopb + + + +Using the nanopb library +------------------------ +To use the nanopb library, you need to do two things: + +1. Compile your .proto files for nanopb, using protoc. +2. Include pb_encode.c, pb_decode.c and pb_common.c in your project. + +The easiest way to get started is to study the project in "examples/simple". +It contains a Makefile, which should work directly under most Linux systems. +However, for any other kind of build system, see the manual steps in +README.txt in that folder. + + + +Using the Protocol Buffers compiler (protoc) +-------------------------------------------- +The nanopb generator is implemented as a plugin for the Google's own protoc +compiler. This has the advantage that there is no need to reimplement the +basic parsing of .proto files. However, it does mean that you need the +Google's protobuf library in order to run the generator. + +If you have downloaded a binary package for nanopb (either Windows, Linux or +Mac OS X version), the 'protoc' binary is included in the 'generator-bin' +folder. In this case, you are ready to go. Simply run this command: + + generator-bin/protoc --nanopb_out=. myprotocol.proto + +However, if you are using a git checkout or a plain source distribution, you +need to provide your own version of protoc and the Google's protobuf library. +On Linux, the necessary packages are protobuf-compiler and python-protobuf. +On Windows, you can either build Google's protobuf library from source or use +one of the binary distributions of it. In either case, if you use a separate +protoc, you need to manually give the path to nanopb generator: + + protoc --plugin=protoc-gen-nanopb=nanopb/generator/protoc-gen-nanopb ... + + + +Running the tests +----------------- +If you want to perform further development of the nanopb core, or to verify +its functionality using your compiler and platform, you'll want to run the +test suite. The build rules for the test suite are implemented using Scons, +so you need to have that installed. To run the tests: + + cd tests + scons + +This will show the progress of various test cases. If the output does not +end in an error, the test cases were successful. + +Note: Mac OS X by default aliases 'clang' as 'gcc', while not actually +supporting the same command line options as gcc does. To run tests on +Mac OS X, use: "scons CC=clang CXX=clang". Same way can be used to run +tests with different compilers on any platform. diff --git a/hardware-wallet/firmware/vendor/nanopb/WORKSPACE b/hardware-wallet/firmware/vendor/nanopb/WORKSPACE new file mode 100644 index 00000000..2837cb37 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/WORKSPACE @@ -0,0 +1 @@ +workspace(name="com_github_nanopb_nanopb") diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/Makefile b/hardware-wallet/firmware/vendor/nanopb/docs/Makefile new file mode 100644 index 00000000..0dbd97cf --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/Makefile @@ -0,0 +1,9 @@ +all: index.html concepts.html reference.html security.html migration.html \ + generator_flow.png + +%.png: %.svg + rsvg $< $@ + +%.html: %.rst + rst2html --stylesheet=lsr.css --link-stylesheet $< $@ + sed -i 's!!\n!' $@ diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/concepts.rst b/hardware-wallet/firmware/vendor/nanopb/docs/concepts.rst new file mode 100644 index 00000000..2e0d3f9b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/concepts.rst @@ -0,0 +1,392 @@ +====================== +Nanopb: Basic concepts +====================== + +.. include :: menu.rst + +The things outlined here are the underlying concepts of the nanopb design. + +.. contents:: + +Proto files +=========== +All Protocol Buffers implementations use .proto files to describe the message +format. The point of these files is to be a portable interface description +language. + +Compiling .proto files for nanopb +--------------------------------- +Nanopb uses the Google's protoc compiler to parse the .proto file, and then a +python script to generate the C header and source code from it:: + + user@host:~$ protoc -omessage.pb message.proto + user@host:~$ python ../generator/nanopb_generator.py message.pb + Writing to message.h and message.c + user@host:~$ + +Modifying generator behaviour +----------------------------- +Using generator options, you can set maximum sizes for fields in order to +allocate them statically. The preferred way to do this is to create an .options +file with the same name as your .proto file:: + + # Foo.proto + message Foo { + required string name = 1; + } + +:: + + # Foo.options + Foo.name max_size:16 + +For more information on this, see the `Proto file options`_ section in the +reference manual. + +.. _`Proto file options`: reference.html#proto-file-options + +Streams +======= + +Nanopb uses streams for accessing the data in encoded format. +The stream abstraction is very lightweight, and consists of a structure (*pb_ostream_t* or *pb_istream_t*) which contains a pointer to a callback function. + +There are a few generic rules for callback functions: + +#) Return false on IO errors. The encoding or decoding process will abort immediately. +#) Use state to store your own data, such as a file descriptor. +#) *bytes_written* and *bytes_left* are updated by pb_write and pb_read. +#) Your callback may be used with substreams. In this case *bytes_left*, *bytes_written* and *max_size* have smaller values than the original stream. Don't use these values to calculate pointers. +#) Always read or write the full requested length of data. For example, POSIX *recv()* needs the *MSG_WAITALL* parameter to accomplish this. + +Output streams +-------------- + +:: + + struct _pb_ostream_t + { + bool (*callback)(pb_ostream_t *stream, const uint8_t *buf, size_t count); + void *state; + size_t max_size; + size_t bytes_written; + }; + +The *callback* for output stream may be NULL, in which case the stream simply counts the number of bytes written. In this case, *max_size* is ignored. + +Otherwise, if *bytes_written* + bytes_to_be_written is larger than *max_size*, pb_write returns false before doing anything else. If you don't want to limit the size of the stream, pass SIZE_MAX. + +**Example 1:** + +This is the way to get the size of the message without storing it anywhere:: + + Person myperson = ...; + pb_ostream_t sizestream = {0}; + pb_encode(&sizestream, Person_fields, &myperson); + printf("Encoded size is %d\n", sizestream.bytes_written); + +**Example 2:** + +Writing to stdout:: + + bool callback(pb_ostream_t *stream, const uint8_t *buf, size_t count) + { + FILE *file = (FILE*) stream->state; + return fwrite(buf, 1, count, file) == count; + } + + pb_ostream_t stdoutstream = {&callback, stdout, SIZE_MAX, 0}; + +Input streams +------------- +For input streams, there is one extra rule: + +#) You don't need to know the length of the message in advance. After getting EOF error when reading, set bytes_left to 0 and return false. Pb_decode will detect this and if the EOF was in a proper position, it will return true. + +Here is the structure:: + + struct _pb_istream_t + { + bool (*callback)(pb_istream_t *stream, uint8_t *buf, size_t count); + void *state; + size_t bytes_left; + }; + +The *callback* must always be a function pointer. *Bytes_left* is an upper limit on the number of bytes that will be read. You can use SIZE_MAX if your callback handles EOF as described above. + +**Example:** + +This function binds an input stream to stdin: + +:: + + bool callback(pb_istream_t *stream, uint8_t *buf, size_t count) + { + FILE *file = (FILE*)stream->state; + bool status; + + if (buf == NULL) + { + while (count-- && fgetc(file) != EOF); + return count == 0; + } + + status = (fread(buf, 1, count, file) == count); + + if (feof(file)) + stream->bytes_left = 0; + + return status; + } + + pb_istream_t stdinstream = {&callback, stdin, SIZE_MAX}; + +Data types +========== + +Most Protocol Buffers datatypes have directly corresponding C datatypes, such as int32 is int32_t, float is float and bool is bool. However, the variable-length datatypes are more complex: + +1) Strings, bytes and repeated fields of any type map to callback functions by default. +2) If there is a special option *(nanopb).max_size* specified in the .proto file, string maps to null-terminated char array and bytes map to a structure containing a char array and a size field. +3) If *(nanopb).fixed_length* is set to *true* and *(nanopb).max_size* is also set, then bytes map to an inline byte array of fixed size. +4) If there is a special option *(nanopb).max_count* specified on a repeated field, it maps to an array of whatever type is being repeated. Another field will be created for the actual number of entries stored. + +=============================================================================== ======================= + field in .proto autogenerated in .h +=============================================================================== ======================= +required string name = 1; pb_callback_t name; +required string name = 1 [(nanopb).max_size = 40]; char name[40]; +repeated string name = 1 [(nanopb).max_size = 40]; pb_callback_t name; +repeated string name = 1 [(nanopb).max_size = 40, (nanopb).max_count = 5]; | size_t name_count; + | char name[5][40]; +required bytes data = 1 [(nanopb).max_size = 40]; | typedef struct { + | size_t size; + | pb_byte_t bytes[40]; + | } Person_data_t; + | Person_data_t data; +required bytes data = 1 [(nanopb).max_size = 40, (nanopb).fixed_length = true]; | pb_byte_t data[40]; +=============================================================================== ======================= + +The maximum lengths are checked in runtime. If string/bytes/array exceeds the allocated length, *pb_decode* will return false. + +Note: for the *bytes* datatype, the field length checking may not be exact. +The compiler may add some padding to the *pb_bytes_t* structure, and the nanopb runtime doesn't know how much of the structure size is padding. Therefore it uses the whole length of the structure for storing data, which is not very smart but shouldn't cause problems. In practise, this means that if you specify *(nanopb).max_size=5* on a *bytes* field, you may be able to store 6 bytes there. For the *string* field type, the length limit is exact. + +Field callbacks +=============== +When a field has dynamic length, nanopb cannot statically allocate storage for it. Instead, it allows you to handle the field in whatever way you want, using a callback function. + +The `pb_callback_t`_ structure contains a function pointer and a *void* pointer called *arg* you can use for passing data to the callback. If the function pointer is NULL, the field will be skipped. A pointer to the *arg* is passed to the function, so that it can modify it and retrieve the value. + +The actual behavior of the callback function is different in encoding and decoding modes. In encoding mode, the callback is called once and should write out everything, including field tags. In decoding mode, the callback is called repeatedly for every data item. + +.. _`pb_callback_t`: reference.html#pb-callback-t + +Encoding callbacks +------------------ +:: + + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); + +When encoding, the callback should write out complete fields, including the wire type and field number tag. It can write as many or as few fields as it likes. For example, if you want to write out an array as *repeated* field, you should do it all in a single call. + +Usually you can use `pb_encode_tag_for_field`_ to encode the wire type and tag number of the field. However, if you want to encode a repeated field as a packed array, you must call `pb_encode_tag`_ instead to specify a wire type of *PB_WT_STRING*. + +If the callback is used in a submessage, it will be called multiple times during a single call to `pb_encode`_. In this case, it must produce the same amount of data every time. If the callback is directly in the main message, it is called only once. + +.. _`pb_encode`: reference.html#pb-encode +.. _`pb_encode_tag_for_field`: reference.html#pb-encode-tag-for-field +.. _`pb_encode_tag`: reference.html#pb-encode-tag + +This callback writes out a dynamically sized string:: + + bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) + { + char *str = get_string_from_somewhere(); + if (!pb_encode_tag_for_field(stream, field)) + return false; + + return pb_encode_string(stream, (uint8_t*)str, strlen(str)); + } + +Decoding callbacks +------------------ +:: + + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + +When decoding, the callback receives a length-limited substring that reads the contents of a single field. The field tag has already been read. For *string* and *bytes*, the length value has already been parsed, and is available at *stream->bytes_left*. + +The callback will be called multiple times for repeated fields. For packed fields, you can either read multiple values until the stream ends, or leave it to `pb_decode`_ to call your function over and over until all values have been read. + +.. _`pb_decode`: reference.html#pb-decode + +This callback reads multiple integers and prints them:: + + bool read_ints(pb_istream_t *stream, const pb_field_t *field, void **arg) + { + while (stream->bytes_left) + { + uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + printf("%lld\n", value); + } + return true; + } + +Field description array +======================= + +For using the *pb_encode* and *pb_decode* functions, you need an array of pb_field_t constants describing the structure you wish to encode. This description is usually autogenerated from .proto file. + +For example this submessage in the Person.proto file:: + + message Person { + message PhoneNumber { + required string number = 1 [(nanopb).max_size = 40]; + optional PhoneType type = 2 [default = HOME]; + } + } + +generates this field description array for the structure *Person_PhoneNumber*:: + + const pb_field_t Person_PhoneNumber_fields[3] = { + PB_FIELD( 1, STRING , REQUIRED, STATIC, Person_PhoneNumber, number, number, 0), + PB_FIELD( 2, ENUM , OPTIONAL, STATIC, Person_PhoneNumber, type, number, &Person_PhoneNumber_type_default), + PB_LAST_FIELD + }; + +Oneof +===== +Protocol Buffers supports `oneof`_ sections. Here is an example of ``oneof`` usage:: + + message MsgType1 { + required int32 value = 1; + } + + message MsgType2 { + required bool value = 1; + } + + message MsgType3 { + required int32 value1 = 1; + required int32 value2 = 2; + } + + message MyMessage { + required uint32 uid = 1; + required uint32 pid = 2; + required uint32 utime = 3; + + oneof payload { + MsgType1 msg1 = 4; + MsgType2 msg2 = 5; + MsgType3 msg3 = 6; + } + } + +Nanopb will generate ``payload`` as a C union and add an additional field ``which_payload``:: + + typedef struct _MyMessage { + uint32_t uid; + uint32_t pid; + uint32_t utime; + pb_size_t which_payload; + union { + MsgType1 msg1; + MsgType2 msg2; + MsgType3 msg3; + } payload; + /* @@protoc_insertion_point(struct:MyMessage) */ + } MyMessage; + +``which_payload`` indicates which of the ``oneof`` fields is actually set. +The user is expected to set the filed manually using the correct field tag:: + + MyMessage msg = MyMessage_init_zero; + msg.payload.msg2.value = true; + msg.which_payload = MyMessage_msg2_tag; + +Notice that neither ``which_payload`` field nor the unused fileds in ``payload`` +will consume any space in the resulting encoded message. + +.. _`oneof`: https://developers.google.com/protocol-buffers/docs/reference/proto2-spec#oneof_and_oneof_field + +Extension fields +================ +Protocol Buffers supports a concept of `extension fields`_, which are +additional fields to a message, but defined outside the actual message. +The definition can even be in a completely separate .proto file. + +The base message is declared as extensible by keyword *extensions* in +the .proto file:: + + message MyMessage { + .. fields .. + extensions 100 to 199; + } + +For each extensible message, *nanopb_generator.py* declares an additional +callback field called *extensions*. The field and associated datatype +*pb_extension_t* forms a linked list of handlers. When an unknown field is +encountered, the decoder calls each handler in turn until either one of them +handles the field, or the list is exhausted. + +The actual extensions are declared using the *extend* keyword in the .proto, +and are in the global namespace:: + + extend MyMessage { + optional int32 myextension = 100; + } + +For each extension, *nanopb_generator.py* creates a constant of type +*pb_extension_type_t*. To link together the base message and the extension, +you have to: + +1. Allocate storage for your field, matching the datatype in the .proto. + For example, for a *int32* field, you need a *int32_t* variable to store + the value. +2. Create a *pb_extension_t* constant, with pointers to your variable and + to the generated *pb_extension_type_t*. +3. Set the *message.extensions* pointer to point to the *pb_extension_t*. + +An example of this is available in *tests/test_encode_extensions.c* and +*tests/test_decode_extensions.c*. + +.. _`extension fields`: https://developers.google.com/protocol-buffers/docs/proto#extensions + +Message framing +=============== +Protocol Buffers does not specify a method of framing the messages for transmission. +This is something that must be provided by the library user, as there is no one-size-fits-all +solution. Typical needs for a framing format are to: + +1. Encode the message length. +2. Encode the message type. +3. Perform any synchronization and error checking that may be needed depending on application. + +For example UDP packets already fullfill all the requirements, and TCP streams typically only +need a way to identify the message length and type. Lower level interfaces such as serial ports +may need a more robust frame format, such as HDLC (high-level data link control). + +Nanopb provides a few helpers to facilitate implementing framing formats: + +1. Functions *pb_encode_delimited* and *pb_decode_delimited* prefix the message data with a varint-encoded length. +2. Union messages and oneofs are supported in order to implement top-level container messages. +3. Message IDs can be specified using the *(nanopb_msgopt).msgid* option and can then be accessed from the header. + +Return values and error handling +================================ + +Most functions in nanopb return bool: *true* means success, *false* means failure. There is also some support for error messages for debugging purposes: the error messages go in *stream->errmsg*. + +The error messages help in guessing what is the underlying cause of the error. The most common error conditions are: + +1) Running out of memory, i.e. stack overflow. +2) Invalid field descriptors (would usually mean a bug in the generator). +3) IO errors in your own stream callbacks. +4) Errors that happen in your callback functions. +5) Exceeding the max_size or bytes_left of a stream. +6) Exceeding the max_size of a string or array field +7) Invalid protocol buffers binary message. diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/generator_flow.svg b/hardware-wallet/firmware/vendor/nanopb/docs/generator_flow.svg new file mode 100644 index 00000000..e30277a7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/generator_flow.svg @@ -0,0 +1,2869 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyMessage.proto + + + pb_encode( ); + pb_decode( ); + + + nanopb_generator.py + + + + + + + + + + + + + + + + + + MyMessage.pb.c + MyMessage.pb.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + c + + Nanopb library + + + + Protocol Buffersmessages + + + + + + + + + + + + + + + + + + + + + Data structures + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + User application + + + diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/index.rst b/hardware-wallet/firmware/vendor/nanopb/docs/index.rst new file mode 100644 index 00000000..afc7ee4f --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/index.rst @@ -0,0 +1,127 @@ +============================================= +Nanopb: Protocol Buffers with small code size +============================================= + +.. include :: menu.rst + +Nanopb is an ANSI-C library for encoding and decoding messages in Google's `Protocol Buffers`__ format with minimal requirements for RAM and code space. +It is primarily suitable for 32-bit microcontrollers. + +__ https://developers.google.com/protocol-buffers/docs/reference/overview + +Overall structure +================= + +For the runtime program, you always need *pb.h* for type declarations. +Depending on whether you want to encode, decode, or both, you also need *pb_encode.h/c* or *pb_decode.h/c*. + +The high-level encoding and decoding functions take an array of *pb_field_t* structures, which describes the fields of a message structure. Usually you want these autogenerated from a *.proto* file. The tool script *nanopb_generator.py* accomplishes this. + +.. image:: generator_flow.png + +So a typical project might include these files: + +1) Nanopb runtime library: + - pb.h + - pb_common.h and pb_common.c (always needed) + - pb_decode.h and pb_decode.c (needed for decoding messages) + - pb_encode.h and pb_encode.c (needed for encoding messages) +2) Protocol description (you can have many): + - person.proto (just an example) + - person.pb.c (autogenerated, contains initializers for const arrays) + - person.pb.h (autogenerated, contains type declarations) + +Features and limitations +======================== + +**Features** + +#) Pure C runtime +#) Small code size (2–10 kB depending on processor, plus any message definitions) +#) Small ram usage (typically ~300 bytes, plus any message structs) +#) Allows specifying maximum size for strings and arrays, so that they can be allocated statically. +#) No malloc needed: everything can be allocated statically or on the stack. Optional malloc support available. +#) You can use either encoder or decoder alone to cut the code size in half. +#) Support for most protobuf features, including: all data types, nested submessages, default values, repeated and optional fields, oneofs, packed arrays, extension fields. +#) Callback mechanism for handling messages larger than can fit in available RAM. +#) Extensive set of tests. + +**Limitations** + +#) Some speed has been sacrificed for code size. +#) Encoding is focused on writing to streams. For memory buffers only it could be made more efficient. +#) The deprecated Protocol Buffers feature called "groups" is not supported. +#) Fields in the generated structs are ordered by the tag number, instead of the natural ordering in .proto file. +#) Unknown fields are not preserved when decoding and re-encoding a message. +#) Reflection (runtime introspection) is not supported. E.g. you can't request a field by giving its name in a string. +#) Numeric arrays are always encoded as packed, even if not marked as packed in .proto. +#) Cyclic references between messages are supported only in callback and malloc mode. + +Getting started +=============== + +For starters, consider this simple message:: + + message Example { + required int32 value = 1; + } + +Save this in *message.proto* and compile it:: + + user@host:~$ protoc -omessage.pb message.proto + user@host:~$ python nanopb/generator/nanopb_generator.py message.pb + +You should now have in *message.pb.h*:: + + typedef struct { + int32_t value; + } Example; + + extern const pb_field_t Example_fields[2]; + +Now in your main program do this to encode a message:: + + Example mymessage = {42}; + uint8_t buffer[10]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + pb_encode(&stream, Example_fields, &mymessage); + +After that, buffer will contain the encoded message. +The number of bytes in the message is stored in *stream.bytes_written*. +You can feed the message to *protoc --decode=Example message.proto* to verify its validity. + +For a complete example of the simple case, see *example/simple.c*. +For a more complex example with network interface, see the *example/network_server* subdirectory. + +Compiler requirements +===================== +Nanopb should compile with most ansi-C compatible compilers. It however +requires a few header files to be available: + +#) *string.h*, with these functions: *strlen*, *memcpy*, *memset* +#) *stdint.h*, for definitions of *int32_t* etc. +#) *stddef.h*, for definition of *size_t* +#) *stdbool.h*, for definition of *bool* + +If these header files do not come with your compiler, you can use the +file *extra/pb_syshdr.h* instead. It contains an example of how to provide +the dependencies. You may have to edit it a bit to suit your custom platform. + +To use the pb_syshdr.h, define *PB_SYSTEM_HEADER* as *"pb_syshdr.h"* (including the quotes). +Similarly, you can provide a custom include file, which should provide all the dependencies +listed above. + +Running the test cases +====================== +Extensive unittests and test cases are included under the *tests* folder. + +To build the tests, you will need the `scons`__ build system. The tests should +be runnable on most platforms. Windows and Linux builds are regularly tested. + +__ http://www.scons.org/ + +In addition to the build system, you will also need a working Google Protocol +Buffers *protoc* compiler, and the Python bindings for Protocol Buffers. On +Debian-based systems, install the following packages: *protobuf-compiler*, +*python-protobuf* and *libprotobuf-dev*. + diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo.png b/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9534fa165cda53a29a848848c2e0a4c5ead3e5 GIT binary patch literal 14973 zcmZvDby!qi)b$-g1`ruKM7pF?x`siz1f)X&LApBz1PMv$F6kIRLK;QMpEL|2DIne5 z@AZA3@4s&zhGBSS?m1`QefC~^t$m`jG!zN&sPO;*AW&99yZ~Rj|2?4(z~3+C9B{xF zEO)rFE);wOK&>Ld_qZ-fhVB3$V*2k1p+Y_f{{W~w6bw9coZonOzjCt%yuH17-a6U4 zTfTC!=5cnj$=Z{o1^{|M86l_Zlf4`0n{J}ea(Atlv+(BQz&GZk3@$;ECRsQJw8n?G z3>V7mzzD@KBhu=|kB;6@Fw~Wm`_5Ttf*89{GqGrV8fYGnhxQ{C0GmpZb25 zR=7Ctf9G@Vgyx+AzLt`-d09%#e`lJcCS0?hGiCx7oJjTT<2WVeqf}TSiLAG=v9auX z0GpDNtY39RKVJRu#NJQ3;PbY{9G?-X^MC*s7nh6`(TFcK#%y8qz4ZYMgRErmRS~pj zL3>`0*di%jIBhI~vCAr^0|sO4HXzA2DX@9J{pDzo^Ko9_*{}H1^K-hS0jmX;FenL8 z7|bF@4w^_20QkQ0HWleY576(|aaBg}pZTzpUJ_k(5Ma(AF@nHc|)Q9Z?PG*jc+)Xr5)yQ0)N z6V`gW2+bq&AC%Y1pjApT=~%lj5RFhRm9;VKJWlisD(JLwzAt zI*x8u45eho(02X5RCwX7-!K(yUp2%ZU2A6qABJ-Th(Wfl9Rcv_y^-cpHS%xCs zzn7+nLKtw7%Y#2c)C$bRa-uZP*-1mK4M(RKT9nV(fT9qS`laYs+{czNYq;#j1s>v3 z+=)t(pIw%}-BZuA;qm2aE8|;4|JKGf*YiC3-H0}8JGYFN@?t~YGA2Ud1+Z_+E^Y`v__7@)bLx zxv}v!)V(u}G|2Q65-riF3u$)zodi^HSiJ}t^wsBWla*#7{~-0saC$s{aVaNctU}hT zu`3GeA<%W$``89$(sJbW^u{fzv8%PbMl(MFb`?|=da0|YI?t9gz!JAIC(TMoP&=W` z{a99tm+|ZIhzwoZ{oQr&8^f1H6^p7*%=h%3n1`EjX6e$*{}7|@_dj(jtH^+1L?QlU zhvQQOy_zJ%<8$JpChONcN6%*mSXj_|{KwyS^WAfv1YC7uVx_kiB)l_7@5iA|aQjJc zMqcZA=v`YH$ExTf(RB@V^`CX1pZmT3M90^CA;-dv)OU!#dTiX}@QXq)<3HT-nbV2$ zH8Tov(=VR-rD;PG9(&lRYY#m&;^`*GTs78x(+1nIPU|2PumZE>=T^ym*hlNXGxodL z`94&+OF!_&tg*^2Ak)sD1Xs;Yi=`q_1FLbTT(^QJLruEVcC2t#McM#q8j(nxpWGw0 zhcMo-*Z#~V*c30iHu&YK*&$Mb)a>Ua;RjYpYT`6p#@(g`EYWyx+TN3S>Jv8K} zg>;QboCSgw=!82X=v==OQ4kUm26NIpVxo>^qsc8XY)XUdn z(x7y z0;w-gmca3u^g`O-yzU>FskNJ`KoO5I8@6pfuX6m|tFG^_d#ZR2Y&N=d^6Bk76kOX> zc%ZytCEz<3ijDt>_Ou6c$3u4w7fsFr30Tc19P^_79N=LrzG4gbo;JfQ5eZJH6RiTu09nJdl z+rmvXf66dQx32|aH^0#MY~BZ9ooxHNm{JG}3vZ*VjnU$T;PqT=FwS z_wA~fn(4pwI4{u+JPF}pwWKIhyNKnr)^Z+f#9s9k&v6pl$bWZ+`oahC!mIfEpkpOY zVySiS^=+#;`#b%BF0a3j5v7t5D*>g_2^(GAd_aOg?=ei!|7_gJ?taNwRYhT`QDUGuYQ3;>(Zo0=T^74n2HK5 zTI|qg#knYH^vI*peMo+Vyt|iC0cH%fo?vK{t%?(&g~wR>m6=Qpxmtx@OD-Ksowp12 z`ppzRZT?mn9wd^T*+1BtfQSFZ^4LC=s!zF05mC_ToeAfdP)RtU7MZRBHeN(elGwVZ zpU>wgn7BuZO_g@dsK2QQZs*-Fu+-|bqT!PRkQH)Zl~q>Shx~zjWJ=V)fqurva$wDIZ*aoozJ z{>it0Hwz9hQcq-zb8#B0{ceI-4S+j{Pe>>XmxOgSitoh*Zs${>o=;c(w>1twFk)!+ z7?3NXk9$=BFphH#4H5=UdLHclZtiiVK@@2lq^>Dr$&7rg*effTvD^8Wwud_R8WM`B z%dH5C1S~@!@1N788MYpqnXKOkMTV4LPLufgXb_N6MDBsdpRf^+(bwyBRDu$vSDI znZ7AFuLlnvBn()=VxJSmK0iJt^yRMpguZecvJ%Mc;Z?s2YE(1&Z=xw$Mi$Ahs0XDF zbFmrD{>2-Xt{Z#9JPA2HG9WYY<#7zP62L`!CJtB~367Re@N991=z3aJqqc5JXw7}| zT0!h0V_k@dgBn*{a%030RJ3TgpkS{xgdHK}{;Eor24rea%ShNX5a#CQ3tHriZEi7d z&)!~Uaon^H7D@L_ZUO9eiIZepQMNi$(g-BKyfE&lBXP2dE<*=->SvV=j+nW=*ZiMe zlw)Yd{ipaOqlBcJbJDQ$o$`fVdZZj8rzq&~-@ai2EO!(Dy2N$XWf9zXI=N32&+)3O zOg)MF+wJY`@uBn+%F8e18#|^+6MQerWv(O!1qN@phlmj;CM}CR-8J%4q01)d4ppn= za(KGM3&F`*Q@n<9mIR&3A#PHlUw#;iiC#w1?% zWE|o}T_G+ZL?l&%E)gFj5@L}NgE(r_#7(YGDLh-v#Psy^^nItF7vIl(Q6i95bX~cY zd`fLvm z=*(y?b$A4$ytQ`Iwb&c1=UY7;nQpxxUIY~?NP@@D+IL#_9?Z+@)MPHBIY3JnD!Yb+ z8a2zZL?aj#&X8zEzhVc#@azRWqd_WJ73Js01+&~h`R6w^kr!yOn@j6$aFPXGW--5FCiX4p=(y#bx+{V7KGI|Bo^7)2pd%s5_IwHyfMd-H@20#g zNnbZU;Xh8H{0!Z#p4%^g&RyaA5nCg`^D!;$bAb%5t)1~}99_nKmrXZEAirUcS7fLj z3>>S@``8EP14(RoGUSWTWIeS9CL=p%Z1Mv8U9&~PVAmPb7!NqI9)$D1f2vbLiq%@a zf_(y8pUcjf=?s*3|Ni~a=1JxP>S4uT(V09LPneUGrD%+RFCwIPIVACYN!A^@$ecKS zCIHy^JRcDtyKvvuh0_D8E$*g*4hdhOj3_;B9!){fg3@C zhq!6OMRV&@Uuz)Xb7|>%E1tA9lEbnTW^s3O2^L`oEPbwzAphxnN-K)<$-!qB9UVnx zW@bv_>OyoaLq3T!kE|Suj&C-g(iG{ghs656N09{2qS0)WmK0j#zWSA&Xx*-B?xCyI zCdc0xZ5A{Zr7!?EoA+LPJ7DG3xZSES@!r3MMwM#7?^jl4ChWrxyj066<@_`Dp<~D2 zO$e!kO2*%4084z;m!y|jbVY>nybRq6x2EbDB)zy_{?}j@LJBdUr0Mvrl zPa$DdGx#oMUWwnTe~*;Zk6KcQ)a3||i+l8G;;p4~-GUBRe9tmpiDsS|AJiO9c4xqK zrp8X1iT?FVtg1wrH3=ma=bo_L8eg^#_{4`Y6?Q~!5Kfe+w-s*DiOc?)dCQRyt?+?d z!O!2HPNVn*9ppxjp4Yr%Q(8G4Oj<%BA{5mxo<_VBkJCXA|87cDDXs-A7Rrz;)~KkK z&bQoDQ&aOnrNbCB8#-#ku9s3j_6-okF?I{CE(t{Dggc=*F{W@JO3eN5T(%N34-q_} zh9~{GeMa1r{gzY`tNOPp!_U!B`fyG2WMdXNN!pPS89T$5Z@z`$QuMAIN(=^~W@l#! ziN>6%Ed9%wwTww{6{h^c`I{VmH#vrw){@kz;sO9SH+LR2Ep6vi(=K&>0&wJp-XtDOCI?o#gQ>1k#qj+&t9t5f?{gWqhfnqOk?;P8F2TnAr? zzC#R%!Rp_Qpy~7VR#fb>FA79~)*BWx*Fe~8Fpo|#Vp9Q&b4`xMqvo|Fd^}M4x)JH? zhKB?Mw~~oUH>E40pPC=ALe4)EF@tW;=XZJ;e7Rk0gxlKrn+>-QC@F^H9piaAGJmG&Oa4+uCl}fCZbZ=SkY0;h{kEsU?su z=FYmcwH57v@ymQk4wz}0UlScx6c-nNsduCSW~5Tsm?=Vc8%>x?1&`DLE7>y-mXSvmym(06`D`;%Q|EY1kM<<=F!c^bd!9ErwoSQai}xDv5;?w! z=}TYn~{kVdb00| z4ws5cNbJ`%(CCz?wd6*27CxBpZBa>qqVvH0`1SA4tQ?g*ItxM;008e=ujqQb%W(V) z-27%NyD#D6)X+ZH&goyjd;^Qu(j|S5ej!eDdJS}0kX-NfS_V_L`O%)5yE{8H6(^Ve z;%5dJfGmiJK!S;X_%e8dIib-x3L-88n&A&<99`YVni&FXw}=ye#>^70>2j~=S1&&V zx74&X6ct&zTbsWc>7`W%09!}LoNlq;Z1+1z2id4{J_!SwQSy)I@LRAxFE4xcFB3Qb zny@j+oR}BFIusZEo{zj*Yy1O>d1j@kB!sCwBnvw_0!N#6<7b<02~pM`KOJluYbeF9 zWXnv<%oqp_zhd6l-QD$|SvLiabT}&tW?H2Z{O=rwFU_;EvfeGH7JaAH1OS7spj!}z ze*o(`4Z@ zVB_gF?1MMO*T%+1_)Zst-tGFujAJ-EJ@S2OYAWCQ4LbW+r#)=gSu1Wu^l6{#@GlTH zNTsA&U!833|IL=^r_3r)Y}h)cS8lG}Zar_Q@%K_xRD4YuU*+NWdtM_QgG{OC>U4V| zZYBH8?=#a@aos`Ien+C-nRx;N0`r;%u0x+2g+AAX-Bzcpx9_F8%Tfbl-0vo{#oSBM zE-7C;L)ou>P8qZ}VX}otj?T@gWgpYI4f8(peGQP7%Rgw`=!;vq0l8&w1*h@NiBiq~ zPHE_RgwbWQ&IJT?j@~ruGjVZoA`cBSu_iwq`QX;)jc#F5--m9uDiV*8GFD(}VbbpqHKZ-BKYQGr0DCP99aBW`zK0jk)tGk$ z&7BxyVX>2dbPI*+@O>KpbHD%M#I^bqpZE>AW?TCE`!7~CaK*;Pmbwn_zm8Ejc_i4# zqP3C{21A4J$-LUia`Ki?=H}qtzreM)>2alm_RONR{G`FMLe^LjgxN&^MA~v9OSy+y zKQ}df~)^`IK|aMqjPY5{4a%4 zVqkyJs;OL;|2a0#r+$6()druOOSHAC>s~NJ?QbAh##X*>H1W{-C<|xl+Pn?<(}-Rb z&UltK@*BuyDr^I{{JwFAU!&<}GZiidMhpye`cjwS;GdNESpi4lxDUDI#$B^NUteAA z{ol~nuETWJF}u|tyX&hkJeB5wo3+4w|HY?6X}pV_Aieoxetur2*3sX&@731RzE#W z-=&+m`J#GCYH?kit5FSVDR3*y-0nVH{HuXe7i*#tGss}c36L6-1^oJ`w5*Q{>=@9g zli8h80h2HLW-!uAI<%WaA~))r7yP!zRJt^uf}^lxW@S;h4AWW0{5+b7QvIUr>`Aje z9ug7~oq5~a+goOB*tMFSS4aY`tG!!1?p;9v12ge2X#vmdkk+)uV36TuCLUx zR7}GAbZ(q%&$&9@C5y;22kDkBj!WqvC{zmqj$$LwOKTm&t-A|JdR0{^KX_;kF6g4W zyL%ch8cry60&BbY^Py{q^16`Y=EW0g8k+A*OBS606$C~2GV7A&$BISTV7U|ua^0>c z8shJEwS_#UR0+oQ*crk&!+av$?=Bnd(OxePV*jJ#p_jEz7qroMVz~q9or&=D?2pGX zvakK&Ij@8B;6X0k^2%wh(N4$t0tFs})8A}&L;Lgdb0!d~hHGzh%(y)a&E^#*j-scI z{hL-WE-$Cco5XX%ijf{>w&?$h2p$OmY#N)JWempXN`kwQK#JvXwirY2OioOl=GIn1 z#dT^ezChfH$um*Wi!N*FCZ&tDLy(<|Q!Rec#auZ1_3PJ<%a2*-Wxx^0KdkA|cQhMv zcbTv#2GX^lv5jt7IjGdop1&2K%TR_IJ7?$nY1{kC!gxwpzMrj=)7>-69ecB9AvJ7S zI~ZusU@#l{Mj^gcuFsGLGpz`wOD=jZ20A~cq!i7H>?aj}^&-S-m)9OduJ2t$O&UhO zC?7NqVB#%koS&kJ8%_Ab@IFgUHle7SUWkw=>Goe)8s> zY3;0Qc2d&7su8!p&X-V9Ka6e=(q0yT1SyDKBvT_}I(~q1L5~|HInuU zGHJe3`ioJ=@|^mpnJuMAwXJ?sJu~{^vOEOhG0|V|Dm88k>4w~eb1JS?PZiZIsY^D| z@?49}CS`G0UCs!^2NSeomW21-GSg+S2k73I9v&W&JEFshHQT*<^ZMaeeOtjU8l$ZI zy|gh1Mzm2X3-*%(sLtJZTBp$Ig8%+)spD^K%jk}0Bt*I+@h5jm6lG@8^GTn&(j;jK zP9)nqNsteKk)Jsd=Q7Vv>9IIQ(_f$M{Bn=lU|1EI2Eo|EwI$w#PHBoh1)b2(dPhF1<3-td|F2e$ zDcjYgV(Q+3q-wM4r+e*Dj2H$G@hrNTo_D|_aXNGvTFxsr-M;ys92^`BffZszVeOd> zU;xH`RPn)exnxQ1Yu}%ruFBr33%8ZO*IyjtHEJ;NX?&0=-jKH4s!8k84N0sQ9A=>J zru~v!i-q?W%)hI60QtNZHc*m!$ zqF#~=Nu!dEN4(zawptHx|AOCGj1^i$0uqp{XO6@BNV=p><5!Itg-C1YA z)m84KneXDKBr|Vb)4>(2FY)bp<-PycRYtvBwlJ7Yb93{3eRg{&xdodgSh1m^cUr$` zUin7cOfn3MnV@qP=jTm9@iD;OSBJJ@G ziu-4uH;?2iM;D{9rC}&d4(>hd%Ma3chX3TRrd6f{1C#Io6RryazVl z{6ShllikxCyjTo)vHNk)d8RN}&YE9@2P2FKtl0SY__Sabe~XWYGR>l(fzSP~np(Cf5vV9!(wceN7Lf)~trWG2clZ@fQ7>-K6-7MD^A?_> zPm+3dr6H#0WY0{Tar-yRnVL!Q9l6B~68PTs$aF*yR5x+dirN9- z{_eahFZ#!8&5G960lw+=eOFTv=LU>$dBNh*%HHbPqRJ+$l9ylYN81LrSJrSVNX=G{ zd>33xKBR8GMjm3LJr|!uA&$0UJv=e`@q?L(A(mCLUCoYmx%K%pQ$4= z9!*nhjOadsp#*!K6Wf*p#zg)2&kXZ7hM(W4&wg>W?DCVM@4i5abGJy60~_B-G#xBr z8eN8u-|rk8@PX6-KpMtf$<#(^3Ccy~x_Ds0ZwFN{n;Mf+-Wq*ApD$c4%u3wvFPQO= zI0_4_rfaPRh^tK7$a8Y0GN!)kvhx0xSGEDcKLc`mvK@qDGNk`aborfbX$tm!+4+iH zZ;w;@qP+cDdv|S$Neq<94h~%II**4X2*CpJP{@qMYI}5I;$2M*&-WEqhlO@3&X-k4 zFwT!8p0g6;f?Ur(TF__2f8kwGoH$;@6EDh0sQKlf{&RIe#@kNp8>)SK01D-EDrmyE zw2xb%;SD^ipHRsK8DvJ{4XNJxXBwVSJovvn8M?kF-X>pT2xVVdfPq^M zQHDY(3Q==kNTsMOhf|n!PiV@-+T{8^5TGOkKxpK8I;C&9(C&-fduH%;v3L1D$L z4i9<=gQ;Z=%#wv$PcE|xMb#6;gT!+{n)g5NEy>18n4nu12K%ztx;;8Q{nBM* zEzLac*JqpcAp~Nksk(5}54b?z73^W2gj=m_fIaW&n`&AI8`89zXq3uFJ6~&l#>uMZCdD>4%e^X~q(rR`7HPY(WUG zL_HH0PTAS`c=@|2hj11|lh_MfUH(&+yeUekOM*|#XitiPqzeBK_G>aFsCLR0GI9%o z0368Rx(y38ig)cF1ESa;F1Y|WnCUnc(C$ir76yN)rzIqZXspoMEa-zr-q`YVWsX?U zt1=99^u$Hjol}r19dalzhU*;kH{#q_{C@UvfEnDPe@F7-Q&Y*+vYruu3BaJyjtsmD zuqXuHpak((UhBu~`>n9wyr$>@Eg|0lvh@J)8qy21H@D zjqS*lGqC@l7W!**ALwQ+d<2|heldj>Xwp>vJ!AlEFfIV(K0ZTqZ^Ykm6X=o;Z903#{3hUMd&?I9m@W{TQpE^H4@{nz6auT5{mjLJV_np}E z=$vLN4DcukyDC*>Ec1o1XI_10zS$Cf>%Y_C{q+<1#?H=3&T|mRDzR*G5$2u!HW=&0<^KDaK~BP<+n6u*_!9~Oh|dRv^xtWcbB~@ zhqa>?;0g$6nG|&Moy7R^usaPpqU*87_BjV%mJQNDU`o&W|0+&`uAS#f&lVbA~OfSPRZ-AyPN6J#j_hxR}(1iXKp zhq2B}U{+)IOZ^V+{vaB+eugh6Sl_>J|H2rEb4U><{rpInZ8u%`vUQii;v}#li zF$CODcasD97+)wQ>~?u!V~z00-5^5xLU}+EBcI>99J9L)9;u%qqzM?{BQbq?O0C5x zB*KEB-FeB9a9|H`dATR`?C;=*IVpYm-)27F_vfF(;;;rG~8jLxZNT^*;UtmC_VyglwwOD3j#zn z$$|*n%16k7ywf3(v~!z=UnsvqJx7Pbg+*uDET5=1U@H5PvWR&C3>&5ON*DV&EN%x^F# zOk5zKkWIe`ieJn2=GR6GLoBGYHeag4!Sig^<0nrcW-z$Nn)KdX|JI5O<^dH$m^^|A zpwk=g+Ool1wVPP4mCt_<$z}|jDJ-s(YkHG*P~mikDcj+e>s%eVvEAZ*SqA$vFt=7b zBgX;w43t)ZIe{GcFwR#Nx-4>SkmlC@o$X2FhLDvp3mLhV=&xiCO+1F9YGlmmnBHU0 z$+V{xIx?yM%bIU*Ya1JXpb~tulpz1;YrXZ5%k^&a%5nr<@2iL>shVweQyeB9V+tFa zn}_~VKsP8k#R}U`la?tbXSG`Y%oP3t@&))|K49JyJsFjcy=pK2d+rv#b-p%y91gmA zq%9FJHS5dg-9c-ZvWCkLCcbsY)W5Y)%zM2mg>PsoRb_IQ4f`W3fAkqp8+g(N`!{Cku8q<3s#K_3k{Y@Tqb1aVyI~EBSb>q%YRS<}4#@_-tMP^_# zLB|zaWiG96&B#j8IaL|j<94pHw-d}nF=!T0bUOGKJ)+ohyQ9fC2jdRS+q|mzt7$k7 z202mr)zt(bFV#y1Ogf|KR z*`IP`YzC7fxq$e>TKzpIhVO3jvoIuzJ?)Mq%;$GPT*G=7eb@#=p*Q3Ues>DEvp6>G zwG9LbF$~^v@FMLY|LG6!Q@|aLl<*n-M3587suPmq3XnPcB{2rX*Z+Fqks|JIk1z=H zyC<0JeajzQ`l?R`VaUvRqD?opw}%L8m6?etK`mF37UW@Z{v7&*i0kp(=raGx>Ik@W zGYP&uy}XOVB$U(|ekaaIR;J5|L*K>h_!NUnC(fJ%Ud2#YnRuE>!$T_5EO$TLy~IDb zJZnNr+ygdHk>x@7^u>bzW13$EGLw(5qiivdZ4gP0u+hpU%i5ynILL@F*i)$q6Prne z*|is(VhfSqM*jx;e`=#L)EpPM#rfT&KXeg1WzK6a?#nZu$DyoSkanK@0aTI6?a_XI z=|hZTO8Flz^X_kKz2lbd$_(65t#=%?H?A@3nQ(G$qhHZV-|Bj|## zQ0x9K3063gu#aUmpTp6~7RGKg&s6GXQf?aby{KQInhZ(D$QhX@@CiMY=Pz}1EAF*% zE8B#9WHKUxjz5&!J+hN;ok$RlyH|yd72GeN(P*YHr2%qTzfgd*OtRif$kQ&?yDU_t zC91;;RU5;jr@YUyQ)EjuJ%A}APKU~o!Cy)P_DJFBc3!5phs0&qwLR*%Ko;QhbMwx3 z=im{1+T<4Nw-cv&x8~Dhuru?>cc5=Kji(y2_mR#I`Y>z zPw(iU3_<%TiLloOcnxXMMUMg!*ZsH+29G~;=BFv7I&V)`Up_Sg-BvPu9sxzY?9M0t z%gHQ*QN~H?B=>UB8weO<>QF&GL>9`VMru58Y4ExfXF!Z)ei2)4Gikd?=L<7{jd|Dh zBw+!Z37+x`^kElS1yyty`NJf~3G5zeDp`Nh*oDSJs+-oz%>){qmL`WHx8Sc2{`lPr5W!=( z+e*A+-)-+Ml0yh4>hb43FUUHgTO^D7)?I);e1=xlRZPHii>`e5dx`w+ z(+APY^_=W;Tcs2rg#jnUrg!SQ8G&ZdG1RB5_f<=GWZg8Ref8J_ht|eQ+_p}A^4!lc zLscgqZ&Nrwk6PC;J`UFmqdZmT5n6HyiJ72L3X0wbe?IWO?s-q3ARZ(J&h_E#ZIo?C zX2}Nrs)uyHh)`N zXlY)MIEbV`(0h=zc+>m&ugH_i5y2GsQ2sOHQxP4q1E(G68_arXosqRSk!9H7dn3VX zHTw}&=S4)_iLVv=#$=Kk?AD2a8>nH2e@6cqf0^)Urb*{SqF(WtLet`_y4;BVaC;wF ziY2n-AD8`pK6}rbia&lK54Rh=R?B$tto>?uZnLPrLd!UT<;EFkA5sh#Dl9E6HE$x1 zskExuFMiCxT(NZFgfCdcipfzp^S&}enm03SZ0Xy5;$AsZf8DoXN*Iam0mCQ(9P;xkK zSr@mGIIyDY-3LxEeJJWXW>E|hKv~6ch>(!be;}c=?Msf$KveH68;A1}HDthmYq*^U zDuG}n$w1Cy5^2Eorh)K9IjNc7CX0u+_e$sWp1h)>wu~u}hnO1;>o?=<$Dobv}o$ z!{7x0)u8U{2P$tx1qBe0?CcpGh0z9{Xx|*h2O}60`S991X)|i>l*-^J?li2SdZ)d; zJsy{pET{{1eQxF{5XAk^Nt48_@lQtoRfjVLyox>XPQJf_kKgL_Krx(LEK@LY1l|N|#miHfGERPtL|E`^8cA8Da)Q!wZWtn_~JQw7UT`{ar^n*~KH$m}Py2j5&aF%0#K^|kvR*WTYeu7y76P)#=gq4bB^XM%Klx` z-kB;;2K}bA!hbb_p-Ti(@^^CVq^$_NR*nNue_K&9$y+PoR(v@r)EZP%$?4~~x4wHw z95ny;@C7!Nibt&_y8;hM+t_S(1aUQI_m*_u# zMs*K#QwlyZ!81b6V}TV2uiG#on&KO+I-9<*c&|#!;~|!iC?E*k-d|QJWu%($CwqT> zYD$mv8?9PgTUK||E-zniE(x3uHH$LQ{XEX8zXrBx?rS_HP7gEJ4_vK-Nj&dSHc0h! zmZTMlTZDq6K;8fT=li|B%JNi?u~NGzZLnu#W-7kJE?5UAl>%37f!6fGy5-g`xOWC1 z687@;e!On`Z*tHkNAp3-Yd&OT)vi^nKCYEn5WC`9qCf9cUp!E3cl)9`*XX)(@tyl! zl8@w`n4IA##?Bj1RvYFOU0*L-$hT|6koC2UP!HveS7f>|L#t3NKhV_t+PswQeR_8G z3`)m92#)d))LVxT9>kVa8gXeUw-{?sR2ao86<>d~_2L*)-X65G%!_68BAdRP$u`@K zEI3ALItcS)vyX>PQvMWEYsIMu8pY`DQbiqXZ=S3xZ%79N3Z22jzW(0c=W~Tw!dTqh zP9XbscnUVnBtaS~zU7}isHDWDYCjr1KB~N(a_3z>i{2BOx+8c|Sx*<;!pu)^-G|M$H#ZHn1`qUzU`tPsB_$<`BxAVZU_;)F?uW{QB+M?! zL9!s!qKXtK00oG5wu-IefHQIHHQMi&q3_;{zq;}Rk4B(?+U`j_rB{__$DEa8rsPMiryf)4YET5c{ar!x$v6{}2o=Lj1iif%He|5)JK2S}HTQajK12 zC6*I{dg*q7fL}n@%}?BL__{OLHKgJ0bO(hVJc7&1%i~)|r2e%znV!!qK3k)Sw=#G7 zP?S2QxvPy5>?O`V#s>?5U#iArQiAl|68Ji$8nN$tmKDQcS0?J%-^zN4H@nKO-B2k> z@tZUUO@YWyL|a+<7CohFPi4SJ*Tw@bxG z7aRAL;jsH(6B9aal=cHQI9NXGg#`u6pqxM$2HR>^R^W(^!YU#Z@>C+uAhA^oZxcg}bQbN#8;fO#_N(*>?wNV(mWBrD5_ioWlZO+V9vGz&YH3OGnbGAZ!uo3eFJpA?? zJje$H<1G$jmp=IMe=UN> z50}W%p6hZ+A#OYG-170-!bm+D|Dq=Vz_KdM{q7dT9Q(Se=yN#uc}no}*U7LyMrcnP z$U=39k^gpA8h#E`!2DFCcLr>tS%3HLUD_i;!t0t}Cfrz9Gd*$$U32r`8rUCDNG2qM zPeR^+p2!!yzS;M7_%aJ|QoAB5at1#979<})p)h(v#zL^MHXCaxfZ_Xc&9(+amSyj$ zC~pLNOdS?chYI2xy!c|K60;;ub-XYJ2G#+>)O0>E`&cy`7JXU0Hj5_;Q#;t literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo.svg b/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo.svg new file mode 100644 index 00000000..91ab28b6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo.svg @@ -0,0 +1,1470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Pb + Pb + + + + + + + + + + + + + + + + + + nano + nano + + + + + diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo16px.png b/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo16px.png new file mode 100644 index 0000000000000000000000000000000000000000..8db0e2ef3f472f50b2c0b9ee4c545453f865ad2c GIT binary patch literal 854 zcmV-c1F8IpP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L017Dp017DqCuavK00007bV*G`2iyS# z5(76cq%NcY00P!YL_t(I%UzN`Xe?C}#=m>#&fb}woynSPOtNmWEG%KgLhvbA2sW_` zcELhIDpQz7o}eJeLLgQ?tZZDcu(nV6NcAkN0)pvGB*kWjgk*MS=Fa_dY_dz92Tpg+ zcfQ{_hcy}vktB&rl7zI@0szXg{4|c^@1>L-Yc0)YvwyVK7o78-FE1}&;Ysi;%goWy z5tU`R1mIg^%&SJD@%z@+*1Ib!D=SeHwc-{koVa;ZfE2X~bbUH7RB*D_s z61KOuQ4|HzG{x=hE%H2vwRU0KT8rs)`qS0b)pK5})s{Wa8>DH9<>h7c`+XEefxEjq zWLbu)s^FZ%YuubeN_n)ox%m+f!|=0uz5Yd#B$%T)=b*L5!@~nO=NJx$i)JE%wHDUe zT2)ow2qDDo#>NJeQn{F5Ezfg&|0I_YP}|4jDb=L#+Y|F=llbu6gcP5 zTI1~O3`!~N?d_r4?P4?Yse;?LbR8=(>c#9ijxYiohS`ZPObI9`?qtOVb zr>D5TzsGbs#mUJDdc7XB)=)~#cf&+gRsTvU-yk9Y0AmdGdL4&{hX8=p)z!tsvMd*A zt%VRG86&PdiJnw?F+wBjd zD0(S`2=Kp{BWbNsmL-a!fKm!X1SzHUeg6|iMCf!nFM=R=PDGfa%+G0zSs+wZ1tNm) z`v`*Ix5;F3z=#NpG1hLk|0JUKoO6rGkN1W#X7Nly2n0cJk*4X}L`3}2DqUY+KeN{U zVy)Fr7p9bga}J*8K}u=DF#L5gnGERBDtl@f0M^&nKh|1*XN(zGYu^L_&+~4C5Pu6H gei)C(XHV<@1J&fBKi_@Vod5s;07*qoM6N<$g0TRKQUCw| literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo48px.png b/hardware-wallet/firmware/vendor/nanopb/docs/logo/logo48px.png new file mode 100644 index 0000000000000000000000000000000000000000..b598c01186356d10ef4d4959690d0f792556ca9c GIT binary patch literal 2577 zcmV+s3hwoZP)Px#24YJ`L;wH)0002_L%V+f000SaNLh0L01ejw01ejxLMWSf00007bV*G`2iyS# z5ikgE@7VAF011&vL_t(&-sM_-j2vYd|2^}uGqZcUz1!Q{-q(6uOCixldQCt%N-IGG z3LM4i1;R%V>S0qfVk4F0Dosd>^-?W~wW4T3BA6Hw#MmkY5kCl32(|*2_6&FJ-L~7i z>v6X?yE|X+JpSR#X6|T{M!nk_pJbBF%$u3#_rAa9dCkVjy%}yX&sI zt{NU5-c3Z8c%BExao~9#eBTE%!}GiXGjBY4^yn`x1OVa8tH+KVOK#er*<#fpQeRH{qUGys6>y0C2OZ zno&rW*XGxMMbe@P%EEdtw(11)P1Iw~7Gc!}oK6B$k*YyK6TYO zbw)kUgJoH;EDMQ50@-Z#L#Z_cKtygLk$Ab*?erI2*L7Uih2uEYLN-1=4rWF&nM7k_ zV>SDP&P$R6MN!mzKL30wm1?XRfWg7Rw_Ml#o@H6EZ5x$J1?6%X)6>&9b?Ov|24RSvxW^ zQmF}mvsqhPTfDBW?xlD<-tGH7Ow%lsN~PNhg~GvbOgf!@TvgSF6N!Wb;7_jW-a0Ze zGP#hO`g2-7pD#~NPTpXe<|{!EHyeiWyQZe5JHs)Plar4y^Ubd7PAZDBO4s$*T3T8z zI?E<%?lu1_5ZdzP%VU*F7tKKP(N97pFaeEdV71*@4ox)^_FF=5<)B$LJax7|7t82+dnikG&S!40?tcImMqz$s_K_~ z-$$iVfoYo0PfbnT&CDeLNTpJlhK7b;CK8D&0hqRJKW$mo=Ve*WWV2a`h^mcYP#k^N zbw`8{j|~qG|9D;jgx1;FxlK`&M?(;$Qt42!SnOfu5di4v>50Gh-g`e2LiD(<3r*9I zOeWFV+6o~AEXzWGRTYL|tf;H2`-`fo zR|1fShK5#ImbE&p=&4i+ot>RXr_-pbt3xangDlG+B1n=1Ns^$dDl|>IDHe+z>Fn%W zGp_&u;KYd&-*+76IsjveqCnU6=2$HDN_~C(y~SejX-(7WlgVVYugYXHP*oK~G;609 zZRZt5fu?C$Ns^w<<#NWn0sw%~(a~4RheG-pXSLI_BbbXEZ&XysoY85!wTurS7{R4Ufk*oc{#8EBe@8+cq>! zgRbk?zkfg0u3d{#sf4|I_u`E=-oT+lhp=wlI`sGV&zk*En+@s&OOkYv6e&da1?t+B zMARR--%3PJ5YZkYS`*ycOhgGHx`Bwk92vWXh+ZP1Z_H`UuNOk7<#HLm?^lD?w(aVy zGBXYyJczEYE-*6|FJ6q@yLV&r=FQMFZI=2GT;w=TuM~VZ2H+6@R{>ZB;QrwLWdL3T z@GSs~0HlbhDR|xupclYbg0Xi1xDCL~0J?}Md`A~EcZ4FDZQIohBZL3|^!N8;>(;Hf z_~MJPW5cqfY$&RL{tahQ2?8n*(Rbk00km?9Kd7D>_nApMNvRR)hshGFo5al=_;`1=4K?5 zNfe7k?Ao;p0|Nt9;Vf)3f^2jkq|k!^3e3DA5T$+s;2r==06ZHwcLKoW06q)gMP}X< z0Dcm{?Eo$U@H!DC04xP?2Y~09xm+j|{?5!(;fzNMR;YZ>l`N;GrmBG7fB$_rjx(#h z0N{;{jqM9pU{UZv0B`}^1mJ4{rM?5;DFBxN_zVCGz|P3nUI1Hycl;259^4xa`yXcJ z&d$zbilST*&OQM2_4R?7v0=jo?Af!YdT25}J`TrmuzUAz6bc3G+_@9BZCB4Fg4rKq zW_O|L06IE4zN_o{SEI6I2xP8QAF6&)RV1v?01&h%zZx4GyJey30Fue%mQtzILqtoW z{6Aa&6P4?u)L~}GvJ6#KrxS_9-3wWX0RXvNZjCI8cE`6z(snMB|`D~fW@ z#Kgo;7aTyKay$v3FDlK?o&D$))(u&fA%<>aPZEZEY((&wI{w-Ogw=o_l~O%Q6&2Ij!sZoui|p zzn%9j<-f5STZ9nT_`ZLs@B7UFbY^xWNh(N^^bbjrUd!cjkG=Wko9=?_iT_h;Y;644 nQyVO&=00000NkvXXu0mjf@tD#T literal 0 HcmV?d00001 diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/lsr.css b/hardware-wallet/firmware/vendor/nanopb/docs/lsr.css new file mode 100644 index 00000000..429bce51 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/lsr.css @@ -0,0 +1,240 @@ +/* +Author: Peter Parente +Date: 2008/01/22 +Version: 1.0 (modified) +Copyright: This stylesheet has been placed in the public domain - free to edit and use for all uses. +*/ + +body { + font: 100% sans-serif; + background: #ffffff; + color: black; + margin: 2em; + padding: 0em 2em; +} + +p.topic-title { + font-weight: bold; +} + +table.docinfo { + text-align: left; + margin: 2em 0em; +} + +a[href] { + color: #436976; + background-color: transparent; +} + +a.toc-backref { + text-decoration: none; +} + +h1 a[href] { + color: #003a6b; + text-decoration: none; + background-color: transparent; +} + +a.strong { + font-weight: bold; +} + +img { + margin: 0; + border: 0; +} + +p { + margin: 0.5em 0 1em 0; + line-height: 1.5em; +} + +p a:visited { + color: purple; + background-color: transparent; +} + +p a:active { + color: red; + background-color: transparent; +} + +a:hover { + text-decoration: none; +} + +p img { + border: 0; + margin: 0; +} + +p.rubric { + font-weight: bold; + font-style: italic; +} + +em { + font-style: normal; + font-family: monospace; + font-weight: bold; +} + +pre { + border-left: 3px double #aaa; + padding: 5px 10px; + background-color: #f6f6f6; +} + +h1.title { + color: #003a6b; + font-size: 180%; + margin-bottom: 0em; +} + +h2.subtitle { + color: #003a6b; + border-bottom: 0px; +} + +h1, h2, h3, h4, h5, h6 { + color: #555; + background-color: transparent; + margin: 0em; + padding-top: 0.5em; +} + +h1 { + font-size: 150%; + margin-bottom: 0.5em; + border-bottom: 2px solid #aaa; +} + +h2 { + font-size: 130%; + margin-bottom: 0.5em; + border-bottom: 1px solid #aaa; +} + +h3 { + font-size: 120%; + margin-bottom: 0.5em; +} + +h4 { + font-size: 110%; + font-weight: bold; + margin-bottom: 0.5em; +} + +h5 { + font-size: 105%; + font-weight: bold; + margin-bottom: 0.5em; +} + +h6 { + font-size: 100%; + font-weight: bold; + margin-bottom: 0.5em; +} + +dt { + font-style: italic; +} + +dd { + margin-bottom: 1.5em; +} + +div.admonition, div.note, div.tip, div.caution, div.important { + margin: 2em 2em; + padding: 0em 1em; + border-top: 1px solid #aaa; + border-left: 1px solid #aaa; + border-bottom: 2px solid #555; + border-right: 2px solid #555; +} + +div.important { + background: transparent url('../images/important.png') 10px 2px no-repeat; +} + +div.caution { + background: transparent url('../images/caution.png') 10px 2px no-repeat; +} + +div.note { + background: transparent url('../images/note.png') 10px 2px no-repeat; +} + +div.tip { + background: transparent url('../images/tip.png') 10px 2px no-repeat; +} + +div.admonition-example { + background: transparent url('../images/tip.png') 10px 2px no-repeat; +} + +div.admonition-critical-example { + background: transparent url('../images/important.png') 10px 2px no-repeat; +} + +p.admonition-title { + font-weight: bold; + border-bottom: 1px solid #aaa; + padding-left: 30px; +} + +table.docutils { + text-align: left; + border: 1px solid gray; + border-collapse: collapse; + margin: 1.5em 0em; +} + +table.docutils caption { + font-style: italic; +} + +table.docutils td, table.docutils th { + padding: 0.25em 0.5em; +} + +th.field-name { + text-align: right; + width: 15em; +} + +table.docutils th { + font-family: monospace; + background-color: #f6f6f6; + vertical-align: middle; +} + +table.field-list { + border: none; +} + +div.sidebar { + margin: 2em 2em 2em 0em; + padding: 0em 1em; + border-top: 1px solid #aaa; + border-left: 1px solid #aaa; + border-bottom: 2px solid #555; + border-right: 2px solid #555; +} + +p.sidebar-title { + margin-bottom: 0em; + color: #003a6b; + border-bottom: 1px solid #aaa; + font-weight: bold; +} + +p.sidebar-subtitle { + margin-top: 0em; + font-style: italic; + color: #003a6b; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/menu.rst b/hardware-wallet/firmware/vendor/nanopb/docs/menu.rst new file mode 100644 index 00000000..2c110def --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/menu.rst @@ -0,0 +1,13 @@ +.. sidebar :: Documentation index + + 1) `Overview`_ + 2) `Concepts`_ + 3) `API reference`_ + 4) `Security model`_ + 5) `Migration from older versions`_ + +.. _`Overview`: index.html +.. _`Concepts`: concepts.html +.. _`API reference`: reference.html +.. _`Security model`: security.html +.. _`Migration from older versions`: migration.html diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/migration.rst b/hardware-wallet/firmware/vendor/nanopb/docs/migration.rst new file mode 100644 index 00000000..4fe3b3eb --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/migration.rst @@ -0,0 +1,304 @@ +===================================== +Nanopb: Migration from older versions +===================================== + +.. include :: menu.rst + +This document details all the breaking changes that have been made to nanopb +since its initial release. For each change, the rationale and required +modifications of user applications are explained. Also any error indications +are included, in order to make it easier to find this document. + +.. contents :: + +Nanopb-0.3.8 (2017-03-05) +========================= + +Fully drain substreams before closing +------------------------------------- + +**Rationale:** If the substream functions were called directly and the caller +did not completely empty the substring before closing it, the parent stream +would be put into an incorrect state. + +**Changes:** *pb_close_string_substream* can now error and returns a boolean. + +**Required actions:** Add error checking onto any call to +*pb_close_string_substream*. + +Change oneof format in .pb.c files +---------------------------------- + +**Rationale:** Previously two oneofs in a single message would be erroneously +handled as part of the same union. + +**Changes:** Oneofs fields now use special *PB_DATAOFFSET_UNION* offset type +in generated .pb.c files to distinguish whether they are the first or following +field inside an union. + +**Required actions:** Regenerate *.pb.c/.pb.h* files with new nanopb version if +oneofs are used. + +Nanopb-0.3.5 (2016-02-13) +========================= + +Add support for platforms without uint8_t +----------------------------------------- +**Rationale:** Some platforms cannot access 8-bit sized values directly, and +do not define *uint8_t*. Nanopb previously didn't support these platforms. + +**Changes:** References to *uint8_t* were replaced with several alternatives, +one of them being a new *pb_byte_t* typedef. This in turn uses *uint_least8_t* +which means the smallest available type. + +**Required actions:** If your platform does not have a standards-compliant +*stdint.h*, it may lack the definition for *[u]int_least8_t*. This must be +added manually, example can be found in *extra/pb_syshdr.h*. + +**Error indications:** Compiler error: "unknown type name 'uint_least8_t'". + +Nanopb-0.3.2 (2015-01-24) +========================= + +Add support for OneOfs +---------------------- +**Rationale:** Previously nanopb did not support the *oneof* construct in +*.proto* files. Those fields were generated as regular *optional* fields. + +**Changes:** OneOfs are now generated as C unions. Callback fields are not +supported inside oneof and generator gives an error. + +**Required actions:** The generator option *no_unions* can be used to restore old +behaviour and to allow callbacks to be used. To use unions, one change is +needed: use *which_xxxx* field to detect which field is present, instead +of *has_xxxx*. Compare the value against *MyStruct_myfield_tag*. + +**Error indications:** Generator error: "Callback fields inside of oneof are +not supported". Compiler error: "Message" has no member named "has_xxxx". + +Nanopb-0.3.0 (2014-08-26) +========================= + +Separate field iterator logic to pb_common.c +-------------------------------------------- +**Rationale:** Originally, the field iteration logic was simple enough to be +duplicated in *pb_decode.c* and *pb_encode.c*. New field types have made the +logic more complex, which required the creation of a new file to contain the +common functionality. + +**Changes:** There is a new file, *pb_common.c*, which must be included in +builds. + +**Required actions:** Add *pb_common.c* to build rules. This file is always +required. Either *pb_decode.c* or *pb_encode.c* can still be left out if some +functionality is not needed. + +**Error indications:** Linker error: undefined reference to +*pb_field_iter_begin*, *pb_field_iter_next* or similar. + +Change data type of field counts to pb_size_t +--------------------------------------------- +**Rationale:** Often nanopb is used with small arrays, such as 255 items or +less. Using a full *size_t* field to store the array count wastes memory if +there are many arrays. There already exists parameters *PB_FIELD_16BIT* and +*PB_FIELD_32BIT* which tell nanopb what is the maximum size of arrays in use. + +**Changes:** Generator will now use *pb_size_t* for the array *_count* fields. +The size of the type will be controlled by the *PB_FIELD_16BIT* and +*PB_FIELD_32BIT* compilation time options. + +**Required actions:** Regenerate all *.pb.h* files. In some cases casts to the +*pb_size_t* type may need to be added in the user code when accessing the +*_count* fields. + +**Error indications:** Incorrect data at runtime, crashes. But note that other +changes in the same version already require regenerating the files and have +better indications of errors, so this is only an issue for development +versions. + +Renamed some macros and identifiers +----------------------------------- +**Rationale:** Some names in nanopb core were badly chosen and conflicted with +ISO C99 reserved names or lacked a prefix. While they haven't caused trouble +so far, it is reasonable to switch to non-conflicting names as these are rarely +used from user code. + +**Changes:** The following identifier names have changed: + + * Macros: + + * STATIC_ASSERT(x) -> PB_STATIC_ASSERT(x) + * UNUSED(x) -> PB_UNUSED(x) + + * Include guards: + + * _PB_filename_ -> PB_filename_INCLUDED + + * Structure forward declaration tags: + + * _pb_field_t -> pb_field_s + * _pb_bytes_array_t -> pb_bytes_array_s + * _pb_callback_t -> pb_callback_s + * _pb_extension_type_t -> pb_extension_type_s + * _pb_extension_t -> pb_extension_s + * _pb_istream_t -> pb_istream_s + * _pb_ostream_t -> pb_ostream_s + +**Required actions:** Regenerate all *.pb.c* files. If you use any of the above +identifiers in your application code, perform search-replace to the new name. + +**Error indications:** Compiler errors on lines with the macro/type names. + +Nanopb-0.2.9 (2014-08-09) +========================= + +Change semantics of generator -e option +--------------------------------------- +**Rationale:** Some compilers do not accept filenames with two dots (like +in default extension .pb.c). The *-e* option to the generator allowed changing +the extension, but not skipping the extra dot. + +**Changes:** The *-e* option in generator will no longer add the prepending +dot. The default value has been adjusted accordingly to *.pb.c* to keep the +default behaviour the same as before. + +**Required actions:** Only if using the generator -e option. Add dot before +the parameter value on the command line. + +**Error indications:** File not found when trying to compile generated files. + +Nanopb-0.2.7 (2014-04-07) +========================= + +Changed pointer-type bytes field datatype +----------------------------------------- +**Rationale:** In the initial pointer encoding support since nanopb-0.2.5, +the bytes type used a separate *pb_bytes_ptr_t* type to represent *bytes* +fields. This made it easy to encode data from a separate, user-allocated +buffer. However, it made the internal logic more complex and was inconsistent +with the other types. + +**Changes:** Dynamically allocated bytes fields now have the *pb_bytes_array_t* +type, just like statically allocated ones. + +**Required actions:** Only if using pointer-type fields with the bytes datatype. +Change any access to *msg->field.size* to *msg->field->size*. Change any +allocation to reserve space of amount *PB_BYTES_ARRAY_T_ALLOCSIZE(n)*. If the +data pointer was begin assigned from external source, implement the field using +a callback function instead. + +**Error indications:** Compiler error: unknown type name *pb_bytes_ptr_t*. + +Nanopb-0.2.4 (2013-11-07) +========================= + +Remove the NANOPB_INTERNALS compilation option +---------------------------------------------- +**Rationale:** Having the option in the headers required the functions to +be non-static, even if the option is not used. This caused errors on some +static analysis tools. + +**Changes:** The *#ifdef* and associated functions were removed from the +header. + +**Required actions:** Only if the *NANOPB_INTERNALS* option was previously +used. Actions are as listed under nanopb-0.1.3 and nanopb-0.1.6. + +**Error indications:** Compiler warning: implicit declaration of function +*pb_dec_string*, *pb_enc_string*, or similar. + +Nanopb-0.2.1 (2013-04-14) +========================= + +Callback function signature +--------------------------- +**Rationale:** Previously the auxilary data to field callbacks was passed +as *void\**. This allowed passing of any data, but made it unnecessarily +complex to return a pointer from callback. + +**Changes:** The callback function parameter was changed to *void\*\**. + +**Required actions:** You can continue using the old callback style by +defining *PB_OLD_CALLBACK_STYLE*. Recommended action is to: + + * Change the callback signatures to contain *void\*\** for decoders and + *void \* const \** for encoders. + * Change the callback function body to use *\*arg* instead of *arg*. + +**Error indications:** Compiler warning: assignment from incompatible +pointer type, when initializing *funcs.encode* or *funcs.decode*. + +Nanopb-0.2.0 (2013-03-02) +========================= + +Reformatted generated .pb.c file using macros +--------------------------------------------- +**Rationale:** Previously the generator made a list of C *pb_field_t* +initializers in the .pb.c file. This led to a need to regenerate all .pb.c +files after even small changes to the *pb_field_t* definition. + +**Changes:** Macros were added to pb.h which allow for cleaner definition +of the .pb.c contents. By changing the macro definitions, changes to the +field structure are possible without breaking compatibility with old .pb.c +files. + +**Required actions:** Regenerate all .pb.c files from the .proto sources. + +**Error indications:** Compiler warning: implicit declaration of function +*pb_delta_end*. + +Changed pb_type_t definitions +----------------------------- +**Rationale:** The *pb_type_t* was previously an enumeration type. This +caused warnings on some compilers when using bitwise operations to set flags +inside the values. + +**Changes:** The *pb_type_t* was changed to *typedef uint8_t*. The values +were changed to *#define*. Some value names were changed for consistency. + +**Required actions:** Only if you directly access the `pb_field_t` contents +in your own code, something which is not usually done. Needed changes: + + * Change *PB_HTYPE_ARRAY* to *PB_HTYPE_REPEATED*. + * Change *PB_HTYPE_CALLBACK* to *PB_ATYPE()* and *PB_ATYPE_CALLBACK*. + +**Error indications:** Compiler error: *PB_HTYPE_ARRAY* or *PB_HTYPE_CALLBACK* +undeclared. + +Nanopb-0.1.6 (2012-09-02) +========================= + +Refactored field decoder interface +---------------------------------- +**Rationale:** Similarly to field encoders in nanopb-0.1.3. + +**Changes:** New functions with names *pb_decode_\** were added. + +**Required actions:** By defining NANOPB_INTERNALS, you can still keep using +the old functions. Recommended action is to replace any calls with the newer +*pb_decode_\** equivalents. + +**Error indications:** Compiler warning: implicit declaration of function +*pb_dec_string*, *pb_dec_varint*, *pb_dec_submessage* or similar. + +Nanopb-0.1.3 (2012-06-12) +========================= + +Refactored field encoder interface +---------------------------------- +**Rationale:** The old *pb_enc_\** functions were designed mostly for the +internal use by the core. Because they are internally accessed through +function pointers, their signatures had to be common. This led to a confusing +interface for external users. + +**Changes:** New functions with names *pb_encode_\** were added. These have +easier to use interfaces. The old functions are now only thin wrappers for +the new interface. + +**Required actions:** By defining NANOPB_INTERNALS, you can still keep using +the old functions. Recommended action is to replace any calls with the newer +*pb_encode_\** equivalents. + +**Error indications:** Compiler warning: implicit declaration of function +*pb_enc_string*, *pb_enc_varint, *pb_enc_submessage* or similar. + diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/reference.rst b/hardware-wallet/firmware/vendor/nanopb/docs/reference.rst new file mode 100644 index 00000000..5ee332eb --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/reference.rst @@ -0,0 +1,773 @@ +===================== +Nanopb: API reference +===================== + +.. include :: menu.rst + +.. contents :: + + + + +Compilation options +=================== +The following options can be specified in one of two ways: + +1. Using the -D switch on the C compiler command line. +2. By #defining them at the top of pb.h. + +You must have the same settings for the nanopb library and all code that +includes pb.h. + +============================ ================================================ +PB_NO_PACKED_STRUCTS Disable packed structs. Increases RAM usage but + is necessary on some platforms that do not + support unaligned memory access. +PB_ENABLE_MALLOC Set this to enable dynamic allocation support + in the decoder. +PB_MAX_REQUIRED_FIELDS Maximum number of required fields to check for + presence. Default value is 64. Increases stack + usage 1 byte per every 8 fields. Compiler + warning will tell if you need this. +PB_FIELD_16BIT Add support for tag numbers > 255 and fields + larger than 255 bytes or 255 array entries. + Increases code size 3 bytes per each field. + Compiler error will tell if you need this. +PB_FIELD_32BIT Add support for tag numbers > 65535 and fields + larger than 65535 bytes or 65535 array entries. + Increases code size 9 bytes per each field. + Compiler error will tell if you need this. +PB_NO_ERRMSG Disables the support for error messages; only + error information is the true/false return + value. Decreases the code size by a few hundred + bytes. +PB_BUFFER_ONLY Disables the support for custom streams. Only + supports encoding and decoding with memory + buffers. Speeds up execution and decreases code + size slightly. +PB_OLD_CALLBACK_STYLE Use the old function signature (void\* instead + of void\*\*) for callback fields. This was the + default until nanopb-0.2.1. +PB_SYSTEM_HEADER Replace the standard header files with a single + header file. It should define all the required + functions and typedefs listed on the + `overview page`_. Value must include quotes, + for example *#define PB_SYSTEM_HEADER "foo.h"*. +PB_WITHOUT_64BIT Disable 64-bit support, for old compilers or + for a slight speedup on 8-bit platforms. +============================ ================================================ + +The PB_MAX_REQUIRED_FIELDS, PB_FIELD_16BIT and PB_FIELD_32BIT settings allow +raising some datatype limits to suit larger messages. Their need is recognized +automatically by C-preprocessor #if-directives in the generated .pb.h files. +The default setting is to use the smallest datatypes (least resources used). + +.. _`overview page`: index.html#compiler-requirements + + +Proto file options +================== +The generator behaviour can be adjusted using these options, defined in the +'nanopb.proto' file in the generator folder: + +============================ ================================================ +max_size Allocated size for *bytes* and *string* fields. +max_count Allocated number of entries in arrays + (*repeated* fields). +int_size Override the integer type of a field. + (To use e.g. uint8_t to save RAM.) +type Type of the generated field. Default value + is *FT_DEFAULT*, which selects automatically. + You can use *FT_CALLBACK*, *FT_POINTER*, + *FT_STATIC* or *FT_IGNORE* to + force a callback field, a dynamically + allocated field, a static field or to + completely ignore the field. +long_names Prefix the enum name to the enum value in + definitions, i.e. *EnumName_EnumValue*. Enabled + by default. +packed_struct Make the generated structures packed. + NOTE: This cannot be used on CPUs that break + on unaligned accesses to variables. +skip_message Skip the whole message from generation. +no_unions Generate 'oneof' fields as optional fields + instead of C unions. +msgid Specifies a unique id for this message type. + Can be used by user code as an identifier. +anonymous_oneof Generate 'oneof' fields as anonymous unions. +fixed_length Generate 'bytes' fields with constant length + (max_size must be defined also). +============================ ================================================ + +These options can be defined for the .proto files before they are converted +using the nanopb-generatory.py. There are three ways to define the options: + +1. Using a separate .options file. + This is the preferred way as of nanopb-0.2.1, because it has the best + compatibility with other protobuf libraries. +2. Defining the options on the command line of nanopb_generator.py. + This only makes sense for settings that apply to a whole file. +3. Defining the options in the .proto file using the nanopb extensions. + This is the way used in nanopb-0.1, and will remain supported in the + future. It however sometimes causes trouble when using the .proto file + with other protobuf libraries. + +The effect of the options is the same no matter how they are given. The most +common purpose is to define maximum size for string fields in order to +statically allocate them. + +Defining the options in a .options file +--------------------------------------- +The preferred way to define options is to have a separate file +'myproto.options' in the same directory as the 'myproto.proto'. :: + + # myproto.proto + message MyMessage { + required string name = 1; + repeated int32 ids = 4; + } + +:: + + # myproto.options + MyMessage.name max_size:40 + MyMessage.ids max_count:5 + +The generator will automatically search for this file and read the +options from it. The file format is as follows: + +* Lines starting with '#' or '//' are regarded as comments. +* Blank lines are ignored. +* All other lines should start with a field name pattern, followed by one or + more options. For example: *"MyMessage.myfield max_size:5 max_count:10"*. +* The field name pattern is matched against a string of form *'Message.field'*. + For nested messages, the string is *'Message.SubMessage.field'*. +* The field name pattern may use the notation recognized by Python fnmatch(): + + - *\** matches any part of string, like 'Message.\*' for all fields + - *\?* matches any single character + - *[seq]* matches any of characters 's', 'e' and 'q' + - *[!seq]* matches any other character + +* The options are written as *'option_name:option_value'* and several options + can be defined on same line, separated by whitespace. +* Options defined later in the file override the ones specified earlier, so + it makes sense to define wildcard options first in the file and more specific + ones later. + +If preferred, the name of the options file can be set using the command line +switch *-f* to nanopb_generator.py. + +Defining the options on command line +------------------------------------ +The nanopb_generator.py has a simple command line option *-s OPTION:VALUE*. +The setting applies to the whole file that is being processed. + +Defining the options in the .proto file +--------------------------------------- +The .proto file format allows defining custom options for the fields. +The nanopb library comes with *nanopb.proto* which does exactly that, allowing +you do define the options directly in the .proto file:: + + import "nanopb.proto"; + + message MyMessage { + required string name = 1 [(nanopb).max_size = 40]; + repeated int32 ids = 4 [(nanopb).max_count = 5]; + } + +A small complication is that you have to set the include path of protoc so that +nanopb.proto can be found. This file, in turn, requires the file +*google/protobuf/descriptor.proto*. This is usually installed under +*/usr/include*. Therefore, to compile a .proto file which uses options, use a +protoc command similar to:: + + protoc -I/usr/include -Inanopb/generator -I. -omessage.pb message.proto + +The options can be defined in file, message and field scopes:: + + option (nanopb_fileopt).max_size = 20; // File scope + message Message + { + option (nanopb_msgopt).max_size = 30; // Message scope + required string fieldsize = 1 [(nanopb).max_size = 40]; // Field scope + } + + + + + + + + + +pb.h +==== + +pb_byte_t +--------- +Type used for storing byte-sized data, such as raw binary input and bytes-type fields. :: + + typedef uint_least8_t pb_byte_t; + +For most platforms this is equivalent to `uint8_t`. Some platforms however do not support +8-bit variables, and on those platforms 16 or 32 bits need to be used for each byte. + +pb_type_t +--------- +Type used to store the type of each field, to control the encoder/decoder behaviour. :: + + typedef uint_least8_t pb_type_t; + +The low-order nibble of the enumeration values defines the function that can be used for encoding and decoding the field data: + +=========================== ===== ================================================ +LTYPE identifier Value Storage format +=========================== ===== ================================================ +PB_LTYPE_VARINT 0x00 Integer. +PB_LTYPE_UVARINT 0x01 Unsigned integer. +PB_LTYPE_SVARINT 0x02 Integer, zigzag encoded. +PB_LTYPE_FIXED32 0x03 32-bit integer or floating point. +PB_LTYPE_FIXED64 0x04 64-bit integer or floating point. +PB_LTYPE_BYTES 0x05 Structure with *size_t* field and byte array. +PB_LTYPE_STRING 0x06 Null-terminated string. +PB_LTYPE_SUBMESSAGE 0x07 Submessage structure. +PB_LTYPE_EXTENSION 0x08 Point to *pb_extension_t*. +PB_LTYPE_FIXED_LENGTH_BYTES 0x09 Inline *pb_byte_t* array of fixed size. +=========================== ===== ================================================ + +The bits 4-5 define whether the field is required, optional or repeated: + +==================== ===== ================================================ +HTYPE identifier Value Field handling +==================== ===== ================================================ +PB_HTYPE_REQUIRED 0x00 Verify that field exists in decoded message. +PB_HTYPE_OPTIONAL 0x10 Use separate *has_* boolean to specify + whether the field is present. + (Unless it is a callback) +PB_HTYPE_REPEATED 0x20 A repeated field with preallocated array. + Separate *_count* for number of items. + (Unless it is a callback) +==================== ===== ================================================ + +The bits 6-7 define the how the storage for the field is allocated: + +==================== ===== ================================================ +ATYPE identifier Value Allocation method +==================== ===== ================================================ +PB_ATYPE_STATIC 0x00 Statically allocated storage in the structure. +PB_ATYPE_CALLBACK 0x40 A field with dynamic storage size. Struct field + actually contains a pointer to a callback + function. +==================== ===== ================================================ + + +pb_field_t +---------- +Describes a single structure field with memory position in relation to others. The descriptions are usually autogenerated. :: + + typedef struct pb_field_s pb_field_t; + struct pb_field_s { + pb_size_t tag; + pb_type_t type; + pb_size_t data_offset; + pb_ssize_t size_offset; + pb_size_t data_size; + pb_size_t array_size; + const void *ptr; + } pb_packed; + +:tag: Tag number of the field or 0 to terminate a list of fields. +:type: LTYPE, HTYPE and ATYPE of the field. +:data_offset: Offset of field data, relative to the end of the previous field. +:size_offset: Offset of *bool* flag for optional fields or *size_t* count for arrays, relative to field data. +:data_size: Size of a single data entry, in bytes. For PB_LTYPE_BYTES, the size of the byte array inside the containing structure. For PB_HTYPE_CALLBACK, size of the C data type if known. +:array_size: Maximum number of entries in an array, if it is an array type. +:ptr: Pointer to default value for optional fields, or to submessage description for PB_LTYPE_SUBMESSAGE. + +The *uint8_t* datatypes limit the maximum size of a single item to 255 bytes and arrays to 255 items. Compiler will give error if the values are too large. The types can be changed to larger ones by defining *PB_FIELD_16BIT*. + +pb_bytes_array_t +---------------- +An byte array with a field for storing the length:: + + typedef struct { + pb_size_t size; + pb_byte_t bytes[1]; + } pb_bytes_array_t; + +In an actual array, the length of *bytes* may be different. + +pb_callback_t +------------- +Part of a message structure, for fields with type PB_HTYPE_CALLBACK:: + + typedef struct _pb_callback_t pb_callback_t; + struct _pb_callback_t { + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); + } funcs; + + void *arg; + }; + +A pointer to the *arg* is passed to the callback when calling. It can be used to store any information that the callback might need. + +Previously the function received just the value of *arg* instead of a pointer to it. This old behaviour can be enabled by defining *PB_OLD_CALLBACK_STYLE*. + +When calling `pb_encode`_, *funcs.encode* is used, and similarly when calling `pb_decode`_, *funcs.decode* is used. The function pointers are stored in the same memory location but are of incompatible types. You can set the function pointer to NULL to skip the field. + +pb_wire_type_t +-------------- +Protocol Buffers wire types. These are used with `pb_encode_tag`_. :: + + typedef enum { + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5 + } pb_wire_type_t; + +pb_extension_type_t +------------------- +Defines the handler functions and auxiliary data for a field that extends +another message. Usually autogenerated by *nanopb_generator.py*:: + + typedef struct { + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, + uint32_t tag, pb_wire_type_t wire_type); + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + const void *arg; + } pb_extension_type_t; + +In the normal case, the function pointers are *NULL* and the decoder and +encoder use their internal implementations. The internal implementations +assume that *arg* points to a *pb_field_t* that describes the field in question. + +To implement custom processing of unknown fields, you can provide pointers +to your own functions. Their functionality is mostly the same as for normal +callback fields, except that they get called for any unknown field when decoding. + +pb_extension_t +-------------- +Ties together the extension field type and the storage for the field value:: + + typedef struct { + const pb_extension_type_t *type; + void *dest; + pb_extension_t *next; + bool found; + } pb_extension_t; + +:type: Pointer to the structure that defines the callback functions. +:dest: Pointer to the variable that stores the field value + (as used by the default extension callback functions.) +:next: Pointer to the next extension handler, or *NULL*. +:found: Decoder sets this to true if the extension was found. + +PB_GET_ERROR +------------ +Get the current error message from a stream, or a placeholder string if +there is no error message:: + + #define PB_GET_ERROR(stream) (string expression) + +This should be used for printing errors, for example:: + + if (!pb_decode(...)) + { + printf("Decode failed: %s\n", PB_GET_ERROR(stream)); + } + +The macro only returns pointers to constant strings (in code memory), +so that there is no need to release the returned pointer. + +PB_RETURN_ERROR +--------------- +Set the error message and return false:: + + #define PB_RETURN_ERROR(stream,msg) (sets error and returns false) + +This should be used to handle error conditions inside nanopb functions +and user callback functions:: + + if (error_condition) + { + PB_RETURN_ERROR(stream, "something went wrong"); + } + +The *msg* parameter must be a constant string. + + + +pb_encode.h +=========== + +pb_ostream_from_buffer +---------------------- +Constructs an output stream for writing into a memory buffer. This is just a helper function, it doesn't do anything you couldn't do yourself in a callback function. It uses an internal callback that stores the pointer in stream *state* field. :: + + pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + +:buf: Memory buffer to write into. +:bufsize: Maximum number of bytes to write. +:returns: An output stream. + +After writing, you can check *stream.bytes_written* to find out how much valid data there is in the buffer. + +pb_write +-------- +Writes data to an output stream. Always use this function, instead of trying to call stream callback manually. :: + + bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + +:stream: Output stream to write to. +:buf: Pointer to buffer with the data to be written. +:count: Number of bytes to write. +:returns: True on success, false if maximum length is exceeded or an IO error happens. + +If an error happens, *bytes_written* is not incremented. Depending on the callback used, calling pb_write again after it has failed once may be dangerous. Nanopb itself never does this, instead it returns the error to user application. The builtin pb_ostream_from_buffer is safe to call again after failed write. + +pb_encode +--------- +Encodes the contents of a structure as a protocol buffers message and writes it to output stream. :: + + bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +:stream: Output stream to write to. +:fields: A field description array, usually autogenerated. +:src_struct: Pointer to the data that will be serialized. +:returns: True on success, false on IO error, on detectable errors in field description, or if a field encoder returns false. + +Normally pb_encode simply walks through the fields description array and serializes each field in turn. However, submessages must be serialized twice: first to calculate their size and then to actually write them to output. This causes some constraints for callback fields, which must return the same data on every call. + +pb_encode_delimited +------------------- +Calculates the length of the message, encodes it as varint and then encodes the message. :: + + bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +(parameters are the same as for `pb_encode`_.) + +A common way to indicate the message length in Protocol Buffers is to prefix it with a varint. +This function does this, and it is compatible with *parseDelimitedFrom* in Google's protobuf library. + +.. sidebar:: Encoding fields manually + + The functions with names *pb_encode_\** are used when dealing with callback fields. The typical reason for using callbacks is to have an array of unlimited size. In that case, `pb_encode`_ will call your callback function, which in turn will call *pb_encode_\** functions repeatedly to write out values. + + The tag of a field must be encoded separately with `pb_encode_tag_for_field`_. After that, you can call exactly one of the content-writing functions to encode the payload of the field. For repeated fields, you can repeat this process multiple times. + + Writing packed arrays is a little bit more involved: you need to use `pb_encode_tag` and specify `PB_WT_STRING` as the wire type. Then you need to know exactly how much data you are going to write, and use `pb_encode_varint`_ to write out the number of bytes before writing the actual data. Substreams can be used to determine the number of bytes beforehand; see `pb_encode_submessage`_ source code for an example. + +pb_get_encoded_size +------------------- +Calculates the length of the encoded message. :: + + bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct); + +:size: Calculated size of the encoded message. +:fields: A field description array, usually autogenerated. +:src_struct: Pointer to the data that will be serialized. +:returns: True on success, false on detectable errors in field description or if a field encoder returns false. + +pb_encode_tag +------------- +Starts a field in the Protocol Buffers binary format: encodes the field number and the wire type of the data. :: + + bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); + +:stream: Output stream to write to. 1-5 bytes will be written. +:wiretype: PB_WT_VARINT, PB_WT_64BIT, PB_WT_STRING or PB_WT_32BIT +:field_number: Identifier for the field, defined in the .proto file. You can get it from field->tag. +:returns: True on success, false on IO error. + +pb_encode_tag_for_field +----------------------- +Same as `pb_encode_tag`_, except takes the parameters from a *pb_field_t* structure. :: + + bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field); + +:stream: Output stream to write to. 1-5 bytes will be written. +:field: Field description structure. Usually autogenerated. +:returns: True on success, false on IO error or unknown field type. + +This function only considers the LTYPE of the field. You can use it from your field callbacks, because the source generator writes correct LTYPE also for callback type fields. + +Wire type mapping is as follows: + +============================================= ============ +LTYPEs Wire type +============================================= ============ +VARINT, UVARINT, SVARINT PB_WT_VARINT +FIXED64 PB_WT_64BIT +STRING, BYTES, SUBMESSAGE, FIXED_LENGTH_BYTES PB_WT_STRING +FIXED32 PB_WT_32BIT +============================================= ============ + +pb_encode_varint +---------------- +Encodes a signed or unsigned integer in the varint_ format. Works for fields of type `bool`, `enum`, `int32`, `int64`, `uint32` and `uint64`:: + + bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); + +:stream: Output stream to write to. 1-10 bytes will be written. +:value: Value to encode. Just cast e.g. int32_t directly to uint64_t. +:returns: True on success, false on IO error. + +.. _varint: http://code.google.com/apis/protocolbuffers/docs/encoding.html#varints + +pb_encode_svarint +----------------- +Encodes a signed integer in the 'zig-zagged' format. Works for fields of type `sint32` and `sint64`:: + + bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); + +(parameters are the same as for `pb_encode_varint`_ + +pb_encode_string +---------------- +Writes the length of a string as varint and then contents of the string. Works for fields of type `bytes` and `string`:: + + bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); + +:stream: Output stream to write to. +:buffer: Pointer to string data. +:size: Number of bytes in the string. Pass `strlen(s)` for strings. +:returns: True on success, false on IO error. + +pb_encode_fixed32 +----------------- +Writes 4 bytes to stream and swaps bytes on big-endian architectures. Works for fields of type `fixed32`, `sfixed32` and `float`:: + + bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + +:stream: Output stream to write to. +:value: Pointer to a 4-bytes large C variable, for example `uint32_t foo;`. +:returns: True on success, false on IO error. + +pb_encode_fixed64 +----------------- +Writes 8 bytes to stream and swaps bytes on big-endian architecture. Works for fields of type `fixed64`, `sfixed64` and `double`:: + + bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); + +:stream: Output stream to write to. +:value: Pointer to a 8-bytes large C variable, for example `uint64_t foo;`. +:returns: True on success, false on IO error. + +pb_encode_submessage +-------------------- +Encodes a submessage field, including the size header for it. Works for fields of any message type:: + + bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +:stream: Output stream to write to. +:fields: Pointer to the autogenerated field description array for the submessage type, e.g. `MyMessage_fields`. +:src: Pointer to the structure where submessage data is. +:returns: True on success, false on IO errors, pb_encode errors or if submessage size changes between calls. + +In Protocol Buffers format, the submessage size must be written before the submessage contents. Therefore, this function has to encode the submessage twice in order to know the size beforehand. + +If the submessage contains callback fields, the callback function might misbehave and write out a different amount of data on the second call. This situation is recognized and *false* is returned, but garbage will be written to the output before the problem is detected. + + + + + + + + + + + + +pb_decode.h +=========== + +pb_istream_from_buffer +---------------------- +Helper function for creating an input stream that reads data from a memory buffer. :: + + pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize); + +:buf: Pointer to byte array to read from. +:bufsize: Size of the byte array. +:returns: An input stream ready to use. + +pb_read +------- +Read data from input stream. Always use this function, don't try to call the stream callback directly. :: + + bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + +:stream: Input stream to read from. +:buf: Buffer to store the data to, or NULL to just read data without storing it anywhere. +:count: Number of bytes to read. +:returns: True on success, false if *stream->bytes_left* is less than *count* or if an IO error occurs. + +End of file is signalled by *stream->bytes_left* being zero after pb_read returns false. + +pb_decode +--------- +Read and decode all fields of a structure. Reads until EOF on input stream. :: + + bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +:stream: Input stream to read from. +:fields: A field description array. Usually autogenerated. +:dest_struct: Pointer to structure where data will be stored. +:returns: True on success, false on IO error, on detectable errors in field description, if a field encoder returns false or if a required field is missing. + +In Protocol Buffers binary format, EOF is only allowed between fields. If it happens anywhere else, pb_decode will return *false*. If pb_decode returns false, you cannot trust any of the data in the structure. + +In addition to EOF, the pb_decode implementation supports terminating a message with a 0 byte. This is compatible with the official Protocol Buffers because 0 is never a valid field tag. + +For optional fields, this function applies the default value and sets *has_* to false if the field is not present. + +If *PB_ENABLE_MALLOC* is defined, this function may allocate storage for any pointer type fields. +In this case, you have to call `pb_release`_ to release the memory after you are done with the message. +On error return `pb_decode` will release the memory itself. + +pb_decode_noinit +---------------- +Same as `pb_decode`_, except does not apply the default values to fields. :: + + bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +(parameters are the same as for `pb_decode`_.) + +The destination structure should be filled with zeros before calling this function. Doing a *memset* manually can be slightly faster than using `pb_decode`_ if you don't need any default values. + +In addition to decoding a single message, this function can be used to merge two messages, so that +values from previous message will remain if the new message does not contain a field. + +This function *will not* release the message even on error return. If you use *PB_ENABLE_MALLOC*, +you will need to call `pb_release`_ yourself. + +pb_decode_delimited +------------------- +Same as `pb_decode`_, except that it first reads a varint with the length of the message. :: + + bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +(parameters are the same as for `pb_decode`_.) + +A common method to indicate message size in Protocol Buffers is to prefix it with a varint. +This function is compatible with *writeDelimitedTo* in the Google's Protocol Buffers library. + +pb_release +---------- +Releases any dynamically allocated fields:: + + void pb_release(const pb_field_t fields[], void *dest_struct); + +:fields: A field description array. Usually autogenerated. +:dest_struct: Pointer to structure where data is stored. If NULL, function does nothing. + +This function is only available if *PB_ENABLE_MALLOC* is defined. It will release any +pointer type fields in the structure and set the pointers to NULL. + +pb_decode_tag +------------- +Decode the tag that comes before field in the protobuf encoding:: + + bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); + +:stream: Input stream to read from. +:wire_type: Pointer to variable where to store the wire type of the field. +:tag: Pointer to variable where to store the tag of the field. +:eof: Pointer to variable where to store end-of-file status. +:returns: True on success, false on error or EOF. + +When the message (stream) ends, this function will return false and set *eof* to true. On other +errors, *eof* will be set to false. + +pb_skip_field +------------- +Remove the data for a field from the stream, without actually decoding it:: + + bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + +:stream: Input stream to read from. +:wire_type: Type of field to skip. +:returns: True on success, false on IO error. + +.. sidebar:: Decoding fields manually + + The functions with names beginning with *pb_decode_* are used when dealing with callback fields. The typical reason for using callbacks is to have an array of unlimited size. In that case, `pb_decode`_ will call your callback function repeatedly, which can then store the values into e.g. filesystem in the order received in. + + For decoding numeric (including enumerated and boolean) values, use `pb_decode_varint`_, `pb_decode_svarint`_, `pb_decode_fixed32`_ and `pb_decode_fixed64`_. They take a pointer to a 32- or 64-bit C variable, which you may then cast to smaller datatype for storage. + + For decoding strings and bytes fields, the length has already been decoded. You can therefore check the total length in *stream->bytes_left* and read the data using `pb_read`_. + + Finally, for decoding submessages in a callback, simply use `pb_decode`_ and pass it the *SubMessage_fields* descriptor array. + +pb_decode_varint +---------------- +Read and decode a varint_ encoded integer. :: + + bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); + +:stream: Input stream to read from. 1-10 bytes will be read. +:dest: Storage for the decoded integer. Value is undefined on error. +:returns: True on success, false if value exceeds uint64_t range or an IO error happens. + +pb_decode_svarint +----------------- +Similar to `pb_decode_varint`_, except that it performs zigzag-decoding on the value. This corresponds to the Protocol Buffers *sint32* and *sint64* datatypes. :: + + bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); + +(parameters are the same as `pb_decode_varint`_) + +pb_decode_fixed32 +----------------- +Decode a *fixed32*, *sfixed32* or *float* value. :: + + bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + +:stream: Input stream to read from. 4 bytes will be read. +:dest: Pointer to destination *int32_t*, *uint32_t* or *float*. +:returns: True on success, false on IO errors. + +This function reads 4 bytes from the input stream. +On big endian architectures, it then reverses the order of the bytes. +Finally, it writes the bytes to *dest*. + +pb_decode_fixed64 +----------------- +Decode a *fixed64*, *sfixed64* or *double* value. :: + + bool pb_decode_fixed64(pb_istream_t *stream, void *dest); + +:stream: Input stream to read from. 8 bytes will be read. +:dest: Pointer to destination *int64_t*, *uint64_t* or *double*. +:returns: True on success, false on IO errors. + +Same as `pb_decode_fixed32`_, except this reads 8 bytes. + +pb_make_string_substream +------------------------ +Decode the length for a field with wire type *PB_WT_STRING* and create a substream for reading the data. :: + + bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +:stream: Original input stream to read the length and data from. +:substream: New substream that has limited length. Filled in by the function. +:returns: True on success, false if reading the length fails. + +This function uses `pb_decode_varint`_ to read an integer from the stream. This is interpreted as a number of bytes, and the substream is set up so that its `bytes_left` is initially the same as the length, and its callback function and state the same as the parent stream. + +pb_close_string_substream +------------------------- +Close the substream created with `pb_make_string_substream`_. :: + + void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +:stream: Original input stream to read the length and data from. +:substream: Substream to close + +This function copies back the state from the substream to the parent stream. +It must be called after done with the substream. diff --git a/hardware-wallet/firmware/vendor/nanopb/docs/security.rst b/hardware-wallet/firmware/vendor/nanopb/docs/security.rst new file mode 100644 index 00000000..d8546122 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/docs/security.rst @@ -0,0 +1,84 @@ +====================== +Nanopb: Security model +====================== + +.. include :: menu.rst + +.. contents :: + + + +Importance of security in a Protocol Buffers library +==================================================== +In the context of protocol buffers, security comes into play when decoding +untrusted data. Naturally, if the attacker can modify the contents of a +protocol buffers message, he can feed the application any values possible. +Therefore the application itself must be prepared to receive untrusted values. + +Where nanopb plays a part is preventing the attacker from running arbitrary +code on the target system. Mostly this means that there must not be any +possibility to cause buffer overruns, memory corruption or invalid pointers +by the means of crafting a malicious message. + +Division of trusted and untrusted data +====================================== +The following data is regarded as **trusted**. It must be under the control of +the application writer. Malicious data in these structures could cause +security issues, such as execution of arbitrary code: + +1. Callback, pointer and extension fields in message structures given to + pb_encode() and pb_decode(). These fields are memory pointers, and are + generated depending on the message definition in the .proto file. +2. The automatically generated field definitions, i.e. *pb_field_t* lists. +3. Contents of the *pb_istream_t* and *pb_ostream_t* structures (this does not + mean the contents of the stream itself, just the stream definition). + +The following data is regarded as **untrusted**. Invalid/malicious data in +these will cause "garbage in, garbage out" behaviour. It will not cause +buffer overflows, information disclosure or other security problems: + +1. All data read from *pb_istream_t*. +2. All fields in message structures, except: + + - callbacks (*pb_callback_t* structures) + - pointer fields (malloc support) and *_count* fields for pointers + - extensions (*pb_extension_t* structures) + +Invariants +========== +The following invariants are maintained during operation, even if the +untrusted data has been maliciously crafted: + +1. Nanopb will never read more than *bytes_left* bytes from *pb_istream_t*. +2. Nanopb will never write more than *max_size* bytes to *pb_ostream_t*. +3. Nanopb will never access memory out of bounds of the message structure. +4. After pb_decode() returns successfully, the message structure will be + internally consistent: + + - The *count* fields of arrays will not exceed the array size. + - The *size* field of bytes will not exceed the allocated size. + - All string fields will have null terminator. + +5. After pb_encode() returns successfully, the resulting message is a valid + protocol buffers message. (Except if user-defined callbacks write incorrect + data.) + +Further considerations +====================== +Even if the nanopb library is free of any security issues, there are still +several possible attack vectors that the application author must consider. +The following list is not comprehensive: + +1. Stack usage may depend on the contents of the message. The message + definition places an upper bound on how much stack will be used. Tests + should be run with all fields present, to record the maximum possible + stack usage. +2. Callbacks can do anything. The code for the callbacks must be carefully + checked if they are used with untrusted data. +3. If using stream input, a maximum size should be set in *pb_istream_t* to + stop a denial of service attack from using an infinite message. +4. If using network sockets as streams, a timeout should be set to stop + denial of service attacks. +5. If using *malloc()* support, some method of limiting memory use should be + employed. This can be done by defining custom *pb_realloc()* function. + Nanopb will properly detect and handle failed memory allocations. diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/CMakeLists.txt b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/CMakeLists.txt new file mode 100644 index 00000000..e7727d85 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 2.8) +project(NANOPB_CMAKE_SIMPLE C) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../extra) +find_package(Nanopb REQUIRED) +include_directories(${NANOPB_INCLUDE_DIRS}) + +nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS RELPATH proto + proto/simple.proto proto/sub/unlucky.proto) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +#add_custom_target(generate_proto_sources DEPENDS ${PROTO_SRCS} ${PROTO_HDRS}) +set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS} + PROPERTIES GENERATED TRUE) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -g -O0") + +add_executable(simple simple.c ${PROTO_SRCS} ${PROTO_HDRS}) diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/README.txt b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/README.txt new file mode 100644 index 00000000..aa0f3f3a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/README.txt @@ -0,0 +1,18 @@ +Nanopb example "simple" using CMake +======================= + +This example is the same as the simple nanopb example but built using CMake. + +Example usage +------------- + +On Linux, create a build directory and then call cmake: + + nanopb/examples/cmake_simple$ mkdir build + nanopb/examples/cmake_simple$ cd build/ + nanopb/examples/cmake_simple/build$ cmake .. + nanopb/examples/cmake_simple/build$ make + +After that, you can run it with the command: ./simple + +On other platforms supported by CMake, refer to CMake instructions. diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/simple.proto b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/simple.proto new file mode 100644 index 00000000..3bf4ad1d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/simple.proto @@ -0,0 +1,11 @@ +// A very simple protocol definition, consisting of only +// one message. +syntax = "proto2"; + +import "sub/unlucky.proto"; + +message SimpleMessage { + required int32 lucky_number = 1; + required UnluckyNumber unlucky = 2; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/sub/unlucky.proto b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/sub/unlucky.proto new file mode 100644 index 00000000..97a42c9c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/proto/sub/unlucky.proto @@ -0,0 +1,5 @@ +syntax = "proto2"; + +message UnluckyNumber { + required uint32 number = 1; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/simple.c b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/simple.c new file mode 100644 index 00000000..231886c2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_relpath/simple.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include "simple.pb.h" + +int main() +{ + /* This is the buffer where we will store our message. */ + uint8_t buffer[128]; + size_t message_length; + bool status; + + /* Encode our message */ + { + /* Allocate space on the stack to store the message data. + * + * Nanopb generates simple struct definitions for all the messages. + * - check out the contents of simple.pb.h! + * It is a good idea to always initialize your structures + * so that you do not have garbage data from RAM in there. + */ + SimpleMessage message = SimpleMessage_init_zero; + + /* Create a stream that will write to our buffer. */ + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Fill in the lucky number */ + message.lucky_number = 13; + message.unlucky.number = 42; + + /* Now we are ready to encode the message! */ + status = pb_encode(&stream, SimpleMessage_fields, &message); + message_length = stream.bytes_written; + + /* Then just check for any errors.. */ + if (!status) + { + printf("Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + } + + /* Now we could transmit the message over network, store it in a file or + * wrap it to a pigeon's leg. + */ + + /* But because we are lazy, we will just decode it immediately. */ + + { + /* Allocate space for the decoded message. */ + SimpleMessage message = SimpleMessage_init_zero; + + /* Create a stream that reads from the buffer. */ + pb_istream_t stream = pb_istream_from_buffer(buffer, message_length); + + /* Now we are ready to decode the message. */ + status = pb_decode(&stream, SimpleMessage_fields, &message); + + /* Check for errors... */ + if (!status) + { + printf("Decoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + + /* Print the data contained in the message. */ + printf("Your lucky number was %d!\n", message.lucky_number); + printf("Your unlucky number was %u!\n", message.unlucky.number); + } + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/CMakeLists.txt b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/CMakeLists.txt new file mode 100644 index 00000000..e5f33a02 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 2.8) +project(NANOPB_CMAKE_SIMPLE C) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../extra) +find_package(Nanopb REQUIRED) +include_directories(${NANOPB_INCLUDE_DIRS}) + +nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS simple.proto) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +#add_custom_target(generate_proto_sources DEPENDS ${PROTO_SRCS} ${PROTO_HDRS}) +set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS} + PROPERTIES GENERATED TRUE) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -g -O0") + +add_executable(simple simple.c ${PROTO_SRCS} ${PROTO_HDRS}) diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/README.txt b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/README.txt new file mode 100644 index 00000000..aa0f3f3a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/README.txt @@ -0,0 +1,18 @@ +Nanopb example "simple" using CMake +======================= + +This example is the same as the simple nanopb example but built using CMake. + +Example usage +------------- + +On Linux, create a build directory and then call cmake: + + nanopb/examples/cmake_simple$ mkdir build + nanopb/examples/cmake_simple$ cd build/ + nanopb/examples/cmake_simple/build$ cmake .. + nanopb/examples/cmake_simple/build$ make + +After that, you can run it with the command: ./simple + +On other platforms supported by CMake, refer to CMake instructions. diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.c b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.c new file mode 100644 index 00000000..1f6b1373 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include "simple.pb.h" + +int main() +{ + /* This is the buffer where we will store our message. */ + uint8_t buffer[128]; + size_t message_length; + bool status; + + /* Encode our message */ + { + /* Allocate space on the stack to store the message data. + * + * Nanopb generates simple struct definitions for all the messages. + * - check out the contents of simple.pb.h! + * It is a good idea to always initialize your structures + * so that you do not have garbage data from RAM in there. + */ + SimpleMessage message = SimpleMessage_init_zero; + + /* Create a stream that will write to our buffer. */ + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Fill in the lucky number */ + message.lucky_number = 13; + + /* Now we are ready to encode the message! */ + status = pb_encode(&stream, SimpleMessage_fields, &message); + message_length = stream.bytes_written; + + /* Then just check for any errors.. */ + if (!status) + { + printf("Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + } + + /* Now we could transmit the message over network, store it in a file or + * wrap it to a pigeon's leg. + */ + + /* But because we are lazy, we will just decode it immediately. */ + + { + /* Allocate space for the decoded message. */ + SimpleMessage message = SimpleMessage_init_zero; + + /* Create a stream that reads from the buffer. */ + pb_istream_t stream = pb_istream_from_buffer(buffer, message_length); + + /* Now we are ready to decode the message. */ + status = pb_decode(&stream, SimpleMessage_fields, &message); + + /* Check for errors... */ + if (!status) + { + printf("Decoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + + /* Print the data contained in the message. */ + printf("Your lucky number was %d!\n", message.lucky_number); + } + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.proto b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.proto new file mode 100644 index 00000000..5c73a3b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/cmake_simple/simple.proto @@ -0,0 +1,9 @@ +// A very simple protocol definition, consisting of only +// one message. + +syntax = "proto2"; + +message SimpleMessage { + required int32 lucky_number = 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/Makefile b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/Makefile new file mode 100644 index 00000000..2c7639a1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/Makefile @@ -0,0 +1,17 @@ +# Include the nanopb provided Makefile rules +include ../../extra/nanopb.mk + +# Compiler flags to enable all warnings & debug info +CFLAGS = -ansi -Wall -Werror -g -O0 +CFLAGS += -I$(NANOPB_DIR) + +all: server client + +.SUFFIXES: + +clean: + rm -f server client fileproto.pb.c fileproto.pb.h + +%: %.c common.c fileproto.pb.c + $(CC) $(CFLAGS) -o $@ $^ $(NANOPB_CORE) + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/README.txt b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/README.txt new file mode 100644 index 00000000..7bdcbed5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/README.txt @@ -0,0 +1,60 @@ +Nanopb example "network_server" +=============================== + +This example demonstrates the use of nanopb to communicate over network +connections. It consists of a server that sends file listings, and of +a client that requests the file list from the server. + +Example usage +------------- + +user@host:~/nanopb/examples/network_server$ make # Build the example +protoc -ofileproto.pb fileproto.proto +python ../../generator/nanopb_generator.py fileproto.pb +Writing to fileproto.pb.h and fileproto.pb.c +cc -ansi -Wall -Werror -I .. -g -O0 -I../.. -o server server.c + ../../pb_decode.c ../../pb_encode.c fileproto.pb.c common.c +cc -ansi -Wall -Werror -I .. -g -O0 -I../.. -o client client.c + ../../pb_decode.c ../../pb_encode.c fileproto.pb.c common.c + +user@host:~/nanopb/examples/network_server$ ./server & # Start the server on background +[1] 24462 + +petteri@oddish:~/nanopb/examples/network_server$ ./client /bin # Request the server to list /bin +Got connection. +Listing directory: /bin +1327119 bzdiff +1327126 bzless +1327147 ps +1327178 ntfsmove +1327271 mv +1327187 mount +1327259 false +1327266 tempfile +1327285 zfgrep +1327165 gzexe +1327204 nc.openbsd +1327260 uname + + +Details of implementation +------------------------- +fileproto.proto contains the portable Google Protocol Buffers protocol definition. +It could be used as-is to implement a server or a client in any other language, for +example Python or Java. + +fileproto.options contains the nanopb-specific options for the protocol file. This +sets the amount of space allocated for file names when decoding messages. + +common.c/h contains functions that allow nanopb to read and write directly from +network socket. This way there is no need to allocate a separate buffer to store +the message. + +server.c contains the code to open a listening socket, to respond to clients and +to list directory contents. + +client.c contains the code to connect to a server, to send a request and to print +the response message. + +The code is implemented using the POSIX socket api, but it should be easy enough +to port into any other socket api, such as lwip. diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/client.c b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/client.c new file mode 100644 index 00000000..ca0c68ef --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/client.c @@ -0,0 +1,138 @@ +/* This is a simple TCP client that connects to port 1234 and prints a list + * of files in a given directory. + * + * It directly deserializes and serializes messages from network, minimizing + * memory use. + * + * For flexibility, this example is implemented using posix api. + * In a real embedded system you would typically use some other kind of + * a communication and filesystem layer. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "fileproto.pb.h" +#include "common.h" + +/* This callback function will be called once for each filename received + * from the server. The filenames will be printed out immediately, so that + * no memory has to be allocated for them. + */ +bool printfile_callback(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + FileInfo fileinfo = {}; + + if (!pb_decode(stream, FileInfo_fields, &fileinfo)) + return false; + + printf("%-10lld %s\n", (long long)fileinfo.inode, fileinfo.name); + + return true; +} + +/* This function sends a request to socket 'fd' to list the files in + * directory given in 'path'. The results received from server will + * be printed to stdout. + */ +bool listdir(int fd, char *path) +{ + /* Construct and send the request to server */ + { + ListFilesRequest request = {}; + pb_ostream_t output = pb_ostream_from_socket(fd); + + /* In our protocol, path is optional. If it is not given, + * the server will list the root directory. */ + if (path == NULL) + { + request.has_path = false; + } + else + { + request.has_path = true; + if (strlen(path) + 1 > sizeof(request.path)) + { + fprintf(stderr, "Too long path.\n"); + return false; + } + + strcpy(request.path, path); + } + + /* Encode the request. It is written to the socket immediately + * through our custom stream. */ + if (!pb_encode_delimited(&output, ListFilesRequest_fields, &request)) + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&output)); + return false; + } + } + + /* Read back the response from server */ + { + ListFilesResponse response = {}; + pb_istream_t input = pb_istream_from_socket(fd); + + /* Give a pointer to our callback function, which will handle the + * filenames as they arrive. */ + response.file.funcs.decode = &printfile_callback; + + if (!pb_decode_delimited(&input, ListFilesResponse_fields, &response)) + { + fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&input)); + return false; + } + + /* If the message from server decodes properly, but directory was + * not found on server side, we get path_error == true. */ + if (response.path_error) + { + fprintf(stderr, "Server reported error.\n"); + return false; + } + } + + return true; +} + +int main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + char *path = NULL; + + if (argc > 1) + path = argv[1]; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + /* Connect to server running on localhost:1234 */ + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + servaddr.sin_port = htons(1234); + + if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) + { + perror("connect"); + return 1; + } + + /* Send the directory listing request */ + if (!listdir(sockfd, path)) + return 2; + + /* Close connection */ + close(sockfd); + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.c b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.c new file mode 100644 index 00000000..04a5aa85 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.c @@ -0,0 +1,40 @@ +/* Simple binding of nanopb streams to TCP sockets. + */ + +#include +#include +#include +#include + +#include "common.h" + +static bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count) +{ + int fd = (intptr_t)stream->state; + return send(fd, buf, count, 0) == count; +} + +static bool read_callback(pb_istream_t *stream, uint8_t *buf, size_t count) +{ + int fd = (intptr_t)stream->state; + int result; + + result = recv(fd, buf, count, MSG_WAITALL); + + if (result == 0) + stream->bytes_left = 0; /* EOF */ + + return result == count; +} + +pb_ostream_t pb_ostream_from_socket(int fd) +{ + pb_ostream_t stream = {&write_callback, (void*)(intptr_t)fd, SIZE_MAX, 0}; + return stream; +} + +pb_istream_t pb_istream_from_socket(int fd) +{ + pb_istream_t stream = {&read_callback, (void*)(intptr_t)fd, SIZE_MAX}; + return stream; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.h b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.h new file mode 100644 index 00000000..8dab3b7c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/common.h @@ -0,0 +1,9 @@ +#ifndef _PB_EXAMPLE_COMMON_H_ +#define _PB_EXAMPLE_COMMON_H_ + +#include + +pb_ostream_t pb_ostream_from_socket(int fd); +pb_istream_t pb_istream_from_socket(int fd); + +#endif \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.options b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.options new file mode 100644 index 00000000..29a2ab0e --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.options @@ -0,0 +1,13 @@ +# This file defines the nanopb-specific options for the messages defined +# in fileproto.proto. +# +# If you come from high-level programming background, the hardcoded +# maximum lengths may disgust you. However, if your microcontroller only +# has a few kB of ram to begin with, setting reasonable limits for +# filenames is ok. +# +# On the other hand, using the callback interface, it is not necessary +# to set a limit on the number of files in the response. + +ListFilesRequest.path max_size:128 +FileInfo.name max_size:128 diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.proto b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.proto new file mode 100644 index 00000000..5640b8d5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/fileproto.proto @@ -0,0 +1,20 @@ +// This defines protocol for a simple server that lists files. +// +// See also the nanopb-specific options in fileproto.options. + +syntax = "proto2"; + +message ListFilesRequest { + optional string path = 1 [default = "/"]; +} + +message FileInfo { + required uint64 inode = 1; + required string name = 2; +} + +message ListFilesResponse { + optional bool path_error = 1 [default = false]; + repeated FileInfo file = 2; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/network_server/server.c b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/server.c new file mode 100644 index 00000000..f500dcd7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/network_server/server.c @@ -0,0 +1,162 @@ +/* This is a simple TCP server that listens on port 1234 and provides lists + * of files to clients, using a protocol defined in file_server.proto. + * + * It directly deserializes and serializes messages from network, minimizing + * memory use. + * + * For flexibility, this example is implemented using posix api. + * In a real embedded system you would typically use some other kind of + * a communication and filesystem layer. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "fileproto.pb.h" +#include "common.h" + +/* This callback function will be called once during the encoding. + * It will write out any number of FileInfo entries, without consuming unnecessary memory. + * This is accomplished by fetching the filenames one at a time and encoding them + * immediately. + */ +bool listdir_callback(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + DIR *dir = (DIR*) *arg; + struct dirent *file; + FileInfo fileinfo = {}; + + while ((file = readdir(dir)) != NULL) + { + fileinfo.inode = file->d_ino; + strncpy(fileinfo.name, file->d_name, sizeof(fileinfo.name)); + fileinfo.name[sizeof(fileinfo.name) - 1] = '\0'; + + /* This encodes the header for the field, based on the constant info + * from pb_field_t. */ + if (!pb_encode_tag_for_field(stream, field)) + return false; + + /* This encodes the data for the field, based on our FileInfo structure. */ + if (!pb_encode_submessage(stream, FileInfo_fields, &fileinfo)) + return false; + } + + /* Because the main program uses pb_encode_delimited(), this callback will be + * called twice. Rewind the directory for the next call. */ + rewinddir(dir); + + return true; +} + +/* Handle one arriving client connection. + * Clients are expected to send a ListFilesRequest, terminated by a '0'. + * Server will respond with a ListFilesResponse message. + */ +void handle_connection(int connfd) +{ + DIR *directory = NULL; + + /* Decode the message from the client and open the requested directory. */ + { + ListFilesRequest request = {}; + pb_istream_t input = pb_istream_from_socket(connfd); + + if (!pb_decode_delimited(&input, ListFilesRequest_fields, &request)) + { + printf("Decode failed: %s\n", PB_GET_ERROR(&input)); + return; + } + + directory = opendir(request.path); + printf("Listing directory: %s\n", request.path); + } + + /* List the files in the directory and transmit the response to client */ + { + ListFilesResponse response = {}; + pb_ostream_t output = pb_ostream_from_socket(connfd); + + if (directory == NULL) + { + perror("opendir"); + + /* Directory was not found, transmit error status */ + response.has_path_error = true; + response.path_error = true; + response.file.funcs.encode = NULL; + } + else + { + /* Directory was found, transmit filenames */ + response.has_path_error = false; + response.file.funcs.encode = &listdir_callback; + response.file.arg = directory; + } + + if (!pb_encode_delimited(&output, ListFilesResponse_fields, &response)) + { + printf("Encoding failed: %s\n", PB_GET_ERROR(&output)); + } + } + + if (directory != NULL) + closedir(directory); +} + +int main(int argc, char **argv) +{ + int listenfd, connfd; + struct sockaddr_in servaddr; + int reuse = 1; + + /* Listen on localhost:1234 for TCP connections */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + servaddr.sin_port = htons(1234); + if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0) + { + perror("bind"); + return 1; + } + + if (listen(listenfd, 5) != 0) + { + perror("listen"); + return 1; + } + + for(;;) + { + /* Wait for a client */ + connfd = accept(listenfd, NULL, NULL); + + if (connfd < 0) + { + perror("accept"); + return 1; + } + + printf("Got connection.\n"); + + handle_connection(connfd); + + printf("Closing connection.\n"); + + close(connfd); + } + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/simple/Makefile b/hardware-wallet/firmware/vendor/nanopb/examples/simple/Makefile new file mode 100644 index 00000000..970a8650 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/simple/Makefile @@ -0,0 +1,22 @@ +# Include the nanopb provided Makefile rules +include ../../extra/nanopb.mk + +# Compiler flags to enable all warnings & debug info +CFLAGS = -Wall -Werror -g -O0 +CFLAGS += -I$(NANOPB_DIR) + +# C source code files that are required +CSRC = simple.c # The main program +CSRC += simple.pb.c # The compiled protocol definition +CSRC += $(NANOPB_DIR)/pb_encode.c # The nanopb encoder +CSRC += $(NANOPB_DIR)/pb_decode.c # The nanopb decoder +CSRC += $(NANOPB_DIR)/pb_common.c # The nanopb common parts + +# Build rule for the main program +simple: $(CSRC) + $(CC) $(CFLAGS) -osimple $(CSRC) + +# Build rule for the protocol +simple.pb.c: simple.proto + $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. simple.proto + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/simple/README.txt b/hardware-wallet/firmware/vendor/nanopb/examples/simple/README.txt new file mode 100644 index 00000000..ee77bfc7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/simple/README.txt @@ -0,0 +1,29 @@ +Nanopb example "simple" +======================= + +This example demonstrates the very basic use of nanopb. It encodes and +decodes a simple message. + +The code uses four different API functions: + + * pb_ostream_from_buffer() to declare the output buffer that is to be used + * pb_encode() to encode a message + * pb_istream_from_buffer() to declare the input buffer that is to be used + * pb_decode() to decode a message + +Example usage +------------- + +On Linux, simply type "make" to build the example. After that, you can +run it with the command: ./simple + +On other platforms, you first have to compile the protocol definition using +the following command:: + + ../../generator-bin/protoc --nanopb_out=. simple.proto + +After that, add the following four files to your project and compile: + + simple.c simple.pb.c pb_encode.c pb_decode.c + + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.c b/hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.c new file mode 100644 index 00000000..1f6b1373 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include "simple.pb.h" + +int main() +{ + /* This is the buffer where we will store our message. */ + uint8_t buffer[128]; + size_t message_length; + bool status; + + /* Encode our message */ + { + /* Allocate space on the stack to store the message data. + * + * Nanopb generates simple struct definitions for all the messages. + * - check out the contents of simple.pb.h! + * It is a good idea to always initialize your structures + * so that you do not have garbage data from RAM in there. + */ + SimpleMessage message = SimpleMessage_init_zero; + + /* Create a stream that will write to our buffer. */ + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Fill in the lucky number */ + message.lucky_number = 13; + + /* Now we are ready to encode the message! */ + status = pb_encode(&stream, SimpleMessage_fields, &message); + message_length = stream.bytes_written; + + /* Then just check for any errors.. */ + if (!status) + { + printf("Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + } + + /* Now we could transmit the message over network, store it in a file or + * wrap it to a pigeon's leg. + */ + + /* But because we are lazy, we will just decode it immediately. */ + + { + /* Allocate space for the decoded message. */ + SimpleMessage message = SimpleMessage_init_zero; + + /* Create a stream that reads from the buffer. */ + pb_istream_t stream = pb_istream_from_buffer(buffer, message_length); + + /* Now we are ready to decode the message. */ + status = pb_decode(&stream, SimpleMessage_fields, &message); + + /* Check for errors... */ + if (!status) + { + printf("Decoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + + /* Print the data contained in the message. */ + printf("Your lucky number was %d!\n", message.lucky_number); + } + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.proto b/hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.proto new file mode 100644 index 00000000..5c73a3b2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/simple/simple.proto @@ -0,0 +1,9 @@ +// A very simple protocol definition, consisting of only +// one message. + +syntax = "proto2"; + +message SimpleMessage { + required int32 lucky_number = 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/Makefile b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/Makefile new file mode 100644 index 00000000..874a64bd --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/Makefile @@ -0,0 +1,24 @@ +# Include the nanopb provided Makefile rules +include ../../extra/nanopb.mk + +# Compiler flags to enable all warnings & debug info +CFLAGS = -Wall -Werror -g -O0 +CFLAGS += -I$(NANOPB_DIR) + +all: run_tests + +.SUFFIXES: + +clean: + rm -f test_conversions encode_double decode_double doubleproto.pb.c doubleproto.pb.h + +test_conversions: test_conversions.c double_conversion.c + $(CC) $(CFLAGS) -o $@ $^ + +%: %.c double_conversion.c doubleproto.pb.c + $(CC) $(CFLAGS) -o $@ $^ $(NANOPB_CORE) + +run_tests: test_conversions encode_double decode_double + ./test_conversions + ./encode_double | ./decode_double + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/README.txt b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/README.txt new file mode 100644 index 00000000..d9fcdfc6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/README.txt @@ -0,0 +1,25 @@ +Nanopb example "using_double_on_avr" +==================================== + +Some processors/compilers, such as AVR-GCC, do not support the double +datatype. Instead, they have sizeof(double) == 4. Because protocol +binary format uses the double encoding directly, this causes trouble +if the protocol in .proto requires double fields. + +This directory contains a solution to this problem. It uses uint64_t +to store the raw wire values, because its size is correct on all +platforms. The file double_conversion.c provides functions that +convert these values to/from floats, without relying on compiler +support. + +To use this method, you need to make some modifications to your code: + +1) Change all 'double' fields into 'fixed64' in the .proto. + +2) Whenever writing to a 'double' field, use float_to_double(). + +3) Whenever reading a 'double' field, use double_to_float(). + +The conversion routines are as accurate as the float datatype can +be. Furthermore, they should handle all special values (NaN, inf, denormalized +numbers) correctly. There are testcases in test_conversions.c. diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/decode_double.c b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/decode_double.c new file mode 100644 index 00000000..5802eca7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/decode_double.c @@ -0,0 +1,33 @@ +/* Decodes a double value into a float variable. + * Used to read double values with AVR code, which doesn't support double directly. + */ + +#include +#include +#include "double_conversion.h" +#include "doubleproto.pb.h" + +int main() +{ + uint8_t buffer[32]; + size_t count = fread(buffer, 1, sizeof(buffer), stdin); + pb_istream_t stream = pb_istream_from_buffer(buffer, count); + + AVRDoubleMessage message; + pb_decode(&stream, AVRDoubleMessage_fields, &message); + + float v1 = double_to_float(message.field1); + float v2 = double_to_float(message.field2); + + printf("Values: %f %f\n", v1, v2); + + if (v1 == 1234.5678f && + v2 == 0.00001f) + { + return 0; + } + else + { + return 1; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.c b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.c new file mode 100644 index 00000000..cf79b9a0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.c @@ -0,0 +1,123 @@ +/* Conversion routines for platforms that do not support 'double' directly. */ + +#include "double_conversion.h" +#include + +typedef union { + float f; + uint32_t i; +} conversion_t; + +/* Note: IEE 754 standard specifies float formats as follows: + * Single precision: sign, 8-bit exp, 23-bit frac. + * Double precision: sign, 11-bit exp, 52-bit frac. + */ + +uint64_t float_to_double(float value) +{ + conversion_t in; + in.f = value; + uint8_t sign; + int16_t exponent; + uint64_t mantissa; + + /* Decompose input value */ + sign = (in.i >> 31) & 1; + exponent = ((in.i >> 23) & 0xFF) - 127; + mantissa = in.i & 0x7FFFFF; + + if (exponent == 128) + { + /* Special value (NaN etc.) */ + exponent = 1024; + } + else if (exponent == -127) + { + if (!mantissa) + { + /* Zero */ + exponent = -1023; + } + else + { + /* Denormalized */ + mantissa <<= 1; + while (!(mantissa & 0x800000)) + { + mantissa <<= 1; + exponent--; + } + mantissa &= 0x7FFFFF; + } + } + + /* Combine fields */ + mantissa <<= 29; + mantissa |= (uint64_t)(exponent + 1023) << 52; + mantissa |= (uint64_t)sign << 63; + + return mantissa; +} + +float double_to_float(uint64_t value) +{ + uint8_t sign; + int16_t exponent; + uint32_t mantissa; + conversion_t out; + + /* Decompose input value */ + sign = (value >> 63) & 1; + exponent = ((value >> 52) & 0x7FF) - 1023; + mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */ + + /* Figure if value is in range representable by floats. */ + if (exponent == 1024) + { + /* Special value */ + exponent = 128; + } + else if (exponent > 127) + { + /* Too large */ + if (sign) + return -INFINITY; + else + return INFINITY; + } + else if (exponent < -150) + { + /* Too small */ + if (sign) + return -0.0f; + else + return 0.0f; + } + else if (exponent < -126) + { + /* Denormalized */ + mantissa |= 0x1000000; + mantissa >>= (-126 - exponent); + exponent = -127; + } + + /* Round off mantissa */ + mantissa = (mantissa + 1) >> 1; + + /* Check if mantissa went over 2.0 */ + if (mantissa & 0x800000) + { + exponent += 1; + mantissa &= 0x7FFFFF; + mantissa >>= 1; + } + + /* Combine fields */ + out.i = mantissa; + out.i |= (uint32_t)(exponent + 127) << 23; + out.i |= (uint32_t)sign << 31; + + return out.f; +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.h b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.h new file mode 100644 index 00000000..62b6a8ae --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/double_conversion.h @@ -0,0 +1,26 @@ +/* AVR-GCC does not have real double datatype. Instead its double + * is equal to float, i.e. 32 bit value. If you need to communicate + * with other systems that use double in their .proto files, you + * need to do some conversion. + * + * These functions use bitwise operations to mangle floats into doubles + * and then store them in uint64_t datatype. + */ + +#ifndef DOUBLE_CONVERSION +#define DOUBLE_CONVERSION + +#include + +/* Convert native 4-byte float into a 8-byte double. */ +extern uint64_t float_to_double(float value); + +/* Convert 8-byte double into native 4-byte float. + * Values are rounded to nearest, 0.5 away from zero. + * Overflowing values are converted to Inf or -Inf. + */ +extern float double_to_float(uint64_t value); + + +#endif + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/doubleproto.proto b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/doubleproto.proto new file mode 100644 index 00000000..72d3f9c1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/doubleproto.proto @@ -0,0 +1,15 @@ +// A message containing doubles, as used by other applications. +syntax = "proto2"; + +message DoubleMessage { + required double field1 = 1; + required double field2 = 2; +} + +// A message containing doubles, but redefined using uint64_t. +// For use in AVR code. +message AVRDoubleMessage { + required fixed64 field1 = 1; + required fixed64 field2 = 2; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/encode_double.c b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/encode_double.c new file mode 100644 index 00000000..cd532d46 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/encode_double.c @@ -0,0 +1,25 @@ +/* Encodes a float value into a double on the wire. + * Used to emit doubles from AVR code, which doesn't support double directly. + */ + +#include +#include +#include "double_conversion.h" +#include "doubleproto.pb.h" + +int main() +{ + AVRDoubleMessage message = { + float_to_double(1234.5678f), + float_to_double(0.00001f) + }; + + uint8_t buffer[32]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + pb_encode(&stream, AVRDoubleMessage_fields, &message); + fwrite(buffer, 1, stream.bytes_written, stdout); + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/test_conversions.c b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/test_conversions.c new file mode 100644 index 00000000..22620a6a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_double_on_avr/test_conversions.c @@ -0,0 +1,56 @@ +#include "double_conversion.h" +#include +#include + +static const double testvalues[] = { + 0.0, -0.0, 0.1, -0.1, + M_PI, -M_PI, 123456.789, -123456.789, + INFINITY, -INFINITY, NAN, INFINITY - INFINITY, + 1e38, -1e38, 1e39, -1e39, + 1e-38, -1e-38, 1e-39, -1e-39, + 3.14159e-37,-3.14159e-37, 3.14159e-43, -3.14159e-43, + 1e-60, -1e-60, 1e-45, -1e-45, + 0.99999999999999, -0.99999999999999, 127.999999999999, -127.999999999999 +}; + +#define TESTVALUES_COUNT (sizeof(testvalues)/sizeof(testvalues[0])) + +int main() +{ + int status = 0; + int i; + for (i = 0; i < TESTVALUES_COUNT; i++) + { + double orig = testvalues[i]; + float expected_float = (float)orig; + double expected_double = (double)expected_float; + + float got_float = double_to_float(*(uint64_t*)&orig); + uint64_t got_double = float_to_double(got_float); + + uint32_t e1 = *(uint32_t*)&expected_float; + uint32_t g1 = *(uint32_t*)&got_float; + uint64_t e2 = *(uint64_t*)&expected_double; + uint64_t g2 = got_double; + + if (g1 != e1) + { + printf("%3d double_to_float fail: %08x != %08x\n", i, g1, e1); + status = 1; + } + + if (g2 != e2) + { + printf("%3d float_to_double fail: %016llx != %016llx\n", i, + (unsigned long long)g2, + (unsigned long long)e2); + status = 1; + } + } + + return status; +} + + + + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/Makefile b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/Makefile new file mode 100644 index 00000000..66396a02 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/Makefile @@ -0,0 +1,20 @@ +# Include the nanopb provided Makefile rules +include ../../extra/nanopb.mk + +# Compiler flags to enable all warnings & debug info +CFLAGS = -ansi -Wall -Werror -g -O0 +CFLAGS += -I$(NANOPB_DIR) + +all: encode decode + ./encode 1 | ./decode + ./encode 2 | ./decode + ./encode 3 | ./decode + +.SUFFIXES: + +clean: + rm -f encode unionproto.pb.h unionproto.pb.c + +%: %.c unionproto.pb.c + $(CC) $(CFLAGS) -o $@ $^ $(NANOPB_CORE) + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/README.txt b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/README.txt new file mode 100644 index 00000000..d4b7fd2a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/README.txt @@ -0,0 +1,55 @@ +Nanopb example "using_union_messages" +===================================== + +Union messages is a common technique in Google Protocol Buffers used to +represent a group of messages, only one of which is passed at a time. +It is described in Google's documentation: +https://developers.google.com/protocol-buffers/docs/techniques#union + +This directory contains an example on how to encode and decode union messages +with minimal memory usage. Usually, nanopb would allocate space to store +all of the possible messages at the same time, even though at most one of +them will be used at a time. + +By using some of the lower level nanopb APIs, we can manually generate the +top level message, so that we only need to allocate the one submessage that +we actually want. Similarly when decoding, we can manually read the tag of +the top level message, and only then allocate the memory for the submessage +after we already know its type. + +NOTE: There is a newer protobuf feature called `oneof` that is also supported +by nanopb. It might be a better option for new code. + + +Example usage +------------- + +Type `make` to run the example. It will build it and run commands like +following: + +./encode 1 | ./decode +Got MsgType1: 42 +./encode 2 | ./decode +Got MsgType2: true +./encode 3 | ./decode +Got MsgType3: 3 1415 + +This simply demonstrates that the "decode" program has correctly identified +the type of the received message, and managed to decode it. + + +Details of implementation +------------------------- + +unionproto.proto contains the protocol used in the example. It consists of +three messages: MsgType1, MsgType2 and MsgType3, which are collected together +into UnionMessage. + +encode.c takes one command line argument, which should be a number 1-3. It +then fills in and encodes the corresponding message, and writes it to stdout. + +decode.c reads a UnionMessage from stdin. Then it calls the function +decode_unionmessage_type() to determine the type of the message. After that, +the corresponding message is decoded and the contents of it printed to the +screen. + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/decode.c b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/decode.c new file mode 100644 index 00000000..b9f4af55 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/decode.c @@ -0,0 +1,96 @@ +/* This program reads a message from stdin, detects its type and decodes it. + */ + +#include +#include +#include + +#include +#include "unionproto.pb.h" + +/* This function reads manually the first tag from the stream and finds the + * corresponding message type. It doesn't yet decode the actual message. + * + * Returns a pointer to the MsgType_fields array, as an identifier for the + * message type. Returns null if the tag is of unknown type or an error occurs. + */ +const pb_field_t* decode_unionmessage_type(pb_istream_t *stream) +{ + pb_wire_type_t wire_type; + uint32_t tag; + bool eof; + + while (pb_decode_tag(stream, &wire_type, &tag, &eof)) + { + if (wire_type == PB_WT_STRING) + { + const pb_field_t *field; + for (field = UnionMessage_fields; field->tag != 0; field++) + { + if (field->tag == tag && (field->type & PB_LTYPE_SUBMESSAGE)) + { + /* Found our field. */ + return field->ptr; + } + } + } + + /* Wasn't our field.. */ + pb_skip_field(stream, wire_type); + } + + return NULL; +} + +bool decode_unionmessage_contents(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + pb_istream_t substream; + bool status; + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode(&substream, fields, dest_struct); + pb_close_string_substream(stream, &substream); + return status; +} + +int main() +{ + /* Read the data into buffer */ + uint8_t buffer[512]; + size_t count = fread(buffer, 1, sizeof(buffer), stdin); + pb_istream_t stream = pb_istream_from_buffer(buffer, count); + + const pb_field_t *type = decode_unionmessage_type(&stream); + bool status = false; + + if (type == MsgType1_fields) + { + MsgType1 msg = {}; + status = decode_unionmessage_contents(&stream, MsgType1_fields, &msg); + printf("Got MsgType1: %d\n", msg.value); + } + else if (type == MsgType2_fields) + { + MsgType2 msg = {}; + status = decode_unionmessage_contents(&stream, MsgType2_fields, &msg); + printf("Got MsgType2: %s\n", msg.value ? "true" : "false"); + } + else if (type == MsgType3_fields) + { + MsgType3 msg = {}; + status = decode_unionmessage_contents(&stream, MsgType3_fields, &msg); + printf("Got MsgType3: %d %d\n", msg.value1, msg.value2); + } + + if (!status) + { + printf("Decode failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + + return 0; +} + + + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/encode.c b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/encode.c new file mode 100644 index 00000000..e124bf91 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/encode.c @@ -0,0 +1,85 @@ +/* This program takes a command line argument and encodes a message in + * one of MsgType1, MsgType2 or MsgType3. + */ + +#include +#include +#include + +#include +#include "unionproto.pb.h" + +/* This function is the core of the union encoding process. It handles + * the top-level pb_field_t array manually, in order to encode a correct + * field tag before the message. The pointer to MsgType_fields array is + * used as an unique identifier for the message type. + */ +bool encode_unionmessage(pb_ostream_t *stream, const pb_field_t messagetype[], const void *message) +{ + const pb_field_t *field; + for (field = UnionMessage_fields; field->tag != 0; field++) + { + if (field->ptr == messagetype) + { + /* This is our field, encode the message using it. */ + if (!pb_encode_tag_for_field(stream, field)) + return false; + + return pb_encode_submessage(stream, messagetype, message); + } + } + + /* Didn't find the field for messagetype */ + return false; +} + +int main(int argc, char **argv) +{ + if (argc != 2) + { + fprintf(stderr, "Usage: %s (1|2|3)\n", argv[0]); + return 1; + } + + uint8_t buffer[512]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + bool status = false; + int msgtype = atoi(argv[1]); + if (msgtype == 1) + { + /* Send message of type 1 */ + MsgType1 msg = {42}; + status = encode_unionmessage(&stream, MsgType1_fields, &msg); + } + else if (msgtype == 2) + { + /* Send message of type 2 */ + MsgType2 msg = {true}; + status = encode_unionmessage(&stream, MsgType2_fields, &msg); + } + else if (msgtype == 3) + { + /* Send message of type 3 */ + MsgType3 msg = {3, 1415}; + status = encode_unionmessage(&stream, MsgType3_fields, &msg); + } + else + { + fprintf(stderr, "Unknown message type: %d\n", msgtype); + return 2; + } + + if (!status) + { + fprintf(stderr, "Encoding failed!\n"); + return 3; + } + else + { + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/unionproto.proto b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/unionproto.proto new file mode 100644 index 00000000..209df0d2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/examples/using_union_messages/unionproto.proto @@ -0,0 +1,32 @@ +// This is an example of how to handle 'union' style messages +// with nanopb, without allocating memory for all the message types. +// +// There is no official type in Protocol Buffers for describing unions, +// but they are commonly implemented by filling out exactly one of +// several optional fields. + +syntax = "proto2"; + +message MsgType1 +{ + required int32 value = 1; +} + +message MsgType2 +{ + required bool value = 1; +} + +message MsgType3 +{ + required int32 value1 = 1; + required int32 value2 = 2; +} + +message UnionMessage +{ + optional MsgType1 msg1 = 1; + optional MsgType2 msg2 = 2; + optional MsgType3 msg3 = 3; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/extra/FindNanopb.cmake b/hardware-wallet/firmware/vendor/nanopb/extra/FindNanopb.cmake new file mode 100644 index 00000000..dda63f63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/extra/FindNanopb.cmake @@ -0,0 +1,313 @@ +# This is an example script for use with CMake projects for locating and configuring +# the nanopb library. +# +# The following variables can be set and are optional: +# +# +# PROTOBUF_SRC_ROOT_FOLDER - When compiling with MSVC, if this cache variable is set +# the protobuf-default VS project build locations +# (vsprojects/Debug & vsprojects/Release) will be searched +# for libraries and binaries. +# +# NANOPB_IMPORT_DIRS - List of additional directories to be searched for +# imported .proto files. +# +# NANOPB_GENERATE_CPP_APPEND_PATH - By default -I will be passed to protoc +# for each directory where a proto file is referenced. +# Set to FALSE if you want to disable this behaviour. +# +# Defines the following variables: +# +# NANOPB_FOUND - Found the nanopb library (source&header files, generator tool, protoc compiler tool) +# NANOPB_INCLUDE_DIRS - Include directories for Google Protocol Buffers +# +# The following cache variables are also available to set or use: +# PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler +# NANOPB_GENERATOR_SOURCE_DIR - The nanopb generator source +# +# ==================================================================== +# +# NANOPB_GENERATE_CPP (public function) +# NANOPB_GENERTAE_CPP(SRCS HDRS [RELPATH ] +# ...) +# SRCS = Variable to define with autogenerated source files +# HDRS = Variable to define with autogenerated header files +# If you want to use relative paths in your import statements use the RELPATH +# option. The argument to RELPATH should be the directory that all the +# imports will be relative to. +# When RELPATH is not specified then all proto files can be imported without +# a path. +# +# +# ==================================================================== +# Example: +# +# set(NANOPB_SRC_ROOT_FOLDER "/path/to/nanopb") +# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_SRC_ROOT_FOLDER}/extra) +# find_package( Nanopb REQUIRED ) +# include_directories(${NANOPB_INCLUDE_DIRS}) +# +# NANOPB_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto) +# +# include_directories(${CMAKE_CURRENT_BINARY_DIR}) +# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS}) +# +# Example with RELPATH: +# Assume we have a layout like: +# .../CMakeLists.txt +# .../bar.cc +# .../proto/ +# .../proto/foo.proto (Which contains: import "sub/bar.proto"; ) +# .../proto/sub/bar.proto +# Everything would be the same as the previous example, but the call to +# NANOPB_GENERATE_CPP would change to: +# +# NANOPB_GENERATE_CPP(PROTO_SRCS PROTO_HDRS RELPATH proto +# proto/foo.proto proto/sub/bar.proto) +# +# ==================================================================== + +#============================================================================= +# Copyright 2009 Kitware, Inc. +# Copyright 2009-2011 Philip Lowman +# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS +# +# 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 names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their 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. +# +#============================================================================= +# +# Changes +# 2013.01.31 - Pavlo Ilin - used Modules/FindProtobuf.cmake from cmake 2.8.10 to +# write FindNanopb.cmake +# +#============================================================================= + + +function(NANOPB_GENERATE_CPP SRCS HDRS) + cmake_parse_arguments(NANOPB_GENERATE_CPP "" "RELPATH" "" ${ARGN}) + if(NOT NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS) + return() + endif() + + if(NANOPB_GENERATE_CPP_APPEND_PATH) + # Create an include path for each file specified + foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(ABS_PATH ${ABS_FIL} PATH) + list(APPEND _nanobp_include_path "-I${ABS_PATH}") + endforeach() + else() + set(_nanobp_include_path "-I${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + if(NANOPB_GENERATE_CPP_RELPATH) + list(APPEND _nanobp_include_path "-I${NANOPB_GENERATE_CPP_RELPATH}") + endif() + + if(DEFINED NANOPB_IMPORT_DIRS) + foreach(DIR ${NANOPB_IMPORT_DIRS}) + get_filename_component(ABS_PATH ${DIR} ABSOLUTE) + list(APPEND _nanobp_include_path -I ${ABS_PATH}) + endforeach() + endif() + + list(REMOVE_DUPLICATES _nanobp_include_path) + + set(${SRCS}) + set(${HDRS}) + + set(GENERATOR_PATH ${CMAKE_BINARY_DIR}/nanopb/generator) + + set(NANOPB_GENERATOR_EXECUTABLE ${GENERATOR_PATH}/nanopb_generator.py) + + set(GENERATOR_CORE_DIR ${GENERATOR_PATH}/proto) + set(GENERATOR_CORE_SRC + ${GENERATOR_CORE_DIR}/nanopb.proto + ${GENERATOR_CORE_DIR}/plugin.proto) + + # Treat the source diretory as immutable. + # + # Copy the generator directory to the build directory before + # compiling python and proto files. Fixes issues when using the + # same build directory with different python/protobuf versions + # as the binary build directory is discarded across builds. + # + add_custom_command( + OUTPUT ${NANOPB_GENERATOR_EXECUTABLE} ${GENERATOR_CORE_SRC} + COMMAND ${CMAKE_COMMAND} -E copy_directory + ARGS ${NANOPB_GENERATOR_SOURCE_DIR} ${GENERATOR_PATH} + VERBATIM) + + set(GENERATOR_CORE_PYTHON_SRC) + foreach(FIL ${GENERATOR_CORE_SRC}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(FIL_WE ${FIL} NAME_WE) + + set(output "${GENERATOR_CORE_DIR}/${FIL_WE}_pb2.py") + set(GENERATOR_CORE_PYTHON_SRC ${GENERATOR_CORE_PYTHON_SRC} ${output}) + add_custom_command( + OUTPUT ${output} + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} + ARGS -I${GENERATOR_PATH}/proto + --python_out=${GENERATOR_CORE_DIR} ${ABS_FIL} + DEPENDS ${ABS_FIL} + VERBATIM) + endforeach() + + if(NANOPB_GENERATE_CPP_RELPATH) + get_filename_component(ABS_ROOT ${NANOPB_GENERATE_CPP_RELPATH} ABSOLUTE) + endif() + foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(FIL_WE ${FIL} NAME_WE) + get_filename_component(FIL_DIR ${FIL} PATH) + set(FIL_PATH_REL) + if(ABS_ROOT) + # Check that the file is under the given "RELPATH" + string(FIND ${ABS_FIL} ${ABS_ROOT} LOC) + if (${LOC} EQUAL 0) + string(REPLACE "${ABS_ROOT}/" "" FIL_REL ${ABS_FIL}) + get_filename_component(FIL_PATH_REL ${FIL_REL} PATH) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}) + endif() + endif() + if(NOT FIL_PATH_REL) + set(FIL_PATH_REL ".") + endif() + + set(NANOPB_OPTIONS_FILE ${FIL_DIR}/${FIL_WE}.options) + set(NANOPB_OPTIONS) + if(EXISTS ${NANOPB_OPTIONS_FILE}) + set(NANOPB_OPTIONS -f ${NANOPB_OPTIONS_FILE}) + else() + set(NANOPB_OPTIONS_FILE) + endif() + + set(GEN_C_FILE ) + + list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c") + list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h") + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb" + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} + ARGS -I${GENERATOR_PATH} -I${GENERATOR_CORE_DIR} + -I${CMAKE_CURRENT_BINARY_DIR} ${_nanobp_include_path} + -o${FIL_PATH_REL}/${FIL_WE}.pb ${ABS_FIL} + DEPENDS ${ABS_FIL} ${GENERATOR_CORE_PYTHON_SRC} + COMMENT "Running C++ protocol buffer compiler on ${FIL}" + VERBATIM ) + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c" + "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h" + COMMAND ${PYTHON_EXECUTABLE} + ARGS ${NANOPB_GENERATOR_EXECUTABLE} ${FIL_PATH_REL}/${FIL_WE}.pb ${NANOPB_OPTIONS} + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb" ${NANOPB_OPTIONS_FILE} + COMMENT "Running nanopb generator on ${FIL_PATH_REL}/${FIL_WE}.pb" + VERBATIM ) + endforeach() + + set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) + set(${SRCS} ${${SRCS}} ${NANOPB_SRCS} PARENT_SCOPE) + set(${HDRS} ${${HDRS}} ${NANOPB_HDRS} PARENT_SCOPE) + +endfunction() + + + +# +# Main. +# + +# By default have NANOPB_GENERATE_CPP macro pass -I to protoc +# for each directory where a proto file is referenced. +if(NOT DEFINED NANOPB_GENERATE_CPP_APPEND_PATH) + set(NANOPB_GENERATE_CPP_APPEND_PATH TRUE) +endif() + +# Make a really good guess regarding location of NANOPB_SRC_ROOT_FOLDER +if(NOT DEFINED NANOPB_SRC_ROOT_FOLDER) + get_filename_component(NANOPB_SRC_ROOT_FOLDER + ${CMAKE_CURRENT_LIST_DIR}/.. ABSOLUTE) +endif() + +# Find the include directory +find_path(NANOPB_INCLUDE_DIRS + pb.h + PATHS ${NANOPB_SRC_ROOT_FOLDER} +) +mark_as_advanced(NANOPB_INCLUDE_DIRS) + +# Find nanopb source files +set(NANOPB_SRCS) +set(NANOPB_HDRS) +list(APPEND _nanopb_srcs pb_decode.c pb_encode.c pb_common.c) +list(APPEND _nanopb_hdrs pb_decode.h pb_encode.h pb_common.h pb.h) + +foreach(FIL ${_nanopb_srcs}) + find_file(${FIL}__nano_pb_file NAMES ${FIL} PATHS ${NANOPB_SRC_ROOT_FOLDER} ${NANOPB_INCLUDE_DIRS}) + list(APPEND NANOPB_SRCS "${${FIL}__nano_pb_file}") + mark_as_advanced(${FIL}__nano_pb_file) +endforeach() + +foreach(FIL ${_nanopb_hdrs}) + find_file(${FIL}__nano_pb_file NAMES ${FIL} PATHS ${NANOPB_INCLUDE_DIRS}) + mark_as_advanced(${FIL}__nano_pb_file) + list(APPEND NANOPB_HDRS "${${FIL}__nano_pb_file}") +endforeach() + +# Find the protoc Executable +find_program(PROTOBUF_PROTOC_EXECUTABLE + NAMES protoc + DOC "The Google Protocol Buffers Compiler" + PATHS + ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release + ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug +) +mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE) + +# Find nanopb generator source dir +find_path(NANOPB_GENERATOR_SOURCE_DIR + NAMES nanopb_generator.py + DOC "nanopb generator source" + PATHS + ${NANOPB_SRC_ROOT_FOLDER}/generator +) +mark_as_advanced(NANOPB_GENERATOR_SOURCE_DIR) + +find_package(PythonInterp REQUIRED) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(NANOPB DEFAULT_MSG + NANOPB_INCLUDE_DIRS + NANOPB_SRCS NANOPB_HDRS + NANOPB_GENERATOR_SOURCE_DIR + PROTOBUF_PROTOC_EXECUTABLE + ) diff --git a/hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config-version.cmake.in b/hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config-version.cmake.in new file mode 100644 index 00000000..f9292a83 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config-version.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@nanopb_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config.cmake b/hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config.cmake new file mode 100644 index 00000000..4f726a68 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/extra/nanopb-config.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/nanopb-targets.cmake) diff --git a/hardware-wallet/firmware/vendor/nanopb/extra/nanopb.mk b/hardware-wallet/firmware/vendor/nanopb/extra/nanopb.mk new file mode 100644 index 00000000..5c2cff56 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/extra/nanopb.mk @@ -0,0 +1,37 @@ +# This is an include file for Makefiles. It provides rules for building +# .pb.c and .pb.h files out of .proto, as well the path to nanopb core. + +# Path to the nanopb root directory +NANOPB_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))../) + +# Files for the nanopb core +NANOPB_CORE = $(NANOPB_DIR)/pb_encode.c $(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_common.c + +# Check if we are running on Windows +ifdef windir +WINDOWS = 1 +endif +ifdef WINDIR +WINDOWS = 1 +endif + +# Check whether to use binary version of nanopb_generator or the +# system-supplied python interpreter. +ifneq "$(wildcard $(NANOPB_DIR)/generator-bin)" "" + # Binary package + PROTOC = $(NANOPB_DIR)/generator-bin/protoc + PROTOC_OPTS = +else + # Source only or git checkout + PROTOC = protoc + ifdef WINDOWS + PROTOC_OPTS = --plugin=protoc-gen-nanopb=$(NANOPB_DIR)/generator/protoc-gen-nanopb.bat + else + PROTOC_OPTS = --plugin=protoc-gen-nanopb=$(NANOPB_DIR)/generator/protoc-gen-nanopb + endif +endif + +# Rule for building .pb.c and .pb.h +%.pb.c %.pb.h: %.proto $(wildcard %.options) + $(PROTOC) $(PROTOC_OPTS) --nanopb_out=. $< + diff --git a/hardware-wallet/firmware/vendor/nanopb/extra/pb_syshdr.h b/hardware-wallet/firmware/vendor/nanopb/extra/pb_syshdr.h new file mode 100644 index 00000000..55d06a3a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/extra/pb_syshdr.h @@ -0,0 +1,112 @@ +/* This is an example of a header file for platforms/compilers that do + * not come with stdint.h/stddef.h/stdbool.h/string.h. To use it, define + * PB_SYSTEM_HEADER as "pb_syshdr.h", including the quotes, and add the + * extra folder to your include path. + * + * It is very likely that you will need to customize this file to suit + * your platform. For any compiler that supports C99, this file should + * not be necessary. + */ + +#ifndef _PB_SYSHDR_H_ +#define _PB_SYSHDR_H_ + +/* stdint.h subset */ +#ifdef HAVE_STDINT_H +#include +#else +/* You will need to modify these to match the word size of your platform. */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; + +/* These are ok for most platforms, unless uint8_t is actually not available, + * in which case you should give the smallest available type. */ +typedef int8_t int_least8_t; +typedef uint8_t uint_least8_t; +typedef uint8_t uint_fast8_t; +typedef int16_t int_least16_t; +typedef uint16_t uint_least16_t; +#endif + +/* stddef.h subset */ +#ifdef HAVE_STDDEF_H +#include +#else + +typedef uint32_t size_t; +#define offsetof(st, m) ((size_t)(&((st *)0)->m)) + +#ifndef NULL +#define NULL 0 +#endif + +#endif + +/* stdbool.h subset */ +#ifdef HAVE_STDBOOL_H +#include +#else + +#ifndef __cplusplus +typedef int bool; +#define false 0 +#define true 1 +#endif + +#endif + +/* stdlib.h subset */ +#ifdef PB_ENABLE_MALLOC +#ifdef HAVE_STDLIB_H +#include +#else +void *realloc(void *ptr, size_t size); +void free(void *ptr); +#endif +#endif + +/* string.h subset */ +#ifdef HAVE_STRING_H +#include +#else + +/* Implementations are from the Public Domain C Library (PDCLib). */ +static size_t strlen( const char * s ) +{ + size_t rc = 0; + while ( s[rc] ) + { + ++rc; + } + return rc; +} + +static void * memcpy( void *s1, const void *s2, size_t n ) +{ + char * dest = (char *) s1; + const char * src = (const char *) s2; + while ( n-- ) + { + *dest++ = *src++; + } + return s1; +} + +static void * memset( void * s, int c, size_t n ) +{ + unsigned char * p = (unsigned char *) s; + while ( n-- ) + { + *p++ = (unsigned char) c; + } + return s; +} +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/nanopb/options.proto b/hardware-wallet/firmware/vendor/nanopb/generator/nanopb/options.proto new file mode 100644 index 00000000..f08e53d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/nanopb/options.proto @@ -0,0 +1,120 @@ +// This is a transitional file, to provide parallel support between the old +// nanopb.proto and new options.proto files. Eventually nanopb.proto will +// be left only for legacy code, but for now the generator is still also +// using it. However, your new code can start using this file already now. +// See pull request #241 for details: +// https://github.com/nanopb/nanopb/pull/241 + +// Custom options for defining: +// - Maximum size of string/bytes +// - Maximum number of elements in array +// +// These are used by nanopb to generate statically allocable structures +// for memory-limited environments. + +syntax = "proto2"; +import "google/protobuf/descriptor.proto"; + +package nanopb; +option java_package = "fi.kapsi.koti.jpa.nanopb"; + +enum FieldType { + FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible. + FT_CALLBACK = 1; // Always generate a callback field. + FT_POINTER = 4; // Always generate a dynamically allocated field. + FT_STATIC = 2; // Generate a static field or raise an exception if not possible. + FT_IGNORE = 3; // Ignore the field completely. + FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead +} + +enum IntSize { + IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto + IS_8 = 8; + IS_16 = 16; + IS_32 = 32; + IS_64 = 64; +} + +// This is the inner options message, which basically defines options for +// a field. When it is used in message or file scope, it applies to all +// fields. +message Options { + // Allocated size for 'bytes' and 'string' fields. + // For string fields, this should include the space for null terminator. + optional int32 max_size = 1; + + // Maximum length for 'string' fields. Setting this is equivalent + // to setting max_size to a value of length+1. + optional int32 max_length = 14; + + // Allocated number of entries in arrays ('repeated' fields) + optional int32 max_count = 2; + + // Size of integer fields. Can save some memory if you don't need + // full 32 bits for the value. + optional IntSize int_size = 7 [default = IS_DEFAULT]; + + // Force type of field (callback or static allocation) + optional FieldType type = 3 [default = FT_DEFAULT]; + + // Use long names for enums, i.e. EnumName_EnumValue. + optional bool long_names = 4 [default = true]; + + // Add 'packed' attribute to generated structs. + // Note: this cannot be used on CPUs that break on unaligned + // accesses to variables. + optional bool packed_struct = 5 [default = false]; + + // Add 'packed' attribute to generated enums. + optional bool packed_enum = 10 [default = false]; + + // Skip this message + optional bool skip_message = 6 [default = false]; + + // Generate oneof fields as normal optional fields instead of union. + optional bool no_unions = 8 [default = false]; + + // integer type tag for a message + optional uint32 msgid = 9; + + // decode oneof as anonymous union + optional bool anonymous_oneof = 11 [default = false]; + + // Proto3 singular field does not generate a "has_" flag + optional bool proto3 = 12 [default = false]; + + // Generate an enum->string mapping function (can take up lots of space). + optional bool enum_to_string = 13 [default = false]; + + // Generate bytes arrays with fixed length + optional bool fixed_length = 15 [default = false]; +} + +// Extensions to protoc 'Descriptor' type in order to define options +// inside a .proto file. +// +// Protocol Buffers extension number registry +// -------------------------------- +// Project: Nanopb +// Contact: Petteri Aimonen +// Web site: http://kapsi.fi/~jpa/nanopb +// Extensions: 1010 (all types) +// -------------------------------- + +extend google.protobuf.FileOptions { + optional Options fileopt = 1010; +} + +extend google.protobuf.MessageOptions { + optional Options msgopt = 1010; +} + +extend google.protobuf.EnumOptions { + optional Options enumopt = 1010; +} + +extend google.protobuf.FieldOptions { + optional Options fieldopt = 1010; +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/nanopb_generator.py b/hardware-wallet/firmware/vendor/nanopb/generator/nanopb_generator.py new file mode 100755 index 00000000..057df40d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/nanopb_generator.py @@ -0,0 +1,1680 @@ +#!/usr/bin/env python + +from __future__ import unicode_literals + +'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.''' +nanopb_version = "nanopb-0.3.9" + +import sys +import re +from functools import reduce + +try: + # Add some dummy imports to keep packaging tools happy. + import google, distutils.util # bbfreeze seems to need these + import pkg_resources # pyinstaller / protobuf 2.5 seem to need these +except: + # Don't care, we will error out later if it is actually important. + pass + +try: + import google.protobuf.text_format as text_format + import google.protobuf.descriptor_pb2 as descriptor +except: + sys.stderr.write(''' + ************************************************************* + *** Could not import the Google protobuf Python libraries *** + *** Try installing package 'python-protobuf' or similar. *** + ************************************************************* + ''' + '\n') + raise + +try: + import proto.nanopb_pb2 as nanopb_pb2 + import proto.plugin_pb2 as plugin_pb2 +except TypeError: + sys.stderr.write(''' + **************************************************************************** + *** Got TypeError when importing the protocol definitions for generator. *** + *** This usually means that the protoc in your path doesn't match the *** + *** Python protobuf library version. *** + *** *** + *** Please check the output of the following commands: *** + *** which protoc *** + *** protoc --version *** + *** python -c 'import google.protobuf; print(google.protobuf.__file__)' *** + **************************************************************************** + ''' + '\n') + raise +except: + sys.stderr.write(''' + ******************************************************************** + *** Failed to import the protocol definitions for generator. *** + *** You have to run 'make' in the nanopb/generator/proto folder. *** + ******************************************************************** + ''' + '\n') + raise + +# --------------------------------------------------------------------------- +# Generation of single fields +# --------------------------------------------------------------------------- + +import time +import os.path + +# Values are tuple (c type, pb type, encoded size, int_size_allowed) +FieldD = descriptor.FieldDescriptorProto +datatypes = { + FieldD.TYPE_BOOL: ('bool', 'BOOL', 1, False), + FieldD.TYPE_DOUBLE: ('double', 'DOUBLE', 8, False), + FieldD.TYPE_FIXED32: ('uint32_t', 'FIXED32', 4, False), + FieldD.TYPE_FIXED64: ('uint64_t', 'FIXED64', 8, False), + FieldD.TYPE_FLOAT: ('float', 'FLOAT', 4, False), + FieldD.TYPE_INT32: ('int32_t', 'INT32', 10, True), + FieldD.TYPE_INT64: ('int64_t', 'INT64', 10, True), + FieldD.TYPE_SFIXED32: ('int32_t', 'SFIXED32', 4, False), + FieldD.TYPE_SFIXED64: ('int64_t', 'SFIXED64', 8, False), + FieldD.TYPE_SINT32: ('int32_t', 'SINT32', 5, True), + FieldD.TYPE_SINT64: ('int64_t', 'SINT64', 10, True), + FieldD.TYPE_UINT32: ('uint32_t', 'UINT32', 5, True), + FieldD.TYPE_UINT64: ('uint64_t', 'UINT64', 10, True) +} + +# Integer size overrides (from .proto settings) +intsizes = { + nanopb_pb2.IS_8: 'int8_t', + nanopb_pb2.IS_16: 'int16_t', + nanopb_pb2.IS_32: 'int32_t', + nanopb_pb2.IS_64: 'int64_t', +} + +# String types (for python 2 / python 3 compatibility) +try: + strtypes = (unicode, str) +except NameError: + strtypes = (str, ) + +class Names: + '''Keeps a set of nested names and formats them to C identifier.''' + def __init__(self, parts = ()): + if isinstance(parts, Names): + parts = parts.parts + self.parts = tuple(parts) + + def __str__(self): + return '_'.join(self.parts) + + def __add__(self, other): + if isinstance(other, strtypes): + return Names(self.parts + (other,)) + elif isinstance(other, tuple): + return Names(self.parts + other) + else: + raise ValueError("Name parts should be of type str") + + def __eq__(self, other): + return isinstance(other, Names) and self.parts == other.parts + +def names_from_type_name(type_name): + '''Parse Names() from FieldDescriptorProto type_name''' + if type_name[0] != '.': + raise NotImplementedError("Lookup of non-absolute type names is not supported") + return Names(type_name[1:].split('.')) + +def varint_max_size(max_value): + '''Returns the maximum number of bytes a varint can take when encoded.''' + if max_value < 0: + max_value = 2**64 - max_value + for i in range(1, 11): + if (max_value >> (i * 7)) == 0: + return i + raise ValueError("Value too large for varint: " + str(max_value)) + +assert varint_max_size(-1) == 10 +assert varint_max_size(0) == 1 +assert varint_max_size(127) == 1 +assert varint_max_size(128) == 2 + +class EncodedSize: + '''Class used to represent the encoded size of a field or a message. + Consists of a combination of symbolic sizes and integer sizes.''' + def __init__(self, value = 0, symbols = []): + if isinstance(value, EncodedSize): + self.value = value.value + self.symbols = value.symbols + elif isinstance(value, strtypes + (Names,)): + self.symbols = [str(value)] + self.value = 0 + else: + self.value = value + self.symbols = symbols + + def __add__(self, other): + if isinstance(other, int): + return EncodedSize(self.value + other, self.symbols) + elif isinstance(other, strtypes + (Names,)): + return EncodedSize(self.value, self.symbols + [str(other)]) + elif isinstance(other, EncodedSize): + return EncodedSize(self.value + other.value, self.symbols + other.symbols) + else: + raise ValueError("Cannot add size: " + repr(other)) + + def __mul__(self, other): + if isinstance(other, int): + return EncodedSize(self.value * other, [str(other) + '*' + s for s in self.symbols]) + else: + raise ValueError("Cannot multiply size: " + repr(other)) + + def __str__(self): + if not self.symbols: + return str(self.value) + else: + return '(' + str(self.value) + ' + ' + ' + '.join(self.symbols) + ')' + + def upperlimit(self): + if not self.symbols: + return self.value + else: + return 2**32 - 1 + +class Enum: + def __init__(self, names, desc, enum_options): + '''desc is EnumDescriptorProto''' + + self.options = enum_options + self.names = names + desc.name + + if enum_options.long_names: + self.values = [(self.names + x.name, x.number) for x in desc.value] + else: + self.values = [(names + x.name, x.number) for x in desc.value] + + self.value_longnames = [self.names + x.name for x in desc.value] + self.packed = enum_options.packed_enum + + def has_negative(self): + for n, v in self.values: + if v < 0: + return True + return False + + def encoded_size(self): + return max([varint_max_size(v) for n,v in self.values]) + + def __str__(self): + result = 'typedef enum _%s {\n' % self.names + result += ',\n'.join([" %s = %d" % x for x in self.values]) + result += '\n}' + + if self.packed: + result += ' pb_packed' + + result += ' %s;' % self.names + + result += '\n#define _%s_MIN %s' % (self.names, self.values[0][0]) + result += '\n#define _%s_MAX %s' % (self.names, self.values[-1][0]) + result += '\n#define _%s_ARRAYSIZE ((%s)(%s+1))' % (self.names, self.names, self.values[-1][0]) + + if not self.options.long_names: + # Define the long names always so that enum value references + # from other files work properly. + for i, x in enumerate(self.values): + result += '\n#define %s %s' % (self.value_longnames[i], x[0]) + + if self.options.enum_to_string: + result += '\nconst char *%s_name(%s v);\n' % (self.names, self.names) + + return result + + def enum_to_string_definition(self): + if not self.options.enum_to_string: + return "" + + result = 'const char *%s_name(%s v) {\n' % (self.names, self.names) + result += ' switch (v) {\n' + + for ((enumname, _), strname) in zip(self.values, self.value_longnames): + # Strip off the leading type name from the string value. + strval = str(strname)[len(str(self.names)) + 1:] + result += ' case %s: return "%s";\n' % (enumname, strval) + + result += ' }\n' + result += ' return "unknown";\n' + result += '}\n' + + return result + +class FieldMaxSize: + def __init__(self, worst = 0, checks = [], field_name = 'undefined'): + if isinstance(worst, list): + self.worst = max(i for i in worst if i is not None) + else: + self.worst = worst + + self.worst_field = field_name + self.checks = list(checks) + + def extend(self, extend, field_name = None): + self.worst = max(self.worst, extend.worst) + + if self.worst == extend.worst: + self.worst_field = extend.worst_field + + self.checks.extend(extend.checks) + +class Field: + def __init__(self, struct_name, desc, field_options): + '''desc is FieldDescriptorProto''' + self.tag = desc.number + self.struct_name = struct_name + self.union_name = None + self.name = desc.name + self.default = None + self.max_size = None + self.max_count = None + self.array_decl = "" + self.enc_size = None + self.ctype = None + + if field_options.type == nanopb_pb2.FT_INLINE: + # Before nanopb-0.3.8, fixed length bytes arrays were specified + # by setting type to FT_INLINE. But to handle pointer typed fields, + # it makes sense to have it as a separate option. + field_options.type = nanopb_pb2.FT_STATIC + field_options.fixed_length = True + + # Parse field options + if field_options.HasField("max_size"): + self.max_size = field_options.max_size + + if desc.type == FieldD.TYPE_STRING and field_options.HasField("max_length"): + # max_length overrides max_size for strings + self.max_size = field_options.max_length + 1 + + if field_options.HasField("max_count"): + self.max_count = field_options.max_count + + if desc.HasField('default_value'): + self.default = desc.default_value + + # Check field rules, i.e. required/optional/repeated. + can_be_static = True + if desc.label == FieldD.LABEL_REPEATED: + self.rules = 'REPEATED' + if self.max_count is None: + can_be_static = False + else: + self.array_decl = '[%d]' % self.max_count + elif field_options.proto3: + self.rules = 'SINGULAR' + elif desc.label == FieldD.LABEL_REQUIRED: + self.rules = 'REQUIRED' + elif desc.label == FieldD.LABEL_OPTIONAL: + self.rules = 'OPTIONAL' + else: + raise NotImplementedError(desc.label) + + # Check if the field can be implemented with static allocation + # i.e. whether the data size is known. + if desc.type == FieldD.TYPE_STRING and self.max_size is None: + can_be_static = False + + if desc.type == FieldD.TYPE_BYTES and self.max_size is None: + can_be_static = False + + # Decide how the field data will be allocated + if field_options.type == nanopb_pb2.FT_DEFAULT: + if can_be_static: + field_options.type = nanopb_pb2.FT_STATIC + else: + field_options.type = nanopb_pb2.FT_CALLBACK + + if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static: + raise Exception("Field '%s' is defined as static, but max_size or " + "max_count is not given." % self.name) + + if field_options.type == nanopb_pb2.FT_STATIC: + self.allocation = 'STATIC' + elif field_options.type == nanopb_pb2.FT_POINTER: + self.allocation = 'POINTER' + elif field_options.type == nanopb_pb2.FT_CALLBACK: + self.allocation = 'CALLBACK' + else: + raise NotImplementedError(field_options.type) + + # Decide the C data type to use in the struct. + if desc.type in datatypes: + self.ctype, self.pbtype, self.enc_size, isa = datatypes[desc.type] + + # Override the field size if user wants to use smaller integers + if isa and field_options.int_size != nanopb_pb2.IS_DEFAULT: + self.ctype = intsizes[field_options.int_size] + if desc.type == FieldD.TYPE_UINT32 or desc.type == FieldD.TYPE_UINT64: + self.ctype = 'u' + self.ctype; + elif desc.type == FieldD.TYPE_ENUM: + self.pbtype = 'ENUM' + self.ctype = names_from_type_name(desc.type_name) + if self.default is not None: + self.default = self.ctype + self.default + self.enc_size = None # Needs to be filled in when enum values are known + elif desc.type == FieldD.TYPE_STRING: + self.pbtype = 'STRING' + self.ctype = 'char' + if self.allocation == 'STATIC': + self.ctype = 'char' + self.array_decl += '[%d]' % self.max_size + self.enc_size = varint_max_size(self.max_size) + self.max_size + elif desc.type == FieldD.TYPE_BYTES: + if field_options.fixed_length: + self.pbtype = 'FIXED_LENGTH_BYTES' + + if self.max_size is None: + raise Exception("Field '%s' is defined as fixed length, " + "but max_size is not given." % self.name) + + self.enc_size = varint_max_size(self.max_size) + self.max_size + self.ctype = 'pb_byte_t' + self.array_decl += '[%d]' % self.max_size + else: + self.pbtype = 'BYTES' + self.ctype = 'pb_bytes_array_t' + if self.allocation == 'STATIC': + self.ctype = self.struct_name + self.name + 't' + self.enc_size = varint_max_size(self.max_size) + self.max_size + elif desc.type == FieldD.TYPE_MESSAGE: + self.pbtype = 'MESSAGE' + self.ctype = self.submsgname = names_from_type_name(desc.type_name) + self.enc_size = None # Needs to be filled in after the message type is available + else: + raise NotImplementedError(desc.type) + + def __lt__(self, other): + return self.tag < other.tag + + def __str__(self): + result = '' + if self.allocation == 'POINTER': + if self.rules == 'REPEATED': + result += ' pb_size_t ' + self.name + '_count;\n' + + if self.pbtype == 'MESSAGE': + # Use struct definition, so recursive submessages are possible + result += ' struct _%s *%s;' % (self.ctype, self.name) + elif self.pbtype == 'FIXED_LENGTH_BYTES': + # Pointer to fixed size array + result += ' %s (*%s)%s;' % (self.ctype, self.name, self.array_decl) + elif self.rules == 'REPEATED' and self.pbtype in ['STRING', 'BYTES']: + # String/bytes arrays need to be defined as pointers to pointers + result += ' %s **%s;' % (self.ctype, self.name) + else: + result += ' %s *%s;' % (self.ctype, self.name) + elif self.allocation == 'CALLBACK': + result += ' pb_callback_t %s;' % self.name + else: + if self.rules == 'OPTIONAL' and self.allocation == 'STATIC': + result += ' bool has_' + self.name + ';\n' + elif self.rules == 'REPEATED' and self.allocation == 'STATIC': + result += ' pb_size_t ' + self.name + '_count;\n' + result += ' %s %s%s;' % (self.ctype, self.name, self.array_decl) + return result + + def types(self): + '''Return definitions for any special types this field might need.''' + if self.pbtype == 'BYTES' and self.allocation == 'STATIC': + result = 'typedef PB_BYTES_ARRAY_T(%d) %s;\n' % (self.max_size, self.ctype) + else: + result = '' + return result + + def get_dependencies(self): + '''Get list of type names used by this field.''' + if self.allocation == 'STATIC': + return [str(self.ctype)] + else: + return [] + + def get_initializer(self, null_init, inner_init_only = False): + '''Return literal expression for this field's default value. + null_init: If True, initialize to a 0 value instead of default from .proto + inner_init_only: If True, exclude initialization for any count/has fields + ''' + + inner_init = None + if self.pbtype == 'MESSAGE': + if null_init: + inner_init = '%s_init_zero' % self.ctype + else: + inner_init = '%s_init_default' % self.ctype + elif self.default is None or null_init: + if self.pbtype == 'STRING': + inner_init = '""' + elif self.pbtype == 'BYTES': + inner_init = '{0, {0}}' + elif self.pbtype == 'FIXED_LENGTH_BYTES': + inner_init = '{0}' + elif self.pbtype in ('ENUM', 'UENUM'): + inner_init = '(%s)0' % self.ctype + else: + inner_init = '0' + else: + if self.pbtype == 'STRING': + inner_init = self.default.replace('"', '\\"') + inner_init = '"' + inner_init + '"' + elif self.pbtype == 'BYTES': + data = ['0x%02x' % ord(c) for c in self.default] + if len(data) == 0: + inner_init = '{0, {0}}' + else: + inner_init = '{%d, {%s}}' % (len(data), ','.join(data)) + elif self.pbtype == 'FIXED_LENGTH_BYTES': + data = ['0x%02x' % ord(c) for c in self.default] + if len(data) == 0: + inner_init = '{0}' + else: + inner_init = '{%s}' % ','.join(data) + elif self.pbtype in ['FIXED32', 'UINT32']: + inner_init = str(self.default) + 'u' + elif self.pbtype in ['FIXED64', 'UINT64']: + inner_init = str(self.default) + 'ull' + elif self.pbtype in ['SFIXED64', 'INT64']: + inner_init = str(self.default) + 'll' + else: + inner_init = str(self.default) + + if inner_init_only: + return inner_init + + outer_init = None + if self.allocation == 'STATIC': + if self.rules == 'REPEATED': + outer_init = '0, {' + outer_init += ', '.join([inner_init] * self.max_count) + outer_init += '}' + elif self.rules == 'OPTIONAL': + outer_init = 'false, ' + inner_init + else: + outer_init = inner_init + elif self.allocation == 'POINTER': + if self.rules == 'REPEATED': + outer_init = '0, NULL' + else: + outer_init = 'NULL' + elif self.allocation == 'CALLBACK': + if self.pbtype == 'EXTENSION': + outer_init = 'NULL' + else: + outer_init = '{{NULL}, NULL}' + + return outer_init + + def default_decl(self, declaration_only = False): + '''Return definition for this field's default value.''' + if self.default is None: + return None + + ctype = self.ctype + default = self.get_initializer(False, True) + array_decl = '' + + if self.pbtype == 'STRING': + if self.allocation != 'STATIC': + return None # Not implemented + array_decl = '[%d]' % self.max_size + elif self.pbtype == 'BYTES': + if self.allocation != 'STATIC': + return None # Not implemented + elif self.pbtype == 'FIXED_LENGTH_BYTES': + if self.allocation != 'STATIC': + return None # Not implemented + array_decl = '[%d]' % self.max_size + + if declaration_only: + return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl) + else: + return 'const %s %s_default%s = %s;' % (ctype, self.struct_name + self.name, array_decl, default) + + def tags(self): + '''Return the #define for the tag number of this field.''' + identifier = '%s_%s_tag' % (self.struct_name, self.name) + return '#define %-40s %d\n' % (identifier, self.tag) + + def pb_field_t(self, prev_field_name, union_index = None): + '''Return the pb_field_t initializer to use in the constant array. + prev_field_name is the name of the previous field or None. For OneOf + unions, union_index is the index of this field inside the OneOf. + ''' + + if self.rules == 'ONEOF': + if self.anonymous: + result = ' PB_ANONYMOUS_ONEOF_FIELD(%s, ' % self.union_name + else: + result = ' PB_ONEOF_FIELD(%s, ' % self.union_name + else: + result = ' PB_FIELD(' + + result += '%3d, ' % self.tag + result += '%-8s, ' % self.pbtype + result += '%s, ' % self.rules + result += '%-8s, ' % self.allocation + + if union_index is not None and union_index > 0: + result += 'UNION, ' + elif prev_field_name is None: + result += 'FIRST, ' + else: + result += 'OTHER, ' + + result += '%s, ' % self.struct_name + result += '%s, ' % self.name + result += '%s, ' % (prev_field_name or self.name) + + if self.pbtype == 'MESSAGE': + result += '&%s_fields)' % self.submsgname + elif self.default is None: + result += '0)' + elif self.pbtype in ['BYTES', 'STRING', 'FIXED_LENGTH_BYTES'] and self.allocation != 'STATIC': + result += '0)' # Arbitrary size default values not implemented + elif self.rules == 'OPTEXT': + result += '0)' # Default value for extensions is not implemented + else: + result += '&%s_default)' % (self.struct_name + self.name) + + return result + + def get_last_field_name(self): + return self.name + + def largest_field_value(self): + '''Determine if this field needs 16bit or 32bit pb_field_t structure to compile properly. + Returns numeric value or a C-expression for assert.''' + check = [] + if self.pbtype == 'MESSAGE' and self.allocation == 'STATIC': + if self.rules == 'REPEATED': + check.append('pb_membersize(%s, %s[0])' % (self.struct_name, self.name)) + elif self.rules == 'ONEOF': + if self.anonymous: + check.append('pb_membersize(%s, %s)' % (self.struct_name, self.name)) + else: + check.append('pb_membersize(%s, %s.%s)' % (self.struct_name, self.union_name, self.name)) + else: + check.append('pb_membersize(%s, %s)' % (self.struct_name, self.name)) + elif self.pbtype == 'BYTES' and self.allocation == 'STATIC': + if self.max_size > 251: + check.append('pb_membersize(%s, %s)' % (self.struct_name, self.name)) + + return FieldMaxSize([self.tag, self.max_size, self.max_count], + check, + ('%s.%s' % (self.struct_name, self.name))) + + def encoded_size(self, dependencies): + '''Return the maximum size that this field can take when encoded, + including the field tag. If the size cannot be determined, returns + None.''' + + if self.allocation != 'STATIC': + return None + + if self.pbtype == 'MESSAGE': + encsize = None + if str(self.submsgname) in dependencies: + submsg = dependencies[str(self.submsgname)] + encsize = submsg.encoded_size(dependencies) + if encsize is not None: + # Include submessage length prefix + encsize += varint_max_size(encsize.upperlimit()) + + if encsize is None: + # Submessage or its size cannot be found. + # This can occur if submessage is defined in different + # file, and it or its .options could not be found. + # Instead of direct numeric value, reference the size that + # has been #defined in the other file. + encsize = EncodedSize(self.submsgname + 'size') + + # We will have to make a conservative assumption on the length + # prefix size, though. + encsize += 5 + + elif self.pbtype in ['ENUM', 'UENUM']: + if str(self.ctype) in dependencies: + enumtype = dependencies[str(self.ctype)] + encsize = enumtype.encoded_size() + else: + # Conservative assumption + encsize = 10 + + elif self.enc_size is None: + raise RuntimeError("Could not determine encoded size for %s.%s" + % (self.struct_name, self.name)) + else: + encsize = EncodedSize(self.enc_size) + + encsize += varint_max_size(self.tag << 3) # Tag + wire type + + if self.rules == 'REPEATED': + # Decoders must be always able to handle unpacked arrays. + # Therefore we have to reserve space for it, even though + # we emit packed arrays ourselves. For length of 1, packed + # arrays are larger however so we need to add allowance + # for the length byte. + encsize *= self.max_count + + if self.max_count == 1: + encsize += 1 + + return encsize + + +class ExtensionRange(Field): + def __init__(self, struct_name, range_start, field_options): + '''Implements a special pb_extension_t* field in an extensible message + structure. The range_start signifies the index at which the extensions + start. Not necessarily all tags above this are extensions, it is merely + a speed optimization. + ''' + self.tag = range_start + self.struct_name = struct_name + self.name = 'extensions' + self.pbtype = 'EXTENSION' + self.rules = 'OPTIONAL' + self.allocation = 'CALLBACK' + self.ctype = 'pb_extension_t' + self.array_decl = '' + self.default = None + self.max_size = 0 + self.max_count = 0 + + def __str__(self): + return ' pb_extension_t *extensions;' + + def types(self): + return '' + + def tags(self): + return '' + + def encoded_size(self, dependencies): + # We exclude extensions from the count, because they cannot be known + # until runtime. Other option would be to return None here, but this + # way the value remains useful if extensions are not used. + return EncodedSize(0) + +class ExtensionField(Field): + def __init__(self, struct_name, desc, field_options): + self.fullname = struct_name + desc.name + self.extendee_name = names_from_type_name(desc.extendee) + Field.__init__(self, self.fullname + 'struct', desc, field_options) + + if self.rules != 'OPTIONAL': + self.skip = True + else: + self.skip = False + self.rules = 'OPTEXT' + + def tags(self): + '''Return the #define for the tag number of this field.''' + identifier = '%s_tag' % self.fullname + return '#define %-40s %d\n' % (identifier, self.tag) + + def extension_decl(self): + '''Declaration of the extension type in the .pb.h file''' + if self.skip: + msg = '/* Extension field %s was skipped because only "optional"\n' % self.fullname + msg +=' type of extension fields is currently supported. */\n' + return msg + + return ('extern const pb_extension_type_t %s; /* field type: %s */\n' % + (self.fullname, str(self).strip())) + + def extension_def(self): + '''Definition of the extension type in the .pb.c file''' + + if self.skip: + return '' + + result = 'typedef struct {\n' + result += str(self) + result += '\n} %s;\n\n' % self.struct_name + result += ('static const pb_field_t %s_field = \n %s;\n\n' % + (self.fullname, self.pb_field_t(None))) + result += 'const pb_extension_type_t %s = {\n' % self.fullname + result += ' NULL,\n' + result += ' NULL,\n' + result += ' &%s_field\n' % self.fullname + result += '};\n' + return result + + +# --------------------------------------------------------------------------- +# Generation of oneofs (unions) +# --------------------------------------------------------------------------- + +class OneOf(Field): + def __init__(self, struct_name, oneof_desc): + self.struct_name = struct_name + self.name = oneof_desc.name + self.ctype = 'union' + self.pbtype = 'oneof' + self.fields = [] + self.allocation = 'ONEOF' + self.default = None + self.rules = 'ONEOF' + self.anonymous = False + + def add_field(self, field): + if field.allocation == 'CALLBACK': + raise Exception("Callback fields inside of oneof are not supported" + + " (field %s)" % field.name) + + field.union_name = self.name + field.rules = 'ONEOF' + field.anonymous = self.anonymous + self.fields.append(field) + self.fields.sort(key = lambda f: f.tag) + + # Sort by the lowest tag number inside union + self.tag = min([f.tag for f in self.fields]) + + def __str__(self): + result = '' + if self.fields: + result += ' pb_size_t which_' + self.name + ";\n" + result += ' union {\n' + for f in self.fields: + result += ' ' + str(f).replace('\n', '\n ') + '\n' + if self.anonymous: + result += ' };' + else: + result += ' } ' + self.name + ';' + return result + + def types(self): + return ''.join([f.types() for f in self.fields]) + + def get_dependencies(self): + deps = [] + for f in self.fields: + deps += f.get_dependencies() + return deps + + def get_initializer(self, null_init): + return '0, {' + self.fields[0].get_initializer(null_init) + '}' + + def default_decl(self, declaration_only = False): + return None + + def tags(self): + return ''.join([f.tags() for f in self.fields]) + + def pb_field_t(self, prev_field_name): + parts = [] + for union_index, field in enumerate(self.fields): + parts.append(field.pb_field_t(prev_field_name, union_index)) + return ',\n'.join(parts) + + def get_last_field_name(self): + if self.anonymous: + return self.fields[-1].name + else: + return self.name + '.' + self.fields[-1].name + + def largest_field_value(self): + largest = FieldMaxSize() + for f in self.fields: + largest.extend(f.largest_field_value()) + return largest + + def encoded_size(self, dependencies): + '''Returns the size of the largest oneof field.''' + largest = EncodedSize(0) + for f in self.fields: + size = EncodedSize(f.encoded_size(dependencies)) + if size.value is None: + return None + elif size.symbols: + return None # Cannot resolve maximum of symbols + elif size.value > largest.value: + largest = size + + return largest + +# --------------------------------------------------------------------------- +# Generation of messages (structures) +# --------------------------------------------------------------------------- + + +class Message: + def __init__(self, names, desc, message_options): + self.name = names + self.fields = [] + self.oneofs = {} + no_unions = [] + + if message_options.msgid: + self.msgid = message_options.msgid + + if hasattr(desc, 'oneof_decl'): + for i, f in enumerate(desc.oneof_decl): + oneof_options = get_nanopb_suboptions(desc, message_options, self.name + f.name) + if oneof_options.no_unions: + no_unions.append(i) # No union, but add fields normally + elif oneof_options.type == nanopb_pb2.FT_IGNORE: + pass # No union and skip fields also + else: + oneof = OneOf(self.name, f) + if oneof_options.anonymous_oneof: + oneof.anonymous = True + self.oneofs[i] = oneof + self.fields.append(oneof) + + for f in desc.field: + field_options = get_nanopb_suboptions(f, message_options, self.name + f.name) + if field_options.type == nanopb_pb2.FT_IGNORE: + continue + + field = Field(self.name, f, field_options) + if (hasattr(f, 'oneof_index') and + f.HasField('oneof_index') and + f.oneof_index not in no_unions): + if f.oneof_index in self.oneofs: + self.oneofs[f.oneof_index].add_field(field) + else: + self.fields.append(field) + + if len(desc.extension_range) > 0: + field_options = get_nanopb_suboptions(desc, message_options, self.name + 'extensions') + range_start = min([r.start for r in desc.extension_range]) + if field_options.type != nanopb_pb2.FT_IGNORE: + self.fields.append(ExtensionRange(self.name, range_start, field_options)) + + self.packed = message_options.packed_struct + self.ordered_fields = self.fields[:] + self.ordered_fields.sort() + + def get_dependencies(self): + '''Get list of type names that this structure refers to.''' + deps = [] + for f in self.fields: + deps += f.get_dependencies() + return deps + + def __str__(self): + result = 'typedef struct _%s {\n' % self.name + + if not self.ordered_fields: + # Empty structs are not allowed in C standard. + # Therefore add a dummy field if an empty message occurs. + result += ' char dummy_field;' + + result += '\n'.join([str(f) for f in self.ordered_fields]) + result += '\n/* @@protoc_insertion_point(struct:%s) */' % self.name + result += '\n}' + + if self.packed: + result += ' pb_packed' + + result += ' %s;' % self.name + + if self.packed: + result = 'PB_PACKED_STRUCT_START\n' + result + result += '\nPB_PACKED_STRUCT_END' + + return result + + def types(self): + return ''.join([f.types() for f in self.fields]) + + def get_initializer(self, null_init): + if not self.ordered_fields: + return '{0}' + + parts = [] + for field in self.ordered_fields: + parts.append(field.get_initializer(null_init)) + return '{' + ', '.join(parts) + '}' + + def default_decl(self, declaration_only = False): + result = "" + for field in self.fields: + default = field.default_decl(declaration_only) + if default is not None: + result += default + '\n' + return result + + def count_required_fields(self): + '''Returns number of required fields inside this message''' + count = 0 + for f in self.fields: + if not isinstance(f, OneOf): + if f.rules == 'REQUIRED': + count += 1 + return count + + def count_all_fields(self): + count = 0 + for f in self.fields: + if isinstance(f, OneOf): + count += len(f.fields) + else: + count += 1 + return count + + def fields_declaration(self): + result = 'extern const pb_field_t %s_fields[%d];' % (self.name, self.count_all_fields() + 1) + return result + + def fields_definition(self): + result = 'const pb_field_t %s_fields[%d] = {\n' % (self.name, self.count_all_fields() + 1) + + prev = None + for field in self.ordered_fields: + result += field.pb_field_t(prev) + result += ',\n' + prev = field.get_last_field_name() + + result += ' PB_LAST_FIELD\n};' + return result + + def encoded_size(self, dependencies): + '''Return the maximum size that this message can take when encoded. + If the size cannot be determined, returns None. + ''' + size = EncodedSize(0) + for field in self.fields: + fsize = field.encoded_size(dependencies) + if fsize is None: + return None + size += fsize + + return size + + +# --------------------------------------------------------------------------- +# Processing of entire .proto files +# --------------------------------------------------------------------------- + +def iterate_messages(desc, names = Names()): + '''Recursively find all messages. For each, yield name, DescriptorProto.''' + if hasattr(desc, 'message_type'): + submsgs = desc.message_type + else: + submsgs = desc.nested_type + + for submsg in submsgs: + sub_names = names + submsg.name + yield sub_names, submsg + + for x in iterate_messages(submsg, sub_names): + yield x + +def iterate_extensions(desc, names = Names()): + '''Recursively find all extensions. + For each, yield name, FieldDescriptorProto. + ''' + for extension in desc.extension: + yield names, extension + + for subname, subdesc in iterate_messages(desc, names): + for extension in subdesc.extension: + yield subname, extension + +def toposort2(data): + '''Topological sort. + From http://code.activestate.com/recipes/577413-topological-sort/ + This function is under the MIT license. + ''' + for k, v in list(data.items()): + v.discard(k) # Ignore self dependencies + extra_items_in_deps = reduce(set.union, list(data.values()), set()) - set(data.keys()) + data.update(dict([(item, set()) for item in extra_items_in_deps])) + while True: + ordered = set(item for item,dep in list(data.items()) if not dep) + if not ordered: + break + for item in sorted(ordered): + yield item + data = dict([(item, (dep - ordered)) for item,dep in list(data.items()) + if item not in ordered]) + assert not data, "A cyclic dependency exists amongst %r" % data + +def sort_dependencies(messages): + '''Sort a list of Messages based on dependencies.''' + dependencies = {} + message_by_name = {} + for message in messages: + dependencies[str(message.name)] = set(message.get_dependencies()) + message_by_name[str(message.name)] = message + + for msgname in toposort2(dependencies): + if msgname in message_by_name: + yield message_by_name[msgname] + +def make_identifier(headername): + '''Make #ifndef identifier that contains uppercase A-Z and digits 0-9''' + result = "" + for c in headername.upper(): + if c.isalnum(): + result += c + else: + result += '_' + return result + +class ProtoFile: + def __init__(self, fdesc, file_options): + '''Takes a FileDescriptorProto and parses it.''' + self.fdesc = fdesc + self.file_options = file_options + self.dependencies = {} + self.parse() + + # Some of types used in this file probably come from the file itself. + # Thus it has implicit dependency on itself. + self.add_dependency(self) + + def parse(self): + self.enums = [] + self.messages = [] + self.extensions = [] + + if self.fdesc.package: + base_name = Names(self.fdesc.package.split('.')) + else: + base_name = Names() + + for enum in self.fdesc.enum_type: + enum_options = get_nanopb_suboptions(enum, self.file_options, base_name + enum.name) + self.enums.append(Enum(base_name, enum, enum_options)) + + for names, message in iterate_messages(self.fdesc, base_name): + message_options = get_nanopb_suboptions(message, self.file_options, names) + + if message_options.skip_message: + continue + + self.messages.append(Message(names, message, message_options)) + for enum in message.enum_type: + enum_options = get_nanopb_suboptions(enum, message_options, names + enum.name) + self.enums.append(Enum(names, enum, enum_options)) + + for names, extension in iterate_extensions(self.fdesc, base_name): + field_options = get_nanopb_suboptions(extension, self.file_options, names + extension.name) + if field_options.type != nanopb_pb2.FT_IGNORE: + self.extensions.append(ExtensionField(names, extension, field_options)) + + def add_dependency(self, other): + for enum in other.enums: + self.dependencies[str(enum.names)] = enum + + for msg in other.messages: + self.dependencies[str(msg.name)] = msg + + # Fix field default values where enum short names are used. + for enum in other.enums: + if not enum.options.long_names: + for message in self.messages: + for field in message.fields: + if field.default in enum.value_longnames: + idx = enum.value_longnames.index(field.default) + field.default = enum.values[idx][0] + + # Fix field data types where enums have negative values. + for enum in other.enums: + if not enum.has_negative(): + for message in self.messages: + for field in message.fields: + if field.pbtype == 'ENUM' and field.ctype == enum.names: + field.pbtype = 'UENUM' + + def generate_header(self, includes, headername, options): + '''Generate content for a header file. + Generates strings, which should be concatenated and stored to file. + ''' + + yield '/* Automatically generated nanopb header */\n' + if options.notimestamp: + yield '/* Generated by %s */\n\n' % (nanopb_version) + else: + yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime()) + + if self.fdesc.package: + symbol = make_identifier(self.fdesc.package + '_' + headername) + else: + symbol = make_identifier(headername) + yield '#ifndef PB_%s_INCLUDED\n' % symbol + yield '#define PB_%s_INCLUDED\n' % symbol + try: + yield options.libformat % ('pb.h') + except TypeError: + # no %s specified - use whatever was passed in as options.libformat + yield options.libformat + yield '\n' + + for incfile in includes: + noext = os.path.splitext(incfile)[0] + yield options.genformat % (noext + options.extension + options.header_extension) + yield '\n' + + yield '/* @@protoc_insertion_point(includes) */\n' + + yield '#if PB_PROTO_HEADER_VERSION != 30\n' + yield '#error Regenerate this file with the current version of nanopb generator.\n' + yield '#endif\n' + yield '\n' + + yield '#ifdef __cplusplus\n' + yield 'extern "C" {\n' + yield '#endif\n\n' + + if self.enums: + yield '/* Enum definitions */\n' + for enum in self.enums: + yield str(enum) + '\n\n' + + if self.messages: + yield '/* Struct definitions */\n' + for msg in sort_dependencies(self.messages): + yield msg.types() + yield str(msg) + '\n\n' + + if self.extensions: + yield '/* Extensions */\n' + for extension in self.extensions: + yield extension.extension_decl() + yield '\n' + + if self.messages: + yield '/* Default values for struct fields */\n' + for msg in self.messages: + yield msg.default_decl(True) + yield '\n' + + yield '/* Initializer values for message structs */\n' + for msg in self.messages: + identifier = '%s_init_default' % msg.name + yield '#define %-40s %s\n' % (identifier, msg.get_initializer(False)) + for msg in self.messages: + identifier = '%s_init_zero' % msg.name + yield '#define %-40s %s\n' % (identifier, msg.get_initializer(True)) + yield '\n' + + yield '/* Field tags (for use in manual encoding/decoding) */\n' + for msg in sort_dependencies(self.messages): + for field in msg.fields: + yield field.tags() + for extension in self.extensions: + yield extension.tags() + yield '\n' + + yield '/* Struct field encoding specification for nanopb */\n' + for msg in self.messages: + yield msg.fields_declaration() + '\n' + yield '\n' + + yield '/* Maximum encoded size of messages (where known) */\n' + for msg in self.messages: + msize = msg.encoded_size(self.dependencies) + identifier = '%s_size' % msg.name + if msize is not None: + yield '#define %-40s %s\n' % (identifier, msize) + else: + yield '/* %s depends on runtime parameters */\n' % identifier + yield '\n' + + yield '/* Message IDs (where set with "msgid" option) */\n' + + yield '#ifdef PB_MSGID\n' + for msg in self.messages: + if hasattr(msg,'msgid'): + yield '#define PB_MSG_%d %s\n' % (msg.msgid, msg.name) + yield '\n' + + symbol = make_identifier(headername.split('.')[0]) + yield '#define %s_MESSAGES \\\n' % symbol + + for msg in self.messages: + m = "-1" + msize = msg.encoded_size(self.dependencies) + if msize is not None: + m = msize + if hasattr(msg,'msgid'): + yield '\tPB_MSG(%d,%s,%s) \\\n' % (msg.msgid, m, msg.name) + yield '\n' + + for msg in self.messages: + if hasattr(msg,'msgid'): + yield '#define %s_msgid %d\n' % (msg.name, msg.msgid) + yield '\n' + + yield '#endif\n\n' + + yield '#ifdef __cplusplus\n' + yield '} /* extern "C" */\n' + yield '#endif\n' + + # End of header + yield '/* @@protoc_insertion_point(eof) */\n' + yield '\n#endif\n' + + def generate_source(self, headername, options): + '''Generate content for a source file.''' + + yield '/* Automatically generated nanopb constant definitions */\n' + if options.notimestamp: + yield '/* Generated by %s */\n\n' % (nanopb_version) + else: + yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime()) + yield options.genformat % (headername) + yield '\n' + yield '/* @@protoc_insertion_point(includes) */\n' + + yield '#if PB_PROTO_HEADER_VERSION != 30\n' + yield '#error Regenerate this file with the current version of nanopb generator.\n' + yield '#endif\n' + yield '\n' + + for msg in self.messages: + yield msg.default_decl(False) + + yield '\n\n' + + for msg in self.messages: + yield msg.fields_definition() + '\n\n' + + for ext in self.extensions: + yield ext.extension_def() + '\n' + + for enum in self.enums: + yield enum.enum_to_string_definition() + '\n' + + # Add checks for numeric limits + if self.messages: + largest_msg = max(self.messages, key = lambda m: m.count_required_fields()) + largest_count = largest_msg.count_required_fields() + if largest_count > 64: + yield '\n/* Check that missing required fields will be properly detected */\n' + yield '#if PB_MAX_REQUIRED_FIELDS < %d\n' % largest_count + yield '#error Properly detecting missing required fields in %s requires \\\n' % largest_msg.name + yield ' setting PB_MAX_REQUIRED_FIELDS to %d or more.\n' % largest_count + yield '#endif\n' + + max_field = FieldMaxSize() + checks_msgnames = [] + for msg in self.messages: + checks_msgnames.append(msg.name) + for field in msg.fields: + max_field.extend(field.largest_field_value()) + + worst = max_field.worst + worst_field = max_field.worst_field + checks = max_field.checks + + if worst > 255 or checks: + yield '\n/* Check that field information fits in pb_field_t */\n' + + if worst > 65535 or checks: + yield '#if !defined(PB_FIELD_32BIT)\n' + if worst > 65535: + yield '#error Field descriptor for %s is too large. Define PB_FIELD_32BIT to fix this.\n' % worst_field + else: + assertion = ' && '.join(str(c) + ' < 65536' for c in checks) + msgs = '_'.join(str(n) for n in checks_msgnames) + yield '/* If you get an error here, it means that you need to define PB_FIELD_32BIT\n' + yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n' + yield ' * \n' + yield ' * The reason you need to do this is that some of your messages contain tag\n' + yield ' * numbers or field sizes that are larger than what can fit in 8 or 16 bit\n' + yield ' * field descriptors.\n' + yield ' */\n' + yield 'PB_STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs) + yield '#endif\n\n' + + if worst < 65536: + yield '#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)\n' + if worst > 255: + yield '#error Field descriptor for %s is too large. Define PB_FIELD_16BIT to fix this.\n' % worst_field + else: + assertion = ' && '.join(str(c) + ' < 256' for c in checks) + msgs = '_'.join(str(n) for n in checks_msgnames) + yield '/* If you get an error here, it means that you need to define PB_FIELD_16BIT\n' + yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n' + yield ' * \n' + yield ' * The reason you need to do this is that some of your messages contain tag\n' + yield ' * numbers or field sizes that are larger than what can fit in the default\n' + yield ' * 8 bit descriptors.\n' + yield ' */\n' + yield 'PB_STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs) + yield '#endif\n\n' + + # Add check for sizeof(double) + has_double = False + for msg in self.messages: + for field in msg.fields: + if field.ctype == 'double': + has_double = True + + if has_double: + yield '\n' + yield '/* On some platforms (such as AVR), double is really float.\n' + yield ' * These are not directly supported by nanopb, but see example_avr_double.\n' + yield ' * To get rid of this error, remove any double fields from your .proto.\n' + yield ' */\n' + yield 'PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)\n' + + yield '\n' + yield '/* @@protoc_insertion_point(eof) */\n' + +# --------------------------------------------------------------------------- +# Options parsing for the .proto files +# --------------------------------------------------------------------------- + +from fnmatch import fnmatch + +def read_options_file(infile): + '''Parse a separate options file to list: + [(namemask, options), ...] + ''' + results = [] + data = infile.read() + data = re.sub('/\*.*?\*/', '', data, flags = re.MULTILINE) + data = re.sub('//.*?$', '', data, flags = re.MULTILINE) + data = re.sub('#.*?$', '', data, flags = re.MULTILINE) + for i, line in enumerate(data.split('\n')): + line = line.strip() + if not line: + continue + + parts = line.split(None, 1) + + if len(parts) < 2: + sys.stderr.write("%s:%d: " % (infile.name, i + 1) + + "Option lines should have space between field name and options. " + + "Skipping line: '%s'\n" % line) + continue + + opts = nanopb_pb2.NanoPBOptions() + + try: + text_format.Merge(parts[1], opts) + except Exception as e: + sys.stderr.write("%s:%d: " % (infile.name, i + 1) + + "Unparseable option line: '%s'. " % line + + "Error: %s\n" % str(e)) + continue + results.append((parts[0], opts)) + + return results + +class Globals: + '''Ugly global variables, should find a good way to pass these.''' + verbose_options = False + separate_options = [] + matched_namemasks = set() + +def get_nanopb_suboptions(subdesc, options, name): + '''Get copy of options, and merge information from subdesc.''' + new_options = nanopb_pb2.NanoPBOptions() + new_options.CopyFrom(options) + + if hasattr(subdesc, 'syntax') and subdesc.syntax == "proto3": + new_options.proto3 = True + + # Handle options defined in a separate file + dotname = '.'.join(name.parts) + for namemask, options in Globals.separate_options: + if fnmatch(dotname, namemask): + Globals.matched_namemasks.add(namemask) + new_options.MergeFrom(options) + + # Handle options defined in .proto + if isinstance(subdesc.options, descriptor.FieldOptions): + ext_type = nanopb_pb2.nanopb + elif isinstance(subdesc.options, descriptor.FileOptions): + ext_type = nanopb_pb2.nanopb_fileopt + elif isinstance(subdesc.options, descriptor.MessageOptions): + ext_type = nanopb_pb2.nanopb_msgopt + elif isinstance(subdesc.options, descriptor.EnumOptions): + ext_type = nanopb_pb2.nanopb_enumopt + else: + raise Exception("Unknown options type") + + if subdesc.options.HasExtension(ext_type): + ext = subdesc.options.Extensions[ext_type] + new_options.MergeFrom(ext) + + if Globals.verbose_options: + sys.stderr.write("Options for " + dotname + ": ") + sys.stderr.write(text_format.MessageToString(new_options) + "\n") + + return new_options + + +# --------------------------------------------------------------------------- +# Command line interface +# --------------------------------------------------------------------------- + +import sys +import os.path +from optparse import OptionParser + +optparser = OptionParser( + usage = "Usage: nanopb_generator.py [options] file.pb ...", + epilog = "Compile file.pb from file.proto by: 'protoc -ofile.pb file.proto'. " + + "Output will be written to file.pb.h and file.pb.c.") +optparser.add_option("-x", dest="exclude", metavar="FILE", action="append", default=[], + help="Exclude file from generated #include list.") +optparser.add_option("-e", "--extension", dest="extension", metavar="EXTENSION", default=".pb", + help="Set extension to use instead of '.pb' for generated files. [default: %default]") +optparser.add_option("-H", "--header-extension", dest="header_extension", metavar="EXTENSION", default=".h", + help="Set extension to use for generated header files. [default: %default]") +optparser.add_option("-S", "--source-extension", dest="source_extension", metavar="EXTENSION", default=".c", + help="Set extension to use for generated source files. [default: %default]") +optparser.add_option("-f", "--options-file", dest="options_file", metavar="FILE", default="%s.options", + help="Set name of a separate generator options file.") +optparser.add_option("-I", "--options-path", dest="options_path", metavar="DIR", + action="append", default = [], + help="Search for .options files additionally in this path") +optparser.add_option("-D", "--output-dir", dest="output_dir", + metavar="OUTPUTDIR", default=None, + help="Output directory of .pb.h and .pb.c files") +optparser.add_option("-Q", "--generated-include-format", dest="genformat", + metavar="FORMAT", default='#include "%s"\n', + help="Set format string to use for including other .pb.h files. [default: %default]") +optparser.add_option("-L", "--library-include-format", dest="libformat", + metavar="FORMAT", default='#include <%s>\n', + help="Set format string to use for including the nanopb pb.h header. [default: %default]") +optparser.add_option("-T", "--no-timestamp", dest="notimestamp", action="store_true", default=False, + help="Don't add timestamp to .pb.h and .pb.c preambles") +optparser.add_option("-q", "--quiet", dest="quiet", action="store_true", default=False, + help="Don't print anything except errors.") +optparser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False, + help="Print more information.") +optparser.add_option("-s", dest="settings", metavar="OPTION:VALUE", action="append", default=[], + help="Set generator option (max_size, max_count etc.).") + +def parse_file(filename, fdesc, options): + '''Parse a single file. Returns a ProtoFile instance.''' + toplevel_options = nanopb_pb2.NanoPBOptions() + for s in options.settings: + text_format.Merge(s, toplevel_options) + + if not fdesc: + data = open(filename, 'rb').read() + fdesc = descriptor.FileDescriptorSet.FromString(data).file[0] + + # Check if there is a separate .options file + had_abspath = False + try: + optfilename = options.options_file % os.path.splitext(filename)[0] + except TypeError: + # No %s specified, use the filename as-is + optfilename = options.options_file + had_abspath = True + + paths = ['.'] + options.options_path + for p in paths: + if os.path.isfile(os.path.join(p, optfilename)): + optfilename = os.path.join(p, optfilename) + if options.verbose: + sys.stderr.write('Reading options from ' + optfilename + '\n') + Globals.separate_options = read_options_file(open(optfilename, "rU")) + break + else: + # If we are given a full filename and it does not exist, give an error. + # However, don't give error when we automatically look for .options file + # with the same name as .proto. + if options.verbose or had_abspath: + sys.stderr.write('Options file not found: ' + optfilename + '\n') + Globals.separate_options = [] + + Globals.matched_namemasks = set() + + # Parse the file + file_options = get_nanopb_suboptions(fdesc, toplevel_options, Names([filename])) + f = ProtoFile(fdesc, file_options) + f.optfilename = optfilename + + return f + +def process_file(filename, fdesc, options, other_files = {}): + '''Process a single file. + filename: The full path to the .proto or .pb source file, as string. + fdesc: The loaded FileDescriptorSet, or None to read from the input file. + options: Command line options as they come from OptionsParser. + + Returns a dict: + {'headername': Name of header file, + 'headerdata': Data for the .h header file, + 'sourcename': Name of the source code file, + 'sourcedata': Data for the .c source code file + } + ''' + f = parse_file(filename, fdesc, options) + + # Provide dependencies if available + for dep in f.fdesc.dependency: + if dep in other_files: + f.add_dependency(other_files[dep]) + + # Decide the file names + noext = os.path.splitext(filename)[0] + headername = noext + options.extension + options.header_extension + sourcename = noext + options.extension + options.source_extension + headerbasename = os.path.basename(headername) + + # List of .proto files that should not be included in the C header file + # even if they are mentioned in the source .proto. + excludes = ['nanopb.proto', 'google/protobuf/descriptor.proto'] + options.exclude + includes = [d for d in f.fdesc.dependency if d not in excludes] + + headerdata = ''.join(f.generate_header(includes, headerbasename, options)) + sourcedata = ''.join(f.generate_source(headerbasename, options)) + + # Check if there were any lines in .options that did not match a member + unmatched = [n for n,o in Globals.separate_options if n not in Globals.matched_namemasks] + if unmatched and not options.quiet: + sys.stderr.write("Following patterns in " + f.optfilename + " did not match any fields: " + + ', '.join(unmatched) + "\n") + if not Globals.verbose_options: + sys.stderr.write("Use protoc --nanopb-out=-v:. to see a list of the field names.\n") + + return {'headername': headername, 'headerdata': headerdata, + 'sourcename': sourcename, 'sourcedata': sourcedata} + +def main_cli(): + '''Main function when invoked directly from the command line.''' + + options, filenames = optparser.parse_args() + + if not filenames: + optparser.print_help() + sys.exit(1) + + if options.quiet: + options.verbose = False + + if options.output_dir and not os.path.exists(options.output_dir): + optparser.print_help() + sys.stderr.write("\noutput_dir does not exist: %s\n" % options.output_dir) + sys.exit(1) + + + Globals.verbose_options = options.verbose + for filename in filenames: + results = process_file(filename, None, options) + + base_dir = options.output_dir or '' + to_write = [ + (os.path.join(base_dir, results['headername']), results['headerdata']), + (os.path.join(base_dir, results['sourcename']), results['sourcedata']), + ] + + if not options.quiet: + paths = " and ".join([x[0] for x in to_write]) + sys.stderr.write("Writing to %s\n" % paths) + + for path, data in to_write: + with open(path, 'w') as f: + f.write(data) + +def main_plugin(): + '''Main function when invoked as a protoc plugin.''' + + import io, sys + if sys.platform == "win32": + import os, msvcrt + # Set stdin and stdout to binary mode + msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) + msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + + data = io.open(sys.stdin.fileno(), "rb").read() + + request = plugin_pb2.CodeGeneratorRequest.FromString(data) + + try: + # Versions of Python prior to 2.7.3 do not support unicode + # input to shlex.split(). Try to convert to str if possible. + params = str(request.parameter) + except UnicodeEncodeError: + params = request.parameter + + import shlex + args = shlex.split(params) + options, dummy = optparser.parse_args(args) + + Globals.verbose_options = options.verbose + + response = plugin_pb2.CodeGeneratorResponse() + + # Google's protoc does not currently indicate the full path of proto files. + # Instead always add the main file path to the search dirs, that works for + # the common case. + import os.path + options.options_path.append(os.path.dirname(request.file_to_generate[0])) + + # Process any include files first, in order to have them + # available as dependencies + other_files = {} + for fdesc in request.proto_file: + other_files[fdesc.name] = parse_file(fdesc.name, fdesc, options) + + for filename in request.file_to_generate: + for fdesc in request.proto_file: + if fdesc.name == filename: + results = process_file(filename, fdesc, options, other_files) + + f = response.file.add() + f.name = results['headername'] + f.content = results['headerdata'] + + f = response.file.add() + f.name = results['sourcename'] + f.content = results['sourcedata'] + + io.open(sys.stdout.fileno(), "wb").write(response.SerializeToString()) + +if __name__ == '__main__': + # Check if we are running as a plugin under protoc + if 'protoc-gen-' in sys.argv[0] or '--protoc-plugin' in sys.argv: + main_plugin() + else: + main_cli() diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/proto/Makefile b/hardware-wallet/firmware/vendor/nanopb/generator/proto/Makefile new file mode 100644 index 00000000..89bfe528 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/proto/Makefile @@ -0,0 +1,4 @@ +all: nanopb_pb2.py plugin_pb2.py + +%_pb2.py: %.proto + protoc --python_out=. $< diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/proto/__init__.py b/hardware-wallet/firmware/vendor/nanopb/generator/proto/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/proto/google/protobuf/descriptor.proto b/hardware-wallet/firmware/vendor/nanopb/generator/proto/google/protobuf/descriptor.proto new file mode 100644 index 00000000..e17c0cc8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/proto/google/protobuf/descriptor.proto @@ -0,0 +1,714 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 Google Inc. 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. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; + optional int32 end = 2; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + TYPE_GROUP = 10; // Tag-delimited aggregate. + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + }; + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + // TODO(sanjay): Should we add LABEL_MAP? + }; + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. Extensions of a oneof should + // not set this since the oneof to which they belong will be inferred based + // on the extension range containing the extension's field number. + optional int32 oneof_index = 9; + + optional FieldOptions options = 8; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default=false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default=false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Object-C plugin) and your porject website (if available) -- there's no need +// to explain how you intend to use them. Usually you only need one extension +// number. You can declare multiple options with only one extension number by +// putting them in a sub-message. See the Custom Options section of the docs +// for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + optional string java_outer_classname = 8; + + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default=false]; + + // If set true, then the Java code generator will generate equals() and + // hashCode() methods for all messages defined in the .proto file. + // - In the full runtime, this is purely a speed optimization, as the + // AbstractMessage base class includes reflection-based implementations of + // these methods. + //- In the lite runtime, setting this option changes the semantics of + // equals() and hashCode() to more closely match those of the full runtime; + // the generated methods compute their results based on field values rather + // than object identity. (Implementations should not assume that hashcodes + // will be consistent across runtimes or versions of the protocol compiler.) + optional bool java_generate_equals_and_hash = 20 [default=false]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default=false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default=SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default=false]; + optional bool java_generic_services = 17 [default=false]; + optional bool py_generic_services = 18 [default=false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default=false]; + + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default=false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default=false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default=false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default=false]; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. + optional bool packed = 2; + + + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outher message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default=false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default=false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default=false]; + + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed=true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed=true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + optional string leading_comments = 3; + optional string trailing_comments = 4; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/proto/nanopb.proto b/hardware-wallet/firmware/vendor/nanopb/generator/proto/nanopb.proto new file mode 100644 index 00000000..e4c1da79 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/proto/nanopb.proto @@ -0,0 +1,112 @@ +// Custom options for defining: +// - Maximum size of string/bytes +// - Maximum number of elements in array +// +// These are used by nanopb to generate statically allocable structures +// for memory-limited environments. + +syntax = "proto2"; +import "google/protobuf/descriptor.proto"; + +option java_package = "fi.kapsi.koti.jpa.nanopb"; + +enum FieldType { + FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible. + FT_CALLBACK = 1; // Always generate a callback field. + FT_POINTER = 4; // Always generate a dynamically allocated field. + FT_STATIC = 2; // Generate a static field or raise an exception if not possible. + FT_IGNORE = 3; // Ignore the field completely. + FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead +} + +enum IntSize { + IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto + IS_8 = 8; + IS_16 = 16; + IS_32 = 32; + IS_64 = 64; +} + +// This is the inner options message, which basically defines options for +// a field. When it is used in message or file scope, it applies to all +// fields. +message NanoPBOptions { + // Allocated size for 'bytes' and 'string' fields. + // For string fields, this should include the space for null terminator. + optional int32 max_size = 1; + + // Maximum length for 'string' fields. Setting this is equivalent + // to setting max_size to a value of length+1. + optional int32 max_length = 14; + + // Allocated number of entries in arrays ('repeated' fields) + optional int32 max_count = 2; + + // Size of integer fields. Can save some memory if you don't need + // full 32 bits for the value. + optional IntSize int_size = 7 [default = IS_DEFAULT]; + + // Force type of field (callback or static allocation) + optional FieldType type = 3 [default = FT_DEFAULT]; + + // Use long names for enums, i.e. EnumName_EnumValue. + optional bool long_names = 4 [default = true]; + + // Add 'packed' attribute to generated structs. + // Note: this cannot be used on CPUs that break on unaligned + // accesses to variables. + optional bool packed_struct = 5 [default = false]; + + // Add 'packed' attribute to generated enums. + optional bool packed_enum = 10 [default = false]; + + // Skip this message + optional bool skip_message = 6 [default = false]; + + // Generate oneof fields as normal optional fields instead of union. + optional bool no_unions = 8 [default = false]; + + // integer type tag for a message + optional uint32 msgid = 9; + + // decode oneof as anonymous union + optional bool anonymous_oneof = 11 [default = false]; + + // Proto3 singular field does not generate a "has_" flag + optional bool proto3 = 12 [default = false]; + + // Generate an enum->string mapping function (can take up lots of space). + optional bool enum_to_string = 13 [default = false]; + + // Generate bytes arrays with fixed length + optional bool fixed_length = 15 [default = false]; +} + +// Extensions to protoc 'Descriptor' type in order to define options +// inside a .proto file. +// +// Protocol Buffers extension number registry +// -------------------------------- +// Project: Nanopb +// Contact: Petteri Aimonen +// Web site: http://kapsi.fi/~jpa/nanopb +// Extensions: 1010 (all types) +// -------------------------------- + +extend google.protobuf.FileOptions { + optional NanoPBOptions nanopb_fileopt = 1010; +} + +extend google.protobuf.MessageOptions { + optional NanoPBOptions nanopb_msgopt = 1010; +} + +extend google.protobuf.EnumOptions { + optional NanoPBOptions nanopb_enumopt = 1010; +} + +extend google.protobuf.FieldOptions { + optional NanoPBOptions nanopb = 1010; +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/proto/plugin.proto b/hardware-wallet/firmware/vendor/nanopb/generator/proto/plugin.proto new file mode 100644 index 00000000..e627289b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/proto/plugin.proto @@ -0,0 +1,148 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 Google Inc. 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. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +import "google/protobuf/descriptor.proto"; + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + repeated FileDescriptorProto proto_file = 15; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + } + repeated File file = 15; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb b/hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb new file mode 100755 index 00000000..471a620b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb @@ -0,0 +1,13 @@ +#!/bin/sh + +# This file is used to invoke nanopb_generator.py as a plugin +# to protoc on Linux and other *nix-style systems. +# Use it like this: +# protoc --plugin=protoc-gen-nanopb=..../protoc-gen-nanopb --nanopb_out=dir foo.proto +# +# Note that if you use the binary package of nanopb, the protoc +# path is already set up properly and there is no need to give +# --plugin= on the command line. + +MYPATH=$(dirname "$0") +exec "$MYPATH/nanopb_generator.py" --protoc-plugin diff --git a/hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb.bat b/hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb.bat new file mode 100644 index 00000000..e6cf187f --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/generator/protoc-gen-nanopb.bat @@ -0,0 +1,12 @@ +@echo off +:: This file is used to invoke nanopb_generator.py as a plugin +:: to protoc on Windows. +:: Use it like this: +:: protoc --plugin=protoc-gen-nanopb=..../protoc-gen-nanopb.bat --nanopb_out=dir foo.proto +:: +:: Note that if you use the binary package of nanopb, the protoc +:: path is already set up properly and there is no need to give +:: --plugin= on the command line. + +set mydir=%~dp0 +python "%mydir%\nanopb_generator.py" --protoc-plugin diff --git a/hardware-wallet/firmware/vendor/nanopb/library.json b/hardware-wallet/firmware/vendor/nanopb/library.json new file mode 100644 index 00000000..0a3e17c8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/library.json @@ -0,0 +1,26 @@ +{ + "name": "Nanopb", + "version": "0.3.9", + "keywords": "protocol buffers, protobuf, google", + "description": "Nanopb is a plain-C implementation of Google's Protocol Buffers data format. It is targeted at 32 bit microcontrollers, but is also fit for other embedded systems with tight (2-10 kB ROM, <1 kB RAM) memory constraints.", + "repository": { + "type": "git", + "url": "https://github.com/nanopb/nanopb.git" + }, + "authors": [{ + "name": "Petteri Aimonen", + "email": "jpa@nanopb.mail.kapsi.fi", + "url": "http://koti.kapsi.fi/jpa/nanopb/" + }], + "export": { + "include": [ + "*.c", + "*.cpp", + "*.h", + "examples" + ] + }, + "examples": "examples/*/*.c", + "frameworks": "*", + "platforms": "*" +} diff --git a/hardware-wallet/firmware/vendor/nanopb/pb.h b/hardware-wallet/firmware/vendor/nanopb/pb.h new file mode 100644 index 00000000..64c0b43c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/pb.h @@ -0,0 +1,585 @@ +/* Common parts of the nanopb library. Most of these are quite low-level + * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. + */ + +#ifndef PB_H_INCLUDED +#define PB_H_INCLUDED + +/***************************************************************** + * Nanopb compilation time options. You can change these here by * + * uncommenting the lines, or on the compiler command line. * + *****************************************************************/ + +/* Enable support for dynamically allocated fields */ +/* #define PB_ENABLE_MALLOC 1 */ + +/* Define this if your CPU / compiler combination does not support + * unaligned memory access to packed structures. */ +/* #define PB_NO_PACKED_STRUCTS 1 */ + +/* Increase the number of required fields that are tracked. + * A compiler warning will tell if you need this. */ +/* #define PB_MAX_REQUIRED_FIELDS 256 */ + +/* Add support for tag numbers > 255 and fields larger than 255 bytes. */ +/* #define PB_FIELD_16BIT 1 */ + +/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ +/* #define PB_FIELD_32BIT 1 */ + +/* Disable support for error messages in order to save some code space. */ +/* #define PB_NO_ERRMSG 1 */ + +/* Disable support for custom streams (support only memory buffers). */ +/* #define PB_BUFFER_ONLY 1 */ + +/* Switch back to the old-style callback function signature. + * This was the default until nanopb-0.2.1. */ +/* #define PB_OLD_CALLBACK_STYLE */ + + +/****************************************************************** + * You usually don't need to change anything below this line. * + * Feel free to look around and use the defined macros, though. * + ******************************************************************/ + + +/* Version of the nanopb library. Just in case you want to check it in + * your own program. */ +#define NANOPB_VERSION nanopb-0.3.9 + +/* Include all the system headers needed by nanopb. You will need the + * definitions of the following: + * - strlen, memcpy, memset functions + * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t + * - size_t + * - bool + * + * If you don't have the standard header files, you can instead provide + * a custom header that defines or includes all this. In that case, + * define PB_SYSTEM_HEADER to the path of this file. + */ +#ifdef PB_SYSTEM_HEADER +#include PB_SYSTEM_HEADER +#else +#include +#include +#include +#include + +#ifdef PB_ENABLE_MALLOC +#include +#endif +#endif + +/* Macro for defining packed structures (compiler dependent). + * This just reduces memory requirements, but is not required. + */ +#if defined(PB_NO_PACKED_STRUCTS) + /* Disable struct packing */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#elif defined(__GNUC__) || defined(__clang__) + /* For GCC and clang */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed __attribute__((packed)) +#elif defined(__ICCARM__) || defined(__CC_ARM) + /* For IAR ARM and Keil MDK-ARM compilers */ +# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +# define pb_packed +#elif defined(_MSC_VER) && (_MSC_VER >= 1500) + /* For Microsoft Visual C++ */ +# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +# define PB_PACKED_STRUCT_END __pragma(pack(pop)) +# define pb_packed +#else + /* Unknown compiler */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#endif + +/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ +#ifndef PB_UNUSED +#define PB_UNUSED(x) (void)(x) +#endif + +/* Compile-time assertion, used for checking compatible compilation options. + * If this does not work properly on your compiler, use + * #define PB_NO_STATIC_ASSERT to disable it. + * + * But before doing that, check carefully the error message / place where it + * comes from to see if the error has a real cause. Unfortunately the error + * message is not always very clear to read, but you can see the reason better + * in the place where the PB_STATIC_ASSERT macro was called. + */ +#ifndef PB_NO_STATIC_ASSERT +#ifndef PB_STATIC_ASSERT +#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; +#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER +#endif +#else +#define PB_STATIC_ASSERT(COND,MSG) +#endif + +/* Number of required fields to keep track of. */ +#ifndef PB_MAX_REQUIRED_FIELDS +#define PB_MAX_REQUIRED_FIELDS 64 +#endif + +#if PB_MAX_REQUIRED_FIELDS < 64 +#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). +#endif + +/* List of possible field types. These are used in the autogenerated code. + * Least-significant 4 bits tell the scalar type + * Most-significant 4 bits specify repeated/required/packed etc. + */ + +typedef uint_least8_t pb_type_t; + +/**** Field data types ****/ + +/* Numeric types */ +#define PB_LTYPE_VARINT 0x00 /* int32, int64, enum, bool */ +#define PB_LTYPE_UVARINT 0x01 /* uint32, uint64 */ +#define PB_LTYPE_SVARINT 0x02 /* sint32, sint64 */ +#define PB_LTYPE_FIXED32 0x03 /* fixed32, sfixed32, float */ +#define PB_LTYPE_FIXED64 0x04 /* fixed64, sfixed64, double */ + +/* Marker for last packable field type. */ +#define PB_LTYPE_LAST_PACKABLE 0x04 + +/* Byte array with pre-allocated buffer. + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ +#define PB_LTYPE_BYTES 0x05 + +/* String with pre-allocated buffer. + * data_size is the maximum length. */ +#define PB_LTYPE_STRING 0x06 + +/* Submessage + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMESSAGE 0x07 + +/* Extension pseudo-field + * The field contains a pointer to pb_extension_t */ +#define PB_LTYPE_EXTENSION 0x08 + +/* Byte array with inline, pre-allocated byffer. + * data_size is the length of the inline, allocated buffer. + * This differs from PB_LTYPE_BYTES by defining the element as + * pb_byte_t[data_size] rather than pb_bytes_array_t. */ +#define PB_LTYPE_FIXED_LENGTH_BYTES 0x09 + +/* Number of declared LTYPES */ +#define PB_LTYPES_COUNT 0x0A +#define PB_LTYPE_MASK 0x0F + +/**** Field repetition rules ****/ + +#define PB_HTYPE_REQUIRED 0x00 +#define PB_HTYPE_OPTIONAL 0x10 +#define PB_HTYPE_REPEATED 0x20 +#define PB_HTYPE_ONEOF 0x30 +#define PB_HTYPE_MASK 0x30 + +/**** Field allocation types ****/ + +#define PB_ATYPE_STATIC 0x00 +#define PB_ATYPE_POINTER 0x80 +#define PB_ATYPE_CALLBACK 0x40 +#define PB_ATYPE_MASK 0xC0 + +#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) + +/* Data type used for storing sizes of struct fields + * and array counts. + */ +#if defined(PB_FIELD_32BIT) + typedef uint32_t pb_size_t; + typedef int32_t pb_ssize_t; +#elif defined(PB_FIELD_16BIT) + typedef uint_least16_t pb_size_t; + typedef int_least16_t pb_ssize_t; +#else + typedef uint_least8_t pb_size_t; + typedef int_least8_t pb_ssize_t; +#endif +#define PB_SIZE_MAX ((pb_size_t)-1) + +/* Data type for storing encoded data and other byte streams. + * This typedef exists to support platforms where uint8_t does not exist. + * You can regard it as equivalent on uint8_t on other platforms. + */ +typedef uint_least8_t pb_byte_t; + +/* This structure is used in auto-generated constants + * to specify struct fields. + * You can change field sizes if you need structures + * larger than 256 bytes or field tags larger than 256. + * The compiler should complain if your .proto has such + * structures. Fix that by defining PB_FIELD_16BIT or + * PB_FIELD_32BIT. + */ +PB_PACKED_STRUCT_START +typedef struct pb_field_s pb_field_t; +struct pb_field_s { + pb_size_t tag; + pb_type_t type; + pb_size_t data_offset; /* Offset of field data, relative to previous field. */ + pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */ + pb_size_t data_size; /* Data size in bytes for a single item */ + pb_size_t array_size; /* Maximum number of entries in array */ + + /* Field definitions for submessage + * OR default value for all other non-array, non-callback types + * If null, then field will zeroed. */ + const void *ptr; +} pb_packed; +PB_PACKED_STRUCT_END + +/* Make sure that the standard integer types are of the expected sizes. + * Otherwise fixed32/fixed64 fields can break. + * + * If you get errors here, it probably means that your stdint.h is not + * correct for your platform. + */ +#ifndef PB_WITHOUT_64BIT +PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) +#endif + +/* This structure is used for 'bytes' arrays. + * It has the number of bytes in the beginning, and after that an array. + * Note that actual structs used will have a different length of bytes array. + */ +#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } +#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) + +struct pb_bytes_array_s { + pb_size_t size; + pb_byte_t bytes[1]; +}; +typedef struct pb_bytes_array_s pb_bytes_array_t; + +/* This structure is used for giving the callback function. + * It is stored in the message structure and filled in by the method that + * calls pb_decode. + * + * The decoding callback will be given a limited-length stream + * If the wire type was string, the length is the length of the string. + * If the wire type was a varint/fixed32/fixed64, the length is the length + * of the actual value. + * The function may be called multiple times (especially for repeated types, + * but also otherwise if the message happens to contain the field multiple + * times.) + * + * The encoding callback will receive the actual output stream. + * It should write all the data in one call, including the field tag and + * wire type. It can write multiple fields. + * + * The callback can be null if you want to skip a field. + */ +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_callback_s pb_callback_t; +struct pb_callback_s { +#ifdef PB_OLD_CALLBACK_STYLE + /* Deprecated since nanopb-0.2.1 */ + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg); + } funcs; +#else + /* New function signature, which allows modifying arg contents in callback. */ + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); + } funcs; +#endif + + /* Free arg for use by callback */ + void *arg; +}; + +/* Wire types. Library user needs these only in encoder callbacks. */ +typedef enum { + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5 +} pb_wire_type_t; + +/* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. + */ +typedef struct pb_extension_type_s pb_extension_type_t; +typedef struct pb_extension_s pb_extension_t; +struct pb_extension_type_s { + /* Called for each unknown field in the message. + * If you handle the field, read off all of its data and return true. + * If you do not handle the field, do not read anything and return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, + uint32_t tag, pb_wire_type_t wire_type); + + /* Called once after all regular fields have been encoded. + * If you have something to write, do so and return true. + * If you do not have anything to write, just return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + + /* Free field for use by the callback. */ + const void *arg; +}; + +struct pb_extension_s { + /* Type describing the extension field. Usually you'll initialize + * this to a pointer to the automatically generated structure. */ + const pb_extension_type_t *type; + + /* Destination for the decoded data. This must match the datatype + * of the extension field. */ + void *dest; + + /* Pointer to the next extension handler, or NULL. + * If this extension does not match a field, the next handler is + * automatically called. */ + pb_extension_t *next; + + /* The decoder sets this to true if the extension was found. + * Ignored for encoding. */ + bool found; +}; + +/* Memory allocation functions to use. You can define pb_realloc and + * pb_free to custom functions if you want. */ +#ifdef PB_ENABLE_MALLOC +# ifndef pb_realloc +# define pb_realloc(ptr, size) realloc(ptr, size) +# endif +# ifndef pb_free +# define pb_free(ptr) free(ptr) +# endif +#endif + +/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ +#define PB_PROTO_HEADER_VERSION 30 + +/* These macros are used to declare pb_field_t's in the constant array. */ +/* Size of a structure member, in bytes. */ +#define pb_membersize(st, m) (sizeof ((st*)0)->m) +/* Number of entries in an array. */ +#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) +/* Delta from start of one member to the start of another member. */ +#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) +/* Marks the end of the field list */ +#define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0} + +/* Macros for filling in the data_offset field */ +/* data_offset for first field in a message */ +#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1)) +/* data_offset for subsequent fields */ +#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2)) +/* data offset for subsequent fields inside an union (oneof) */ +#define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX) +/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */ +#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \ + ? PB_DATAOFFSET_FIRST(st, m1, m2) \ + : PB_DATAOFFSET_OTHER(st, m1, m2)) + +/* Required fields are the simplest. They just have delta (padding) from + * previous field end, and the size of the field. Pointer is used for + * submessages and default values. + */ +#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +/* Optional fields add the delta to the has_ variable. */ +#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ + fd, \ + pb_delta(st, has_ ## m, m), \ + pb_membersize(st, m), 0, ptr} + +#define PB_SINGULAR_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +/* Repeated fields have a _count field and also the maximum number of entries. */ +#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \ + fd, \ + pb_delta(st, m ## _count, m), \ + pb_membersize(st, m[0]), \ + pb_arraysize(st, m), ptr} + +/* Allocated fields carry the size of the actual data, not the pointer */ +#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \ + fd, 0, pb_membersize(st, m[0]), 0, ptr} + +/* Optional fields don't need a has_ variable, as information would be redundant */ +#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m[0]), 0, ptr} + +/* Same as optional fields*/ +#define PB_SINGULAR_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m[0]), 0, ptr} + +/* Repeated fields have a _count field and a pointer to array of pointers */ +#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \ + fd, pb_delta(st, m ## _count, m), \ + pb_membersize(st, m[0]), 0, ptr} + +/* Callbacks are much like required fields except with special datatype. */ +#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +#define PB_SINGULAR_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +/* Optional extensions don't have the has_ field, as that would be redundant. + * Furthermore, the combination of OPTIONAL without has_ field is used + * for indicating proto3 style fields. Extensions exist in proto2 mode only, + * so they should be encoded according to proto2 rules. To avoid the conflict, + * extensions are marked as REQUIRED instead. + */ +#define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ + 0, \ + 0, \ + pb_membersize(st, m), 0, ptr} + +#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \ + PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) + +#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \ + PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) + +/* The mapping from protobuf types to LTYPEs is done using these macros. */ +#define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT +#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION +#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES + +/* This is the actual macro used in field descriptions. + * It takes these arguments: + * - Field tag number + * - Field type: BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64, + * FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64 + * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION + * - Field rules: REQUIRED, OPTIONAL or REPEATED + * - Allocation: STATIC, CALLBACK or POINTER + * - Placement: FIRST or OTHER, depending on if this is the first field in structure. + * - Message name + * - Field name + * - Previous field name (or field name again for first field) + * - Pointer to default value or submsg fields. + */ + +#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ + PB_ ## rules ## _ ## allocation(tag, message, field, \ + PB_DATAOFFSET_ ## placement(message, field, prevfield), \ + PB_LTYPE_MAP_ ## type, ptr) + +/* Field description for oneof fields. This requires taking into account the + * union name also, that's why a separate set of macros is needed. + */ +#define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, u.m), \ + pb_membersize(st, u.m), 0, ptr} + +#define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, u.m), \ + pb_membersize(st, u.m[0]), 0, ptr} + +#define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ + PB_ONEOF_ ## allocation(union_name, tag, message, field, \ + PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \ + PB_LTYPE_MAP_ ## type, ptr) + +#define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, m), \ + pb_membersize(st, m), 0, ptr} + +#define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, m), \ + pb_membersize(st, m[0]), 0, ptr} + +#define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ + PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \ + PB_DATAOFFSET_ ## placement(message, field, prevfield), \ + PB_LTYPE_MAP_ ## type, ptr) + +/* These macros are used for giving out error messages. + * They are mostly a debugging aid; the main error information + * is the true/false return value from functions. + * Some code space can be saved by disabling the error + * messages if not used. + * + * PB_SET_ERROR() sets the error message if none has been set yet. + * msg must be a constant string literal. + * PB_GET_ERROR() always returns a pointer to a string. + * PB_RETURN_ERROR() sets the error and returns false from current + * function. + */ +#ifdef PB_NO_ERRMSG +#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) +#define PB_GET_ERROR(stream) "(errmsg disabled)" +#else +#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) +#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") +#endif + +#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false + +#endif diff --git a/hardware-wallet/firmware/vendor/nanopb/pb_common.c b/hardware-wallet/firmware/vendor/nanopb/pb_common.c new file mode 100644 index 00000000..4fb7186b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/pb_common.c @@ -0,0 +1,97 @@ +/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. + * + * 2014 Petteri Aimonen + */ + +#include "pb_common.h" + +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct) +{ + iter->start = fields; + iter->pos = fields; + iter->required_field_index = 0; + iter->dest_struct = dest_struct; + iter->pData = (char*)dest_struct + iter->pos->data_offset; + iter->pSize = (char*)iter->pData + iter->pos->size_offset; + + return (iter->pos->tag != 0); +} + +bool pb_field_iter_next(pb_field_iter_t *iter) +{ + const pb_field_t *prev_field = iter->pos; + + if (prev_field->tag == 0) + { + /* Handle empty message types, where the first field is already the terminator. + * In other cases, the iter->pos never points to the terminator. */ + return false; + } + + iter->pos++; + + if (iter->pos->tag == 0) + { + /* Wrapped back to beginning, reinitialize */ + (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct); + return false; + } + else + { + /* Increment the pointers based on previous field size */ + size_t prev_size = prev_field->data_size; + + if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF && + PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF && + iter->pos->data_offset == PB_SIZE_MAX) + { + /* Don't advance pointers inside unions */ + return true; + } + else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC && + PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED) + { + /* In static arrays, the data_size tells the size of a single entry and + * array_size is the number of entries */ + prev_size *= prev_field->array_size; + } + else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER) + { + /* Pointer fields always have a constant size in the main structure. + * The data_size only applies to the dynamically allocated area. */ + prev_size = sizeof(void*); + } + + if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED) + { + /* Count the required fields, in order to check their presence in the + * decoder. */ + iter->required_field_index++; + } + + iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset; + iter->pSize = (char*)iter->pData + iter->pos->size_offset; + return true; + } +} + +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) +{ + const pb_field_t *start = iter->pos; + + do { + if (iter->pos->tag == tag && + PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION) + { + /* Found the wanted field */ + return true; + } + + (void)pb_field_iter_next(iter); + } while (iter->pos != start); + + /* Searched all the way back to start, and found nothing. */ + return false; +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/pb_common.h b/hardware-wallet/firmware/vendor/nanopb/pb_common.h new file mode 100644 index 00000000..60b3d374 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/pb_common.h @@ -0,0 +1,42 @@ +/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. + * These functions are rarely needed by applications directly. + */ + +#ifndef PB_COMMON_H_INCLUDED +#define PB_COMMON_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Iterator for pb_field_t list */ +struct pb_field_iter_s { + const pb_field_t *start; /* Start of the pb_field_t array */ + const pb_field_t *pos; /* Current position of the iterator */ + unsigned required_field_index; /* Zero-based index that counts only the required fields */ + void *dest_struct; /* Pointer to start of the structure */ + void *pData; /* Pointer to current field value */ + void *pSize; /* Pointer to count/has field */ +}; +typedef struct pb_field_iter_s pb_field_iter_t; + +/* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct); + +/* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ +bool pb_field_iter_next(pb_field_iter_t *iter); + +/* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/hardware-wallet/firmware/vendor/nanopb/pb_decode.c b/hardware-wallet/firmware/vendor/nanopb/pb_decode.c new file mode 100644 index 00000000..dc344dc7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/pb_decode.c @@ -0,0 +1,1458 @@ +/* pb_decode.c -- decode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +#include "pb.h" +#include "pb_decode.h" +#include "pb_common.h" + +/************************************** + * Declarations internal to this file * + **************************************/ + +typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension); +static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn find_extension_field(pb_field_iter_t *iter); +static void pb_field_set_to_default(pb_field_iter_t *iter); +static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct); +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof); +static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_skip_varint(pb_istream_t *stream); +static bool checkreturn pb_skip_string(pb_istream_t *stream); + +#ifdef PB_ENABLE_MALLOC +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); +static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter); +static void pb_release_single_field(const pb_field_iter_t *iter); +#endif + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +/* --- Function pointers to field decoders --- + * Order in the array must match pb_action_t LTYPE numbering. + */ +static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { + &pb_dec_varint, + &pb_dec_uvarint, + &pb_dec_svarint, + &pb_dec_fixed32, + &pb_dec_fixed64, + + &pb_dec_bytes, + &pb_dec_string, + &pb_dec_submessage, + NULL, /* extensions */ + &pb_dec_fixed_length_bytes +}; + +/******************************* + * pb_istream_t implementation * + *******************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ + size_t i; + const pb_byte_t *source = (const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + count; + + if (buf != NULL) + { + for (i = 0; i < count; i++) + buf[i] = source[i]; + } + + return true; +} + +bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ +#ifndef PB_BUFFER_ONLY + if (buf == NULL && stream->callback != buf_read) + { + /* Skip input bytes */ + pb_byte_t tmp[16]; + while (count > 16) + { + if (!pb_read(stream, tmp, 16)) + return false; + + count -= 16; + } + + return pb_read(stream, tmp, count); + } +#endif + + if (stream->bytes_left < count) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!buf_read(stream, buf, count)) + return false; +#endif + + stream->bytes_left -= count; + return true; +} + +/* Read a single byte from input stream. buf may not be NULL. + * This is an optimization for the varint decoding. */ +static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) +{ + if (stream->bytes_left == 0) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, 1)) + PB_RETURN_ERROR(stream, "io error"); +#else + *buf = *(const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + 1; +#endif + + stream->bytes_left--; + + return true; +} + +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize) +{ + pb_istream_t stream; + /* Cast away the const from buf without a compiler error. We are + * careful to use it only in a const manner in the callbacks. + */ + union { + void *state; + const void *c_state; + } state; +#ifdef PB_BUFFER_ONLY + stream.callback = NULL; +#else + stream.callback = &buf_read; +#endif + state.c_state = buf; + stream.state = state.state; + stream.bytes_left = bufsize; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +/******************** + * Helper functions * + ********************/ + +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof) +{ + pb_byte_t byte; + uint32_t result; + + if (!pb_readbyte(stream, &byte)) + { + if (stream->bytes_left == 0) + { + if (eof) + { + *eof = true; + } + } + + return false; + } + + if ((byte & 0x80) == 0) + { + /* Quick case, 1 byte value */ + result = byte; + } + else + { + /* Multibyte case */ + uint_fast8_t bitpos = 7; + result = byte & 0x7F; + + do + { + if (!pb_readbyte(stream, &byte)) + return false; + + if (bitpos >= 32) + { + /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */ + uint8_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; + + if ((byte & 0x7F) != 0x00 && ((result >> 31) == 0 || byte != sign_extension)) + { + PB_RETURN_ERROR(stream, "varint overflow"); + } + } + else + { + result |= (uint32_t)(byte & 0x7F) << bitpos; + } + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + if (bitpos == 35 && (byte & 0x70) != 0) + { + /* The last byte was at bitpos=28, so only bottom 4 bits fit. */ + PB_RETURN_ERROR(stream, "varint overflow"); + } + } + + *dest = result; + return true; +} + +bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) +{ + return pb_decode_varint32_eof(stream, dest, NULL); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) +{ + pb_byte_t byte; + uint_fast8_t bitpos = 0; + uint64_t result = 0; + + do + { + if (bitpos >= 64) + PB_RETURN_ERROR(stream, "varint overflow"); + + if (!pb_readbyte(stream, &byte)) + return false; + + result |= (uint64_t)(byte & 0x7F) << bitpos; + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + *dest = result; + return true; +} +#endif + +bool checkreturn pb_skip_varint(pb_istream_t *stream) +{ + pb_byte_t byte; + do + { + if (!pb_read(stream, &byte, 1)) + return false; + } while (byte & 0x80); + return true; +} + +bool checkreturn pb_skip_string(pb_istream_t *stream) +{ + uint32_t length; + if (!pb_decode_varint32(stream, &length)) + return false; + + return pb_read(stream, NULL, length); +} + +bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) +{ + uint32_t temp; + *eof = false; + *wire_type = (pb_wire_type_t) 0; + *tag = 0; + + if (!pb_decode_varint32_eof(stream, &temp, eof)) + { + return false; + } + + if (temp == 0) + { + *eof = true; /* Special feature: allow 0-terminated messages. */ + return false; + } + + *tag = temp >> 3; + *wire_type = (pb_wire_type_t)(temp & 7); + return true; +} + +bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) +{ + switch (wire_type) + { + case PB_WT_VARINT: return pb_skip_varint(stream); + case PB_WT_64BIT: return pb_read(stream, NULL, 8); + case PB_WT_STRING: return pb_skip_string(stream); + case PB_WT_32BIT: return pb_read(stream, NULL, 4); + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Read a raw value to buffer, for the purpose of passing it to callback as + * a substream. Size is maximum size on call, and actual size on return. + */ +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) +{ + size_t max_size = *size; + switch (wire_type) + { + case PB_WT_VARINT: + *size = 0; + do + { + (*size)++; + if (*size > max_size) return false; + if (!pb_read(stream, buf, 1)) return false; + } while (*buf++ & 0x80); + return true; + + case PB_WT_64BIT: + *size = 8; + return pb_read(stream, buf, 8); + + case PB_WT_32BIT: + *size = 4; + return pb_read(stream, buf, 4); + + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Decode string length from stream and return a substream with limited length. + * Remember to close the substream using pb_close_string_substream(). + */ +bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + uint32_t size; + if (!pb_decode_varint32(stream, &size)) + return false; + + *substream = *stream; + if (substream->bytes_left < size) + PB_RETURN_ERROR(stream, "parent stream too short"); + + substream->bytes_left = size; + stream->bytes_left -= size; + return true; +} + +bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + if (substream->bytes_left) { + if (!pb_read(substream, NULL, substream->bytes_left)) + return false; + } + + stream->state = substream->state; + +#ifndef PB_NO_ERRMSG + stream->errmsg = substream->errmsg; +#endif + return true; +} + +/************************* + * Decode a single field * + *************************/ + +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ + pb_type_t type; + pb_decoder_t func; + + type = iter->pos->type; + func = PB_DECODERS[PB_LTYPE(type)]; + + switch (PB_HTYPE(type)) + { + case PB_HTYPE_REQUIRED: + return func(stream, iter->pos, iter->pData); + + case PB_HTYPE_OPTIONAL: + if (iter->pSize != iter->pData) + *(bool*)iter->pSize = true; + return func(stream, iter->pos, iter->pData); + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array */ + bool status = true; + pb_size_t *size = (pb_size_t*)iter->pSize; + pb_istream_t substream; + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left > 0 && *size < iter->pos->array_size) + { + void *pItem = (char*)iter->pData + iter->pos->data_size * (*size); + if (!func(&substream, iter->pos, pItem)) + { + status = false; + break; + } + (*size)++; + } + + if (substream.bytes_left != 0) + PB_RETURN_ERROR(stream, "array overflow"); + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Repeated field */ + pb_size_t *size = (pb_size_t*)iter->pSize; + void *pItem = (char*)iter->pData + iter->pos->data_size * (*size); + if (*size >= iter->pos->array_size) + PB_RETURN_ERROR(stream, "array overflow"); + + (*size)++; + return func(stream, iter->pos, pItem); + } + + case PB_HTYPE_ONEOF: + *(pb_size_t*)iter->pSize = iter->pos->tag; + if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) + { + /* We memset to zero so that any callbacks are set to NULL. + * Then set any default values. */ + memset(iter->pData, 0, iter->pos->data_size); + pb_message_set_to_defaults((const pb_field_t*)iter->pos->ptr, iter->pData); + } + return func(stream, iter->pos, iter->pData); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +#ifdef PB_ENABLE_MALLOC +/* Allocate storage for the field and store the pointer at iter->pData. + * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. + */ +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) +{ + void *ptr = *(void**)pData; + + if (data_size == 0 || array_size == 0) + PB_RETURN_ERROR(stream, "invalid size"); + + /* Check for multiplication overflows. + * This code avoids the costly division if the sizes are small enough. + * Multiplication is safe as long as only half of bits are set + * in either multiplicand. + */ + { + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); + if (data_size >= check_limit || array_size >= check_limit) + { + const size_t size_max = (size_t)-1; + if (size_max / array_size < data_size) + { + PB_RETURN_ERROR(stream, "size too large"); + } + } + } + + /* Allocate new or expand previous allocation */ + /* Note: on failure the old pointer will remain in the structure, + * the message must be freed by caller also on error return. */ + ptr = pb_realloc(ptr, array_size * data_size); + if (ptr == NULL) + PB_RETURN_ERROR(stream, "realloc failed"); + + *(void**)pData = ptr; + return true; +} + +/* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ +static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter) +{ + if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING || + PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) + { + *(void**)pItem = NULL; + } + else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) + { + /* We memset to zero so that any callbacks are set to NULL. + * Then set any default values. */ + memset(pItem, 0, iter->pos->data_size); + pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, pItem); + } +} +#endif + +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +#ifndef PB_ENABLE_MALLOC + PB_UNUSED(wire_type); + PB_UNUSED(iter); + PB_RETURN_ERROR(stream, "no malloc support"); +#else + pb_type_t type; + pb_decoder_t func; + + type = iter->pos->type; + func = PB_DECODERS[PB_LTYPE(type)]; + + switch (PB_HTYPE(type)) + { + case PB_HTYPE_REQUIRED: + case PB_HTYPE_OPTIONAL: + case PB_HTYPE_ONEOF: + if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && + *(void**)iter->pData != NULL) + { + /* Duplicate field, have to release the old allocation first. */ + pb_release_single_field(iter); + } + + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)iter->pSize = iter->pos->tag; + } + + if (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES) + { + return func(stream, iter->pos, iter->pData); + } + else + { + if (!allocate_field(stream, iter->pData, iter->pos->data_size, 1)) + return false; + + initialize_pointer_field(*(void**)iter->pData, iter); + return func(stream, iter->pos, *(void**)iter->pData); + } + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array, multiple items come in at once. */ + bool status = true; + pb_size_t *size = (pb_size_t*)iter->pSize; + size_t allocated_size = *size; + void *pItem; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left) + { + if ((size_t)*size + 1 > allocated_size) + { + /* Allocate more storage. This tries to guess the + * number of remaining entries. Round the division + * upwards. */ + allocated_size += (substream.bytes_left - 1) / iter->pos->data_size + 1; + + if (!allocate_field(&substream, iter->pData, iter->pos->data_size, allocated_size)) + { + status = false; + break; + } + } + + /* Decode the array entry */ + pItem = *(char**)iter->pData + iter->pos->data_size * (*size); + initialize_pointer_field(pItem, iter); + if (!func(&substream, iter->pos, pItem)) + { + status = false; + break; + } + + if (*size == PB_SIZE_MAX) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = "too many array entries"; +#endif + status = false; + break; + } + + (*size)++; + } + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Normal repeated field, i.e. only one item at a time. */ + pb_size_t *size = (pb_size_t*)iter->pSize; + void *pItem; + + if (*size == PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "too many array entries"); + + (*size)++; + if (!allocate_field(stream, iter->pData, iter->pos->data_size, *size)) + return false; + + pItem = *(char**)iter->pData + iter->pos->data_size * (*size - 1); + initialize_pointer_field(pItem, iter); + return func(stream, iter->pos, pItem); + } + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +#endif +} + +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ + pb_callback_t *pCallback = (pb_callback_t*)iter->pData; + +#ifdef PB_OLD_CALLBACK_STYLE + void *arg = pCallback->arg; +#else + void **arg = &(pCallback->arg); +#endif + + if (pCallback == NULL || pCallback->funcs.decode == NULL) + return pb_skip_field(stream, wire_type); + + if (wire_type == PB_WT_STRING) + { + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + do + { + if (!pCallback->funcs.decode(&substream, iter->pos, arg)) + PB_RETURN_ERROR(stream, "callback failed"); + } while (substream.bytes_left); + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return true; + } + else + { + /* Copy the single scalar value to stack. + * This is required so that we can limit the stream length, + * which in turn allows to use same callback for packed and + * not-packed fields. */ + pb_istream_t substream; + pb_byte_t buffer[10]; + size_t size = sizeof(buffer); + + if (!read_raw_value(stream, wire_type, buffer, &size)) + return false; + substream = pb_istream_from_buffer(buffer, size); + + return pCallback->funcs.decode(&substream, iter->pos, arg); + } +} + +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +#ifdef PB_ENABLE_MALLOC + /* When decoding an oneof field, check if there is old data that must be + * released first. */ + if (PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF) + { + if (!pb_release_union_field(stream, iter)) + return false; + } +#endif + + switch (PB_ATYPE(iter->pos->type)) + { + case PB_ATYPE_STATIC: + return decode_static_field(stream, wire_type, iter); + + case PB_ATYPE_POINTER: + return decode_pointer_field(stream, wire_type, iter); + + case PB_ATYPE_CALLBACK: + return decode_callback_field(stream, wire_type, iter); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension) +{ + /* Fake a field iterator for the extension field. + * It is not actually safe to advance this iterator, but decode_field + * will not even try to. */ + const pb_field_t *field = (const pb_field_t*)extension->type->arg; + (void)pb_field_iter_begin(iter, field, extension->dest); + iter->pData = extension->dest; + iter->pSize = &extension->found; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + iter->pData = &extension->dest; + } +} + +/* Default handler for extension fields. Expects a pb_field_t structure + * in extension->type->arg. */ +static bool checkreturn default_extension_decoder(pb_istream_t *stream, + pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) +{ + const pb_field_t *field = (const pb_field_t*)extension->type->arg; + pb_field_iter_t iter; + + if (field->tag != tag) + return true; + + iter_from_extension(&iter, extension); + extension->found = true; + return decode_field(stream, wire_type, &iter); +} + +/* Try to decode an unknown field as an extension field. Tries each extension + * decoder in turn, until one of them handles the field or loop ends. */ +static bool checkreturn decode_extension(pb_istream_t *stream, + uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ + pb_extension_t *extension = *(pb_extension_t* const *)iter->pData; + size_t pos = stream->bytes_left; + + while (extension != NULL && pos == stream->bytes_left) + { + bool status; + if (extension->type->decode) + status = extension->type->decode(stream, extension, tag, wire_type); + else + status = default_extension_decoder(stream, extension, tag, wire_type); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/* Step through the iterator until an extension field is found or until all + * entries have been checked. There can be only one extension field per + * message. Returns false if no extension field is found. */ +static bool checkreturn find_extension_field(pb_field_iter_t *iter) +{ + const pb_field_t *start = iter->pos; + + do { + if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION) + return true; + (void)pb_field_iter_next(iter); + } while (iter->pos != start); + + return false; +} + +/* Initialize message fields to default values, recursively */ +static void pb_field_set_to_default(pb_field_iter_t *iter) +{ + pb_type_t type; + type = iter->pos->type; + + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + pb_extension_t *ext = *(pb_extension_t* const *)iter->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + ext->found = false; + iter_from_extension(&ext_iter, ext); + pb_field_set_to_default(&ext_iter); + ext = ext->next; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + bool init_data = true; + if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && iter->pSize != iter->pData) + { + /* Set has_field to false. Still initialize the optional field + * itself also. */ + *(bool*)iter->pSize = false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* REPEATED: Set array count to 0, no need to initialize contents. + ONEOF: Set which_field to 0. */ + *(pb_size_t*)iter->pSize = 0; + init_data = false; + } + + if (init_data) + { + if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) + { + /* Initialize submessage to defaults */ + pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, iter->pData); + } + else if (iter->pos->ptr != NULL) + { + /* Initialize to default value */ + memcpy(iter->pData, iter->pos->ptr, iter->pos->data_size); + } + else + { + /* Initialize to zeros */ + memset(iter->pData, 0, iter->pos->data_size); + } + } + } + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + /* Initialize the pointer to NULL. */ + *(void**)iter->pData = NULL; + + /* Initialize array count to 0. */ + if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)iter->pSize = 0; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) + { + /* Don't overwrite callback */ + } +} + +static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct) +{ + pb_field_iter_t iter; + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do + { + pb_field_set_to_default(&iter); + } while (pb_field_iter_next(&iter)); +} + +/********************* + * Decode all fields * + *********************/ + +bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + uint32_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 31) / 32] = {0, 0}; + const uint32_t allbits = ~(uint32_t)0; + uint32_t extension_range_start = 0; + pb_field_iter_t iter; + + /* Return value ignored, as empty message types will be correctly handled by + * pb_field_iter_find() anyway. */ + (void)pb_field_iter_begin(&iter, fields, dest_struct); + + while (stream->bytes_left) + { + uint32_t tag; + pb_wire_type_t wire_type; + bool eof; + + if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) + { + if (eof) + break; + else + return false; + } + + if (!pb_field_iter_find(&iter, tag)) + { + /* No match found, check if it matches an extension. */ + if (tag >= extension_range_start) + { + if (!find_extension_field(&iter)) + extension_range_start = (uint32_t)-1; + else + extension_range_start = iter.pos->tag; + + if (tag >= extension_range_start) + { + size_t pos = stream->bytes_left; + + if (!decode_extension(stream, tag, wire_type, &iter)) + return false; + + if (pos != stream->bytes_left) + { + /* The field was handled */ + continue; + } + } + } + + /* No match found, skip data */ + if (!pb_skip_field(stream, wire_type)) + return false; + continue; + } + + if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED + && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) + { + uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); + fields_seen[iter.required_field_index >> 5] |= tmp; + } + + if (!decode_field(stream, wire_type, &iter)) + return false; + } + + /* Check that all required fields were present. */ + { + /* First figure out the number of required fields by + * seeking to the end of the field array. Usually we + * are already close to end after decoding. + */ + unsigned req_field_count; + pb_type_t last_type; + unsigned i; + do { + req_field_count = iter.required_field_index; + last_type = iter.pos->type; + } while (pb_field_iter_next(&iter)); + + /* Fixup if last field was also required. */ + if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0) + req_field_count++; + + if (req_field_count > PB_MAX_REQUIRED_FIELDS) + req_field_count = PB_MAX_REQUIRED_FIELDS; + + if (req_field_count > 0) + { + /* Check the whole words */ + for (i = 0; i < (req_field_count >> 5); i++) + { + if (fields_seen[i] != allbits) + PB_RETURN_ERROR(stream, "missing required field"); + } + + /* Check the remaining bits (if any) */ + if ((req_field_count & 31) != 0) + { + if (fields_seen[req_field_count >> 5] != + (allbits >> (32 - (req_field_count & 31)))) + { + PB_RETURN_ERROR(stream, "missing required field"); + } + } + } + } + + return true; +} + +bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + bool status; + pb_message_set_to_defaults(fields, dest_struct); + status = pb_decode_noinit(stream, fields, dest_struct); + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; +} + +bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + pb_istream_t substream; + bool status; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode_noinit(&substream, fields, dest_struct); + + if (!pb_close_string_substream(stream, &substream)) + return false; + return status; +} + +bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + pb_istream_t substream; + bool status; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode(&substream, fields, dest_struct); + + if (!pb_close_string_substream(stream, &substream)) + return false; + return status; +} + +bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + /* This behaviour will be separated in nanopb-0.4.0, see issue #278. */ + return pb_decode(stream, fields, dest_struct); +} + +#ifdef PB_ENABLE_MALLOC +/* Given an oneof field, if there has already been a field inside this oneof, + * release it before overwriting with a different one. */ +static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter) +{ + pb_size_t old_tag = *(pb_size_t*)iter->pSize; /* Previous which_ value */ + pb_size_t new_tag = iter->pos->tag; /* New which_ value */ + + if (old_tag == 0) + return true; /* Ok, no old data in union */ + + if (old_tag == new_tag) + return true; /* Ok, old data is of same type => merge */ + + /* Release old data. The find can fail if the message struct contains + * invalid data. */ + if (!pb_field_iter_find(iter, old_tag)) + PB_RETURN_ERROR(stream, "invalid union tag"); + + pb_release_single_field(iter); + + /* Restore iterator to where it should be. + * This shouldn't fail unless the pb_field_t structure is corrupted. */ + if (!pb_field_iter_find(iter, new_tag)) + PB_RETURN_ERROR(stream, "iterator error"); + + return true; +} + +static void pb_release_single_field(const pb_field_iter_t *iter) +{ + pb_type_t type; + type = iter->pos->type; + + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + if (*(pb_size_t*)iter->pSize != iter->pos->tag) + return; /* This is not the current field in the union */ + } + + /* Release anything contained inside an extension or submsg. + * This has to be done even if the submsg itself is statically + * allocated. */ + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + /* Release fields from all extensions in the linked list */ + pb_extension_t *ext = *(pb_extension_t**)iter->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + iter_from_extension(&ext_iter, ext); + pb_release_single_field(&ext_iter); + ext = ext->next; + } + } + else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) + { + /* Release fields in submessage or submsg array */ + void *pItem = iter->pData; + pb_size_t count = 1; + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + pItem = *(void**)iter->pData; + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + count = *(pb_size_t*)iter->pSize; + + if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > iter->pos->array_size) + { + /* Protect against corrupted _count fields */ + count = iter->pos->array_size; + } + } + + if (pItem) + { + while (count--) + { + pb_release((const pb_field_t*)iter->pos->ptr, pItem); + pItem = (char*)pItem + iter->pos->data_size; + } + } + } + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && + (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES)) + { + /* Release entries in repeated string or bytes array */ + void **pItem = *(void***)iter->pData; + pb_size_t count = *(pb_size_t*)iter->pSize; + while (count--) + { + pb_free(*pItem); + *pItem++ = NULL; + } + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* We are going to release the array, so set the size to 0 */ + *(pb_size_t*)iter->pSize = 0; + } + + /* Release main item */ + pb_free(*(void**)iter->pData); + *(void**)iter->pData = NULL; + } +} + +void pb_release(const pb_field_t fields[], void *dest_struct) +{ + pb_field_iter_t iter; + + if (!dest_struct) + return; /* Ignore NULL pointers, similar to free() */ + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do + { + pb_release_single_field(&iter); + } while (pb_field_iter_next(&iter)); +} +#endif + +/* Field decoders */ + +bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) +{ + pb_uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + if (value & 1) + *dest = (pb_int64_t)(~(value >> 1)); + else + *dest = (pb_int64_t)(value >> 1); + + return true; +} + +bool pb_decode_fixed32(pb_istream_t *stream, void *dest) +{ + pb_byte_t bytes[4]; + + if (!pb_read(stream, bytes, 4)) + return false; + + *(uint32_t*)dest = ((uint32_t)bytes[0] << 0) | + ((uint32_t)bytes[1] << 8) | + ((uint32_t)bytes[2] << 16) | + ((uint32_t)bytes[3] << 24); + return true; +} + +#ifndef PB_WITHOUT_64BIT +bool pb_decode_fixed64(pb_istream_t *stream, void *dest) +{ + pb_byte_t bytes[8]; + + if (!pb_read(stream, bytes, 8)) + return false; + + *(uint64_t*)dest = ((uint64_t)bytes[0] << 0) | + ((uint64_t)bytes[1] << 8) | + ((uint64_t)bytes[2] << 16) | + ((uint64_t)bytes[3] << 24) | + ((uint64_t)bytes[4] << 32) | + ((uint64_t)bytes[5] << 40) | + ((uint64_t)bytes[6] << 48) | + ((uint64_t)bytes[7] << 56); + + return true; +} +#endif + +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + pb_uint64_t value; + pb_int64_t svalue; + pb_int64_t clamped; + if (!pb_decode_varint(stream, &value)) + return false; + + /* See issue 97: Google's C++ protobuf allows negative varint values to + * be cast as int32_t, instead of the int64_t that should be used when + * encoding. Previous nanopb versions had a bug in encoding. In order to + * not break decoding of such messages, we cast <=32 bit fields to + * int32_t first to get the sign correct. + */ + if (field->data_size == sizeof(pb_int64_t)) + svalue = (pb_int64_t)value; + else + svalue = (int32_t)value; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_int64_t)) + clamped = *(pb_int64_t*)dest = svalue; + else if (field->data_size == sizeof(int32_t)) + clamped = *(int32_t*)dest = (int32_t)svalue; + else if (field->data_size == sizeof(int_least16_t)) + clamped = *(int_least16_t*)dest = (int_least16_t)svalue; + else if (field->data_size == sizeof(int_least8_t)) + clamped = *(int_least8_t*)dest = (int_least8_t)svalue; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != svalue) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; +} + +static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + pb_uint64_t value, clamped; + if (!pb_decode_varint(stream, &value)) + return false; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_uint64_t)) + clamped = *(pb_uint64_t*)dest = value; + else if (field->data_size == sizeof(uint32_t)) + clamped = *(uint32_t*)dest = (uint32_t)value; + else if (field->data_size == sizeof(uint_least16_t)) + clamped = *(uint_least16_t*)dest = (uint_least16_t)value; + else if (field->data_size == sizeof(uint_least8_t)) + clamped = *(uint_least8_t*)dest = (uint_least8_t)value; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != value) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; +} + +static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + pb_int64_t value, clamped; + if (!pb_decode_svarint(stream, &value)) + return false; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_int64_t)) + clamped = *(pb_int64_t*)dest = value; + else if (field->data_size == sizeof(int32_t)) + clamped = *(int32_t*)dest = (int32_t)value; + else if (field->data_size == sizeof(int_least16_t)) + clamped = *(int_least16_t*)dest = (int_least16_t)value; + else if (field->data_size == sizeof(int_least8_t)) + clamped = *(int_least8_t*)dest = (int_least8_t)value; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != value) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; +} + +static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + PB_UNUSED(field); + return pb_decode_fixed32(stream, dest); +} + +static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + PB_UNUSED(field); +#ifndef PB_WITHOUT_64BIT + return pb_decode_fixed64(stream, dest); +#else + PB_UNUSED(dest); + PB_RETURN_ERROR(stream, "no 64bit support"); +#endif +} + +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + size_t alloc_size; + pb_bytes_array_t *bdest; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); + if (size > alloc_size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (!allocate_field(stream, dest, alloc_size, 1)) + return false; + bdest = *(pb_bytes_array_t**)dest; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "bytes overflow"); + bdest = (pb_bytes_array_t*)dest; + } + + bdest->size = (pb_size_t)size; + return pb_read(stream, bdest->bytes, size); +} + +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + size_t alloc_size; + bool status; + if (!pb_decode_varint32(stream, &size)) + return false; + + /* Space for null terminator */ + alloc_size = size + 1; + + if (alloc_size < size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (!allocate_field(stream, dest, alloc_size, 1)) + return false; + dest = *(void**)dest; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "string overflow"); + } + + status = pb_read(stream, (pb_byte_t*)dest, size); + *((pb_byte_t*)dest + size) = 0; + return status; +} + +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + bool status; + pb_istream_t substream; + const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + if (field->ptr == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + /* New array entries need to be initialized, while required and optional + * submessages have already been initialized in the top-level pb_decode. */ + if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) + status = pb_decode(&substream, submsg_fields, dest); + else + status = pb_decode_noinit(&substream, submsg_fields, dest); + + if (!pb_close_string_substream(stream, &substream)) + return false; + return status; +} + +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + if (size == 0) + { + /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ + memset(dest, 0, field->data_size); + return true; + } + + if (size != field->data_size) + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); + + return pb_read(stream, (pb_byte_t*)dest, field->data_size); +} diff --git a/hardware-wallet/firmware/vendor/nanopb/pb_decode.h b/hardware-wallet/firmware/vendor/nanopb/pb_decode.h new file mode 100644 index 00000000..398b24a0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/pb_decode.h @@ -0,0 +1,175 @@ +/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. + * The main function is pb_decode. You also need an input stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_DECODE_H_INCLUDED +#define PB_DECODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom input streams. You will need to provide + * a callback function to read the bytes from your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause decoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer), + * and rely on pb_read to verify that no-body reads past bytes_left. + * 3) Your callback may be used with substreams, in which case bytes_left + * is different than from the main stream. Don't use bytes_left to compute + * any pointers. + */ +struct pb_istream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + */ + int *callback; +#else + bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); +#endif + + void *state; /* Free field for use by callback implementation */ + size_t bytes_left; + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +/*************************** + * Main decoding functions * + ***************************/ + +/* Decode a single protocol buffers message from input stream into a C structure. + * Returns true on success, false on any failure. + * The actual struct pointed to by dest must match the description in fields. + * Callback fields of the destination structure must be initialized by caller. + * All other fields will be initialized by this function. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_istream_t stream; + * + * // ... read some data into buffer ... + * + * stream = pb_istream_from_buffer(buffer, count); + * pb_decode(&stream, MyMessage_fields, &msg); + */ +bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except does not initialize the destination structure + * to default values. This is slightly faster if you need no default values + * and just do memset(struct, 0, sizeof(struct)) yourself. + * + * This can also be used for 'merging' two messages, i.e. update only the + * fields that exist in the new message. + * + * Note: If this function returns with an error, it will not release any + * dynamically allocated fields. You will need to call pb_release() yourself. + */ +bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except expects the stream to start with the message size + * encoded as varint. Corresponds to parseDelimitedFrom() in Google's + * protobuf API. + */ +bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode_delimited, except that it does not initialize the destination structure. + * See pb_decode_noinit + */ +bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except allows the message to be terminated with a null byte. + * NOTE: Until nanopb-0.4.0, pb_decode() also allows null-termination. This behaviour + * is not supported in most other protobuf implementations, so pb_decode_delimited() + * is a better option for compatibility. + */ +bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +#ifdef PB_ENABLE_MALLOC +/* Release any allocated pointer fields. If you use dynamic allocation, you should + * call this for any successfully decoded message when you are done with it. If + * pb_decode() returns with an error, the message is already released. + */ +void pb_release(const pb_field_t fields[], void *dest_struct); +#endif + + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an input stream for reading from a memory buffer. + * + * Alternatively, you can use a custom stream that reads directly from e.g. + * a file or a network socket. + */ +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize); + +/* Function to read from a pb_istream_t. You can use this if you need to + * read some custom header data, or to read data in field callbacks. + */ +bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Decode the tag for the next field in the stream. Gives the wire type and + * field tag. At end of the message, returns false and sets eof to true. */ +bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); + +/* Skip the field payload data, given the wire type. */ +bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + +/* Decode an integer in the varint format. This works for bool, enum, int32, + * int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); +#else +#define pb_decode_varint pb_decode_varint32 +#endif + +/* Decode an integer in the varint format. This works for bool, enum, int32, + * and uint32 field types. */ +bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); + +/* Decode an integer in the zig-zagged svarint format. This works for sint32 + * and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); +#else +bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); +#endif + +/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to + * a 4-byte wide C variable. */ +bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + +#ifndef PB_WITHOUT_64BIT +/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to + * a 8-byte wide C variable. */ +bool pb_decode_fixed64(pb_istream_t *stream, void *dest); +#endif + +/* Make a limited-length substream for reading a PB_WT_STRING field. */ +bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); +bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/nanopb/pb_encode.c b/hardware-wallet/firmware/vendor/nanopb/pb_encode.c new file mode 100644 index 00000000..e957d426 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/pb_encode.c @@ -0,0 +1,828 @@ +/* pb_encode.c -- encode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +#include "pb.h" +#include "pb_encode.h" +#include "pb_common.h" + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +/************************************** + * Declarations internal to this file * + **************************************/ +typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn; + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func); +static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData); +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension); +static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData); +static void *pb_const_cast(const void *p); +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +/* --- Function pointers to field encoders --- + * Order in the array must match pb_action_t LTYPE numbering. + */ +static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = { + &pb_enc_varint, + &pb_enc_uvarint, + &pb_enc_svarint, + &pb_enc_fixed32, + &pb_enc_fixed64, + + &pb_enc_bytes, + &pb_enc_string, + &pb_enc_submessage, + NULL, /* extensions */ + &pb_enc_fixed_length_bytes +}; + +/******************************* + * pb_ostream_t implementation * + *******************************/ + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + size_t i; + pb_byte_t *dest = (pb_byte_t*)stream->state; + stream->state = dest + count; + + for (i = 0; i < count; i++) + dest[i] = buf[i]; + + return true; +} + +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) +{ + pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY + stream.callback = (void*)1; /* Just a marker value */ +#else + stream.callback = &buf_write; +#endif + stream.state = buf; + stream.max_size = bufsize; + stream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + if (stream->callback != NULL) + { + if (stream->bytes_written + count > stream->max_size) + PB_RETURN_ERROR(stream, "stream full"); + +#ifdef PB_BUFFER_ONLY + if (!buf_write(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#endif + } + + stream->bytes_written += count; + return true; +} + +/************************* + * Encode a single field * + *************************/ + +/* Encode a static array. Handles the size calculations and possible packing. */ +static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, + const void *pData, size_t count, pb_encoder_t func) +{ + size_t i; + const void *p; + size_t size; + + if (count == 0) + return true; + + if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) + PB_RETURN_ERROR(stream, "array max size exceeded"); + + /* We always pack arrays if the datatype allows it. */ + if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) + return false; + + /* Determine the total size of packed array. */ + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) + { + size = 4 * count; + } + else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + size = 8 * count; + } + else + { + pb_ostream_t sizestream = PB_OSTREAM_SIZING; + p = pData; + for (i = 0; i < count; i++) + { + if (!func(&sizestream, field, p)) + return false; + p = (const char*)p + field->data_size; + } + size = sizestream.bytes_written; + } + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing.. */ + + /* Write the data */ + p = pData; + for (i = 0; i < count; i++) + { + if (!func(stream, field, p)) + return false; + p = (const char*)p + field->data_size; + } + } + else + { + p = pData; + for (i = 0; i < count; i++) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + /* Normally the data is stored directly in the array entries, but + * for pointer-type string and bytes fields, the array entries are + * actually pointers themselves also. So we have to dereference once + * more to get to the actual data. */ + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && + (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES)) + { + if (!func(stream, field, *(const void* const*)p)) + return false; + } + else + { + if (!func(stream, field, p)) + return false; + } + p = (const char*)p + field->data_size; + } + } + + return true; +} + +/* In proto3, all fields are optional and are only encoded if their value is "non-zero". + * This function implements the check for the zero value. */ +static bool pb_check_proto3_default_value(const pb_field_t *field, const void *pData) +{ + pb_type_t type = field->type; + const void *pSize = (const char*)pData + field->size_offset; + + if (PB_HTYPE(type) == PB_HTYPE_REQUIRED) + { + /* Required proto2 fields inside proto3 submessage, pretty rare case */ + return false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* Repeated fields inside proto3 submessage: present if count != 0 */ + return *(const pb_size_t*)pSize == 0; + } + else if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* Oneof fields */ + return *(const pb_size_t*)pSize == 0; + } + else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->size_offset) + { + /* Proto2 optional fields inside proto3 submessage */ + return *(const bool*)pSize == false; + } + + /* Rest is proto3 singular fields */ + + if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + if (PB_LTYPE(type) == PB_LTYPE_BYTES) + { + const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)pData; + return bytes->size == 0; + } + else if (PB_LTYPE(type) == PB_LTYPE_STRING) + { + return *(const char*)pData == '\0'; + } + else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES) + { + /* Fixed length bytes is only empty if its length is fixed + * as 0. Which would be pretty strange, but we can check + * it anyway. */ + return field->data_size == 0; + } + else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) + { + /* Check all fields in the submessage to find if any of them + * are non-zero. The comparison cannot be done byte-per-byte + * because the C struct may contain padding bytes that must + * be skipped. + */ + pb_field_iter_t iter; + if (pb_field_iter_begin(&iter, (const pb_field_t*)field->ptr, pb_const_cast(pData))) + { + do + { + if (!pb_check_proto3_default_value(iter.pos, iter.pData)) + { + return false; + } + } while (pb_field_iter_next(&iter)); + } + return true; + } + } + + { + /* Catch-all branch that does byte-per-byte comparison for zero value. + * + * This is for all pointer fields, and for static PB_LTYPE_VARINT, + * UVARINT, SVARINT, FIXED32, FIXED64, EXTENSION fields, and also + * callback fields. These all have integer or pointer value which + * can be compared with 0. + */ + pb_size_t i; + const char *p = (const char*)pData; + for (i = 0; i < field->data_size; i++) + { + if (p[i] != 0) + { + return false; + } + } + + return true; + } +} + +/* Encode a field with static or pointer allocation, i.e. one whose data + * is available to the encoder directly. */ +static bool checkreturn encode_basic_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + pb_encoder_t func; + bool implicit_has; + const void *pSize = &implicit_has; + + func = PB_ENCODERS[PB_LTYPE(field->type)]; + + if (field->size_offset) + { + /* Static optional, repeated or oneof field */ + pSize = (const char*)pData + field->size_offset; + } + else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL) + { + /* Proto3 style field, optional but without explicit has_ field. */ + implicit_has = !pb_check_proto3_default_value(field, pData); + } + else + { + /* Required field, always present */ + implicit_has = true; + } + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* pData is a pointer to the field, which contains pointer to + * the data. If the 2nd pointer is NULL, it is interpreted as if + * the has_field was false. + */ + pData = *(const void* const*)pData; + implicit_has = (pData != NULL); + } + + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + if (!pData) + PB_RETURN_ERROR(stream, "missing required field"); + if (!pb_encode_tag_for_field(stream, field)) + return false; + if (!func(stream, field, pData)) + return false; + break; + + case PB_HTYPE_OPTIONAL: + if (*(const bool*)pSize) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!func(stream, field, pData)) + return false; + } + break; + + case PB_HTYPE_REPEATED: + if (!encode_array(stream, field, pData, *(const pb_size_t*)pSize, func)) + return false; + break; + + case PB_HTYPE_ONEOF: + if (*(const pb_size_t*)pSize == field->tag) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!func(stream, field, pData)) + return false; + } + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } + + return true; +} + +/* Encode a field with callback semantics. This means that a user function is + * called to provide and encode the actual data. */ +static bool checkreturn encode_callback_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + const pb_callback_t *callback = (const pb_callback_t*)pData; + +#ifdef PB_OLD_CALLBACK_STYLE + const void *arg = callback->arg; +#else + void * const *arg = &(callback->arg); +#endif + + if (callback->funcs.encode != NULL) + { + if (!callback->funcs.encode(stream, field, arg)) + PB_RETURN_ERROR(stream, "callback error"); + } + return true; +} + +/* Encode a single field of any callback or static type. */ +static bool checkreturn encode_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + switch (PB_ATYPE(field->type)) + { + case PB_ATYPE_STATIC: + case PB_ATYPE_POINTER: + return encode_basic_field(stream, field, pData); + + case PB_ATYPE_CALLBACK: + return encode_callback_field(stream, field, pData); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Default handler for extension fields. Expects to have a pb_field_t + * pointer in the extension->type->arg field. */ +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, + const pb_extension_t *extension) +{ + const pb_field_t *field = (const pb_field_t*)extension->type->arg; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + return encode_field(stream, field, &extension->dest); + } + else + { + return encode_field(stream, field, extension->dest); + } +} + +/* Walk through all the registered extensions and give them a chance + * to encode themselves. */ +static bool checkreturn encode_extension_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + const pb_extension_t *extension = *(const pb_extension_t* const *)pData; + PB_UNUSED(field); + + while (extension) + { + bool status; + if (extension->type->encode) + status = extension->type->encode(stream, extension); + else + status = default_extension_encoder(stream, extension); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/********************* + * Encode all fields * + *********************/ + +static void *pb_const_cast(const void *p) +{ + /* Note: this casts away const, in order to use the common field iterator + * logic for both encoding and decoding. */ + union { + void *p1; + const void *p2; + } t; + t.p2 = p; + return t.p1; +} + +bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + pb_field_iter_t iter; + if (!pb_field_iter_begin(&iter, fields, pb_const_cast(src_struct))) + return true; /* Empty message type */ + + do { + if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION) + { + /* Special case for the extension field placeholder */ + if (!encode_extension_field(stream, iter.pos, iter.pData)) + return false; + } + else + { + /* Regular field */ + if (!encode_field(stream, iter.pos, iter.pData)) + return false; + } + } while (pb_field_iter_next(&iter)); + + return true; +} + +bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + return pb_encode_submessage(stream, fields, src_struct); +} + +bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + const pb_byte_t zero = 0; + + if (!pb_encode(stream, fields, src_struct)) + return false; + + return pb_write(stream, &zero, 1); +} + +bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct) +{ + pb_ostream_t stream = PB_OSTREAM_SIZING; + + if (!pb_encode(&stream, fields, src_struct)) + return false; + + *size = stream.bytes_written; + return true; +} + +/******************** + * Helper functions * + ********************/ +bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) +{ + pb_byte_t buffer[10]; + size_t i = 0; + + if (value <= 0x7F) + { + pb_byte_t v = (pb_byte_t)value; + return pb_write(stream, &v, 1); + } + + while (value) + { + buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80); + value >>= 7; + i++; + } + buffer[i-1] &= 0x7F; /* Unset top bit on last byte */ + + return pb_write(stream, buffer, i); +} + +bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) +{ + pb_uint64_t zigzagged; + if (value < 0) + zigzagged = ~((pb_uint64_t)value << 1); + else + zigzagged = (pb_uint64_t)value << 1; + + return pb_encode_varint(stream, zigzagged); +} + +bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) +{ + uint32_t val = *(const uint32_t*)value; + pb_byte_t bytes[4]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + return pb_write(stream, bytes, 4); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) +{ + uint64_t val = *(const uint64_t*)value; + pb_byte_t bytes[8]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); + bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); + bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); + bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); + return pb_write(stream, bytes, 8); +} +#endif + +bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) +{ + pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; + return pb_encode_varint(stream, tag); +} + +bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field) +{ + pb_wire_type_t wiretype; + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + wiretype = PB_WT_VARINT; + break; + + case PB_LTYPE_FIXED32: + wiretype = PB_WT_32BIT; + break; + + case PB_LTYPE_FIXED64: + wiretype = PB_WT_64BIT; + break; + + case PB_LTYPE_BYTES: + case PB_LTYPE_STRING: + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_FIXED_LENGTH_BYTES: + wiretype = PB_WT_STRING; + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } + + return pb_encode_tag(stream, wiretype, field->tag); +} + +bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) +{ + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + return pb_write(stream, buffer, size); +} + +bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + /* First calculate the message size using a non-writing substream. */ + pb_ostream_t substream = PB_OSTREAM_SIZING; + size_t size; + bool status; + + if (!pb_encode(&substream, fields, src_struct)) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + return false; + } + + size = substream.bytes_written; + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing */ + + if (stream->bytes_written + size > stream->max_size) + PB_RETURN_ERROR(stream, "stream full"); + + /* Use a substream to verify that a callback doesn't write more than + * what it did the first time. */ + substream.callback = stream->callback; + substream.state = stream->state; + substream.max_size = size; + substream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + substream.errmsg = NULL; +#endif + + status = pb_encode(&substream, fields, src_struct); + + stream->bytes_written += substream.bytes_written; + stream->state = substream.state; +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + + if (substream.bytes_written != size) + PB_RETURN_ERROR(stream, "submsg size changed"); + + return status; +} + +/* Field encoders */ + +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + pb_int64_t value = 0; + + if (field->data_size == sizeof(int_least8_t)) + value = *(const int_least8_t*)src; + else if (field->data_size == sizeof(int_least16_t)) + value = *(const int_least16_t*)src; + else if (field->data_size == sizeof(int32_t)) + value = *(const int32_t*)src; + else if (field->data_size == sizeof(pb_int64_t)) + value = *(const pb_int64_t*)src; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_varint(stream, (pb_uint64_t)value); +} + +static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + pb_uint64_t value = 0; + + if (field->data_size == sizeof(uint_least8_t)) + value = *(const uint_least8_t*)src; + else if (field->data_size == sizeof(uint_least16_t)) + value = *(const uint_least16_t*)src; + else if (field->data_size == sizeof(uint32_t)) + value = *(const uint32_t*)src; + else if (field->data_size == sizeof(pb_uint64_t)) + value = *(const pb_uint64_t*)src; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_varint(stream, value); +} + +static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + pb_int64_t value = 0; + + if (field->data_size == sizeof(int_least8_t)) + value = *(const int_least8_t*)src; + else if (field->data_size == sizeof(int_least16_t)) + value = *(const int_least16_t*)src; + else if (field->data_size == sizeof(int32_t)) + value = *(const int32_t*)src; + else if (field->data_size == sizeof(pb_int64_t)) + value = *(const pb_int64_t*)src; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_svarint(stream, value); +} + +static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + PB_UNUSED(field); +#ifndef PB_WITHOUT_64BIT + return pb_encode_fixed64(stream, src); +#else + PB_UNUSED(src); + PB_RETURN_ERROR(stream, "no 64bit support"); +#endif +} + +static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + PB_UNUSED(field); + return pb_encode_fixed32(stream, src); +} + +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + const pb_bytes_array_t *bytes = NULL; + + bytes = (const pb_bytes_array_t*)src; + + if (src == NULL) + { + /* Treat null pointer as an empty bytes field */ + return pb_encode_string(stream, NULL, 0); + } + + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) > field->data_size) + { + PB_RETURN_ERROR(stream, "bytes size exceeded"); + } + + return pb_encode_string(stream, bytes->bytes, bytes->size); +} + +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + size_t size = 0; + size_t max_size = field->data_size; + const char *p = (const char*)src; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + max_size = (size_t)-1; + + if (src == NULL) + { + size = 0; /* Treat null pointer as an empty string */ + } + else + { + /* strnlen() is not always available, so just use a loop */ + while (size < max_size && *p != '\0') + { + size++; + p++; + } + } + + return pb_encode_string(stream, (const pb_byte_t*)src, size); +} + +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + if (field->ptr == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src); +} + +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size); +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/pb_encode.h b/hardware-wallet/firmware/vendor/nanopb/pb_encode.h new file mode 100644 index 00000000..8bf78dd5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/pb_encode.h @@ -0,0 +1,170 @@ +/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. + * The main function is pb_encode. You also need an output stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_ENCODE_H_INCLUDED +#define PB_ENCODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom output streams. You will need to provide + * a callback function to write the bytes to your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause encoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer). + * 3) pb_write will update bytes_written after your callback runs. + * 4) Substreams will modify max_size and bytes_written. Don't use them + * to calculate any pointers. + */ +struct pb_ostream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + * Also, NULL pointer marks a 'sizing stream' that does not + * write anything. + */ + int *callback; +#else + bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +#endif + void *state; /* Free field for use by callback implementation. */ + size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ + size_t bytes_written; /* Number of bytes written so far. */ + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +/*************************** + * Main encoding functions * + ***************************/ + +/* Encode a single protocol buffers message from C structure into a stream. + * Returns true on success, false on any failure. + * The actual struct pointed to by src_struct must match the description in fields. + * All required fields in the struct are assumed to have been filled in. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_ostream_t stream; + * + * msg.field1 = 42; + * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + * pb_encode(&stream, MyMessage_fields, &msg); + */ +bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Same as pb_encode, but prepends the length of the message as a varint. + * Corresponds to writeDelimitedTo() in Google's protobuf API. + */ +bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Same as pb_encode, but appends a null byte to the message for termination. + * NOTE: This behaviour is not supported in most other protobuf implementations, so pb_encode_delimited() + * is a better option for compatibility. + */ +bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Encode the message to get the size of the encoded data, but do not store + * the data. */ +bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an output stream for writing into a memory buffer. + * The number of bytes written can be found in stream.bytes_written after + * encoding the message. + * + * Alternatively, you can use a custom stream that writes directly to e.g. + * a file or a network socket. + */ +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + +/* Pseudo-stream for measuring the size of a message without actually storing + * the encoded data. + * + * Example usage: + * MyMessage msg = {}; + * pb_ostream_t stream = PB_OSTREAM_SIZING; + * pb_encode(&stream, MyMessage_fields, &msg); + * printf("Message size is %d\n", stream.bytes_written); + */ +#ifndef PB_NO_ERRMSG +#define PB_OSTREAM_SIZING {0,0,0,0,0} +#else +#define PB_OSTREAM_SIZING {0,0,0,0} +#endif + +/* Function to write into a pb_ostream_t stream. You can use this if you need + * to append or prepend some custom headers to the message. + */ +bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Encode field header based on type and field number defined in the field + * structure. Call this from the callback before writing out field contents. */ +bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field); + +/* Encode field header by manually specifing wire type. You need to use this + * if you want to write out packed arrays from a callback field. */ +bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); + +/* Encode an integer in the varint format. + * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); +#else +bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); +#endif + +/* Encode an integer in the zig-zagged svarint format. + * This works for sint32 and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); +#else +bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); +#endif + +/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ +bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); + +/* Encode a fixed32, sfixed32 or float value. + * You need to pass a pointer to a 4-byte wide C variable. */ +bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + +#ifndef PB_WITHOUT_64BIT +/* Encode a fixed64, sfixed64 or double value. + * You need to pass a pointer to a 8-byte wide C variable. */ +bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); +#endif + +/* Encode a submessage field. + * You need to pass the pb_field_t array and pointer to struct, just like + * with pb_encode(). This internally encodes the submessage twice, first to + * calculate message size and then to actually write it out. + */ +bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/Makefile b/hardware-wallet/firmware/vendor/nanopb/tests/Makefile new file mode 100644 index 00000000..cee6bf67 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/Makefile @@ -0,0 +1,21 @@ +all: + scons + +clean: + scons -c + +coverage: + rm -rf build coverage + + # LCOV does not like the newer gcov format + scons CC=gcc-4.6 CXX=gcc-4.6 + + # Collect the data + mkdir build/coverage + lcov --base-directory . --directory build/ --gcov-tool gcov-4.6 -c -o build/coverage/nanopb.info + + # Remove the test code from results + lcov -r build/coverage/nanopb.info '*tests*' -o build/coverage/nanopb.info + + # Generate HTML + genhtml -o build/coverage build/coverage/nanopb.info diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/SConstruct b/hardware-wallet/firmware/vendor/nanopb/tests/SConstruct new file mode 100644 index 00000000..ae79f710 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/SConstruct @@ -0,0 +1,157 @@ +Help(''' +Type 'scons' to build and run all the available test cases. +It will automatically detect your platform and C compiler and +build appropriately. + +You can modify the behavious using following options: +CC Name of C compiler +CXX Name of C++ compiler +CCFLAGS Flags to pass to the C compiler +CXXFLAGS Flags to pass to the C++ compiler + +For example, for a clang build, use: +scons CC=clang CXX=clang++ +''') + +import os +env = Environment(ENV = os.environ, tools = ['default', 'nanopb']) + +# Allow overriding the compiler with scons CC=??? +if 'CC' in ARGUMENTS: env.Replace(CC = ARGUMENTS['CC']) +if 'CXX' in ARGUMENTS: env.Replace(CXX = ARGUMENTS['CXX']) +if 'CCFLAGS' in ARGUMENTS: env.Append(CCFLAGS = ARGUMENTS['CCFLAGS']) +if 'CXXFLAGS' in ARGUMENTS: env.Append(CXXFLAGS = ARGUMENTS['CXXFLAGS']) + +# Add the builders defined in site_init.py +add_nanopb_builders(env) + +# Path to the files shared by tests, and to the nanopb core. +env.Append(CPPPATH = ["#../", "$COMMON"]) + +# Path for finding nanopb.proto +env.Append(PROTOCPATH = '#../generator') + +# Check the compilation environment, unless we are just cleaning up. +if not env.GetOption('clean'): + def check_ccflags(context, flags, linkflags = ''): + '''Check if given CCFLAGS are supported''' + context.Message('Checking support for CCFLAGS="%s"... ' % flags) + oldflags = context.env['CCFLAGS'] + oldlinkflags = context.env['CCFLAGS'] + context.env.Append(CCFLAGS = flags) + context.env.Append(LINKFLAGS = linkflags) + result = context.TryCompile("int main() {return 0;}", '.c') + context.env.Replace(CCFLAGS = oldflags) + context.env.Replace(LINKFLAGS = oldlinkflags) + context.Result(result) + return result + + conf = Configure(env, custom_tests = {'CheckCCFLAGS': check_ccflags}) + + # If the platform doesn't support C99, use our own header file instead. + stdbool = conf.CheckCHeader('stdbool.h') + stdint = conf.CheckCHeader('stdint.h') + stddef = conf.CheckCHeader('stddef.h') + string = conf.CheckCHeader('string.h') + stdlib = conf.CheckCHeader('stdlib.h') + if not stdbool or not stdint or not stddef or not string: + conf.env.Append(CPPDEFINES = {'PB_SYSTEM_HEADER': '\\"pb_syshdr.h\\"'}) + conf.env.Append(CPPPATH = "#../extra") + conf.env.Append(SYSHDR = '\\"pb_syshdr.h\\"') + + if stdbool: conf.env.Append(CPPDEFINES = {'HAVE_STDBOOL_H': 1}) + if stdint: conf.env.Append(CPPDEFINES = {'HAVE_STDINT_H': 1}) + if stddef: conf.env.Append(CPPDEFINES = {'HAVE_STDDEF_H': 1}) + if string: conf.env.Append(CPPDEFINES = {'HAVE_STRING_H': 1}) + if stdlib: conf.env.Append(CPPDEFINES = {'HAVE_STDLIB_H': 1}) + + # Check if we can use pkg-config to find protobuf include path + status, output = conf.TryAction('pkg-config protobuf --variable=includedir > $TARGET') + if status: + conf.env.Append(PROTOCPATH = output.strip()) + else: + conf.env.Append(PROTOCPATH = '/usr/include') + + # Check protoc version + status, output = conf.TryAction('$PROTOC --version > $TARGET') + if status: + conf.env['PROTOC_VERSION'] = output + + # Check if libmudflap is available (only with GCC) + if 'gcc' in env['CC']: + if conf.CheckLib('mudflap'): + conf.env.Append(CCFLAGS = '-fmudflap') + conf.env.Append(LINKFLAGS = '-fmudflap') + + # Check if we can use extra strict warning flags (only with GCC) + extra = '-Wcast-qual -Wlogical-op -Wconversion' + extra += ' -fstrict-aliasing -Wstrict-aliasing=1' + extra += ' -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls' + extra += ' -Wstack-protector ' + if 'gcc' in env['CC']: + if conf.CheckCCFLAGS(extra): + conf.env.Append(CORECFLAGS = extra) + + # Check if we can use undefined behaviour sanitizer (only with clang) + # TODO: Fuzz test triggers the bool sanitizer, figure out whether to + # modify the fuzz test or to keep ignoring the check. + extra = '-fsanitize=undefined,integer -fno-sanitize-recover=undefined,integer -fsanitize-recover=bool ' + if 'clang' in env['CC']: + if conf.CheckCCFLAGS(extra, linkflags = extra): + conf.env.Append(CORECFLAGS = extra) + conf.env.Append(LINKFLAGS = extra) + + # End the config stuff + env = conf.Finish() + +# Initialize the CCFLAGS according to the compiler +if 'gcc' in env['CC']: + # GNU Compiler Collection + + # Debug info, warnings as errors + env.Append(CFLAGS = '-ansi -pedantic -g -Wall -Werror -fprofile-arcs -ftest-coverage ') + env.Append(CORECFLAGS = '-Wextra') + env.Append(LINKFLAGS = '-g --coverage') + + # We currently need uint64_t anyway, even though ANSI C90 otherwise.. + env.Append(CFLAGS = '-Wno-long-long') +elif 'clang' in env['CC']: + # CLang + env.Append(CFLAGS = '-ansi -g -Wall -Werror') + env.Append(CORECFLAGS = ' -Wextra -Wcast-qual -Wconversion') +elif 'cl' in env['CC']: + # Microsoft Visual C++ + + # Debug info on, warning level 2 for tests, warnings as errors + env.Append(CFLAGS = '/Zi /W2 /WX') + env.Append(LINKFLAGS = '/DEBUG') + + # More strict checks on the nanopb core + env.Append(CORECFLAGS = '/W4') +elif 'tcc' in env['CC']: + # Tiny C Compiler + env.Append(CFLAGS = '-Wall -Werror -g') + +env.SetDefault(CORECFLAGS = '') + +if 'clang' in env['CXX']: + env.Append(CXXFLAGS = '-g -Wall -Werror -Wextra -Wno-missing-field-initializers') +elif 'g++' in env['CXX'] or 'gcc' in env['CXX']: + env.Append(CXXFLAGS = '-g -Wall -Werror -Wextra -Wno-missing-field-initializers') +elif 'cl' in env['CXX']: + env.Append(CXXFLAGS = '/Zi /W2 /WX') + +# Now include the SConscript files from all subdirectories +import os.path +env['VARIANT_DIR'] = 'build' +env['BUILD'] = '#' + env['VARIANT_DIR'] +env['COMMON'] = '#' + env['VARIANT_DIR'] + '/common' + +# Include common/SConscript first to make sure its exports are available +# to other SConscripts. +SConscript("common/SConscript", exports = 'env', variant_dir = env['VARIANT_DIR'] + '/common') + +for subdir in Glob('*/SConscript') + Glob('regression/*/SConscript'): + if str(subdir).startswith("common"): continue + SConscript(subdir, exports = 'env', variant_dir = env['VARIANT_DIR'] + '/' + os.path.dirname(str(subdir))) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/SConscript new file mode 100644 index 00000000..6c6238c6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/SConscript @@ -0,0 +1,35 @@ +# Build and run a test that encodes and decodes a message that contains +# all of the Protocol Buffers data types. + +Import("env") + +env.NanopbProto(["alltypes", "alltypes.options"]) +enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +# Test the round-trip from nanopb encoder to nanopb decoder +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) + +# Re-encode the data using protoc, and check that the results from nanopb +# match byte-per-byte to the protoc output. +env.Decode("encode_alltypes.output.decoded", + ["encode_alltypes.output", "alltypes.proto"], + MESSAGE='AllTypes') +env.Encode("encode_alltypes.output.recoded", + ["encode_alltypes.output.decoded", "alltypes.proto"], + MESSAGE='AllTypes') +env.Compare(["encode_alltypes.output", "encode_alltypes.output.recoded"]) + +# Do the same checks with the optional fields present. +env.RunTest("optionals.output", enc, ARGS = ['1']) +env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) +env.Decode("optionals.output.decoded", + ["optionals.output", "alltypes.proto"], + MESSAGE='AllTypes') +env.Encode("optionals.output.recoded", + ["optionals.output.decoded", "alltypes.proto"], + MESSAGE='AllTypes') +env.Compare(["optionals.output", "optionals.output.recoded"]) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.options new file mode 100644 index 00000000..0d5ab12b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.options @@ -0,0 +1,3 @@ +* max_size:16 +* max_count:5 +*.*fbytes fixed_length:true max_size:4 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.proto new file mode 100644 index 00000000..b2250c00 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/alltypes.proto @@ -0,0 +1,125 @@ +syntax = "proto2"; +// package name placeholder + +message SubMessage { + required string substuff1 = 1 [default = "1"]; + required int32 substuff2 = 2 [default = 2]; + optional fixed32 substuff3 = 3 [default = 3]; +} + +message EmptyMessage { + +} + +enum HugeEnum { + Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ + Positive = 2147483647; +} + +message Limits { + required int32 int32_min = 1 [default = 2147483647]; + required int32 int32_max = 2 [default = -2147483647]; + required uint32 uint32_min = 3 [default = 4294967295]; + required uint32 uint32_max = 4 [default = 0]; + required int64 int64_min = 5 [default = 9223372036854775807]; + required int64 int64_max = 6 [default = -9223372036854775807]; + required uint64 uint64_min = 7 [default = 18446744073709551615]; + required uint64 uint64_max = 8 [default = 0]; + required HugeEnum enum_min = 9 [default = Positive]; + required HugeEnum enum_max = 10 [default = Negative]; +} + +enum MyEnum { + Zero = 0; + First = 1; + Second = 2; + Truth = 42; +} + +message AllTypes { + required int32 req_int32 = 1; + required int64 req_int64 = 2; + required uint32 req_uint32 = 3; + required uint64 req_uint64 = 4; + required sint32 req_sint32 = 5; + required sint64 req_sint64 = 6; + required bool req_bool = 7; + + required fixed32 req_fixed32 = 8; + required sfixed32 req_sfixed32= 9; + required float req_float = 10; + + required fixed64 req_fixed64 = 11; + required sfixed64 req_sfixed64= 12; + required double req_double = 13; + + required string req_string = 14; + required bytes req_bytes = 15; + required SubMessage req_submsg = 16; + required MyEnum req_enum = 17; + required EmptyMessage req_emptymsg = 18; + required bytes req_fbytes = 19; + + repeated int32 rep_int32 = 21 [packed = true]; + repeated int64 rep_int64 = 22 [packed = true]; + repeated uint32 rep_uint32 = 23 [packed = true]; + repeated uint64 rep_uint64 = 24 [packed = true]; + repeated sint32 rep_sint32 = 25 [packed = true]; + repeated sint64 rep_sint64 = 26 [packed = true]; + repeated bool rep_bool = 27 [packed = true]; + + repeated fixed32 rep_fixed32 = 28 [packed = true]; + repeated sfixed32 rep_sfixed32= 29 [packed = true]; + repeated float rep_float = 30 [packed = true]; + + repeated fixed64 rep_fixed64 = 31 [packed = true]; + repeated sfixed64 rep_sfixed64= 32 [packed = true]; + repeated double rep_double = 33 [packed = true]; + + repeated string rep_string = 34; + repeated bytes rep_bytes = 35; + repeated SubMessage rep_submsg = 36; + repeated MyEnum rep_enum = 37 [packed = true]; + repeated EmptyMessage rep_emptymsg = 38; + repeated bytes rep_fbytes = 39; + + optional int32 opt_int32 = 41 [default = 4041]; + optional int64 opt_int64 = 42 [default = 4042]; + optional uint32 opt_uint32 = 43 [default = 4043]; + optional uint64 opt_uint64 = 44 [default = 4044]; + optional sint32 opt_sint32 = 45 [default = 4045]; + optional sint64 opt_sint64 = 46 [default = 4046]; + optional bool opt_bool = 47 [default = false]; + + optional fixed32 opt_fixed32 = 48 [default = 4048]; + optional sfixed32 opt_sfixed32= 49 [default = 4049]; + optional float opt_float = 50 [default = 4050]; + + optional fixed64 opt_fixed64 = 51 [default = 4051]; + optional sfixed64 opt_sfixed64= 52 [default = 4052]; + optional double opt_double = 53 [default = 4053]; + + optional string opt_string = 54 [default = "4054"]; + optional bytes opt_bytes = 55 [default = "4055"]; + optional SubMessage opt_submsg = 56; + optional MyEnum opt_enum = 57 [default = Second]; + optional EmptyMessage opt_emptymsg = 58; + optional bytes opt_fbytes = 59 [default = "4059"]; + + oneof oneof + { + SubMessage oneof_msg1 = 60; + EmptyMessage oneof_msg2 = 61; + } + + // Check that extreme integer values are handled correctly + required Limits req_limits = 98; + + // Just to make sure that the size of the fields has been calculated + // properly, i.e. otherwise a bug in last field might not be detected. + required int32 end = 99; + + + extensions 200 to 255; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/decode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/decode_alltypes.c new file mode 100644 index 00000000..2e609e56 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/decode_alltypes.c @@ -0,0 +1,229 @@ +/* Tests the decoding of all types. + * This is the counterpart of test_encode3. + * Run e.g. ./test_encode3 | ./test_decode3 + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed.\n"); \ + return false; \ + } + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + /* Uses _init_default to just make sure that it works. */ + AllTypes alltypes = AllTypes_init_default; + + /* Fill with garbage to better detect initialization errors */ + memset(&alltypes, 0xAA, sizeof(alltypes)); + alltypes.extensions = 0; + + if (!pb_decode(stream, AllTypes_fields, &alltypes)) + return false; + + TEST(alltypes.req_int32 == -1001); + TEST(alltypes.req_int64 == -1002); + TEST(alltypes.req_uint32 == 1003); + TEST(alltypes.req_uint64 == 1004); + TEST(alltypes.req_sint32 == -1005); + TEST(alltypes.req_sint64 == -1006); + TEST(alltypes.req_bool == true); + + TEST(alltypes.req_fixed32 == 1008); + TEST(alltypes.req_sfixed32 == -1009); + TEST(alltypes.req_float == 1010.0f); + + TEST(alltypes.req_fixed64 == 1011); + TEST(alltypes.req_sfixed64 == -1012); + TEST(alltypes.req_double == 1013.0f); + + TEST(strcmp(alltypes.req_string, "1014") == 0); + TEST(alltypes.req_bytes.size == 4); + TEST(memcmp(alltypes.req_bytes.bytes, "1015", 4) == 0); + TEST(strcmp(alltypes.req_submsg.substuff1, "1016") == 0); + TEST(alltypes.req_submsg.substuff2 == 1016); + TEST(alltypes.req_submsg.substuff3 == 3); + TEST(alltypes.req_enum == MyEnum_Truth); + TEST(memcmp(alltypes.req_fbytes, "1019", 4) == 0); + + TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0); + TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0); + TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0); + TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0); + TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0); + TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0); + TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false); + + TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0); + TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0); + TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f); + + TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0); + TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0); + TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0); + + TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0'); + TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0); + TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0); + + TEST(alltypes.rep_submsg_count == 5); + TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0'); + TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0); + TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 3); + + TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero); + TEST(alltypes.rep_emptymsg_count == 5); + TEST(alltypes.rep_fbytes_count == 5); + TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0); + TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0); + + if (mode == 0) + { + /* Expect default values */ + TEST(alltypes.has_opt_int32 == false); + TEST(alltypes.opt_int32 == 4041); + TEST(alltypes.has_opt_int64 == false); + TEST(alltypes.opt_int64 == 4042); + TEST(alltypes.has_opt_uint32 == false); + TEST(alltypes.opt_uint32 == 4043); + TEST(alltypes.has_opt_uint64 == false); + TEST(alltypes.opt_uint64 == 4044); + TEST(alltypes.has_opt_sint32 == false); + TEST(alltypes.opt_sint32 == 4045); + TEST(alltypes.has_opt_sint64 == false); + TEST(alltypes.opt_sint64 == 4046); + TEST(alltypes.has_opt_bool == false); + TEST(alltypes.opt_bool == false); + + TEST(alltypes.has_opt_fixed32 == false); + TEST(alltypes.opt_fixed32 == 4048); + TEST(alltypes.has_opt_sfixed32 == false); + TEST(alltypes.opt_sfixed32 == 4049); + TEST(alltypes.has_opt_float == false); + TEST(alltypes.opt_float == 4050.0f); + + TEST(alltypes.has_opt_fixed64 == false); + TEST(alltypes.opt_fixed64 == 4051); + TEST(alltypes.has_opt_sfixed64 == false); + TEST(alltypes.opt_sfixed64 == 4052); + TEST(alltypes.has_opt_double == false); + TEST(alltypes.opt_double == 4053.0); + + TEST(alltypes.has_opt_string == false); + TEST(strcmp(alltypes.opt_string, "4054") == 0); + TEST(alltypes.has_opt_bytes == false); + TEST(alltypes.opt_bytes.size == 4); + TEST(memcmp(alltypes.opt_bytes.bytes, "4055", 4) == 0); + TEST(alltypes.has_opt_submsg == false); + TEST(strcmp(alltypes.opt_submsg.substuff1, "1") == 0); + TEST(alltypes.opt_submsg.substuff2 == 2); + TEST(alltypes.opt_submsg.substuff3 == 3); + TEST(alltypes.has_opt_enum == false); + TEST(alltypes.opt_enum == MyEnum_Second); + TEST(alltypes.has_opt_emptymsg == false); + TEST(alltypes.has_opt_fbytes == false); + TEST(memcmp(alltypes.opt_fbytes, "4059", 4) == 0); + + TEST(alltypes.which_oneof == 0); + } + else + { + /* Expect filled-in values */ + TEST(alltypes.has_opt_int32 == true); + TEST(alltypes.opt_int32 == 3041); + TEST(alltypes.has_opt_int64 == true); + TEST(alltypes.opt_int64 == 3042); + TEST(alltypes.has_opt_uint32 == true); + TEST(alltypes.opt_uint32 == 3043); + TEST(alltypes.has_opt_uint64 == true); + TEST(alltypes.opt_uint64 == 3044); + TEST(alltypes.has_opt_sint32 == true); + TEST(alltypes.opt_sint32 == 3045); + TEST(alltypes.has_opt_sint64 == true); + TEST(alltypes.opt_sint64 == 3046); + TEST(alltypes.has_opt_bool == true); + TEST(alltypes.opt_bool == true); + + TEST(alltypes.has_opt_fixed32 == true); + TEST(alltypes.opt_fixed32 == 3048); + TEST(alltypes.has_opt_sfixed32 == true); + TEST(alltypes.opt_sfixed32 == 3049); + TEST(alltypes.has_opt_float == true); + TEST(alltypes.opt_float == 3050.0f); + + TEST(alltypes.has_opt_fixed64 == true); + TEST(alltypes.opt_fixed64 == 3051); + TEST(alltypes.has_opt_sfixed64 == true); + TEST(alltypes.opt_sfixed64 == 3052); + TEST(alltypes.has_opt_double == true); + TEST(alltypes.opt_double == 3053.0); + + TEST(alltypes.has_opt_string == true); + TEST(strcmp(alltypes.opt_string, "3054") == 0); + TEST(alltypes.has_opt_bytes == true); + TEST(alltypes.opt_bytes.size == 4); + TEST(memcmp(alltypes.opt_bytes.bytes, "3055", 4) == 0); + TEST(alltypes.has_opt_submsg == true); + TEST(strcmp(alltypes.opt_submsg.substuff1, "3056") == 0); + TEST(alltypes.opt_submsg.substuff2 == 3056); + TEST(alltypes.opt_submsg.substuff3 == 3); + TEST(alltypes.has_opt_enum == true); + TEST(alltypes.opt_enum == MyEnum_Truth); + TEST(alltypes.has_opt_emptymsg == true); + TEST(alltypes.has_opt_fbytes == true); + TEST(memcmp(alltypes.opt_fbytes, "3059", 4) == 0); + + TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag); + TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0); + TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059); + } + + TEST(alltypes.req_limits.int32_min == INT32_MIN); + TEST(alltypes.req_limits.int32_max == INT32_MAX); + TEST(alltypes.req_limits.uint32_min == 0); + TEST(alltypes.req_limits.uint32_max == UINT32_MAX); + TEST(alltypes.req_limits.int64_min == INT64_MIN); + TEST(alltypes.req_limits.int64_max == INT64_MAX); + TEST(alltypes.req_limits.uint64_min == 0); + TEST(alltypes.req_limits.uint64_max == UINT64_MAX); + TEST(alltypes.req_limits.enum_min == HugeEnum_Negative); + TEST(alltypes.req_limits.enum_max == HugeEnum_Positive); + + TEST(alltypes.end == 1099); + + return true; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!check_alltypes(&stream, mode)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/encode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/encode_alltypes.c new file mode 100644 index 00000000..1b863555 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes/encode_alltypes.c @@ -0,0 +1,155 @@ +/* Attempts to test all the datatypes supported by ProtoBuf. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Initialize the structure with constants */ + AllTypes alltypes = AllTypes_init_zero; + + alltypes.req_int32 = -1001; + alltypes.req_int64 = -1002; + alltypes.req_uint32 = 1003; + alltypes.req_uint64 = 1004; + alltypes.req_sint32 = -1005; + alltypes.req_sint64 = -1006; + alltypes.req_bool = true; + + alltypes.req_fixed32 = 1008; + alltypes.req_sfixed32 = -1009; + alltypes.req_float = 1010.0f; + + alltypes.req_fixed64 = 1011; + alltypes.req_sfixed64 = -1012; + alltypes.req_double = 1013.0; + + strcpy(alltypes.req_string, "1014"); + alltypes.req_bytes.size = 4; + memcpy(alltypes.req_bytes.bytes, "1015", 4); + strcpy(alltypes.req_submsg.substuff1, "1016"); + alltypes.req_submsg.substuff2 = 1016; + alltypes.req_enum = MyEnum_Truth; + memcpy(alltypes.req_fbytes, "1019", 4); + + alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001; + alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002; + alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003; + alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004; + alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005; + alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006; + alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true; + + alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008; + alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009; + alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f; + + alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011; + alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012; + alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0; + + alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014"); + alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4; + memcpy(alltypes.rep_bytes[4].bytes, "2015", 4); + + alltypes.rep_submsg_count = 5; + strcpy(alltypes.rep_submsg[4].substuff1, "2016"); + alltypes.rep_submsg[4].substuff2 = 2016; + alltypes.rep_submsg[4].has_substuff3 = true; + alltypes.rep_submsg[4].substuff3 = 2016; + + alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth; + alltypes.rep_emptymsg_count = 5; + + alltypes.rep_fbytes_count = 5; + memcpy(alltypes.rep_fbytes[4], "2019", 4); + + alltypes.req_limits.int32_min = INT32_MIN; + alltypes.req_limits.int32_max = INT32_MAX; + alltypes.req_limits.uint32_min = 0; + alltypes.req_limits.uint32_max = UINT32_MAX; + alltypes.req_limits.int64_min = INT64_MIN; + alltypes.req_limits.int64_max = INT64_MAX; + alltypes.req_limits.uint64_min = 0; + alltypes.req_limits.uint64_max = UINT64_MAX; + alltypes.req_limits.enum_min = HugeEnum_Negative; + alltypes.req_limits.enum_max = HugeEnum_Positive; + + if (mode != 0) + { + /* Fill in values for optional fields */ + alltypes.has_opt_int32 = true; + alltypes.opt_int32 = 3041; + alltypes.has_opt_int64 = true; + alltypes.opt_int64 = 3042; + alltypes.has_opt_uint32 = true; + alltypes.opt_uint32 = 3043; + alltypes.has_opt_uint64 = true; + alltypes.opt_uint64 = 3044; + alltypes.has_opt_sint32 = true; + alltypes.opt_sint32 = 3045; + alltypes.has_opt_sint64 = true; + alltypes.opt_sint64 = 3046; + alltypes.has_opt_bool = true; + alltypes.opt_bool = true; + + alltypes.has_opt_fixed32 = true; + alltypes.opt_fixed32 = 3048; + alltypes.has_opt_sfixed32 = true; + alltypes.opt_sfixed32 = 3049; + alltypes.has_opt_float = true; + alltypes.opt_float = 3050.0f; + + alltypes.has_opt_fixed64 = true; + alltypes.opt_fixed64 = 3051; + alltypes.has_opt_sfixed64 = true; + alltypes.opt_sfixed64 = 3052; + alltypes.has_opt_double = true; + alltypes.opt_double = 3053.0; + + alltypes.has_opt_string = true; + strcpy(alltypes.opt_string, "3054"); + alltypes.has_opt_bytes = true; + alltypes.opt_bytes.size = 4; + memcpy(alltypes.opt_bytes.bytes, "3055", 4); + alltypes.has_opt_submsg = true; + strcpy(alltypes.opt_submsg.substuff1, "3056"); + alltypes.opt_submsg.substuff2 = 3056; + alltypes.has_opt_enum = true; + alltypes.opt_enum = MyEnum_Truth; + alltypes.has_opt_emptymsg = true; + alltypes.has_opt_fbytes = true; + memcpy(alltypes.opt_fbytes, "3059", 4); + + alltypes.which_oneof = AllTypes_oneof_msg1_tag; + strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059"); + alltypes.oneof.oneof_msg1.substuff2 = 4059; + } + + alltypes.end = 1099; + + { + uint8_t buffer[AllTypes_size]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/SConscript new file mode 100644 index 00000000..8be53908 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/SConscript @@ -0,0 +1,28 @@ +# Test the AllTypes encoding & decoding using callbacks for all fields. + +Import("env", "malloc_env") + +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.proto", "#alltypes/alltypes.proto", c) + +env.NanopbProto(["alltypes", "alltypes.options"]) +enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX" + +# Encode and compare results +env.RunTest(enc) +env.RunTest("decode_alltypes.output", [refdec, "encode_alltypes_callback.output"]) +env.RunTest("decode_alltypes_callback.output", [dec, "encode_alltypes_callback.output"]) + +# Do the same thing with the optional fields present +env.RunTest("optionals.output", enc, ARGS = ['1']) +env.RunTest("optionals.refdecout", [refdec, "optionals.output"], ARGS = ['1']) +env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) + +# Try with malloc support also +mallocbin1 = malloc_env.Object("decode_with_malloc.o", "decode_alltypes_callback.c") +mallocbin2 = malloc_env.Object("alltypes_malloc.pb.o", "alltypes.pb.c") +mallocdec = malloc_env.Program("decode_with_malloc", [mallocbin1, mallocbin2, "$COMMON/pb_decode_with_malloc.o", "$COMMON/pb_common_with_malloc.o", "$COMMON/malloc_wrappers.o"]) +env.RunTest("decode_with_malloc.output", [mallocdec, "encode_alltypes_callback.output"]) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/alltypes.options new file mode 100644 index 00000000..74d7a9c0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/alltypes.options @@ -0,0 +1,8 @@ +# Generate all fields as callbacks. +AllTypes.* type:FT_CALLBACK +SubMessage.substuff1 max_size:16 +AllTypes.oneof no_unions:true + +# With FT_CALLBACK, these options should get ignored +*.*fbytes fixed_length:true max_size:4 + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/decode_alltypes_callback.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/decode_alltypes_callback.c new file mode 100644 index 00000000..576ce307 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/decode_alltypes_callback.c @@ -0,0 +1,442 @@ +/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields. + * Note that normally there would be no reason to use callback fields for this, + * because each encoder defined here only gives a single field. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed (in field %d).\n", field->tag); \ + return false; \ + } + +static bool read_varint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + TEST((int64_t)value == (long)*arg); + return true; +} + +static bool read_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + int64_t value; + if (!pb_decode_svarint(stream, &value)) + return false; + + TEST(value == (long)*arg); + return true; +} + +static bool read_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint32_t value; + if (!pb_decode_fixed32(stream, &value)) + return false; + + TEST(value == *(uint32_t*)*arg); + return true; +} + +static bool read_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t value; + if (!pb_decode_fixed64(stream, &value)) + return false; + + TEST(value == *(uint64_t*)*arg); + return true; +} + +static bool read_string(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint8_t buf[16] = {0}; + size_t len = stream->bytes_left; + + if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len)) + return false; + + TEST(strcmp((char*)buf, *arg) == 0); + return true; +} + +static bool read_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + SubMessage submsg = {""}; + SubMessage *ref = *arg; + + if (!pb_decode(stream, SubMessage_fields, &submsg)) + return false; + + TEST(strcmp(submsg.substuff1, ref->substuff1) == 0); + TEST(submsg.substuff2 == ref->substuff2); + TEST(submsg.has_substuff3 == ref->has_substuff3); + TEST(submsg.substuff3 == ref->substuff3); + return true; +} + +static bool read_emptymsg(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + EmptyMessage emptymsg = {0}; + return pb_decode(stream, EmptyMessage_fields, &emptymsg); +} + +static bool read_repeated_varint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + int32_t** expected = (int32_t**)arg; + uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + int32_t** expected = (int32_t**)arg; + int64_t value; + if (!pb_decode_svarint(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint32_t** expected = (uint32_t**)arg; + uint32_t value; + if (!pb_decode_fixed32(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t** expected = (uint64_t**)arg; + uint64_t value; + if (!pb_decode_fixed64(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_string(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint8_t*** expected = (uint8_t***)arg; + uint8_t buf[16] = {0}; + size_t len = stream->bytes_left; + + if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len)) + return false; + + TEST(strcmp((char*)*(*expected)++, (char*)buf) == 0); + return true; +} + +static bool read_repeated_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + SubMessage** expected = (SubMessage**)arg; + SubMessage submsg = {""}; + if (!pb_decode(stream, SubMessage_fields, &submsg)) + return false; + + TEST(strcmp(submsg.substuff1, (*expected)->substuff1) == 0); + TEST(submsg.substuff2 == (*expected)->substuff2); + TEST(submsg.has_substuff3 == (*expected)->has_substuff3); + TEST(submsg.substuff3 == (*expected)->substuff3); + (*expected)++; + + return true; +} + +static bool read_limits(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + Limits decoded = {0}; + if (!pb_decode(stream, Limits_fields, &decoded)) + return false; + + TEST(decoded.int32_min == INT32_MIN); + TEST(decoded.int32_max == INT32_MAX); + TEST(decoded.uint32_min == 0); + TEST(decoded.uint32_max == UINT32_MAX); + TEST(decoded.int64_min == INT64_MIN); + TEST(decoded.int64_max == INT64_MAX); + TEST(decoded.uint64_min == 0); + TEST(decoded.uint64_max == UINT64_MAX); + TEST(decoded.enum_min == HugeEnum_Negative); + TEST(decoded.enum_max == HugeEnum_Positive); + + return true; +} + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + /* Values for use from callbacks through pointers. */ + bool status; + uint32_t req_fixed32 = 1008; + int32_t req_sfixed32 = -1009; + float req_float = 1010.0f; + uint64_t req_fixed64 = 1011; + int64_t req_sfixed64 = -1012; + double req_double = 1013.0; + SubMessage req_submsg = {"1016", 1016, false, 3}; + + int32_t rep_int32[5] = {0, 0, 0, 0, -2001}; + int32_t rep_int64[5] = {0, 0, 0, 0, -2002}; + int32_t rep_uint32[5] = {0, 0, 0, 0, 2003}; + int32_t rep_uint64[5] = {0, 0, 0, 0, 2004}; + int32_t rep_sint32[5] = {0, 0, 0, 0, -2005}; + int32_t rep_sint64[5] = {0, 0, 0, 0, -2006}; + int32_t rep_bool[5] = {false, false, false, false, true}; + uint32_t rep_fixed32[5] = {0, 0, 0, 0, 2008}; + int32_t rep_sfixed32[5] = {0, 0, 0, 0, -2009}; + float rep_float[5] = {0, 0, 0, 0, 2010.0f}; + uint64_t rep_fixed64[5] = {0, 0, 0, 0, 2011}; + int64_t rep_sfixed64[5] = {0, 0, 0, 0, -2012}; + double rep_double[5] = {0, 0, 0, 0, 2013.0}; + char* rep_string[5] = {"", "", "", "", "2014"}; + char* rep_bytes[5] = {"", "", "", "", "2015"}; + SubMessage rep_submsg[5] = {{"", 0, 0, 3}, + {"", 0, 0, 3}, + {"", 0, 0, 3}, + {"", 0, 0, 3}, + {"2016", 2016, true, 2016}}; + int32_t rep_enum[5] = {0, 0, 0, 0, MyEnum_Truth}; + + uint32_t opt_fixed32 = 3048; + int32_t opt_sfixed32 = 3049; + float opt_float = 3050.0f; + uint64_t opt_fixed64 = 3051; + int64_t opt_sfixed64 = 3052; + double opt_double = 3053.0f; + SubMessage opt_submsg = {"3056", 3056, false, 3}; + + SubMessage oneof_msg1 = {"4059", 4059, false, 3}; + + /* Bind callbacks for required fields */ + AllTypes alltypes = AllTypes_init_zero; + + alltypes.req_int32.funcs.decode = &read_varint; + alltypes.req_int32.arg = (void*)-1001; + + alltypes.req_int64.funcs.decode = &read_varint; + alltypes.req_int64.arg = (void*)-1002; + + alltypes.req_uint32.funcs.decode = &read_varint; + alltypes.req_uint32.arg = (void*)1003; + + alltypes.req_uint32.funcs.decode = &read_varint; + alltypes.req_uint32.arg = (void*)1003; + + alltypes.req_uint64.funcs.decode = &read_varint; + alltypes.req_uint64.arg = (void*)1004; + + alltypes.req_sint32.funcs.decode = &read_svarint; + alltypes.req_sint32.arg = (void*)-1005; + + alltypes.req_sint64.funcs.decode = &read_svarint; + alltypes.req_sint64.arg = (void*)-1006; + + alltypes.req_bool.funcs.decode = &read_varint; + alltypes.req_bool.arg = (void*)true; + + alltypes.req_fixed32.funcs.decode = &read_fixed32; + alltypes.req_fixed32.arg = &req_fixed32; + + alltypes.req_sfixed32.funcs.decode = &read_fixed32; + alltypes.req_sfixed32.arg = &req_sfixed32; + + alltypes.req_float.funcs.decode = &read_fixed32; + alltypes.req_float.arg = &req_float; + + alltypes.req_fixed64.funcs.decode = &read_fixed64; + alltypes.req_fixed64.arg = &req_fixed64; + + alltypes.req_sfixed64.funcs.decode = &read_fixed64; + alltypes.req_sfixed64.arg = &req_sfixed64; + + alltypes.req_double.funcs.decode = &read_fixed64; + alltypes.req_double.arg = &req_double; + + alltypes.req_string.funcs.decode = &read_string; + alltypes.req_string.arg = "1014"; + + alltypes.req_bytes.funcs.decode = &read_string; + alltypes.req_bytes.arg = "1015"; + + alltypes.req_submsg.funcs.decode = &read_submsg; + alltypes.req_submsg.arg = &req_submsg; + + alltypes.req_enum.funcs.decode = &read_varint; + alltypes.req_enum.arg = (void*)MyEnum_Truth; + + alltypes.req_emptymsg.funcs.decode = &read_emptymsg; + + /* Bind callbacks for repeated fields */ + alltypes.rep_int32.funcs.decode = &read_repeated_varint; + alltypes.rep_int32.arg = rep_int32; + + alltypes.rep_int64.funcs.decode = &read_repeated_varint; + alltypes.rep_int64.arg = rep_int64; + + alltypes.rep_uint32.funcs.decode = &read_repeated_varint; + alltypes.rep_uint32.arg = rep_uint32; + + alltypes.rep_uint64.funcs.decode = &read_repeated_varint; + alltypes.rep_uint64.arg = rep_uint64; + + alltypes.rep_sint32.funcs.decode = &read_repeated_svarint; + alltypes.rep_sint32.arg = rep_sint32; + + alltypes.rep_sint64.funcs.decode = &read_repeated_svarint; + alltypes.rep_sint64.arg = rep_sint64; + + alltypes.rep_bool.funcs.decode = &read_repeated_varint; + alltypes.rep_bool.arg = rep_bool; + + alltypes.rep_fixed32.funcs.decode = &read_repeated_fixed32; + alltypes.rep_fixed32.arg = rep_fixed32; + + alltypes.rep_sfixed32.funcs.decode = &read_repeated_fixed32; + alltypes.rep_sfixed32.arg = rep_sfixed32; + + alltypes.rep_float.funcs.decode = &read_repeated_fixed32; + alltypes.rep_float.arg = rep_float; + + alltypes.rep_fixed64.funcs.decode = &read_repeated_fixed64; + alltypes.rep_fixed64.arg = rep_fixed64; + + alltypes.rep_sfixed64.funcs.decode = &read_repeated_fixed64; + alltypes.rep_sfixed64.arg = rep_sfixed64; + + alltypes.rep_double.funcs.decode = &read_repeated_fixed64; + alltypes.rep_double.arg = rep_double; + + alltypes.rep_string.funcs.decode = &read_repeated_string; + alltypes.rep_string.arg = rep_string; + + alltypes.rep_bytes.funcs.decode = &read_repeated_string; + alltypes.rep_bytes.arg = rep_bytes; + + alltypes.rep_submsg.funcs.decode = &read_repeated_submsg; + alltypes.rep_submsg.arg = rep_submsg; + + alltypes.rep_enum.funcs.decode = &read_repeated_varint; + alltypes.rep_enum.arg = rep_enum; + + alltypes.rep_emptymsg.funcs.decode = &read_emptymsg; + + alltypes.req_limits.funcs.decode = &read_limits; + + alltypes.end.funcs.decode = &read_varint; + alltypes.end.arg = (void*)1099; + + /* Bind callbacks for optional fields */ + if (mode == 1) + { + alltypes.opt_int32.funcs.decode = &read_varint; + alltypes.opt_int32.arg = (void*)3041; + + alltypes.opt_int64.funcs.decode = &read_varint; + alltypes.opt_int64.arg = (void*)3042; + + alltypes.opt_uint32.funcs.decode = &read_varint; + alltypes.opt_uint32.arg = (void*)3043; + + alltypes.opt_uint64.funcs.decode = &read_varint; + alltypes.opt_uint64.arg = (void*)3044; + + alltypes.opt_sint32.funcs.decode = &read_svarint; + alltypes.opt_sint32.arg = (void*)3045; + + alltypes.opt_sint64.funcs.decode = &read_svarint; + alltypes.opt_sint64.arg = (void*)3046; + + alltypes.opt_bool.funcs.decode = &read_varint; + alltypes.opt_bool.arg = (void*)true; + + alltypes.opt_fixed32.funcs.decode = &read_fixed32; + alltypes.opt_fixed32.arg = &opt_fixed32; + + alltypes.opt_sfixed32.funcs.decode = &read_fixed32; + alltypes.opt_sfixed32.arg = &opt_sfixed32; + + alltypes.opt_float.funcs.decode = &read_fixed32; + alltypes.opt_float.arg = &opt_float; + + alltypes.opt_fixed64.funcs.decode = &read_fixed64; + alltypes.opt_fixed64.arg = &opt_fixed64; + + alltypes.opt_sfixed64.funcs.decode = &read_fixed64; + alltypes.opt_sfixed64.arg = &opt_sfixed64; + + alltypes.opt_double.funcs.decode = &read_fixed64; + alltypes.opt_double.arg = &opt_double; + + alltypes.opt_string.funcs.decode = &read_string; + alltypes.opt_string.arg = "3054"; + + alltypes.opt_bytes.funcs.decode = &read_string; + alltypes.opt_bytes.arg = "3055"; + + alltypes.opt_submsg.funcs.decode = &read_submsg; + alltypes.opt_submsg.arg = &opt_submsg; + + alltypes.opt_enum.funcs.decode = &read_varint; + alltypes.opt_enum.arg = (void*)MyEnum_Truth; + + alltypes.opt_emptymsg.funcs.decode = &read_emptymsg; + + alltypes.oneof_msg1.funcs.decode = &read_submsg; + alltypes.oneof_msg1.arg = &oneof_msg1; + } + + status = pb_decode(stream, AllTypes_fields, &alltypes); + +#ifdef PB_ENABLE_MALLOC + /* Just to check for any interference between pb_release() and callback fields */ + pb_release(AllTypes_fields, &alltypes); +#endif + + return status; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!check_alltypes(&stream, mode)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/encode_alltypes_callback.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/encode_alltypes_callback.c new file mode 100644 index 00000000..b206783b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_callback/encode_alltypes_callback.c @@ -0,0 +1,411 @@ +/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields. + * Note that normally there would be no reason to use callback fields for this, + * because each encoder defined here only gives a single field. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +static bool write_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, (long)*arg); +} + +static bool write_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, (long)*arg); +} + +static bool write_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_fixed32(stream, *arg); +} + +static bool write_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_fixed64(stream, *arg); +} + +static bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, *arg, strlen(*arg)); +} + +static bool write_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, *arg); +} + +static bool write_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + EmptyMessage emptymsg = {0}; + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg); +} + +static bool write_repeated_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, (long)*arg); +} + +static bool write_repeated_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, (long)*arg); +} + +static bool write_repeated_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + uint32_t dummy = 0; + + /* Make it a packed field */ + return pb_encode_tag(stream, PB_WT_STRING, field->tag) && + pb_encode_varint(stream, 5 * 4) && /* Number of bytes */ + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, *arg); +} + +static bool write_repeated_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + uint64_t dummy = 0; + + /* Make it a packed field */ + return pb_encode_tag(stream, PB_WT_STRING, field->tag) && + pb_encode_varint(stream, 5 * 8) && /* Number of bytes */ + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, *arg); +} + +static bool write_repeated_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, *arg, strlen(*arg)); +} + +static bool write_repeated_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + SubMessage dummy = {""}; + + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, *arg); +} + +static bool write_limits(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + Limits limits = {0}; + limits.int32_min = INT32_MIN; + limits.int32_max = INT32_MAX; + limits.uint32_min = 0; + limits.uint32_max = UINT32_MAX; + limits.int64_min = INT64_MIN; + limits.int64_max = INT64_MAX; + limits.uint64_min = 0; + limits.uint64_max = UINT64_MAX; + limits.enum_min = HugeEnum_Negative; + limits.enum_max = HugeEnum_Positive; + + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, Limits_fields, &limits); +} + +static bool write_repeated_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + EmptyMessage emptymsg = {0}; + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg); +} + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Values for use from callbacks through pointers. */ + uint32_t req_fixed32 = 1008; + int32_t req_sfixed32 = -1009; + float req_float = 1010.0f; + uint64_t req_fixed64 = 1011; + int64_t req_sfixed64 = -1012; + double req_double = 1013.0; + SubMessage req_submsg = {"1016", 1016}; + + uint32_t rep_fixed32 = 2008; + int32_t rep_sfixed32 = -2009; + float rep_float = 2010.0f; + uint64_t rep_fixed64 = 2011; + int64_t rep_sfixed64 = -2012; + double rep_double = 2013.0; + SubMessage rep_submsg = {"2016", 2016, true, 2016}; + + uint32_t opt_fixed32 = 3048; + int32_t opt_sfixed32 = 3049; + float opt_float = 3050.0f; + uint64_t opt_fixed64 = 3051; + int64_t opt_sfixed64 = 3052; + double opt_double = 3053.0f; + SubMessage opt_submsg = {"3056", 3056}; + + SubMessage oneof_msg1 = {"4059", 4059}; + + /* Bind callbacks for required fields */ + AllTypes alltypes = {{{0}}}; + + alltypes.req_int32.funcs.encode = &write_varint; + alltypes.req_int32.arg = (void*)-1001; + + alltypes.req_int64.funcs.encode = &write_varint; + alltypes.req_int64.arg = (void*)-1002; + + alltypes.req_uint32.funcs.encode = &write_varint; + alltypes.req_uint32.arg = (void*)1003; + + alltypes.req_uint32.funcs.encode = &write_varint; + alltypes.req_uint32.arg = (void*)1003; + + alltypes.req_uint64.funcs.encode = &write_varint; + alltypes.req_uint64.arg = (void*)1004; + + alltypes.req_sint32.funcs.encode = &write_svarint; + alltypes.req_sint32.arg = (void*)-1005; + + alltypes.req_sint64.funcs.encode = &write_svarint; + alltypes.req_sint64.arg = (void*)-1006; + + alltypes.req_bool.funcs.encode = &write_varint; + alltypes.req_bool.arg = (void*)true; + + alltypes.req_fixed32.funcs.encode = &write_fixed32; + alltypes.req_fixed32.arg = &req_fixed32; + + alltypes.req_sfixed32.funcs.encode = &write_fixed32; + alltypes.req_sfixed32.arg = &req_sfixed32; + + alltypes.req_float.funcs.encode = &write_fixed32; + alltypes.req_float.arg = &req_float; + + alltypes.req_fixed64.funcs.encode = &write_fixed64; + alltypes.req_fixed64.arg = &req_fixed64; + + alltypes.req_sfixed64.funcs.encode = &write_fixed64; + alltypes.req_sfixed64.arg = &req_sfixed64; + + alltypes.req_double.funcs.encode = &write_fixed64; + alltypes.req_double.arg = &req_double; + + alltypes.req_string.funcs.encode = &write_string; + alltypes.req_string.arg = "1014"; + + alltypes.req_bytes.funcs.encode = &write_string; + alltypes.req_bytes.arg = "1015"; + + alltypes.req_submsg.funcs.encode = &write_submsg; + alltypes.req_submsg.arg = &req_submsg; + + alltypes.req_enum.funcs.encode = &write_varint; + alltypes.req_enum.arg = (void*)MyEnum_Truth; + + alltypes.req_emptymsg.funcs.encode = &write_emptymsg; + + alltypes.req_fbytes.funcs.encode = &write_string; + alltypes.req_fbytes.arg = "1019"; + + /* Bind callbacks for repeated fields */ + alltypes.rep_int32.funcs.encode = &write_repeated_varint; + alltypes.rep_int32.arg = (void*)-2001; + + alltypes.rep_int64.funcs.encode = &write_repeated_varint; + alltypes.rep_int64.arg = (void*)-2002; + + alltypes.rep_uint32.funcs.encode = &write_repeated_varint; + alltypes.rep_uint32.arg = (void*)2003; + + alltypes.rep_uint64.funcs.encode = &write_repeated_varint; + alltypes.rep_uint64.arg = (void*)2004; + + alltypes.rep_sint32.funcs.encode = &write_repeated_svarint; + alltypes.rep_sint32.arg = (void*)-2005; + + alltypes.rep_sint64.funcs.encode = &write_repeated_svarint; + alltypes.rep_sint64.arg = (void*)-2006; + + alltypes.rep_bool.funcs.encode = &write_repeated_varint; + alltypes.rep_bool.arg = (void*)true; + + alltypes.rep_fixed32.funcs.encode = &write_repeated_fixed32; + alltypes.rep_fixed32.arg = &rep_fixed32; + + alltypes.rep_sfixed32.funcs.encode = &write_repeated_fixed32; + alltypes.rep_sfixed32.arg = &rep_sfixed32; + + alltypes.rep_float.funcs.encode = &write_repeated_fixed32; + alltypes.rep_float.arg = &rep_float; + + alltypes.rep_fixed64.funcs.encode = &write_repeated_fixed64; + alltypes.rep_fixed64.arg = &rep_fixed64; + + alltypes.rep_sfixed64.funcs.encode = &write_repeated_fixed64; + alltypes.rep_sfixed64.arg = &rep_sfixed64; + + alltypes.rep_double.funcs.encode = &write_repeated_fixed64; + alltypes.rep_double.arg = &rep_double; + + alltypes.rep_string.funcs.encode = &write_repeated_string; + alltypes.rep_string.arg = "2014"; + + alltypes.rep_bytes.funcs.encode = &write_repeated_string; + alltypes.rep_bytes.arg = "2015"; + + alltypes.rep_submsg.funcs.encode = &write_repeated_submsg; + alltypes.rep_submsg.arg = &rep_submsg; + + alltypes.rep_enum.funcs.encode = &write_repeated_varint; + alltypes.rep_enum.arg = (void*)MyEnum_Truth; + + alltypes.rep_emptymsg.funcs.encode = &write_repeated_emptymsg; + + alltypes.rep_fbytes.funcs.encode = &write_repeated_string; + alltypes.rep_fbytes.arg = "2019"; + + alltypes.req_limits.funcs.encode = &write_limits; + + /* Bind callbacks for optional fields */ + if (mode != 0) + { + alltypes.opt_int32.funcs.encode = &write_varint; + alltypes.opt_int32.arg = (void*)3041; + + alltypes.opt_int64.funcs.encode = &write_varint; + alltypes.opt_int64.arg = (void*)3042; + + alltypes.opt_uint32.funcs.encode = &write_varint; + alltypes.opt_uint32.arg = (void*)3043; + + alltypes.opt_uint64.funcs.encode = &write_varint; + alltypes.opt_uint64.arg = (void*)3044; + + alltypes.opt_sint32.funcs.encode = &write_svarint; + alltypes.opt_sint32.arg = (void*)3045; + + alltypes.opt_sint64.funcs.encode = &write_svarint; + alltypes.opt_sint64.arg = (void*)3046; + + alltypes.opt_bool.funcs.encode = &write_varint; + alltypes.opt_bool.arg = (void*)true; + + alltypes.opt_fixed32.funcs.encode = &write_fixed32; + alltypes.opt_fixed32.arg = &opt_fixed32; + + alltypes.opt_sfixed32.funcs.encode = &write_fixed32; + alltypes.opt_sfixed32.arg = &opt_sfixed32; + + alltypes.opt_float.funcs.encode = &write_fixed32; + alltypes.opt_float.arg = &opt_float; + + alltypes.opt_fixed64.funcs.encode = &write_fixed64; + alltypes.opt_fixed64.arg = &opt_fixed64; + + alltypes.opt_sfixed64.funcs.encode = &write_fixed64; + alltypes.opt_sfixed64.arg = &opt_sfixed64; + + alltypes.opt_double.funcs.encode = &write_fixed64; + alltypes.opt_double.arg = &opt_double; + + alltypes.opt_string.funcs.encode = &write_string; + alltypes.opt_string.arg = "3054"; + + alltypes.opt_bytes.funcs.encode = &write_string; + alltypes.opt_bytes.arg = "3055"; + + alltypes.opt_submsg.funcs.encode = &write_submsg; + alltypes.opt_submsg.arg = &opt_submsg; + + alltypes.opt_enum.funcs.encode = &write_varint; + alltypes.opt_enum.arg = (void*)MyEnum_Truth; + + alltypes.opt_emptymsg.funcs.encode = &write_emptymsg; + + alltypes.opt_fbytes.funcs.encode = &write_string; + alltypes.opt_fbytes.arg = "3059"; + + alltypes.oneof_msg1.funcs.encode = &write_submsg; + alltypes.oneof_msg1.arg = &oneof_msg1; + } + + alltypes.end.funcs.encode = &write_varint; + alltypes.end.arg = (void*)1099; + + { + uint8_t buffer[2048]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/SConscript new file mode 100644 index 00000000..b095ae03 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/SConscript @@ -0,0 +1,40 @@ +# Encode the AllTypes message using pointers for all fields, and verify the +# output against the normal AllTypes test case. + +Import("env", "malloc_env") + +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.proto", "#alltypes/alltypes.proto", c) + +env.NanopbProto(["alltypes", "alltypes.options"]) +enc = malloc_env.Program(["encode_alltypes_pointer.c", + "alltypes.pb.c", + "$COMMON/pb_encode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) +dec = malloc_env.Program(["decode_alltypes_pointer.c", + "alltypes.pb.c", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) + +# Encode and compare results to non-pointer alltypes test case +env.RunTest(enc) +env.Compare(["encode_alltypes_pointer.output", "$BUILD/alltypes/encode_alltypes.output"]) + +# Decode (under valgrind if available) +valgrind = env.WhereIs('valgrind') +kwargs = {} +if valgrind: + kwargs['COMMAND'] = valgrind + kwargs['ARGS'] = ["-q", "--error-exitcode=99", dec[0].abspath] + +env.RunTest("decode_alltypes.output", [dec, "encode_alltypes_pointer.output"], **kwargs) + +# Do the same thing with the optional fields present +env.RunTest("optionals.output", enc, ARGS = ['1']) +env.Compare(["optionals.output", "$BUILD/alltypes/optionals.output"]) + +kwargs['ARGS'] = kwargs.get('ARGS', []) + ['1'] +env.RunTest("optionals.decout", [dec, "optionals.output"], **kwargs) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/alltypes.options new file mode 100644 index 00000000..8699fe27 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/alltypes.options @@ -0,0 +1,4 @@ +# Generate all fields as pointers. +* type:FT_POINTER +*.*fbytes fixed_length:true max_size:4 + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/decode_alltypes_pointer.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/decode_alltypes_pointer.c new file mode 100644 index 00000000..4ee6f8bf --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/decode_alltypes_pointer.c @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + fprintf(stderr, "Test " #x " failed.\n"); \ + status = false; \ + } + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + bool status = true; + AllTypes alltypes; + + /* Fill with garbage to better detect initialization errors */ + memset(&alltypes, 0xAA, sizeof(alltypes)); + alltypes.extensions = 0; + + if (!pb_decode(stream, AllTypes_fields, &alltypes)) + return false; + + TEST(alltypes.req_int32 && *alltypes.req_int32 == -1001); + TEST(alltypes.req_int64 && *alltypes.req_int64 == -1002); + TEST(alltypes.req_uint32 && *alltypes.req_uint32 == 1003); + TEST(alltypes.req_uint64 && *alltypes.req_uint64 == 1004); + TEST(alltypes.req_sint32 && *alltypes.req_sint32 == -1005); + TEST(alltypes.req_sint64 && *alltypes.req_sint64 == -1006); + TEST(alltypes.req_bool && *alltypes.req_bool == true); + + TEST(alltypes.req_fixed32 && *alltypes.req_fixed32 == 1008); + TEST(alltypes.req_sfixed32 && *alltypes.req_sfixed32 == -1009); + TEST(alltypes.req_float && *alltypes.req_float == 1010.0f); + + TEST(alltypes.req_fixed64 && *alltypes.req_fixed64 == 1011); + TEST(alltypes.req_sfixed64 && *alltypes.req_sfixed64 == -1012); + TEST(alltypes.req_double && *alltypes.req_double == 1013.0f); + + TEST(alltypes.req_string && strcmp(alltypes.req_string, "1014") == 0); + TEST(alltypes.req_bytes && alltypes.req_bytes->size == 4); + TEST(alltypes.req_bytes && memcmp(&alltypes.req_bytes->bytes, "1015", 4) == 0); + TEST(alltypes.req_submsg && alltypes.req_submsg->substuff1 + && strcmp(alltypes.req_submsg->substuff1, "1016") == 0); + TEST(alltypes.req_submsg && alltypes.req_submsg->substuff2 + && *alltypes.req_submsg->substuff2 == 1016); + TEST(alltypes.req_enum && *alltypes.req_enum == MyEnum_Truth); + TEST(alltypes.req_fbytes && memcmp(alltypes.req_fbytes, "1019", 4) == 0); + + TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0); + TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0); + TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0); + TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0); + TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0); + TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0); + TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false); + + TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0); + TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0); + TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f); + + TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0); + TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0); + TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0); + + TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0'); + TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4]->size == 4 && alltypes.rep_bytes[0]->size == 0); + TEST(memcmp(&alltypes.rep_bytes[4]->bytes, "2015", 4) == 0); + + TEST(alltypes.rep_submsg_count == 5); + TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0'); + TEST(*alltypes.rep_submsg[4].substuff2 == 2016 && *alltypes.rep_submsg[0].substuff2 == 0); + TEST(*alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == NULL); + + TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero); + TEST(alltypes.rep_emptymsg_count == 5); + TEST(alltypes.rep_fbytes_count == 5); + TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0); + TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0); + + if (mode == 0) + { + /* Expect that optional values are not present */ + TEST(alltypes.opt_int32 == NULL); + TEST(alltypes.opt_int64 == NULL); + TEST(alltypes.opt_uint32 == NULL); + TEST(alltypes.opt_uint64 == NULL); + TEST(alltypes.opt_sint32 == NULL); + TEST(alltypes.opt_sint64 == NULL); + TEST(alltypes.opt_bool == NULL); + + TEST(alltypes.opt_fixed32 == NULL); + TEST(alltypes.opt_sfixed32 == NULL); + TEST(alltypes.opt_float == NULL); + TEST(alltypes.opt_fixed64 == NULL); + TEST(alltypes.opt_sfixed64 == NULL); + TEST(alltypes.opt_double == NULL); + + TEST(alltypes.opt_string == NULL); + TEST(alltypes.opt_bytes == NULL); + TEST(alltypes.opt_submsg == NULL); + TEST(alltypes.opt_enum == NULL); + TEST(alltypes.opt_fbytes == NULL); + + TEST(alltypes.which_oneof == 0); + } + else + { + /* Expect filled-in values */ + TEST(alltypes.opt_int32 && *alltypes.opt_int32 == 3041); + TEST(alltypes.opt_int64 && *alltypes.opt_int64 == 3042); + TEST(alltypes.opt_uint32 && *alltypes.opt_uint32 == 3043); + TEST(alltypes.opt_uint64 && *alltypes.opt_uint64 == 3044); + TEST(alltypes.opt_sint32 && *alltypes.opt_sint32 == 3045); + TEST(alltypes.opt_sint64 && *alltypes.opt_sint64 == 3046); + TEST(alltypes.opt_bool && *alltypes.opt_bool == true); + + TEST(alltypes.opt_fixed32 && *alltypes.opt_fixed32 == 3048); + TEST(alltypes.opt_sfixed32 && *alltypes.opt_sfixed32== 3049); + TEST(alltypes.opt_float && *alltypes.opt_float == 3050.0f); + TEST(alltypes.opt_fixed64 && *alltypes.opt_fixed64 == 3051); + TEST(alltypes.opt_sfixed64 && *alltypes.opt_sfixed64== 3052); + TEST(alltypes.opt_double && *alltypes.opt_double == 3053.0); + + TEST(alltypes.opt_string && strcmp(alltypes.opt_string, "3054") == 0); + TEST(alltypes.opt_bytes && alltypes.opt_bytes->size == 4); + TEST(alltypes.opt_bytes && memcmp(&alltypes.opt_bytes->bytes, "3055", 4) == 0); + TEST(alltypes.opt_submsg && strcmp(alltypes.opt_submsg->substuff1, "3056") == 0); + TEST(alltypes.opt_submsg && *alltypes.opt_submsg->substuff2 == 3056); + TEST(alltypes.opt_enum && *alltypes.opt_enum == MyEnum_Truth); + TEST(alltypes.opt_emptymsg); + TEST(alltypes.opt_fbytes && memcmp(alltypes.opt_fbytes, "3059", 4) == 0); + + TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag); + TEST(alltypes.oneof.oneof_msg1 && strcmp(alltypes.oneof.oneof_msg1->substuff1, "4059") == 0); + TEST(alltypes.oneof.oneof_msg1->substuff2 && *alltypes.oneof.oneof_msg1->substuff2 == 4059); + } + + TEST(alltypes.req_limits->int32_min && *alltypes.req_limits->int32_min == INT32_MIN); + TEST(alltypes.req_limits->int32_max && *alltypes.req_limits->int32_max == INT32_MAX); + TEST(alltypes.req_limits->uint32_min && *alltypes.req_limits->uint32_min == 0); + TEST(alltypes.req_limits->uint32_max && *alltypes.req_limits->uint32_max == UINT32_MAX); + TEST(alltypes.req_limits->int64_min && *alltypes.req_limits->int64_min == INT64_MIN); + TEST(alltypes.req_limits->int64_max && *alltypes.req_limits->int64_max == INT64_MAX); + TEST(alltypes.req_limits->uint64_min && *alltypes.req_limits->uint64_min == 0); + TEST(alltypes.req_limits->uint64_max && *alltypes.req_limits->uint64_max == UINT64_MAX); + TEST(alltypes.req_limits->enum_min && *alltypes.req_limits->enum_min == HugeEnum_Negative); + TEST(alltypes.req_limits->enum_max && *alltypes.req_limits->enum_max == HugeEnum_Positive); + + TEST(alltypes.end && *alltypes.end == 1099); + + pb_release(AllTypes_fields, &alltypes); + + return status; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and verify the message */ + if (!check_alltypes(&stream, mode)) + { + fprintf(stderr, "Test failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + else + { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/encode_alltypes_pointer.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/encode_alltypes_pointer.c new file mode 100644 index 00000000..a39af6fa --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_pointer/encode_alltypes_pointer.c @@ -0,0 +1,200 @@ +/* Attempts to test all the datatypes supported by ProtoBuf. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Values for required fields */ + int32_t req_int32 = -1001; + int64_t req_int64 = -1002; + uint32_t req_uint32 = 1003; + uint64_t req_uint64 = 1004; + int32_t req_sint32 = -1005; + int64_t req_sint64 = -1006; + bool req_bool = true; + uint32_t req_fixed32 = 1008; + int32_t req_sfixed32 = -1009; + float req_float = 1010.0f; + uint64_t req_fixed64 = 1011; + int64_t req_sfixed64 = -1012; + double req_double = 1013.0; + char* req_string = "1014"; + PB_BYTES_ARRAY_T(4) req_bytes = {4, {'1', '0', '1', '5'}}; + static int32_t req_substuff = 1016; + SubMessage req_submsg = {"1016", &req_substuff}; + MyEnum req_enum = MyEnum_Truth; + EmptyMessage req_emptymsg = {0}; + pb_byte_t req_fbytes[4] = {'1', '0', '1', '9'}; + + int32_t end = 1099; + + /* Values for repeated fields */ + int32_t rep_int32[5] = {0, 0, 0, 0, -2001}; + int64_t rep_int64[5] = {0, 0, 0, 0, -2002}; + uint32_t rep_uint32[5] = {0, 0, 0, 0, 2003}; + uint64_t rep_uint64[5] = {0, 0, 0, 0, 2004}; + int32_t rep_sint32[5] = {0, 0, 0, 0, -2005}; + int64_t rep_sint64[5] = {0, 0, 0, 0, -2006}; + bool rep_bool[5] = {false, false, false, false, true}; + uint32_t rep_fixed32[5] = {0, 0, 0, 0, 2008}; + int32_t rep_sfixed32[5] = {0, 0, 0, 0, -2009}; + float rep_float[5] = {0, 0, 0, 0, 2010.0f}; + uint64_t rep_fixed64[5] = {0, 0, 0, 0, 2011}; + int64_t rep_sfixed64[5] = {0, 0, 0, 0, -2012}; + double rep_double[5] = {0, 0, 0, 0, 2013.0f}; + char* rep_string[5] = {"", "", "", "", "2014"}; + static PB_BYTES_ARRAY_T(4) rep_bytes_4 = {4, {'2', '0', '1', '5'}}; + pb_bytes_array_t *rep_bytes[5]= {NULL, NULL, NULL, NULL, (pb_bytes_array_t*)&rep_bytes_4}; + static int32_t rep_sub2zero = 0; + static int32_t rep_substuff2 = 2016; + static uint32_t rep_substuff3 = 2016; + SubMessage rep_submsg[5] = {{"", &rep_sub2zero}, + {"", &rep_sub2zero}, + {"", &rep_sub2zero}, + {"", &rep_sub2zero}, + {"2016", &rep_substuff2, &rep_substuff3}}; + MyEnum rep_enum[5] = {0, 0, 0, 0, MyEnum_Truth}; + EmptyMessage rep_emptymsg[5] = {{0}, {0}, {0}, {0}, {0}}; + pb_byte_t rep_fbytes[5][4] = {{0}, {0}, {0}, {0}, {'2', '0', '1', '9'}}; + + /* Values for optional fields */ + int32_t opt_int32 = 3041; + int64_t opt_int64 = 3042; + uint32_t opt_uint32 = 3043; + uint64_t opt_uint64 = 3044; + int32_t opt_sint32 = 3045; + int64_t opt_sint64 = 3046; + bool opt_bool = true; + uint32_t opt_fixed32 = 3048; + int32_t opt_sfixed32 = 3049; + float opt_float = 3050.0f; + uint64_t opt_fixed64 = 3051; + int64_t opt_sfixed64 = 3052; + double opt_double = 3053.0; + char* opt_string = "3054"; + PB_BYTES_ARRAY_T(4) opt_bytes = {4, {'3', '0', '5', '5'}}; + static int32_t opt_substuff = 3056; + SubMessage opt_submsg = {"3056", &opt_substuff}; + MyEnum opt_enum = MyEnum_Truth; + EmptyMessage opt_emptymsg = {0}; + pb_byte_t opt_fbytes[4] = {'3', '0', '5', '9'}; + + static int32_t oneof_substuff = 4059; + SubMessage oneof_msg1 = {"4059", &oneof_substuff}; + + /* Values for the Limits message. */ + static int32_t int32_min = INT32_MIN; + static int32_t int32_max = INT32_MAX; + static uint32_t uint32_min = 0; + static uint32_t uint32_max = UINT32_MAX; + static int64_t int64_min = INT64_MIN; + static int64_t int64_max = INT64_MAX; + static uint64_t uint64_min = 0; + static uint64_t uint64_max = UINT64_MAX; + static HugeEnum enum_min = HugeEnum_Negative; + static HugeEnum enum_max = HugeEnum_Positive; + Limits req_limits = {&int32_min, &int32_max, + &uint32_min, &uint32_max, + &int64_min, &int64_max, + &uint64_min, &uint64_max, + &enum_min, &enum_max}; + + /* Initialize the message struct with pointers to the fields. */ + AllTypes alltypes = {0}; + + alltypes.req_int32 = &req_int32; + alltypes.req_int64 = &req_int64; + alltypes.req_uint32 = &req_uint32; + alltypes.req_uint64 = &req_uint64; + alltypes.req_sint32 = &req_sint32; + alltypes.req_sint64 = &req_sint64; + alltypes.req_bool = &req_bool; + alltypes.req_fixed32 = &req_fixed32; + alltypes.req_sfixed32 = &req_sfixed32; + alltypes.req_float = &req_float; + alltypes.req_fixed64 = &req_fixed64; + alltypes.req_sfixed64 = &req_sfixed64; + alltypes.req_double = &req_double; + alltypes.req_string = req_string; + alltypes.req_bytes = (pb_bytes_array_t*)&req_bytes; + alltypes.req_submsg = &req_submsg; + alltypes.req_enum = &req_enum; + alltypes.req_emptymsg = &req_emptymsg; + alltypes.req_fbytes = &req_fbytes; + alltypes.req_limits = &req_limits; + + alltypes.rep_int32_count = 5; alltypes.rep_int32 = rep_int32; + alltypes.rep_int64_count = 5; alltypes.rep_int64 = rep_int64; + alltypes.rep_uint32_count = 5; alltypes.rep_uint32 = rep_uint32; + alltypes.rep_uint64_count = 5; alltypes.rep_uint64 = rep_uint64; + alltypes.rep_sint32_count = 5; alltypes.rep_sint32 = rep_sint32; + alltypes.rep_sint64_count = 5; alltypes.rep_sint64 = rep_sint64; + alltypes.rep_bool_count = 5; alltypes.rep_bool = rep_bool; + alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32 = rep_fixed32; + alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32 = rep_sfixed32; + alltypes.rep_float_count = 5; alltypes.rep_float = rep_float; + alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64 = rep_fixed64; + alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64 = rep_sfixed64; + alltypes.rep_double_count = 5; alltypes.rep_double = rep_double; + alltypes.rep_string_count = 5; alltypes.rep_string = rep_string; + alltypes.rep_bytes_count = 5; alltypes.rep_bytes = rep_bytes; + alltypes.rep_submsg_count = 5; alltypes.rep_submsg = rep_submsg; + alltypes.rep_enum_count = 5; alltypes.rep_enum = rep_enum; + alltypes.rep_emptymsg_count = 5; alltypes.rep_emptymsg = rep_emptymsg; + alltypes.rep_fbytes_count = 5; alltypes.rep_fbytes = rep_fbytes; + + if (mode != 0) + { + /* Fill in values for optional fields */ + alltypes.opt_int32 = &opt_int32; + alltypes.opt_int64 = &opt_int64; + alltypes.opt_uint32 = &opt_uint32; + alltypes.opt_uint64 = &opt_uint64; + alltypes.opt_sint32 = &opt_sint32; + alltypes.opt_sint64 = &opt_sint64; + alltypes.opt_bool = &opt_bool; + alltypes.opt_fixed32 = &opt_fixed32; + alltypes.opt_sfixed32 = &opt_sfixed32; + alltypes.opt_float = &opt_float; + alltypes.opt_fixed64 = &opt_fixed64; + alltypes.opt_sfixed64 = &opt_sfixed64; + alltypes.opt_double = &opt_double; + alltypes.opt_string = opt_string; + alltypes.opt_bytes = (pb_bytes_array_t*)&opt_bytes; + alltypes.opt_submsg = &opt_submsg; + alltypes.opt_enum = &opt_enum; + alltypes.opt_emptymsg = &opt_emptymsg; + alltypes.opt_fbytes = &opt_fbytes; + + alltypes.which_oneof = AllTypes_oneof_msg1_tag; + alltypes.oneof.oneof_msg1 = &oneof_msg1; + } + + alltypes.end = &end; + + { + uint8_t buffer[4096]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/SConscript new file mode 100644 index 00000000..c0b2fc1b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/SConscript @@ -0,0 +1,45 @@ +# Version of AllTypes test case for protobuf 3 file format. + +Import("env") + +import re +match = None +if 'PROTOC_VERSION' in env: + match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION']) + +if match: + version = map(int, match.groups()) + +# proto3 syntax is supported by protoc >= 3.0.0 +if env.GetOption('clean') or (match and version[0] >= 3): + + env.NanopbProto(["alltypes", "alltypes.options"]) + enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) + dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + + # Test the round-trip from nanopb encoder to nanopb decoder + env.RunTest(enc) + env.RunTest([dec, "encode_alltypes.output"]) + + # Re-encode the data using protoc, and check that the results from nanopb + # match byte-per-byte to the protoc output. + env.Decode("encode_alltypes.output.decoded", + ["encode_alltypes.output", "alltypes.proto"], + MESSAGE='AllTypes') + env.Encode("encode_alltypes.output.recoded", + ["encode_alltypes.output.decoded", "alltypes.proto"], + MESSAGE='AllTypes') + env.Compare(["encode_alltypes.output", "encode_alltypes.output.recoded"]) + + # Do the same checks with the optional fields present. + env.RunTest("optionals.output", enc, ARGS = ['1']) + env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) + env.Decode("optionals.output.decoded", + ["optionals.output", "alltypes.proto"], + MESSAGE='AllTypes') + env.Encode("optionals.output.recoded", + ["optionals.output.decoded", "alltypes.proto"], + MESSAGE='AllTypes') + env.Compare(["optionals.output", "optionals.output.recoded"]) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.options new file mode 100644 index 00000000..78dd08d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.options @@ -0,0 +1,4 @@ +* max_size:16 +* max_count:5 +*.*fbytes fixed_length:true max_size:4 + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.proto new file mode 100644 index 00000000..f66109ec --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/alltypes.proto @@ -0,0 +1,100 @@ +syntax = "proto3"; +// package name placeholder + +message SubMessage { + string substuff1 = 1; + int32 substuff2 = 2; + fixed32 substuff3 = 3; +} + +message EmptyMessage { + +} + +enum HugeEnum { + HE_Zero = 0; + Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ + Positive = 2147483647; +} + +message Limits { + int32 int32_min = 1; + int32 int32_max = 2; + uint32 uint32_min = 3; + uint32 uint32_max = 4; + int64 int64_min = 5; + int64 int64_max = 6; + uint64 uint64_min = 7; + uint64 uint64_max = 8; + HugeEnum enum_min = 9; + HugeEnum enum_max = 10; +} + +enum MyEnum { + Zero = 0; + First = 1; + Second = 2; + Truth = 42; +} + +message AllTypes { + int32 sng_int32 = 1; + int64 sng_int64 = 2; + uint32 sng_uint32 = 3; + uint64 sng_uint64 = 4; + sint32 sng_sint32 = 5; + sint64 sng_sint64 = 6; + bool sng_bool = 7; + + fixed32 sng_fixed32 = 8; + sfixed32 sng_sfixed32= 9; + float sng_float = 10; + + fixed64 sng_fixed64 = 11; + sfixed64 sng_sfixed64= 12; + double sng_double = 13; + + string sng_string = 14; + bytes sng_bytes = 15; + SubMessage sng_submsg = 16; + MyEnum sng_enum = 17; + EmptyMessage sng_emptymsg = 18; + bytes sng_fbytes = 19; + + repeated int32 rep_int32 = 21 [packed = true]; + repeated int64 rep_int64 = 22 [packed = true]; + repeated uint32 rep_uint32 = 23 [packed = true]; + repeated uint64 rep_uint64 = 24 [packed = true]; + repeated sint32 rep_sint32 = 25 [packed = true]; + repeated sint64 rep_sint64 = 26 [packed = true]; + repeated bool rep_bool = 27 [packed = true]; + + repeated fixed32 rep_fixed32 = 28 [packed = true]; + repeated sfixed32 rep_sfixed32= 29 [packed = true]; + repeated float rep_float = 30 [packed = true]; + + repeated fixed64 rep_fixed64 = 31 [packed = true]; + repeated sfixed64 rep_sfixed64= 32 [packed = true]; + repeated double rep_double = 33 [packed = true]; + + repeated string rep_string = 34; + repeated bytes rep_bytes = 35; + repeated SubMessage rep_submsg = 36; + repeated MyEnum rep_enum = 37 [packed = true]; + repeated EmptyMessage rep_emptymsg = 38; + repeated bytes rep_fbytes = 39; + + oneof oneof + { + SubMessage oneof_msg1 = 59; + EmptyMessage oneof_msg2 = 60; + } + + // Check that extreme integer values are handled correctly + Limits req_limits = 98; + + // Just to make sure that the size of the fields has been calculated + // properly, i.e. otherwise a bug in last field might not be detected. + int32 end = 99; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/decode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/decode_alltypes.c new file mode 100644 index 00000000..51c1c41e --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/decode_alltypes.c @@ -0,0 +1,167 @@ +/* Tests the decoding of all types. + * This is the counterpart of test_encode3. + * Run e.g. ./test_encode3 | ./test_decode3 + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed.\n"); \ + return false; \ + } + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + AllTypes alltypes = AllTypes_init_zero; + + /* Fill with garbage to better detect initialization errors */ + memset(&alltypes, 0xAA, sizeof(alltypes)); + + if (!pb_decode(stream, AllTypes_fields, &alltypes)) + return false; + + TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0); + TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0); + TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0); + TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0); + TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0); + TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0); + TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false); + + TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0); + TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0); + TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f); + + TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0); + TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0); + TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0); + + TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0'); + TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0); + TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0); + + TEST(alltypes.rep_submsg_count == 5); + TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0'); + TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0); + TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 0); + + TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero); + TEST(alltypes.rep_emptymsg_count == 5); + + TEST(alltypes.rep_fbytes_count == 5); + TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0); + TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0); + + if (mode == 0) + { + /* Expect default values */ + TEST(alltypes.sng_int32 == 0); + TEST(alltypes.sng_int64 == 0); + TEST(alltypes.sng_uint32 == 0); + TEST(alltypes.sng_uint64 == 0); + TEST(alltypes.sng_sint32 == 0); + TEST(alltypes.sng_sint64 == 0); + TEST(alltypes.sng_bool == false); + + TEST(alltypes.sng_fixed32 == 0); + TEST(alltypes.sng_sfixed32 == 0); + TEST(alltypes.sng_float == 0.0f); + + TEST(alltypes.sng_fixed64 == 0); + TEST(alltypes.sng_sfixed64 == 0); + TEST(alltypes.sng_double == 0.0); + + TEST(strcmp(alltypes.sng_string, "") == 0); + TEST(alltypes.sng_bytes.size == 0); + TEST(strcmp(alltypes.sng_submsg.substuff1, "") == 0); + TEST(alltypes.sng_submsg.substuff2 == 0); + TEST(alltypes.sng_submsg.substuff3 == 0); + TEST(alltypes.sng_enum == MyEnum_Zero); + TEST(alltypes.sng_fbytes[0] == 0 && + alltypes.sng_fbytes[1] == 0 && + alltypes.sng_fbytes[2] == 0 && + alltypes.sng_fbytes[3] == 0); + + TEST(alltypes.which_oneof == 0); + } + else + { + /* Expect filled-in values */ + TEST(alltypes.sng_int32 == 3041); + TEST(alltypes.sng_int64 == 3042); + TEST(alltypes.sng_uint32 == 3043); + TEST(alltypes.sng_uint64 == 3044); + TEST(alltypes.sng_sint32 == 3045); + TEST(alltypes.sng_sint64 == 3046); + TEST(alltypes.sng_bool == true); + + TEST(alltypes.sng_fixed32 == 3048); + TEST(alltypes.sng_sfixed32 == 3049); + TEST(alltypes.sng_float == 3050.0f); + + TEST(alltypes.sng_fixed64 == 3051); + TEST(alltypes.sng_sfixed64 == 3052); + TEST(alltypes.sng_double == 3053.0); + + TEST(strcmp(alltypes.sng_string, "3054") == 0); + TEST(alltypes.sng_bytes.size == 4); + TEST(memcmp(alltypes.sng_bytes.bytes, "3055", 4) == 0); + TEST(strcmp(alltypes.sng_submsg.substuff1, "3056") == 0); + TEST(alltypes.sng_submsg.substuff2 == 3056); + TEST(alltypes.sng_submsg.substuff3 == 0); + TEST(alltypes.sng_enum == MyEnum_Truth); + TEST(memcmp(alltypes.sng_fbytes, "3059", 4) == 0); + + TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag); + TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0); + TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059); + } + + TEST(alltypes.req_limits.int32_min == INT32_MIN); + TEST(alltypes.req_limits.int32_max == INT32_MAX); + TEST(alltypes.req_limits.uint32_min == 0); + TEST(alltypes.req_limits.uint32_max == UINT32_MAX); + TEST(alltypes.req_limits.int64_min == INT64_MIN); + TEST(alltypes.req_limits.int64_max == INT64_MAX); + TEST(alltypes.req_limits.uint64_min == 0); + TEST(alltypes.req_limits.uint64_max == UINT64_MAX); + TEST(alltypes.req_limits.enum_min == HugeEnum_Negative); + TEST(alltypes.req_limits.enum_max == HugeEnum_Positive); + + TEST(alltypes.end == 1099); + + return true; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!check_alltypes(&stream, mode)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/encode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/encode_alltypes.c new file mode 100644 index 00000000..1da06688 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3/encode_alltypes.c @@ -0,0 +1,111 @@ +/* Attempts to test all the datatypes supported by ProtoBuf3. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Initialize the structure with constants */ + AllTypes alltypes = AllTypes_init_zero; + + alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001; + alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002; + alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003; + alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004; + alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005; + alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006; + alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true; + + alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008; + alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009; + alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f; + + alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011; + alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012; + alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0; + + alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014"); + alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4; + memcpy(alltypes.rep_bytes[4].bytes, "2015", 4); + + alltypes.rep_submsg_count = 5; + strcpy(alltypes.rep_submsg[4].substuff1, "2016"); + alltypes.rep_submsg[4].substuff2 = 2016; + alltypes.rep_submsg[4].substuff3 = 2016; + + alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth; + alltypes.rep_emptymsg_count = 5; + + alltypes.rep_fbytes_count = 5; + memcpy(alltypes.rep_fbytes[4], "2019", 4); + + alltypes.req_limits.int32_min = INT32_MIN; + alltypes.req_limits.int32_max = INT32_MAX; + alltypes.req_limits.uint32_min = 0; + alltypes.req_limits.uint32_max = UINT32_MAX; + alltypes.req_limits.int64_min = INT64_MIN; + alltypes.req_limits.int64_max = INT64_MAX; + alltypes.req_limits.uint64_min = 0; + alltypes.req_limits.uint64_max = UINT64_MAX; + alltypes.req_limits.enum_min = HugeEnum_Negative; + alltypes.req_limits.enum_max = HugeEnum_Positive; + + if (mode != 0) + { + /* Fill in values for singular fields */ + alltypes.sng_int32 = 3041; + alltypes.sng_int64 = 3042; + alltypes.sng_uint32 = 3043; + alltypes.sng_uint64 = 3044; + alltypes.sng_sint32 = 3045; + alltypes.sng_sint64 = 3046; + alltypes.sng_bool = true; + + alltypes.sng_fixed32 = 3048; + alltypes.sng_sfixed32 = 3049; + alltypes.sng_float = 3050.0f; + + alltypes.sng_fixed64 = 3051; + alltypes.sng_sfixed64 = 3052; + alltypes.sng_double = 3053.0; + + strcpy(alltypes.sng_string, "3054"); + alltypes.sng_bytes.size = 4; + memcpy(alltypes.sng_bytes.bytes, "3055", 4); + strcpy(alltypes.sng_submsg.substuff1, "3056"); + alltypes.sng_submsg.substuff2 = 3056; + alltypes.sng_enum = MyEnum_Truth; + memcpy(alltypes.sng_fbytes, "3059", 4); + + alltypes.which_oneof = AllTypes_oneof_msg1_tag; + strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059"); + alltypes.oneof.oneof_msg1.substuff2 = 4059; + } + + alltypes.end = 1099; + + { + uint8_t buffer[AllTypes_size]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/SConscript new file mode 100644 index 00000000..183a138a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/SConscript @@ -0,0 +1,23 @@ +# Test the AllTypes encoding & decoding using callbacks for all fields. + +Import("env", "malloc_env") + +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.proto", "#alltypes_proto3/alltypes.proto", c) + +env.NanopbProto(["alltypes", "alltypes.options"]) +enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +refdec = "$BUILD/alltypes_proto3/decode_alltypes$PROGSUFFIX" + +# Encode and compare results +env.RunTest(enc) +env.RunTest("decode_alltypes.output", [refdec, "encode_alltypes_callback.output"]) +env.RunTest("decode_alltypes_callback.output", [dec, "encode_alltypes_callback.output"]) + +# Do the same thing with the optional fields present +env.RunTest("optionals.output", enc, ARGS = ['1']) +env.RunTest("optionals.refdecout", [refdec, "optionals.output"], ARGS = ['1']) +env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/alltypes.options new file mode 100644 index 00000000..74d7a9c0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/alltypes.options @@ -0,0 +1,8 @@ +# Generate all fields as callbacks. +AllTypes.* type:FT_CALLBACK +SubMessage.substuff1 max_size:16 +AllTypes.oneof no_unions:true + +# With FT_CALLBACK, these options should get ignored +*.*fbytes fixed_length:true max_size:4 + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/decode_alltypes_callback.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/decode_alltypes_callback.c new file mode 100644 index 00000000..2b3c2f32 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/decode_alltypes_callback.c @@ -0,0 +1,376 @@ +/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields. + * Note that normally there would be no reason to use callback fields for this, + * because each encoder defined here only gives a single field. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed (in field %d).\n", field->tag); \ + return false; \ + } + +static bool read_varint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + TEST((int64_t)value == (long)*arg); + return true; +} + +static bool read_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + int64_t value; + if (!pb_decode_svarint(stream, &value)) + return false; + + TEST(value == (long)*arg); + return true; +} + +static bool read_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint32_t value; + if (!pb_decode_fixed32(stream, &value)) + return false; + + TEST(value == *(uint32_t*)*arg); + return true; +} + +static bool read_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t value; + if (!pb_decode_fixed64(stream, &value)) + return false; + + TEST(value == *(uint64_t*)*arg); + return true; +} + +static bool read_string(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint8_t buf[16] = {0}; + size_t len = stream->bytes_left; + + if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len)) + return false; + + TEST(strcmp((char*)buf, *arg) == 0); + return true; +} + +static bool read_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + SubMessage submsg = {""}; + SubMessage *ref = *arg; + + if (!pb_decode(stream, SubMessage_fields, &submsg)) + return false; + + TEST(strcmp(submsg.substuff1, ref->substuff1) == 0); + TEST(submsg.substuff2 == ref->substuff2); + TEST(submsg.substuff3 == ref->substuff3); + return true; +} + +static bool read_emptymsg(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + EmptyMessage emptymsg = {0}; + return pb_decode(stream, EmptyMessage_fields, &emptymsg); +} + +static bool read_repeated_varint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + int32_t** expected = (int32_t**)arg; + uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + int32_t** expected = (int32_t**)arg; + int64_t value; + if (!pb_decode_svarint(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint32_t** expected = (uint32_t**)arg; + uint32_t value; + if (!pb_decode_fixed32(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t** expected = (uint64_t**)arg; + uint64_t value; + if (!pb_decode_fixed64(stream, &value)) + return false; + + TEST(*(*expected)++ == value); + return true; +} + +static bool read_repeated_string(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint8_t*** expected = (uint8_t***)arg; + uint8_t buf[16] = {0}; + size_t len = stream->bytes_left; + + if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len)) + return false; + + TEST(strcmp((char*)*(*expected)++, (char*)buf) == 0); + return true; +} + +static bool read_repeated_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + SubMessage** expected = (SubMessage**)arg; + SubMessage submsg = {""}; + if (!pb_decode(stream, SubMessage_fields, &submsg)) + return false; + + TEST(strcmp(submsg.substuff1, (*expected)->substuff1) == 0); + TEST(submsg.substuff2 == (*expected)->substuff2); + TEST(submsg.substuff3 == (*expected)->substuff3); + (*expected)++; + + return true; +} + +static bool read_limits(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + Limits decoded = {0}; + if (!pb_decode(stream, Limits_fields, &decoded)) + return false; + + TEST(decoded.int32_min == INT32_MIN); + TEST(decoded.int32_max == INT32_MAX); + TEST(decoded.uint32_min == 0); + TEST(decoded.uint32_max == UINT32_MAX); + TEST(decoded.int64_min == INT64_MIN); + TEST(decoded.int64_max == INT64_MAX); + TEST(decoded.uint64_min == 0); + TEST(decoded.uint64_max == UINT64_MAX); + TEST(decoded.enum_min == HugeEnum_Negative); + TEST(decoded.enum_max == HugeEnum_Positive); + + return true; +} + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + /* Values for use from callbacks through pointers. */ + bool status; + + int32_t rep_int32[5] = {0, 0, 0, 0, -2001}; + int32_t rep_int64[5] = {0, 0, 0, 0, -2002}; + int32_t rep_uint32[5] = {0, 0, 0, 0, 2003}; + int32_t rep_uint64[5] = {0, 0, 0, 0, 2004}; + int32_t rep_sint32[5] = {0, 0, 0, 0, -2005}; + int32_t rep_sint64[5] = {0, 0, 0, 0, -2006}; + int32_t rep_bool[5] = {false, false, false, false, true}; + uint32_t rep_fixed32[5] = {0, 0, 0, 0, 2008}; + int32_t rep_sfixed32[5] = {0, 0, 0, 0, -2009}; + float rep_float[5] = {0, 0, 0, 0, 2010.0f}; + uint64_t rep_fixed64[5] = {0, 0, 0, 0, 2011}; + int64_t rep_sfixed64[5] = {0, 0, 0, 0, -2012}; + double rep_double[5] = {0, 0, 0, 0, 2013.0}; + char* rep_string[5] = {"", "", "", "", "2014"}; + char* rep_bytes[5] = {"", "", "", "", "2015"}; + SubMessage rep_submsg[5] = {{"", 0, 0}, + {"", 0, 0}, + {"", 0, 0}, + {"", 0, 0}, + {"2016", 2016, 2016}}; + int32_t rep_enum[5] = {0, 0, 0, 0, MyEnum_Truth}; + + uint32_t sng_fixed32 = 3048; + int32_t sng_sfixed32 = 3049; + float sng_float = 3050.0f; + uint64_t sng_fixed64 = 3051; + int64_t sng_sfixed64 = 3052; + double sng_double = 3053.0f; + SubMessage sng_submsg = {"3056", 3056}; + + SubMessage oneof_msg1 = {"4059", 4059}; + + AllTypes alltypes = AllTypes_init_zero; + + /* Bind callbacks for repeated fields */ + alltypes.rep_int32.funcs.decode = &read_repeated_varint; + alltypes.rep_int32.arg = rep_int32; + + alltypes.rep_int64.funcs.decode = &read_repeated_varint; + alltypes.rep_int64.arg = rep_int64; + + alltypes.rep_uint32.funcs.decode = &read_repeated_varint; + alltypes.rep_uint32.arg = rep_uint32; + + alltypes.rep_uint64.funcs.decode = &read_repeated_varint; + alltypes.rep_uint64.arg = rep_uint64; + + alltypes.rep_sint32.funcs.decode = &read_repeated_svarint; + alltypes.rep_sint32.arg = rep_sint32; + + alltypes.rep_sint64.funcs.decode = &read_repeated_svarint; + alltypes.rep_sint64.arg = rep_sint64; + + alltypes.rep_bool.funcs.decode = &read_repeated_varint; + alltypes.rep_bool.arg = rep_bool; + + alltypes.rep_fixed32.funcs.decode = &read_repeated_fixed32; + alltypes.rep_fixed32.arg = rep_fixed32; + + alltypes.rep_sfixed32.funcs.decode = &read_repeated_fixed32; + alltypes.rep_sfixed32.arg = rep_sfixed32; + + alltypes.rep_float.funcs.decode = &read_repeated_fixed32; + alltypes.rep_float.arg = rep_float; + + alltypes.rep_fixed64.funcs.decode = &read_repeated_fixed64; + alltypes.rep_fixed64.arg = rep_fixed64; + + alltypes.rep_sfixed64.funcs.decode = &read_repeated_fixed64; + alltypes.rep_sfixed64.arg = rep_sfixed64; + + alltypes.rep_double.funcs.decode = &read_repeated_fixed64; + alltypes.rep_double.arg = rep_double; + + alltypes.rep_string.funcs.decode = &read_repeated_string; + alltypes.rep_string.arg = rep_string; + + alltypes.rep_bytes.funcs.decode = &read_repeated_string; + alltypes.rep_bytes.arg = rep_bytes; + + alltypes.rep_submsg.funcs.decode = &read_repeated_submsg; + alltypes.rep_submsg.arg = rep_submsg; + + alltypes.rep_enum.funcs.decode = &read_repeated_varint; + alltypes.rep_enum.arg = rep_enum; + + alltypes.rep_emptymsg.funcs.decode = &read_emptymsg; + + alltypes.req_limits.funcs.decode = &read_limits; + + alltypes.end.funcs.decode = &read_varint; + alltypes.end.arg = (void*)1099; + + /* Bind callbacks for optional fields */ + if (mode == 1) + { + alltypes.sng_int32.funcs.decode = &read_varint; + alltypes.sng_int32.arg = (void*)3041; + + alltypes.sng_int64.funcs.decode = &read_varint; + alltypes.sng_int64.arg = (void*)3042; + + alltypes.sng_uint32.funcs.decode = &read_varint; + alltypes.sng_uint32.arg = (void*)3043; + + alltypes.sng_uint64.funcs.decode = &read_varint; + alltypes.sng_uint64.arg = (void*)3044; + + alltypes.sng_sint32.funcs.decode = &read_svarint; + alltypes.sng_sint32.arg = (void*)3045; + + alltypes.sng_sint64.funcs.decode = &read_svarint; + alltypes.sng_sint64.arg = (void*)3046; + + alltypes.sng_bool.funcs.decode = &read_varint; + alltypes.sng_bool.arg = (void*)true; + + alltypes.sng_fixed32.funcs.decode = &read_fixed32; + alltypes.sng_fixed32.arg = &sng_fixed32; + + alltypes.sng_sfixed32.funcs.decode = &read_fixed32; + alltypes.sng_sfixed32.arg = &sng_sfixed32; + + alltypes.sng_float.funcs.decode = &read_fixed32; + alltypes.sng_float.arg = &sng_float; + + alltypes.sng_fixed64.funcs.decode = &read_fixed64; + alltypes.sng_fixed64.arg = &sng_fixed64; + + alltypes.sng_sfixed64.funcs.decode = &read_fixed64; + alltypes.sng_sfixed64.arg = &sng_sfixed64; + + alltypes.sng_double.funcs.decode = &read_fixed64; + alltypes.sng_double.arg = &sng_double; + + alltypes.sng_string.funcs.decode = &read_string; + alltypes.sng_string.arg = "3054"; + + alltypes.sng_bytes.funcs.decode = &read_string; + alltypes.sng_bytes.arg = "3055"; + + alltypes.sng_submsg.funcs.decode = &read_submsg; + alltypes.sng_submsg.arg = &sng_submsg; + + alltypes.sng_enum.funcs.decode = &read_varint; + alltypes.sng_enum.arg = (void*)MyEnum_Truth; + + alltypes.sng_emptymsg.funcs.decode = &read_emptymsg; + + alltypes.oneof_msg1.funcs.decode = &read_submsg; + alltypes.oneof_msg1.arg = &oneof_msg1; + } + + status = pb_decode(stream, AllTypes_fields, &alltypes); + +#ifdef PB_ENABLE_MALLOC + /* Just to check for any interference between pb_release() and callback fields */ + pb_release(AllTypes_fields, &alltypes); +#endif + + return status; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!check_alltypes(&stream, mode)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/encode_alltypes_callback.c b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/encode_alltypes_callback.c new file mode 100644 index 00000000..8c7bdd66 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/alltypes_proto3_callback/encode_alltypes_callback.c @@ -0,0 +1,343 @@ +/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields. + * Note that normally there would be no reason to use callback fields for this, + * because each encoder defined here only gives a single field. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +static bool write_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, (long)*arg); +} + +static bool write_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, (long)*arg); +} + +static bool write_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_fixed32(stream, *arg); +} + +static bool write_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_fixed64(stream, *arg); +} + +static bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, *arg, strlen(*arg)); +} + +static bool write_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, *arg); +} + +static bool write_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + EmptyMessage emptymsg = {0}; + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg); +} + +static bool write_repeated_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, (long)*arg); +} + +static bool write_repeated_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_svarint(stream, (long)*arg); +} + +static bool write_repeated_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + uint32_t dummy = 0; + + /* Make it a packed field */ + return pb_encode_tag(stream, PB_WT_STRING, field->tag) && + pb_encode_varint(stream, 5 * 4) && /* Number of bytes */ + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, &dummy) && + pb_encode_fixed32(stream, *arg); +} + +static bool write_repeated_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + uint64_t dummy = 0; + + /* Make it a packed field */ + return pb_encode_tag(stream, PB_WT_STRING, field->tag) && + pb_encode_varint(stream, 5 * 8) && /* Number of bytes */ + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, &dummy) && + pb_encode_fixed64(stream, *arg); +} + +static bool write_repeated_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + return pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, 0, 0) && + pb_encode_tag_for_field(stream, field) && + pb_encode_string(stream, *arg, strlen(*arg)); +} + +static bool write_repeated_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + SubMessage dummy = {""}; + + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, &dummy) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, SubMessage_fields, *arg); +} + +static bool write_limits(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + Limits limits = {0}; + limits.int32_min = INT32_MIN; + limits.int32_max = INT32_MAX; + limits.uint32_min = 0; + limits.uint32_max = UINT32_MAX; + limits.int64_min = INT64_MIN; + limits.int64_max = INT64_MAX; + limits.uint64_min = 0; + limits.uint64_max = UINT64_MAX; + limits.enum_min = HugeEnum_Negative; + limits.enum_max = HugeEnum_Positive; + + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, Limits_fields, &limits); +} + +static bool write_repeated_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + EmptyMessage emptymsg = {0}; + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) && + pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg); +} + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Values for use from callbacks through pointers. */ + uint32_t rep_fixed32 = 2008; + int32_t rep_sfixed32 = -2009; + float rep_float = 2010.0f; + uint64_t rep_fixed64 = 2011; + int64_t rep_sfixed64 = -2012; + double rep_double = 2013.0; + SubMessage rep_submsg = {"2016", 2016, 2016}; + + uint32_t sng_fixed32 = 3048; + int32_t sng_sfixed32 = 3049; + float sng_float = 3050.0f; + uint64_t sng_fixed64 = 3051; + int64_t sng_sfixed64 = 3052; + double sng_double = 3053.0f; + SubMessage sng_submsg = {"3056", 3056}; + + SubMessage oneof_msg1 = {"4059", 4059}; + + AllTypes alltypes = AllTypes_init_zero; + + /* Bind callbacks for repeated fields */ + alltypes.rep_int32.funcs.encode = &write_repeated_varint; + alltypes.rep_int32.arg = (void*)-2001; + + alltypes.rep_int64.funcs.encode = &write_repeated_varint; + alltypes.rep_int64.arg = (void*)-2002; + + alltypes.rep_uint32.funcs.encode = &write_repeated_varint; + alltypes.rep_uint32.arg = (void*)2003; + + alltypes.rep_uint64.funcs.encode = &write_repeated_varint; + alltypes.rep_uint64.arg = (void*)2004; + + alltypes.rep_sint32.funcs.encode = &write_repeated_svarint; + alltypes.rep_sint32.arg = (void*)-2005; + + alltypes.rep_sint64.funcs.encode = &write_repeated_svarint; + alltypes.rep_sint64.arg = (void*)-2006; + + alltypes.rep_bool.funcs.encode = &write_repeated_varint; + alltypes.rep_bool.arg = (void*)true; + + alltypes.rep_fixed32.funcs.encode = &write_repeated_fixed32; + alltypes.rep_fixed32.arg = &rep_fixed32; + + alltypes.rep_sfixed32.funcs.encode = &write_repeated_fixed32; + alltypes.rep_sfixed32.arg = &rep_sfixed32; + + alltypes.rep_float.funcs.encode = &write_repeated_fixed32; + alltypes.rep_float.arg = &rep_float; + + alltypes.rep_fixed64.funcs.encode = &write_repeated_fixed64; + alltypes.rep_fixed64.arg = &rep_fixed64; + + alltypes.rep_sfixed64.funcs.encode = &write_repeated_fixed64; + alltypes.rep_sfixed64.arg = &rep_sfixed64; + + alltypes.rep_double.funcs.encode = &write_repeated_fixed64; + alltypes.rep_double.arg = &rep_double; + + alltypes.rep_string.funcs.encode = &write_repeated_string; + alltypes.rep_string.arg = "2014"; + + alltypes.rep_bytes.funcs.encode = &write_repeated_string; + alltypes.rep_bytes.arg = "2015"; + + alltypes.rep_submsg.funcs.encode = &write_repeated_submsg; + alltypes.rep_submsg.arg = &rep_submsg; + + alltypes.rep_enum.funcs.encode = &write_repeated_varint; + alltypes.rep_enum.arg = (void*)MyEnum_Truth; + + alltypes.rep_emptymsg.funcs.encode = &write_repeated_emptymsg; + + alltypes.rep_fbytes.funcs.encode = &write_repeated_string; + alltypes.rep_fbytes.arg = "2019"; + + alltypes.req_limits.funcs.encode = &write_limits; + + /* Bind callbacks for singular fields */ + if (mode != 0) + { + alltypes.sng_int32.funcs.encode = &write_varint; + alltypes.sng_int32.arg = (void*)3041; + + alltypes.sng_int64.funcs.encode = &write_varint; + alltypes.sng_int64.arg = (void*)3042; + + alltypes.sng_uint32.funcs.encode = &write_varint; + alltypes.sng_uint32.arg = (void*)3043; + + alltypes.sng_uint64.funcs.encode = &write_varint; + alltypes.sng_uint64.arg = (void*)3044; + + alltypes.sng_sint32.funcs.encode = &write_svarint; + alltypes.sng_sint32.arg = (void*)3045; + + alltypes.sng_sint64.funcs.encode = &write_svarint; + alltypes.sng_sint64.arg = (void*)3046; + + alltypes.sng_bool.funcs.encode = &write_varint; + alltypes.sng_bool.arg = (void*)true; + + alltypes.sng_fixed32.funcs.encode = &write_fixed32; + alltypes.sng_fixed32.arg = &sng_fixed32; + + alltypes.sng_sfixed32.funcs.encode = &write_fixed32; + alltypes.sng_sfixed32.arg = &sng_sfixed32; + + alltypes.sng_float.funcs.encode = &write_fixed32; + alltypes.sng_float.arg = &sng_float; + + alltypes.sng_fixed64.funcs.encode = &write_fixed64; + alltypes.sng_fixed64.arg = &sng_fixed64; + + alltypes.sng_sfixed64.funcs.encode = &write_fixed64; + alltypes.sng_sfixed64.arg = &sng_sfixed64; + + alltypes.sng_double.funcs.encode = &write_fixed64; + alltypes.sng_double.arg = &sng_double; + + alltypes.sng_string.funcs.encode = &write_string; + alltypes.sng_string.arg = "3054"; + + alltypes.sng_bytes.funcs.encode = &write_string; + alltypes.sng_bytes.arg = "3055"; + + alltypes.sng_submsg.funcs.encode = &write_submsg; + alltypes.sng_submsg.arg = &sng_submsg; + + alltypes.sng_enum.funcs.encode = &write_varint; + alltypes.sng_enum.arg = (void*)MyEnum_Truth; + + alltypes.sng_emptymsg.funcs.encode = &write_emptymsg; + + alltypes.sng_fbytes.funcs.encode = &write_string; + alltypes.sng_fbytes.arg = "3059"; + + alltypes.oneof_msg1.funcs.encode = &write_submsg; + alltypes.oneof_msg1.arg = &oneof_msg1; + } + + alltypes.end.funcs.encode = &write_varint; + alltypes.end.arg = (void*)1099; + + { + uint8_t buffer[2048]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/SConscript new file mode 100644 index 00000000..10672287 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/SConscript @@ -0,0 +1,30 @@ +# Test anonymous_oneof generator option + +Import('env') + +import re + +match = None +if 'PROTOC_VERSION' in env: + match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION']) + +if match: + version = map(int, match.groups()) + +# Oneof is supported by protoc >= 2.6.0 +if env.GetOption('clean') or (match and (version[0] > 2 or (version[0] == 2 and version[1] >= 6))): + # Anonymous oneofs are supported by clang and gcc + if 'clang' in env['CC'] or 'gcc' in env['CC']: + env2 = env.Clone() + if '-pedantic' in env2['CFLAGS']: + env2['CFLAGS'].remove('-pedantic') + env2.NanopbProto('oneof') + + dec = env2.Program(['decode_oneof.c', + 'oneof.pb.c', + '$COMMON/pb_decode.o', + '$COMMON/pb_common.o']) + + env2.RunTest("message1.txt", [dec, '$BUILD/oneof/message1.pb'], ARGS = ['1']) + env2.RunTest("message2.txt", [dec, '$BUILD/oneof/message2.pb'], ARGS = ['2']) + env2.RunTest("message3.txt", [dec, '$BUILD/oneof/message3.pb'], ARGS = ['3']) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/decode_oneof.c b/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/decode_oneof.c new file mode 100644 index 00000000..0f774dbc --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/decode_oneof.c @@ -0,0 +1,88 @@ +/* Decode a message using oneof fields */ + +#include +#include +#include +#include +#include "oneof.pb.h" +#include "test_helpers.h" +#include "unittests.h" + +/* Test the 'AnonymousOneOfMessage' */ +int test_oneof_1(pb_istream_t *stream, int option) +{ + AnonymousOneOfMessage msg; + int status = 0; + + /* To better catch initialization errors */ + memset(&msg, 0xAA, sizeof(msg)); + + if (!pb_decode(stream, AnonymousOneOfMessage_fields, &msg)) + { + printf("Decoding failed: %s\n", PB_GET_ERROR(stream)); + return 1; + } + + /* Check that the basic fields work normally */ + TEST(msg.prefix == 123); + TEST(msg.suffix == 321); + + /* Check that we got the right oneof according to command line */ + if (option == 1) + { + TEST(msg.which_values == AnonymousOneOfMessage_first_tag); + TEST(msg.first == 999); + } + else if (option == 2) + { + TEST(msg.which_values == AnonymousOneOfMessage_second_tag); + TEST(strcmp(msg.second, "abcd") == 0); + } + else if (option == 3) + { + TEST(msg.which_values == AnonymousOneOfMessage_third_tag); + TEST(msg.third.array[0] == 1); + TEST(msg.third.array[1] == 2); + TEST(msg.third.array[2] == 3); + TEST(msg.third.array[3] == 4); + TEST(msg.third.array[4] == 5); + } + + return status; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[AnonymousOneOfMessage_size]; + size_t count; + int option; + + if (argc != 2) + { + fprintf(stderr, "Usage: decode_oneof [number]\n"); + return 1; + } + option = atoi(argv[1]); + + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + if (!feof(stdin)) + { + printf("Message does not fit in buffer\n"); + return 1; + } + + { + int status = 0; + pb_istream_t stream; + + stream = pb_istream_from_buffer(buffer, count); + status = test_oneof_1(&stream, option); + + if (status != 0) + return status; + } + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/oneof.proto b/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/oneof.proto new file mode 100644 index 00000000..d56285c0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/anonymous_oneof/oneof.proto @@ -0,0 +1,23 @@ +syntax = "proto2"; + +import 'nanopb.proto'; + +message SubMessage +{ + repeated int32 array = 1 [(nanopb).max_count = 8]; +} + +/* Oneof in a message with other fields */ +message AnonymousOneOfMessage +{ + option (nanopb_msgopt).anonymous_oneof = true; + required int32 prefix = 1; + oneof values + { + int32 first = 5; + string second = 6 [(nanopb).max_size = 8]; + SubMessage third = 7; + } + required int32 suffix = 99; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/SConscript new file mode 100644 index 00000000..81b03182 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/SConscript @@ -0,0 +1,11 @@ +# Check that the old generated .pb.c/.pb.h files are still compatible with the +# current version of nanopb. + +Import("env") + +enc = env.Program(["encode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = env.Program(["decode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_legacy.output"]) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.c b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.c new file mode 100644 index 00000000..7311fd45 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.c @@ -0,0 +1,153 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.0-dev at Tue Aug 19 17:53:24 2014. */ + +#include "alltypes_legacy.h" + +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + +const char SubMessage_substuff1_default[16] = "1"; +const int32_t SubMessage_substuff2_default = 2; +const uint32_t SubMessage_substuff3_default = 3u; +const int32_t Limits_int32_min_default = 2147483647; +const int32_t Limits_int32_max_default = -2147483647; +const uint32_t Limits_uint32_min_default = 4294967295u; +const uint32_t Limits_uint32_max_default = 0u; +const int64_t Limits_int64_min_default = 9223372036854775807ll; +const int64_t Limits_int64_max_default = -9223372036854775807ll; +const uint64_t Limits_uint64_min_default = 18446744073709551615ull; +const uint64_t Limits_uint64_max_default = 0ull; +const HugeEnum Limits_enum_min_default = HugeEnum_Positive; +const HugeEnum Limits_enum_max_default = HugeEnum_Negative; +const int32_t AllTypes_opt_int32_default = 4041; +const int64_t AllTypes_opt_int64_default = 4042ll; +const uint32_t AllTypes_opt_uint32_default = 4043u; +const uint64_t AllTypes_opt_uint64_default = 4044ull; +const int32_t AllTypes_opt_sint32_default = 4045; +const int64_t AllTypes_opt_sint64_default = 4046; +const bool AllTypes_opt_bool_default = false; +const uint32_t AllTypes_opt_fixed32_default = 4048u; +const int32_t AllTypes_opt_sfixed32_default = 4049; +const float AllTypes_opt_float_default = 4050; +const uint64_t AllTypes_opt_fixed64_default = 4051ull; +const int64_t AllTypes_opt_sfixed64_default = 4052ll; +const double AllTypes_opt_double_default = 4053; +const char AllTypes_opt_string_default[16] = "4054"; +const AllTypes_opt_bytes_t AllTypes_opt_bytes_default = {4, {0x34,0x30,0x35,0x35}}; +const MyEnum AllTypes_opt_enum_default = MyEnum_Second; + + +const pb_field_t SubMessage_fields[4] = { + PB_FIELD( 1, STRING , REQUIRED, STATIC , FIRST, SubMessage, substuff1, substuff1, &SubMessage_substuff1_default), + PB_FIELD( 2, INT32 , REQUIRED, STATIC , OTHER, SubMessage, substuff2, substuff1, &SubMessage_substuff2_default), + PB_FIELD( 3, FIXED32 , OPTIONAL, STATIC , OTHER, SubMessage, substuff3, substuff2, &SubMessage_substuff3_default), + PB_LAST_FIELD +}; + +const pb_field_t EmptyMessage_fields[1] = { + PB_LAST_FIELD +}; + +const pb_field_t Limits_fields[11] = { + PB_FIELD( 1, INT32 , REQUIRED, STATIC , FIRST, Limits, int32_min, int32_min, &Limits_int32_min_default), + PB_FIELD( 2, INT32 , REQUIRED, STATIC , OTHER, Limits, int32_max, int32_min, &Limits_int32_max_default), + PB_FIELD( 3, UINT32 , REQUIRED, STATIC , OTHER, Limits, uint32_min, int32_max, &Limits_uint32_min_default), + PB_FIELD( 4, UINT32 , REQUIRED, STATIC , OTHER, Limits, uint32_max, uint32_min, &Limits_uint32_max_default), + PB_FIELD( 5, INT64 , REQUIRED, STATIC , OTHER, Limits, int64_min, uint32_max, &Limits_int64_min_default), + PB_FIELD( 6, INT64 , REQUIRED, STATIC , OTHER, Limits, int64_max, int64_min, &Limits_int64_max_default), + PB_FIELD( 7, UINT64 , REQUIRED, STATIC , OTHER, Limits, uint64_min, int64_max, &Limits_uint64_min_default), + PB_FIELD( 8, UINT64 , REQUIRED, STATIC , OTHER, Limits, uint64_max, uint64_min, &Limits_uint64_max_default), + PB_FIELD( 9, ENUM , REQUIRED, STATIC , OTHER, Limits, enum_min, uint64_max, &Limits_enum_min_default), + PB_FIELD( 10, ENUM , REQUIRED, STATIC , OTHER, Limits, enum_max, enum_min, &Limits_enum_max_default), + PB_LAST_FIELD +}; + +const pb_field_t AllTypes_fields[54] = { + PB_FIELD( 1, INT32 , REQUIRED, STATIC , FIRST, AllTypes, req_int32, req_int32, 0), + PB_FIELD( 2, INT64 , REQUIRED, STATIC , OTHER, AllTypes, req_int64, req_int32, 0), + PB_FIELD( 3, UINT32 , REQUIRED, STATIC , OTHER, AllTypes, req_uint32, req_int64, 0), + PB_FIELD( 4, UINT64 , REQUIRED, STATIC , OTHER, AllTypes, req_uint64, req_uint32, 0), + PB_FIELD( 5, SINT32 , REQUIRED, STATIC , OTHER, AllTypes, req_sint32, req_uint64, 0), + PB_FIELD( 6, SINT64 , REQUIRED, STATIC , OTHER, AllTypes, req_sint64, req_sint32, 0), + PB_FIELD( 7, BOOL , REQUIRED, STATIC , OTHER, AllTypes, req_bool, req_sint64, 0), + PB_FIELD( 8, FIXED32 , REQUIRED, STATIC , OTHER, AllTypes, req_fixed32, req_bool, 0), + PB_FIELD( 9, SFIXED32, REQUIRED, STATIC , OTHER, AllTypes, req_sfixed32, req_fixed32, 0), + PB_FIELD( 10, FLOAT , REQUIRED, STATIC , OTHER, AllTypes, req_float, req_sfixed32, 0), + PB_FIELD( 11, FIXED64 , REQUIRED, STATIC , OTHER, AllTypes, req_fixed64, req_float, 0), + PB_FIELD( 12, SFIXED64, REQUIRED, STATIC , OTHER, AllTypes, req_sfixed64, req_fixed64, 0), + PB_FIELD( 13, DOUBLE , REQUIRED, STATIC , OTHER, AllTypes, req_double, req_sfixed64, 0), + PB_FIELD( 14, STRING , REQUIRED, STATIC , OTHER, AllTypes, req_string, req_double, 0), + PB_FIELD( 15, BYTES , REQUIRED, STATIC , OTHER, AllTypes, req_bytes, req_string, 0), + PB_FIELD( 16, MESSAGE , REQUIRED, STATIC , OTHER, AllTypes, req_submsg, req_bytes, &SubMessage_fields), + PB_FIELD( 17, ENUM , REQUIRED, STATIC , OTHER, AllTypes, req_enum, req_submsg, 0), + PB_FIELD( 21, INT32 , REPEATED, STATIC , OTHER, AllTypes, rep_int32, req_enum, 0), + PB_FIELD( 22, INT64 , REPEATED, STATIC , OTHER, AllTypes, rep_int64, rep_int32, 0), + PB_FIELD( 23, UINT32 , REPEATED, STATIC , OTHER, AllTypes, rep_uint32, rep_int64, 0), + PB_FIELD( 24, UINT64 , REPEATED, STATIC , OTHER, AllTypes, rep_uint64, rep_uint32, 0), + PB_FIELD( 25, SINT32 , REPEATED, STATIC , OTHER, AllTypes, rep_sint32, rep_uint64, 0), + PB_FIELD( 26, SINT64 , REPEATED, STATIC , OTHER, AllTypes, rep_sint64, rep_sint32, 0), + PB_FIELD( 27, BOOL , REPEATED, STATIC , OTHER, AllTypes, rep_bool, rep_sint64, 0), + PB_FIELD( 28, FIXED32 , REPEATED, STATIC , OTHER, AllTypes, rep_fixed32, rep_bool, 0), + PB_FIELD( 29, SFIXED32, REPEATED, STATIC , OTHER, AllTypes, rep_sfixed32, rep_fixed32, 0), + PB_FIELD( 30, FLOAT , REPEATED, STATIC , OTHER, AllTypes, rep_float, rep_sfixed32, 0), + PB_FIELD( 31, FIXED64 , REPEATED, STATIC , OTHER, AllTypes, rep_fixed64, rep_float, 0), + PB_FIELD( 32, SFIXED64, REPEATED, STATIC , OTHER, AllTypes, rep_sfixed64, rep_fixed64, 0), + PB_FIELD( 33, DOUBLE , REPEATED, STATIC , OTHER, AllTypes, rep_double, rep_sfixed64, 0), + PB_FIELD( 34, STRING , REPEATED, STATIC , OTHER, AllTypes, rep_string, rep_double, 0), + PB_FIELD( 35, BYTES , REPEATED, STATIC , OTHER, AllTypes, rep_bytes, rep_string, 0), + PB_FIELD( 36, MESSAGE , REPEATED, STATIC , OTHER, AllTypes, rep_submsg, rep_bytes, &SubMessage_fields), + PB_FIELD( 37, ENUM , REPEATED, STATIC , OTHER, AllTypes, rep_enum, rep_submsg, 0), + PB_FIELD( 41, INT32 , OPTIONAL, STATIC , OTHER, AllTypes, opt_int32, rep_enum, &AllTypes_opt_int32_default), + PB_FIELD( 42, INT64 , OPTIONAL, STATIC , OTHER, AllTypes, opt_int64, opt_int32, &AllTypes_opt_int64_default), + PB_FIELD( 43, UINT32 , OPTIONAL, STATIC , OTHER, AllTypes, opt_uint32, opt_int64, &AllTypes_opt_uint32_default), + PB_FIELD( 44, UINT64 , OPTIONAL, STATIC , OTHER, AllTypes, opt_uint64, opt_uint32, &AllTypes_opt_uint64_default), + PB_FIELD( 45, SINT32 , OPTIONAL, STATIC , OTHER, AllTypes, opt_sint32, opt_uint64, &AllTypes_opt_sint32_default), + PB_FIELD( 46, SINT64 , OPTIONAL, STATIC , OTHER, AllTypes, opt_sint64, opt_sint32, &AllTypes_opt_sint64_default), + PB_FIELD( 47, BOOL , OPTIONAL, STATIC , OTHER, AllTypes, opt_bool, opt_sint64, &AllTypes_opt_bool_default), + PB_FIELD( 48, FIXED32 , OPTIONAL, STATIC , OTHER, AllTypes, opt_fixed32, opt_bool, &AllTypes_opt_fixed32_default), + PB_FIELD( 49, SFIXED32, OPTIONAL, STATIC , OTHER, AllTypes, opt_sfixed32, opt_fixed32, &AllTypes_opt_sfixed32_default), + PB_FIELD( 50, FLOAT , OPTIONAL, STATIC , OTHER, AllTypes, opt_float, opt_sfixed32, &AllTypes_opt_float_default), + PB_FIELD( 51, FIXED64 , OPTIONAL, STATIC , OTHER, AllTypes, opt_fixed64, opt_float, &AllTypes_opt_fixed64_default), + PB_FIELD( 52, SFIXED64, OPTIONAL, STATIC , OTHER, AllTypes, opt_sfixed64, opt_fixed64, &AllTypes_opt_sfixed64_default), + PB_FIELD( 53, DOUBLE , OPTIONAL, STATIC , OTHER, AllTypes, opt_double, opt_sfixed64, &AllTypes_opt_double_default), + PB_FIELD( 54, STRING , OPTIONAL, STATIC , OTHER, AllTypes, opt_string, opt_double, &AllTypes_opt_string_default), + PB_FIELD( 55, BYTES , OPTIONAL, STATIC , OTHER, AllTypes, opt_bytes, opt_string, &AllTypes_opt_bytes_default), + PB_FIELD( 56, MESSAGE , OPTIONAL, STATIC , OTHER, AllTypes, opt_submsg, opt_bytes, &SubMessage_fields), + PB_FIELD( 57, ENUM , OPTIONAL, STATIC , OTHER, AllTypes, opt_enum, opt_submsg, &AllTypes_opt_enum_default), + PB_FIELD( 99, INT32 , REQUIRED, STATIC , OTHER, AllTypes, end, opt_enum, 0), + PB_FIELD(200, EXTENSION, OPTIONAL, CALLBACK, OTHER, AllTypes, extensions, end, 0), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 65536 && pb_membersize(AllTypes, rep_submsg[0]) < 65536 && pb_membersize(AllTypes, opt_submsg) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_SubMessage_EmptyMessage_Limits_AllTypes) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 256 && pb_membersize(AllTypes, rep_submsg[0]) < 256 && pb_membersize(AllTypes, opt_submsg) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_SubMessage_EmptyMessage_Limits_AllTypes) +#endif + + +/* On some platforms (such as AVR), double is really float. + * These are not directly supported by nanopb, but see example_avr_double. + * To get rid of this error, remove any double fields from your .proto. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.h b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.h new file mode 100644 index 00000000..4e0a63be --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.h @@ -0,0 +1,274 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.0-dev at Tue Aug 19 17:53:24 2014. */ + +#ifndef PB_ALLTYPES_LEGACY_H_INCLUDED +#define PB_ALLTYPES_LEGACY_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Enum definitions */ +typedef enum _HugeEnum { + HugeEnum_Negative = -2147483647, + HugeEnum_Positive = 2147483647 +} HugeEnum; + +typedef enum _MyEnum { + MyEnum_Zero = 0, + MyEnum_First = 1, + MyEnum_Second = 2, + MyEnum_Truth = 42 +} MyEnum; + +/* Struct definitions */ +typedef struct _EmptyMessage { + uint8_t dummy_field; +} EmptyMessage; + +typedef struct _Limits { + int32_t int32_min; + int32_t int32_max; + uint32_t uint32_min; + uint32_t uint32_max; + int64_t int64_min; + int64_t int64_max; + uint64_t uint64_min; + uint64_t uint64_max; + HugeEnum enum_min; + HugeEnum enum_max; +} Limits; + +typedef struct _SubMessage { + char substuff1[16]; + int32_t substuff2; + bool has_substuff3; + uint32_t substuff3; +} SubMessage; + +typedef PB_BYTES_ARRAY_T(16) AllTypes_req_bytes_t; + +typedef PB_BYTES_ARRAY_T(16) AllTypes_rep_bytes_t; + +typedef PB_BYTES_ARRAY_T(16) AllTypes_opt_bytes_t; + +typedef struct _AllTypes { + int32_t req_int32; + int64_t req_int64; + uint32_t req_uint32; + uint64_t req_uint64; + int32_t req_sint32; + int64_t req_sint64; + bool req_bool; + uint32_t req_fixed32; + int32_t req_sfixed32; + float req_float; + uint64_t req_fixed64; + int64_t req_sfixed64; + double req_double; + char req_string[16]; + AllTypes_req_bytes_t req_bytes; + SubMessage req_submsg; + MyEnum req_enum; + pb_size_t rep_int32_count; + int32_t rep_int32[5]; + pb_size_t rep_int64_count; + int64_t rep_int64[5]; + pb_size_t rep_uint32_count; + uint32_t rep_uint32[5]; + pb_size_t rep_uint64_count; + uint64_t rep_uint64[5]; + pb_size_t rep_sint32_count; + int32_t rep_sint32[5]; + pb_size_t rep_sint64_count; + int64_t rep_sint64[5]; + pb_size_t rep_bool_count; + bool rep_bool[5]; + pb_size_t rep_fixed32_count; + uint32_t rep_fixed32[5]; + pb_size_t rep_sfixed32_count; + int32_t rep_sfixed32[5]; + pb_size_t rep_float_count; + float rep_float[5]; + pb_size_t rep_fixed64_count; + uint64_t rep_fixed64[5]; + pb_size_t rep_sfixed64_count; + int64_t rep_sfixed64[5]; + pb_size_t rep_double_count; + double rep_double[5]; + pb_size_t rep_string_count; + char rep_string[5][16]; + pb_size_t rep_bytes_count; + AllTypes_rep_bytes_t rep_bytes[5]; + pb_size_t rep_submsg_count; + SubMessage rep_submsg[5]; + pb_size_t rep_enum_count; + MyEnum rep_enum[5]; + bool has_opt_int32; + int32_t opt_int32; + bool has_opt_int64; + int64_t opt_int64; + bool has_opt_uint32; + uint32_t opt_uint32; + bool has_opt_uint64; + uint64_t opt_uint64; + bool has_opt_sint32; + int32_t opt_sint32; + bool has_opt_sint64; + int64_t opt_sint64; + bool has_opt_bool; + bool opt_bool; + bool has_opt_fixed32; + uint32_t opt_fixed32; + bool has_opt_sfixed32; + int32_t opt_sfixed32; + bool has_opt_float; + float opt_float; + bool has_opt_fixed64; + uint64_t opt_fixed64; + bool has_opt_sfixed64; + int64_t opt_sfixed64; + bool has_opt_double; + double opt_double; + bool has_opt_string; + char opt_string[16]; + bool has_opt_bytes; + AllTypes_opt_bytes_t opt_bytes; + bool has_opt_submsg; + SubMessage opt_submsg; + bool has_opt_enum; + MyEnum opt_enum; + int32_t end; + pb_extension_t *extensions; +} AllTypes; + +/* Default values for struct fields */ +extern const char SubMessage_substuff1_default[16]; +extern const int32_t SubMessage_substuff2_default; +extern const uint32_t SubMessage_substuff3_default; +extern const int32_t Limits_int32_min_default; +extern const int32_t Limits_int32_max_default; +extern const uint32_t Limits_uint32_min_default; +extern const uint32_t Limits_uint32_max_default; +extern const int64_t Limits_int64_min_default; +extern const int64_t Limits_int64_max_default; +extern const uint64_t Limits_uint64_min_default; +extern const uint64_t Limits_uint64_max_default; +extern const HugeEnum Limits_enum_min_default; +extern const HugeEnum Limits_enum_max_default; +extern const int32_t AllTypes_opt_int32_default; +extern const int64_t AllTypes_opt_int64_default; +extern const uint32_t AllTypes_opt_uint32_default; +extern const uint64_t AllTypes_opt_uint64_default; +extern const int32_t AllTypes_opt_sint32_default; +extern const int64_t AllTypes_opt_sint64_default; +extern const bool AllTypes_opt_bool_default; +extern const uint32_t AllTypes_opt_fixed32_default; +extern const int32_t AllTypes_opt_sfixed32_default; +extern const float AllTypes_opt_float_default; +extern const uint64_t AllTypes_opt_fixed64_default; +extern const int64_t AllTypes_opt_sfixed64_default; +extern const double AllTypes_opt_double_default; +extern const char AllTypes_opt_string_default[16]; +extern const AllTypes_opt_bytes_t AllTypes_opt_bytes_default; +extern const MyEnum AllTypes_opt_enum_default; + +/* Initializer values for message structs */ +#define SubMessage_init_default {"1", 2, false, 3u} +#define EmptyMessage_init_default {0} +#define Limits_init_default {2147483647, -2147483647, 4294967295u, 0u, 9223372036854775807ll, -9223372036854775807ll, 18446744073709551615ull, 0ull, HugeEnum_Positive, HugeEnum_Negative} +#define AllTypes_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", {0, {0}}, SubMessage_init_default, (MyEnum)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, 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, {SubMessage_init_default, SubMessage_init_default, SubMessage_init_default, SubMessage_init_default, SubMessage_init_default}, 0, {(MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0}, false, 4041, false, 4042ll, false, 4043u, false, 4044ull, false, 4045, false, 4046, false, false, false, 4048u, false, 4049, false, 4050, false, 4051ull, false, 4052ll, false, 4053, false, "4054", false, {4, {0x34,0x30,0x35,0x35}}, false, SubMessage_init_default, false, MyEnum_Second, 0, NULL} +#define SubMessage_init_zero {"", 0, false, 0} +#define EmptyMessage_init_zero {0} +#define Limits_init_zero {0, 0, 0, 0, 0, 0, 0, 0, (HugeEnum)0, (HugeEnum)0} +#define AllTypes_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", {0, {0}}, SubMessage_init_zero, (MyEnum)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, 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, {SubMessage_init_zero, SubMessage_init_zero, SubMessage_init_zero, SubMessage_init_zero, SubMessage_init_zero}, 0, {(MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0}, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, "", false, {0, {0}}, false, SubMessage_init_zero, false, (MyEnum)0, 0, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define Limits_int32_min_tag 1 +#define Limits_int32_max_tag 2 +#define Limits_uint32_min_tag 3 +#define Limits_uint32_max_tag 4 +#define Limits_int64_min_tag 5 +#define Limits_int64_max_tag 6 +#define Limits_uint64_min_tag 7 +#define Limits_uint64_max_tag 8 +#define Limits_enum_min_tag 9 +#define Limits_enum_max_tag 10 +#define SubMessage_substuff1_tag 1 +#define SubMessage_substuff2_tag 2 +#define SubMessage_substuff3_tag 3 +#define AllTypes_req_int32_tag 1 +#define AllTypes_req_int64_tag 2 +#define AllTypes_req_uint32_tag 3 +#define AllTypes_req_uint64_tag 4 +#define AllTypes_req_sint32_tag 5 +#define AllTypes_req_sint64_tag 6 +#define AllTypes_req_bool_tag 7 +#define AllTypes_req_fixed32_tag 8 +#define AllTypes_req_sfixed32_tag 9 +#define AllTypes_req_float_tag 10 +#define AllTypes_req_fixed64_tag 11 +#define AllTypes_req_sfixed64_tag 12 +#define AllTypes_req_double_tag 13 +#define AllTypes_req_string_tag 14 +#define AllTypes_req_bytes_tag 15 +#define AllTypes_req_submsg_tag 16 +#define AllTypes_req_enum_tag 17 +#define AllTypes_rep_int32_tag 21 +#define AllTypes_rep_int64_tag 22 +#define AllTypes_rep_uint32_tag 23 +#define AllTypes_rep_uint64_tag 24 +#define AllTypes_rep_sint32_tag 25 +#define AllTypes_rep_sint64_tag 26 +#define AllTypes_rep_bool_tag 27 +#define AllTypes_rep_fixed32_tag 28 +#define AllTypes_rep_sfixed32_tag 29 +#define AllTypes_rep_float_tag 30 +#define AllTypes_rep_fixed64_tag 31 +#define AllTypes_rep_sfixed64_tag 32 +#define AllTypes_rep_double_tag 33 +#define AllTypes_rep_string_tag 34 +#define AllTypes_rep_bytes_tag 35 +#define AllTypes_rep_submsg_tag 36 +#define AllTypes_rep_enum_tag 37 +#define AllTypes_opt_int32_tag 41 +#define AllTypes_opt_int64_tag 42 +#define AllTypes_opt_uint32_tag 43 +#define AllTypes_opt_uint64_tag 44 +#define AllTypes_opt_sint32_tag 45 +#define AllTypes_opt_sint64_tag 46 +#define AllTypes_opt_bool_tag 47 +#define AllTypes_opt_fixed32_tag 48 +#define AllTypes_opt_sfixed32_tag 49 +#define AllTypes_opt_float_tag 50 +#define AllTypes_opt_fixed64_tag 51 +#define AllTypes_opt_sfixed64_tag 52 +#define AllTypes_opt_double_tag 53 +#define AllTypes_opt_string_tag 54 +#define AllTypes_opt_bytes_tag 55 +#define AllTypes_opt_submsg_tag 56 +#define AllTypes_opt_enum_tag 57 +#define AllTypes_end_tag 99 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t SubMessage_fields[4]; +extern const pb_field_t EmptyMessage_fields[1]; +extern const pb_field_t Limits_fields[11]; +extern const pb_field_t AllTypes_fields[54]; + +/* Maximum encoded size of messages (where known) */ +#define SubMessage_size 34 +#define EmptyMessage_size 0 +#define Limits_size 90 +#define AllTypes_size 1362 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.options b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.options new file mode 100644 index 00000000..b31e3cf0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.options @@ -0,0 +1,3 @@ +* max_size:16 +* max_count:5 + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.proto b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.proto new file mode 100644 index 00000000..f5bc35ce --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/alltypes_legacy.proto @@ -0,0 +1,110 @@ +syntax = "proto2"; + +message SubMessage { + required string substuff1 = 1 [default = "1"]; + required int32 substuff2 = 2 [default = 2]; + optional fixed32 substuff3 = 3 [default = 3]; +} + +message EmptyMessage { + +} + +enum HugeEnum { + Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ + Positive = 2147483647; +} + +message Limits { + required int32 int32_min = 1 [default = 2147483647]; + required int32 int32_max = 2 [default = -2147483647]; + required uint32 uint32_min = 3 [default = 4294967295]; + required uint32 uint32_max = 4 [default = 0]; + required int64 int64_min = 5 [default = 9223372036854775807]; + required int64 int64_max = 6 [default = -9223372036854775807]; + required uint64 uint64_min = 7 [default = 18446744073709551615]; + required uint64 uint64_max = 8 [default = 0]; + required HugeEnum enum_min = 9 [default = Positive]; + required HugeEnum enum_max = 10 [default = Negative]; +} + +enum MyEnum { + Zero = 0; + First = 1; + Second = 2; + Truth = 42; +} + +message AllTypes { + required int32 req_int32 = 1; + required int64 req_int64 = 2; + required uint32 req_uint32 = 3; + required uint64 req_uint64 = 4; + required sint32 req_sint32 = 5; + required sint64 req_sint64 = 6; + required bool req_bool = 7; + + required fixed32 req_fixed32 = 8; + required sfixed32 req_sfixed32= 9; + required float req_float = 10; + + required fixed64 req_fixed64 = 11; + required sfixed64 req_sfixed64= 12; + required double req_double = 13; + + required string req_string = 14; + required bytes req_bytes = 15; + required SubMessage req_submsg = 16; + required MyEnum req_enum = 17; + + + repeated int32 rep_int32 = 21 [packed = true]; + repeated int64 rep_int64 = 22 [packed = true]; + repeated uint32 rep_uint32 = 23 [packed = true]; + repeated uint64 rep_uint64 = 24 [packed = true]; + repeated sint32 rep_sint32 = 25 [packed = true]; + repeated sint64 rep_sint64 = 26 [packed = true]; + repeated bool rep_bool = 27 [packed = true]; + + repeated fixed32 rep_fixed32 = 28 [packed = true]; + repeated sfixed32 rep_sfixed32= 29 [packed = true]; + repeated float rep_float = 30 [packed = true]; + + repeated fixed64 rep_fixed64 = 31 [packed = true]; + repeated sfixed64 rep_sfixed64= 32 [packed = true]; + repeated double rep_double = 33 [packed = true]; + + repeated string rep_string = 34; + repeated bytes rep_bytes = 35; + repeated SubMessage rep_submsg = 36; + repeated MyEnum rep_enum = 37 [packed = true]; + + optional int32 opt_int32 = 41 [default = 4041]; + optional int64 opt_int64 = 42 [default = 4042]; + optional uint32 opt_uint32 = 43 [default = 4043]; + optional uint64 opt_uint64 = 44 [default = 4044]; + optional sint32 opt_sint32 = 45 [default = 4045]; + optional sint64 opt_sint64 = 46 [default = 4046]; + optional bool opt_bool = 47 [default = false]; + + optional fixed32 opt_fixed32 = 48 [default = 4048]; + optional sfixed32 opt_sfixed32= 49 [default = 4049]; + optional float opt_float = 50 [default = 4050]; + + optional fixed64 opt_fixed64 = 51 [default = 4051]; + optional sfixed64 opt_sfixed64= 52 [default = 4052]; + optional double opt_double = 53 [default = 4053]; + + optional string opt_string = 54 [default = "4054"]; + optional bytes opt_bytes = 55 [default = "4055"]; + optional SubMessage opt_submsg = 56; + optional MyEnum opt_enum = 57 [default = Second]; + + // Just to make sure that the size of the fields has been calculated + // properly, i.e. otherwise a bug in last field might not be detected. + required int32 end = 99; + + + extensions 200 to 255; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/decode_legacy.c b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/decode_legacy.c new file mode 100644 index 00000000..5f5b6bbe --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/decode_legacy.c @@ -0,0 +1,199 @@ +/* Tests the decoding of all types. + * This is a backwards-compatibility test, using alltypes_legacy.h. + * It is similar to decode_alltypes, but duplicated in order to allow + * decode_alltypes to test any new features introduced later. + * + * Run e.g. ./encode_legacy | ./decode_legacy + */ + +#include +#include +#include +#include +#include "alltypes_legacy.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed.\n"); \ + return false; \ + } + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + AllTypes alltypes = {0}; + + if (!pb_decode(stream, AllTypes_fields, &alltypes)) + return false; + + TEST(alltypes.req_int32 == -1001); + TEST(alltypes.req_int64 == -1002); + TEST(alltypes.req_uint32 == 1003); + TEST(alltypes.req_uint64 == 1004); + TEST(alltypes.req_sint32 == -1005); + TEST(alltypes.req_sint64 == -1006); + TEST(alltypes.req_bool == true); + + TEST(alltypes.req_fixed32 == 1008); + TEST(alltypes.req_sfixed32 == -1009); + TEST(alltypes.req_float == 1010.0f); + + TEST(alltypes.req_fixed64 == 1011); + TEST(alltypes.req_sfixed64 == -1012); + TEST(alltypes.req_double == 1013.0f); + + TEST(strcmp(alltypes.req_string, "1014") == 0); + TEST(alltypes.req_bytes.size == 4); + TEST(memcmp(alltypes.req_bytes.bytes, "1015", 4) == 0); + TEST(strcmp(alltypes.req_submsg.substuff1, "1016") == 0); + TEST(alltypes.req_submsg.substuff2 == 1016); + TEST(alltypes.req_submsg.substuff3 == 3); + TEST(alltypes.req_enum == MyEnum_Truth); + + TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0); + TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0); + TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0); + TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0); + TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0); + TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0); + TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false); + + TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0); + TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0); + TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f); + + TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0); + TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0); + TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0); + + TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0'); + TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0); + TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0); + + TEST(alltypes.rep_submsg_count == 5); + TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0'); + TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0); + TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 3); + + TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero); + + if (mode == 0) + { + /* Expect default values */ + TEST(alltypes.has_opt_int32 == false); + TEST(alltypes.opt_int32 == 4041); + TEST(alltypes.has_opt_int64 == false); + TEST(alltypes.opt_int64 == 4042); + TEST(alltypes.has_opt_uint32 == false); + TEST(alltypes.opt_uint32 == 4043); + TEST(alltypes.has_opt_uint64 == false); + TEST(alltypes.opt_uint64 == 4044); + TEST(alltypes.has_opt_sint32 == false); + TEST(alltypes.opt_sint32 == 4045); + TEST(alltypes.has_opt_sint64 == false); + TEST(alltypes.opt_sint64 == 4046); + TEST(alltypes.has_opt_bool == false); + TEST(alltypes.opt_bool == false); + + TEST(alltypes.has_opt_fixed32 == false); + TEST(alltypes.opt_fixed32 == 4048); + TEST(alltypes.has_opt_sfixed32 == false); + TEST(alltypes.opt_sfixed32 == 4049); + TEST(alltypes.has_opt_float == false); + TEST(alltypes.opt_float == 4050.0f); + + TEST(alltypes.has_opt_fixed64 == false); + TEST(alltypes.opt_fixed64 == 4051); + TEST(alltypes.has_opt_sfixed64 == false); + TEST(alltypes.opt_sfixed64 == 4052); + TEST(alltypes.has_opt_double == false); + TEST(alltypes.opt_double == 4053.0); + + TEST(alltypes.has_opt_string == false); + TEST(strcmp(alltypes.opt_string, "4054") == 0); + TEST(alltypes.has_opt_bytes == false); + TEST(alltypes.opt_bytes.size == 4); + TEST(memcmp(alltypes.opt_bytes.bytes, "4055", 4) == 0); + TEST(alltypes.has_opt_submsg == false); + TEST(strcmp(alltypes.opt_submsg.substuff1, "1") == 0); + TEST(alltypes.opt_submsg.substuff2 == 2); + TEST(alltypes.opt_submsg.substuff3 == 3); + TEST(alltypes.has_opt_enum == false); + TEST(alltypes.opt_enum == MyEnum_Second); + } + else + { + /* Expect filled-in values */ + TEST(alltypes.has_opt_int32 == true); + TEST(alltypes.opt_int32 == 3041); + TEST(alltypes.has_opt_int64 == true); + TEST(alltypes.opt_int64 == 3042); + TEST(alltypes.has_opt_uint32 == true); + TEST(alltypes.opt_uint32 == 3043); + TEST(alltypes.has_opt_uint64 == true); + TEST(alltypes.opt_uint64 == 3044); + TEST(alltypes.has_opt_sint32 == true); + TEST(alltypes.opt_sint32 == 3045); + TEST(alltypes.has_opt_sint64 == true); + TEST(alltypes.opt_sint64 == 3046); + TEST(alltypes.has_opt_bool == true); + TEST(alltypes.opt_bool == true); + + TEST(alltypes.has_opt_fixed32 == true); + TEST(alltypes.opt_fixed32 == 3048); + TEST(alltypes.has_opt_sfixed32 == true); + TEST(alltypes.opt_sfixed32 == 3049); + TEST(alltypes.has_opt_float == true); + TEST(alltypes.opt_float == 3050.0f); + + TEST(alltypes.has_opt_fixed64 == true); + TEST(alltypes.opt_fixed64 == 3051); + TEST(alltypes.has_opt_sfixed64 == true); + TEST(alltypes.opt_sfixed64 == 3052); + TEST(alltypes.has_opt_double == true); + TEST(alltypes.opt_double == 3053.0); + + TEST(alltypes.has_opt_string == true); + TEST(strcmp(alltypes.opt_string, "3054") == 0); + TEST(alltypes.has_opt_bytes == true); + TEST(alltypes.opt_bytes.size == 4); + TEST(memcmp(alltypes.opt_bytes.bytes, "3055", 4) == 0); + TEST(alltypes.has_opt_submsg == true); + TEST(strcmp(alltypes.opt_submsg.substuff1, "3056") == 0); + TEST(alltypes.opt_submsg.substuff2 == 3056); + TEST(alltypes.opt_submsg.substuff3 == 3); + TEST(alltypes.has_opt_enum == true); + TEST(alltypes.opt_enum == MyEnum_Truth); + } + + TEST(alltypes.end == 1099); + + return true; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!check_alltypes(&stream, mode)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/encode_legacy.c b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/encode_legacy.c new file mode 100644 index 00000000..5c9d41b3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/backwards_compatibility/encode_legacy.c @@ -0,0 +1,135 @@ +/* Attempts to test all the datatypes supported by ProtoBuf. + * This is a backwards-compatibility test, using alltypes_legacy.h. + * It is similar to encode_alltypes, but duplicated in order to allow + * encode_alltypes to test any new features introduced later. + */ + +#include +#include +#include +#include +#include "alltypes_legacy.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Initialize the structure with constants */ + AllTypes alltypes = {0}; + + alltypes.req_int32 = -1001; + alltypes.req_int64 = -1002; + alltypes.req_uint32 = 1003; + alltypes.req_uint64 = 1004; + alltypes.req_sint32 = -1005; + alltypes.req_sint64 = -1006; + alltypes.req_bool = true; + + alltypes.req_fixed32 = 1008; + alltypes.req_sfixed32 = -1009; + alltypes.req_float = 1010.0f; + + alltypes.req_fixed64 = 1011; + alltypes.req_sfixed64 = -1012; + alltypes.req_double = 1013.0; + + strcpy(alltypes.req_string, "1014"); + alltypes.req_bytes.size = 4; + memcpy(alltypes.req_bytes.bytes, "1015", 4); + strcpy(alltypes.req_submsg.substuff1, "1016"); + alltypes.req_submsg.substuff2 = 1016; + alltypes.req_enum = MyEnum_Truth; + + alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001; + alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002; + alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003; + alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004; + alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005; + alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006; + alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true; + + alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008; + alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009; + alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f; + + alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011; + alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012; + alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0; + + alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014"); + alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4; + memcpy(alltypes.rep_bytes[4].bytes, "2015", 4); + + alltypes.rep_submsg_count = 5; + strcpy(alltypes.rep_submsg[4].substuff1, "2016"); + alltypes.rep_submsg[4].substuff2 = 2016; + alltypes.rep_submsg[4].has_substuff3 = true; + alltypes.rep_submsg[4].substuff3 = 2016; + + alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth; + + if (mode != 0) + { + /* Fill in values for optional fields */ + alltypes.has_opt_int32 = true; + alltypes.opt_int32 = 3041; + alltypes.has_opt_int64 = true; + alltypes.opt_int64 = 3042; + alltypes.has_opt_uint32 = true; + alltypes.opt_uint32 = 3043; + alltypes.has_opt_uint64 = true; + alltypes.opt_uint64 = 3044; + alltypes.has_opt_sint32 = true; + alltypes.opt_sint32 = 3045; + alltypes.has_opt_sint64 = true; + alltypes.opt_sint64 = 3046; + alltypes.has_opt_bool = true; + alltypes.opt_bool = true; + + alltypes.has_opt_fixed32 = true; + alltypes.opt_fixed32 = 3048; + alltypes.has_opt_sfixed32 = true; + alltypes.opt_sfixed32 = 3049; + alltypes.has_opt_float = true; + alltypes.opt_float = 3050.0f; + + alltypes.has_opt_fixed64 = true; + alltypes.opt_fixed64 = 3051; + alltypes.has_opt_sfixed64 = true; + alltypes.opt_sfixed64 = 3052; + alltypes.has_opt_double = true; + alltypes.opt_double = 3053.0; + + alltypes.has_opt_string = true; + strcpy(alltypes.opt_string, "3054"); + alltypes.has_opt_bytes = true; + alltypes.opt_bytes.size = 4; + memcpy(alltypes.opt_bytes.bytes, "3055", 4); + alltypes.has_opt_submsg = true; + strcpy(alltypes.opt_submsg.substuff1, "3056"); + alltypes.opt_submsg.substuff2 = 3056; + alltypes.has_opt_enum = true; + alltypes.opt_enum = MyEnum_Truth; + } + + alltypes.end = 1099; + + { + uint8_t buffer[1024]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed!\n"); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/SConscript new file mode 100644 index 00000000..acaf5ffa --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/SConscript @@ -0,0 +1,12 @@ +# Build and run a basic round-trip test using memory buffer encoding. + +Import("env") + +enc = env.Program(["encode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = env.Program(["decode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_buffer.output"]) +env.Decode(["encode_buffer.output", "$COMMON/person.proto"], MESSAGE = "Person") +env.Compare(["decode_buffer.output", "encode_buffer.decoded"]) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/decode_buffer.c b/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/decode_buffer.c new file mode 100644 index 00000000..291d164c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/decode_buffer.c @@ -0,0 +1,88 @@ +/* A very simple decoding test case, using person.proto. + * Produces output compatible with protoc --decode. + * Reads the encoded data from stdin and prints the values + * to stdout as text. + * + * Run e.g. ./test_encode1 | ./test_decode1 + */ + +#include +#include +#include "person.pb.h" +#include "test_helpers.h" + +/* This function is called once from main(), it handles + the decoding and printing. */ +bool print_person(pb_istream_t *stream) +{ + int i; + Person person = Person_init_zero; + + if (!pb_decode(stream, Person_fields, &person)) + return false; + + /* Now the decoding is done, rest is just to print stuff out. */ + + printf("name: \"%s\"\n", person.name); + printf("id: %ld\n", (long)person.id); + + if (person.has_email) + printf("email: \"%s\"\n", person.email); + + for (i = 0; i < person.phone_count; i++) + { + Person_PhoneNumber *phone = &person.phone[i]; + printf("phone {\n"); + printf(" number: \"%s\"\n", phone->number); + + if (phone->has_type) + { + switch (phone->type) + { + case Person_PhoneType_WORK: + printf(" type: WORK\n"); + break; + + case Person_PhoneType_HOME: + printf(" type: HOME\n"); + break; + + case Person_PhoneType_MOBILE: + printf(" type: MOBILE\n"); + break; + } + } + printf("}\n"); + } + + return true; +} + +int main() +{ + uint8_t buffer[Person_size]; + pb_istream_t stream; + size_t count; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + if (!feof(stdin)) + { + printf("Message does not fit in buffer\n"); + return 1; + } + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!print_person(&stream)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/encode_buffer.c b/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/encode_buffer.c new file mode 100644 index 00000000..c412c14e --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/basic_buffer/encode_buffer.c @@ -0,0 +1,38 @@ +/* A very simple encoding test case using person.proto. + * Just puts constant data in the fields and encodes into + * buffer, which is then written to stdout. + */ + +#include +#include +#include "person.pb.h" +#include "test_helpers.h" + +int main() +{ + uint8_t buffer[Person_size]; + pb_ostream_t stream; + + /* Initialize the structure with constants */ + Person person = {"Test Person 99", 99, true, "test@person.com", + 3, {{"555-12345678", true, Person_PhoneType_MOBILE}, + {"99-2342", false, 0}, + {"1234-5678", true, Person_PhoneType_WORK}, + }}; + + stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, Person_fields, &person)) + { + /* Write the result data to stdout */ + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/SConscript new file mode 100644 index 00000000..7d668562 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/SConscript @@ -0,0 +1,12 @@ +# Build and run a basic round-trip test using direct stream encoding. + +Import("env") + +enc = env.Program(["encode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = env.Program(["decode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_stream.output"]) +env.Decode(["encode_stream.output", "$COMMON/person.proto"], MESSAGE = "Person") +env.Compare(["decode_stream.output", "encode_stream.decoded"]) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/decode_stream.c b/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/decode_stream.c new file mode 100644 index 00000000..798dcc50 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/decode_stream.c @@ -0,0 +1,84 @@ +/* Same as test_decode1 but reads from stdin directly. + */ + +#include +#include +#include "person.pb.h" +#include "test_helpers.h" + +/* This function is called once from main(), it handles + the decoding and printing. + Ugly copy-paste from test_decode1.c. */ +bool print_person(pb_istream_t *stream) +{ + int i; + Person person = Person_init_zero; + + if (!pb_decode(stream, Person_fields, &person)) + return false; + + /* Now the decoding is done, rest is just to print stuff out. */ + + printf("name: \"%s\"\n", person.name); + printf("id: %ld\n", (long)person.id); + + if (person.has_email) + printf("email: \"%s\"\n", person.email); + + for (i = 0; i < person.phone_count; i++) + { + Person_PhoneNumber *phone = &person.phone[i]; + printf("phone {\n"); + printf(" number: \"%s\"\n", phone->number); + + if (phone->has_type) + { + switch (phone->type) + { + case Person_PhoneType_WORK: + printf(" type: WORK\n"); + break; + + case Person_PhoneType_HOME: + printf(" type: HOME\n"); + break; + + case Person_PhoneType_MOBILE: + printf(" type: MOBILE\n"); + break; + } + } + printf("}\n"); + } + + return true; +} + +/* This binds the pb_istream_t to stdin */ +bool callback(pb_istream_t *stream, uint8_t *buf, size_t count) +{ + FILE *file = (FILE*)stream->state; + bool status; + + status = (fread(buf, 1, count, file) == count); + + if (feof(file)) + stream->bytes_left = 0; + + return status; +} + +int main() +{ + pb_istream_t stream = {&callback, NULL, SIZE_MAX}; + stream.state = stdin; + SET_BINARY_MODE(stdin); + + if (!print_person(&stream)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/encode_stream.c b/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/encode_stream.c new file mode 100644 index 00000000..7f571c41 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/basic_stream/encode_stream.c @@ -0,0 +1,40 @@ +/* Same as test_encode1.c, except writes directly to stdout. + */ + +#include +#include +#include "person.pb.h" +#include "test_helpers.h" + +/* This binds the pb_ostream_t into the stdout stream */ +bool streamcallback(pb_ostream_t *stream, const uint8_t *buf, size_t count) +{ + FILE *file = (FILE*) stream->state; + return fwrite(buf, 1, count, file) == count; +} + +int main() +{ + /* Initialize the structure with constants */ + Person person = {"Test Person 99", 99, true, "test@person.com", + 3, {{"555-12345678", true, Person_PhoneType_MOBILE}, + {"99-2342", false, 0}, + {"1234-5678", true, Person_PhoneType_WORK}, + }}; + + /* Prepare the stream, output goes directly to stdout */ + pb_ostream_t stream = {&streamcallback, NULL, SIZE_MAX, 0}; + stream.state = stdout; + SET_BINARY_MODE(stdout); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, Person_fields, &person)) + { + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/buffer_only/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/buffer_only/SConscript new file mode 100644 index 00000000..55b747b0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/buffer_only/SConscript @@ -0,0 +1,28 @@ +# Run the alltypes test case, but compile with PB_BUFFER_ONLY=1 + +Import("env") + +# Take copy of the files for custom build. +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.pb.h", "$BUILD/alltypes/alltypes.pb.h", c) +env.Command("alltypes.pb.c", "$BUILD/alltypes/alltypes.pb.c", c) +env.Command("encode_alltypes.c", "$BUILD/alltypes/encode_alltypes.c", c) +env.Command("decode_alltypes.c", "$BUILD/alltypes/decode_alltypes.c", c) + +# Define the compilation options +opts = env.Clone() +opts.Append(CPPDEFINES = {'PB_BUFFER_ONLY': 1}) + +# Build new version of core +strict = opts.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_decode_bufonly.o", "$NANOPB/pb_decode.c") +strict.Object("pb_encode_bufonly.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common_bufonly.o", "$NANOPB/pb_common.c") + +# Now build and run the test normally. +enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_bufonly.o", "pb_common_bufonly.o"]) +dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_bufonly.o", "pb_common_bufonly.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/SConscript new file mode 100644 index 00000000..44521439 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/SConscript @@ -0,0 +1,14 @@ +# Test the functionality of the callback fields. + +Import("env") + +env.NanopbProto("callbacks") +enc = env.Program(["encode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = env.Program(["decode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_callbacks.output"]) + +env.Decode(["encode_callbacks.output", "callbacks.proto"], MESSAGE = "TestMessage") +env.Compare(["decode_callbacks.output", "encode_callbacks.decoded"]) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/callbacks.proto b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/callbacks.proto new file mode 100644 index 00000000..96ac744d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/callbacks.proto @@ -0,0 +1,18 @@ +syntax = "proto2"; + +message SubMessage { + optional string stringvalue = 1; + repeated int32 int32value = 2; + repeated fixed32 fixed32value = 3; + repeated fixed64 fixed64value = 4; +} + +message TestMessage { + optional string stringvalue = 1; + repeated int32 int32value = 2; + repeated fixed32 fixed32value = 3; + repeated fixed64 fixed64value = 4; + optional SubMessage submsg = 5; + repeated string repeatedstring = 6; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/decode_callbacks.c b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/decode_callbacks.c new file mode 100644 index 00000000..45724d0b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/decode_callbacks.c @@ -0,0 +1,97 @@ +/* Decoding testcase for callback fields. + * Run e.g. ./test_encode_callbacks | ./test_decode_callbacks + */ + +#include +#include +#include "callbacks.pb.h" +#include "test_helpers.h" + +bool print_string(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint8_t buffer[1024] = {0}; + + /* We could read block-by-block to avoid the large buffer... */ + if (stream->bytes_left > sizeof(buffer) - 1) + return false; + + if (!pb_read(stream, buffer, stream->bytes_left)) + return false; + + /* Print the string, in format comparable with protoc --decode. + * Format comes from the arg defined in main(). + */ + printf((char*)*arg, buffer); + return true; +} + +bool print_int32(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + printf((char*)*arg, (long)value); + return true; +} + +bool print_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint32_t value; + if (!pb_decode_fixed32(stream, &value)) + return false; + + printf((char*)*arg, (long)value); + return true; +} + +bool print_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint64_t value; + if (!pb_decode_fixed64(stream, &value)) + return false; + + printf((char*)*arg, (long)value); + return true; +} + +int main() +{ + uint8_t buffer[1024]; + size_t length; + pb_istream_t stream; + /* Note: empty initializer list initializes the struct with all-0. + * This is recommended so that unused callbacks are set to NULL instead + * of crashing at runtime. + */ + TestMessage testmessage = {{{NULL}}}; + + SET_BINARY_MODE(stdin); + length = fread(buffer, 1, 1024, stdin); + stream = pb_istream_from_buffer(buffer, length); + + testmessage.submsg.stringvalue.funcs.decode = &print_string; + testmessage.submsg.stringvalue.arg = "submsg {\n stringvalue: \"%s\"\n"; + testmessage.submsg.int32value.funcs.decode = &print_int32; + testmessage.submsg.int32value.arg = " int32value: %ld\n"; + testmessage.submsg.fixed32value.funcs.decode = &print_fixed32; + testmessage.submsg.fixed32value.arg = " fixed32value: %ld\n"; + testmessage.submsg.fixed64value.funcs.decode = &print_fixed64; + testmessage.submsg.fixed64value.arg = " fixed64value: %ld\n}\n"; + + testmessage.stringvalue.funcs.decode = &print_string; + testmessage.stringvalue.arg = "stringvalue: \"%s\"\n"; + testmessage.int32value.funcs.decode = &print_int32; + testmessage.int32value.arg = "int32value: %ld\n"; + testmessage.fixed32value.funcs.decode = &print_fixed32; + testmessage.fixed32value.arg = "fixed32value: %ld\n"; + testmessage.fixed64value.funcs.decode = &print_fixed64; + testmessage.fixed64value.arg = "fixed64value: %ld\n"; + testmessage.repeatedstring.funcs.decode = &print_string; + testmessage.repeatedstring.arg = "repeatedstring: \"%s\"\n"; + + if (!pb_decode(&stream, TestMessage_fields, &testmessage)) + return 1; + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/encode_callbacks.c b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/encode_callbacks.c new file mode 100644 index 00000000..6cb67b1e --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/callbacks/encode_callbacks.c @@ -0,0 +1,92 @@ +/* Encoding testcase for callback fields */ + +#include +#include +#include +#include "callbacks.pb.h" +#include "test_helpers.h" + +bool encode_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + char *str = "Hello world!"; + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + return pb_encode_string(stream, (uint8_t*)str, strlen(str)); +} + +bool encode_int32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + if (!pb_encode_tag_for_field(stream, field)) + return false; + + return pb_encode_varint(stream, 42); +} + +bool encode_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + uint32_t value = 42; + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + return pb_encode_fixed32(stream, &value); +} + +bool encode_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + uint64_t value = 42; + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + return pb_encode_fixed64(stream, &value); +} + +bool encode_repeatedstring(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + char *str[4] = {"Hello world!", "", "Test", "Test2"}; + int i; + + for (i = 0; i < 4; i++) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!pb_encode_string(stream, (uint8_t*)str[i], strlen(str[i]))) + return false; + } + return true; +} + +int main() +{ + uint8_t buffer[1024]; + pb_ostream_t stream; + TestMessage testmessage = {{{NULL}}}; + + stream = pb_ostream_from_buffer(buffer, 1024); + + testmessage.stringvalue.funcs.encode = &encode_string; + testmessage.int32value.funcs.encode = &encode_int32; + testmessage.fixed32value.funcs.encode = &encode_fixed32; + testmessage.fixed64value.funcs.encode = &encode_fixed64; + + testmessage.has_submsg = true; + testmessage.submsg.stringvalue.funcs.encode = &encode_string; + testmessage.submsg.int32value.funcs.encode = &encode_int32; + testmessage.submsg.fixed32value.funcs.encode = &encode_fixed32; + testmessage.submsg.fixed64value.funcs.encode = &encode_fixed64; + + testmessage.repeatedstring.funcs.encode = &encode_repeatedstring; + + if (!pb_encode(&stream, TestMessage_fields, &testmessage)) + return 1; + + SET_BINARY_MODE(stdout); + if (fwrite(buffer, stream.bytes_written, 1, stdout) != 1) + return 2; + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/common/SConscript new file mode 100644 index 00000000..05e2f852 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/SConscript @@ -0,0 +1,48 @@ +# Build the common files needed by multiple test cases + +Import('env') + +# Protocol definitions for the encode/decode_unittests +env.NanopbProto("unittestproto") + +# Protocol definitions for basic_buffer/stream tests +env.NanopbProto("person") + +#-------------------------------------------- +# Binaries of the pb_decode.c and pb_encode.c +# These are built using more strict warning flags. +strict = env.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_decode.o", "$NANOPB/pb_decode.c") +strict.Object("pb_encode.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common.o", "$NANOPB/pb_common.c") + +#----------------------------------------------- +# Binaries of pb_decode etc. with malloc support +# Uses malloc_wrappers.c to count allocations. +malloc_env = env.Clone() +malloc_env.Append(CPPDEFINES = {'PB_ENABLE_MALLOC': 1, + 'PB_SYSTEM_HEADER': '\\"malloc_wrappers_syshdr.h\\"'}) +malloc_env.Append(CPPPATH = ["$COMMON"]) + +if 'SYSHDR' in malloc_env: + malloc_env.Append(CPPDEFINES = {'PB_OLD_SYSHDR': malloc_env['SYSHDR']}) + +# Disable libmudflap, because it will confuse valgrind +# and other memory leak detection tools. +if '-fmudflap' in env["CCFLAGS"]: + malloc_env["CCFLAGS"].remove("-fmudflap") + malloc_env["LINKFLAGS"].remove("-fmudflap") + malloc_env["LIBS"].remove("mudflap") + +malloc_strict = malloc_env.Clone() +malloc_strict.Append(CFLAGS = malloc_strict['CORECFLAGS']) +malloc_strict.Object("pb_decode_with_malloc.o", "$NANOPB/pb_decode.c") +malloc_strict.Object("pb_encode_with_malloc.o", "$NANOPB/pb_encode.c") +malloc_strict.Object("pb_common_with_malloc.o", "$NANOPB/pb_common.c") + +malloc_env.Object("malloc_wrappers.o", "malloc_wrappers.c") +malloc_env.Depends("$NANOPB/pb.h", ["malloc_wrappers_syshdr.h", "malloc_wrappers.h"]) + +Export("malloc_env") + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.c b/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.c new file mode 100644 index 00000000..ad69f1ce --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.c @@ -0,0 +1,54 @@ +#include "malloc_wrappers.h" +#include +#include +#include + +static size_t alloc_count = 0; + +/* Allocate memory and place check values before and after. */ +void* malloc_with_check(size_t size) +{ + size_t size32 = (size + 3) / 4 + 3; + uint32_t *buf = malloc(size32 * sizeof(uint32_t)); + buf[0] = size32; + buf[1] = 0xDEADBEEF; + buf[size32 - 1] = 0xBADBAD; + return buf + 2; +} + +/* Free memory allocated with malloc_with_check() and do the checks. */ +void free_with_check(void *mem) +{ + uint32_t *buf = (uint32_t*)mem - 2; + assert(buf[1] == 0xDEADBEEF); + assert(buf[buf[0] - 1] == 0xBADBAD); + free(buf); +} + +/* Track memory usage */ +void* counting_realloc(void *ptr, size_t size) +{ + /* Don't allocate crazy amounts of RAM when fuzzing */ + if (size > 1000000) + return NULL; + + if (!ptr && size) + alloc_count++; + + return realloc(ptr, size); +} + +void counting_free(void *ptr) +{ + if (ptr) + { + assert(alloc_count > 0); + alloc_count--; + free(ptr); + } +} + +size_t get_alloc_count() +{ + return alloc_count; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.h b/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.h new file mode 100644 index 00000000..7eec7952 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers.h @@ -0,0 +1,7 @@ +#include + +void* malloc_with_check(size_t size); +void free_with_check(void *mem); +void* counting_realloc(void *ptr, size_t size); +void counting_free(void *ptr); +size_t get_alloc_count(); diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers_syshdr.h b/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers_syshdr.h new file mode 100644 index 00000000..d295d9ed --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/malloc_wrappers_syshdr.h @@ -0,0 +1,15 @@ +/* This is just a wrapper in order to get our own malloc wrappers into nanopb core. */ + +#define pb_realloc(ptr,size) counting_realloc(ptr,size) +#define pb_free(ptr) counting_free(ptr) + +#ifdef PB_OLD_SYSHDR +#include PB_OLD_SYSHDR +#else +#include +#include +#include +#include +#endif + +#include diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/person.proto b/hardware-wallet/firmware/vendor/nanopb/tests/common/person.proto new file mode 100644 index 00000000..becefdf3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/person.proto @@ -0,0 +1,22 @@ +syntax = "proto2"; + +import "nanopb.proto"; + +message Person { + required string name = 1 [(nanopb).max_size = 40]; + required int32 id = 2; + optional string email = 3 [(nanopb).max_size = 40]; + + enum PhoneType { + MOBILE = 0; + HOME = 1; + WORK = 2; + } + + message PhoneNumber { + required string number = 1 [(nanopb).max_size = 40]; + optional PhoneType type = 2 [default = HOME]; + } + + repeated PhoneNumber phone = 4 [(nanopb).max_count = 5]; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/test_helpers.h b/hardware-wallet/firmware/vendor/nanopb/tests/common/test_helpers.h new file mode 100644 index 00000000..f77760a5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/test_helpers.h @@ -0,0 +1,17 @@ +/* Compatibility helpers for the test programs. */ + +#ifndef _TEST_HELPERS_H_ +#define _TEST_HELPERS_H_ + +#ifdef _WIN32 +#include +#include +#define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) + +#else +#define SET_BINARY_MODE(file) + +#endif + + +#endif diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/unittestproto.proto b/hardware-wallet/firmware/vendor/nanopb/tests/common/unittestproto.proto new file mode 100644 index 00000000..23b5b97f --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/unittestproto.proto @@ -0,0 +1,43 @@ +syntax = "proto2"; + +import 'nanopb.proto'; + +message IntegerArray { + repeated int32 data = 1 [(nanopb).max_count = 10]; +} + +message FloatArray { + repeated float data = 1 [(nanopb).max_count = 10]; +} + +message StringMessage { + required string data = 1 [(nanopb).max_size = 10]; +} + +message BytesMessage { + required bytes data = 1 [(nanopb).max_size = 16]; +} + +message CallbackArray { + // We cheat a bit and use this message for testing other types, too. + // Nanopb does not care about the actual defined data type for callback + // fields. + repeated int32 data = 1; +} + +message IntegerContainer { + required IntegerArray submsg = 1; +} + +message CallbackContainer { + required CallbackArray submsg = 1; +} + +message CallbackContainerContainer { + required CallbackContainer submsg = 1; +} + +message StringPointerContainer { + repeated string rep_str = 1 [(nanopb).type = FT_POINTER]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/common/unittests.h b/hardware-wallet/firmware/vendor/nanopb/tests/common/unittests.h new file mode 100644 index 00000000..c2b470ad --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/common/unittests.h @@ -0,0 +1,14 @@ +#include + +#define COMMENT(x) printf("\n----" x "----\n"); +#define STR(x) #x +#define STR2(x) STR(x) +#define TEST(x) \ + if (!(x)) { \ + fprintf(stderr, "\033[31;1mFAILED:\033[22;39m " __FILE__ ":" STR2(__LINE__) " " #x "\n"); \ + status = 1; \ + } else { \ + printf("\033[32;1mOK:\033[22;39m " #x "\n"); \ + } + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/cxx_main_program/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/cxx_main_program/SConscript new file mode 100644 index 00000000..edb88127 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/cxx_main_program/SConscript @@ -0,0 +1,25 @@ +# Run the alltypes test case, but compile it as C++ instead. +# In fact, compile the entire nanopb using C++ compiler. + +Import("env") + +# This is needed to get INT32_MIN etc. macros defined +env = env.Clone() +env.Append(CPPDEFINES = ['__STDC_LIMIT_MACROS']) + +# Copy the files to .cxx extension in order to force C++ build. +c = Copy("$TARGET", "$SOURCE") +env.Command("pb_encode.cxx", "#../pb_encode.c", c) +env.Command("pb_decode.cxx", "#../pb_decode.c", c) +env.Command("pb_common.cxx", "#../pb_common.c", c) +env.Command("alltypes.pb.h", "$BUILD/alltypes/alltypes.pb.h", c) +env.Command("alltypes.pb.cxx", "$BUILD/alltypes/alltypes.pb.c", c) +env.Command("encode_alltypes.cxx", "$BUILD/alltypes/encode_alltypes.c", c) +env.Command("decode_alltypes.cxx", "$BUILD/alltypes/decode_alltypes.c", c) + +# Now build and run the test normally. +enc = env.Program(["encode_alltypes.cxx", "alltypes.pb.cxx", "pb_encode.cxx", "pb_common.cxx"]) +dec = env.Program(["decode_alltypes.cxx", "alltypes.pb.cxx", "pb_decode.cxx", "pb_common.cxx"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/SConscript new file mode 100644 index 00000000..c782001c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/SConscript @@ -0,0 +1,11 @@ +Import("env") + +# Encode cyclic messages with callback fields + +c = Copy("$TARGET", "$SOURCE") +env.Command("cyclic_callback.proto", "cyclic.proto", c) +env.NanopbProto(["cyclic_callback", "cyclic_callback.options"]) + +enc_callback = env.Program(["encode_cyclic_callback.c", "cyclic_callback.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic.proto b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic.proto new file mode 100644 index 00000000..8cab0b14 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic.proto @@ -0,0 +1,27 @@ +// Test structures with cyclic references. +// These can only be handled in pointer/callback mode, +// see associated .options files. + +syntax = "proto2"; + +message TreeNode +{ + optional int32 leaf = 1; + optional TreeNode left = 2; + optional TreeNode right = 3; +} + +message Dictionary +{ + repeated KeyValuePair dictItem = 1; +} + +message KeyValuePair +{ + required string key = 1; + optional string stringValue = 2; + optional int32 intValue = 3; + optional Dictionary dictValue = 4; + optional TreeNode treeValue = 5; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic_callback.options b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic_callback.options new file mode 100644 index 00000000..fd4e1e1c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/cyclic_callback.options @@ -0,0 +1,7 @@ +TreeNode.left type:FT_CALLBACK +TreeNode.right type:FT_CALLBACK + +Dictionary.data type:FT_CALLBACK +KeyValuePair.key max_size:8 +KeyValuePair.stringValue max_size:8 +KeyValuePair.treeValue type:FT_CALLBACK diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/encode_cyclic_callback.c b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/encode_cyclic_callback.c new file mode 100644 index 00000000..7f67e70c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/cyclic_messages/encode_cyclic_callback.c @@ -0,0 +1,148 @@ +/* This program parses an input string in a format a bit like JSON: + * {'foobar': 1234, 'xyz': 'abc', 'tree': [[[1, 2], 3], [4, 5]]} + * and encodes it as protobuf + * + * Note: The string parsing here is not in any way intended to be robust + * nor safe against buffer overflows. It is just for this test. + */ + +#include +#include +#include +#include +#include "cyclic_callback.pb.h" + +static char *find_end_of_item(char *p) +{ + int depth = 0; + do { + if (*p == '[' || *p == '{') depth++; + if (*p == ']' || *p == '}') depth--; + p++; + } while (depth > 0 || (*p != ',' && *p != '}')); + + if (*p == '}') + return p; /* End of parent dict */ + + p++; + while (*p == ' ') p++; + return p; +} + +/* Parse a tree in format [[1 2] 3] and encode it directly to protobuf */ +static bool encode_tree(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + TreeNode tree = TreeNode_init_zero; + char *p = (char*)*arg; + + if (*p == '[') + { + /* This is a tree branch */ + p++; + tree.left.funcs.encode = encode_tree; + tree.left.arg = p; + + p = find_end_of_item(p); + tree.right.funcs.encode = encode_tree; + tree.right.arg = p; + } + else + { + /* This is a leaf node */ + tree.has_leaf = true; + tree.leaf = atoi(p); + } + + return pb_encode_tag_for_field(stream, field) && + pb_encode_submessage(stream, TreeNode_fields, &tree); +} + +/* Parse a dictionary in format {'name': value} and encode it directly to protobuf */ +static bool encode_dictionary(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + int textlen; + char *p = (char*)*arg; + if (*p == '{') p++; + while (*p != '}') + { + KeyValuePair pair = KeyValuePair_init_zero; + + if (*p != '\'') + PB_RETURN_ERROR(stream, "invalid key, missing quote"); + + p++; /* Starting quote of key */ + textlen = strchr(p, '\'') - p; + strncpy(pair.key, p, textlen); + pair.key[textlen] = 0; + p += textlen + 2; + + while (*p == ' ') p++; + + if (*p == '[') + { + /* Value is a tree */ + pair.treeValue.funcs.encode = encode_tree; + pair.treeValue.arg = p; + } + else if (*p == '\'') + { + /* Value is a string */ + pair.has_stringValue = true; + p++; + textlen = strchr(p, '\'') - p; + strncpy(pair.stringValue, p, textlen); + pair.stringValue[textlen] = 0; + } + else if (*p == '{') + { + /* Value is a dictionary */ + pair.has_dictValue = true; + pair.dictValue.dictItem.funcs.encode = encode_dictionary; + pair.dictValue.dictItem.arg = p; + } + else + { + /* Value is integer */ + pair.has_intValue = true; + pair.intValue = atoi(p); + } + + p = find_end_of_item(p); + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!pb_encode_submessage(stream, KeyValuePair_fields, &pair)) + return false; + } + + return true; +} + + +int main(int argc, char *argv[]) +{ + uint8_t buffer[256]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + Dictionary dict = Dictionary_init_zero; + + if (argc <= 1) + { + fprintf(stderr, "Usage: %s \"{'foobar': 1234, ...}\"\n", argv[0]); + return 1; + } + + dict.dictItem.funcs.encode = encode_dictionary; + dict.dictItem.arg = argv[1]; + + if (!pb_encode(&stream, Dictionary_fields, &dict)) + { + fprintf(stderr, "Encoding error: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/SConscript new file mode 100644 index 00000000..369b9dc7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/SConscript @@ -0,0 +1,4 @@ +Import('env') +p = env.Program(["decode_unittests.c", "$COMMON/unittestproto.pb.c"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/decode_unittests.c b/hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/decode_unittests.c new file mode 100644 index 00000000..dc1e719c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/decode_unittests/decode_unittests.c @@ -0,0 +1,399 @@ +/* This includes the whole .c file to get access to static functions. */ +#define PB_ENABLE_MALLOC +#include "pb_common.c" +#include "pb_decode.c" + +#include +#include +#include "unittests.h" +#include "unittestproto.pb.h" + +#define S(x) pb_istream_from_buffer((uint8_t*)x, sizeof(x) - 1) + +bool stream_callback(pb_istream_t *stream, uint8_t *buf, size_t count) +{ + if (stream->state != NULL) + return false; /* Simulate error */ + + if (buf != NULL) + memset(buf, 'x', count); + return true; +} + +/* Verifies that the stream passed to callback matches the byte array pointed to by arg. */ +bool callback_check(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + int i; + uint8_t byte; + pb_bytes_array_t *ref = (pb_bytes_array_t*) *arg; + + for (i = 0; i < ref->size; i++) + { + if (!pb_read(stream, &byte, 1)) + return false; + + if (byte != ref->bytes[i]) + return false; + } + + return true; +} + +int main() +{ + int status = 0; + + { + uint8_t buffer1[] = "foobartest1234"; + uint8_t buffer2[sizeof(buffer1)]; + pb_istream_t stream = pb_istream_from_buffer(buffer1, sizeof(buffer1)); + + COMMENT("Test pb_read and pb_istream_t"); + TEST(pb_read(&stream, buffer2, 6)) + TEST(memcmp(buffer2, "foobar", 6) == 0) + TEST(stream.bytes_left == sizeof(buffer1) - 6) + TEST(pb_read(&stream, buffer2 + 6, stream.bytes_left)) + TEST(memcmp(buffer1, buffer2, sizeof(buffer1)) == 0) + TEST(stream.bytes_left == 0) + TEST(!pb_read(&stream, buffer2, 1)) + } + + { + uint8_t buffer[20]; + pb_istream_t stream = {&stream_callback, NULL, 20}; + + COMMENT("Test pb_read with custom callback"); + TEST(pb_read(&stream, buffer, 5)) + TEST(memcmp(buffer, "xxxxx", 5) == 0) + TEST(!pb_read(&stream, buffer, 50)) + stream.state = (void*)1; /* Simulated error return from callback */ + TEST(!pb_read(&stream, buffer, 5)) + stream.state = NULL; + TEST(pb_read(&stream, buffer, 15)) + } + + { + pb_istream_t s; + uint64_t u; + int64_t i; + + COMMENT("Test pb_decode_varint"); + TEST((s = S("\x00"), pb_decode_varint(&s, &u) && u == 0)); + TEST((s = S("\x01"), pb_decode_varint(&s, &u) && u == 1)); + TEST((s = S("\xAC\x02"), pb_decode_varint(&s, &u) && u == 300)); + TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint(&s, &u) && u == UINT32_MAX)); + TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint(&s, (uint64_t*)&i) && i == UINT32_MAX)); + TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), + pb_decode_varint(&s, (uint64_t*)&i) && i == -1)); + TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), + pb_decode_varint(&s, &u) && u == UINT64_MAX)); + TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), + !pb_decode_varint(&s, &u))); + } + + { + pb_istream_t s; + uint32_t u; + + COMMENT("Test pb_decode_varint32"); + TEST((s = S("\x00"), pb_decode_varint32(&s, &u) && u == 0)); + TEST((s = S("\x01"), pb_decode_varint32(&s, &u) && u == 1)); + TEST((s = S("\xAC\x02"), pb_decode_varint32(&s, &u) && u == 300)); + TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint32(&s, &u) && u == UINT32_MAX)); + TEST((s = S("\xFF\xFF\xFF\xFF\x8F\x00"), pb_decode_varint32(&s, &u) && u == UINT32_MAX)); + TEST((s = S("\xFF\xFF\xFF\xFF\x10"), !pb_decode_varint32(&s, &u))); + TEST((s = S("\xFF\xFF\xFF\xFF\x40"), !pb_decode_varint32(&s, &u))); + TEST((s = S("\xFF\xFF\xFF\xFF\xFF\x01"), !pb_decode_varint32(&s, &u))); + } + + { + pb_istream_t s; + COMMENT("Test pb_skip_varint"); + TEST((s = S("\x00""foobar"), pb_skip_varint(&s) && s.bytes_left == 6)) + TEST((s = S("\xAC\x02""foobar"), pb_skip_varint(&s) && s.bytes_left == 6)) + TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01""foobar"), + pb_skip_varint(&s) && s.bytes_left == 6)) + TEST((s = S("\xFF"), !pb_skip_varint(&s))) + } + + { + pb_istream_t s; + COMMENT("Test pb_skip_string") + TEST((s = S("\x00""foobar"), pb_skip_string(&s) && s.bytes_left == 6)) + TEST((s = S("\x04""testfoobar"), pb_skip_string(&s) && s.bytes_left == 6)) + TEST((s = S("\x04"), !pb_skip_string(&s))) + TEST((s = S("\xFF"), !pb_skip_string(&s))) + } + + { + pb_istream_t s = S("\x01\x00"); + pb_field_t f = {1, PB_LTYPE_VARINT, 0, 0, 4, 0, 0}; + uint32_t d; + COMMENT("Test pb_dec_varint using uint32_t") + TEST(pb_dec_varint(&s, &f, &d) && d == 1) + + /* Verify that no more than data_size is written. */ + d = 0xFFFFFFFF; + f.data_size = 1; + TEST(pb_dec_varint(&s, &f, &d) && (d == 0xFFFFFF00 || d == 0x00FFFFFF)) + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0}; + int32_t d; + + COMMENT("Test pb_dec_svarint using int32_t") + TEST((s = S("\x01"), pb_dec_svarint(&s, &f, &d) && d == -1)) + TEST((s = S("\x02"), pb_dec_svarint(&s, &f, &d) && d == 1)) + TEST((s = S("\xfe\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d) && d == INT32_MAX)) + TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d) && d == INT32_MIN)) + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 8, 0, 0}; + int64_t d; + + COMMENT("Test pb_dec_svarint using int64_t") + TEST((s = S("\x01"), pb_dec_svarint(&s, &f, &d) && d == -1)) + TEST((s = S("\x02"), pb_dec_svarint(&s, &f, &d) && d == 1)) + TEST((s = S("\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_svarint(&s, &f, &d) && d == INT64_MAX)) + TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_svarint(&s, &f, &d) && d == INT64_MIN)) + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0}; + int32_t d; + + COMMENT("Test pb_dec_svarint overflow detection using int32_t"); + TEST((s = S("\xfe\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d))); + TEST((s = S("\xfe\xff\xff\xff\x10"), !pb_dec_svarint(&s, &f, &d))); + TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d))); + TEST((s = S("\xff\xff\xff\xff\x10"), !pb_dec_svarint(&s, &f, &d))); + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0}; + uint32_t d; + + COMMENT("Test pb_dec_uvarint using uint32_t") + TEST((s = S("\x01"), pb_dec_uvarint(&s, &f, &d) && d == 1)) + TEST((s = S("\x02"), pb_dec_uvarint(&s, &f, &d) && d == 2)) + TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_uvarint(&s, &f, &d) && d == UINT32_MAX)) + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 8, 0, 0}; + uint64_t d; + + COMMENT("Test pb_dec_uvarint using uint64_t") + TEST((s = S("\x01"), pb_dec_uvarint(&s, &f, &d) && d == 1)) + TEST((s = S("\x02"), pb_dec_uvarint(&s, &f, &d) && d == 2)) + TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_uvarint(&s, &f, &d) && d == UINT64_MAX)) + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0}; + uint32_t d; + + COMMENT("Test pb_dec_uvarint overflow detection using int32_t"); + TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_uvarint(&s, &f, &d))); + TEST((s = S("\xff\xff\xff\xff\x10"), !pb_dec_uvarint(&s, &f, &d))); + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_FIXED32, 0, 0, 4, 0, 0}; + float d; + + COMMENT("Test pb_dec_fixed32 using float (failures here may be caused by imperfect rounding)") + TEST((s = S("\x00\x00\x00\x00"), pb_dec_fixed32(&s, &f, &d) && d == 0.0f)) + TEST((s = S("\x00\x00\xc6\x42"), pb_dec_fixed32(&s, &f, &d) && d == 99.0f)) + TEST((s = S("\x4e\x61\x3c\xcb"), pb_dec_fixed32(&s, &f, &d) && d == -12345678.0f)) + TEST((s = S("\x00"), !pb_dec_fixed32(&s, &f, &d) && d == -12345678.0f)) + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_FIXED64, 0, 0, 8, 0, 0}; + double d; + + COMMENT("Test pb_dec_fixed64 using double (failures here may be caused by imperfect rounding)") + TEST((s = S("\x00\x00\x00\x00\x00\x00\x00\x00"), pb_dec_fixed64(&s, &f, &d) && d == 0.0)) + TEST((s = S("\x00\x00\x00\x00\x00\xc0\x58\x40"), pb_dec_fixed64(&s, &f, &d) && d == 99.0)) + TEST((s = S("\x00\x00\x00\xc0\x29\x8c\x67\xc1"), pb_dec_fixed64(&s, &f, &d) && d == -12345678.0f)) + } + + { + pb_istream_t s; + struct { pb_size_t size; uint8_t bytes[5]; } d; + pb_field_t f = {1, PB_LTYPE_BYTES, 0, 0, sizeof(d), 0, 0}; + + COMMENT("Test pb_dec_bytes") + TEST((s = S("\x00"), pb_dec_bytes(&s, &f, &d) && d.size == 0)) + TEST((s = S("\x01\xFF"), pb_dec_bytes(&s, &f, &d) && d.size == 1 && d.bytes[0] == 0xFF)) + TEST((s = S("\x05xxxxx"), pb_dec_bytes(&s, &f, &d) && d.size == 5)) + TEST((s = S("\x05xxxx"), !pb_dec_bytes(&s, &f, &d))) + + /* Note: the size limit on bytes-fields is not strictly obeyed, as + * the compiler may add some padding to the struct. Using this padding + * is not a very good thing to do, but it is difficult to avoid when + * we use only a single uint8_t to store the size of the field. + * Therefore this tests against a 10-byte string, while otherwise even + * 6 bytes should error out. + */ + TEST((s = S("\x10xxxxxxxxxx"), !pb_dec_bytes(&s, &f, &d))) + } + + { + pb_istream_t s; + pb_field_t f = {1, PB_LTYPE_STRING, 0, 0, 5, 0, 0}; + char d[5]; + + COMMENT("Test pb_dec_string") + TEST((s = S("\x00"), pb_dec_string(&s, &f, &d) && d[0] == '\0')) + TEST((s = S("\x04xyzz"), pb_dec_string(&s, &f, &d) && strcmp(d, "xyzz") == 0)) + TEST((s = S("\x05xyzzy"), !pb_dec_string(&s, &f, &d))) + } + + { + pb_istream_t s; + IntegerArray dest; + + COMMENT("Testing pb_decode with repeated int32 field") + TEST((s = S(""), pb_decode(&s, IntegerArray_fields, &dest) && dest.data_count == 0)) + TEST((s = S("\x08\x01\x08\x02"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 2 && dest.data[0] == 1 && dest.data[1] == 2)) + s = S("\x08\x01\x08\x02\x08\x03\x08\x04\x08\x05\x08\x06\x08\x07\x08\x08\x08\x09\x08\x0A"); + TEST(pb_decode(&s, IntegerArray_fields, &dest) && dest.data_count == 10 && dest.data[9] == 10) + s = S("\x08\x01\x08\x02\x08\x03\x08\x04\x08\x05\x08\x06\x08\x07\x08\x08\x08\x09\x08\x0A\x08\x0B"); + TEST(!pb_decode(&s, IntegerArray_fields, &dest)) + } + + { + pb_istream_t s; + IntegerArray dest; + + COMMENT("Testing pb_decode with packed int32 field") + TEST((s = S("\x0A\x00"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 0)) + TEST((s = S("\x0A\x01\x01"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 1 && dest.data[0] == 1)) + TEST((s = S("\x0A\x0A\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 10 && dest.data[0] == 1 && dest.data[9] == 10)) + TEST((s = S("\x0A\x0B\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B"), !pb_decode(&s, IntegerArray_fields, &dest))) + + /* Test invalid wire data */ + TEST((s = S("\x0A\xFF"), !pb_decode(&s, IntegerArray_fields, &dest))) + TEST((s = S("\x0A\x01"), !pb_decode(&s, IntegerArray_fields, &dest))) + } + + { + pb_istream_t s; + IntegerArray dest; + + COMMENT("Testing pb_decode with unknown fields") + TEST((s = S("\x18\x0F\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 1 && dest.data[0] == 1)) + TEST((s = S("\x19\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 1 && dest.data[0] == 1)) + TEST((s = S("\x1A\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 1 && dest.data[0] == 1)) + TEST((s = S("\x1B\x08\x01"), !pb_decode(&s, IntegerArray_fields, &dest))) + TEST((s = S("\x1D\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest) + && dest.data_count == 1 && dest.data[0] == 1)) + } + + { + pb_istream_t s; + CallbackArray dest; + struct { pb_size_t size; uint8_t bytes[10]; } ref; + dest.data.funcs.decode = &callback_check; + dest.data.arg = &ref; + + COMMENT("Testing pb_decode with callbacks") + /* Single varint */ + ref.size = 1; ref.bytes[0] = 0x55; + TEST((s = S("\x08\x55"), pb_decode(&s, CallbackArray_fields, &dest))) + /* Packed varint */ + ref.size = 3; ref.bytes[0] = ref.bytes[1] = ref.bytes[2] = 0x55; + TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_fields, &dest))) + /* Packed varint with loop */ + ref.size = 1; ref.bytes[0] = 0x55; + TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_fields, &dest))) + /* Single fixed32 */ + ref.size = 4; ref.bytes[0] = ref.bytes[1] = ref.bytes[2] = ref.bytes[3] = 0xAA; + TEST((s = S("\x0D\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_fields, &dest))) + /* Single fixed64 */ + ref.size = 8; memset(ref.bytes, 0xAA, 8); + TEST((s = S("\x09\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_fields, &dest))) + /* Unsupported field type */ + TEST((s = S("\x0B\x00"), !pb_decode(&s, CallbackArray_fields, &dest))) + + /* Just make sure that our test function works */ + ref.size = 1; ref.bytes[0] = 0x56; + TEST((s = S("\x08\x55"), !pb_decode(&s, CallbackArray_fields, &dest))) + } + + { + pb_istream_t s; + IntegerArray dest; + + COMMENT("Testing pb_decode message termination") + TEST((s = S(""), pb_decode(&s, IntegerArray_fields, &dest))) + TEST((s = S("\x00"), pb_decode(&s, IntegerArray_fields, &dest))) + TEST((s = S("\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest))) + TEST((s = S("\x08\x01\x00"), pb_decode(&s, IntegerArray_fields, &dest))) + TEST((s = S("\x08"), !pb_decode(&s, IntegerArray_fields, &dest))) + } + + { + pb_istream_t s; + IntegerArray dest; + + COMMENT("Testing pb_decode with invalid tag numbers") + TEST((s = S("\x9f\xea"), !pb_decode(&s, IntegerArray_fields, &dest))); + } + + { + pb_istream_t s; + IntegerContainer dest = {{0}}; + + COMMENT("Testing pb_decode_delimited") + TEST((s = S("\x09\x0A\x07\x0A\x05\x01\x02\x03\x04\x05"), + pb_decode_delimited(&s, IntegerContainer_fields, &dest)) && + dest.submsg.data_count == 5) + } + + { + pb_istream_t s = {0}; + void *data = NULL; + + COMMENT("Testing allocate_field") + TEST(allocate_field(&s, &data, 10, 10) && data != NULL); + TEST(allocate_field(&s, &data, 10, 20) && data != NULL); + + { + void *oldvalue = data; + size_t very_big = (size_t)-1; + size_t somewhat_big = very_big / 2 + 1; + size_t not_so_big = (size_t)1 << (4 * sizeof(size_t)); + + TEST(!allocate_field(&s, &data, very_big, 2) && data == oldvalue); + TEST(!allocate_field(&s, &data, somewhat_big, 2) && data == oldvalue); + TEST(!allocate_field(&s, &data, not_so_big, not_so_big) && data == oldvalue); + } + + pb_free(data); + } + + if (status != 0) + fprintf(stdout, "\n\nSome tests FAILED!\n"); + + return status; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/SConscript new file mode 100644 index 00000000..bf6d1404 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/SConscript @@ -0,0 +1,5 @@ +# Build and run the stand-alone unit tests for the nanopb encoder part. + +Import('env') +p = env.Program(["encode_unittests.c", "$COMMON/unittestproto.pb.c"]) +env.RunTest(p) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/encode_unittests.c b/hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/encode_unittests.c new file mode 100644 index 00000000..583af5c6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/encode_unittests/encode_unittests.c @@ -0,0 +1,355 @@ +/* This includes the whole .c file to get access to static functions. */ +#include "pb_common.c" +#include "pb_encode.c" + +#include +#include +#include "unittests.h" +#include "unittestproto.pb.h" + +bool streamcallback(pb_ostream_t *stream, const uint8_t *buf, size_t count) +{ + /* Allow only 'x' to be written */ + while (count--) + { + if (*buf++ != 'x') + return false; + } + return true; +} + +bool fieldcallback(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + int value = 0x55; + if (!pb_encode_tag_for_field(stream, field)) + return false; + return pb_encode_varint(stream, value); +} + +bool crazyfieldcallback(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + /* This callback writes different amount of data the second time. */ + uint32_t *state = (uint32_t*)arg; + *state <<= 8; + if (!pb_encode_tag_for_field(stream, field)) + return false; + return pb_encode_varint(stream, *state); +} + +/* Check that expression x writes data y. + * Y is a string, which may contain null bytes. Null terminator is ignored. + */ +#define WRITES(x, y) \ +memset(buffer, 0xAA, sizeof(buffer)), \ +s = pb_ostream_from_buffer(buffer, sizeof(buffer)), \ +(x) && \ +memcmp(buffer, y, sizeof(y) - 1) == 0 && \ +buffer[sizeof(y) - 1] == 0xAA + +int main() +{ + int status = 0; + + { + uint8_t buffer1[] = "foobartest1234"; + uint8_t buffer2[sizeof(buffer1)]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer2, sizeof(buffer1)); + + COMMENT("Test pb_write and pb_ostream_t"); + TEST(pb_write(&stream, buffer1, sizeof(buffer1))); + TEST(memcmp(buffer1, buffer2, sizeof(buffer1)) == 0); + TEST(!pb_write(&stream, buffer1, 1)); + TEST(stream.bytes_written == sizeof(buffer1)); + } + + { + uint8_t buffer1[] = "xxxxxxx"; + pb_ostream_t stream = {&streamcallback, 0, SIZE_MAX, 0}; + + COMMENT("Test pb_write with custom callback"); + TEST(pb_write(&stream, buffer1, 5)); + buffer1[0] = 'a'; + TEST(!pb_write(&stream, buffer1, 5)); + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + + COMMENT("Test pb_encode_varint") + TEST(WRITES(pb_encode_varint(&s, 0), "\0")); + TEST(WRITES(pb_encode_varint(&s, 1), "\1")); + TEST(WRITES(pb_encode_varint(&s, 0x7F), "\x7F")); + TEST(WRITES(pb_encode_varint(&s, 0x80), "\x80\x01")); + TEST(WRITES(pb_encode_varint(&s, UINT32_MAX), "\xFF\xFF\xFF\xFF\x0F")); + TEST(WRITES(pb_encode_varint(&s, UINT64_MAX), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01")); + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + + COMMENT("Test pb_encode_tag") + TEST(WRITES(pb_encode_tag(&s, PB_WT_STRING, 5), "\x2A")); + TEST(WRITES(pb_encode_tag(&s, PB_WT_VARINT, 99), "\x98\x06")); + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + pb_field_t field = {10, PB_LTYPE_SVARINT}; + + COMMENT("Test pb_encode_tag_for_field") + TEST(WRITES(pb_encode_tag_for_field(&s, &field), "\x50")); + + field.type = PB_LTYPE_FIXED64; + TEST(WRITES(pb_encode_tag_for_field(&s, &field), "\x51")); + + field.type = PB_LTYPE_STRING; + TEST(WRITES(pb_encode_tag_for_field(&s, &field), "\x52")); + + field.type = PB_LTYPE_FIXED32; + TEST(WRITES(pb_encode_tag_for_field(&s, &field), "\x55")); + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + + COMMENT("Test pb_encode_string") + TEST(WRITES(pb_encode_string(&s, (const uint8_t*)"abcd", 4), "\x04""abcd")); + TEST(WRITES(pb_encode_string(&s, (const uint8_t*)"abcd\x00", 5), "\x05""abcd\x00")); + TEST(WRITES(pb_encode_string(&s, (const uint8_t*)"", 0), "\x00")); + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + uint8_t value = 1; + int32_t max = INT32_MAX; + int32_t min = INT32_MIN; + int64_t lmax = INT64_MAX; + int64_t lmin = INT64_MIN; + pb_field_t field = {1, PB_LTYPE_VARINT, 0, 0, sizeof(value)}; + + COMMENT("Test pb_enc_varint and pb_enc_svarint") + TEST(WRITES(pb_enc_varint(&s, &field, &value), "\x01")); + + field.data_size = sizeof(max); + TEST(WRITES(pb_enc_svarint(&s, &field, &max), "\xfe\xff\xff\xff\x0f")); + TEST(WRITES(pb_enc_svarint(&s, &field, &min), "\xff\xff\xff\xff\x0f")); + + field.data_size = sizeof(lmax); + TEST(WRITES(pb_enc_svarint(&s, &field, &lmax), "\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01")); + TEST(WRITES(pb_enc_svarint(&s, &field, &lmin), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01")); + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + float fvalue; + double dvalue; + + COMMENT("Test pb_enc_fixed32 using float") + fvalue = 0.0f; + TEST(WRITES(pb_enc_fixed32(&s, NULL, &fvalue), "\x00\x00\x00\x00")) + fvalue = 99.0f; + TEST(WRITES(pb_enc_fixed32(&s, NULL, &fvalue), "\x00\x00\xc6\x42")) + fvalue = -12345678.0f; + TEST(WRITES(pb_enc_fixed32(&s, NULL, &fvalue), "\x4e\x61\x3c\xcb")) + + COMMENT("Test pb_enc_fixed64 using double") + dvalue = 0.0; + TEST(WRITES(pb_enc_fixed64(&s, NULL, &dvalue), "\x00\x00\x00\x00\x00\x00\x00\x00")) + dvalue = 99.0; + TEST(WRITES(pb_enc_fixed64(&s, NULL, &dvalue), "\x00\x00\x00\x00\x00\xc0\x58\x40")) + dvalue = -12345678.0; + TEST(WRITES(pb_enc_fixed64(&s, NULL, &dvalue), "\x00\x00\x00\xc0\x29\x8c\x67\xc1")) + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + struct { pb_size_t size; uint8_t bytes[5]; } value = {5, {'x', 'y', 'z', 'z', 'y'}}; + + COMMENT("Test pb_enc_bytes") + TEST(WRITES(pb_enc_bytes(&s, &BytesMessage_fields[0], &value), "\x05xyzzy")) + value.size = 0; + TEST(WRITES(pb_enc_bytes(&s, &BytesMessage_fields[0], &value), "\x00")) + } + + { + uint8_t buffer[30]; + pb_ostream_t s; + char value[30] = "xyzzy"; + + COMMENT("Test pb_enc_string") + TEST(WRITES(pb_enc_string(&s, &StringMessage_fields[0], &value), "\x05xyzzy")) + value[0] = '\0'; + TEST(WRITES(pb_enc_string(&s, &StringMessage_fields[0], &value), "\x00")) + memset(value, 'x', 30); + TEST(WRITES(pb_enc_string(&s, &StringMessage_fields[0], &value), "\x0Axxxxxxxxxx")) + } + + { + uint8_t buffer[10]; + pb_ostream_t s; + IntegerArray msg = {5, {1, 2, 3, 4, 5}}; + + COMMENT("Test pb_encode with int32 array") + + TEST(WRITES(pb_encode(&s, IntegerArray_fields, &msg), "\x0A\x05\x01\x02\x03\x04\x05")) + + msg.data_count = 0; + TEST(WRITES(pb_encode(&s, IntegerArray_fields, &msg), "")) + + msg.data_count = 10; + TEST(!pb_encode(&s, IntegerArray_fields, &msg)) + } + + { + uint8_t buffer[10]; + pb_ostream_t s; + FloatArray msg = {1, {99.0f}}; + + COMMENT("Test pb_encode with float array") + + TEST(WRITES(pb_encode(&s, FloatArray_fields, &msg), + "\x0A\x04\x00\x00\xc6\x42")) + + msg.data_count = 0; + TEST(WRITES(pb_encode(&s, FloatArray_fields, &msg), "")) + + msg.data_count = 3; + TEST(!pb_encode(&s, FloatArray_fields, &msg)) + } + + { + uint8_t buffer[50]; + pb_ostream_t s; + FloatArray msg = {1, {99.0f}}; + + COMMENT("Test array size limit in pb_encode") + + s = pb_ostream_from_buffer(buffer, sizeof(buffer)); + TEST((msg.data_count = 10) && pb_encode(&s, FloatArray_fields, &msg)) + + s = pb_ostream_from_buffer(buffer, sizeof(buffer)); + TEST((msg.data_count = 11) && !pb_encode(&s, FloatArray_fields, &msg)) + } + + { + uint8_t buffer[10]; + pb_ostream_t s; + CallbackArray msg; + + msg.data.funcs.encode = &fieldcallback; + + COMMENT("Test pb_encode with callback field.") + TEST(WRITES(pb_encode(&s, CallbackArray_fields, &msg), "\x08\x55")) + } + + { + uint8_t buffer[10]; + pb_ostream_t s; + IntegerContainer msg = {{5, {1,2,3,4,5}}}; + + COMMENT("Test pb_encode with packed array in a submessage.") + TEST(WRITES(pb_encode(&s, IntegerContainer_fields, &msg), + "\x0A\x07\x0A\x05\x01\x02\x03\x04\x05")) + } + + { + uint8_t buffer[32]; + pb_ostream_t s; + BytesMessage msg = {{3, "xyz"}}; + + COMMENT("Test pb_encode with bytes message.") + TEST(WRITES(pb_encode(&s, BytesMessage_fields, &msg), + "\x0A\x03xyz")) + + msg.data.size = 17; /* More than maximum */ + TEST(!pb_encode(&s, BytesMessage_fields, &msg)) + } + + + { + uint8_t buffer[20]; + pb_ostream_t s; + IntegerContainer msg = {{5, {1,2,3,4,5}}}; + + COMMENT("Test pb_encode_delimited.") + TEST(WRITES(pb_encode_delimited(&s, IntegerContainer_fields, &msg), + "\x09\x0A\x07\x0A\x05\x01\x02\x03\x04\x05")) + } + + { + IntegerContainer msg = {{5, {1,2,3,4,5}}}; + size_t size; + + COMMENT("Test pb_get_encoded_size.") + TEST(pb_get_encoded_size(&size, IntegerContainer_fields, &msg) && + size == 9); + } + + { + uint8_t buffer[10]; + pb_ostream_t s; + CallbackContainer msg; + CallbackContainerContainer msg2; + uint32_t state = 1; + + msg.submsg.data.funcs.encode = &fieldcallback; + msg2.submsg.submsg.data.funcs.encode = &fieldcallback; + + COMMENT("Test pb_encode with callback field in a submessage.") + TEST(WRITES(pb_encode(&s, CallbackContainer_fields, &msg), "\x0A\x02\x08\x55")) + TEST(WRITES(pb_encode(&s, CallbackContainerContainer_fields, &msg2), + "\x0A\x04\x0A\x02\x08\x55")) + + /* Misbehaving callback: varying output between calls */ + msg.submsg.data.funcs.encode = &crazyfieldcallback; + msg.submsg.data.arg = &state; + msg2.submsg.submsg.data.funcs.encode = &crazyfieldcallback; + msg2.submsg.submsg.data.arg = &state; + + TEST(!pb_encode(&s, CallbackContainer_fields, &msg)) + state = 1; + TEST(!pb_encode(&s, CallbackContainerContainer_fields, &msg2)) + } + + { + uint8_t buffer[StringMessage_size]; + pb_ostream_t s; + StringMessage msg = {"0123456789"}; + + s = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + COMMENT("Test that StringMessage_size is correct") + + TEST(pb_encode(&s, StringMessage_fields, &msg)); + TEST(s.bytes_written == StringMessage_size); + } + + { + uint8_t buffer[128]; + pb_ostream_t s; + StringPointerContainer msg = StringPointerContainer_init_zero; + char *strs[1] = {NULL}; + char zstr[] = "Z"; + + COMMENT("Test string pointer encoding."); + + msg.rep_str = strs; + msg.rep_str_count = 1; + TEST(WRITES(pb_encode(&s, StringPointerContainer_fields, &msg), "\x0a\x00")) + + strs[0] = zstr; + TEST(WRITES(pb_encode(&s, StringPointerContainer_fields, &msg), "\x0a\x01Z")) + } + + if (status != 0) + fprintf(stdout, "\n\nSome tests FAILED!\n"); + + return status; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/SConscript new file mode 100644 index 00000000..048592ed --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/SConscript @@ -0,0 +1,12 @@ +# Test that different sizes of enum fields are properly encoded and decoded. + +Import('env') + +env.NanopbProto('enumsizes') + +p = env.Program(["enumsizes_unittests.c", + "enumsizes.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_decode.o", + "$COMMON/pb_common.o"]) +env.RunTest(p) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes.proto new file mode 100644 index 00000000..a85d4160 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes.proto @@ -0,0 +1,86 @@ +/* Test handling of enums with different value ranges. + * Depending on compiler and the packed_enum setting, the datatypes + * for enums can be either signed or unsigned. In past this has caused + * a bit of a problem for the encoder/decoder (issue #164). + */ + +syntax = "proto2"; + +import 'nanopb.proto'; + +option (nanopb_fileopt).long_names = false; + +enum UnpackedUint8 { + option (nanopb_enumopt).packed_enum = false; + UU8_MIN = 0; + UU8_MAX = 255; +} + +enum PackedUint8 { + option (nanopb_enumopt).packed_enum = true; + PU8_MIN = 0; + PU8_MAX = 255; +} + +enum UnpackedInt8 { + option (nanopb_enumopt).packed_enum = false; + UI8_MIN = -128; + UI8_MAX = 127; +} + +enum PackedInt8 { + option (nanopb_enumopt).packed_enum = true; + PI8_MIN = -128; + PI8_MAX = 127; +} + +enum UnpackedUint16 { + option (nanopb_enumopt).packed_enum = false; + UU16_MIN = 0; + UU16_MAX = 65535; +} + +enum PackedUint16 { + option (nanopb_enumopt).packed_enum = true; + PU16_MIN = 0; + PU16_MAX = 65535; +} + +enum UnpackedInt16 { + option (nanopb_enumopt).packed_enum = false; + UI16_MIN = -32768; + UI16_MAX = 32767; +} + +enum PackedInt16 { + option (nanopb_enumopt).packed_enum = true; + PI16_MIN = -32768; + PI16_MAX = 32767; +} + +/* Protobuf supports enums up to 32 bits. + * The 32 bit case is covered by HugeEnum in the alltypes test. + */ + +message PackedEnums { + required PackedUint8 u8_min = 1; + required PackedUint8 u8_max = 2; + required PackedInt8 i8_min = 3; + required PackedInt8 i8_max = 4; + required PackedUint16 u16_min = 5; + required PackedUint16 u16_max = 6; + required PackedInt16 i16_min = 7; + required PackedInt16 i16_max = 8; +} + +message UnpackedEnums { + required UnpackedUint8 u8_min = 1; + required UnpackedUint8 u8_max = 2; + required UnpackedInt8 i8_min = 3; + required UnpackedInt8 i8_max = 4; + required UnpackedUint16 u16_min = 5; + required UnpackedUint16 u16_max = 6; + required UnpackedInt16 i16_min = 7; + required UnpackedInt16 i16_max = 8; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes_unittests.c b/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes_unittests.c new file mode 100644 index 00000000..5606895a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/enum_sizes/enumsizes_unittests.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include "unittests.h" +#include "enumsizes.pb.h" + +int main() +{ + int status = 0; + + UnpackedEnums msg1 = { + UU8_MIN, UU8_MAX, + UI8_MIN, UI8_MAX, + UU16_MIN, UU16_MAX, + UI16_MIN, UI16_MAX, + }; + + PackedEnums msg2; + UnpackedEnums msg3; + uint8_t buf[256]; + size_t msgsize; + + COMMENT("Step 1: unpacked enums -> protobuf"); + { + pb_ostream_t s = pb_ostream_from_buffer(buf, sizeof(buf)); + TEST(pb_encode(&s, UnpackedEnums_fields, &msg1)); + msgsize = s.bytes_written; + } + + COMMENT("Step 2: protobuf -> packed enums"); + { + pb_istream_t s = pb_istream_from_buffer(buf, msgsize); + TEST(pb_decode(&s, PackedEnums_fields, &msg2)); + + TEST(msg1.u8_min == (int)msg2.u8_min); + TEST(msg1.u8_max == (int)msg2.u8_max); + TEST(msg1.i8_min == (int)msg2.i8_min); + TEST(msg1.i8_max == (int)msg2.i8_max); + TEST(msg1.u16_min == (int)msg2.u16_min); + TEST(msg1.u16_max == (int)msg2.u16_max); + TEST(msg1.i16_min == (int)msg2.i16_min); + TEST(msg1.i16_max == (int)msg2.i16_max); + } + + COMMENT("Step 3: packed enums -> protobuf"); + { + pb_ostream_t s = pb_ostream_from_buffer(buf, sizeof(buf)); + TEST(pb_encode(&s, PackedEnums_fields, &msg2)); + msgsize = s.bytes_written; + } + + COMMENT("Step 4: protobuf -> unpacked enums"); + { + pb_istream_t s = pb_istream_from_buffer(buf, msgsize); + TEST(pb_decode(&s, UnpackedEnums_fields, &msg3)); + + TEST(msg1.u8_min == (int)msg3.u8_min); + TEST(msg1.u8_max == (int)msg3.u8_max); + TEST(msg1.i8_min == (int)msg3.i8_min); + TEST(msg1.i8_max == (int)msg3.i8_max); + TEST(msg1.u16_min == (int)msg2.u16_min); + TEST(msg1.u16_max == (int)msg2.u16_max); + TEST(msg1.i16_min == (int)msg2.i16_min); + TEST(msg1.i16_max == (int)msg2.i16_max); + } + + if (status != 0) + fprintf(stdout, "\n\nSome tests FAILED!\n"); + + return status; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/SConscript new file mode 100644 index 00000000..e86fcca0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/SConscript @@ -0,0 +1,7 @@ +# Test enum to string functionality + +Import('env') +env.NanopbProto("enum.proto") +p = env.Program(["enum_to_string.c", "enum.pb.c"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum.proto b/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum.proto new file mode 100644 index 00000000..07c67363 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum.proto @@ -0,0 +1,19 @@ +/* Test enum to string function generation */ + +syntax = "proto2"; + +import "nanopb.proto"; + +option (nanopb_fileopt).enum_to_string = true; + +enum MyEnum { + VALUE1 = 1; + VALUE2 = 2; + VALUE15 = 15; +} + +enum MyShortNameEnum { + option (nanopb_enumopt).long_names = false; + MSNE_VALUE256 = 256; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum_to_string.c b/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum_to_string.c new file mode 100644 index 00000000..c4fb31d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/enum_to_string/enum_to_string.c @@ -0,0 +1,19 @@ +#include +#include "unittests.h" +#include "enum.pb.h" + +int main() +{ + int status = 0; + TEST(strcmp(MyEnum_name(MyEnum_VALUE1), "VALUE1") == 0); + TEST(strcmp(MyEnum_name(MyEnum_VALUE2), "VALUE2") == 0); + TEST(strcmp(MyEnum_name(MyEnum_VALUE15), "VALUE15") == 0); + TEST(strcmp(MyShortNameEnum_name(MSNE_VALUE256), "MSNE_VALUE256") == 0); + TEST(strcmp(MyShortNameEnum_name(9999), "unknown") == 0); + + if (status != 0) + fprintf(stdout, "\n\nSome tests FAILED!\n"); + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/extensions/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/SConscript new file mode 100644 index 00000000..a2c87428 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/SConscript @@ -0,0 +1,16 @@ +# Test the support for extension fields. + +Import("env") + +# We use the files from the alltypes test case +incpath = env.Clone() +incpath.Append(PROTOCPATH = '$BUILD/alltypes') +incpath.Append(CPPPATH = '$BUILD/alltypes') + +incpath.NanopbProto(["extensions", "extensions.options"]) +enc = incpath.Program(["encode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +dec = incpath.Program(["decode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_extensions.output"]) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/extensions/decode_extensions.c b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/decode_extensions.c new file mode 100644 index 00000000..e4374380 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/decode_extensions.c @@ -0,0 +1,60 @@ +/* Test decoding of extension fields. */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "extensions.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed.\n"); \ + return 2; \ + } + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + AllTypes alltypes = {0}; + int32_t extensionfield1; + pb_extension_t ext1; + ExtensionMessage extensionfield2; + pb_extension_t ext2; + + /* Read the message data */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + stream = pb_istream_from_buffer(buffer, count); + + /* Add the extensions */ + alltypes.extensions = &ext1; + + ext1.type = &AllTypes_extensionfield1; + ext1.dest = &extensionfield1; + ext1.next = &ext2; + + ext2.type = &ExtensionMessage_AllTypes_extensionfield2; + ext2.dest = &extensionfield2; + ext2.next = NULL; + + /* Decode the message */ + if (!pb_decode(&stream, AllTypes_fields, &alltypes)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } + + /* Check that the extensions decoded properly */ + TEST(ext1.found) + TEST(extensionfield1 == 12345) + TEST(ext2.found) + TEST(strcmp(extensionfield2.test1, "test") == 0) + TEST(extensionfield2.test2 == 54321) + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/extensions/encode_extensions.c b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/encode_extensions.c new file mode 100644 index 00000000..00745826 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/encode_extensions.c @@ -0,0 +1,54 @@ +/* Tests extension fields. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "extensions.pb.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + pb_ostream_t stream; + + AllTypes alltypes = {0}; + int32_t extensionfield1 = 12345; + pb_extension_t ext1; + ExtensionMessage extensionfield2 = {"test", 54321}; + pb_extension_t ext2; + + /* Set up the extensions */ + alltypes.extensions = &ext1; + + ext1.type = &AllTypes_extensionfield1; + ext1.dest = &extensionfield1; + ext1.next = &ext2; + + ext2.type = &ExtensionMessage_AllTypes_extensionfield2; + ext2.dest = &extensionfield2; + ext2.next = NULL; + + /* Set up the output stream */ + stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode the message and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + + /* Check that the field tags are properly generated */ + (void)AllTypes_extensionfield1_tag; + (void)ExtensionMessage_AllTypes_extensionfield2_tag; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.options b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.options new file mode 100644 index 00000000..a5cd61dd --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.options @@ -0,0 +1 @@ +* max_size:16 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.proto b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.proto new file mode 100644 index 00000000..fcd5b43b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/extensions/extensions.proto @@ -0,0 +1,19 @@ +syntax = "proto2"; + +import 'alltypes.proto'; + +extend AllTypes { + optional int32 AllTypes_extensionfield1 = 255 [default = 5]; +} + +message ExtensionMessage { + extend AllTypes { + optional ExtensionMessage AllTypes_extensionfield2 = 254; + // required ExtensionMessage AllTypes_extensionfield3 = 253; // No longer allowed by protobuf 3 + repeated ExtensionMessage AllTypes_extensionfield4 = 252; + } + + required string test1 = 1; + required int32 test2 = 2; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/SConscript new file mode 100644 index 00000000..75ac5c5e --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/SConscript @@ -0,0 +1,16 @@ +# Test that the decoder properly handles unknown fields in the input. + +Import("env") + +dec = env.GetBuildPath('$BUILD/basic_buffer/${PROGPREFIX}decode_buffer${PROGSUFFIX}') +env.RunTest('person_with_extra_field.output', [dec, "person_with_extra_field.pb"]) +env.Compare(["person_with_extra_field.output", "person_with_extra_field.expected"]) + +dec = env.GetBuildPath('$BUILD/basic_stream/${PROGPREFIX}decode_stream${PROGSUFFIX}') +env.RunTest('person_with_extra_field_stream.output', [dec, "person_with_extra_field.pb"]) +env.Compare(["person_with_extra_field_stream.output", "person_with_extra_field.expected"]) + +# This uses the backwards compatibility alltypes test, so that +# alltypes_with_extra_fields.pb doesn't have to be remade so often. +dec2 = env.GetBuildPath('$BUILD/backwards_compatibility/${PROGPREFIX}decode_legacy${PROGSUFFIX}') +env.RunTest('alltypes_with_extra_fields.output', [dec2, 'alltypes_with_extra_fields.pb']) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/person_with_extra_field.expected b/hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/person_with_extra_field.expected new file mode 100644 index 00000000..da9c32df --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/extra_fields/person_with_extra_field.expected @@ -0,0 +1,14 @@ +name: "Test Person 99" +id: 99 +email: "test@person.com" +phone { + number: "555-12345678" + type: MOBILE +} +phone { + number: "99-2342" +} +phone { + number: "1234-5678" + type: WORK +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/SConscript new file mode 100644 index 00000000..99bc3440 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/SConscript @@ -0,0 +1,32 @@ +# Run the alltypes test case, but compile with PB_FIELD_16BIT=1. +# Also the .proto file has been modified to have high indexes. + +Import("env") + +# Take copy of the files for custom build. +c = Copy("$TARGET", "$SOURCE") +env.Command("encode_alltypes.c", "$BUILD/alltypes/encode_alltypes.c", c) +env.Command("decode_alltypes.c", "$BUILD/alltypes/decode_alltypes.c", c) + +env.NanopbProto(["alltypes", "alltypes.options"]) + +# Define the compilation options +opts = env.Clone() +opts.Append(CPPDEFINES = {'PB_FIELD_16BIT': 1}) + +# Build new version of core +strict = opts.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_decode_fields16.o", "$NANOPB/pb_decode.c") +strict.Object("pb_encode_fields16.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common_fields16.o", "$NANOPB/pb_common.c") + +# Now build and run the test normally. +enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields16.o", "pb_common_fields16.o"]) +dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields16.o", "pb_common_fields16.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) + +env.RunTest("optionals.output", enc, ARGS = ['1']) +env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.options new file mode 100644 index 00000000..78dd08d1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.options @@ -0,0 +1,4 @@ +* max_size:16 +* max_count:5 +*.*fbytes fixed_length:true max_size:4 + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.proto new file mode 100644 index 00000000..46ac46af --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16/alltypes.proto @@ -0,0 +1,123 @@ +syntax = "proto2"; + +message SubMessage { + required string substuff1 = 1 [default = "1"]; + required int32 substuff2 = 2 [default = 2]; + optional fixed32 substuff3 = 65535 [default = 3]; +} + +message EmptyMessage { + +} + +enum HugeEnum { + Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ + Positive = 2147483647; +} + +message Limits { + required int32 int32_min = 1; + required int32 int32_max = 2; + required uint32 uint32_min = 3; + required uint32 uint32_max = 4; + required int64 int64_min = 5; + required int64 int64_max = 6; + required uint64 uint64_min = 7; + required uint64 uint64_max = 8; + required HugeEnum enum_min = 9; + required HugeEnum enum_max = 10; +} + +enum MyEnum { + Zero = 0; + First = 1; + Second = 2; + Truth = 42; +} + +message AllTypes { + required int32 req_int32 = 1; + required int64 req_int64 = 2; + required uint32 req_uint32 = 3; + required uint64 req_uint64 = 4; + required sint32 req_sint32 = 5; + required sint64 req_sint64 = 6; + required bool req_bool = 7; + + required fixed32 req_fixed32 = 8; + required sfixed32 req_sfixed32= 9; + required float req_float = 10; + + required fixed64 req_fixed64 = 11; + required sfixed64 req_sfixed64= 12; + required double req_double = 13; + + required string req_string = 14; + required bytes req_bytes = 15; + required SubMessage req_submsg = 16; + required MyEnum req_enum = 17; + required EmptyMessage req_emptymsg = 18; + required bytes req_fbytes = 19; + + repeated int32 rep_int32 = 21; + repeated int64 rep_int64 = 22; + repeated uint32 rep_uint32 = 23; + repeated uint64 rep_uint64 = 24; + repeated sint32 rep_sint32 = 25; + repeated sint64 rep_sint64 = 26; + repeated bool rep_bool = 27; + + repeated fixed32 rep_fixed32 = 28; + repeated sfixed32 rep_sfixed32= 29; + repeated float rep_float = 30; + + repeated fixed64 rep_fixed64 = 10031; + repeated sfixed64 rep_sfixed64= 10032; + repeated double rep_double = 10033; + + repeated string rep_string = 10034; + repeated bytes rep_bytes = 10035; + repeated SubMessage rep_submsg = 10036; + repeated MyEnum rep_enum = 10037; + repeated EmptyMessage rep_emptymsg = 10038; + repeated bytes rep_fbytes = 10039; + + optional int32 opt_int32 = 10041 [default = 4041]; + optional int64 opt_int64 = 10042 [default = 4042]; + optional uint32 opt_uint32 = 10043 [default = 4043]; + optional uint64 opt_uint64 = 10044 [default = 4044]; + optional sint32 opt_sint32 = 10045 [default = 4045]; + optional sint64 opt_sint64 = 10046 [default = 4046]; + optional bool opt_bool = 10047 [default = false]; + + optional fixed32 opt_fixed32 = 10048 [default = 4048]; + optional sfixed32 opt_sfixed32= 10049 [default = 4049]; + optional float opt_float = 10050 [default = 4050]; + + optional fixed64 opt_fixed64 = 10051 [default = 4051]; + optional sfixed64 opt_sfixed64= 10052 [default = 4052]; + optional double opt_double = 10053 [default = 4053]; + + optional string opt_string = 10054 [default = "4054"]; + optional bytes opt_bytes = 10055 [default = "4055"]; + optional SubMessage opt_submsg = 10056; + optional MyEnum opt_enum = 10057 [default = Second]; + optional EmptyMessage opt_emptymsg = 10058; + optional bytes opt_fbytes = 10059 [default = "4059"]; + + oneof oneof + { + SubMessage oneof_msg1 = 10060; + EmptyMessage oneof_msg2 = 10061; + } + + // Check that extreme integer values are handled correctly + required Limits req_limits = 98; + + // Just to make sure that the size of the fields has been calculated + // properly, i.e. otherwise a bug in last field might not be detected. + required int32 end = 10099; + + extensions 200 to 255; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/SConscript new file mode 100644 index 00000000..912c0389 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/SConscript @@ -0,0 +1,34 @@ +# Version of AllTypes test case for protobuf 3 file format. + +Import("env") + +import re +match = None +if 'PROTOC_VERSION' in env: + match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION']) + +if match: + version = map(int, match.groups()) + +# proto3 syntax is supported by protoc >= 3.0.0 +if env.GetOption('clean') or (match and version[0] >= 3): + + env.NanopbProto(["alltypes", "alltypes.options"]) + + # Define the compilation options + opts = env.Clone() + opts.Append(CPPDEFINES = {'PB_FIELD_16BIT': 1}) + + # Build new version of core + strict = opts.Clone() + strict.Append(CFLAGS = strict['CORECFLAGS']) + strict.Object("pb_decode_fields16.o", "$NANOPB/pb_decode.c") + strict.Object("pb_encode_fields16.o", "$NANOPB/pb_encode.c") + strict.Object("pb_common_fields16.o", "$NANOPB/pb_common.c") + + # Now build and run the test normally. + enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields16.o", "pb_common_fields16.o"]) + dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields16.o", "pb_common_fields16.o"]) + + env.RunTest(enc) + env.RunTest([dec, "encode_alltypes.output"]) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.options new file mode 100644 index 00000000..edfbe788 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.options @@ -0,0 +1,4 @@ +* max_size:16 +* max_count:5 +*.*fbytes fixed_length:true max_size:4 +SubMessage.substuff1 max_size:256 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.proto new file mode 100644 index 00000000..f66109ec --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/alltypes.proto @@ -0,0 +1,100 @@ +syntax = "proto3"; +// package name placeholder + +message SubMessage { + string substuff1 = 1; + int32 substuff2 = 2; + fixed32 substuff3 = 3; +} + +message EmptyMessage { + +} + +enum HugeEnum { + HE_Zero = 0; + Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ + Positive = 2147483647; +} + +message Limits { + int32 int32_min = 1; + int32 int32_max = 2; + uint32 uint32_min = 3; + uint32 uint32_max = 4; + int64 int64_min = 5; + int64 int64_max = 6; + uint64 uint64_min = 7; + uint64 uint64_max = 8; + HugeEnum enum_min = 9; + HugeEnum enum_max = 10; +} + +enum MyEnum { + Zero = 0; + First = 1; + Second = 2; + Truth = 42; +} + +message AllTypes { + int32 sng_int32 = 1; + int64 sng_int64 = 2; + uint32 sng_uint32 = 3; + uint64 sng_uint64 = 4; + sint32 sng_sint32 = 5; + sint64 sng_sint64 = 6; + bool sng_bool = 7; + + fixed32 sng_fixed32 = 8; + sfixed32 sng_sfixed32= 9; + float sng_float = 10; + + fixed64 sng_fixed64 = 11; + sfixed64 sng_sfixed64= 12; + double sng_double = 13; + + string sng_string = 14; + bytes sng_bytes = 15; + SubMessage sng_submsg = 16; + MyEnum sng_enum = 17; + EmptyMessage sng_emptymsg = 18; + bytes sng_fbytes = 19; + + repeated int32 rep_int32 = 21 [packed = true]; + repeated int64 rep_int64 = 22 [packed = true]; + repeated uint32 rep_uint32 = 23 [packed = true]; + repeated uint64 rep_uint64 = 24 [packed = true]; + repeated sint32 rep_sint32 = 25 [packed = true]; + repeated sint64 rep_sint64 = 26 [packed = true]; + repeated bool rep_bool = 27 [packed = true]; + + repeated fixed32 rep_fixed32 = 28 [packed = true]; + repeated sfixed32 rep_sfixed32= 29 [packed = true]; + repeated float rep_float = 30 [packed = true]; + + repeated fixed64 rep_fixed64 = 31 [packed = true]; + repeated sfixed64 rep_sfixed64= 32 [packed = true]; + repeated double rep_double = 33 [packed = true]; + + repeated string rep_string = 34; + repeated bytes rep_bytes = 35; + repeated SubMessage rep_submsg = 36; + repeated MyEnum rep_enum = 37 [packed = true]; + repeated EmptyMessage rep_emptymsg = 38; + repeated bytes rep_fbytes = 39; + + oneof oneof + { + SubMessage oneof_msg1 = 59; + EmptyMessage oneof_msg2 = 60; + } + + // Check that extreme integer values are handled correctly + Limits req_limits = 98; + + // Just to make sure that the size of the fields has been calculated + // properly, i.e. otherwise a bug in last field might not be detected. + int32 end = 99; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/decode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/decode_alltypes.c new file mode 100644 index 00000000..6611f8cc --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/decode_alltypes.c @@ -0,0 +1,167 @@ +/* Tests the decoding of all types. + * This is the counterpart of test_encode3. + * Run e.g. ./test_encode3 | ./test_decode3 + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed.\n"); \ + return false; \ + } + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + AllTypes alltypes = AllTypes_init_zero; + + /* Fill with garbage to better detect initialization errors */ + memset(&alltypes, 0xAA, sizeof(alltypes)); + + if (!pb_decode(stream, AllTypes_fields, &alltypes)) + return false; + + TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0); + TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0); + TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0); + TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0); + TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0); + TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0); + TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false); + + TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0); + TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0); + TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f); + + TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0); + TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0); + TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0); + + TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0'); + TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0); + TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0); + + TEST(alltypes.rep_submsg_count == 5); + TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0'); + TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0); + TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 0); + + TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero); + TEST(alltypes.rep_emptymsg_count == 5); + + TEST(alltypes.rep_fbytes_count == 5); + TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0); + TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0); + + if (mode == 0) + { + /* Expect default values */ + TEST(alltypes.sng_int32 == 0); + TEST(alltypes.sng_int64 == 0); + TEST(alltypes.sng_uint32 == 0); + TEST(alltypes.sng_uint64 == 0); + TEST(alltypes.sng_sint32 == 0); + TEST(alltypes.sng_sint64 == 0); + TEST(alltypes.sng_bool == false); + + TEST(alltypes.sng_fixed32 == 0); + TEST(alltypes.sng_sfixed32 == 0); + TEST(alltypes.sng_float == 0.0f); + + TEST(alltypes.sng_fixed64 == 0); + TEST(alltypes.sng_sfixed64 == 0); + TEST(alltypes.sng_double == 0.0); + + TEST(strcmp(alltypes.sng_string, "") == 0); + TEST(alltypes.sng_bytes.size == 0); + TEST(strcmp(alltypes.sng_submsg.substuff1, "") == 0); + TEST(alltypes.sng_submsg.substuff2 == 0); + TEST(alltypes.sng_submsg.substuff3 == 0); + TEST(alltypes.sng_enum == MyEnum_Zero); + TEST(alltypes.sng_fbytes[0] == 0 && + alltypes.sng_fbytes[1] == 0 && + alltypes.sng_fbytes[2] == 0 && + alltypes.sng_fbytes[3] == 0); + + TEST(alltypes.which_oneof == 0); + } + else + { + /* Expect filled-in values */ + TEST(alltypes.sng_int32 == 3041); + TEST(alltypes.sng_int64 == 3042); + TEST(alltypes.sng_uint32 == 3043); + TEST(alltypes.sng_uint64 == 3044); + TEST(alltypes.sng_sint32 == 3045); + TEST(alltypes.sng_sint64 == 3046); + TEST(alltypes.sng_bool == true); + + TEST(alltypes.sng_fixed32 == 3048); + TEST(alltypes.sng_sfixed32 == 3049); + TEST(alltypes.sng_float == 3050.0f); + + TEST(alltypes.sng_fixed64 == 3051); + TEST(alltypes.sng_sfixed64 == 3052); + TEST(alltypes.sng_double == 3053.0); + + TEST(strcmp(alltypes.sng_string, "3054") == 0); + TEST(alltypes.sng_bytes.size == 4); + TEST(memcmp(alltypes.sng_bytes.bytes, "3055", 4) == 0); + TEST(strcmp(alltypes.sng_submsg.substuff1, "3056") == 0); + TEST(alltypes.sng_submsg.substuff2 == 3056); + TEST(alltypes.sng_submsg.substuff3 == 0); + TEST(alltypes.sng_enum == MyEnum_Truth); + TEST(memcmp(alltypes.sng_fbytes, "3059", 4) == 0); + + TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag); + TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0); + TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059); + } + + TEST(alltypes.req_limits.int32_min == INT32_MIN); + TEST(alltypes.req_limits.int32_max == INT32_MAX); + TEST(alltypes.req_limits.uint32_min == 0); + TEST(alltypes.req_limits.uint32_max == UINT32_MAX); + TEST(alltypes.req_limits.int64_min == INT64_MIN); + TEST(alltypes.req_limits.int64_max == INT64_MAX); + TEST(alltypes.req_limits.uint64_min == 0); + TEST(alltypes.req_limits.uint64_max == UINT64_MAX); + TEST(alltypes.req_limits.enum_min == HugeEnum_Negative); + TEST(alltypes.req_limits.enum_max == HugeEnum_Positive); + + TEST(alltypes.end == 1099); + + return true; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[2048]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!check_alltypes(&stream, mode)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/encode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/encode_alltypes.c new file mode 100644 index 00000000..1da06688 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_16_proto3/encode_alltypes.c @@ -0,0 +1,111 @@ +/* Attempts to test all the datatypes supported by ProtoBuf3. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Initialize the structure with constants */ + AllTypes alltypes = AllTypes_init_zero; + + alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001; + alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002; + alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003; + alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004; + alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005; + alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006; + alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true; + + alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008; + alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009; + alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f; + + alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011; + alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012; + alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0; + + alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014"); + alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4; + memcpy(alltypes.rep_bytes[4].bytes, "2015", 4); + + alltypes.rep_submsg_count = 5; + strcpy(alltypes.rep_submsg[4].substuff1, "2016"); + alltypes.rep_submsg[4].substuff2 = 2016; + alltypes.rep_submsg[4].substuff3 = 2016; + + alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth; + alltypes.rep_emptymsg_count = 5; + + alltypes.rep_fbytes_count = 5; + memcpy(alltypes.rep_fbytes[4], "2019", 4); + + alltypes.req_limits.int32_min = INT32_MIN; + alltypes.req_limits.int32_max = INT32_MAX; + alltypes.req_limits.uint32_min = 0; + alltypes.req_limits.uint32_max = UINT32_MAX; + alltypes.req_limits.int64_min = INT64_MIN; + alltypes.req_limits.int64_max = INT64_MAX; + alltypes.req_limits.uint64_min = 0; + alltypes.req_limits.uint64_max = UINT64_MAX; + alltypes.req_limits.enum_min = HugeEnum_Negative; + alltypes.req_limits.enum_max = HugeEnum_Positive; + + if (mode != 0) + { + /* Fill in values for singular fields */ + alltypes.sng_int32 = 3041; + alltypes.sng_int64 = 3042; + alltypes.sng_uint32 = 3043; + alltypes.sng_uint64 = 3044; + alltypes.sng_sint32 = 3045; + alltypes.sng_sint64 = 3046; + alltypes.sng_bool = true; + + alltypes.sng_fixed32 = 3048; + alltypes.sng_sfixed32 = 3049; + alltypes.sng_float = 3050.0f; + + alltypes.sng_fixed64 = 3051; + alltypes.sng_sfixed64 = 3052; + alltypes.sng_double = 3053.0; + + strcpy(alltypes.sng_string, "3054"); + alltypes.sng_bytes.size = 4; + memcpy(alltypes.sng_bytes.bytes, "3055", 4); + strcpy(alltypes.sng_submsg.substuff1, "3056"); + alltypes.sng_submsg.substuff2 = 3056; + alltypes.sng_enum = MyEnum_Truth; + memcpy(alltypes.sng_fbytes, "3059", 4); + + alltypes.which_oneof = AllTypes_oneof_msg1_tag; + strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059"); + alltypes.oneof.oneof_msg1.substuff2 = 4059; + } + + alltypes.end = 1099; + + { + uint8_t buffer[AllTypes_size]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/SConscript new file mode 100644 index 00000000..650c6268 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/SConscript @@ -0,0 +1,32 @@ +# Run the alltypes test case, but compile with PB_FIELD_32BIT=1. +# Also the .proto file has been modified to have high indexes. + +Import("env") + +# Take copy of the files for custom build. +c = Copy("$TARGET", "$SOURCE") +env.Command("encode_alltypes.c", "$BUILD/alltypes/encode_alltypes.c", c) +env.Command("decode_alltypes.c", "$BUILD/alltypes/decode_alltypes.c", c) + +env.NanopbProto(["alltypes", "alltypes.options"]) + +# Define the compilation options +opts = env.Clone() +opts.Append(CPPDEFINES = {'PB_FIELD_32BIT': 1}) + +# Build new version of core +strict = opts.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_decode_fields32.o", "$NANOPB/pb_decode.c") +strict.Object("pb_encode_fields32.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common_fields32.o", "$NANOPB/pb_common.c") + +# Now build and run the test normally. +enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields32.o", "pb_common_fields32.o"]) +dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields32.o", "pb_common_fields32.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) + +env.RunTest("optionals.output", enc, ARGS = ['1']) +env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.options new file mode 100644 index 00000000..0d5ab12b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.options @@ -0,0 +1,3 @@ +* max_size:16 +* max_count:5 +*.*fbytes fixed_length:true max_size:4 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.proto new file mode 100644 index 00000000..ac76c8ef --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/field_size_32/alltypes.proto @@ -0,0 +1,123 @@ +syntax = "proto2"; + +message SubMessage { + required string substuff1 = 1 [default = "1"]; + required int32 substuff2 = 2 [default = 2]; + optional fixed32 substuff3 = 12365535 [default = 3]; +} + +message EmptyMessage { + +} + +enum HugeEnum { + Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ + Positive = 2147483647; +} + +message Limits { + required int32 int32_min = 1; + required int32 int32_max = 2; + required uint32 uint32_min = 3; + required uint32 uint32_max = 4; + required int64 int64_min = 5; + required int64 int64_max = 6; + required uint64 uint64_min = 7; + required uint64 uint64_max = 8; + required HugeEnum enum_min = 9; + required HugeEnum enum_max = 10; +} + +enum MyEnum { + Zero = 0; + First = 1; + Second = 2; + Truth = 42; +} + +message AllTypes { + required int32 req_int32 = 1; + required int64 req_int64 = 2; + required uint32 req_uint32 = 3; + required uint64 req_uint64 = 4; + required sint32 req_sint32 = 5; + required sint64 req_sint64 = 6; + required bool req_bool = 7; + + required fixed32 req_fixed32 = 8; + required sfixed32 req_sfixed32= 9; + required float req_float = 10; + + required fixed64 req_fixed64 = 11; + required sfixed64 req_sfixed64= 12; + required double req_double = 13; + + required string req_string = 14; + required bytes req_bytes = 15; + required SubMessage req_submsg = 16; + required MyEnum req_enum = 17; + required EmptyMessage req_emptymsg = 18; + required bytes req_fbytes = 19; + + repeated int32 rep_int32 = 21; + repeated int64 rep_int64 = 22; + repeated uint32 rep_uint32 = 23; + repeated uint64 rep_uint64 = 24; + repeated sint32 rep_sint32 = 25; + repeated sint64 rep_sint64 = 26; + repeated bool rep_bool = 27; + + repeated fixed32 rep_fixed32 = 28; + repeated sfixed32 rep_sfixed32= 29; + repeated float rep_float = 30; + + repeated fixed64 rep_fixed64 = 10031; + repeated sfixed64 rep_sfixed64= 10032; + repeated double rep_double = 10033; + + repeated string rep_string = 10034; + repeated bytes rep_bytes = 10035; + repeated SubMessage rep_submsg = 10036; + repeated MyEnum rep_enum = 10037; + repeated EmptyMessage rep_emptymsg = 10038; + repeated bytes rep_fbytes = 10039; + + optional int32 opt_int32 = 10041 [default = 4041]; + optional int64 opt_int64 = 10042 [default = 4042]; + optional uint32 opt_uint32 = 10043 [default = 4043]; + optional uint64 opt_uint64 = 10044 [default = 4044]; + optional sint32 opt_sint32 = 10045 [default = 4045]; + optional sint64 opt_sint64 = 10046 [default = 4046]; + optional bool opt_bool = 10047 [default = false]; + + optional fixed32 opt_fixed32 = 10048 [default = 4048]; + optional sfixed32 opt_sfixed32= 10049 [default = 4049]; + optional float opt_float = 10050 [default = 4050]; + + optional fixed64 opt_fixed64 = 10051 [default = 4051]; + optional sfixed64 opt_sfixed64= 10052 [default = 4052]; + optional double opt_double = 10053 [default = 4053]; + + optional string opt_string = 10054 [default = "4054"]; + optional bytes opt_bytes = 10055 [default = "4055"]; + optional SubMessage opt_submsg = 10056; + optional MyEnum opt_enum = 10057 [default = Second]; + optional EmptyMessage opt_emptymsg = 10058; + optional bytes opt_fbytes = 10059 [default = "4059"]; + + oneof oneof + { + SubMessage oneof_msg1 = 10060; + EmptyMessage oneof_msg2 = 10061; + } + + // Check that extreme integer values are handled correctly + required Limits req_limits = 98; + + // Just to make sure that the size of the fields has been calculated + // properly, i.e. otherwise a bug in last field might not be detected. + required int32 end = 13432099; + + extensions 200 to 255; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/SConscript new file mode 100644 index 00000000..d2fb689c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/SConscript @@ -0,0 +1,43 @@ +# Run a fuzz test to verify robustness against corrupted/malicious data. + +Import("env", "malloc_env") + +def set_pkgname(src, dst, pkgname): + data = open(str(src)).read() + placeholder = '// package name placeholder' + assert placeholder in data + data = data.replace(placeholder, 'package %s;' % pkgname) + open(str(dst), 'w').write(data) + +# We want both pointer and static versions of the AllTypes message +# Prefix them with package name. +env.Command("alltypes_static.proto", "#alltypes/alltypes.proto", + lambda target, source, env: set_pkgname(source[0], target[0], 'alltypes_static')) +env.Command("alltypes_pointer.proto", "#alltypes/alltypes.proto", + lambda target, source, env: set_pkgname(source[0], target[0], 'alltypes_pointer')) + +p1 = env.NanopbProto(["alltypes_pointer", "alltypes_pointer.options"]) +p2 = env.NanopbProto(["alltypes_static", "alltypes_static.options"]) +fuzz = malloc_env.Program(["fuzztest.c", + "alltypes_pointer.pb.c", + "alltypes_static.pb.c", + "$COMMON/pb_encode_with_malloc.o", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) + +env.RunTest(fuzz) + +fuzzstub = malloc_env.Program(["fuzzstub.c", + "alltypes_pointer.pb.c", + "alltypes_static.pb.c", + "$COMMON/pb_encode_with_malloc.o", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) + +generate_message = malloc_env.Program(["generate_message.c", + "alltypes_static.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_pointer.options b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_pointer.options new file mode 100644 index 00000000..7e3ad1e5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_pointer.options @@ -0,0 +1,3 @@ +# Generate all fields as pointers. +* type:FT_POINTER +*.*fbytes fixed_length:true max_size:4 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_static.options b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_static.options new file mode 100644 index 00000000..e197e1df --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/alltypes_static.options @@ -0,0 +1,4 @@ +* max_size:32 +* max_count:8 +*.extensions type:FT_IGNORE +*.*fbytes fixed_length:true max_size:4 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzzstub.c b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzzstub.c new file mode 100644 index 00000000..ec9e2afe --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzzstub.c @@ -0,0 +1,189 @@ +/* Fuzz testing for the nanopb core. + * This can be used with external fuzzers, e.g. radamsa. + * It performs most of the same checks as fuzztest, but does not feature data generation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "alltypes_static.pb.h" +#include "alltypes_pointer.pb.h" + +#define BUFSIZE 4096 + +static bool do_static_decode(uint8_t *buffer, size_t msglen, bool assert_success) +{ + pb_istream_t stream; + bool status; + + alltypes_static_AllTypes *msg = malloc_with_check(sizeof(alltypes_static_AllTypes)); + stream = pb_istream_from_buffer(buffer, msglen); + status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg); + + if (!status && assert_success) + { + /* Anything that was successfully encoded, should be decodeable. + * One exception: strings without null terminator are encoded up + * to end of buffer, but refused on decode because the terminator + * would not fit. */ + if (strcmp(stream.errmsg, "string overflow") != 0) + assert(status); + } + + free_with_check(msg); + return status; +} + +static bool do_pointer_decode(uint8_t *buffer, size_t msglen, bool assert_success) +{ + pb_istream_t stream; + bool status; + alltypes_pointer_AllTypes *msg; + + msg = malloc_with_check(sizeof(alltypes_pointer_AllTypes)); + memset(msg, 0, sizeof(alltypes_pointer_AllTypes)); + stream = pb_istream_from_buffer(buffer, msglen); + + assert(get_alloc_count() == 0); + status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg); + + if (assert_success) + assert(status); + + pb_release(alltypes_pointer_AllTypes_fields, msg); + assert(get_alloc_count() == 0); + + free_with_check(msg); + + return status; +} + +/* Do a decode -> encode -> decode -> encode roundtrip */ +static void do_static_roundtrip(uint8_t *buffer, size_t msglen) +{ + bool status; + uint8_t *buf2 = malloc_with_check(BUFSIZE); + uint8_t *buf3 = malloc_with_check(BUFSIZE); + size_t msglen2, msglen3; + alltypes_static_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_static_AllTypes)); + alltypes_static_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_static_AllTypes)); + memset(msg1, 0, sizeof(alltypes_static_AllTypes)); + memset(msg2, 0, sizeof(alltypes_static_AllTypes)); + + { + pb_istream_t stream = pb_istream_from_buffer(buffer, msglen); + status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg1); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE); + status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg1); + assert(status); + msglen2 = stream.bytes_written; + } + + { + pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2); + status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg2); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE); + status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg2); + assert(status); + msglen3 = stream.bytes_written; + } + + assert(msglen2 == msglen3); + assert(memcmp(buf2, buf3, msglen2) == 0); + + free_with_check(msg1); + free_with_check(msg2); + free_with_check(buf2); + free_with_check(buf3); +} + +/* Do decode -> encode -> decode -> encode roundtrip */ +static void do_pointer_roundtrip(uint8_t *buffer, size_t msglen) +{ + bool status; + uint8_t *buf2 = malloc_with_check(BUFSIZE); + uint8_t *buf3 = malloc_with_check(BUFSIZE); + size_t msglen2, msglen3; + alltypes_pointer_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_pointer_AllTypes)); + alltypes_pointer_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_pointer_AllTypes)); + memset(msg1, 0, sizeof(alltypes_pointer_AllTypes)); + memset(msg2, 0, sizeof(alltypes_pointer_AllTypes)); + + { + pb_istream_t stream = pb_istream_from_buffer(buffer, msglen); + status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg1); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE); + status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg1); + assert(status); + msglen2 = stream.bytes_written; + } + + { + pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2); + status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg2); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE); + status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg2); + assert(status); + msglen3 = stream.bytes_written; + } + + assert(msglen2 == msglen3); + assert(memcmp(buf2, buf3, msglen2) == 0); + + pb_release(alltypes_pointer_AllTypes_fields, msg1); + pb_release(alltypes_pointer_AllTypes_fields, msg2); + free_with_check(msg1); + free_with_check(msg2); + free_with_check(buf2); + free_with_check(buf3); +} + +static void run_iteration() +{ + uint8_t *buffer = malloc_with_check(BUFSIZE); + size_t msglen; + bool status; + + msglen = fread(buffer, 1, BUFSIZE, stdin); + + status = do_static_decode(buffer, msglen, false); + + if (status) + do_static_roundtrip(buffer, msglen); + + status = do_pointer_decode(buffer, msglen, false); + + if (status) + do_pointer_roundtrip(buffer, msglen); + + free_with_check(buffer); +} + +int main(int argc, char **argv) +{ + run_iteration(); + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzztest.c b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzztest.c new file mode 100644 index 00000000..ee851ec0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/fuzztest.c @@ -0,0 +1,432 @@ +/* Fuzz testing for the nanopb core. + * Attempts to verify all the properties defined in the security model document. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "alltypes_static.pb.h" +#include "alltypes_pointer.pb.h" + +static uint64_t random_seed; + +/* Uses xorshift64 here instead of rand() for both speed and + * reproducibility across platforms. */ +static uint32_t rand_word() +{ + random_seed ^= random_seed >> 12; + random_seed ^= random_seed << 25; + random_seed ^= random_seed >> 27; + return random_seed * 2685821657736338717ULL; +} + +/* Get a random integer in range, with approximately flat distribution. */ +static int rand_int(int min, int max) +{ + return rand_word() % (max + 1 - min) + min; +} + +static bool rand_bool() +{ + return rand_word() & 1; +} + +/* Get a random byte, with skewed distribution. + * Important corner cases like 0xFF, 0x00 and 0xFE occur more + * often than other values. */ +static uint8_t rand_byte() +{ + uint32_t w = rand_word(); + uint8_t b = w & 0xFF; + if (w & 0x100000) + b >>= (w >> 8) & 7; + if (w & 0x200000) + b <<= (w >> 12) & 7; + if (w & 0x400000) + b ^= 0xFF; + return b; +} + +/* Get a random length, with skewed distribution. + * Favors the shorter lengths, but always atleast 1. */ +static size_t rand_len(size_t max) +{ + uint32_t w = rand_word(); + size_t s; + if (w & 0x800000) + w &= 3; + else if (w & 0x400000) + w &= 15; + else if (w & 0x200000) + w &= 255; + + s = (w % max); + if (s == 0) + s = 1; + + return s; +} + +/* Fills a buffer with random data with skewed distribution. */ +static void rand_fill(uint8_t *buf, size_t count) +{ + while (count--) + *buf++ = rand_byte(); +} + +/* Fill with random protobuf-like data */ +static size_t rand_fill_protobuf(uint8_t *buf, size_t min_bytes, size_t max_bytes, int min_tag) +{ + pb_ostream_t stream = pb_ostream_from_buffer(buf, max_bytes); + + while(stream.bytes_written < min_bytes) + { + pb_wire_type_t wt = rand_int(0, 3); + if (wt == 3) wt = 5; /* Gap in values */ + + if (!pb_encode_tag(&stream, wt, rand_int(min_tag, min_tag + 512))) + break; + + if (wt == PB_WT_VARINT) + { + uint64_t value; + rand_fill((uint8_t*)&value, sizeof(value)); + pb_encode_varint(&stream, value); + } + else if (wt == PB_WT_64BIT) + { + uint64_t value; + rand_fill((uint8_t*)&value, sizeof(value)); + pb_encode_fixed64(&stream, &value); + } + else if (wt == PB_WT_32BIT) + { + uint32_t value; + rand_fill((uint8_t*)&value, sizeof(value)); + pb_encode_fixed32(&stream, &value); + } + else if (wt == PB_WT_STRING) + { + size_t len; + uint8_t *buf; + + if (min_bytes > stream.bytes_written) + len = rand_len(min_bytes - stream.bytes_written); + else + len = 0; + + buf = malloc(len); + pb_encode_varint(&stream, len); + rand_fill(buf, len); + pb_write(&stream, buf, len); + free(buf); + } + } + + return stream.bytes_written; +} + +/* Given a buffer of data, mess it up a bit */ +static void rand_mess(uint8_t *buf, size_t count) +{ + int m = rand_int(0, 3); + + if (m == 0) + { + /* Replace random substring */ + int s = rand_int(0, count - 1); + int l = rand_len(count - s); + rand_fill(buf + s, l); + } + else if (m == 1) + { + /* Swap random bytes */ + int a = rand_int(0, count - 1); + int b = rand_int(0, count - 1); + int x = buf[a]; + buf[a] = buf[b]; + buf[b] = x; + } + else if (m == 2) + { + /* Duplicate substring */ + int s = rand_int(0, count - 2); + int l = rand_len((count - s) / 2); + memcpy(buf + s + l, buf + s, l); + } + else if (m == 3) + { + /* Add random protobuf noise */ + int s = rand_int(0, count - 1); + int l = rand_len(count - s); + rand_fill_protobuf(buf + s, l, count - s, 1); + } +} + +/* Some default data to put in the message */ +static const alltypes_static_AllTypes initval = alltypes_static_AllTypes_init_default; + +#define BUFSIZE 4096 + +static bool do_static_encode(uint8_t *buffer, size_t *msglen) +{ + pb_ostream_t stream; + bool status; + + /* Allocate a message and fill it with defaults */ + alltypes_static_AllTypes *msg = malloc_with_check(sizeof(alltypes_static_AllTypes)); + memcpy(msg, &initval, sizeof(initval)); + + /* Apply randomness to the data before encoding */ + while (rand_int(0, 7)) + rand_mess((uint8_t*)msg, sizeof(alltypes_static_AllTypes)); + + stream = pb_ostream_from_buffer(buffer, BUFSIZE); + status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg); + assert(stream.bytes_written <= BUFSIZE); + assert(stream.bytes_written <= alltypes_static_AllTypes_size); + + *msglen = stream.bytes_written; + pb_release(alltypes_static_AllTypes_fields, msg); + free_with_check(msg); + + return status; +} + +/* Append or prepend protobuf noise */ +static void do_protobuf_noise(uint8_t *buffer, size_t *msglen) +{ + int m = rand_int(0, 2); + size_t max_size = BUFSIZE - 32 - *msglen; + if (m == 1) + { + /* Prepend */ + uint8_t *tmp = malloc_with_check(BUFSIZE); + size_t s = rand_fill_protobuf(tmp, rand_len(max_size), BUFSIZE - *msglen, 512); + memmove(buffer + s, buffer, *msglen); + memcpy(buffer, tmp, s); + free_with_check(tmp); + *msglen += s; + } + else if (m == 2) + { + /* Append */ + size_t s = rand_fill_protobuf(buffer + *msglen, rand_len(max_size), BUFSIZE - *msglen, 512); + *msglen += s; + } +} + +static bool do_static_decode(uint8_t *buffer, size_t msglen, bool assert_success) +{ + pb_istream_t stream; + bool status; + + alltypes_static_AllTypes *msg = malloc_with_check(sizeof(alltypes_static_AllTypes)); + rand_fill((uint8_t*)msg, sizeof(alltypes_static_AllTypes)); + stream = pb_istream_from_buffer(buffer, msglen); + status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg); + + if (!status && assert_success) + { + /* Anything that was successfully encoded, should be decodeable. + * One exception: strings without null terminator are encoded up + * to end of buffer, but refused on decode because the terminator + * would not fit. */ + if (strcmp(stream.errmsg, "string overflow") != 0) + assert(status); + } + + free_with_check(msg); + return status; +} + +static bool do_pointer_decode(uint8_t *buffer, size_t msglen, bool assert_success) +{ + pb_istream_t stream; + bool status; + alltypes_pointer_AllTypes *msg; + + msg = malloc_with_check(sizeof(alltypes_pointer_AllTypes)); + memset(msg, 0, sizeof(alltypes_pointer_AllTypes)); + stream = pb_istream_from_buffer(buffer, msglen); + + assert(get_alloc_count() == 0); + status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg); + + if (assert_success) + assert(status); + + pb_release(alltypes_pointer_AllTypes_fields, msg); + assert(get_alloc_count() == 0); + + free_with_check(msg); + + return status; +} + +/* Do a decode -> encode -> decode -> encode roundtrip */ +static void do_static_roundtrip(uint8_t *buffer, size_t msglen) +{ + bool status; + uint8_t *buf2 = malloc_with_check(BUFSIZE); + uint8_t *buf3 = malloc_with_check(BUFSIZE); + size_t msglen2, msglen3; + alltypes_static_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_static_AllTypes)); + alltypes_static_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_static_AllTypes)); + memset(msg1, 0, sizeof(alltypes_static_AllTypes)); + memset(msg2, 0, sizeof(alltypes_static_AllTypes)); + + { + pb_istream_t stream = pb_istream_from_buffer(buffer, msglen); + status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg1); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE); + status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg1); + assert(status); + msglen2 = stream.bytes_written; + } + + { + pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2); + status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg2); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE); + status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg2); + assert(status); + msglen3 = stream.bytes_written; + } + + assert(msglen2 == msglen3); + assert(memcmp(buf2, buf3, msglen2) == 0); + + free_with_check(msg1); + free_with_check(msg2); + free_with_check(buf2); + free_with_check(buf3); +} + +/* Do decode -> encode -> decode -> encode roundtrip */ +static void do_pointer_roundtrip(uint8_t *buffer, size_t msglen) +{ + bool status; + uint8_t *buf2 = malloc_with_check(BUFSIZE); + uint8_t *buf3 = malloc_with_check(BUFSIZE); + size_t msglen2, msglen3; + alltypes_pointer_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_pointer_AllTypes)); + alltypes_pointer_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_pointer_AllTypes)); + memset(msg1, 0, sizeof(alltypes_pointer_AllTypes)); + memset(msg2, 0, sizeof(alltypes_pointer_AllTypes)); + + { + pb_istream_t stream = pb_istream_from_buffer(buffer, msglen); + status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg1); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE); + status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg1); + assert(status); + msglen2 = stream.bytes_written; + } + + { + pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2); + status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg2); + assert(status); + } + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE); + status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg2); + assert(status); + msglen3 = stream.bytes_written; + } + + assert(msglen2 == msglen3); + assert(memcmp(buf2, buf3, msglen2) == 0); + + pb_release(alltypes_pointer_AllTypes_fields, msg1); + pb_release(alltypes_pointer_AllTypes_fields, msg2); + free_with_check(msg1); + free_with_check(msg2); + free_with_check(buf2); + free_with_check(buf3); +} + +static void run_iteration() +{ + uint8_t *buffer = malloc_with_check(BUFSIZE); + size_t msglen; + bool status; + + rand_fill(buffer, BUFSIZE); + + if (do_static_encode(buffer, &msglen)) + { + do_protobuf_noise(buffer, &msglen); + + status = do_static_decode(buffer, msglen, true); + + if (status) + do_static_roundtrip(buffer, msglen); + + status = do_pointer_decode(buffer, msglen, true); + + if (status) + do_pointer_roundtrip(buffer, msglen); + + /* Apply randomness to the encoded data */ + while (rand_bool()) + rand_mess(buffer, BUFSIZE); + + /* Apply randomness to encoded data length */ + if (rand_bool()) + msglen = rand_int(0, BUFSIZE); + + status = do_static_decode(buffer, msglen, false); + do_pointer_decode(buffer, msglen, status); + + if (status) + { + do_static_roundtrip(buffer, msglen); + do_pointer_roundtrip(buffer, msglen); + } + } + + free_with_check(buffer); +} + +int main(int argc, char **argv) +{ + int i; + if (argc > 1) + { + random_seed = atol(argv[1]); + } + else + { + random_seed = time(NULL); + } + + fprintf(stderr, "Random seed: %llu\n", (long long unsigned)random_seed); + + for (i = 0; i < 10000; i++) + { + run_iteration(); + } + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/generate_message.c b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/generate_message.c new file mode 100644 index 00000000..6e492990 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/generate_message.c @@ -0,0 +1,101 @@ +/* Generates a random, valid protobuf message. Useful to seed + * external fuzzers such as afl-fuzz. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "alltypes_static.pb.h" + +static uint64_t random_seed; + +/* Uses xorshift64 here instead of rand() for both speed and + * reproducibility across platforms. */ +static uint32_t rand_word() +{ + random_seed ^= random_seed >> 12; + random_seed ^= random_seed << 25; + random_seed ^= random_seed >> 27; + return random_seed * 2685821657736338717ULL; +} + +/* Fills a buffer with random data. */ +static void rand_fill(uint8_t *buf, size_t count) +{ + while (count--) + { + *buf++ = rand_word() & 0xff; + } +} + +/* Check that size/count fields do not exceed their max size. + * Otherwise we would have to loop pretty long in generate_message(). + * Note that there may still be a few encoding errors from submessages. + */ +static void limit_sizes(alltypes_static_AllTypes *msg) +{ + pb_field_iter_t iter; + pb_field_iter_begin(&iter, alltypes_static_AllTypes_fields, msg); + while (pb_field_iter_next(&iter)) + { + if (PB_LTYPE(iter.pos->type) == PB_LTYPE_BYTES) + { + ((pb_bytes_array_t*)iter.pData)->size %= iter.pos->data_size - PB_BYTES_ARRAY_T_ALLOCSIZE(0); + } + + if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REPEATED) + { + *((pb_size_t*)iter.pSize) %= iter.pos->array_size; + } + + if (PB_HTYPE(iter.pos->type) == PB_HTYPE_ONEOF) + { + /* Set the oneof to this message type with 50% chance. */ + if (rand_word() & 1) + { + *((pb_size_t*)iter.pSize) = iter.pos->tag; + } + } + } +} + +static void generate_message() +{ + alltypes_static_AllTypes msg; + uint8_t buf[8192]; + pb_ostream_t stream = {0}; + + do { + if (stream.errmsg) + fprintf(stderr, "Encoder error: %s\n", stream.errmsg); + + stream = pb_ostream_from_buffer(buf, sizeof(buf)); + rand_fill((void*)&msg, sizeof(msg)); + limit_sizes(&msg); + } while (!pb_encode(&stream, alltypes_static_AllTypes_fields, &msg)); + + fwrite(buf, 1, stream.bytes_written, stdout); +} + +int main(int argc, char **argv) +{ + if (argc > 1) + { + random_seed = atol(argv[1]); + } + else + { + random_seed = time(NULL); + } + + fprintf(stderr, "Random seed: %llu\n", (long long unsigned)random_seed); + + generate_message(); + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/run_radamsa.sh b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/run_radamsa.sh new file mode 100755 index 00000000..52cd40a8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/fuzztest/run_radamsa.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +TMP=`tempfile` + +echo $TMP +while true +do + radamsa sample_data/* > $TMP + $1 < $TMP + test $? -gt 127 && break +done + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/inline/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/inline/SConscript new file mode 100644 index 00000000..34371fda --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/inline/SConscript @@ -0,0 +1,16 @@ +# Test that inlined bytes fields work. + +Import("env") + +env.NanopbProto("inline") +env.Object("inline.pb.c") + +env.Match(["inline.pb.h", "inline.expected"]) + +p = env.Program(["inline_unittests.c", + "inline.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_decode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(p) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.expected b/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.expected new file mode 100644 index 00000000..593e972b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.expected @@ -0,0 +1,3 @@ +pb_byte_t data\[32\]; +bool has_data; +pb_byte_t data\[64\]; diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.proto b/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.proto new file mode 100644 index 00000000..6e511f0a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline.proto @@ -0,0 +1,17 @@ +/* Test nanopb option parsing. + * options.expected lists the patterns that are searched for in the output. + */ + +syntax = "proto2"; + +import "nanopb.proto"; + +message Message1 +{ + required bytes data = 1 [(nanopb).type = FT_INLINE, (nanopb).max_size = 32]; +} + +message Message2 +{ + optional bytes data = 1 [(nanopb).type = FT_INLINE, (nanopb).max_size = 64]; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline_unittests.c b/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline_unittests.c new file mode 100644 index 00000000..b5834c7e --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/inline/inline_unittests.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include "unittests.h" +#include "inline.pb.h" + +int main() +{ + int status = 0; + int i = 0; + COMMENT("Test inline byte fields"); + + { + Message1 msg1 = Message1_init_zero; + TEST(sizeof(msg1.data) == 32); + } + + { + Message1 msg1 = Message1_init_zero; + pb_byte_t msg1_buffer[Message1_size]; + pb_ostream_t ostream = pb_ostream_from_buffer(msg1_buffer, Message1_size); + Message1 msg1_deserialized = Message1_init_zero; + pb_istream_t istream = pb_istream_from_buffer(msg1_buffer, Message1_size); + + for (i = 0; i < 32; i++) { + msg1.data[i] = i; + } + + TEST(pb_encode(&ostream, Message1_fields, &msg1)); + TEST(ostream.bytes_written == Message1_size); + + TEST(pb_decode(&istream, Message1_fields, &msg1_deserialized)); + + TEST(istream.bytes_left == 0); + TEST(memcmp(&msg1_deserialized, &msg1, sizeof(msg1)) == 0); + } + + { + Message2 msg2 = {true, {0}}; + Message2 msg2_no_data = {false, {1}}; + pb_byte_t msg2_buffer[Message2_size]; + pb_ostream_t ostream = pb_ostream_from_buffer(msg2_buffer, Message2_size); + Message2 msg2_deserialized = Message2_init_zero; + pb_istream_t istream = pb_istream_from_buffer(msg2_buffer, Message2_size); + + for (i = 0; i < 64; i++) { + msg2.data[i] = i; + } + + TEST(pb_encode(&ostream, Message2_fields, &msg2)); + TEST(ostream.bytes_written == Message2_size); + + TEST(pb_decode(&istream, Message2_fields, &msg2_deserialized)); + + TEST(istream.bytes_left == 0); + TEST(memcmp(&msg2_deserialized, &msg2, sizeof(msg2)) == 0); + TEST(msg2_deserialized.has_data); + + memset(msg2_buffer, 0, sizeof(msg2_buffer)); + ostream = pb_ostream_from_buffer(msg2_buffer, Message2_size); + TEST(pb_encode(&ostream, Message2_fields, &msg2_no_data)); + istream = pb_istream_from_buffer(msg2_buffer, Message2_size); + TEST(pb_decode(&istream, Message2_fields, &msg2_deserialized)); + TEST(!msg2_deserialized.has_data); + TEST(memcmp(&msg2_deserialized, &msg2, sizeof(msg2)) != 0); + } + + if (status != 0) + fprintf(stdout, "\n\nSome tests FAILED!\n"); + + return status; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/SConscript new file mode 100644 index 00000000..a90680bc --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/SConscript @@ -0,0 +1,12 @@ +# Test that the int_size option in .proto works. + +Import('env') + +env.NanopbProto('intsizes') + +p = env.Program(["intsizes_unittests.c", + "intsizes.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_decode.o", + "$COMMON/pb_common.o"]) +env.RunTest(p) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes.proto new file mode 100644 index 00000000..91444d41 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes.proto @@ -0,0 +1,41 @@ +/* Test the integer size overriding in nanopb options. + * This allows to use 8- and 16-bit integer variables, which are not supported + * directly by Google Protobuf. + * + * The int_size setting will override the number of bits, but keep the type + * otherwise. E.g. uint32 + IS_8 => uint8_t + */ + +syntax = "proto2"; + +import 'nanopb.proto'; + +message IntSizes { + required int32 req_int8 = 1 [(nanopb).int_size = IS_8]; + required uint32 req_uint8 = 2 [(nanopb).int_size = IS_8]; + required sint32 req_sint8 = 3 [(nanopb).int_size = IS_8]; + required int32 req_int16 = 4 [(nanopb).int_size = IS_16]; + required uint32 req_uint16 = 5 [(nanopb).int_size = IS_16]; + required sint32 req_sint16 = 6 [(nanopb).int_size = IS_16]; + required int32 req_int32 = 7 [(nanopb).int_size = IS_32]; + required uint32 req_uint32 = 8 [(nanopb).int_size = IS_32]; + required sint32 req_sint32 = 9 [(nanopb).int_size = IS_32]; + required int32 req_int64 = 10 [(nanopb).int_size = IS_64]; + required uint32 req_uint64 = 11 [(nanopb).int_size = IS_64]; + required sint32 req_sint64 = 12 [(nanopb).int_size = IS_64]; +} + +message DefaultSizes { + required int32 req_int8 = 1 ; + required uint32 req_uint8 = 2 ; + required sint32 req_sint8 = 3 ; + required int32 req_int16 = 4 ; + required uint32 req_uint16 = 5 ; + required sint32 req_sint16 = 6 ; + required int32 req_int32 = 7 ; + required uint32 req_uint32 = 8 ; + required sint32 req_sint32 = 9 ; + required int64 req_int64 = 10; + required uint64 req_uint64 = 11; + required sint64 req_sint64 = 12; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes_unittests.c b/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes_unittests.c new file mode 100644 index 00000000..79ef0369 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/intsizes/intsizes_unittests.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include "unittests.h" +#include "intsizes.pb.h" + +#define S(x) pb_istream_from_buffer((uint8_t*)x, sizeof(x) - 1) + +/* This is a macro instead of function in order to get the actual values + * into the TEST() lines in output */ +#define TEST_ROUNDTRIP(int8, uint8, sint8, \ + int16, uint16, sint16, \ + int32, uint32, sint32, \ + int64, uint64, sint64, expected_result) \ +{ \ + uint8_t buffer1[128], buffer2[128]; \ + size_t msgsize; \ + DefaultSizes msg1 = DefaultSizes_init_zero; \ + IntSizes msg2 = IntSizes_init_zero; \ + \ + msg1.req_int8 = int8; \ + msg1.req_uint8 = uint8; \ + msg1.req_sint8 = sint8; \ + msg1.req_int16 = int16; \ + msg1.req_uint16 = uint16; \ + msg1.req_sint16 = sint16; \ + msg1.req_int32 = int32; \ + msg1.req_uint32 = uint32; \ + msg1.req_sint32 = sint32; \ + msg1.req_int64 = int64; \ + msg1.req_uint64 = uint64; \ + msg1.req_sint64 = sint64; \ + \ + { \ + pb_ostream_t s = pb_ostream_from_buffer(buffer1, sizeof(buffer1)); \ + TEST(pb_encode(&s, DefaultSizes_fields, &msg1)); \ + msgsize = s.bytes_written; \ + } \ + \ + { \ + pb_istream_t s = pb_istream_from_buffer(buffer1, msgsize); \ + TEST(pb_decode(&s, IntSizes_fields, &msg2) == expected_result); \ + if (expected_result) \ + { \ + TEST( (int64_t)msg2.req_int8 == int8); \ + TEST((uint64_t)msg2.req_uint8 == uint8); \ + TEST( (int64_t)msg2.req_sint8 == sint8); \ + TEST( (int64_t)msg2.req_int16 == int16); \ + TEST((uint64_t)msg2.req_uint16 == uint16); \ + TEST( (int64_t)msg2.req_sint16 == sint16); \ + TEST( (int64_t)msg2.req_int32 == int32); \ + TEST((uint64_t)msg2.req_uint32 == uint32); \ + TEST( (int64_t)msg2.req_sint32 == sint32); \ + TEST( (int64_t)msg2.req_int64 == int64); \ + TEST((uint64_t)msg2.req_uint64 == uint64); \ + TEST( (int64_t)msg2.req_sint64 == sint64); \ + } \ + } \ + \ + if (expected_result) \ + { \ + pb_ostream_t s = pb_ostream_from_buffer(buffer2, sizeof(buffer2)); \ + TEST(pb_encode(&s, IntSizes_fields, &msg2)); \ + TEST(s.bytes_written == msgsize); \ + TEST(memcmp(buffer1, buffer2, msgsize) == 0); \ + } \ +} + +int main() +{ + int status = 0; + + { + IntSizes msg = IntSizes_init_zero; + + COMMENT("Test field sizes"); + TEST(sizeof(msg.req_int8) == 1); + TEST(sizeof(msg.req_uint8) == 1); + TEST(sizeof(msg.req_sint8) == 1); + TEST(sizeof(msg.req_int16) == 2); + TEST(sizeof(msg.req_uint16) == 2); + TEST(sizeof(msg.req_sint16) == 2); + TEST(sizeof(msg.req_int32) == 4); + TEST(sizeof(msg.req_uint32) == 4); + TEST(sizeof(msg.req_sint32) == 4); + TEST(sizeof(msg.req_int64) == 8); + TEST(sizeof(msg.req_uint64) == 8); + TEST(sizeof(msg.req_sint64) == 8); + } + + COMMENT("Test roundtrip at maximum value"); + TEST_ROUNDTRIP(127, 255, 127, + 32767, 65535, 32767, + INT32_MAX, UINT32_MAX, INT32_MAX, + INT64_MAX, UINT64_MAX, INT64_MAX, true); + + COMMENT("Test roundtrip at minimum value"); + TEST_ROUNDTRIP(-128, 0, -128, + -32768, 0, -32768, + INT32_MIN, 0, INT32_MIN, + INT64_MIN, 0, INT64_MIN, true); + + COMMENT("Test overflow detection"); + TEST_ROUNDTRIP(-129, 0, -128, + -32768, 0, -32768, + INT32_MIN, 0, INT32_MIN, + INT64_MIN, 0, INT64_MIN, false); + TEST_ROUNDTRIP(127, 256, 127, + 32767, 65535, 32767, + INT32_MAX, UINT32_MAX, INT32_MAX, + INT64_MAX, UINT64_MAX, INT64_MAX, false); + TEST_ROUNDTRIP(-128, 0, -128, + -32768, 0, -32769, + INT32_MIN, 0, INT32_MIN, + INT64_MIN, 0, INT64_MIN, false); + + if (status != 0) + fprintf(stdout, "\n\nSome tests FAILED!\n"); + + return status; +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/SConscript new file mode 100644 index 00000000..60146cc0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/SConscript @@ -0,0 +1,15 @@ +# Simulate io errors when encoding and decoding + +Import("env") + +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.proto", "#alltypes/alltypes.proto", c) + +env.NanopbProto(["alltypes", "alltypes.options"]) + +ioerr = env.Program(["io_errors.c", "alltypes.pb.c", + "$COMMON/pb_encode.o", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) + +env.RunTest("io_errors.output", [ioerr, "$BUILD/alltypes/encode_alltypes.output"]) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/alltypes.options new file mode 100644 index 00000000..0d5ab12b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/alltypes.options @@ -0,0 +1,3 @@ +* max_size:16 +* max_count:5 +*.*fbytes fixed_length:true max_size:4 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/io_errors.c b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/io_errors.c new file mode 100644 index 00000000..76f35b08 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors/io_errors.c @@ -0,0 +1,140 @@ +/* Simulate IO errors after each byte in a stream. + * Verifies proper error propagation. + */ + +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +typedef struct +{ + uint8_t *buffer; + size_t fail_after; +} faulty_stream_t; + +bool read_callback(pb_istream_t *stream, uint8_t *buf, size_t count) +{ + faulty_stream_t *state = stream->state; + + while (count--) + { + if (state->fail_after == 0) + PB_RETURN_ERROR(stream, "simulated"); + state->fail_after--; + *buf++ = *state->buffer++; + } + + return true; +} +bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count) +{ + faulty_stream_t *state = stream->state; + + while (count--) + { + if (state->fail_after == 0) + PB_RETURN_ERROR(stream, "simulated"); + state->fail_after--; + *state->buffer++ = *buf++; + } + + return true; +} + +int main() +{ + uint8_t buffer[2048]; + size_t msglen; + AllTypes msg = AllTypes_init_zero; + + /* Get some base data to run the tests with */ + SET_BINARY_MODE(stdin); + msglen = fread(buffer, 1, sizeof(buffer), stdin); + + /* Test IO errors on decoding */ + { + bool status; + pb_istream_t stream = {&read_callback, NULL, SIZE_MAX}; + faulty_stream_t fs; + size_t i; + + for (i = 0; i < msglen; i++) + { + stream.bytes_left = msglen; + stream.state = &fs; + fs.buffer = buffer; + fs.fail_after = i; + + status = pb_decode(&stream, AllTypes_fields, &msg); + if (status != false) + { + fprintf(stderr, "Unexpected success in decode\n"); + return 2; + } + else if (strcmp(stream.errmsg, "simulated") != 0) + { + fprintf(stderr, "Wrong error in decode: %s\n", stream.errmsg); + return 3; + } + } + + stream.bytes_left = msglen; + stream.state = &fs; + fs.buffer = buffer; + fs.fail_after = msglen; + status = pb_decode(&stream, AllTypes_fields, &msg); + + if (!status) + { + fprintf(stderr, "Decoding failed: %s\n", stream.errmsg); + return 4; + } + } + + /* Test IO errors on encoding */ + { + bool status; + pb_ostream_t stream = {&write_callback, NULL, SIZE_MAX, 0}; + faulty_stream_t fs; + size_t i; + + for (i = 0; i < msglen; i++) + { + stream.max_size = msglen; + stream.bytes_written = 0; + stream.state = &fs; + fs.buffer = buffer; + fs.fail_after = i; + + status = pb_encode(&stream, AllTypes_fields, &msg); + if (status != false) + { + fprintf(stderr, "Unexpected success in encode\n"); + return 5; + } + else if (strcmp(stream.errmsg, "simulated") != 0) + { + fprintf(stderr, "Wrong error in encode: %s\n", stream.errmsg); + return 6; + } + } + + stream.max_size = msglen; + stream.bytes_written = 0; + stream.state = &fs; + fs.buffer = buffer; + fs.fail_after = msglen; + status = pb_encode(&stream, AllTypes_fields, &msg); + + if (!status) + { + fprintf(stderr, "Encoding failed: %s\n", stream.errmsg); + return 7; + } + } + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/SConscript new file mode 100644 index 00000000..03727df9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/SConscript @@ -0,0 +1,26 @@ +# Simulate io errors when encoding and decoding + +Import("env", "malloc_env") + +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.proto", "#alltypes/alltypes.proto", c) +env.Command("io_errors.c", "#io_errors/io_errors.c", c) + +env.NanopbProto(["alltypes", "alltypes.options"]) + +ioerr = env.Program(["io_errors.c", "alltypes.pb.c", + "$COMMON/pb_encode_with_malloc.o", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) + +# Run tests under valgrind if available +valgrind = env.WhereIs('valgrind') +kwargs = {} +if valgrind: + kwargs['COMMAND'] = valgrind + kwargs['ARGS'] = ["-q", "--error-exitcode=99", ioerr[0].abspath] + +env.RunTest("io_errors.output", [ioerr, "$BUILD/alltypes/encode_alltypes.output"], **kwargs) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/alltypes.options new file mode 100644 index 00000000..7e3ad1e5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/io_errors_pointers/alltypes.options @@ -0,0 +1,3 @@ +# Generate all fields as pointers. +* type:FT_POINTER +*.*fbytes fixed_length:true max_size:4 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/SConscript new file mode 100644 index 00000000..6754e285 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/SConscript @@ -0,0 +1,13 @@ +Import("env", "malloc_env") + +env.NanopbProto("mem_release.proto") + +test = malloc_env.Program(["mem_release.c", + "mem_release.pb.c", + "$COMMON/pb_encode_with_malloc.o", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) + +env.RunTest(test) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.c b/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.c new file mode 100644 index 00000000..dc6f87de --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.c @@ -0,0 +1,187 @@ +/* Make sure that all fields are freed in various scenarios. */ + +#include +#include +#include +#include +#include +#include "mem_release.pb.h" + +#define TEST(x) if (!(x)) { \ + fprintf(stderr, "Test " #x " on line %d failed.\n", __LINE__); \ + return false; \ + } + +static char *test_str_arr[] = {"1", "2", ""}; +static SubMessage test_msg_arr[] = {SubMessage_init_zero, SubMessage_init_zero}; +static pb_extension_t ext1, ext2; + +static void fill_TestMessage(TestMessage *msg) +{ + msg->static_req_submsg.dynamic_str = "12345"; + msg->static_req_submsg.dynamic_str_arr_count = 3; + msg->static_req_submsg.dynamic_str_arr = test_str_arr; + msg->static_req_submsg.dynamic_submsg_count = 2; + msg->static_req_submsg.dynamic_submsg = test_msg_arr; + msg->static_req_submsg.dynamic_submsg[1].dynamic_str = "abc"; + msg->static_opt_submsg.dynamic_str = "abc"; + msg->static_rep_submsg_count = 2; + msg->static_rep_submsg[1].dynamic_str = "abc"; + msg->has_static_opt_submsg = true; + msg->dynamic_submsg = &msg->static_req_submsg; + + msg->extensions = &ext1; + ext1.type = &dynamic_ext; + ext1.dest = &msg->static_req_submsg; + ext1.next = &ext2; + ext2.type = &static_ext; + ext2.dest = &msg->static_req_submsg; + ext2.next = NULL; +} + +/* Basic fields, nested submessages, extensions */ +static bool test_TestMessage() +{ + uint8_t buffer[256]; + size_t msgsize; + + /* Construct a message with various fields filled in */ + { + TestMessage msg = TestMessage_init_zero; + pb_ostream_t stream; + + fill_TestMessage(&msg); + + stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + if (!pb_encode(&stream, TestMessage_fields, &msg)) + { + fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&stream)); + return false; + } + msgsize = stream.bytes_written; + } + + /* Output encoded message for debug */ + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, msgsize, stdout); + + /* Decode memory using dynamic allocation */ + { + TestMessage msg = TestMessage_init_zero; + pb_istream_t stream; + SubMessage ext2_dest; + + msg.extensions = &ext1; + ext1.type = &dynamic_ext; + ext1.dest = NULL; + ext1.next = &ext2; + ext2.type = &static_ext; + ext2.dest = &ext2_dest; + ext2.next = NULL; + + stream = pb_istream_from_buffer(buffer, msgsize); + if (!pb_decode(&stream, TestMessage_fields, &msg)) + { + fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&stream)); + return false; + } + + /* Make sure it encodes back to same data */ + { + uint8_t buffer2[256]; + pb_ostream_t ostream = pb_ostream_from_buffer(buffer2, sizeof(buffer2)); + TEST(pb_encode(&ostream, TestMessage_fields, &msg)); + TEST(ostream.bytes_written == msgsize); + TEST(memcmp(buffer, buffer2, msgsize) == 0); + } + + /* Make sure that malloc counters work */ + TEST(get_alloc_count() > 0); + + /* Make sure that pb_release releases everything */ + pb_release(TestMessage_fields, &msg); + TEST(get_alloc_count() == 0); + + /* Check that double-free is a no-op */ + pb_release(TestMessage_fields, &msg); + TEST(get_alloc_count() == 0); + } + + return true; +} + +/* Oneofs */ +static bool test_OneofMessage() +{ + uint8_t buffer[256]; + size_t msgsize; + + { + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Encode first with TestMessage */ + { + OneofMessage msg = OneofMessage_init_zero; + msg.which_msgs = OneofMessage_msg1_tag; + + fill_TestMessage(&msg.msgs.msg1); + + if (!pb_encode(&stream, OneofMessage_fields, &msg)) + { + fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&stream)); + return false; + } + } + + /* Encode second with SubMessage, invoking 'merge' behaviour */ + { + OneofMessage msg = OneofMessage_init_zero; + msg.which_msgs = OneofMessage_msg2_tag; + + msg.first = 999; + msg.msgs.msg2.dynamic_str = "ABCD"; + msg.last = 888; + + if (!pb_encode(&stream, OneofMessage_fields, &msg)) + { + fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&stream)); + return false; + } + } + msgsize = stream.bytes_written; + } + + { + OneofMessage msg = OneofMessage_init_zero; + pb_istream_t stream = pb_istream_from_buffer(buffer, msgsize); + if (!pb_decode(&stream, OneofMessage_fields, &msg)) + { + fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&stream)); + return false; + } + + TEST(msg.first == 999); + TEST(msg.which_msgs == OneofMessage_msg2_tag); + TEST(msg.msgs.msg2.dynamic_str); + TEST(strcmp(msg.msgs.msg2.dynamic_str, "ABCD") == 0); + TEST(msg.msgs.msg2.dynamic_str_arr == NULL); + TEST(msg.msgs.msg2.dynamic_submsg == NULL); + TEST(msg.last == 888); + + pb_release(OneofMessage_fields, &msg); + TEST(get_alloc_count() == 0); + pb_release(OneofMessage_fields, &msg); + TEST(get_alloc_count() == 0); + } + + return true; +} + +int main() +{ + if (test_TestMessage() && test_OneofMessage()) + return 0; + else + return 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.proto b/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.proto new file mode 100644 index 00000000..0816dc22 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/mem_release/mem_release.proto @@ -0,0 +1,35 @@ +syntax = "proto2"; +import "nanopb.proto"; + +message SubMessage +{ + optional string dynamic_str = 1 [(nanopb).type = FT_POINTER]; + repeated string dynamic_str_arr = 2 [(nanopb).type = FT_POINTER]; + repeated SubMessage dynamic_submsg = 3 [(nanopb).type = FT_POINTER]; +} + +message TestMessage +{ + required SubMessage static_req_submsg = 1 [(nanopb).type = FT_STATIC]; + optional SubMessage dynamic_submsg = 2 [(nanopb).type = FT_POINTER]; + optional SubMessage static_opt_submsg = 3 [(nanopb).type = FT_STATIC]; + repeated SubMessage static_rep_submsg = 4 [(nanopb).type = FT_STATIC, (nanopb).max_count=2]; + extensions 100 to 200; +} + +extend TestMessage +{ + optional SubMessage dynamic_ext = 100 [(nanopb).type = FT_POINTER]; + optional SubMessage static_ext = 101 [(nanopb).type = FT_STATIC]; +} + +message OneofMessage +{ + required int32 first = 1; + oneof msgs + { + TestMessage msg1 = 2; + SubMessage msg2 = 3; + } + required int32 last = 4; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/SConscript new file mode 100644 index 00000000..e7524e02 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/SConscript @@ -0,0 +1,11 @@ +# Test the generation of message size #defines + +Import('env') + +incpath = env.Clone() +incpath.Append(PROTOCPATH = '#message_sizes') + +incpath.NanopbProto("messages1") +incpath.NanopbProto("messages2") + +incpath.Program(['dummy.c', 'messages1.pb.c', 'messages2.pb.c']) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/dummy.c b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/dummy.c new file mode 100644 index 00000000..767ad463 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/dummy.c @@ -0,0 +1,9 @@ +/* Just test that the file can be compiled successfully. */ + +#include "messages2.pb.h" + +int main() +{ + return xmit_size; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages1.proto b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages1.proto new file mode 100644 index 00000000..b66fad71 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages1.proto @@ -0,0 +1,29 @@ +syntax = "proto2"; + +enum MessageStatus { + FAIL = 0; + OK = 1; +}; + +message MessageInfo { + required fixed32 msg_id = 1; + optional fixed32 interface_id = 2; +} + +message MessageResponseInfo { + required fixed64 interface_id = 1; + required fixed32 seq = 2; + required fixed32 msg_id = 3; +} + +message MessageHeader { + required MessageInfo info = 1; + optional MessageResponseInfo response_info = 2; + optional MessageResponse response = 3; +} + +message MessageResponse { + required MessageStatus status = 1; + required fixed32 seq = 2; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages2.proto b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages2.proto new file mode 100644 index 00000000..67614080 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/message_sizes/messages2.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +import 'nanopb.proto'; +import 'messages1.proto'; + +message xmit { + required MessageHeader header = 1; + required bytes data = 2 [(nanopb).max_size = 128]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/SConscript new file mode 100644 index 00000000..86ba0833 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/SConscript @@ -0,0 +1,8 @@ +# Check that the decoder properly detects when required fields are missing. + +Import("env") + +env.NanopbProto("missing_fields") +test = env.Program(["missing_fields.c", "missing_fields.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"]) +env.RunTest(test) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.c b/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.c new file mode 100644 index 00000000..8aded827 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.c @@ -0,0 +1,53 @@ +/* Checks that missing required fields are detected properly */ + +#include +#include +#include +#include "missing_fields.pb.h" + +int main() +{ + uint8_t buffer[512]; + size_t size; + + /* Create a message with one missing field */ + { + MissingField msg = {0}; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + if (!pb_encode(&stream, MissingField_fields, &msg)) + { + printf("Encode failed.\n"); + return 1; + } + + size = stream.bytes_written; + } + + /* Test that it decodes properly if we don't require that field */ + { + MissingField msg = {0}; + pb_istream_t stream = pb_istream_from_buffer(buffer, size); + + if (!pb_decode(&stream, MissingField_fields, &msg)) + { + printf("Decode failed: %s\n", PB_GET_ERROR(&stream)); + return 2; + } + } + + /* Test that it does *not* decode properly if we require the field */ + { + AllFields msg = {0}; + pb_istream_t stream = pb_istream_from_buffer(buffer, size); + + if (pb_decode(&stream, AllFields_fields, &msg)) + { + printf("Decode didn't detect missing field.\n"); + return 3; + } + } + + return 0; /* All ok */ +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.proto b/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.proto new file mode 100644 index 00000000..cc5e550b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/missing_fields/missing_fields.proto @@ -0,0 +1,140 @@ +/* Test for one missing field among many */ + +syntax = "proto2"; + +message AllFields +{ + required int32 field1 = 1; + required int32 field2 = 2; + required int32 field3 = 3; + required int32 field4 = 4; + required int32 field5 = 5; + required int32 field6 = 6; + required int32 field7 = 7; + required int32 field8 = 8; + required int32 field9 = 9; + required int32 field10 = 10; + required int32 field11 = 11; + required int32 field12 = 12; + required int32 field13 = 13; + required int32 field14 = 14; + required int32 field15 = 15; + required int32 field16 = 16; + required int32 field17 = 17; + required int32 field18 = 18; + required int32 field19 = 19; + required int32 field20 = 20; + required int32 field21 = 21; + required int32 field22 = 22; + required int32 field23 = 23; + required int32 field24 = 24; + required int32 field25 = 25; + required int32 field26 = 26; + required int32 field27 = 27; + required int32 field28 = 28; + required int32 field29 = 29; + required int32 field30 = 30; + required int32 field31 = 31; + required int32 field32 = 32; + required int32 field33 = 33; + required int32 field34 = 34; + required int32 field35 = 35; + required int32 field36 = 36; + required int32 field37 = 37; + required int32 field38 = 38; + required int32 field39 = 39; + required int32 field40 = 40; + required int32 field41 = 41; + required int32 field42 = 42; + required int32 field43 = 43; + required int32 field44 = 44; + required int32 field45 = 45; + required int32 field46 = 46; + required int32 field47 = 47; + required int32 field48 = 48; + required int32 field49 = 49; + required int32 field50 = 50; + required int32 field51 = 51; + required int32 field52 = 52; + required int32 field53 = 53; + required int32 field54 = 54; + required int32 field55 = 55; + required int32 field56 = 56; + required int32 field57 = 57; + required int32 field58 = 58; + required int32 field59 = 59; + required int32 field60 = 60; + required int32 field61 = 61; + required int32 field62 = 62; + required int32 field63 = 63; + required int32 field64 = 64; +} + +message MissingField +{ + required int32 field1 = 1; + required int32 field2 = 2; + required int32 field3 = 3; + required int32 field4 = 4; + required int32 field5 = 5; + required int32 field6 = 6; + required int32 field7 = 7; + required int32 field8 = 8; + required int32 field9 = 9; + required int32 field10 = 10; + required int32 field11 = 11; + required int32 field12 = 12; + required int32 field13 = 13; + required int32 field14 = 14; + required int32 field15 = 15; + required int32 field16 = 16; + required int32 field17 = 17; + required int32 field18 = 18; + required int32 field19 = 19; + required int32 field20 = 20; + required int32 field21 = 21; + required int32 field22 = 22; + required int32 field23 = 23; + required int32 field24 = 24; + required int32 field25 = 25; + required int32 field26 = 26; + required int32 field27 = 27; + required int32 field28 = 28; + required int32 field29 = 29; + required int32 field30 = 30; + required int32 field31 = 31; + required int32 field32 = 32; + required int32 field33 = 33; + required int32 field34 = 34; + required int32 field35 = 35; + required int32 field36 = 36; + required int32 field37 = 37; + required int32 field38 = 38; + required int32 field39 = 39; + required int32 field40 = 40; + required int32 field41 = 41; + required int32 field42 = 42; + required int32 field43 = 43; + required int32 field44 = 44; + required int32 field45 = 45; + required int32 field46 = 46; + required int32 field47 = 47; + required int32 field48 = 48; + required int32 field49 = 49; + required int32 field50 = 50; + required int32 field51 = 51; + required int32 field52 = 52; + required int32 field53 = 53; + required int32 field54 = 54; + required int32 field55 = 55; + required int32 field56 = 56; + required int32 field57 = 57; + required int32 field58 = 58; + required int32 field59 = 59; + required int32 field60 = 60; + required int32 field61 = 61; + required int32 field62 = 62; +/* required int32 field63 = 63; */ + required int32 field64 = 64; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/SConscript new file mode 100644 index 00000000..b1281e17 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/SConscript @@ -0,0 +1,16 @@ +# Test that multiple .proto files don't cause name collisions. + +Import("env") + +incpath = env.Clone() +incpath.Append(PROTOCPATH = '#multiple_files') +incpath.Append(CPPPATH = '$BUILD/multiple_files') + +incpath.NanopbProto(["multifile1", "multifile1.options"]) +incpath.NanopbProto("multifile2") +incpath.NanopbProto("subdir/multifile2") +test = incpath.Program(["test_multiple_files.c", "multifile1.pb.c", + "multifile2.pb.c", "subdir/multifile2.pb.c"]) + +env.RunTest(test) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.options b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.options new file mode 100644 index 00000000..c44d2669 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.options @@ -0,0 +1 @@ +StaticMessage.repint32 max_count:5 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.proto b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.proto new file mode 100644 index 00000000..18f2c672 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile1.proto @@ -0,0 +1,34 @@ +syntax = "proto2"; + +message SubMessage { + optional string stringvalue = 1; + repeated int32 int32value = 2; + repeated fixed32 fixed32value = 3; + repeated fixed64 fixed64value = 4; +} + +message TestMessage { + optional string stringvalue = 1; + repeated int32 int32value = 2; + repeated fixed32 fixed32value = 3; + repeated fixed64 fixed64value = 4; + optional SubMessage submsg = 5; + repeated string repeatedstring = 6; +} + +message StaticMessage { + repeated fixed32 repint32 = 1; +} + +enum SignedEnum { + SE_MIN = -128; + SE_MAX = 127; +} + +enum UnsignedEnum { + UE_MIN = 0; + UE_MAX = 255; +} + + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile2.proto b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile2.proto new file mode 100644 index 00000000..4af45fd9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/multifile2.proto @@ -0,0 +1,22 @@ +// Test if including generated header file for this file + implicit include of +// multifile2.pb.h still compiles. Used with test_compiles.c. +syntax = "proto2"; + +import "multifile1.proto"; + +message Callback2Message { + required TestMessage tstmsg = 1; + required SubMessage submsg = 2; +} + +message OneofMessage { + oneof msgs { + StaticMessage tstmsg = 1; + } +} + +message Enums { + required SignedEnum senum = 1; + required UnsignedEnum uenum = 2; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/subdir/multifile2.proto b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/subdir/multifile2.proto new file mode 100644 index 00000000..847a9290 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/subdir/multifile2.proto @@ -0,0 +1,25 @@ +syntax = "proto2"; + +package subdir; + +import "multifile1.proto"; + +message Callback2Message { + required TestMessage tstmsg = 1; + required SubMessage submsg = 2; +} + +message OneofMessage { + oneof msgs { + StaticMessage tstmsg = 1; + } +} + +message Enums { + required SignedEnum senum = 1; + required UnsignedEnum uenum = 2; +} + +message SubdirMessage { + required int32 foo = 1 [default = 15]; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/test_multiple_files.c b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/test_multiple_files.c new file mode 100644 index 00000000..70a3e596 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/multiple_files/test_multiple_files.c @@ -0,0 +1,30 @@ +/* + * Tests if this still compiles when multiple .proto files are involved. + */ + +#include +#include +#include "unittests.h" +#include "multifile2.pb.h" +#include "subdir/multifile2.pb.h" + +int main() +{ + int status = 0; + + /* Test that included file options are properly loaded */ + TEST(OneofMessage_size == 27); + + /* Check that enum signedness is detected properly */ + TEST(PB_LTYPE(Enums_fields[0].type) == PB_LTYPE_VARINT); + TEST(PB_LTYPE(Enums_fields[1].type) == PB_LTYPE_UVARINT); + + /* Test that subdir file is correctly included */ + { + subdir_SubdirMessage foo = subdir_SubdirMessage_init_default; + TEST(foo.foo == 15); + /* TEST(subdir_OneofMessage_size == 27); */ /* TODO: Issue #172 */ + } + + return status; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/no_errmsg/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/no_errmsg/SConscript new file mode 100644 index 00000000..629bfa68 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/no_errmsg/SConscript @@ -0,0 +1,28 @@ +# Run the alltypes test case, but compile with PB_NO_ERRMSG=1 + +Import("env") + +# Take copy of the files for custom build. +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.pb.h", "$BUILD/alltypes/alltypes.pb.h", c) +env.Command("alltypes.pb.c", "$BUILD/alltypes/alltypes.pb.c", c) +env.Command("encode_alltypes.c", "$BUILD/alltypes/encode_alltypes.c", c) +env.Command("decode_alltypes.c", "$BUILD/alltypes/decode_alltypes.c", c) + +# Define the compilation options +opts = env.Clone() +opts.Append(CPPDEFINES = {'PB_NO_ERRMSG': 1}) + +# Build new version of core +strict = opts.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_decode_noerr.o", "$NANOPB/pb_decode.c") +strict.Object("pb_encode_noerr.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common_noerr.o", "$NANOPB/pb_common.c") + +# Now build and run the test normally. +enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_noerr.o", "pb_common_noerr.o"]) +dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_noerr.o", "pb_common_noerr.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/no_messages/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/no_messages/SConscript new file mode 100644 index 00000000..6492e2cf --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/no_messages/SConscript @@ -0,0 +1,7 @@ +# Test that a .proto file without any messages compiles fine. + +Import("env") + +env.NanopbProto("no_messages") +env.Object('no_messages.pb.c') + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/no_messages/no_messages.proto b/hardware-wallet/firmware/vendor/nanopb/tests/no_messages/no_messages.proto new file mode 100644 index 00000000..45bb2e66 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/no_messages/no_messages.proto @@ -0,0 +1,9 @@ +/* Test that a file without any messages works. */ + +syntax = "proto2"; + +enum Test { + First = 1; +} + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/oneof/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/SConscript new file mode 100644 index 00000000..22634fb0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/SConscript @@ -0,0 +1,33 @@ +# Test the 'oneof' feature for generating C unions. + +Import('env') + +import re + +match = None +if 'PROTOC_VERSION' in env: + match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION']) + +if match: + version = map(int, match.groups()) + +# Oneof is supported by protoc >= 2.6.0 +if env.GetOption('clean') or (match and (version[0] > 2 or (version[0] == 2 and version[1] >= 6))): + env.NanopbProto('oneof') + + enc = env.Program(['encode_oneof.c', + 'oneof.pb.c', + '$COMMON/pb_encode.o', + '$COMMON/pb_common.o']) + + dec = env.Program(['decode_oneof.c', + 'oneof.pb.c', + '$COMMON/pb_decode.o', + '$COMMON/pb_common.o']) + + env.RunTest("message1.pb", enc, ARGS = ['1']) + env.RunTest("message1.txt", [dec, 'message1.pb'], ARGS = ['1']) + env.RunTest("message2.pb", enc, ARGS = ['2']) + env.RunTest("message2.txt", [dec, 'message2.pb'], ARGS = ['2']) + env.RunTest("message3.pb", enc, ARGS = ['3']) + env.RunTest("message3.txt", [dec, 'message3.pb'], ARGS = ['3']) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/oneof/decode_oneof.c b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/decode_oneof.c new file mode 100644 index 00000000..37075cd6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/decode_oneof.c @@ -0,0 +1,131 @@ +/* Decode a message using oneof fields */ + +#include +#include +#include +#include +#include "oneof.pb.h" +#include "test_helpers.h" +#include "unittests.h" + +/* Test the 'OneOfMessage' */ +int test_oneof_1(pb_istream_t *stream, int option) +{ + OneOfMessage msg; + int status = 0; + + /* To better catch initialization errors */ + memset(&msg, 0xAA, sizeof(msg)); + + if (!pb_decode(stream, OneOfMessage_fields, &msg)) + { + printf("Decoding failed: %s\n", PB_GET_ERROR(stream)); + return 1; + } + + /* Check that the basic fields work normally */ + TEST(msg.prefix == 123); + TEST(msg.suffix == 321); + + /* Check that we got the right oneof according to command line */ + if (option == 1) + { + TEST(msg.which_values == OneOfMessage_first_tag); + TEST(msg.values.first == 999); + } + else if (option == 2) + { + TEST(msg.which_values == OneOfMessage_second_tag); + TEST(strcmp(msg.values.second, "abcd") == 0); + } + else if (option == 3) + { + TEST(msg.which_values == OneOfMessage_third_tag); + TEST(msg.values.third.array[0] == 1); + TEST(msg.values.third.array[1] == 2); + TEST(msg.values.third.array[2] == 3); + TEST(msg.values.third.array[3] == 4); + TEST(msg.values.third.array[4] == 5); + } + + return status; +} + + +/* Test the 'PlainOneOfMessage' */ +int test_oneof_2(pb_istream_t *stream, int option) +{ + PlainOneOfMessage msg = PlainOneOfMessage_init_zero; + int status = 0; + + if (!pb_decode(stream, PlainOneOfMessage_fields, &msg)) + { + printf("Decoding failed: %s\n", PB_GET_ERROR(stream)); + return 1; + } + + /* Check that we got the right oneof according to command line */ + if (option == 1) + { + TEST(msg.which_values == OneOfMessage_first_tag); + TEST(msg.values.first == 999); + } + else if (option == 2) + { + TEST(msg.which_values == OneOfMessage_second_tag); + TEST(strcmp(msg.values.second, "abcd") == 0); + } + else if (option == 3) + { + TEST(msg.which_values == OneOfMessage_third_tag); + TEST(msg.values.third.array[0] == 1); + TEST(msg.values.third.array[1] == 2); + TEST(msg.values.third.array[2] == 3); + TEST(msg.values.third.array[3] == 4); + TEST(msg.values.third.array[4] == 5); + } + + return status; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[OneOfMessage_size]; + size_t count; + int option; + + if (argc != 2) + { + fprintf(stderr, "Usage: decode_oneof [number]\n"); + return 1; + } + option = atoi(argv[1]); + + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + if (!feof(stdin)) + { + printf("Message does not fit in buffer\n"); + return 1; + } + + { + int status = 0; + pb_istream_t stream; + + stream = pb_istream_from_buffer(buffer, count); + status = test_oneof_1(&stream, option); + + if (status != 0) + return status; + + stream = pb_istream_from_buffer(buffer, count); + status = test_oneof_2(&stream, option); + + if (status != 0) + return status; + } + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/oneof/encode_oneof.c b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/encode_oneof.c new file mode 100644 index 00000000..913d2d43 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/encode_oneof.c @@ -0,0 +1,64 @@ +/* Encode a message using oneof fields */ + +#include +#include +#include +#include "oneof.pb.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + uint8_t buffer[OneOfMessage_size]; + OneOfMessage msg = OneOfMessage_init_zero; + pb_ostream_t stream; + int option; + + if (argc != 2) + { + fprintf(stderr, "Usage: encode_oneof [number]\n"); + return 1; + } + option = atoi(argv[1]); + + /* Prefix and suffix are used to test that the union does not disturb + * other fields in the same message. */ + msg.prefix = 123; + + /* We encode one of the 'values' fields based on command line argument */ + if (option == 1) + { + msg.which_values = OneOfMessage_first_tag; + msg.values.first = 999; + } + else if (option == 2) + { + msg.which_values = OneOfMessage_second_tag; + strcpy(msg.values.second, "abcd"); + } + else if (option == 3) + { + msg.which_values = OneOfMessage_third_tag; + msg.values.third.array_count = 5; + msg.values.third.array[0] = 1; + msg.values.third.array[1] = 2; + msg.values.third.array[2] = 3; + msg.values.third.array[3] = 4; + msg.values.third.array[4] = 5; + } + + msg.suffix = 321; + + stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + if (pb_encode(&stream, OneOfMessage_fields, &msg)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/oneof/oneof.proto b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/oneof.proto new file mode 100644 index 00000000..b4fe56f2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/oneof/oneof.proto @@ -0,0 +1,32 @@ +syntax = "proto2"; + +import 'nanopb.proto'; + +message SubMessage +{ + repeated int32 array = 1 [(nanopb).max_count = 8]; +} + +/* Oneof in a message with other fields */ +message OneOfMessage +{ + required int32 prefix = 1; + oneof values + { + int32 first = 5; + string second = 6 [(nanopb).max_size = 8]; + SubMessage third = 7; + } + required int32 suffix = 99; +} + +/* Oneof in a message by itself */ +message PlainOneOfMessage +{ + oneof values + { + int32 first = 5; + string second = 6 [(nanopb).max_size = 8]; + SubMessage third = 7; + } +} \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/options/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/options/SConscript new file mode 100644 index 00000000..215e3bd0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/options/SConscript @@ -0,0 +1,12 @@ +# Test that the generator options work as expected. + +Import("env") + +env.NanopbProto("options") +env.Object('options.pb.c') +env.Match(['options.pb.h', 'options.expected']) + +env.NanopbProto("proto3_options") +env.Object('proto3_options.pb.c') +env.Match(['proto3_options.pb.h', 'proto3_options.expected']) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/options/options.expected b/hardware-wallet/firmware/vendor/nanopb/tests/options/options.expected new file mode 100644 index 00000000..9e47e6a4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/options/options.expected @@ -0,0 +1,20 @@ +char filesize\[20\]; +char msgsize\[30\]; +char fieldsize\[40\]; +char fieldlen\[41\]; +pb_callback_t int32_callback; +\sEnumValue1 = 1 +Message5_EnumValue1 +} pb_packed my_packed_struct; +! skipped_field +! SkippedMessage +#define PB_MSG_103 Message3 +#define PB_MSG_104 Message4 +#define PB_MSG_105 Message5 +#define OPTIONS_MESSAGES \\ +\s+PB_MSG\(103,[0-9]*,Message3\) \\ +\s+PB_MSG\(104,-1,Message4\) \\ +\s+PB_MSG\(105,[0-9]*,Message5\) \\ +#define Message5_msgid 105 +! has_proto3field + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/options/options.proto b/hardware-wallet/firmware/vendor/nanopb/tests/options/options.proto new file mode 100644 index 00000000..c6ca5e25 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/options/options.proto @@ -0,0 +1,98 @@ +/* Test nanopb option parsing. + * options.expected lists the patterns that are searched for in the output. + */ + +syntax = "proto2"; + +import "nanopb.proto"; + +// File level options +option (nanopb_fileopt).max_size = 20; + +message Message1 +{ + required string filesize = 1; +} + +// Message level options +message Message2 +{ + option (nanopb_msgopt).max_size = 30; + required string msgsize = 1; +} + +// Field level options +message Message3 +{ + option (nanopb_msgopt).msgid = 103; + required string fieldsize = 1 [(nanopb).max_size = 40]; + required string fieldlen = 2 [(nanopb).max_length = 40]; +} + +// Forced callback field +message Message4 +{ + option (nanopb_msgopt).msgid = 104; + required int32 int32_callback = 1 [(nanopb).type = FT_CALLBACK]; +} + +// Short enum names +enum Enum1 +{ + option (nanopb_enumopt).long_names = false; + EnumValue1 = 1; + EnumValue2 = 2; +} + +message EnumTest +{ + required Enum1 field = 1 [default = EnumValue2]; +} + +// Short enum names inside message +message Message5 +{ + option (nanopb_msgopt).msgid = 105; + enum Enum2 + { + option (nanopb_enumopt).long_names = false; + EnumValue1 = 1; + } + required Enum2 field = 1 [default = EnumValue1]; +} + +// Packed structure +message my_packed_struct +{ + option (nanopb_msgopt).packed_struct = true; + optional int32 myfield = 1; +} + +// Message with ignored field +message Message6 +{ + required int32 field1 = 1; + optional int32 skipped_field = 2 [(nanopb).type = FT_IGNORE]; +} + +// Message that is skipped +message SkippedMessage +{ + option (nanopb_msgopt).skip_message = true; + required int32 foo = 1; +} + +// Message with oneof field +message OneofMessage +{ + oneof foo { + int32 bar = 1; + } +} + +// Proto3-style optional field in proto2 file +message Proto3Field +{ + optional int32 proto3field = 1 [(nanopb).proto3 = true]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.expected b/hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.expected new file mode 100644 index 00000000..cc2f29c0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.expected @@ -0,0 +1,4 @@ +! bool has_proto3_default +bool has_proto3_off +! bool has_proto3_on + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.proto b/hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.proto new file mode 100644 index 00000000..1017f046 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/options/proto3_options.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "nanopb.proto"; + +message Message1 +{ + int32 proto3_default = 1; + int32 proto3_off = 2 [(nanopb).proto3 = false]; + int32 proto3_on = 3 [(nanopb).proto3 = true]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/package_name/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/package_name/SConscript new file mode 100644 index 00000000..4afc5037 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/package_name/SConscript @@ -0,0 +1,38 @@ +# Check that alltypes test case works also when the .proto file defines +# a package name. + +Import("env") + +def set_pkgname(src, dst, pkgname): + data = open(str(src)).read() + placeholder = '// package name placeholder' + assert placeholder in data + data = data.replace(placeholder, 'package %s;' % pkgname) + open(str(dst), 'w').write(data) + +# Build a modified alltypes.proto +env.Command("alltypes.proto", "#alltypes/alltypes.proto", + lambda target, source, env: set_pkgname(source[0], target[0], 'test.package')) +env.Command("alltypes.options", "#alltypes/alltypes.options", Copy("$TARGET", "$SOURCE")) +env.NanopbProto(["alltypes", "alltypes.options"]) + +# Build a modified encode_alltypes.c +def modify_c(target, source, env): + '''Add package name to type names in .c file.''' + + data = open(str(source[0]), 'r').read() + + type_names = ['AllTypes', 'MyEnum', 'HugeEnum'] + for name in type_names: + data = data.replace(name, 'test_package_' + name) + + open(str(target[0]), 'w').write(data) + return 0 +env.Command("encode_alltypes.c", "#alltypes/encode_alltypes.c", modify_c) + +# Encode and compare results to original alltypes testcase +enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"]) +refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX" +env.RunTest(enc) +env.Compare(["encode_alltypes.output", "$BUILD/alltypes/encode_alltypes.output"]) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/SConscript new file mode 100644 index 00000000..833d9dec --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/SConscript @@ -0,0 +1,12 @@ +# Regression test for Issue 118: Short enum names in imported proto files are not honoured + +Import("env") +env = env.Clone() +env.Append(PROTOCPATH = "#regression/issue_118") + +env.NanopbProto("enumdef") +env.Object('enumdef.pb.c') + +env.NanopbProto(["enumuse", "enumdef.proto"]) +env.Object('enumuse.pb.c') + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumdef.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumdef.proto new file mode 100644 index 00000000..46845bc9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumdef.proto @@ -0,0 +1,8 @@ +syntax = "proto2"; + +import 'nanopb.proto'; + +enum MyEnum { + option (nanopb_enumopt).long_names = false; + FOOBAR = 1; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumuse.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumuse.proto new file mode 100644 index 00000000..4afc4521 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_118/enumuse.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; + +import 'enumdef.proto'; + +message MyMessage { + required MyEnum myenum = 1 [default = FOOBAR]; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/SConscript new file mode 100644 index 00000000..f2155e63 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/SConscript @@ -0,0 +1,9 @@ +# Regression test for Issue 125: Wrong identifier name for extension fields + +Import("env") + +env.NanopbProto(["extensionbug", "extensionbug.options"]) +env.Object('extensionbug.pb.c') + +env.Match(['extensionbug.pb.h', 'extensionbug.expected']) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.expected b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.expected new file mode 100644 index 00000000..fc213354 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.expected @@ -0,0 +1,3 @@ +pb_extension_type_t Message2_extras +uint32_t field2 + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.options b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.options new file mode 100644 index 00000000..30b464a4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.options @@ -0,0 +1,4 @@ +* type:FT_IGNORE + +Message2.extras type:FT_STATIC +Message2.field2 type:FT_STATIC diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.proto new file mode 100644 index 00000000..fd1e74f1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_125/extensionbug.proto @@ -0,0 +1,18 @@ +syntax = "proto2"; + +message Message1 +{ + optional uint32 fieldA = 1; + extensions 30 to max; +} + +message Message2 +{ + extend Message1 + { + optional Message2 extras = 30; + } + + optional uint32 field1 = 1; + optional uint32 field2 = 2; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/SConscript new file mode 100644 index 00000000..b6526bed --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/SConscript @@ -0,0 +1,8 @@ +# Regression test for issue 141: wrong encoded size #define for oneof messages + +Import("env") + +env.NanopbProto("testproto") +env.Object('testproto.pb.c') +env.Match(['testproto.pb.h', 'testproto.expected']) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.expected b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.expected new file mode 100644 index 00000000..75bc195c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.expected @@ -0,0 +1,7 @@ +define SubMessage_size \s* 88 +define OneOfMessage_size \s* 113 +define topMessage_size \s* 70 +define MyMessage1_size \s* 46 +define MyMessage2_size \s* 8 +define MyMessage3_size \s* 5 +define MyMessage4_size \s* 18 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.proto new file mode 100644 index 00000000..a445c68a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_141/testproto.proto @@ -0,0 +1,52 @@ +syntax = "proto2"; + +import 'nanopb.proto'; + +message SubMessage +{ + repeated int32 array = 1 [(nanopb).max_count = 8]; +} + +message OneOfMessage +{ + required int32 prefix = 1; + oneof values + { + int32 first = 5; + string second = 6 [(nanopb).max_size = 8]; + SubMessage third = 7; + } + required int32 suffix = 99; +} + +message topMessage { + required int32 start = 1; + oneof msg { + MyMessage1 msg1 = 2; + MyMessage2 msg2 = 3; + } + required int32 end = 4; +} + +message MyMessage1 { + required uint32 n1 = 1; + required uint32 n2 = 2; + required string s = 3 [(nanopb).max_size = 32]; +} + +message MyMessage2 { + required uint32 num = 1; + required bool b = 2; +} + +message MyMessage3 { + required bool bbb = 1; + required string ss = 2 [(nanopb).max_size = 1]; +} + +message MyMessage4 { + required bool bbbb = 1; + required string sss = 2 [(nanopb).max_size = 2]; + required uint32 num = 3; + required uint32 num2 = 4; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/SConscript new file mode 100644 index 00000000..0b793a7a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/SConscript @@ -0,0 +1,9 @@ +# Regression test for Issue 145: Allow /* */ and // comments in .options files + +Import("env") + +env.NanopbProto(["comments", "comments.options"]) +env.Object('comments.pb.c') + +env.Match(['comments.pb.h', 'comments.expected']) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.expected b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.expected new file mode 100644 index 00000000..7f874587 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.expected @@ -0,0 +1,3 @@ +char foo\[5\]; +char bar\[16\]; + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.options b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.options new file mode 100644 index 00000000..89959ba2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.options @@ -0,0 +1,6 @@ +/* Block comment */ +# Line comment +// Line comment +DummyMessage.foo /* Block comment */ max_size:5 +DummyMessage.bar max_size:16 # Line comment ### + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.proto new file mode 100644 index 00000000..621779f5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_145/comments.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; + +message DummyMessage { + required string foo = 1; + required string bar = 2; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/SConscript new file mode 100644 index 00000000..c50b9193 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/SConscript @@ -0,0 +1,13 @@ +# Verify that the maximum encoded size is calculated properly +# for enums. + +Import('env') + +env.NanopbProto('enums') + +p = env.Program(["enum_encoded_size.c", + "enums.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enum_encoded_size.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enum_encoded_size.c new file mode 100644 index 00000000..84e1c7de --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enum_encoded_size.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include "unittests.h" +#include "enums.pb.h" + +int main() +{ + int status = 0; + + uint8_t buf[256]; + SignedMsg msg1; + UnsignedMsg msg2; + pb_ostream_t s; + + { + COMMENT("Test negative value of signed enum"); + /* Negative value should take up the maximum size */ + msg1.value = SignedEnum_SE_MIN; + s = pb_ostream_from_buffer(buf, sizeof(buf)); + TEST(pb_encode(&s, SignedMsg_fields, &msg1)); + TEST(s.bytes_written == SignedMsg_size); + + COMMENT("Test positive value of signed enum"); + /* Positive value should be smaller */ + msg1.value = SignedEnum_SE_MAX; + s = pb_ostream_from_buffer(buf, sizeof(buf)); + TEST(pb_encode(&s, SignedMsg_fields, &msg1)); + TEST(s.bytes_written < SignedMsg_size); + } + + { + COMMENT("Test positive value of unsigned enum"); + /* This should take up the maximum size */ + msg2.value = UnsignedEnum_UE_MAX; + s = pb_ostream_from_buffer(buf, sizeof(buf)); + TEST(pb_encode(&s, UnsignedMsg_fields, &msg2)); + TEST(s.bytes_written == UnsignedMsg_size); + } + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enums.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enums.proto new file mode 100644 index 00000000..36948044 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_166/enums.proto @@ -0,0 +1,18 @@ +syntax = "proto2"; + +enum SignedEnum { + SE_MIN = -1; + SE_MAX = 255; +} + +enum UnsignedEnum { + UE_MAX = 65536; +} + +message SignedMsg { + required SignedEnum value = 1; +} + +message UnsignedMsg { + required UnsignedEnum value = 1; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/SConscript new file mode 100644 index 00000000..49c919e8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/SConscript @@ -0,0 +1,16 @@ +# Verify that _size define is generated for messages that have +# includes from another directory. + +Import('env') + +incpath = env.Clone() +incpath.Append(PROTOCPATH="#regression/issue_172/submessage") +incpath.Append(CPPPATH="$BUILD/regression/issue_172/submessage") +incpath.NanopbProto('test') +incpath.NanopbProto(['submessage/submessage', 'submessage/submessage.options']) + +p = incpath.Program(["msg_size.c", + "test.pb.c", + "submessage/submessage.pb.c"]) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/msg_size.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/msg_size.c new file mode 100644 index 00000000..be45acb4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/msg_size.c @@ -0,0 +1,9 @@ +#include "test.pb.h" + +PB_STATIC_ASSERT(testmessage_size >= 1+1+1+1+16, TESTMESSAGE_SIZE_IS_WRONG) + +int main() +{ + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.options b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.options new file mode 100644 index 00000000..12fb1984 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.options @@ -0,0 +1 @@ +submessage.data max_size: 16 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.proto new file mode 100644 index 00000000..ce6804af --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/submessage/submessage.proto @@ -0,0 +1,4 @@ +syntax = "proto2"; +message submessage { + required bytes data = 1; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/test.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/test.proto new file mode 100644 index 00000000..fbd97be5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_172/test.proto @@ -0,0 +1,6 @@ +syntax = "proto2"; +import "submessage.proto"; + +message testmessage { + optional submessage sub = 1; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/SConscript new file mode 100644 index 00000000..6bc32712 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/SConscript @@ -0,0 +1,6 @@ +# Regression test for issue with Enums inside OneOf. + +Import('env') + +env.NanopbProto('oneof') + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/oneof.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/oneof.proto new file mode 100644 index 00000000..e37f5c02 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_188/oneof.proto @@ -0,0 +1,29 @@ +syntax = "proto2"; + +message MessageOne +{ + required uint32 one = 1; + required uint32 two = 2; + required uint32 three = 3; + required int32 four = 4; +} + +enum EnumTwo +{ + SOME_ENUM_1 = 1; + SOME_ENUM_2 = 5; + SOME_ENUM_3 = 6; + SOME_ENUM_4 = 9; + SOME_ENUM_5 = 10; + SOME_ENUM_6 = 12; + SOME_ENUM_7 = 39; + SOME_ENUM_8 = 401; +} + +message OneofMessage +{ + oneof payload { + MessageOne message = 1; + EnumTwo enum = 2; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/SConscript new file mode 100644 index 00000000..78326d32 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/SConscript @@ -0,0 +1,10 @@ +# Regression test for Issue 195: Message size not calculated if a submessage includes +# bytes. Basically a non-working #define being generated. + +Import("env") + +env.NanopbProto(["test"]) +env.Object('test.pb.c') + +env.Match(['test.pb.h', 'test.expected']) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.expected b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.expected new file mode 100644 index 00000000..83ea7ab8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.expected @@ -0,0 +1 @@ +/\* TestMessage_size depends diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.proto new file mode 100644 index 00000000..7a77d69d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_195/test.proto @@ -0,0 +1,8 @@ +message TestMessage { + required uint32 id = 1; + required bytes payload = 2; +} +message EncapsulatedMessage { + required uint32 id = 1; + required TestMessage test = 2; +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/SConscript new file mode 100644 index 00000000..8b4d6cc7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/SConscript @@ -0,0 +1,9 @@ +# Regression test for issue with multiple files generated at once + +Import('env') + +env.Command(['file1.pb.c', 'file1.pb.h', 'file2.pb.c', 'file2.pb.h'], ['file1.proto', 'file2.proto'], + env['NANOPB_PROTO_CMD']) + +env.Object('file1.pb.c') +env.Object('file2.pb.c') diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file1.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file1.proto new file mode 100644 index 00000000..dae250b8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file1.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +message SubMessage1 { + required int32 foo = 1; +} + +message Message1 { + required SubMessage1 bar = 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file2.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file2.proto new file mode 100644 index 00000000..513b0f0d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_203/file2.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +message SubMessage2 { + required int32 foo = 1; +} + +message Message2 { + required SubMessage2 bar = 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/SConscript new file mode 100644 index 00000000..ed8899dd --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/SConscript @@ -0,0 +1,14 @@ +# Check that pb_release() correctly handles corrupted size fields of +# static arrays. + +Import('env', 'malloc_env') + +env.NanopbProto('size_corruption') + +p = malloc_env.Program(["size_corruption.c", + "size_corruption.pb.c", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.c new file mode 100644 index 00000000..08cef457 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.c @@ -0,0 +1,12 @@ +#include "size_corruption.pb.h" +#include + +int main() +{ + MainMessage msg = MainMessage_init_zero; + msg.bar_count = (pb_size_t)-1; + pb_release(MainMessage_fields, &msg); + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.proto new file mode 100644 index 00000000..6c9c2453 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_205/size_corruption.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; +import 'nanopb.proto'; + +message SubMessage { + repeated int32 foo = 1 [(nanopb).type = FT_POINTER]; +} + +message MainMessage { + repeated SubMessage bar = 1 [(nanopb).max_count = 5]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/SConscript new file mode 100644 index 00000000..10741240 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/SConscript @@ -0,0 +1,14 @@ +# Regression test for Issue 227:Using proto3 type fields can cause unaligned access +# NOTE: This test will only detect problems when run with clang sanitizer (which +# is done regularly by a jenkins run). + +Import('env') + +env.NanopbProto('unaligned_uint64') + +p = env.Program(["unaligned_uint64.c", + "unaligned_uint64.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.c new file mode 100644 index 00000000..17c1d779 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.c @@ -0,0 +1,14 @@ +#include "unaligned_uint64.pb.h" +#include + +int main() +{ + uint8_t buf[128]; + pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf)); + MainMessage msg = MainMessage_init_zero; + msg.bar[0] = 'A'; + pb_encode(&stream, MainMessage_fields, &msg); + + return 0; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.proto new file mode 100644 index 00000000..f0269f60 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_227/unaligned_uint64.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +import 'nanopb.proto'; + +message MainMessage { + string foo = 1 [(nanopb).max_size = 3]; + string bar = 2 [(nanopb).max_size = 8]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/SConscript new file mode 100644 index 00000000..b0f8376d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/SConscript @@ -0,0 +1,13 @@ +# Regression test for Issue 229: problem encoding message that has +# multiple oneof fields +Import('env') + +env.NanopbProto('multiple_oneof') + +p = env.Program(["multiple_oneof.c", + "multiple_oneof.pb.c", + "$COMMON/pb_decode.o", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.c new file mode 100644 index 00000000..902248d0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.c @@ -0,0 +1,35 @@ +#include "multiple_oneof.pb.h" +#include +#include +#include + +int main() +{ + int status = 0; + uint8_t buf[128]; + size_t msglen; + + { + pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf)); + MainMessage msg = MainMessage_init_zero; + msg.which_oneof1 = MainMessage_oneof1_uint32_tag; + msg.oneof1.oneof1_uint32 = 1234; + msg.which_oneof2 = MainMessage_oneof2_uint32_tag; + msg.oneof2.oneof2_uint32 = 5678; + TEST(pb_encode(&stream, MainMessage_fields, &msg)); + msglen = stream.bytes_written; + } + + { + pb_istream_t stream = pb_istream_from_buffer(buf, msglen); + MainMessage msg = MainMessage_init_zero; + TEST(pb_decode(&stream, MainMessage_fields, &msg)); + TEST(msg.which_oneof1 == MainMessage_oneof1_uint32_tag); + TEST(msg.oneof1.oneof1_uint32 == 1234); + TEST(msg.which_oneof2 == MainMessage_oneof2_uint32_tag); + TEST(msg.oneof2.oneof2_uint32 == 5678); + } + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.proto new file mode 100644 index 00000000..22373e1d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_229/multiple_oneof.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; + +message MainMessage { + oneof oneof1 { + uint32 oneof1_uint32 = 1; + } + oneof oneof2 { + uint32 oneof2_uint32 = 2; + } +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/SConscript new file mode 100644 index 00000000..000063ef --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/SConscript @@ -0,0 +1,13 @@ +# Regression test for Issue 242: pb_encode does not encode tag for +# extension fields that is all zeros +Import('env') + +env.NanopbProto('zero_value') + +p = env.Program(["zero_value.c", + "zero_value.pb.c", + "$COMMON/pb_decode.o", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.c new file mode 100644 index 00000000..b3d96b7a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include "zero_value.pb.h" + +int main() +{ + int status = 0; + + COMMENT("Test extension fields with zero values"); + { + uint8_t buffer[256] = {0}; + pb_ostream_t ostream; + int32_t value = 0; + Extendable source = {0}; + + pb_extension_t source_ext = {0}; + source_ext.type = &opt_int32; + source_ext.dest = &value; + source.extensions = &source_ext; + + ostream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + TEST(pb_encode(&ostream, Extendable_fields, &source)); + + TEST(ostream.bytes_written == 2); + TEST(memcmp(buffer, "\x58\x00", 2) == 0); + } + + /* Note: There never was a bug here, but this check is included + * in the regression test because the logic is closely related. + */ + COMMENT("Test pointer fields with zero values"); + { + uint8_t buffer[256] = {0}; + pb_ostream_t ostream; + int32_t value = 0; + PointerMessage source = {0}; + + source.opt_int32 = &value; + + ostream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + TEST(pb_encode(&ostream, PointerMessage_fields, &source)); + + TEST(ostream.bytes_written == 2); + TEST(memcmp(buffer, "\x58\x00", 2) == 0); + } + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.proto new file mode 100644 index 00000000..020a39a5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_242/zero_value.proto @@ -0,0 +1,15 @@ +syntax = "proto2"; +import "nanopb.proto"; + +message Extendable { + extensions 10 to 100; +} + +extend Extendable { + optional int32 opt_int32 = 11; +} + +message PointerMessage { + optional int32 opt_int32 = 11 [(nanopb).type = FT_POINTER]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/SConscript new file mode 100644 index 00000000..b41e9f29 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/SConscript @@ -0,0 +1,14 @@ +# Test that pb_check_proto3_default_value() correctly skips padding +# bytes in submessage structures. + +Import("env") + +env.NanopbProto("padding") + +p = env.Program(["padding.c", + "padding.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.c new file mode 100644 index 00000000..8860179d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include "padding.pb.h" + +int main() +{ + int status = 0; + + TestMessage msg; + + /* Set padding bytes to garbage */ + memset(&msg, 0xAA, sizeof(msg)); + + /* Set all meaningful fields to 0 */ + msg.submsg.boolfield = false; + msg.submsg.intfield = 0; + + /* Test encoding */ + { + pb_byte_t buf[128] = {0}; + pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf)); + TEST(pb_encode(&stream, TestMessage_fields, &msg)); + + /* Because all fields have zero values, proto3 encoder + * shouldn't write out anything. */ + TEST(stream.bytes_written == 0); + } + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.proto new file mode 100644 index 00000000..20bddac3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_247/padding.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +import "nanopb.proto"; + +message SubMessage { + bool boolfield = 1; + int64 intfield = 2; +} + +message TestMessage { + SubMessage submsg = 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/SConscript new file mode 100644 index 00000000..ba667129 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/SConscript @@ -0,0 +1,12 @@ +# Regression test for Issue 249: proto3 mode pb_decode() corrupts callback fields +Import('env') + +env.NanopbProto('test') + +p = env.Program(["test.c", + "test.pb.c", + "$COMMON/pb_decode.o", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) +env.RunTest(p) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.c new file mode 100644 index 00000000..a37180fd --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.c @@ -0,0 +1,59 @@ +#include "test.pb.h" +#include +#include +#include + +static bool write_array(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) +{ + int i; + for (i = 0; i < 5; i++) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + if (!pb_encode_varint(stream, 1000 + i)) + return false; + } + + return true; +} + +static bool read_array(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + uint32_t i; + int *sum = *arg; + + if (!pb_decode_varint32(stream, &i)) + return false; + + *sum += i; + + return true; +} + +int main() +{ + int status = 0; + pb_byte_t buf[128] = {0}; + pb_size_t msglen; + + { + MainMessage msg = MainMessage_init_zero; + pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf)); + msg.submsg.foo.funcs.encode = &write_array; + TEST(pb_encode(&stream, MainMessage_fields, &msg)); + msglen = stream.bytes_written; + } + + { + MainMessage msg = MainMessage_init_zero; + pb_istream_t stream = pb_istream_from_buffer(buf, msglen); + int sum = 0; + msg.submsg.foo.funcs.decode = &read_array; + msg.submsg.foo.arg = ∑ + TEST(pb_decode(&stream, MainMessage_fields, &msg)); + TEST(sum == 1000 + 1001 + 1002 + 1003 + 1004); + } + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.proto new file mode 100644 index 00000000..eaa2abde --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_249/test.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +message SubMessage { + repeated int32 foo = 1; +} + +message MainMessage { + SubMessage submsg = 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/SConscript new file mode 100644 index 00000000..5a16948c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/SConscript @@ -0,0 +1,15 @@ +# Regression test for Issue 253: Wrong calculated message maximum size + +Import('env') + +env.NanopbProto('short_array') + +p = env.Program(['short_array.c', + 'short_array.pb.c', + "$COMMON/pb_decode.o", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(p) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.c new file mode 100644 index 00000000..5ed6c3f7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.c @@ -0,0 +1,24 @@ +#include +#include +#include "short_array.pb.h" + +int main() +{ + int status = 0; + + COMMENT("Test message length calculation for short arrays"); + { + uint8_t buffer[TestMessage_size] = {0}; + pb_ostream_t ostream = pb_ostream_from_buffer(buffer, TestMessage_size); + TestMessage msg = TestMessage_init_zero; + + msg.rep_uint32_count = 1; + msg.rep_uint32[0] = (1 << 31); + + TEST(pb_encode(&ostream, TestMessage_fields, &msg)); + TEST(ostream.bytes_written == TestMessage_size); + } + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.proto new file mode 100644 index 00000000..5a5d8a3d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_253/short_array.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; +import "nanopb.proto"; + +message TestMessage { + repeated uint32 rep_uint32 = 1 [(nanopb).max_count = 1]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/SConscript new file mode 100644 index 00000000..b2c3e864 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/SConscript @@ -0,0 +1,16 @@ +# Regression test for Issue 256: Proto3 mode skips submessages even when +# later array fields have non-zero value + +Import('env') + +env.NanopbProto('submsg_array') + +p = env.Program(['submsg_array.c', + 'submsg_array.pb.c', + "$COMMON/pb_decode.o", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(p) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.c new file mode 100644 index 00000000..c63bd30a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include "submsg_array.pb.h" + +int main() +{ + int status = 0; + + COMMENT("Test encoding for submessage with array"); + { + uint8_t buffer[TestMessage_size] = {0}; + pb_ostream_t ostream = pb_ostream_from_buffer(buffer, TestMessage_size); + TestMessage msg = TestMessage_init_zero; + + msg.submsg.rep_uint32_count = 3; + msg.submsg.rep_uint32[0] = 0; + msg.submsg.rep_uint32[1] = 1; + msg.submsg.rep_uint32[2] = 2; + + TEST(pb_encode(&ostream, TestMessage_fields, &msg)); + TEST(ostream.bytes_written > 0); + + { + pb_istream_t istream = pb_istream_from_buffer(buffer, ostream.bytes_written); + TestMessage msg2 = TestMessage_init_zero; + + TEST(pb_decode(&istream, TestMessage_fields, &msg2)); + TEST(msg2.submsg.rep_uint32_count == 3); + TEST(msg2.submsg.rep_uint32[0] == 0); + TEST(msg2.submsg.rep_uint32[1] == 1); + TEST(msg2.submsg.rep_uint32[2] == 2); + } + } + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.proto new file mode 100644 index 00000000..4964a05f --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_256/submsg_array.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +import "nanopb.proto"; + +message SubMessage { + repeated uint32 rep_uint32 = 1 [(nanopb).max_count = 3]; +} + +message TestMessage { + SubMessage submsg = 1; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/SConscript new file mode 100644 index 00000000..8340d454 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/SConscript @@ -0,0 +1,22 @@ +# Check that callback fields inside malloc()ed messages +# are correctly initialized. + +Import('env', 'malloc_env') + +env.NanopbProto('callback_pointer') + +p = malloc_env.Program(["callback_pointer.c", + "callback_pointer.pb.c", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) + +# Run test under valgrind if available +valgrind = env.WhereIs('valgrind') +kwargs = {} +if valgrind: + kwargs['COMMAND'] = valgrind + kwargs['ARGS'] = ["-q", "--error-exitcode=99", p[0].abspath] + +env.RunTest(p, **kwargs) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.c b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.c new file mode 100644 index 00000000..f150fbed --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.c @@ -0,0 +1,30 @@ +#include "callback_pointer.pb.h" +#include +#include + +int main() +{ + int status = 0; + const uint8_t msgdata[] = {0x0A, 0x02, 0x08, 0x7F}; + + MainMessage msg = MainMessage_init_zero; + + { + pb_istream_t stream = pb_istream_from_buffer(msgdata, sizeof(msgdata)); + COMMENT("Running first decode"); + TEST(pb_decode(&stream, MainMessage_fields, &msg)); + pb_release(MainMessage_fields, &msg); + } + + { + pb_istream_t stream = pb_istream_from_buffer(msgdata, sizeof(msgdata)); + COMMENT("Running second decode"); + TEST(pb_decode(&stream, MainMessage_fields, &msg)); + pb_release(MainMessage_fields, &msg); + } + + TEST(get_alloc_count() == 0); + + return status; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.proto b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.proto new file mode 100644 index 00000000..a2d04e4a --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/regression/issue_259/callback_pointer.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; +import 'nanopb.proto'; + +message SubMessage { + optional int32 foo = 1 [(nanopb).type = FT_CALLBACK]; +} + +message MainMessage { + optional SubMessage bar = 1 [(nanopb).type = FT_POINTER]; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_init.py b/hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_init.py new file mode 100644 index 00000000..da5f6d65 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_init.py @@ -0,0 +1,109 @@ +import subprocess +import sys +import re + +try: + # Make terminal colors work on windows + import colorama + colorama.init() +except ImportError: + pass + +def add_nanopb_builders(env): + '''Add the necessary builder commands for nanopb tests.''' + + # Build command that runs a test program and saves the output + def run_test(target, source, env): + if len(source) > 1: + infile = open(str(source[1])) + else: + infile = None + + if env.has_key("COMMAND"): + args = [env["COMMAND"]] + else: + args = [str(source[0])] + + if env.has_key('ARGS'): + args.extend(env['ARGS']) + + print 'Command line: ' + str(args) + pipe = subprocess.Popen(args, + stdin = infile, + stdout = open(str(target[0]), 'w'), + stderr = sys.stderr) + result = pipe.wait() + if result == 0: + print '\033[32m[ OK ]\033[0m Ran ' + args[0] + else: + print '\033[31m[FAIL]\033[0m Program ' + args[0] + ' returned ' + str(result) + return result + + run_test_builder = Builder(action = run_test, + suffix = '.output') + env.Append(BUILDERS = {'RunTest': run_test_builder}) + + # Build command that decodes a message using protoc + def decode_actions(source, target, env, for_signature): + esc = env['ESCAPE'] + dirs = ' '.join(['-I' + esc(env.GetBuildPath(d)) for d in env['PROTOCPATH']]) + return '$PROTOC $PROTOCFLAGS %s --decode=%s %s <%s >%s' % ( + dirs, env['MESSAGE'], esc(str(source[1])), esc(str(source[0])), esc(str(target[0]))) + + decode_builder = Builder(generator = decode_actions, + suffix = '.decoded') + env.Append(BUILDERS = {'Decode': decode_builder}) + + # Build command that encodes a message using protoc + def encode_actions(source, target, env, for_signature): + esc = env['ESCAPE'] + dirs = ' '.join(['-I' + esc(env.GetBuildPath(d)) for d in env['PROTOCPATH']]) + return '$PROTOC $PROTOCFLAGS %s --encode=%s %s <%s >%s' % ( + dirs, env['MESSAGE'], esc(str(source[1])), esc(str(source[0])), esc(str(target[0]))) + + encode_builder = Builder(generator = encode_actions, + suffix = '.encoded') + env.Append(BUILDERS = {'Encode': encode_builder}) + + # Build command that asserts that two files be equal + def compare_files(target, source, env): + data1 = open(str(source[0]), 'rb').read() + data2 = open(str(source[1]), 'rb').read() + if data1 == data2: + print '\033[32m[ OK ]\033[0m Files equal: ' + str(source[0]) + ' and ' + str(source[1]) + return 0 + else: + print '\033[31m[FAIL]\033[0m Files differ: ' + str(source[0]) + ' and ' + str(source[1]) + return 1 + + compare_builder = Builder(action = compare_files, + suffix = '.equal') + env.Append(BUILDERS = {'Compare': compare_builder}) + + # Build command that checks that each pattern in source2 is found in source1. + def match_files(target, source, env): + data = open(str(source[0]), 'rU').read() + patterns = open(str(source[1])) + for pattern in patterns: + if pattern.strip(): + invert = False + if pattern.startswith('! '): + invert = True + pattern = pattern[2:] + + status = re.search(pattern.strip(), data, re.MULTILINE) + + if not status and not invert: + print '\033[31m[FAIL]\033[0m Pattern not found in ' + str(source[0]) + ': ' + pattern + return 1 + elif status and invert: + print '\033[31m[FAIL]\033[0m Pattern should not exist, but does in ' + str(source[0]) + ': ' + pattern + return 1 + else: + print '\033[32m[ OK ]\033[0m All patterns found in ' + str(source[0]) + return 0 + + match_builder = Builder(action = match_files, suffix = '.matched') + env.Append(BUILDERS = {'Match': match_builder}) + + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_tools/nanopb.py b/hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_tools/nanopb.py new file mode 100644 index 00000000..c72a45d3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/site_scons/site_tools/nanopb.py @@ -0,0 +1,126 @@ +''' +Scons Builder for nanopb .proto definitions. + +This tool will locate the nanopb generator and use it to generate .pb.c and +.pb.h files from the .proto files. + +Basic example +------------- +# Build myproto.pb.c and myproto.pb.h from myproto.proto +myproto = env.NanopbProto("myproto") + +# Link nanopb core to the program +env.Append(CPPPATH = "$NANOB") +myprog = env.Program(["myprog.c", myproto, "$NANOPB/pb_encode.c", "$NANOPB/pb_decode.c"]) + +Configuration options +--------------------- +Normally, this script is used in the test environment of nanopb and it locates +the nanopb generator by a relative path. If this script is used in another +application, the path to nanopb root directory has to be defined: + +env.SetDefault(NANOPB = "path/to/nanopb") + +Additionally, the path to protoc and the options to give to protoc can be +defined manually: + +env.SetDefault(PROTOC = "path/to/protoc") +env.SetDefault(PROTOCFLAGS = "--plugin=protoc-gen-nanopb=path/to/protoc-gen-nanopb") +''' + +import SCons.Action +import SCons.Builder +import SCons.Util +import os.path + +class NanopbWarning(SCons.Warnings.Warning): + pass +SCons.Warnings.enableWarningClass(NanopbWarning) + +def _detect_nanopb(env): + '''Find the path to nanopb root directory.''' + if env.has_key('NANOPB'): + # Use nanopb dir given by user + return env['NANOPB'] + + p = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')) + if os.path.isdir(p) and os.path.isfile(os.path.join(p, 'pb.h')): + # Assume we are running under tests/site_scons/site_tools + return p + + raise SCons.Errors.StopError(NanopbWarning, + "Could not find the nanopb root directory") + +def _detect_protoc(env): + '''Find the path to the protoc compiler.''' + if env.has_key('PROTOC'): + # Use protoc defined by user + return env['PROTOC'] + + n = _detect_nanopb(env) + p1 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX']) + if os.path.exists(p1): + # Use protoc bundled with binary package + return env['ESCAPE'](p1) + + p = env.WhereIs('protoc') + if p: + # Use protoc from path + return env['ESCAPE'](p) + + raise SCons.Errors.StopError(NanopbWarning, + "Could not find the protoc compiler") + +def _detect_protocflags(env): + '''Find the options to use for protoc.''' + if env.has_key('PROTOCFLAGS'): + return env['PROTOCFLAGS'] + + p = _detect_protoc(env) + n = _detect_nanopb(env) + p1 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX']) + if p == env['ESCAPE'](p1): + # Using the bundled protoc, no options needed + return '' + + e = env['ESCAPE'] + if env['PLATFORM'] == 'win32': + return e('--plugin=protoc-gen-nanopb=' + os.path.join(n, 'generator', 'protoc-gen-nanopb.bat')) + else: + return e('--plugin=protoc-gen-nanopb=' + os.path.join(n, 'generator', 'protoc-gen-nanopb')) + +def _nanopb_proto_actions(source, target, env, for_signature): + esc = env['ESCAPE'] + dirs = ' '.join(['-I' + esc(env.GetBuildPath(d)) for d in env['PROTOCPATH']]) + return '$PROTOC $PROTOCFLAGS %s --nanopb_out=. %s' % (dirs, esc(str(source[0]))) + +def _nanopb_proto_emitter(target, source, env): + basename = os.path.splitext(str(source[0]))[0] + target.append(basename + '.pb.h') + + if os.path.exists(basename + '.options'): + source.append(basename + '.options') + + return target, source + +_nanopb_proto_builder = SCons.Builder.Builder( + generator = _nanopb_proto_actions, + suffix = '.pb.c', + src_suffix = '.proto', + emitter = _nanopb_proto_emitter) + +def generate(env): + '''Add Builder for nanopb protos.''' + + env['NANOPB'] = _detect_nanopb(env) + env['PROTOC'] = _detect_protoc(env) + env['PROTOCFLAGS'] = _detect_protocflags(env) + + env.SetDefault(PROTOCPATH = ['.', os.path.join(env['NANOPB'], 'generator', 'proto')]) + + env.SetDefault(NANOPB_PROTO_CMD = '$PROTOC $PROTOCFLAGS --nanopb_out=. $SOURCES') + env['BUILDERS']['NanopbProto'] = _nanopb_proto_builder + +def exists(env): + return _detect_protoc(env) and _detect_protoc_opts(env) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/special_characters/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/special_characters/SConscript new file mode 100644 index 00000000..2309cf2e --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/special_characters/SConscript @@ -0,0 +1,6 @@ +# Test that special characters in .proto filenames work. + +Import('env') + +env.NanopbProto("funny-proto+name has.characters.proto") +env.Object("funny-proto+name has.characters.pb.c") diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/special_characters/funny-proto+name has.characters.proto b/hardware-wallet/firmware/vendor/nanopb/tests/special_characters/funny-proto+name has.characters.proto new file mode 100644 index 00000000..26b2cb1b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/special_characters/funny-proto+name has.characters.proto @@ -0,0 +1 @@ +syntax="proto2"; diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/splint/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/splint/SConscript new file mode 100644 index 00000000..cd4b5b9d --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/splint/SConscript @@ -0,0 +1,16 @@ +# Check the nanopb core using splint + +Import('env') + +p = env.WhereIs('splint') + +if p: + env.Command('pb_decode.splint', '$NANOPB/pb_decode.c', + 'splint -f splint/splint.rc $SOURCE 2> $TARGET') + + env.Command('pb_encode.splint', '$NANOPB/pb_encode.c', + 'splint -f splint/splint.rc $SOURCE 2> $TARGET') + + env.Command('pb_common.splint', '$NANOPB/pb_common.c', + 'splint -f splint/splint.rc $SOURCE 2> $TARGET') + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/splint/splint.rc b/hardware-wallet/firmware/vendor/nanopb/tests/splint/splint.rc new file mode 100644 index 00000000..e47d3c21 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/splint/splint.rc @@ -0,0 +1,37 @@ ++checks ++partial ++matchanyintegral ++strictlib +-nullassign +-predboolint +-predboolptr ++ptrnegate +-switchloopbreak ++ignoresigns +-infloopsuncon +-type + +# splint's memory checks don't quite work without annotations +-mustfreeonly +-compmempass +-nullret +-observertrans +-statictrans +-compdestroy +-nullpass +-nullstate +-compdef +-usereleased +-temptrans +-dependenttrans +-kepttrans +-branchstate +-immediatetrans +-mustfreefresh + +# These tests give false positives, compiler typically has +# better warnings for these. +-noret +-noeffect +-usedef + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/SConscript b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/SConscript new file mode 100644 index 00000000..4472529c --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/SConscript @@ -0,0 +1,30 @@ +# Run the alltypes test case, but compile with PB_WITHOUT_64BIT. + +Import("env") + +env.NanopbProto(["alltypes", "alltypes.options"]) + +# Define the compilation options +opts = env.Clone() +opts.Append(CPPDEFINES = {'PB_WITHOUT_64BIT': 1, 'HAVE_STDINT_H': 0, 'PB_SYSTEM_HEADER': '\\"no_64bit_syshdr.h\\"'}) +opts.Append(CPPPATH = "#without_64bit") + +if 'SYSHDR' in opts: + opts.Append(CPPDEFINES = {'PB_OLD_SYSHDR': opts['SYSHDR']}) + +# Build new version of core +strict = opts.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_decode_no64bit.o", "$NANOPB/pb_decode.c") +strict.Object("pb_encode_no64bit.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common_no64bit.o", "$NANOPB/pb_common.c") + +# Now build and run the test normally. +enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_no64bit.o", "pb_common_no64bit.o"]) +dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_no64bit.o", "pb_common_no64bit.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) + +env.RunTest("optionals.output", enc, ARGS = ['1']) +env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1']) diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.options b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.options new file mode 100644 index 00000000..0d5ab12b --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.options @@ -0,0 +1,3 @@ +* max_size:16 +* max_count:5 +*.*fbytes fixed_length:true max_size:4 diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.proto b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.proto new file mode 100644 index 00000000..240685b8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/alltypes.proto @@ -0,0 +1,100 @@ +syntax = "proto2"; +// package name placeholder + +message SubMessage { + required string substuff1 = 1 [default = "1"]; + required int32 substuff2 = 2 [default = 2]; + optional fixed32 substuff3 = 3 [default = 3]; +} + +message EmptyMessage { + +} + +enum HugeEnum { + Negative = -2147483647; /* protoc doesn't accept -2147483648 here */ + Positive = 2147483647; +} + +message Limits { + required int32 int32_min = 1 [default = 2147483647]; + required int32 int32_max = 2 [default = -2147483647]; + required uint32 uint32_min = 3 [default = 4294967295]; + required uint32 uint32_max = 4 [default = 0]; + required HugeEnum enum_min = 9 [default = Positive]; + required HugeEnum enum_max = 10 [default = Negative]; +} + +enum MyEnum { + Zero = 0; + First = 1; + Second = 2; + Truth = 42; +} + +message AllTypes { + required int32 req_int32 = 1; + required uint32 req_uint32 = 3; + required sint32 req_sint32 = 5; + required bool req_bool = 7; + + required fixed32 req_fixed32 = 8; + required sfixed32 req_sfixed32= 9; + required float req_float = 10; + + required string req_string = 14; + required bytes req_bytes = 15; + required SubMessage req_submsg = 16; + required MyEnum req_enum = 17; + required EmptyMessage req_emptymsg = 18; + required bytes req_fbytes = 19; + + repeated int32 rep_int32 = 21 [packed = true]; + repeated uint32 rep_uint32 = 23 [packed = true]; + repeated sint32 rep_sint32 = 25 [packed = true]; + repeated bool rep_bool = 27 [packed = true]; + + repeated fixed32 rep_fixed32 = 28 [packed = true]; + repeated sfixed32 rep_sfixed32= 29 [packed = true]; + repeated float rep_float = 30 [packed = true]; + + repeated string rep_string = 34; + repeated bytes rep_bytes = 35; + repeated SubMessage rep_submsg = 36; + repeated MyEnum rep_enum = 37 [packed = true]; + repeated EmptyMessage rep_emptymsg = 38; + repeated bytes rep_fbytes = 39; + + optional int32 opt_int32 = 41 [default = 4041]; + optional uint32 opt_uint32 = 43 [default = 4043]; + optional sint32 opt_sint32 = 45 [default = 4045]; + optional bool opt_bool = 47 [default = false]; + + optional fixed32 opt_fixed32 = 48 [default = 4048]; + optional sfixed32 opt_sfixed32= 49 [default = 4049]; + optional float opt_float = 50 [default = 4050]; + + optional string opt_string = 54 [default = "4054"]; + optional bytes opt_bytes = 55 [default = "4055"]; + optional SubMessage opt_submsg = 56; + optional MyEnum opt_enum = 57 [default = Second]; + optional EmptyMessage opt_emptymsg = 58; + optional bytes opt_fbytes = 59 [default = "4059"]; + + oneof oneof + { + SubMessage oneof_msg1 = 60; + EmptyMessage oneof_msg2 = 61; + } + + // Check that extreme integer values are handled correctly + required Limits req_limits = 98; + + // Just to make sure that the size of the fields has been calculated + // properly, i.e. otherwise a bug in last field might not be detected. + required int32 end = 99; + + + extensions 200 to 255; +} + diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/decode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/decode_alltypes.c new file mode 100644 index 00000000..6b5ff8e3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/decode_alltypes.c @@ -0,0 +1,185 @@ +/* Tests the decoding of all types. + * This is the counterpart of test_encode3. + * Run e.g. ./test_encode3 | ./test_decode3 + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +#define TEST(x) if (!(x)) { \ + printf("Test " #x " failed.\n"); \ + return false; \ + } + +/* This function is called once from main(), it handles + the decoding and checks the fields. */ +bool check_alltypes(pb_istream_t *stream, int mode) +{ + /* Uses _init_default to just make sure that it works. */ + AllTypes alltypes = AllTypes_init_default; + + /* Fill with garbage to better detect initialization errors */ + memset(&alltypes, 0xAA, sizeof(alltypes)); + alltypes.extensions = 0; + + if (!pb_decode(stream, AllTypes_fields, &alltypes)) + return false; + + TEST(alltypes.req_int32 == -1001); + TEST(alltypes.req_uint32 == 1003); + TEST(alltypes.req_sint32 == -1005); + TEST(alltypes.req_bool == true); + + TEST(alltypes.req_fixed32 == 1008); + TEST(alltypes.req_sfixed32 == -1009); + TEST(alltypes.req_float == 1010.0f); + + TEST(strcmp(alltypes.req_string, "1014") == 0); + TEST(alltypes.req_bytes.size == 4); + TEST(memcmp(alltypes.req_bytes.bytes, "1015", 4) == 0); + TEST(strcmp(alltypes.req_submsg.substuff1, "1016") == 0); + TEST(alltypes.req_submsg.substuff2 == 1016); + TEST(alltypes.req_submsg.substuff3 == 3); + TEST(alltypes.req_enum == MyEnum_Truth); + TEST(memcmp(alltypes.req_fbytes, "1019", 4) == 0); + + TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0); + TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0); + TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0); + TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false); + + TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0); + TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0); + TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f); + + TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0'); + TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0); + TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0); + + TEST(alltypes.rep_submsg_count == 5); + TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0'); + TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0); + TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 3); + + TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero); + TEST(alltypes.rep_emptymsg_count == 5); + TEST(alltypes.rep_fbytes_count == 5); + TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0); + TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0); + + if (mode == 0) + { + /* Expect default values */ + TEST(alltypes.has_opt_int32 == false); + TEST(alltypes.opt_int32 == 4041); + TEST(alltypes.has_opt_uint32 == false); + TEST(alltypes.opt_uint32 == 4043); + TEST(alltypes.has_opt_sint32 == false); + TEST(alltypes.opt_sint32 == 4045); + TEST(alltypes.has_opt_bool == false); + TEST(alltypes.opt_bool == false); + + TEST(alltypes.has_opt_fixed32 == false); + TEST(alltypes.opt_fixed32 == 4048); + TEST(alltypes.has_opt_sfixed32 == false); + TEST(alltypes.opt_sfixed32 == 4049); + TEST(alltypes.has_opt_float == false); + TEST(alltypes.opt_float == 4050.0f); + + TEST(alltypes.has_opt_string == false); + TEST(strcmp(alltypes.opt_string, "4054") == 0); + TEST(alltypes.has_opt_bytes == false); + TEST(alltypes.opt_bytes.size == 4); + TEST(memcmp(alltypes.opt_bytes.bytes, "4055", 4) == 0); + TEST(alltypes.has_opt_submsg == false); + TEST(strcmp(alltypes.opt_submsg.substuff1, "1") == 0); + TEST(alltypes.opt_submsg.substuff2 == 2); + TEST(alltypes.opt_submsg.substuff3 == 3); + TEST(alltypes.has_opt_enum == false); + TEST(alltypes.opt_enum == MyEnum_Second); + TEST(alltypes.has_opt_emptymsg == false); + TEST(alltypes.has_opt_fbytes == false); + TEST(memcmp(alltypes.opt_fbytes, "4059", 4) == 0); + + TEST(alltypes.which_oneof == 0); + } + else + { + /* Expect filled-in values */ + TEST(alltypes.has_opt_int32 == true); + TEST(alltypes.opt_int32 == 3041); + TEST(alltypes.has_opt_uint32 == true); + TEST(alltypes.opt_uint32 == 3043); + TEST(alltypes.has_opt_sint32 == true); + TEST(alltypes.opt_sint32 == 3045); + TEST(alltypes.has_opt_bool == true); + TEST(alltypes.opt_bool == true); + + TEST(alltypes.has_opt_fixed32 == true); + TEST(alltypes.opt_fixed32 == 3048); + TEST(alltypes.has_opt_sfixed32 == true); + TEST(alltypes.opt_sfixed32 == 3049); + TEST(alltypes.has_opt_float == true); + TEST(alltypes.opt_float == 3050.0f); + + TEST(alltypes.has_opt_string == true); + TEST(strcmp(alltypes.opt_string, "3054") == 0); + TEST(alltypes.has_opt_bytes == true); + TEST(alltypes.opt_bytes.size == 4); + TEST(memcmp(alltypes.opt_bytes.bytes, "3055", 4) == 0); + TEST(alltypes.has_opt_submsg == true); + TEST(strcmp(alltypes.opt_submsg.substuff1, "3056") == 0); + TEST(alltypes.opt_submsg.substuff2 == 3056); + TEST(alltypes.opt_submsg.substuff3 == 3); + TEST(alltypes.has_opt_enum == true); + TEST(alltypes.opt_enum == MyEnum_Truth); + TEST(alltypes.has_opt_emptymsg == true); + TEST(alltypes.has_opt_fbytes == true); + TEST(memcmp(alltypes.opt_fbytes, "3059", 4) == 0); + + TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag); + TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0); + TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059); + } + + TEST(alltypes.req_limits.int32_min == INT32_MIN); + TEST(alltypes.req_limits.int32_max == INT32_MAX); + TEST(alltypes.req_limits.uint32_min == 0); + TEST(alltypes.req_limits.uint32_max == UINT32_MAX); + TEST(alltypes.req_limits.enum_min == HugeEnum_Negative); + TEST(alltypes.req_limits.enum_max == HugeEnum_Positive); + + TEST(alltypes.end == 1099); + + return true; +} + +int main(int argc, char **argv) +{ + uint8_t buffer[1024]; + size_t count; + pb_istream_t stream; + + /* Whether to expect the optional values or the default values. */ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Read the data into buffer */ + SET_BINARY_MODE(stdin); + count = fread(buffer, 1, sizeof(buffer), stdin); + + /* Construct a pb_istream_t for reading from the buffer */ + stream = pb_istream_from_buffer(buffer, count); + + /* Decode and print out the stuff */ + if (!check_alltypes(&stream, mode)) + { + printf("Parsing failed: %s\n", PB_GET_ERROR(&stream)); + return 1; + } else { + return 0; + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/encode_alltypes.c b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/encode_alltypes.c new file mode 100644 index 00000000..9fe26f64 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/encode_alltypes.c @@ -0,0 +1,124 @@ +/* Attempts to test all the datatypes supported by ProtoBuf. + */ + +#include +#include +#include +#include +#include "alltypes.pb.h" +#include "test_helpers.h" + +int main(int argc, char **argv) +{ + int mode = (argc > 1) ? atoi(argv[1]) : 0; + + /* Initialize the structure with constants */ + AllTypes alltypes = AllTypes_init_zero; + + alltypes.req_int32 = -1001; + alltypes.req_uint32 = 1003; + alltypes.req_sint32 = -1005; + alltypes.req_bool = true; + + alltypes.req_fixed32 = 1008; + alltypes.req_sfixed32 = -1009; + alltypes.req_float = 1010.0f; + + strcpy(alltypes.req_string, "1014"); + alltypes.req_bytes.size = 4; + memcpy(alltypes.req_bytes.bytes, "1015", 4); + strcpy(alltypes.req_submsg.substuff1, "1016"); + alltypes.req_submsg.substuff2 = 1016; + alltypes.req_enum = MyEnum_Truth; + memcpy(alltypes.req_fbytes, "1019", 4); + + alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001; + alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003; + alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005; + alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true; + + alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008; + alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009; + alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f; + + alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014"); + alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4; + memcpy(alltypes.rep_bytes[4].bytes, "2015", 4); + + alltypes.rep_submsg_count = 5; + strcpy(alltypes.rep_submsg[4].substuff1, "2016"); + alltypes.rep_submsg[4].substuff2 = 2016; + alltypes.rep_submsg[4].has_substuff3 = true; + alltypes.rep_submsg[4].substuff3 = 2016; + + alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth; + alltypes.rep_emptymsg_count = 5; + + alltypes.rep_fbytes_count = 5; + memcpy(alltypes.rep_fbytes[4], "2019", 4); + + alltypes.req_limits.int32_min = INT32_MIN; + alltypes.req_limits.int32_max = INT32_MAX; + alltypes.req_limits.uint32_min = 0; + alltypes.req_limits.uint32_max = UINT32_MAX; + alltypes.req_limits.enum_min = HugeEnum_Negative; + alltypes.req_limits.enum_max = HugeEnum_Positive; + + if (mode != 0) + { + /* Fill in values for optional fields */ + alltypes.has_opt_int32 = true; + alltypes.opt_int32 = 3041; + alltypes.has_opt_uint32 = true; + alltypes.opt_uint32 = 3043; + alltypes.has_opt_sint32 = true; + alltypes.opt_sint32 = 3045; + alltypes.has_opt_bool = true; + alltypes.opt_bool = true; + + alltypes.has_opt_fixed32 = true; + alltypes.opt_fixed32 = 3048; + alltypes.has_opt_sfixed32 = true; + alltypes.opt_sfixed32 = 3049; + alltypes.has_opt_float = true; + alltypes.opt_float = 3050.0f; + + alltypes.has_opt_string = true; + strcpy(alltypes.opt_string, "3054"); + alltypes.has_opt_bytes = true; + alltypes.opt_bytes.size = 4; + memcpy(alltypes.opt_bytes.bytes, "3055", 4); + alltypes.has_opt_submsg = true; + strcpy(alltypes.opt_submsg.substuff1, "3056"); + alltypes.opt_submsg.substuff2 = 3056; + alltypes.has_opt_enum = true; + alltypes.opt_enum = MyEnum_Truth; + alltypes.has_opt_emptymsg = true; + alltypes.has_opt_fbytes = true; + memcpy(alltypes.opt_fbytes, "3059", 4); + + alltypes.which_oneof = AllTypes_oneof_msg1_tag; + strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059"); + alltypes.oneof.oneof_msg1.substuff2 = 4059; + } + + alltypes.end = 1099; + + { + uint8_t buffer[AllTypes_size]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* Now encode it and check if we succeeded. */ + if (pb_encode(&stream, AllTypes_fields, &alltypes)) + { + SET_BINARY_MODE(stdout); + fwrite(buffer, 1, stream.bytes_written, stdout); + return 0; /* Success */ + } + else + { + fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return 1; /* Failure */ + } + } +} diff --git a/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/no_64bit_syshdr.h b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/no_64bit_syshdr.h new file mode 100644 index 00000000..970178ff --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tests/without_64bit/no_64bit_syshdr.h @@ -0,0 +1,14 @@ +/* This wrapper undefines (u)int64_t */ + +#ifdef PB_OLD_SYSHDR +#include PB_OLD_SYSHDR +#else +#include +#include +#include +#include +#endif + +#define uint64_t disabled_uint64_t +#define int64_t disabled_int64_t + diff --git a/hardware-wallet/firmware/vendor/nanopb/tools/make_linux_package.sh b/hardware-wallet/firmware/vendor/nanopb/tools/make_linux_package.sh new file mode 100755 index 00000000..0bcba7d3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tools/make_linux_package.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Run this script in the top nanopb directory to create a binary package +# for Linux users. + +# Requires: protobuf, python-protobuf, pyinstaller + +set -e +set -x + +VERSION=`git describe --always`-linux-x86 +DEST=dist/$VERSION + +rm -rf $DEST +mkdir -p $DEST + +# Export the files from newest commit +git archive HEAD | tar x -C $DEST + +# Rebuild the Python .proto files +make -BC $DEST/generator/proto + +# Package the Python libraries +( cd $DEST/generator; pyinstaller nanopb_generator.py ) +mv $DEST/generator/dist/nanopb_generator $DEST/generator-bin + +# Remove temp files +rm -rf $DEST/generator/dist $DEST/generator/build $DEST/generator/nanopb_generator.spec + +# Make the nanopb generator available as a protoc plugin +cp $DEST/generator-bin/nanopb_generator $DEST/generator-bin/protoc-gen-nanopb + +# Package the protoc compiler +cp `which protoc` $DEST/generator-bin/protoc.bin +LIBPROTOC=$(ldd `which protoc` | grep -o '/.*libprotoc[^ ]*') +LIBPROTOBUF=$(ldd `which protoc` | grep -o '/.*libprotobuf[^ ]*') +cp $LIBPROTOC $LIBPROTOBUF $DEST/generator-bin/ +cat > $DEST/generator-bin/protoc << EOF +#!/bin/bash +SCRIPTDIR=\$(dirname "\$0") +export LD_LIBRARY_PATH=\$SCRIPTDIR +export PATH=\$SCRIPTDIR:\$PATH +exec "\$SCRIPTDIR/protoc.bin" "\$@" +EOF +chmod +x $DEST/generator-bin/protoc + +# Remove debugging symbols to reduce size of package +( cd $DEST/generator-bin; strip *.so *.so.* ) + +# Tar it all up +( cd dist; tar -czf $VERSION.tar.gz $VERSION ) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tools/make_mac_package.sh b/hardware-wallet/firmware/vendor/nanopb/tools/make_mac_package.sh new file mode 100755 index 00000000..32bba5cc --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tools/make_mac_package.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Run this script in the top nanopb directory to create a binary package +# for Mac OS X users. + +# Requires: protobuf, python-protobuf, pyinstaller + +set -e +set -x + +VERSION=`git describe --always`-macosx-x86 +DEST=dist/$VERSION + +rm -rf $DEST +mkdir -p $DEST + +# Export the files from newest commit +git archive HEAD | tar x -C $DEST + +# Rebuild the Python .proto files +make -BC $DEST/generator/proto + +# Package the Python libraries +( cd $DEST/generator; pyinstaller nanopb_generator.py ) +mv $DEST/generator/dist/nanopb_generator $DEST/generator-bin + +# Remove temp files +rm -rf $DEST/generator/dist $DEST/generator/build $DEST/generator/nanopb_generator.spec + +# Make the nanopb generator available as a protoc plugin +cp $DEST/generator-bin/nanopb_generator $DEST/generator-bin/protoc-gen-nanopb + +# Package the protoc compiler +cp `which protoc` $DEST/generator-bin/protoc.bin +LIBPROTOC=$(otool -L `which protoc` | grep -o '/.*libprotoc[^ ]*') +LIBPROTOBUF=$(otool -L `which protoc` | grep -o '/.*libprotobuf[^ ]*') +cp $LIBPROTOC $LIBPROTOBUF $DEST/generator-bin/ +cat > $DEST/generator-bin/protoc << EOF +#!/bin/bash +SCRIPTDIR=\$(dirname "\$0") +export DYLD_LIBRARY_PATH=\$SCRIPTDIR +export PATH=\$SCRIPTDIR:\$PATH +exec "\$SCRIPTDIR/protoc.bin" "\$@" +EOF +chmod +x $DEST/generator-bin/protoc + +# Tar it all up +( cd dist; tar -czf $VERSION.tar.gz $VERSION ) + diff --git a/hardware-wallet/firmware/vendor/nanopb/tools/make_windows_package.sh b/hardware-wallet/firmware/vendor/nanopb/tools/make_windows_package.sh new file mode 100755 index 00000000..72de6f33 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tools/make_windows_package.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# Run this script in the top nanopb directory to create a binary package +# for Windows users. This script is designed to run under MingW/MSYS bash +# and requires the following tools: git, make, zip, unix2dos + +set -e +set -x + +VERSION=`git describe --always`-windows-x86 +DEST=dist/$VERSION + +rm -rf $DEST +mkdir -p $DEST + +# Export the files from newest commit +git archive HEAD | tar x -C $DEST + +# Rebuild the Python .proto files +make -BC $DEST/generator/proto + +# Make the nanopb generator available as a protoc plugin +cp $DEST/generator/nanopb_generator.py $DEST/generator/protoc-gen-nanopb.py + +# Package the Python libraries +( cd $DEST/generator; bbfreeze nanopb_generator.py protoc-gen-nanopb.py ) +mv $DEST/generator/dist $DEST/generator-bin + +# Remove temp file +rm $DEST/generator/protoc-gen-nanopb.py + +# The python interpreter requires MSVCR90.dll. +# FIXME: Find a way around hardcoding this path +cp /c/windows/winsxs/x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4974_none_50940634bcb759cb/MSVCR90.DLL $DEST/generator-bin/ +cat > $DEST/generator-bin/Microsoft.VC90.CRT.manifest < + + + + KSaO8M0iCtPF6YEr79P1dZsnomY= ojDmTgpYMFRKJYkPcM6ckpYkWUU= tVogb8kezDre2mXShlIqpp8ErIg= + +EOF + +# Package the protoc compiler +cp `which protoc.exe` $DEST/generator-bin/ +cp `which MSVCR100.DLL` $DEST/generator-bin/ +cp `which MSVCP100.DLL` $DEST/generator-bin/ + +# Convert line breaks for convenience +find $DEST -name '*.c' -o -name '*.h' -o -name '*.txt' \ + -o -name '*.proto' -o -name '*.py' -o -name '*.options' \ + -exec unix2dos '{}' \; + +# Zip it all up +( cd dist; zip -r $VERSION.zip $VERSION ) diff --git a/hardware-wallet/firmware/vendor/nanopb/tools/set_version.sh b/hardware-wallet/firmware/vendor/nanopb/tools/set_version.sh new file mode 100755 index 00000000..0adb5976 --- /dev/null +++ b/hardware-wallet/firmware/vendor/nanopb/tools/set_version.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Run this from the top directory of nanopb tree. +# e.g. user@localhost:~/nanopb$ tools/set_version.sh nanopb-0.1.9-dev +# It sets the version number in pb.h and generator/nanopb_generator.py. + +sed -i -e 's/nanopb_version\s*=\s*"[^"]*"/nanopb_version = "'$1'"/' generator/nanopb_generator.py +sed -i -e 's/#define\s*NANOPB_VERSION\s*.*/#define NANOPB_VERSION '$1'/' pb.h +sed -i -e 's/set(\s*nanopb_VERSION_STRING\s*[^)]*)/set(nanopb_VERSION_STRING '$1')/' CMakeLists.txt + +VERSION_ONLY=$(echo $1 | sed 's/nanopb-//') +if [[ $1 != *dev ]] +then sed -i -e 's/"version":\s*"[^"]*"/"version": "'$VERSION_ONLY'"/' library.json +fi diff --git a/hardware-wallet/firmware/vendor/skycoin-crypto b/hardware-wallet/firmware/vendor/skycoin-crypto new file mode 160000 index 00000000..704fedae --- /dev/null +++ b/hardware-wallet/firmware/vendor/skycoin-crypto @@ -0,0 +1 @@ +Subproject commit 704fedae4fd98f666f42ebb13acb3a3a85a50ca6 diff --git a/hardware-wallet/firmware/vendor/trezor-common/.travis.yml b/hardware-wallet/firmware/vendor/trezor-common/.travis.yml new file mode 100644 index 00000000..cdb1c751 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/.travis.yml @@ -0,0 +1,23 @@ +language: python + +# Runs jobs on container based infrastructure +sudo: false + +# Saves pip downloads/wheels between builds +cache: + directories: + - $HOME/.cache/pip + +python: + - "3.5" + +script: + - python coins-check.py + +notifications: + webhooks: + urls: + - http://ci-bot.satoshilabs.com:5000/travis + on_success: always + on_failure: always + on_start: always diff --git a/hardware-wallet/firmware/vendor/trezor-common/COPYING b/hardware-wallet/firmware/vendor/trezor-common/COPYING new file mode 100644 index 00000000..65c5ca88 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/hardware-wallet/firmware/vendor/trezor-common/README.md b/hardware-wallet/firmware/vendor/trezor-common/README.md new file mode 100644 index 00000000..2a5bf751 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/README.md @@ -0,0 +1,12 @@ +# trezor-common + +[![Build Status](https://travis-ci.org/trezor/trezor-common.svg?branch=master)](https://travis-ci.org/trezor/trezor-common) +[![Gitter](https://badges.gitter.im/trezor/community.svg)](https://gitter.im/trezor/community) + +Common files shared among TREZOR repositories. + +This repo is meant to be included as submodule to others using: + +``` +git submodule add https://github.com/trezor/trezor-common.git trezor-common +``` diff --git a/hardware-wallet/firmware/vendor/trezor-common/coins-check.py b/hardware-wallet/firmware/vendor/trezor-common/coins-check.py new file mode 100755 index 00000000..66cd5772 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/coins-check.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +import json + + +def is_hex(val): + try: + int(val, 16) + return True + except: + return False + + +for coin in json.load(open('coins.json')): + assert isinstance(coin['coin_name'], str) + assert isinstance(coin['coin_shortcut'], str) + assert isinstance(coin['coin_label'], str) + assert isinstance(coin['curve_name'], str) + assert isinstance(coin['address_type'], int) + assert isinstance(coin['address_type_p2sh'], int) + assert coin['address_type'] != coin['address_type_p2sh'] + assert isinstance(coin['maxfee_kb'], int) + assert isinstance(coin['minfee_kb'], int) + assert coin['maxfee_kb'] > coin['minfee_kb'] + assert coin['signed_message_header'] + assert is_hex(coin['hash_genesis_block']) + assert is_hex(coin['xprv_magic']) + assert is_hex(coin['xpub_magic']) + assert isinstance(coin['bip44'], int) + assert isinstance(coin['segwit'], bool) + assert isinstance(coin['decred'], bool) + assert coin['forkid'] is None or isinstance(coin['forkid'], int) + assert isinstance(coin['force_bip143'], bool) + assert isinstance(coin['default_fee_b'], dict) + assert isinstance(coin['dust_limit'], int) + assert isinstance(coin['blocktime_minutes'], int) or isinstance(coin['blocktime_minutes'], float) + assert coin['firmware'] is None or coin['firmware'] in ['stable', 'debug'] + assert isinstance(coin['signed_message_header'], str) + assert isinstance(coin['min_address_length'], int) + assert isinstance(coin['max_address_length'], int) + assert isinstance(coin['bitcore'], list) + assert coin['xpub_magic_segwit_p2sh'] is None or is_hex(coin['xpub_magic_segwit_p2sh']) + assert coin['bech32_prefix'] is None or isinstance(coin['bech32_prefix'], str) + +print('OK') diff --git a/hardware-wallet/firmware/vendor/trezor-common/coins.json b/hardware-wallet/firmware/vendor/trezor-common/coins.json new file mode 100644 index 00000000..08103045 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/coins.json @@ -0,0 +1,547 @@ +[ +{ + "coin_name": "Bitcoin", + "coin_shortcut": "BTC", + "coin_label": "Bitcoin", + "curve_name": "secp256k1", + "address_type": 0, + "address_type_p2sh": 5, + "maxfee_kb": 2000000, + "minfee_kb": 1000, + "signed_message_header": "Bitcoin Signed Message:\n", + "hash_genesis_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", + "xprv_magic": "0488ade4", + "xpub_magic": "0488b21e", + "xpub_magic_segwit_p2sh": "049d7cb2", + "bech32_prefix": "bc", + "cashaddr_prefix": null, + "bip44": 0, + "segwit": true, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Low": 10, + "Economy": 70, + "Normal": 140, + "High": 200 + }, + "dust_limit": 546, + "blocktime_minutes": 10, + "firmware": "stable", + "address_prefix": "bitcoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "https://btc-bitcore3.trezor.io", + "https://btc-bitcore1.trezor.io" + ] +}, +{ + "coin_name": "Testnet", + "coin_shortcut": "TEST", + "coin_label": "Testnet", + "curve_name": "secp256k1", + "address_type": 111, + "address_type_p2sh": 196, + "maxfee_kb": 10000000, + "minfee_kb": 1000, + "signed_message_header": "Bitcoin Signed Message:\n", + "hash_genesis_block": "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943", + "xprv_magic": "04358394", + "xpub_magic": "043587cf", + "xpub_magic_segwit_p2sh": "044a5262", + "bech32_prefix": "tb", + "cashaddr_prefix": null, + "bip44": 1, + "segwit": true, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 546, + "blocktime_minutes": 10, + "firmware": "stable", + "address_prefix": "bitcoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "https://testnet-bitcore1.trezor.io", + "https://testnet-bitcore2.trezor.io" + ] +}, +{ + "coin_name": "Bcash", + "coin_shortcut": "BCH", + "coin_label": "Bitcoin Cash", + "curve_name": "secp256k1", + "address_type": 0, + "address_type_p2sh": 5, + "maxfee_kb": 500000, + "minfee_kb": 1000, + "signed_message_header": "Bitcoin Signed Message:\n", + "hash_genesis_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", + "xprv_magic": "0488ade4", + "xpub_magic": "0488b21e", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": "bitcoincash", + "bip44": 145, + "segwit": false, + "decred": false, + "forkid": 0, + "force_bip143": true, + "default_fee_b": { + "Low": 10, + "Economy": 70, + "Normal": 140, + "High": 200 + }, + "dust_limit": 546, + "blocktime_minutes": 10, + "firmware": "stable", + "address_prefix": "bitcoincash:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "https://bch-bitcore2.trezor.io" + ] +}, +{ + "coin_name": "Bcash Testnet", + "coin_shortcut": "TBCH", + "coin_label": "Bitcoin Cash Testnet", + "curve_name": "secp256k1", + "address_type": 111, + "address_type_p2sh": 196, + "maxfee_kb": 10000000, + "minfee_kb": 1000, + "signed_message_header": "Bitcoin Signed Message:\n", + "hash_genesis_block": "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943", + "xprv_magic": "04358394", + "xpub_magic": "043587cf", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": "bchtest", + "bip44": 1, + "segwit": false, + "decred": false, + "forkid": 0, + "force_bip143": true, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 546, + "blocktime_minutes": 10, + "firmware": "debug", + "address_prefix": "bitcoincash:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [] +}, +{ + "coin_name": "Namecoin", + "coin_shortcut": "NMC", + "coin_label": "Namecoin", + "curve_name": "secp256k1", + "address_type": 52, + "address_type_p2sh": 5, + "maxfee_kb": 10000000, + "minfee_kb": 1000, + "signed_message_header": "Namecoin Signed Message:\n", + "hash_genesis_block": "000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770", + "xprv_magic": "019d9cfe", + "xpub_magic": "019da462", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": null, + "bip44": 7, + "segwit": false, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 2940, + "blocktime_minutes": 10, + "firmware": "stable", + "address_prefix": "namecoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [] +}, +{ + "coin_name": "Litecoin", + "coin_shortcut": "LTC", + "coin_label": "Litecoin", + "curve_name": "secp256k1", + "address_type": 48, + "address_type_p2sh": 50, + "maxfee_kb": 40000000, + "minfee_kb": 100000, + "signed_message_header": "Litecoin Signed Message:\n", + "hash_genesis_block": "12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2", + "xprv_magic": "019d9cfe", + "xpub_magic": "019da462", + "xpub_magic_segwit_p2sh": "01b26ef6", + "bech32_prefix": "ltc", + "cashaddr_prefix": null, + "bip44": 2, + "segwit": true, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 1000 + }, + "dust_limit": 54600, + "blocktime_minutes": 2.5, + "firmware": "stable", + "address_prefix": "litecoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "https://ltc-bitcore3.trezor.io" + ] +}, +{ + "coin_name": "Dogecoin", + "coin_shortcut": "DOGE", + "coin_label": "Dogecoin", + "curve_name": "secp256k1", + "address_type": 30, + "address_type_p2sh": 22, + "maxfee_kb": 1000000000, + "minfee_kb": 1000, + "signed_message_header": "Dogecoin Signed Message:\n", + "hash_genesis_block": "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691", + "xprv_magic": "02fac398", + "xpub_magic": "02facafd", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": null, + "bip44": 3, + "segwit": false, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 10000000, + "blocktime_minutes": 1, + "firmware": "stable", + "address_prefix": "dogecoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [] +}, +{ + "coin_name": "Dash", + "coin_shortcut": "DASH", + "coin_label": "Dash", + "curve_name": "secp256k1", + "address_type": 76, + "address_type_p2sh": 16, + "maxfee_kb": 100000, + "minfee_kb": 10000, + "signed_message_header": "DarkCoin Signed Message:\n", + "hash_genesis_block": "00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6", + "xprv_magic": "02fe52f8", + "xpub_magic": "02fe52cc", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": null, + "bip44": 5, + "segwit": false, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 5460, + "blocktime_minutes": 2.5, + "firmware": "stable", + "address_prefix": "dash:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "https://dash-bitcore1.trezor.io", + "https://dash-bitcore3.trezor.io" + ] +}, +{ + "coin_name": "Zcash", + "coin_shortcut": "ZEC", + "coin_label": "Zcash", + "curve_name": "secp256k1", + "address_type": 7352, + "address_type_p2sh": 7357, + "maxfee_kb": 1000000, + "minfee_kb": 1000, + "signed_message_header": "Zcash Signed Message:\n", + "hash_genesis_block": "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08", + "xprv_magic": "0488ade4", + "xpub_magic": "0488b21e", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": null, + "bip44": 133, + "segwit": false, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 546, + "blocktime_minutes": 2.5, + "firmware": "stable", + "address_prefix": "zcash:", + "min_address_length": 35, + "max_address_length": 95, + "bitcore": [ + "https://zec-bitcore1.trezor.io/" + ] +}, +{ + "coin_name": "Zcash Testnet", + "coin_shortcut": "TAZ", + "coin_label": "Zcash Testnet", + "curve_name": "secp256k1", + "address_type": 7461, + "address_type_p2sh": 7354, + "maxfee_kb": 10000000, + "minfee_kb": 1000, + "signed_message_header": "Zcash Signed Message:\n", + "hash_genesis_block": "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38", + "xprv_magic": "04358394", + "xpub_magic": "043587cf", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": null, + "bip44": 1, + "segwit": false, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 546, + "blocktime_minutes": 2.5, + "firmware": "debug", + "address_prefix": "zcash:", + "min_address_length": 35, + "max_address_length": 95, + "bitcore": [] +}, +{ + "coin_name": "Bitcoin Gold", + "coin_shortcut": "BTG", + "coin_label": "Bitcoin Gold", + "curve_name": "secp256k1", + "address_type": 38, + "address_type_p2sh": 23, + "maxfee_kb": 500000, + "minfee_kb": 1000, + "signed_message_header": "Bitcoin Gold Signed Message:\n", + "hash_genesis_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", + "xprv_magic": "0488ade4", + "xpub_magic": "0488b21e", + "xpub_magic_segwit_p2sh": "049d7cb2", + "bech32_prefix": "btg", + "cashaddr_prefix": null, + "bip44": 156, + "segwit": true, + "decred": false, + "forkid": 79, + "force_bip143": true, + "default_fee_b": { + "Low": 10, + "Economy": 70, + "Normal": 140, + "High": 200 + }, + "dust_limit": 546, + "blocktime_minutes": 10, + "firmware": "stable", + "address_prefix": "bitcoingold:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "https://btg-bitcore2.trezor.io" + ] +}, +{ + "coin_name": "DigiByte", + "coin_shortcut": "DGB", + "coin_label": "DigiByte", + "curve_name": "secp256k1", + "address_type": 30, + "address_type_p2sh": 5, + "maxfee_kb": 500000, + "minfee_kb": 1000, + "signed_message_header": "DigiByte Signed Message:\n", + "hash_genesis_block": "7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496", + "xprv_magic": "0488ade4", + "xpub_magic": "0488b21e", + "xpub_magic_segwit_p2sh": "049d7cb2", + "bech32_prefix": "dgb", + "cashaddr_prefix": null, + "bip44": 20, + "segwit": true, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Low": 10, + "Economy": 70, + "Normal": 140, + "High": 200 + }, + "dust_limit": 546, + "blocktime_minutes": 0.25, + "firmware": "stable", + "address_prefix": "digibyte:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [] +}, +{ + "coin_name": "Monacoin", + "coin_shortcut": "MONA", + "coin_label": "Monacoin", + "curve_name": "secp256k1", + "address_type": 50, + "address_type_p2sh": 55, + "maxfee_kb": 5000000, + "minfee_kb": 100000, + "signed_message_header": "Monacoin Signed Message:\n", + "hash_genesis_block": "ff9f1c0116d19de7c9963845e129f9ed1bfc0b376eb54fd7afa42e0d418c8bb6", + "xpub_magic": "0488b21e", + "xprv_magic": "0488ade4", + "xpub_magic_segwit_p2sh": "049d7cb2", + "bech32_prefix": "mona", + "cashaddr_prefix": null, + "bip44": 22, + "segwit": true, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 100000 + }, + "dust_limit": 54600, + "blocktime_minutes": 1.5, + "firmware": "stable", + "address_prefix": "monacoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "https://mona.chainsight.info" + ] +}, +{ + "coin_name": "Fujicoin", + "coin_shortcut": "FJC", + "coin_label": "Fujicoin", + "curve_name": "secp256k1", + "address_type": 36, + "address_type_p2sh": 16, + "maxfee_kb": 1000000, + "minfee_kb": 100000, + "signed_message_header": "FujiCoin Signed Message:\n", + "hash_genesis_block": "adb6d9cfd74075e7f91608add4bd2a2ea636f70856183086842667a1597714a0", + "xpub_magic": "0488b21e", + "xprv_magic": "0488ade4", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": null, + "bip44": 75, + "segwit": false, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 100000 + }, + "dust_limit": 100000, + "blocktime_minutes": 1.0, + "firmware": "stable", + "address_prefix": "fujicoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [ + "http://explorer.fujicoin.org/" + ] +}, +{ + "coin_name": "Vertcoin", + "coin_shortcut": "VTC", + "coin_label": "Vertcoin", + "curve_name": "secp256k1", + "address_type": 71, + "address_type_p2sh": 5, + "maxfee_kb": 40000000, + "minfee_kb": 100000, + "signed_message_header": "Vertcoin Signed Message:\n", + "hash_genesis_block": "4d96a915f49d40b1e5c2844d1ee2dccb90013a990ccea12c492d22110489f0c4", + "xprv_magic": "0488ade4", + "xpub_magic": "0488b21e", + "xpub_magic_segwit_p2sh": "049d7cb2", + "bech32_prefix": "vtc", + "cashaddr_prefix": null, + "bip44": 28, + "segwit": true, + "decred": false, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 1000 + }, + "dust_limit": 54600, + "blocktime_minutes": 2.5, + "firmware": "stable", + "address_prefix": "vertcoin:", + "min_address_length": 27, + "max_address_length": 34, + "bitcore": [] +}, +{ + "coin_name": "Decred Testnet", + "coin_shortcut": "TDCR", + "coin_label": "Testnet", + "curve_name": "secp256k1_decred", + "address_type": 3873, + "address_type_p2sh": 3836, + "maxfee_kb": 10000000, + "minfee_kb": 1000, + "signed_message_header": "Decred Signed Message:\n", + "hash_genesis_block": "4261602a9d07d80ad47621a64ba6a07754902e496777edc4ff581946bd7bc29c", + "xprv_magic": "04358397", + "xpub_magic": "043587d1", + "xpub_magic_segwit_p2sh": null, + "bech32_prefix": null, + "cashaddr_prefix": null, + "bip44": 1, + "segwit": false, + "decred": true, + "forkid": null, + "force_bip143": false, + "default_fee_b": { + "Normal": 10 + }, + "dust_limit": 546, + "blocktime_minutes": 10, + "firmware": "debug", + "address_prefix": "bitcoin:", + "min_address_length": 35, + "max_address_length": 35, + "bitcore": [] +} +] diff --git a/hardware-wallet/firmware/vendor/trezor-common/ethereum_tokens-gen.py b/hardware-wallet/firmware/vendor/trezor-common/ethereum_tokens-gen.py new file mode 100755 index 00000000..36958deb --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/ethereum_tokens-gen.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +import sys +import requests + + +def get_tokens(ipfs_hash, chain): + URL = 'https://gateway.ipfs.io/ipfs/%s/%s.json' % (ipfs_hash, chain) + r = requests.get(URL) + return r.json() + + +def print_tokens(ipfs_hash, chain, chain_id, python=False): + tokens = get_tokens(ipfs_hash, chain) + if len(tokens) > 0: + if python: + print(' # %s' % chain) + else: + print('\t// %s' % chain) + for t in sorted(tokens, key=lambda x: x['symbol'].upper()): + address, name, symbol, decimal = t['address'], t['name'], t['symbol'], int(t['decimals']) + address = '\\x'.join([address[i:i + 2] for i in range(0, len(address), 2)])[2:].lower() + if python: + print(" (%d, b'%s', '%s', %d), # %s" % (chain_id, address, symbol, decimal, name)) + else: + print('\t{%2d, "%s", " %s", %d}, // %s' % (chain_id, address, symbol, decimal, name)) + + return len(tokens) + + +# disabled are networks with no tokens defined in ethereum-lists/tokens repo + +networks = [ + ('eth', 1), + # ('exp', 2), + # ('rop', 3), + ('rin', 4), + ('ubq', 8), + # ('rsk', 30), + ('kov', 42), + ('etc', 61), +] + + +def generate_c(ipfs_hash): + count = 0 + for s, i in networks: + count += print_tokens(ipfs_hash, s, i) + print('-' * 32) + print('#define TOKENS_COUNT %d' % count) + + +def generate_python(ipfs_hash): + print('tokens = [') + for s, i in networks: + print_tokens(ipfs_hash, s, i, python=True) + print(']') + + +if __name__ == '__main__': + if len(sys.argv) < 2: + print('Usage: ethereum_tokens-gen.py ipfs_hash [--python]') + sys.exit(1) + ipfs_hash = sys.argv[1] + if len(sys.argv) > 2 and sys.argv[2] == '--python': + generate_python(ipfs_hash) + else: + generate_c(ipfs_hash) diff --git a/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.h b/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.h new file mode 100644 index 00000000..ebd7d5b3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.h @@ -0,0 +1,6 @@ +// TREZORv1 production public keys +"\x04\xd5\x71\xb7\xf1\x48\xc5\xe4\x23\x2c\x38\x14\xf7\x77\xd8\xfa\xea\xf1\xa8\x42\x16\xc7\x8d\x56\x9b\x71\x04\x1f\xfc\x76\x8a\x5b\x2d\x81\x0f\xc3\xbb\x13\x4d\xd0\x26\xb5\x7e\x65\x00\x52\x75\xae\xde\xf4\x3e\x15\x5f\x48\xfc\x11\xa3\x2e\xc7\x90\xa9\x33\x12\xbd\x58", +"\x04\x63\x27\x9c\x0c\x08\x66\xe5\x0c\x05\xc7\x99\xd3\x2b\xd6\xba\xb0\x18\x8b\x6d\xe0\x65\x36\xd1\x10\x9d\x2e\xd9\xce\x76\xcb\x33\x5c\x49\x0e\x55\xae\xe1\x0c\xc9\x01\x21\x51\x32\xe8\x53\x09\x7d\x54\x32\xed\xa0\x6b\x79\x20\x73\xbd\x77\x40\xc9\x4c\xe4\x51\x6c\xb1", +"\x04\x43\xae\xdb\xb6\xf7\xe7\x1c\x56\x3f\x8e\xd2\xef\x64\xec\x99\x81\x48\x25\x19\xe7\xef\x4f\x4a\xa9\x8b\x27\x85\x4e\x8c\x49\x12\x6d\x49\x56\xd3\x00\xab\x45\xfd\xc3\x4c\xd2\x6b\xc8\x71\x0d\xe0\xa3\x1d\xbd\xf6\xde\x74\x35\xfd\x0b\x49\x2b\xe7\x0a\xc7\x5f\xde\x58", +"\x04\x87\x7c\x39\xfd\x7c\x62\x23\x7e\x03\x82\x35\xe9\xc0\x75\xda\xb2\x61\x63\x0f\x78\xee\xb8\xed\xb9\x24\x87\x15\x9f\xff\xed\xfd\xf6\x04\x6c\x6f\x8b\x88\x1f\xa4\x07\xc4\xa4\xce\x6c\x28\xde\x0b\x19\xc1\xf4\xe2\x9f\x1f\xcb\xc5\xa5\x8f\xfd\x14\x32\xa3\xe0\x93\x8a", +"\x04\x73\x84\xc5\x1a\xe8\x1a\xdd\x0a\x52\x3a\xdb\xb1\x86\xc9\x1b\x90\x6f\xfb\x64\xc2\xc7\x65\x80\x2b\xf2\x6d\xbd\x13\xbd\xf1\x2c\x31\x9e\x80\xc2\x21\x3a\x13\x6c\x8e\xe0\x3d\x78\x74\xfd\x22\xb7\x0d\x68\xe7\xde\xe4\x69\xde\xcf\xbb\xb5\x10\xee\x9a\x46\x0c\xda\x45", diff --git a/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.pem b/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.pem new file mode 100644 index 00000000..5ca09ff4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.pem @@ -0,0 +1,24 @@ +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1XG38UjF5CMsOBT3d9j66vGoQhbHjVab +cQQf/HaKWy2BD8O7E03QJrV+ZQBSda7e9D4VX0j8EaMux5CpMxK9WA== +-----END PUBLIC KEY----- + +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYyecDAhm5QwFx5nTK9a6sBiLbeBlNtEQ +nS7ZznbLM1xJDlWu4QzJASFRMuhTCX1UMu2ga3kgc713QMlM5FFssQ== +-----END PUBLIC KEY----- + +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEQ67btvfnHFY/jtLvZOyZgUglGefvT0qp +iyeFToxJEm1JVtMAq0X9w0zSa8hxDeCjHb323nQ1/QtJK+cKx1/eWA== +-----END PUBLIC KEY----- + +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEh3w5/XxiI34DgjXpwHXasmFjD3juuO25 +JIcVn//t/fYEbG+LiB+kB8Skzmwo3gsZwfTinx/LxaWP/RQyo+CTig== +-----END PUBLIC KEY----- + +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEc4TFGuga3QpSOtuxhskbkG/7ZMLHZYAr +8m29E73xLDGegMIhOhNsjuA9eHT9IrcNaOfe5Gnez7u1EO6aRgzaRQ== +-----END PUBLIC KEY----- diff --git a/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.txt b/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.txt new file mode 100644 index 00000000..fb63d914 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/keys/public_trezor1.txt @@ -0,0 +1,5 @@ +04d571b7f148c5e4232c3814f777d8faeaf1a84216c78d569b71041ffc768a5b2d810fc3bb134dd026b57e65005275aedef43e155f48fc11a32ec790a93312bd58 +0463279c0c0866e50c05c799d32bd6bab0188b6de06536d1109d2ed9ce76cb335c490e55aee10cc901215132e853097d5432eda06b792073bd7740c94ce4516cb1 +0443aedbb6f7e71c563f8ed2ef64ec9981482519e7ef4f4aa98b27854e8c49126d4956d300ab45fdc34cd26bc8710de0a31dbdf6de7435fd0b492be70ac75fde58 +04877c39fd7c62237e038235e9c075dab261630f78eeb8edb92487159fffedfdf6046c6f8b881fa407c4a4ce6c28de0b19c1f4e29f1fcbc5a58ffd1432a3e0938a +047384c51ae81add0a523adbb186c91b906ffb64c2c765802bf26dbd13bdf12c319e80c2213a136c8ee03d7874fd22b70d68e7dee469decfbbb510ee9a460cda45 diff --git a/hardware-wallet/firmware/vendor/trezor-common/keys/sample.h b/hardware-wallet/firmware/vendor/trezor-common/keys/sample.h new file mode 100644 index 00000000..1518d4f3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/keys/sample.h @@ -0,0 +1,2 @@ +// sample public key "correct horse battery staple" +"\x04\x78\xd4\x30\x27\x4f\x8c\x5e\xc1\x32\x13\x38\x15\x1e\x9f\x27\xf4\xc6\x76\xa0\x08\xbd\xf8\x63\x8d\x07\xc0\xb6\xbe\x9a\xb3\x5c\x71\xa1\x51\x80\x63\x24\x3a\xcd\x4d\xfe\x96\xb6\x6e\x3f\x2e\xc8\x01\x3c\x8e\x07\x2c\xd0\x9b\x38\x34\xa1\x9f\x81\xf6\x59\xcc\x34\x55" diff --git a/hardware-wallet/firmware/vendor/trezor-common/keys/sample.pem b/hardware-wallet/firmware/vendor/trezor-common/keys/sample.pem new file mode 100644 index 00000000..08b0a588 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/keys/sample.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAENEoHRLyHw1AM5jl0pbUNgXHFldzn1jWT +/tGrlePY/vfKVVc2QM2pz0fbYUn4WEZC8DDfQ3XEhvKnsyOotsY7QQ== +-----END PUBLIC KEY----- diff --git a/hardware-wallet/firmware/vendor/trezor-common/keys/sample.txt b/hardware-wallet/firmware/vendor/trezor-common/keys/sample.txt new file mode 100644 index 00000000..53fd380d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/keys/sample.txt @@ -0,0 +1 @@ +0478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455 diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/.gitignore b/hardware-wallet/firmware/vendor/trezor-common/protob/.gitignore new file mode 100644 index 00000000..0a5bea8f --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/.gitignore @@ -0,0 +1 @@ +*.pb diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/Makefile b/hardware-wallet/firmware/vendor/trezor-common/protob/Makefile new file mode 100644 index 00000000..9956d448 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/Makefile @@ -0,0 +1,7 @@ +check: config.pb messages.pb storage.pb types.pb + +%.pb: %.proto + protoc -I/usr/include -I. $< -o $@ + +clean: + rm -f *.pb diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/config.proto b/hardware-wallet/firmware/vendor/trezor-common/protob/config.proto new file mode 100644 index 00000000..fe44a0dc --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/config.proto @@ -0,0 +1,32 @@ +syntax = "proto2"; + +/** + * Configuration format for TREZOR plugin + */ + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorConfig"; + +import "google/protobuf/descriptor.proto"; + +/** + * Device Descriptor used in Configuration + */ +message DeviceDescriptor { + optional uint32 vendor_id = 1; // USB vendor ID + optional uint32 product_id = 2; // USB product ID + optional string serial_number = 3; // USB serial number + optional string path = 4; // USB device path +} + +/** + * Plugin Configuration + */ +message Configuration { + repeated string whitelist_urls = 1; // allowed URLs for plugin + repeated string blacklist_urls = 2; // forbidden URLs for plugin + required google.protobuf.FileDescriptorSet wire_protocol = 3; // compiled specification of write protocol (serialized using "protoc -o") + repeated DeviceDescriptor known_devices = 4; // descriptors of allowed devices + optional uint32 valid_until = 5; // expiration timestamp +} diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto b/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto new file mode 100644 index 00000000..939dcdca --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto @@ -0,0 +1,1082 @@ +syntax = "proto2"; + +/** + * Messages for TREZOR communication + */ + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessage"; + +import "types.proto"; + +/** + * Mapping between Trezor wire identifier (uint) and a protobuf message + */ +enum MessageType { + MessageType_Initialize = 0 [(wire_in) = true]; + MessageType_Ping = 1 [(wire_in) = true]; + MessageType_Success = 2 [(wire_out) = true]; + MessageType_Failure = 3 [(wire_out) = true]; + MessageType_ChangePin = 4 [(wire_in) = true]; + MessageType_WipeDevice = 5 [(wire_in) = true]; + MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true]; + MessageType_GetEntropy = 9 [(wire_in) = true]; + MessageType_Entropy = 10 [(wire_out) = true]; + MessageType_GetPublicKey = 11 [(wire_in) = true]; + MessageType_PublicKey = 12 [(wire_out) = true]; + MessageType_LoadDevice = 13 [(wire_in) = true]; + MessageType_ResetDevice = 14 [(wire_in) = true]; + MessageType_SignTx = 15 [(wire_in) = true]; + MessageType_SimpleSignTx = 16 [(wire_in) = true, deprecated = true]; + MessageType_Features = 17 [(wire_out) = true]; + MessageType_PinMatrixRequest = 18 [(wire_out) = true]; + MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true]; + MessageType_Cancel = 20 [(wire_in) = true]; + MessageType_TxRequest = 21 [(wire_out) = true]; + MessageType_TxAck = 22 [(wire_in) = true]; + MessageType_CipherKeyValue = 23 [(wire_in) = true]; + MessageType_ClearSession = 24 [(wire_in) = true]; + MessageType_ApplySettings = 25 [(wire_in) = true]; + MessageType_ButtonRequest = 26 [(wire_out) = true]; + MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true]; + MessageType_ApplyFlags = 28 [(wire_in) = true]; + MessageType_GetAddress = 29 [(wire_in) = true]; + MessageType_Address = 30 [(wire_out) = true]; + MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_BackupDevice = 34 [(wire_in) = true]; + MessageType_EntropyRequest = 35 [(wire_out) = true]; + MessageType_EntropyAck = 36 [(wire_in) = true]; + MessageType_SignMessage = 38 [(wire_in) = true]; + MessageType_VerifyMessage = 39 [(wire_in) = true]; + MessageType_MessageSignature = 40 [(wire_out) = true]; + MessageType_PassphraseRequest = 41 [(wire_out) = true]; + MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true]; + MessageType_PassphraseStateRequest = 77 [(wire_out) = true]; + MessageType_PassphraseStateAck = 78 [(wire_in) = true, (wire_tiny) = true]; + MessageType_EstimateTxSize = 43 [(wire_in) = true, deprecated = true]; + MessageType_TxSize = 44 [(wire_out) = true, deprecated = true]; + MessageType_RecoveryDevice = 45 [(wire_in) = true]; + MessageType_WordRequest = 46 [(wire_out) = true]; + MessageType_WordAck = 47 [(wire_in) = true]; + MessageType_CipheredKeyValue = 48 [(wire_out) = true]; + MessageType_EncryptMessage = 49 [(wire_in) = true, deprecated = true]; + MessageType_EncryptedMessage = 50 [(wire_out) = true, deprecated = true]; + MessageType_DecryptMessage = 51 [(wire_in) = true, deprecated = true]; + MessageType_DecryptedMessage = 52 [(wire_out) = true, deprecated = true]; + MessageType_SignIdentity = 53 [(wire_in) = true]; + MessageType_SignedIdentity = 54 [(wire_out) = true]; + MessageType_GetFeatures = 55 [(wire_in) = true]; + MessageType_EthereumGetAddress = 56 [(wire_in) = true]; + MessageType_EthereumAddress = 57 [(wire_out) = true]; + MessageType_EthereumSignTx = 58 [(wire_in) = true]; + MessageType_EthereumTxRequest = 59 [(wire_out) = true]; + MessageType_EthereumTxAck = 60 [(wire_in) = true]; + MessageType_GetECDHSessionKey = 61 [(wire_in) = true]; + MessageType_ECDHSessionKey = 62 [(wire_out) = true]; + MessageType_SetU2FCounter = 63 [(wire_in) = true]; + MessageType_EthereumSignMessage = 64 [(wire_in) = true]; + MessageType_EthereumVerifyMessage = 65 [(wire_in) = true]; + MessageType_EthereumMessageSignature = 66 [(wire_out) = true]; + MessageType_NEMGetAddress = 67 [(wire_in) = true]; + MessageType_NEMAddress = 68 [(wire_out) = true]; + MessageType_NEMSignTx = 69 [(wire_in) = true]; + MessageType_NEMSignedTx = 70 [(wire_out) = true]; + MessageType_CosiCommit = 71 [(wire_in) = true]; + MessageType_CosiCommitment = 72 [(wire_out) = true]; + MessageType_CosiSign = 73 [(wire_in) = true]; + MessageType_CosiSignature = 74 [(wire_out) = true]; + MessageType_NEMDecryptMessage = 75 [(wire_in) = true]; + MessageType_NEMDecryptedMessage = 76 [(wire_out) = true]; + MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true]; + MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true]; + MessageType_DebugLinkState = 102 [(wire_debug_out) = true]; + MessageType_DebugLinkStop = 103 [(wire_debug_in) = true]; + MessageType_DebugLinkLog = 104 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true]; + MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; + MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; + MessageType_SkycoinAddress = 114 [(wire_in) = true]; + MessageType_SkycoinCheckMessageSignature = 115 [(wire_in) = true]; + MessageType_SkycoinSignMessage = 116 [(wire_in) = true]; +} + +//////////////////// +// Basic messages // +//////////////////// + +/** + * Request: Reset device to default state and ask for device details + * @next Features + */ +message Initialize { + optional bytes state = 1; // assumed device state, clear session if set and different +} + +/** + * Request: Ask for device details (no device reset) + * @next Features + */ +message GetFeatures { +} + +/** + * Response: Reports various information about the device + * @prev Initialize + * @prev GetFeatures + */ +message Features { + optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" + optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 + optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 + optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 + optional bool bootloader_mode = 5; // is device in bootloader mode? + optional string device_id = 6; // device's unique identifier + optional bool pin_protection = 7; // is device protected by PIN? + optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? + optional string language = 9; // device language + optional string label = 10; // device description label + repeated CoinType coins = 11; // supported coins + optional bool initialized = 12; // does device contain seed? + optional bytes revision = 13; // SCM revision of firmware + optional bytes bootloader_hash = 14; // hash of the bootloader + optional bool imported = 15; // was storage imported from an external source? + optional bool pin_cached = 16; // is PIN already cached in session? + optional bool passphrase_cached = 17; // is passphrase already cached in session? + optional bool firmware_present = 18; // is valid firmware loaded? + optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) + optional uint32 flags = 20; // device flags (equals to Storage.flags) + optional string model = 21; // device hardware model + optional uint32 fw_major = 22; // reported firmware version if in bootloader mode + optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode + optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode + optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode + optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash) +} + +/** + * Request: clear session (removes cached PIN, passphrase, etc). + * @next Success + */ +message ClearSession { +} + +/** + * Request: change language and/or label of the device + * @next Success + * @next Failure + * @next ButtonRequest + * @next PinMatrixRequest + */ +message ApplySettings { + optional string language = 1; + optional string label = 2; + optional bool use_passphrase = 3; + optional bytes homescreen = 4; +} + +/** + * Request: set flags of the device + * @next Success + * @next Failure + */ +message ApplyFlags { + optional uint32 flags = 1; // bitmask, can only set bits, not unset +} + +/** + * Request: Starts workflow for setting/changing/removing the PIN + * @next ButtonRequest + * @next PinMatrixRequest + */ +message ChangePin { + optional bool remove = 1; // is PIN removal requested? +} + +/** + * Request: Generate a Skycoin or a Bitcoin address from a seed, device sends back the address in a Success message + * @next Success + */ +message SkycoinAddress { + required string seed = 1; // seed used to generate address + optional SkycoinAddressType address_type = 2; +} + + +/** + * Request: Check a message signature matches the given address. + * @next Success + */ +message SkycoinCheckMessageSignature { + required string address = 1; //address that was supposedly used to produce the signature + required string message = 2; //message that was signed + required string signature = 3; //electronic signature of the message +} + +/** + * Request: Sign a message digest using the given secret key. + * @next Success + */ +message SkycoinSignMessage { + required string secretKey = 1; //private address used to produce signature + required string message = 2; //message that we want to sign +} +/** + * Request: Test if the device is alive, device sends back the message in Success response + * @next Success + */ +message Ping { + optional string message = 1; // message to send back in Success message + optional bool button_protection = 2; // ask for button press + optional bool pin_protection = 3; // ask for PIN if set in device + optional bool passphrase_protection = 4; // ask for passphrase if set in device +} + +/** + * Response: Success of the previous request + */ +message Success { + optional string message = 1; // human readable description of action or request-specific payload +} + +/** + * Response: Failure of the previous request + */ +message Failure { + optional FailureType code = 1; // computer-readable definition of the error state + optional string message = 2; // human-readable message of the error state +} + +/** + * Response: Device is waiting for HW button press. + * @next ButtonAck + * @next Cancel + */ +message ButtonRequest { + optional ButtonRequestType code = 1; + optional string data = 2; +} + +/** + * Request: Computer agrees to wait for HW button press + * @prev ButtonRequest + */ +message ButtonAck { +} + +/** + * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme + * @next PinMatrixAck + * @next Cancel + */ +message PinMatrixRequest { + optional PinMatrixRequestType type = 1; +} + +/** + * Request: Computer responds with encoded PIN + * @prev PinMatrixRequest + */ +message PinMatrixAck { + required string pin = 1; // matrix encoded PIN entered by user +} + +/** + * Request: Abort last operation that required user interaction + * @prev ButtonRequest + * @prev PinMatrixRequest + * @prev PassphraseRequest + */ +message Cancel { +} + +/** + * Response: Device awaits encryption passphrase + * @next PassphraseAck + * @next Cancel + */ +message PassphraseRequest { + optional bool on_device = 1; // passphrase is being entered on the device +} + +/** + * Request: Send passphrase back + * @prev PassphraseRequest + * @next PassphraseStateRequest + */ +message PassphraseAck { + optional string passphrase = 1; + optional bytes state = 2; // expected device state +} + +/** + * @prev PassphraseAck + * @next PassphraseStateAck + */ +message PassphraseStateRequest { + optional bytes state = 1; // actual device state +} + +/** + * @prev PassphraseStateRequest + */ +message PassphraseStateAck { +} + +/** + * Request: Request a sample of random data generated by hardware RNG. May be used for testing. + * @next ButtonRequest + * @next Entropy + * @next Failure + */ +message GetEntropy { + required uint32 size = 1; // size of requested entropy +} + +/** + * Response: Reply with random data generated by internal RNG + * @prev GetEntropy + */ +message Entropy { + required bytes entropy = 1; // stream of random generated bytes +} + +/** + * Request: Ask device for public key corresponding to address_n path + * @next PassphraseRequest + * @next PublicKey + * @next Failure + */ +message GetPublicKey { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string ecdsa_curve_name = 2; // ECDSA curve name to use + optional bool show_display = 3; // optionally show on display before sending the result + optional string coin_name = 4 [default='Bitcoin']; +} + +/** + * Response: Contains public key derived from device private seed + * @prev GetPublicKey + */ +message PublicKey { + required HDNodeType node = 1; // BIP32 public node + optional string xpub = 2; // serialized form of public node +} + +/** + * Request: Ask device for address corresponding to address_n path + * @next PassphraseRequest + * @next Address + * @next Failure + */ +message GetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string coin_name = 2 [default='Bitcoin']; + optional bool show_display = 3 ; // optionally show on display before sending the result + optional MultisigRedeemScriptType multisig = 4; // filled if we are showing a multisig address + optional InputScriptType script_type = 5 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) +} + +/** + * Request: Ask device for Ethereum address corresponding to address_n path + * @next PassphraseRequest + * @next EthereumAddress + * @next Failure + */ +message EthereumGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // optionally show on display before sending the result +} + +/** + * Response: Contains address derived from device private seed + * @prev GetAddress + */ +message Address { + required string address = 1; // Coin address in Base58 encoding +} + +/** + * Response: Contains an Ethereum address derived from device private seed + * @prev EthereumGetAddress + */ +message EthereumAddress { + required bytes address = 1; // Coin address as an Ethereum 160 bit hash +} + +/** + * Request: Request device to wipe all sensitive data and settings + * @next ButtonRequest + */ +message WipeDevice { +} + +/** + * Request: Load seed and related internal settings from the computer + * @next ButtonRequest + * @next Success + * @next Failure + */ +message LoadDevice { + optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) + optional HDNodeType node = 2; // BIP-32 node + optional string pin = 3; // set PIN protection + optional bool passphrase_protection = 4; // enable master node encryption using passphrase + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum + optional uint32 u2f_counter = 8; // U2F counter +} + +/** + * Request: Ask device to do initialization involving user interaction + * @next EntropyRequest + * @next Failure + */ +message ResetDevice { + optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy + optional uint32 strength = 2 [default=256]; // strength of seed in bits + optional bool passphrase_protection = 3; // enable master node encryption using passphrase + optional bool pin_protection = 4; // enable PIN protection + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional uint32 u2f_counter = 7; // U2F counter + optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow +} + +/** + * Request: Perform backup of the device seed if not backed up using ResetDevice + * @next ButtonRequest + */ +message BackupDevice { +} + +/** + * Response: Ask for additional entropy from host computer + * @prev ResetDevice + * @next EntropyAck + */ +message EntropyRequest { +} + +/** + * Request: Provide additional entropy for seed generation function + * @prev EntropyRequest + * @next ButtonRequest + */ +message EntropyAck { + optional bytes entropy = 1; // 256 bits (32 bytes) of random data +} + +/** + * Request: Start recovery workflow asking user for specific words of mnemonic + * Used to recovery device safely even on untrusted computer. + * @next WordRequest + */ +message RecoveryDevice { + optional uint32 word_count = 1; // number of words in BIP-39 mnemonic + optional bool passphrase_protection = 2; // enable master node encryption using passphrase + optional bool pin_protection = 3; // enable PIN protection + optional string language = 4 [default='english']; // device language + optional string label = 5; // device label + optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process + // 7 reserved for unused recovery method + optional uint32 type = 8; // supported recovery type (see RecoveryType) + optional uint32 u2f_counter = 9; // U2F counter + optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) +} + +/** + * Response: Device is waiting for user to enter word of the mnemonic + * Its position is shown only on device's internal display. + * @prev RecoveryDevice + * @prev WordAck + */ +message WordRequest { + optional WordRequestType type = 1; +} + +/** + * Request: Computer replies with word from the mnemonic + * @prev WordRequest + * @next WordRequest + * @next Success + * @next Failure + */ +message WordAck { + required string word = 1; // one word of mnemonic on asked position +} + +////////////////////////////// +// Message signing messages // +////////////////////////////// + +/** + * Request: Ask device to sign message + * @next MessageSignature + * @next Failure + */ +message SignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + required bytes message = 2; // message to be signed + optional string coin_name = 3 [default='Bitcoin']; // coin to use for signing + optional InputScriptType script_type = 4 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) +} + +/** + * Request: Ask device to verify message + * @next Success + * @next Failure + */ +message VerifyMessage { + optional string address = 1; // address to verify + optional bytes signature = 2; // signature to verify + optional bytes message = 3; // message to verify + optional string coin_name = 4 [default='Bitcoin']; // coin to use for verifying +} + +/** + * Response: Signed message + * @prev SignMessage + */ +message MessageSignature { + optional string address = 1; // address used to sign the message + optional bytes signature = 2; // signature of the message +} + +/////////////////////////// +// Encryption/decryption // +/////////////////////////// + +/** + * Request: Ask device to encrypt message + * @next EncryptedMessage + * @next Failure + */ +message EncryptMessage { + optional bytes pubkey = 1; // public key + optional bytes message = 2; // message to encrypt + optional bool display_only = 3; // show just on display? (don't send back via wire) + repeated uint32 address_n = 4; // BIP-32 path to derive the signing key from master node + optional string coin_name = 5 [default='Bitcoin']; // coin to use for signing +} + +/** + * Response: Encrypted message + * @prev EncryptMessage + */ +message EncryptedMessage { + optional bytes nonce = 1; // nonce used during encryption + optional bytes message = 2; // encrypted message + optional bytes hmac = 3; // message hmac +} + +/** + * Request: Ask device to decrypt message + * @next Success + * @next Failure + */ +message DecryptMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the decryption key from master node + optional bytes nonce = 2; // nonce used during encryption + optional bytes message = 3; // message to decrypt + optional bytes hmac = 4; // message hmac +} + +/** + * Response: Decrypted message + * @prev DecryptedMessage + */ +message DecryptedMessage { + optional bytes message = 1; // decrypted message + optional string address = 2; // address used to sign the message (if used) +} + +/** + * Request: Ask device to encrypt or decrypt value of given key + * @next CipheredKeyValue + * @next Failure + */ +message CipherKeyValue { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional string key = 2; // key component of key:value + optional bytes value = 3; // value component of key:value + optional bool encrypt = 4; // are we encrypting (True) or decrypting (False)? + optional bool ask_on_encrypt = 5; // should we ask on encrypt operation? + optional bool ask_on_decrypt = 6; // should we ask on decrypt operation? + optional bytes iv = 7; // initialization vector (will be computed if not set) +} + +/** + * Response: Return ciphered/deciphered value + * @prev CipherKeyValue + */ +message CipheredKeyValue { + optional bytes value = 1; // ciphered/deciphered value +} + +////////////////////////////////// +// Transaction signing messages // +////////////////////////////////// + +/** + * Request: Estimated size of the transaction + * This behaves exactly like SignTx, which means that it can ask using TxRequest + * This call is non-blocking (except possible PassphraseRequest to unlock the seed) + * @next TxSize + * @next Failure + */ +message EstimateTxSize { + required uint32 outputs_count = 1; // number of transaction outputs + required uint32 inputs_count = 2; // number of transaction inputs + optional string coin_name = 3 [default='Bitcoin']; // coin to use +} + +/** + * Response: Estimated size of the transaction + * @prev EstimateTxSize + */ +message TxSize { + optional uint32 tx_size = 1; // estimated size of transaction in bytes +} + +/** + * Request: Ask device to sign transaction + * @next PassphraseRequest + * @next PinMatrixRequest + * @next TxRequest + * @next Failure + */ +message SignTx { + required uint32 outputs_count = 1; // number of transaction outputs + required uint32 inputs_count = 2; // number of transaction inputs + optional string coin_name = 3 [default='Bitcoin']; // coin to use + optional uint32 version = 4 [default=1]; // transaction version + optional uint32 lock_time = 5 [default=0]; // transaction lock_time + optional uint32 decred_expiry = 6; +} + +/** + * Request: Simplified transaction signing + * This method doesn't support streaming, so there are hardware limits in number of inputs and outputs. + * In case of success, the result is returned using TxRequest message. + * @next PassphraseRequest + * @next PinMatrixRequest + * @next TxRequest + * @next Failure + */ +message SimpleSignTx { + repeated TxInputType inputs = 1; // transaction inputs + repeated TxOutputType outputs = 2; // transaction outputs + repeated TransactionType transactions = 3; // transactions whose outputs are used to build current inputs + optional string coin_name = 4 [default='Bitcoin']; // coin to use + optional uint32 version = 5 [default=1]; // transaction version + optional uint32 lock_time = 6 [default=0]; // transaction lock_time +} + +/** + * Response: Device asks for information for signing transaction or returns the last result + * If request_index is set, device awaits TxAck message (with fields filled in according to request_type) + * If signature_index is set, 'signature' contains signed input of signature_index's input + * @prev SignTx + * @prev SimpleSignTx + * @prev TxAck + */ +message TxRequest { + optional RequestType request_type = 1; // what should be filled in TxAck message? + optional TxRequestDetailsType details = 2; // request for tx details + optional TxRequestSerializedType serialized = 3; // serialized data and request for next +} + +/** + * Request: Reported transaction data + * @prev TxRequest + * @next TxRequest + */ +message TxAck { + optional TransactionType tx = 1; +} + +/** + * Request: Ask device to sign transaction + * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. + * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. + * @next PassphraseRequest + * @next PinMatrixRequest + * @next EthereumTxRequest + * @next Failure + */ +message EthereumSignTx { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes nonce = 2; // <=256 bit unsigned big endian + optional bytes gas_price = 3; // <=256 bit unsigned big endian (in wei) + optional bytes gas_limit = 4; // <=256 bit unsigned big endian + optional bytes to = 5; // 160 bit address hash + optional bytes value = 6; // <=256 bit unsigned big endian (in wei) + optional bytes data_initial_chunk = 7; // The initial data chunk (<= 1024 bytes) + optional uint32 data_length = 8; // Length of transaction payload + optional uint32 chain_id = 9; // Chain Id for EIP 155 +} + +/** + * Response: Device asks for more data from transaction payload, or returns the signature. + * If data_length is set, device awaits that many more bytes of payload. + * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. + * @prev EthereumSignTx + * @next EthereumTxAck + */ +message EthereumTxRequest { + optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) + optional uint32 signature_v = 2; // Computed signature (recovery parameter, limited to 27 or 28) + optional bytes signature_r = 3; // Computed signature R component (256 bit) + optional bytes signature_s = 4; // Computed signature S component (256 bit) +} + +/** + * Request: Transaction payload data. + * @prev EthereumTxRequest + * @next EthereumTxRequest + */ +message EthereumTxAck { + optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) +} + +//////////////////////////////////////// +// Ethereum: Message signing messages // +//////////////////////////////////////// + +/** + * Request: Ask device to sign message + * @next EthereumMessageSignature + * @next Failure + */ +message EthereumSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + required bytes message = 2; // message to be signed +} + +/** + * Request: Ask device to verify message + * @next Success + * @next Failure + */ +message EthereumVerifyMessage { + optional bytes address = 1; // address to verify + optional bytes signature = 2; // signature to verify + optional bytes message = 3; // message to verify +} + +/** + * Response: Signed message + * @prev EthereumSignMessage + */ +message EthereumMessageSignature { + optional bytes address = 1; // address used to sign the message + optional bytes signature = 2; // signature of the message +} + +/////////////////////// +// Identity messages // +/////////////////////// + +/** + * Request: Ask device to sign identity + * @next SignedIdentity + * @next Failure + */ +message SignIdentity { + optional IdentityType identity = 1; // identity + optional bytes challenge_hidden = 2; // non-visible challenge + optional string challenge_visual = 3; // challenge shown on display (e.g. date+time) + optional string ecdsa_curve_name = 4; // ECDSA curve name to use +} + +/** + * Response: Device provides signed identity + * @prev SignIdentity + */ +message SignedIdentity { + optional string address = 1; // identity address + optional bytes public_key = 2; // identity public key + optional bytes signature = 3; // signature of the identity data +} + +/////////////////// +// ECDH messages // +/////////////////// + +/** + * Request: Ask device to generate ECDH session key + * @next ECDHSessionKey + * @next Failure + */ +message GetECDHSessionKey { + optional IdentityType identity = 1; // identity + optional bytes peer_public_key = 2; // peer's public key + optional string ecdsa_curve_name = 3; // ECDSA curve name to use +} + +/** + * Response: Device provides ECDH session key + * @prev GetECDHSessionKey + */ +message ECDHSessionKey { + optional bytes session_key = 1; // ECDH session key +} + +/////////////////// +// U2F messages // +/////////////////// + +/** + * Request: Set U2F counter + * @next Success + */ +message SetU2FCounter { + optional uint32 u2f_counter = 1; // counter +} + +///////////////////////// +// Bootloader messages // +///////////////////////// + +/** + * Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload) + * @next Success + * @next FirmwareRequest + * @next Failure + */ +message FirmwareErase { + optional uint32 length = 1; // length of new firmware +} + +/** + * Response: Ask for firmware chunk + * @next FirmwareUpload + */ +message FirmwareRequest { + optional uint32 offset = 1; // offset of requested firmware chunk + optional uint32 length = 2; // length of requested firmware chunk +} + +/** + * Request: Send firmware in binary form to the device + * @next Success + * @next Failure + */ +message FirmwareUpload { + required bytes payload = 1; // firmware to be loaded into device + optional bytes hash = 2; // hash of the payload +} + + +/** + * Request: Perform a device self-test + * @next Success + * @next Failure + */ +message SelfTest { + optional bytes payload = 1; // payload to be used in self-test +} + +////////////////// +// NEM messages // +////////////////// + +/** + * Request: Ask device for NEM address corresponding to address_n path + * @next PassphraseRequest + * @next NEMAddress + * @next Failure + */ +message NEMGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) + optional bool show_display = 3; // Optionally show on display before sending the result +} + +/** + * Response: Contains NEM address derived from device private seed + * @prev NEMGetAddress + */ +message NEMAddress { + required string address = 1; // NEM address in Base32 encoding +} + +/** + * Request: Ask device to sign transaction + * @next NEMSignedTx + * @next Failure + */ +message NEMSignTx { + optional NEMTransactionCommon transaction = 1; // Common part of transaction + optional NEMTransactionCommon multisig = 2; // Common part of inner transaction for multisig transactions + optional NEMTransfer transfer = 3; // Transfer transaction part + optional bool cosigning = 4; // Whether cosigning or initiating the multisig transaction + optional NEMProvisionNamespace provision_namespace = 5; // Provision namespace part + optional NEMMosaicCreation mosaic_creation = 6; // Mosaic definition creation part + optional NEMMosaicSupplyChange supply_change = 7; // Mosaic supply change part + optional NEMAggregateModification aggregate_modification = 8; // Aggregate modification part + optional NEMImportanceTransfer importance_transfer = 9; // Importance transfer part +} + +/** + * Response: Contains NEM transaction data and signature + * @prev NEMSignTx + */ +message NEMSignedTx { + optional bytes data = 1; // Transaction data + optional bytes signature = 2; // Signature for the transaction +} + +/** + * Request: Ask device to decrypt NEM transaction payload + * @next NEMDecryptedMessage + * @next Failure + */ +message NEMDecryptMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) + optional bytes public_key = 3; // Public key of the other party + optional bytes payload = 4; // Actual message data (encrypted) +} + +/** + * Response: Contains decrypted NEM transaction payload + * @prev NEMDecryptMessage + */ +message NEMDecryptedMessage { + optional bytes payload = 1; // Actual message data (unencrypted) +} + +/////////////////// +// CoSi messages // +/////////////////// + +/** + * Request: Ask device to commit to CoSi signing + * @next CosiCommitment + * @next Failure + */ +message CosiCommit { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes data = 2; // Data to be signed +} + +/** + * Response: Contains a CoSi commitment + * @prev CosiCommit + */ +message CosiCommitment { + optional bytes commitment = 1; // Commitment + optional bytes pubkey = 2; // Public key +} + +/** + * Request: Ask device to sign using CoSi + * @next CosiSignature + * @next Failure + */ +message CosiSign { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes data = 2; // Data to be signed + optional bytes global_commitment = 3; // Aggregated commitment + optional bytes global_pubkey = 4; // Aggregated public key +} + +/** + * Response: Contains a CoSi signature + * @prev CosiSign + */ +message CosiSignature { + optional bytes signature = 1; // Signature +} + +///////////////////////////////////////////////////////////// +// Debug messages (only available if DebugLink is enabled) // +///////////////////////////////////////////////////////////// + +/** + * Request: "Press" the button on the device + * @next Success + */ +message DebugLinkDecision { + required bool yes_no = 1; // true for "Confirm", false for "Cancel" +} + +/** + * Request: Computer asks for device state + * @next DebugLinkState + */ +message DebugLinkGetState { +} + +/** + * Response: Device current state + * @prev DebugLinkGetState + */ +message DebugLinkState { + optional bytes layout = 1; // raw buffer of display + optional string pin = 2; // current PIN, blank if PIN is not set/enabled + optional string matrix = 3; // current PIN matrix + optional string mnemonic = 4; // current BIP-39 mnemonic + optional HDNodeType node = 5; // current BIP-32 node + optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase? + optional string reset_word = 7; // word on device display during ResetDevice workflow + optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow + optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow + optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow +} + +/** + * Request: Ask device to restart + */ +message DebugLinkStop { +} + +/** + * Response: Device wants host to log event + */ +message DebugLinkLog { + optional uint32 level = 1; + optional string bucket = 2; + optional string text = 3; +} + +/** + * Request: Read memory from device + * @next DebugLinkMemory + */ +message DebugLinkMemoryRead { + optional uint32 address = 1; + optional uint32 length = 2; +} + +/** + * Response: Device sends memory back + * @prev DebugLinkMemoryRead + */ +message DebugLinkMemory { + optional bytes memory = 1; +} + +/** + * Request: Write memory to device. + * WARNING: Writing to the wrong location can irreparably break the device. + */ +message DebugLinkMemoryWrite { + optional uint32 address = 1; + optional bytes memory = 2; + optional bool flash = 3; +} + +/** + * Request: Erase block of flash on device + * WARNING: Writing to the wrong location can irreparably break the device. + */ +message DebugLinkFlashErase { + optional uint32 sector = 1; +} diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/protocol.md b/hardware-wallet/firmware/vendor/trezor-common/protob/protocol.md new file mode 100644 index 00000000..38dc411e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/protocol.md @@ -0,0 +1,21 @@ +# TREZOR Protocol + +## version 1 + +Messages are sent in packets of 64 bytes. + +First packet has the following structure: + +| offset | length | type | contents | +|--------|--------|-------------|---------------------------------------------------------------------------------------| +| 0 | 3 | char[3] | '?##' magic constant | +| 3 | 2 | BE uint16_t | numerical [message type](messages.proto#L14) | +| 5 | 4 | BE uint32_t | message size | +| 9 | 55 | uint8_t[55] | first 55 bytes of message encoded in Protocol Buffers (padded with zeroes if shorter) | + +Following packets has the following structure: + +| offset | length | type | contents | +|--------|--------|-------------|----------------------------------------------------------------------------------------| +| 0 | 1 | char[1] | '?' magic constant | +| 1 | 63 | uint8_t[63] | following bytes of message encoded in Protocol Buffers (padded with zeroes if shorter) | diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/storage.proto b/hardware-wallet/firmware/vendor/trezor-common/protob/storage.proto new file mode 100644 index 00000000..764fcdfb --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/storage.proto @@ -0,0 +1,31 @@ +syntax = "proto2"; + +/** + * Storage area of TREZOR + */ + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorStorage"; + +import "types.proto"; + +/** + * Internal persistent storage of device + */ +message Storage { + required uint32 version = 1; // version of storage + optional HDNodeType node = 2; // BIP-32 node (mnemonic cannot be used if this is present) + optional string mnemonic = 3; // BIP-39 mnemonic (node cannot be used if this is present) + optional bool passphrase_protection = 4; // whether to require passphrase to decrypt node or stretch mnemonic + optional uint32 pin_failed_attempts = 5; // number of failed PIN attempts + optional string pin = 6; // current PIN + optional string language = 7; // current language + optional string label = 8; // device label + optional bool imported = 9; // was storage imported from an external source? + optional bytes homescreen = 10; // image used as homescreen (logo + label is used when not set) + optional uint32 u2f_counter = 11; // sequence number for u2f authentications + optional bool needs_backup = 12; // seed is not backed up yet + optional uint32 flags = 13; // device flags + optional HDNodeType u2froot = 14; // U2F root node +} diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/types.proto b/hardware-wallet/firmware/vendor/trezor-common/protob/types.proto new file mode 100644 index 00000000..2099d7f8 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/types.proto @@ -0,0 +1,445 @@ +syntax = "proto2"; + +/** + * Types for TREZOR communication + * + * @author Marek Palatinus + * @version 1.2 + */ + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorType"; + +import "google/protobuf/descriptor.proto"; + +/** + * Options for specifying message direction and type of wire (normal/debug) + */ +extend google.protobuf.EnumValueOptions { + optional bool wire_in = 50002; // message can be transmitted via wire from PC to TREZOR + optional bool wire_out = 50003; // message can be transmitted via wire from TREZOR to PC + optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to TREZOR + optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from TREZOR to PC + optional bool wire_tiny = 50006; // message is handled by TREZOR when the USB stack is in tiny mode + optional bool wire_bootloader = 50007; // message is only handled by TREZOR Bootloader +} + +/** + * Type of failures returned by Failure message + * @used_in Failure + */ +enum FailureType { + Failure_UnexpectedMessage = 1; + Failure_ButtonExpected = 2; + Failure_DataError = 3; + Failure_ActionCancelled = 4; + Failure_PinExpected = 5; + Failure_PinCancelled = 6; + Failure_PinInvalid = 7; + Failure_InvalidSignature = 8; + Failure_ProcessError = 9; + Failure_NotEnoughFunds = 10; + Failure_NotInitialized = 11; + Failure_PinMismatch = 12; + Failure_FirmwareError = 99; +} + +/** + * Type of script which will be used for transaction output + * @used_in TxOutputType + */ +enum OutputScriptType { + PAYTOADDRESS = 0; // used for all addresses (bitcoin, p2sh, witness) + PAYTOSCRIPTHASH = 1; // p2sh address (deprecated; use PAYTOADDRESS) + PAYTOMULTISIG = 2; // only for change output + PAYTOOPRETURN = 3; // op_return + PAYTOWITNESS = 4; // only for change output + PAYTOP2SHWITNESS = 5; // only for change output +} + +/** + * Type of script which will be used for transaction output + * @used_in TxInputType + */ +enum InputScriptType { + SPENDADDRESS = 0; // standard p2pkh address + SPENDMULTISIG = 1; // p2sh multisig address + EXTERNAL = 2; // reserved for external inputs (coinjoin) + SPENDWITNESS = 3; // native segwit + SPENDP2SHWITNESS = 4; // segwit over p2sh (backward compatible) +} + +/** + * Type of information required by transaction signing process + * @used_in TxRequest + */ +enum RequestType { + TXINPUT = 0; + TXOUTPUT = 1; + TXMETA = 2; + TXFINISHED = 3; + TXEXTRADATA = 4; +} + +/** + * Type of button request + * @used_in ButtonRequest + */ +enum ButtonRequestType { + ButtonRequest_Other = 1; + ButtonRequest_FeeOverThreshold = 2; + ButtonRequest_ConfirmOutput = 3; + ButtonRequest_ResetDevice = 4; + ButtonRequest_ConfirmWord = 5; + ButtonRequest_WipeDevice = 6; + ButtonRequest_ProtectCall = 7; + ButtonRequest_SignTx = 8; + ButtonRequest_FirmwareCheck = 9; + ButtonRequest_Address = 10; + ButtonRequest_PublicKey = 11; + ButtonRequest_MnemonicWordCount = 12; + ButtonRequest_MnemonicInput = 13; + ButtonRequest_PassphraseType = 14; +} + +/** + * Type of PIN request + * @used_in PinMatrixRequest + */ +enum PinMatrixRequestType { + PinMatrixRequestType_Current = 1; + PinMatrixRequestType_NewFirst = 2; + PinMatrixRequestType_NewSecond = 3; +} + +/** + * Type of recovery procedure. These should be used as bitmask, e.g., + * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` + * listing every method supported by the host computer. + * + * Note that ScrambledWords must be supported by every implementation + * for backward compatibility; there is no way to not support it. + * + * @used_in RecoveryDevice + */ +enum RecoveryDeviceType { + // use powers of two when extending this field + RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order + RecoveryDeviceType_Matrix = 1; // matrix recovery type +} + +/** + * Type of Recovery Word request + * @used_in WordRequest + */ +enum WordRequestType { + WordRequestType_Plain = 0; + WordRequestType_Matrix9 = 1; + WordRequestType_Matrix6 = 2; +} + +/** + * Structure representing BIP32 (hierarchical deterministic) node + * Used for imports of private key into the device and exporting public key out of device + * @used_in PublicKey + * @used_in LoadDevice + * @used_in DebugLinkState + * @used_in Storage + */ +message HDNodeType { + required uint32 depth = 1; + required uint32 fingerprint = 2; + required uint32 child_num = 3; + required bytes chain_code = 4; + optional bytes private_key = 5; + optional bytes public_key = 6; +} + +message HDNodePathType { + required HDNodeType node = 1; // BIP-32 node in deserialized form + repeated uint32 address_n = 2; // BIP-32 path to derive the key from node +} + +/** + * Structure representing Coin + * @used_in Features + */ +message CoinType { + optional string coin_name = 1; + optional string coin_shortcut = 2; + optional uint32 address_type = 3 [default=0]; + optional uint64 maxfee_kb = 4; + optional uint32 address_type_p2sh = 5 [default=5]; + optional string signed_message_header = 8; + optional uint32 xpub_magic = 9 [default=76067358]; // default=0x0488b21e + optional uint32 xprv_magic = 10 [default=76066276]; // default=0x0488ade4 + optional bool segwit = 11; + optional uint32 forkid = 12; + optional bool force_bip143 = 13; +} + +/** + * Type of redeem script used in input + * @used_in TxInputType + */ +message MultisigRedeemScriptType { + repeated HDNodePathType pubkeys = 1; // pubkeys from multisig address (sorted lexicographically) + repeated bytes signatures = 2; // existing signatures for partially signed input + optional uint32 m = 3; // "m" from n, how many valid signatures is necessary for spending +} + +/** + * Structure representing transaction input + * @used_in SimpleSignTx + * @used_in TransactionType + */ +message TxInputType { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + required bytes prev_hash = 2; // hash of previous transaction output to spend by this input + required uint32 prev_index = 3; // index of previous output to spend + optional bytes script_sig = 4; // script signature, unset for tx to sign + optional uint32 sequence = 5 [default=4294967295]; // sequence (default=0xffffffff) + optional InputScriptType script_type = 6 [default=SPENDADDRESS]; // defines template of input script + optional MultisigRedeemScriptType multisig = 7; // Filled if input is going to spend multisig tx + optional uint64 amount = 8; // amount of previous transaction output (for segwit only) + optional uint32 decred_tree = 9; + optional uint32 decred_script_version = 10; +} + +/** + * Structure representing transaction output + * @used_in SimpleSignTx + * @used_in TransactionType + */ +message TxOutputType { + optional string address = 1; // target coin address in Base58 encoding + repeated uint32 address_n = 2; // BIP-32 path to derive the key from master node; has higher priority than "address" + required uint64 amount = 3; // amount to spend in satoshis + required OutputScriptType script_type = 4; // output script type + optional MultisigRedeemScriptType multisig = 5; // defines multisig address; script_type must be PAYTOMULTISIG + optional bytes op_return_data = 6; // defines op_return data; script_type must be PAYTOOPRETURN, amount must be 0 + optional uint32 decred_script_version = 7; +} + +/** + * Structure representing compiled transaction output + * @used_in TransactionType + */ +message TxOutputBinType { + required uint64 amount = 1; + required bytes script_pubkey = 2; + optional uint32 decred_script_version = 3; +} + +/** + * Structure representing transaction + * @used_in SimpleSignTx + */ +message TransactionType { + optional uint32 version = 1; + repeated TxInputType inputs = 2; + repeated TxOutputBinType bin_outputs = 3; + repeated TxOutputType outputs = 5; + optional uint32 lock_time = 4; + optional uint32 inputs_cnt = 6; + optional uint32 outputs_cnt = 7; + optional bytes extra_data = 8; + optional uint32 extra_data_len = 9; + optional uint32 decred_expiry = 10; +} + +/** + * Structure representing request details + * @used_in TxRequest + */ +message TxRequestDetailsType { + optional uint32 request_index = 1; // device expects TxAck message from the computer + optional bytes tx_hash = 2; // tx_hash of requested transaction + optional uint32 extra_data_len = 3; // length of requested extra data + optional uint32 extra_data_offset = 4; // offset of requested extra data +} + +/** + * Structure representing serialized data + * @used_in TxRequest + */ +message TxRequestSerializedType { + optional uint32 signature_index = 1; // 'signature' field contains signed input of this index + optional bytes signature = 2; // signature of the signature_index input + optional bytes serialized_tx = 3; // part of serialized and signed transaction +} + +/** + * Structure representing identity data + * @used_in IdentityType + */ +message IdentityType { + optional string proto = 1; // proto part of URI + optional string user = 2; // user part of URI + optional string host = 3; // host part of URI + optional string port = 4; // port part of URI + optional string path = 5; // path part of URI + optional uint32 index = 6 [default=0]; // identity index +} + +/** + * Structure representing the common part for NEM transactions + * @used_in NEMSignTx + */ +message NEMTransactionCommon { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) + optional uint32 timestamp = 3; // Number of seconds elapsed since the creation of the nemesis block + optional uint64 fee = 4; // Fee for the transaction + optional uint32 deadline = 5; // Deadline of the transaction + optional bytes signer = 6; // Public key of the account (for multisig transactions) +} + +/** + * Structure representing the transfer transaction part for NEM transactions + * @used_in NEMSignTx + */ +message NEMTransfer { + optional string recipient = 1; // Address of the recipient + optional uint64 amount = 2; // Amount of micro NEM that is transferred + optional bytes payload = 3; // Actual message data (unencrypted) + optional bytes public_key = 4; // Public key of the recipient (for encrypted payloads) + repeated NEMMosaic mosaics = 5; // Attached mosaics +} + +/** + * Structure representing the mosaic attachment for NEM transfer transactions + * @used_in NEMTransfer + */ +message NEMMosaic { + optional string namespace = 1; // Fully qualified name of the namespace + optional string mosaic = 2; // Name of the mosaic definition + optional uint64 quantity = 3; // Mosaic quantity, always given in smallest units +} + +/** + * Structure representing the provision namespace part for NEM transactions + * @used_in NEMSignTx + */ +message NEMProvisionNamespace { + optional string namespace = 1; // New part concatenated to the parent + optional string parent = 2; // Parent namespace (for child namespaces) + optional string sink = 3; // Rental fee sink address + optional uint64 fee = 4; // Rental fee +} + +/** + * Type of levy which will be used for mosaic + * @used_in NEMMosaicDefinition + */ +enum NEMMosaicLevy { + MosaicLevy_Absolute = 1; + MosaicLevy_Percentile = 2; +} + +/** + * Structure representing the mosaic definition creation part for NEM transactions + * @used_in NEMSignTx + */ +message NEMMosaicCreation { + optional NEMMosaicDefinition definition = 1; // Mosaic definition + optional string sink = 2; // Creation fee sink address + optional uint64 fee = 3; // Creation fee +} + +/** + * Structure representing a mosaic definition + * @used_in NEMMosaicCreation + */ +message NEMMosaicDefinition { + optional string name = 1; // User-friendly name of the mosaic (for whitelisted mosaics) + optional string ticker = 2; // Ticker of the mosaic (for whitelisted mosaics) + optional string namespace = 3; // Fully qualified name of the namespace + optional string mosaic = 4; // Name of the mosaic definition + optional uint32 divisibility = 5; // Number of decimal places that a mosaic can be divided into + optional NEMMosaicLevy levy = 6; // Levy type + optional uint64 fee = 7; // Levy fee (interpretation depends on levy type) + optional string levy_address = 8; // Levy address + optional string levy_namespace = 9; // Fully qualified name of the namespace of the levy mosaic + optional string levy_mosaic = 10; // Name of the levy mosaic + optional uint64 supply = 11; // Initial supply to create, always given in entire units + optional bool mutable_supply = 12; // Mutable supply + optional bool transferable = 13; // Mosaic allows transfers among accounts other than the creator + optional string description = 14; // Mosaic description + repeated uint32 networks = 15; // Networks that the mosaic is valid on (for whitelisted mosaics) +} + +/** + * Structure representing the mosaic supply change part for NEM transactions + * @used_in NEMSignTx + */ +message NEMMosaicSupplyChange { + optional string namespace = 1; // Fully qualified name of the namespace + optional string mosaic = 2; // Name of the mosaic definition + optional NEMSupplyChangeType type = 3; // Type of supply change + optional uint64 delta = 4; // Supply delta +} + +/** + * Type of supply change which will be applied to mosaic + * @used_in NEMMosaicSupplyChange + */ +enum NEMSupplyChangeType { + SupplyChange_Increase = 1; + SupplyChange_Decrease = 2; +} + +/** + * Structure representing the aggregate modification part for NEM transactions + * @used_in NEMSignTx + */ +message NEMAggregateModification { + repeated NEMCosignatoryModification modifications = 1; // Cosignatory modifications + optional sint32 relative_change = 2; // Relative change of the minimum cosignatories +} + +/** + * Structure representing the cosignatory modification for aggregate modification transactions + * @used_in NEMAggregateMdofiication + */ +message NEMCosignatoryModification { + optional NEMModificationType type = 1; // Type of cosignatory modification + optional bytes public_key = 2; // Public key of the cosignatory +} + +/** + * Type of cosignatory modification + * @used_in NEMCosignatoryModification + */ +enum NEMModificationType { + CosignatoryModification_Add = 1; + CosignatoryModification_Delete = 2; +} + +/** + * Structure representing the importance transfer part for NEM transactions + * @used_in NEMSignTx + */ +message NEMImportanceTransfer { + optional NEMImportanceTransferMode mode = 1; // Mode of importance transfer + optional bytes public_key = 2; // Public key of the remote account +} + +/** + * Mode of importance transfer + * @used_in NEMModificationType + */ +enum NEMImportanceTransferMode { + ImportanceTransfer_Activate = 1; + ImportanceTransfer_Deactivate = 2; +} + +/** + * Ask trezor to generate a skycoin address + * @used_in SkycoinAddress{ + */ +enum SkycoinAddressType { + AddressTypeSkycoin = 1; + AddressTypeBitcoin = 2; +} diff --git a/hardware-wallet/firmware/vendor/trezor-common/signer/.gitignore b/hardware-wallet/firmware/vendor/trezor-common/signer/.gitignore new file mode 100644 index 00000000..a97789d6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/signer/.gitignore @@ -0,0 +1,4 @@ +config_pb2.py +config_pb2.pyc +config_signed.bin +*.pem diff --git a/hardware-wallet/firmware/vendor/trezor-common/signer/config.json b/hardware-wallet/firmware/vendor/trezor-common/signer/config.json new file mode 100644 index 00000000..1a3186b3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/signer/config.json @@ -0,0 +1,29 @@ +{ + "whitelist_urls": [ + "https?://localhost(:\\d+)?(/.*)?", + "https?://localhost\\.mytrezor\\.com(:\\d+)?(/.*)?", + "https://mytrezor\\.com(/.*)?", + "https://[\\w\\.-]+\\.mytrezor\\.com(/.*)?", + "https://trezor\\.io(/.*)?", + "https://[\\w\\.-]+\\.trezor\\.io(/.*)?", + "https://trezor\\.github\\.io(/.*)?", + "https://greenaddress\\.it(/.*)?", + "https://[\\w\\.-]+\\.greenaddress\\.it(/.*)?", + "https://coinprism\\.com(/.*)?", + "https://[\\w\\.-]+\\.coinprism\\.com(/.*)?", + "https://bitex\\.la(/.*)?", + "https://[\\w\\.-]+\\.bitex\\.la(/.*)?", + "https://dash\\.run(/.*)?", + "https://[\\w\\.-]+\\.dash\\.run(/.*)?", + "https://0xproject\\.com(/.*)?", + "https://[\\w\\.-]+\\.unchained-capital\\.com(/.*)?", + "chrome-extension://jcjjhjgimijdkoamemaghajlhegmoclj(/.*)?" + ], + "blacklist_urls": [ + ], + "known_devices": [ + ["0x534c", "0x0001", "Trezor"], + ["0x1209", "0x53c0", "Trezor2 Bootloader"], + ["0x1209", "0x53c1", "Trezor2"] + ] +} diff --git a/hardware-wallet/firmware/vendor/trezor-common/signer/sample.key b/hardware-wallet/firmware/vendor/trezor-common/signer/sample.key new file mode 100644 index 00000000..6369d96a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/signer/sample.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIMS7yx++yZ1lv1nYXIy2LuLblj8P4Qb0g9mvpzvU45qKoAcGBSuBBAAK +oUQDQgAEeNQwJ0+MXsEyEzgVHp8n9MZ2oAi9+GONB8C2vpqzXHGhUYBjJDrNTf6W +tm4/LsgBPI4HLNCbODShn4H2Wcw0VQ== +-----END EC PRIVATE KEY----- diff --git a/hardware-wallet/firmware/vendor/trezor-common/signer/sign.py b/hardware-wallet/firmware/vendor/trezor-common/signer/sign.py new file mode 100755 index 00000000..31bf26e6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/signer/sign.py @@ -0,0 +1,101 @@ +#!/usr/bin/python +import subprocess +import os +import json +import time +import ecdsa +import hashlib +import binascii +from google.protobuf.descriptor_pb2 import FileDescriptorSet + +PROTOBUF_PROTO_DIR=os.environ.get('PROTOBUF_PROTO_DIR', '/usr/include/') +TREZOR_PROTO_DIR=os.environ.get('TREZOR_PROTO_DIR', '../protob/') + +def compile_config(): + cmd = "protoc --python_out=../signer/ -I" + PROTOBUF_PROTO_DIR + " -I./ config.proto" + subprocess.check_call(cmd.split(), cwd=TREZOR_PROTO_DIR) + +def parse_json(): + return json.loads(open('config.json', 'r').read()) + + +def get_compiled_proto(): + # Compile trezor.proto to binary format + pdir = os.path.abspath(TREZOR_PROTO_DIR) + pfile = os.path.join(pdir, "messages.proto") + cmd = "protoc --include_imports -I" + PROTOBUF_PROTO_DIR + " -I" + pdir + " " + pfile + " -otrezor.bin" + + subprocess.check_call(cmd.split()) + + # Load compiled protocol description to string + proto = open('trezor.bin', 'r').read() + os.unlink('trezor.bin') + + # Parse it into FileDescriptorSet structure + compiled = FileDescriptorSet() + compiled.ParseFromString(proto) + return compiled + +def compose_message(json, proto): + import config_pb2 + + cfg = config_pb2.Configuration() + cfg.valid_until = 2147483647 # maxint + cfg.wire_protocol.MergeFrom(proto) + + for url in json['whitelist_urls']: + cfg.whitelist_urls.append(str(url)) + + for url in json['blacklist_urls']: + cfg.blacklist_urls.append(str(url)) + + for dev in json['known_devices']: + desc = cfg.known_devices.add() + desc.vendor_id = int(dev[0], 16) + desc.product_id = int(dev[1], 16) + + return cfg.SerializeToString() + +def sign_message(data, key): + if key.startswith('-----BEGIN'): + key = ecdsa.keys.SigningKey.from_pem(key) + else: + key = ecdsa.keys.SigningKey.from_secret_exponent(secexp = int(key, 16), curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256) + + verify = key.get_verifying_key() + print "Verifying key:" + print verify.to_pem() + + return key.sign_deterministic(data, hashfunc=hashlib.sha256) + +def pack_datafile(filename, signature, data): + if len(signature) != 64: + raise Exception("Signature must be 64 bytes long") + + fp = open(filename, 'w') + fp.write(binascii.hexlify(signature)) + fp.write(binascii.hexlify(data)) + fp.close() + + print "Signature and data stored to", filename + +if __name__ == '__main__': + key = '' + print "Paste ECDSA private key (in PEM format or SECEXP format) and press Enter:" + while True: + inp = raw_input() + if inp == '': + break + + key += inp + "\n" + + # key = open('sample.key', 'r').read() + + compile_config() + json = parse_json() + proto = get_compiled_proto() + + data = compose_message(json, proto) + signature = sign_message(data, key) + + pack_datafile('config_signed.bin', signature, data) diff --git a/hardware-wallet/firmware/vendor/trezor-common/udev/51-trezor.rules b/hardware-wallet/firmware/vendor/trezor-common/udev/51-trezor.rules new file mode 100644 index 00000000..c937ad79 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/udev/51-trezor.rules @@ -0,0 +1,12 @@ +# TREZOR: The Original Hardware Wallet +# https://trezor.io/ +# Put this file into /usr/lib/udev/rules.d + +# TREZOR +SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n" +KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" + +# TREZOR v2 +SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c0", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n" +SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c1", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n" +KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" diff --git a/hardware-wallet/firmware/vendor/trezor-common/udev/dist/.gitignore b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/.gitignore new file mode 100644 index 00000000..f7dec42e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/.gitignore @@ -0,0 +1,3 @@ +trezor.rules +*.rpm +*.deb diff --git a/hardware-wallet/firmware/vendor/trezor-common/udev/dist/Dockerfile b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/Dockerfile new file mode 100644 index 00000000..8fec8e06 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/Dockerfile @@ -0,0 +1,17 @@ +# initialize from the image + +FROM fedora:25 + +# update package repositories + +RUN dnf update -y + +# install tools + +RUN dnf install -y cmake make wget +RUN dnf install -y gcc gcc-c++ git make patchutils pkgconfig wget + +# install dependencies for Linux packaging + +RUN dnf install -y ruby-devel rubygems rpm-build +RUN gem install fpm --no-document diff --git a/hardware-wallet/firmware/vendor/trezor-common/udev/dist/Makefile b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/Makefile new file mode 100644 index 00000000..dff2eb29 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/Makefile @@ -0,0 +1,18 @@ +VOL_MOUNT = -v $(shell pwd):/release +IMAGETAG = trezor-udev-build-env + +all: .package + +.package: .docker-image trezor.rules + $(info Packaging ...) + docker run -t $(VOL_MOUNT) $(IMAGETAG) /release/release.sh + +trezor.rules: + cp ../51-trezor.rules trezor.rules + +.docker-image: + $(info Preparing docker image ...) + docker build -t $(IMAGETAG) . + +shell: .docker-image + docker run -i -t $(VOL_MOUNT) $(IMAGETAG) /bin/bash diff --git a/hardware-wallet/firmware/vendor/trezor-common/udev/dist/release.sh b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/release.sh new file mode 100755 index 00000000..617ab7b5 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-common/udev/dist/release.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +set -e + +cd $(dirname $0) + +VERSION="2" + +install -D -m 0644 ./trezor.rules ./lib/udev/rules.d/52-trezor-extension.rules + +NAME=trezor-udev + +tar cfj $NAME-$VERSION.tar.bz2 ./lib + +for TYPE in "deb" "rpm"; do + fpm \ + -s tar \ + -t $TYPE \ + -a all \ + -n $NAME \ + -v $VERSION \ + --license "LGPL-3.0" \ + --vendor "SatoshiLabs" \ + --description "Udev rules for TREZOR" \ + --maintainer "SatoshiLabs " \ + --url "https://trezor.io/" \ + --category "Productivity/Security" \ + $NAME-$VERSION.tar.bz2 +done + +rm $NAME-$VERSION.tar.bz2 +rm -rf ./lib diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/.gitignore b/hardware-wallet/firmware/vendor/trezor-crypto/.gitignore new file mode 100644 index 00000000..a826ffce --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/.gitignore @@ -0,0 +1,13 @@ +.vscode/ +_attic/ +*.o +*.d +*.exe +*~ +test_openssl +test_speed +test_check +aes/aestst +*.os +*.so +*.pyc diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/.travis.yml b/hardware-wallet/firmware/vendor/trezor-crypto/.travis.yml new file mode 100644 index 00000000..8f2c902d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/.travis.yml @@ -0,0 +1,37 @@ +sudo: false +dist: trusty +language: c + +compiler: + - clang + - gcc + +addons: + apt: + packages: + - check + - cmake + - cmake-data + - libssl-dev + - python-pip + - valgrind + +install: + - pip install --user pytest ecdsa curve25519-donna + +script: + - make + - ./aes/aestst + - ./test_check + - CK_TIMEOUT_MULTIPLIER=20 valgrind -q --error-exitcode=1 ./test_check + - ./test_openssl 1000 + - ITERS=10 py.test + - mkdir _build && cd _build && cmake .. && make && cd .. + +notifications: + webhooks: + urls: + - http://ci-bot.satoshilabs.com:5000/travis + on_success: always + on_failure: always + on_start: always diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/AUTHORS b/hardware-wallet/firmware/vendor/trezor-crypto/AUTHORS new file mode 100644 index 00000000..51c9bdab --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/AUTHORS @@ -0,0 +1,2 @@ +Tomas Dzetkulic +Pavol Rusnak diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/CMakeLists.txt b/hardware-wallet/firmware/vendor/trezor-crypto/CMakeLists.txt new file mode 100644 index 00000000..81e51f90 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 2.8) + +set(SOURCES + bignum.c ecdsa.c curves.c secp256k1.c nist256p1.c rand.c hmac.c bip32.c bip39.c pbkdf2.c base58.c base32.c + address.c + script.c + ripemd160.c + sha2.c + sha3.c + hasher.c + aes/aescrypt.c aes/aeskey.c aes/aestab.c aes/aes_modes.c + ed25519-donna/curve25519-donna-32bit.c ed25519-donna/curve25519-donna-helpers.c ed25519-donna/modm-donna-32bit.c + ed25519-donna/ed25519-donna-basepoint-table.c ed25519-donna/ed25519-donna-32bit-tables.c ed25519-donna/ed25519-donna-impl-base.c + ed25519-donna/ed25519.c ed25519-donna/curve25519-donna-scalarmult-base.c ed25519-donna/ed25519-sha3.c ed25519-donna/ed25519-keccak.c + blake256.c + blake2b.c blake2s.c + chacha20poly1305/chacha20poly1305.c chacha20poly1305/chacha_merged.c chacha20poly1305/poly1305-donna.c chacha20poly1305/rfc7539.c + rc4.c + nem.c +) + +add_library(TrezorCrypto STATIC ${SOURCES}) + +target_include_directories(TrezorCrypto PUBLIC .) +target_include_directories(TrezorCrypto PUBLIC aes) +target_include_directories(TrezorCrypto PUBLIC chacha20poly1305) +target_include_directories(TrezorCrypto PUBLIC ed25519-donna) + +target_compile_options(TrezorCrypto PRIVATE "-std=c99") + +if(MSVC) + set_source_files_properties(${SOURCES} PROPERTIES LANGUAGE CXX) +endif(MSVC) + +# Build trezor-crypto tests (requires OpenSSL) +if (TREZOR_CRYPTO_TESTS) + add_executable(test_check test_check.c) + target_link_libraries(test_check TrezorCrypto check rt pthread m crypto) + add_test(NAME trezor-crypto COMMAND test_check) + + add_executable(test_openssl test_openssl.c) + target_link_libraries(test_openssl TrezorCrypto check rt pthread m crypto) + add_test(NAME trezor-crypto-openssl COMMAND test_openssl 100) +endif() diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/CONTRIBUTORS b/hardware-wallet/firmware/vendor/trezor-crypto/CONTRIBUTORS new file mode 100644 index 00000000..b5fc5500 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/CONTRIBUTORS @@ -0,0 +1,15 @@ +Tomas Dzetkulic +Pavol Rusnak +Jochen Hoenicke +Dustin Laurence +Ondrej Mikle +Roman Zeyde +Alex Beregszaszi +netanelkl +Jan Pochyla +Ondrej Mikle +Josh Billings +Adam Mackler +Oleg Andreev +mog +John Dvorak diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/LICENSE b/hardware-wallet/firmware/vendor/trezor-crypto/LICENSE new file mode 100644 index 00000000..1ea1df70 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2013 Tomas Dzetkulic +Copyright (c) 2013 Pavol Rusnak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION 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/hardware-wallet/firmware/vendor/trezor-crypto/Makefile b/hardware-wallet/firmware/vendor/trezor-crypto/Makefile new file mode 100644 index 00000000..65b77a26 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/Makefile @@ -0,0 +1,94 @@ +CC ?= gcc + +OPTFLAGS ?= -O3 -g + +CFLAGS += $(OPTFLAGS) \ + -std=gnu99 \ + -W \ + -Wall \ + -Wextra \ + -Wimplicit-function-declaration \ + -Wredundant-decls \ + -Wstrict-prototypes \ + -Wundef \ + -Wshadow \ + -Wpointer-arith \ + -Wformat \ + -Wreturn-type \ + -Wsign-compare \ + -Wmultichar \ + -Wformat-nonliteral \ + -Winit-self \ + -Wuninitialized \ + -Wformat-security \ + -Werror + +CFLAGS += -I. +CFLAGS += -DUSE_ETHEREUM=1 +CFLAGS += -DUSE_GRAPHENE=1 +CFLAGS += -DUSE_NEM=1 + +# disable certain optimizations and features when small footprint is required +ifdef SMALL +CFLAGS += -DUSE_PRECOMPUTED_CP=0 +endif + +SRCS = bignum.c ecdsa.c curves.c secp256k1.c nist256p1.c rand.c hmac.c bip32.c bip39.c pbkdf2.c base58.c base32.c +SRCS += address.c +SRCS += script.c +SRCS += ripemd160.c +SRCS += sha2.c +SRCS += sha3.c +SRCS += hasher.c +SRCS += aes/aescrypt.c aes/aeskey.c aes/aestab.c aes/aes_modes.c +SRCS += ed25519-donna/curve25519-donna-32bit.c ed25519-donna/curve25519-donna-helpers.c ed25519-donna/modm-donna-32bit.c +SRCS += ed25519-donna/ed25519-donna-basepoint-table.c ed25519-donna/ed25519-donna-32bit-tables.c ed25519-donna/ed25519-donna-impl-base.c +SRCS += ed25519-donna/ed25519.c ed25519-donna/curve25519-donna-scalarmult-base.c ed25519-donna/ed25519-sha3.c ed25519-donna/ed25519-keccak.c +SRCS += blake256.c +SRCS += blake2b.c blake2s.c +SRCS += chacha20poly1305/chacha20poly1305.c chacha20poly1305/chacha_merged.c chacha20poly1305/poly1305-donna.c chacha20poly1305/rfc7539.c +SRCS += rc4.c +SRCS += nem.c +SRCS += segwit_addr.c +SRCS += memzero.c + +OBJS = $(SRCS:.c=.o) + +TESTLIBS = $(shell pkg-config --libs check) -lpthread -lm +TESTSSLLIBS = -lcrypto + +all: test_check test_openssl test_speed aes/aestst tools libtrezor-crypto.so + +%.o: %.c %.h options.h + $(CC) $(CFLAGS) -o $@ -c $< + +aes/aestst: aes/aestst.o aes/aescrypt.o aes/aeskey.o aes/aestab.o + $(CC) $^ -o $@ + +test_check: test_check.o $(OBJS) + $(CC) test_check.o $(OBJS) $(TESTLIBS) -o test_check + +test_speed: test_speed.o $(OBJS) + $(CC) test_speed.o $(OBJS) -o test_speed + +test_openssl: test_openssl.o $(OBJS) + $(CC) test_openssl.o $(OBJS) $(TESTSSLLIBS) -o test_openssl + +libtrezor-crypto.so: $(SRCS) + $(CC) $(CFLAGS) -fPIC -shared $(SRCS) -o libtrezor-crypto.so + +tools: tools/xpubaddrgen tools/mktable tools/bip39bruteforce + +tools/xpubaddrgen: tools/xpubaddrgen.o $(OBJS) + $(CC) tools/xpubaddrgen.o $(OBJS) -o tools/xpubaddrgen + +tools/mktable: tools/mktable.o $(OBJS) + $(CC) tools/mktable.o $(OBJS) -o tools/mktable + +tools/bip39bruteforce: tools/bip39bruteforce.o $(OBJS) + $(CC) tools/bip39bruteforce.o $(OBJS) -o tools/bip39bruteforce + +clean: + rm -f *.o aes/*.o chacha20poly1305/*.o ed25519-donna/*.o + rm -f test_check test_speed test_openssl libtrezor-crypto.so + rm -f tools/*.o tools/xpubaddrgen tools/mktable tools/bip39bruteforce diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/README.md b/hardware-wallet/firmware/vendor/trezor-crypto/README.md new file mode 100644 index 00000000..55635602 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/README.md @@ -0,0 +1,43 @@ +# trezor-crypto + +[![Build Status](https://travis-ci.org/trezor/trezor-crypto.svg?branch=master)](https://travis-ci.org/trezor/trezor-crypto) [![gitter](https://badges.gitter.im/trezor/community.svg)](https://gitter.im/trezor/community) + +Heavily optimized cryptography algorithms for embedded devices. + +These include: +- AES/Rijndael encryption/decryption +- Big Number (256 bit) Arithmetics +- BIP32 Hierarchical Deterministic Wallets +- BIP39 Mnemonic code +- ECDSA signing/verifying (supports secp256k1 and nist256p1 curves, + uses RFC6979 for deterministic signatures) +- ECDSA public key derivation +- Base32 (RFC4648 and custom alphabets) +- Base58 address representation +- Ed25519 signing/verifying (also SHA3 and Keccak variants) +- ECDH using secp256k1, nist256p1 and Curve25519 +- HMAC-SHA256 and HMAC-SHA512 +- PBKDF2 +- RIPEMD-160 +- SHA1 +- SHA2-256/SHA2-512 +- SHA3/Keccak +- BLAKE2s/BLAKE2b +- Chacha20-Poly1305 +- unit tests (using Check - check.sf.net; in test_check.c) +- tests against OpenSSL (in test_openssl.c) + +Distibuted under MIT License. + +## Some parts of the library come from external sources: + +- AES: https://github.com/BrianGladman/aes +- Base58: https://github.com/luke-jr/libbase58 +- BLAKE2s/BLAKE2b: https://github.com/BLAKE2/BLAKE2 +- RIPEMD-160: https://github.com/ARMmbed/mbedtls +- SHA1/SHA2: http://www.aarongifford.com/computers/sha.html +- SHA3: https://github.com/rhash/RHash +- Curve25519: https://github.com/agl/curve25519-donna +- Ed25519: https://github.com/floodyberry/ed25519-donna +- Chacha20: https://github.com/wg/c20p1305 +- Poly1305: https://github.com/floodyberry/poly1305-donna diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/address.c b/hardware-wallet/firmware/vendor/trezor-crypto/address.c new file mode 100644 index 00000000..1e558761 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/address.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2016 Daira Hopwood + * Copyright (c) 2016 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "address.h" + +size_t address_prefix_bytes_len(uint32_t address_type) +{ + if (address_type <= 0xFF) return 1; + if (address_type <= 0xFFFF) return 2; + if (address_type <= 0xFFFFFF) return 3; + return 4; +} + +void address_write_prefix_bytes(uint32_t address_type, uint8_t *out) +{ + if (address_type > 0xFFFFFF) *(out++) = address_type >> 24; + if (address_type > 0xFFFF) *(out++) = (address_type >> 16) & 0xFF; + if (address_type > 0xFF) *(out++) = (address_type >> 8) & 0xFF; + *(out++) = address_type & 0xFF; +} + +bool address_check_prefix(const uint8_t *addr, uint32_t address_type) +{ + if (address_type <= 0xFF) { + return address_type == (uint32_t)(addr[0]); + } + if (address_type <= 0xFFFF) { + return address_type == ((uint32_t)(addr[0] << 8) | (uint32_t)(addr[1])); + } + if (address_type <= 0xFFFFFF) { + return address_type == ((uint32_t)(addr[0] << 16) | (uint32_t)(addr[1] << 8) | (uint32_t)(addr[2])); + } + return address_type == ((uint32_t)(addr[0] << 24) | (uint32_t)(addr[1] << 16) | (uint32_t)(addr[2] << 8) | (uint32_t)(addr[3])); +} + +#if USE_ETHEREUM +#include "sha3.h" + +void ethereum_address_checksum(const uint8_t *addr, char *address) +{ + const char *hex = "0123456789abcdef"; + for (int i = 0; i < 20; i++) { + address[i * 2] = hex[(addr[i] >> 4) & 0xF]; + address[i * 2 + 1] = hex[addr[i] & 0xF]; + } + address[40] = 0; + uint8_t hash[32]; + keccak_256((const uint8_t *)address, 40, hash); + for (int i = 0; i < 20; i++) { + if (hash[i] & 0x80 && address[i * 2 ] >= 'a' && address[i * 2 ] <= 'f') { + address[i * 2] -= 0x20; + } + if (hash[i] & 0x08 && address[i * 2 + 1] >= 'a' && address[i * 2 + 1] <= 'f') { + address[i * 2 + 1] -= 0x20; + } + } +} +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/address.h b/hardware-wallet/firmware/vendor/trezor-crypto/address.h new file mode 100644 index 00000000..307cf8dc --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/address.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2016 Daira Hopwood + * Copyright (c) 2016 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __ADDRESS_H__ +#define __ADDRESS_H__ + +#include +#include +#include +#include "options.h" + +size_t address_prefix_bytes_len(uint32_t address_type); +void address_write_prefix_bytes(uint32_t address_type, uint8_t *out); +bool address_check_prefix(const uint8_t *addr, uint32_t address_type); +#if USE_ETHEREUM +void ethereum_address_checksum(const uint8_t *addr, char *address); +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aes.h b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aes.h new file mode 100644 index 00000000..8cc0526a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aes.h @@ -0,0 +1,215 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 + + This file contains the definitions required to use AES in C. See aesopt.h + for optimisation details. +*/ + +#ifndef _AES_H +#define _AES_H + +#include + +/* This include is used to find 8 & 32 bit unsigned integer types */ +#include "brg_types.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// #define AES_128 /* if a fast 128 bit key scheduler is needed */ +// #define AES_192 /* if a fast 192 bit key scheduler is needed */ +#define AES_256 /* if a fast 256 bit key scheduler is needed */ +// #define AES_VAR /* if variable key size scheduler is needed */ +#define AES_MODES /* if support is needed for modes */ + +/* The following must also be set in assembler files if being used */ + +#define AES_ENCRYPT /* if support for encryption is needed */ +#define AES_DECRYPT /* if support for decryption is needed */ + +#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */ +#define N_COLS 4 /* the number of columns in the state */ + +/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ +/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */ +/* or 44, 52 or 60 32-bit words. */ + +#if defined( AES_VAR ) || defined( AES_256 ) +#define KS_LENGTH 60 +#elif defined( AES_192 ) +#define KS_LENGTH 52 +#else +#define KS_LENGTH 44 +#endif + +#define AES_RETURN INT_RETURN + +/* the character array 'inf' in the following structures is used */ +/* to hold AES context information. This AES code uses cx->inf.b[0] */ +/* to hold the number of rounds multiplied by 16. The other three */ +/* elements can be used by code that implements additional modes */ + +typedef union +{ uint32_t l; + uint8_t b[4]; +} aes_inf; + +#ifdef _MSC_VER +# pragma warning( disable : 4324 ) +#endif + +#if defined(_MSC_VER) && defined(_WIN64) +#define ALIGNED_(x) __declspec(align(x)) +#elif defined(__GNUC__) && defined(__x86_64__) +#define ALIGNED_(x) __attribute__ ((aligned(x))) +#else +#define ALIGNED_(x) +#endif + +typedef struct ALIGNED_(16) +{ uint32_t ks[KS_LENGTH]; + aes_inf inf; +} aes_encrypt_ctx; + +typedef struct ALIGNED_(16) +{ uint32_t ks[KS_LENGTH]; + aes_inf inf; +} aes_decrypt_ctx; + +#ifdef _MSC_VER +# pragma warning( default : 4324 ) +#endif + +/* This routine must be called before first use if non-static */ +/* tables are being used */ + +AES_RETURN aes_init(void); + +/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */ +/* those in the range 128 <= key_len <= 256 are given in bits */ + +#if defined( AES_ENCRYPT ) + +#if defined( AES_128 ) || defined( AES_VAR) +AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); +#endif + +#if defined( AES_192 ) || defined( AES_VAR) +AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); +#endif + +#if defined( AES_256 ) || defined( AES_VAR) +AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); +#endif + +#if defined( AES_VAR ) +AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); +#endif + +AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); + +#endif + +#if defined( AES_DECRYPT ) + +#if defined( AES_128 ) || defined( AES_VAR) +AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); +#endif + +#if defined( AES_192 ) || defined( AES_VAR) +AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); +#endif + +#if defined( AES_256 ) || defined( AES_VAR) +AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); +#endif + +#if defined( AES_VAR ) +AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); +#endif + +AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); + +#endif + +#if defined( AES_MODES ) + +/* Multiple calls to the following subroutines for multiple block */ +/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */ +/* long messages incrementally provided that the context AND the iv */ +/* are preserved between all such calls. For the ECB and CBC modes */ +/* each individual call within a series of incremental calls must */ +/* process only full blocks (i.e. len must be a multiple of 16) but */ +/* the CFB, OFB and CTR mode calls can handle multiple incremental */ +/* calls of any length. Each mode is reset when a new AES key is */ +/* set but ECB needs no reset and CBC can be reset without setting */ +/* a new key by setting a new IV value. To reset CFB, OFB and CTR */ +/* without setting the key, aes_mode_reset() must be called and the */ +/* IV must be set. NOTE: All these calls update the IV on exit so */ +/* this has to be reset if a new operation with the same IV as the */ +/* previous one is required (or decryption follows encryption with */ +/* the same IV array). */ + +AES_RETURN aes_test_alignment_detection(unsigned int n); + +AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, const aes_encrypt_ctx cx[1]); + +AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, const aes_decrypt_ctx cx[1]); + +AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, const aes_encrypt_ctx cx[1]); + +AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, const aes_decrypt_ctx cx[1]); + +AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]); + +AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx cx[1]); + +AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx cx[1]); + +#define aes_ofb_encrypt aes_ofb_crypt +#define aes_ofb_decrypt aes_ofb_crypt + +AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx cx[1]); + +typedef void cbuf_inc(unsigned char *cbuf); + +#define aes_ctr_encrypt aes_ctr_crypt +#define aes_ctr_decrypt aes_ctr_crypt + +AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]); + +void aes_ctr_cbuf_inc(unsigned char *cbuf); + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aes_modes.c b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aes_modes.c new file mode 100644 index 00000000..744395e0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aes_modes.c @@ -0,0 +1,957 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 + + These subroutines implement multiple block AES modes for ECB, CBC, CFB, + OFB and CTR encryption, The code provides support for the VIA Advanced + Cryptography Engine (ACE). + + NOTE: In the following subroutines, the AES contexts (ctx) must be + 16 byte aligned if VIA ACE is being used +*/ + +#include +#include +#include + +#include "aesopt.h" + +#if defined( AES_MODES ) +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#pragma intrinsic(memcpy) +#endif + +#define BFR_BLOCKS 8 + +/* These values are used to detect long word alignment in order to */ +/* speed up some buffer operations. This facility may not work on */ +/* some machines so this define can be commented out if necessary */ + +#define FAST_BUFFER_OPERATIONS + +#define lp32(x) ((uint32_t*)(x)) + +#if defined( USE_VIA_ACE_IF_PRESENT ) + +#include "aes_via_ace.h" + +#pragma pack(16) + +aligned_array(unsigned long, enc_gen_table, 12, 16) = NEH_ENC_GEN_DATA; +aligned_array(unsigned long, enc_load_table, 12, 16) = NEH_ENC_LOAD_DATA; +aligned_array(unsigned long, enc_hybrid_table, 12, 16) = NEH_ENC_HYBRID_DATA; +aligned_array(unsigned long, dec_gen_table, 12, 16) = NEH_DEC_GEN_DATA; +aligned_array(unsigned long, dec_load_table, 12, 16) = NEH_DEC_LOAD_DATA; +aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA; + +/* NOTE: These control word macros must only be used after */ +/* a key has been set up because they depend on key size */ +/* See the VIA ACE documentation for key type information */ +/* and aes_via_ace.h for non-default NEH_KEY_TYPE values */ + +#ifndef NEH_KEY_TYPE +# define NEH_KEY_TYPE NEH_HYBRID +#endif + +#if NEH_KEY_TYPE == NEH_LOAD +#define kd_adr(c) ((uint8_t*)(c)->ks) +#elif NEH_KEY_TYPE == NEH_GENERATE +#define kd_adr(c) ((uint8_t*)(c)->ks + (c)->inf.b[0]) +#elif NEH_KEY_TYPE == NEH_HYBRID +#define kd_adr(c) ((uint8_t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0)) +#else +#error no key type defined for VIA ACE +#endif + +#else + +#define aligned_array(type, name, no, stride) type name[no] +#define aligned_auto(type, name, no, stride) type name[no] + +#endif + +#if defined( _MSC_VER ) && _MSC_VER > 1200 + +#define via_cwd(cwd, ty, dir, len) \ + unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4)) + +#else + +#define via_cwd(cwd, ty, dir, len) \ + aligned_auto(unsigned long, cwd, 4, 16); \ + cwd[1] = cwd[2] = cwd[3] = 0; \ + cwd[0] = neh_##dir##_##ty##_key(len) + +#endif + +/* test the code for detecting and setting pointer alignment */ + +AES_RETURN aes_test_alignment_detection(unsigned int n) /* 4 <= n <= 16 */ +{ uint8_t p[16]; + uint32_t i, count_eq = 0, count_neq = 0; + + if(n < 4 || n > 16) + return EXIT_FAILURE; + + for(i = 0; i < n; ++i) + { + uint8_t *qf = ALIGN_FLOOR(p + i, n), + *qh = ALIGN_CEIL(p + i, n); + + if(qh == qf) + ++count_eq; + else if(qh == qf + n) + ++count_neq; + else + return EXIT_FAILURE; + } + return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS); +} + +AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1]) +{ + ctx->inf.b[2] = 0; + return EXIT_SUCCESS; +} + +AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, const aes_encrypt_ctx ctx[1]) +{ int nb = len >> 4; + + if(len & (AES_BLOCK_SIZE - 1)) + return EXIT_FAILURE; + +#if defined( USE_VIA_ACE_IF_PRESENT ) + + if(ctx->inf.b[1] == 0xff) + { uint8_t *ksp = (uint8_t*)(ctx->ks); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); + + if(ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; + + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) + { + via_ecb_op5(ksp, cwd, ibuf, obuf, nb); + } + else + { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip, *op; + + while(nb) + { + int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); + + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + + if(ip != ibuf) + memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + + via_ecb_op5(ksp, cwd, ip, op, m); + + if(op != obuf) + memcpy(obuf, buf, m * AES_BLOCK_SIZE); + + ibuf += m * AES_BLOCK_SIZE; + obuf += m * AES_BLOCK_SIZE; + nb -= m; + } + } + + return EXIT_SUCCESS; + } + +#endif + +#if !defined( ASSUME_VIA_ACE_PRESENT ) + while(nb--) + { + if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } +#endif + return EXIT_SUCCESS; +} + +AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, const aes_decrypt_ctx ctx[1]) +{ int nb = len >> 4; + + if(len & (AES_BLOCK_SIZE - 1)) + return EXIT_FAILURE; + +#if defined( USE_VIA_ACE_IF_PRESENT ) + + if(ctx->inf.b[1] == 0xff) + { uint8_t *ksp = kd_adr(ctx); + via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); + + if(ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; + + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) + { + via_ecb_op5(ksp, cwd, ibuf, obuf, nb); + } + else + { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip, *op; + + while(nb) + { + int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); + + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + + if(ip != ibuf) + memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + + via_ecb_op5(ksp, cwd, ip, op, m); + + if(op != obuf) + memcpy(obuf, buf, m * AES_BLOCK_SIZE); + + ibuf += m * AES_BLOCK_SIZE; + obuf += m * AES_BLOCK_SIZE; + nb -= m; + } + } + + return EXIT_SUCCESS; + } + +#endif + +#if !defined( ASSUME_VIA_ACE_PRESENT ) + while(nb--) + { + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } +#endif + return EXIT_SUCCESS; +} + +AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, const aes_encrypt_ctx ctx[1]) +{ int nb = len >> 4; + + if(len & (AES_BLOCK_SIZE - 1)) + return EXIT_FAILURE; + +#if defined( USE_VIA_ACE_IF_PRESENT ) + + if(ctx->inf.b[1] == 0xff) + { uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; + aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); + + if(ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; + + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + { + ivp = liv; + memcpy(liv, iv, AES_BLOCK_SIZE); + } + + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 )) + { + via_cbc_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp); + } + else + { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip, *op; + + while(nb) + { + int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); + + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + + if(ip != ibuf) + memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + + via_cbc_op7(ksp, cwd, ip, op, m, ivp, ivp); + + if(op != obuf) + memcpy(obuf, buf, m * AES_BLOCK_SIZE); + + ibuf += m * AES_BLOCK_SIZE; + obuf += m * AES_BLOCK_SIZE; + nb -= m; + } + } + + if(iv != ivp) + memcpy(iv, ivp, AES_BLOCK_SIZE); + + return EXIT_SUCCESS; + } + +#endif + +#if !defined( ASSUME_VIA_ACE_PRESENT ) +# ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) + while(nb--) + { + lp32(iv)[0] ^= lp32(ibuf)[0]; + lp32(iv)[1] ^= lp32(ibuf)[1]; + lp32(iv)[2] ^= lp32(ibuf)[2]; + lp32(iv)[3] ^= lp32(ibuf)[3]; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + memcpy(obuf, iv, AES_BLOCK_SIZE); + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } + else +# endif + while(nb--) + { + iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1]; + iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3]; + iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5]; + iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7]; + iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9]; + iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11]; + iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13]; + iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15]; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + memcpy(obuf, iv, AES_BLOCK_SIZE); + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } +#endif + return EXIT_SUCCESS; +} + +AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, const aes_decrypt_ctx ctx[1]) +{ unsigned char tmp[AES_BLOCK_SIZE]; + int nb = len >> 4; + + if(len & (AES_BLOCK_SIZE - 1)) + return EXIT_FAILURE; + +#if defined( USE_VIA_ACE_IF_PRESENT ) + + if(ctx->inf.b[1] == 0xff) + { uint8_t *ksp = kd_adr(ctx), *ivp = iv; + aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); + via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); + + if(ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; + + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + { + ivp = liv; + memcpy(liv, iv, AES_BLOCK_SIZE); + } + + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 )) + { + via_cbc_op6(ksp, cwd, ibuf, obuf, nb, ivp); + } + else + { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip, *op; + + while(nb) + { + int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); + + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + + if(ip != ibuf) + memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + + via_cbc_op6(ksp, cwd, ip, op, m, ivp); + + if(op != obuf) + memcpy(obuf, buf, m * AES_BLOCK_SIZE); + + ibuf += m * AES_BLOCK_SIZE; + obuf += m * AES_BLOCK_SIZE; + nb -= m; + } + } + + if(iv != ivp) + memcpy(iv, ivp, AES_BLOCK_SIZE); + + return EXIT_SUCCESS; + } +#endif + +#if !defined( ASSUME_VIA_ACE_PRESENT ) +# ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) + while(nb--) + { + memcpy(tmp, ibuf, AES_BLOCK_SIZE); + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + lp32(obuf)[0] ^= lp32(iv)[0]; + lp32(obuf)[1] ^= lp32(iv)[1]; + lp32(obuf)[2] ^= lp32(iv)[2]; + lp32(obuf)[3] ^= lp32(iv)[3]; + memcpy(iv, tmp, AES_BLOCK_SIZE); + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } + else +# endif + while(nb--) + { + memcpy(tmp, ibuf, AES_BLOCK_SIZE); + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1]; + obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3]; + obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5]; + obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7]; + obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9]; + obuf[10] ^= iv[10]; obuf[11] ^= iv[11]; + obuf[12] ^= iv[12]; obuf[13] ^= iv[13]; + obuf[14] ^= iv[14]; obuf[15] ^= iv[15]; + memcpy(iv, tmp, AES_BLOCK_SIZE); + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } +#endif + return EXIT_SUCCESS; +} + +AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) +{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; + + if(b_pos) /* complete any partial block */ + { + while(b_pos < AES_BLOCK_SIZE && cnt < len) + { + *obuf++ = (iv[b_pos++] ^= *ibuf++); + cnt++; + } + + b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); + } + + if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ + { +#if defined( USE_VIA_ACE_IF_PRESENT ) + + if(ctx->inf.b[1] == 0xff) + { int m; + uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; + aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); + + if(ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; + + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + { + ivp = liv; + memcpy(liv, iv, AES_BLOCK_SIZE); + } + + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) + { + via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp); + ibuf += nb * AES_BLOCK_SIZE; + obuf += nb * AES_BLOCK_SIZE; + cnt += nb * AES_BLOCK_SIZE; + } + else /* input, output or both are unaligned */ + { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip, *op; + + while(nb) + { + m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; + + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + + if(ip != ibuf) + memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + + via_cfb_op7(ksp, cwd, ip, op, m, ivp, ivp); + + if(op != obuf) + memcpy(obuf, buf, m * AES_BLOCK_SIZE); + + ibuf += m * AES_BLOCK_SIZE; + obuf += m * AES_BLOCK_SIZE; + cnt += m * AES_BLOCK_SIZE; + } + } + + if(ivp != iv) + memcpy(iv, ivp, AES_BLOCK_SIZE); + } +#else +# ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) + while(cnt + AES_BLOCK_SIZE <= len) + { + assert(b_pos == 0); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0]; + lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1]; + lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2]; + lp32(obuf)[3] = lp32(iv)[3] ^= lp32(ibuf)[3]; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; + } + else +# endif + while(cnt + AES_BLOCK_SIZE <= len) + { + assert(b_pos == 0); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1]; + obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3]; + obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5]; + obuf[ 6] = iv[ 6] ^= ibuf[ 6]; obuf[ 7] = iv[ 7] ^= ibuf[ 7]; + obuf[ 8] = iv[ 8] ^= ibuf[ 8]; obuf[ 9] = iv[ 9] ^= ibuf[ 9]; + obuf[10] = iv[10] ^= ibuf[10]; obuf[11] = iv[11] ^= ibuf[11]; + obuf[12] = iv[12] ^= ibuf[12]; obuf[13] = iv[13] ^= ibuf[13]; + obuf[14] = iv[14] ^= ibuf[14]; obuf[15] = iv[15] ^= ibuf[15]; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; + } +#endif + } + + while(cnt < len) + { + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + + while(cnt < len && b_pos < AES_BLOCK_SIZE) + { + *obuf++ = (iv[b_pos++] ^= *ibuf++); + cnt++; + } + + b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); + } + + ctx->inf.b[2] = (uint8_t)b_pos; + return EXIT_SUCCESS; +} + +AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) +{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; + + if(b_pos) /* complete any partial block */ + { uint8_t t; + + while(b_pos < AES_BLOCK_SIZE && cnt < len) + { + t = *ibuf++; + *obuf++ = t ^ iv[b_pos]; + iv[b_pos++] = t; + cnt++; + } + + b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); + } + + if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ + { +#if defined( USE_VIA_ACE_IF_PRESENT ) + + if(ctx->inf.b[1] == 0xff) + { int m; + uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; + aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); + via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); + + if(ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; + + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + { + ivp = liv; + memcpy(liv, iv, AES_BLOCK_SIZE); + } + + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) + { + via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp); + ibuf += nb * AES_BLOCK_SIZE; + obuf += nb * AES_BLOCK_SIZE; + cnt += nb * AES_BLOCK_SIZE; + } + else /* input, output or both are unaligned */ + { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip, *op; + + while(nb) + { + m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; + + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + + if(ip != ibuf) /* input buffer is not aligned */ + memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + + via_cfb_op6(ksp, cwd, ip, op, m, ivp); + + if(op != obuf) /* output buffer is not aligned */ + memcpy(obuf, buf, m * AES_BLOCK_SIZE); + + ibuf += m * AES_BLOCK_SIZE; + obuf += m * AES_BLOCK_SIZE; + cnt += m * AES_BLOCK_SIZE; + } + } + + if(ivp != iv) + memcpy(iv, ivp, AES_BLOCK_SIZE); + } +#else +# ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) &&!ALIGN_OFFSET( iv, 4 )) + while(cnt + AES_BLOCK_SIZE <= len) + { uint32_t t; + + assert(b_pos == 0); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + t = lp32(ibuf)[0], lp32(obuf)[0] = t ^ lp32(iv)[0], lp32(iv)[0] = t; + t = lp32(ibuf)[1], lp32(obuf)[1] = t ^ lp32(iv)[1], lp32(iv)[1] = t; + t = lp32(ibuf)[2], lp32(obuf)[2] = t ^ lp32(iv)[2], lp32(iv)[2] = t; + t = lp32(ibuf)[3], lp32(obuf)[3] = t ^ lp32(iv)[3], lp32(iv)[3] = t; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; + } + else +# endif + while(cnt + AES_BLOCK_SIZE <= len) + { uint8_t t; + + assert(b_pos == 0); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + t = ibuf[ 0], obuf[ 0] = t ^ iv[ 0], iv[ 0] = t; + t = ibuf[ 1], obuf[ 1] = t ^ iv[ 1], iv[ 1] = t; + t = ibuf[ 2], obuf[ 2] = t ^ iv[ 2], iv[ 2] = t; + t = ibuf[ 3], obuf[ 3] = t ^ iv[ 3], iv[ 3] = t; + t = ibuf[ 4], obuf[ 4] = t ^ iv[ 4], iv[ 4] = t; + t = ibuf[ 5], obuf[ 5] = t ^ iv[ 5], iv[ 5] = t; + t = ibuf[ 6], obuf[ 6] = t ^ iv[ 6], iv[ 6] = t; + t = ibuf[ 7], obuf[ 7] = t ^ iv[ 7], iv[ 7] = t; + t = ibuf[ 8], obuf[ 8] = t ^ iv[ 8], iv[ 8] = t; + t = ibuf[ 9], obuf[ 9] = t ^ iv[ 9], iv[ 9] = t; + t = ibuf[10], obuf[10] = t ^ iv[10], iv[10] = t; + t = ibuf[11], obuf[11] = t ^ iv[11], iv[11] = t; + t = ibuf[12], obuf[12] = t ^ iv[12], iv[12] = t; + t = ibuf[13], obuf[13] = t ^ iv[13], iv[13] = t; + t = ibuf[14], obuf[14] = t ^ iv[14], iv[14] = t; + t = ibuf[15], obuf[15] = t ^ iv[15], iv[15] = t; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; + } +#endif + } + + while(cnt < len) + { uint8_t t; + + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + + while(cnt < len && b_pos < AES_BLOCK_SIZE) + { + t = *ibuf++; + *obuf++ = t ^ iv[b_pos]; + iv[b_pos++] = t; + cnt++; + } + + b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); + } + + ctx->inf.b[2] = (uint8_t)b_pos; + return EXIT_SUCCESS; +} + +AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) +{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; + + if(b_pos) /* complete any partial block */ + { + while(b_pos < AES_BLOCK_SIZE && cnt < len) + { + *obuf++ = iv[b_pos++] ^ *ibuf++; + cnt++; + } + + b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); + } + + if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ + { +#if defined( USE_VIA_ACE_IF_PRESENT ) + + if(ctx->inf.b[1] == 0xff) + { int m; + uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; + aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); + + if(ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; + + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + { + ivp = liv; + memcpy(liv, iv, AES_BLOCK_SIZE); + } + + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) + { + via_ofb_op6(ksp, cwd, ibuf, obuf, nb, ivp); + ibuf += nb * AES_BLOCK_SIZE; + obuf += nb * AES_BLOCK_SIZE; + cnt += nb * AES_BLOCK_SIZE; + } + else /* input, output or both are unaligned */ + { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip, *op; + + while(nb) + { + m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; + + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + + if(ip != ibuf) + memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + + via_ofb_op6(ksp, cwd, ip, op, m, ivp); + + if(op != obuf) + memcpy(obuf, buf, m * AES_BLOCK_SIZE); + + ibuf += m * AES_BLOCK_SIZE; + obuf += m * AES_BLOCK_SIZE; + cnt += m * AES_BLOCK_SIZE; + } + } + + if(ivp != iv) + memcpy(iv, ivp, AES_BLOCK_SIZE); + } +#else +# ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) + while(cnt + AES_BLOCK_SIZE <= len) + { + assert(b_pos == 0); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + lp32(obuf)[0] = lp32(iv)[0] ^ lp32(ibuf)[0]; + lp32(obuf)[1] = lp32(iv)[1] ^ lp32(ibuf)[1]; + lp32(obuf)[2] = lp32(iv)[2] ^ lp32(ibuf)[2]; + lp32(obuf)[3] = lp32(iv)[3] ^ lp32(ibuf)[3]; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; + } + else +# endif + while(cnt + AES_BLOCK_SIZE <= len) + { + assert(b_pos == 0); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + obuf[ 0] = iv[ 0] ^ ibuf[ 0]; obuf[ 1] = iv[ 1] ^ ibuf[ 1]; + obuf[ 2] = iv[ 2] ^ ibuf[ 2]; obuf[ 3] = iv[ 3] ^ ibuf[ 3]; + obuf[ 4] = iv[ 4] ^ ibuf[ 4]; obuf[ 5] = iv[ 5] ^ ibuf[ 5]; + obuf[ 6] = iv[ 6] ^ ibuf[ 6]; obuf[ 7] = iv[ 7] ^ ibuf[ 7]; + obuf[ 8] = iv[ 8] ^ ibuf[ 8]; obuf[ 9] = iv[ 9] ^ ibuf[ 9]; + obuf[10] = iv[10] ^ ibuf[10]; obuf[11] = iv[11] ^ ibuf[11]; + obuf[12] = iv[12] ^ ibuf[12]; obuf[13] = iv[13] ^ ibuf[13]; + obuf[14] = iv[14] ^ ibuf[14]; obuf[15] = iv[15] ^ ibuf[15]; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; + } +#endif + } + + while(cnt < len) + { + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + + while(cnt < len && b_pos < AES_BLOCK_SIZE) + { + *obuf++ = iv[b_pos++] ^ *ibuf++; + cnt++; + } + + b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); + } + + ctx->inf.b[2] = (uint8_t)b_pos; + return EXIT_SUCCESS; +} + +#define BFR_LENGTH (BFR_BLOCKS * AES_BLOCK_SIZE) + +AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1]) +{ unsigned char *ip; + int i, blen, b_pos = (int)(ctx->inf.b[2]); + +#if defined( USE_VIA_ACE_IF_PRESENT ) + aligned_auto(uint8_t, buf, BFR_LENGTH, 16); + if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET( ctx, 16 )) + return EXIT_FAILURE; +#else + uint8_t buf[BFR_LENGTH]; +#endif + + if(b_pos) + { + memcpy(buf, cbuf, AES_BLOCK_SIZE); + if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + + while(b_pos < AES_BLOCK_SIZE && len) + { + *obuf++ = *ibuf++ ^ buf[b_pos++]; + --len; + } + + if(len) + ctr_inc(cbuf), b_pos = 0; + } + + while(len) + { + blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen; + + for(i = 0, ip = buf; i < (blen >> 4); ++i) + { + memcpy(ip, cbuf, AES_BLOCK_SIZE); + ctr_inc(cbuf); + ip += AES_BLOCK_SIZE; + } + + if(blen & (AES_BLOCK_SIZE - 1)) + memcpy(ip, cbuf, AES_BLOCK_SIZE), i++; + +#if defined( USE_VIA_ACE_IF_PRESENT ) + if(ctx->inf.b[1] == 0xff) + { + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); + via_ecb_op5((ctx->ks), cwd, buf, buf, i); + } + else +#endif + if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + + i = 0; ip = buf; +# ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( ip, 4 )) + while(i + AES_BLOCK_SIZE <= blen) + { + lp32(obuf)[0] = lp32(ibuf)[0] ^ lp32(ip)[0]; + lp32(obuf)[1] = lp32(ibuf)[1] ^ lp32(ip)[1]; + lp32(obuf)[2] = lp32(ibuf)[2] ^ lp32(ip)[2]; + lp32(obuf)[3] = lp32(ibuf)[3] ^ lp32(ip)[3]; + i += AES_BLOCK_SIZE; + ip += AES_BLOCK_SIZE; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } + else +#endif + while(i + AES_BLOCK_SIZE <= blen) + { + obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1]; + obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3]; + obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5]; + obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7]; + obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9]; + obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11]; + obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13]; + obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15]; + i += AES_BLOCK_SIZE; + ip += AES_BLOCK_SIZE; + ibuf += AES_BLOCK_SIZE; + obuf += AES_BLOCK_SIZE; + } + + while(i++ < blen) + *obuf++ = *ibuf++ ^ ip[b_pos++]; + } + + ctx->inf.b[2] = (uint8_t)b_pos; + return EXIT_SUCCESS; +} + +void aes_ctr_cbuf_inc(unsigned char *cbuf) +{ + int i = AES_BLOCK_SIZE - 1; + while (i >= 0) { + cbuf[i]++; + if (cbuf[i]) return; // if there was no overflow + i--; + } +} + +#if defined(__cplusplus) +} +#endif +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aescrypt.c b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aescrypt.c new file mode 100644 index 00000000..8c7c7f24 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aescrypt.c @@ -0,0 +1,307 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 +*/ + +#include "aesopt.h" +#include "aestab.h" + +#if defined( USE_INTEL_AES_IF_PRESENT ) +# include "aes_ni.h" +#else +/* map names here to provide the external API ('name' -> 'aes_name') */ +# define aes_xi(x) aes_ ## x +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c]) +#define so(y,x,c) word_out(y, c, s(x,c)) + +#if defined(ARRAYS) +#define locals(y,x) x[4],y[4] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 +#endif + +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) + +#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) + +/* Visual C++ .Net v7.1 provides the fastest encryption code when using + Pentium optimiation with small code but this is poor for decryption + so we need to control this with the following VC++ pragmas +*/ + +#if defined( _MSC_VER ) && !defined( _WIN64 ) +#pragma optimize( "s", on ) +#endif + +/* Given the column (c) of the output state variable, the following + macros give the input state variables which are needed in its + computation for each row (r) of the state. All the alternative + macros give the same end values but expand into different ways + of calculating these values. In particular the complex macro + used for dynamically variable block sizes is designed to expand + to a compile time constant whenever possible but will expand to + conditional clauses on some branches (I am grateful to Frank + Yellin for this construction) +*/ + +#define fwd_var(x,r,c)\ + ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ + : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\ + : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ + : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))) + +#if defined(FT4_SET) +#undef dec_fmvars +#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c)) +#elif defined(FT1_SET) +#undef dec_fmvars +#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c)) +#else +#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c))) +#endif + +#if defined(FL4_SET) +#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c)) +#elif defined(FL1_SET) +#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c)) +#else +#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c)) +#endif + +AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]) +{ uint32_t locals(b0, b1); + const uint32_t *kp; +#if defined( dec_fmvars ) + dec_fmvars; /* declare variables for fwd_mcol() if needed */ +#endif + + if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16) + return EXIT_FAILURE; + + kp = cx->ks; + state_in(b0, in, kp); + +#if (ENC_UNROLL == FULL) + + switch(cx->inf.b[0]) + { + case 14 * 16: + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + kp += 2 * N_COLS; + //-fallthrough + case 12 * 16: + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + kp += 2 * N_COLS; + //-fallthrough + case 10 * 16: + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + round(fwd_rnd, b1, b0, kp + 3 * N_COLS); + round(fwd_rnd, b0, b1, kp + 4 * N_COLS); + round(fwd_rnd, b1, b0, kp + 5 * N_COLS); + round(fwd_rnd, b0, b1, kp + 6 * N_COLS); + round(fwd_rnd, b1, b0, kp + 7 * N_COLS); + round(fwd_rnd, b0, b1, kp + 8 * N_COLS); + round(fwd_rnd, b1, b0, kp + 9 * N_COLS); + round(fwd_lrnd, b0, b1, kp +10 * N_COLS); + //-fallthrough + } + +#else + +#if (ENC_UNROLL == PARTIAL) + { uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) + { + kp += N_COLS; + round(fwd_rnd, b1, b0, kp); + kp += N_COLS; + round(fwd_rnd, b0, b1, kp); + } + kp += N_COLS; + round(fwd_rnd, b1, b0, kp); +#else + { uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) + { + kp += N_COLS; + round(fwd_rnd, b1, b0, kp); + l_copy(b0, b1); + } +#endif + kp += N_COLS; + round(fwd_lrnd, b0, b1, kp); + } +#endif + + state_out(out, b0); + return EXIT_SUCCESS; +} + +#endif + +#if ( FUNCS_IN_C & DECRYPTION_IN_C) + +/* Visual C++ .Net v7.1 provides the fastest encryption code when using + Pentium optimiation with small code but this is poor for decryption + so we need to control this with the following VC++ pragmas +*/ + +#if defined( _MSC_VER ) && !defined( _WIN64 ) +#pragma optimize( "t", on ) +#endif + +/* Given the column (c) of the output state variable, the following + macros give the input state variables which are needed in its + computation for each row (r) of the state. All the alternative + macros give the same end values but expand into different ways + of calculating these values. In particular the complex macro + used for dynamically variable block sizes is designed to expand + to a compile time constant whenever possible but will expand to + conditional clauses on some branches (I am grateful to Frank + Yellin for this construction) +*/ + +#define inv_var(x,r,c)\ + ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ + : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\ + : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ + : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))) + +#if defined(IT4_SET) +#undef dec_imvars +#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c)) +#elif defined(IT1_SET) +#undef dec_imvars +#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c)) +#else +#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))) +#endif + +#if defined(IL4_SET) +#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c)) +#elif defined(IL1_SET) +#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c)) +#else +#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)) +#endif + +/* This code can work with the decryption key schedule in the */ +/* order that is used for encrytpion (where the 1st decryption */ +/* round key is at the high end ot the schedule) or with a key */ +/* schedule that has been reversed to put the 1st decryption */ +/* round key at the low end of the schedule in memory (when */ +/* AES_REV_DKS is defined) */ + +#ifdef AES_REV_DKS +#define key_ofs 0 +#define rnd_key(n) (kp + n * N_COLS) +#else +#define key_ofs 1 +#define rnd_key(n) (kp - n * N_COLS) +#endif + +AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]) +{ uint32_t locals(b0, b1); +#if defined( dec_imvars ) + dec_imvars; /* declare variables for inv_mcol() if needed */ +#endif + const uint32_t *kp; + + if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16) + return EXIT_FAILURE; + + kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0); + state_in(b0, in, kp); + +#if (DEC_UNROLL == FULL) + + kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2)); + switch(cx->inf.b[0]) + { + case 14 * 16: + round(inv_rnd, b1, b0, rnd_key(-13)); + round(inv_rnd, b0, b1, rnd_key(-12)); + //-fallthrough + case 12 * 16: + round(inv_rnd, b1, b0, rnd_key(-11)); + round(inv_rnd, b0, b1, rnd_key(-10)); + //-fallthrough + case 10 * 16: + round(inv_rnd, b1, b0, rnd_key(-9)); + round(inv_rnd, b0, b1, rnd_key(-8)); + round(inv_rnd, b1, b0, rnd_key(-7)); + round(inv_rnd, b0, b1, rnd_key(-6)); + round(inv_rnd, b1, b0, rnd_key(-5)); + round(inv_rnd, b0, b1, rnd_key(-4)); + round(inv_rnd, b1, b0, rnd_key(-3)); + round(inv_rnd, b0, b1, rnd_key(-2)); + round(inv_rnd, b1, b0, rnd_key(-1)); + round(inv_lrnd, b0, b1, rnd_key( 0)); + //-fallthrough + } + +#else + +#if (DEC_UNROLL == PARTIAL) + { uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) + { + kp = rnd_key(1); + round(inv_rnd, b1, b0, kp); + kp = rnd_key(1); + round(inv_rnd, b0, b1, kp); + } + kp = rnd_key(1); + round(inv_rnd, b1, b0, kp); +#else + { uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) + { + kp = rnd_key(1); + round(inv_rnd, b1, b0, kp); + l_copy(b0, b1); + } +#endif + kp = rnd_key(1); + round(inv_lrnd, b0, b1, kp); + } +#endif + + state_out(out, b0); + return EXIT_SUCCESS; +} + +#endif + +#if defined(__cplusplus) +} +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aeskey.c b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aeskey.c new file mode 100644 index 00000000..94119185 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aeskey.c @@ -0,0 +1,562 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 +*/ + +#include "aesopt.h" +#include "aestab.h" + +#if defined( USE_INTEL_AES_IF_PRESENT ) +# include "aes_ni.h" +#else +/* map names here to provide the external API ('name' -> 'aes_name') */ +# define aes_xi(x) aes_ ## x +#endif + +#ifdef USE_VIA_ACE_IF_PRESENT +# include "aes_via_ace.h" +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Initialise the key schedule from the user supplied key. The key + length can be specified in bytes, with legal values of 16, 24 + and 32, or in bits, with legal values of 128, 192 and 256. These + values correspond with Nk values of 4, 6 and 8 respectively. + + The following macros implement a single cycle in the key + schedule generation process. The number of cycles needed + for each cx->n_col and nk value is: + + nk = 4 5 6 7 8 + ------------------------------ + cx->n_col = 4 10 9 8 7 7 + cx->n_col = 5 14 11 10 9 9 + cx->n_col = 6 19 15 12 11 11 + cx->n_col = 7 21 19 16 13 14 + cx->n_col = 8 29 23 19 17 14 +*/ + +#if defined( REDUCE_CODE_SIZE ) +# define ls_box ls_sub + uint32_t ls_sub(const uint32_t t, const uint32_t n); +# define inv_mcol im_sub + uint32_t im_sub(const uint32_t x); +# ifdef ENC_KS_UNROLL +# undef ENC_KS_UNROLL +# endif +# ifdef DEC_KS_UNROLL +# undef DEC_KS_UNROLL +# endif +#endif + +#if (FUNCS_IN_C & ENC_KEYING_IN_C) + +#if defined(AES_128) || defined( AES_VAR ) + +#define ke4(k,i) \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ + k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; \ + k[4*(i)+7] = ss[3] ^= ss[2]; \ +} + +AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ uint32_t ss[4]; + + cx->ks[0] = ss[0] = word_in(key, 0); + cx->ks[1] = ss[1] = word_in(key, 1); + cx->ks[2] = ss[2] = word_in(key, 2); + cx->ks[3] = ss[3] = word_in(key, 3); + +#ifdef ENC_KS_UNROLL + ke4(cx->ks, 0); ke4(cx->ks, 1); + ke4(cx->ks, 2); ke4(cx->ks, 3); + ke4(cx->ks, 4); ke4(cx->ks, 5); + ke4(cx->ks, 6); ke4(cx->ks, 7); + ke4(cx->ks, 8); +#else + { uint32_t i; + for(i = 0; i < 9; ++i) + ke4(cx->ks, i); + } +#endif + ke4(cx->ks, 9); + cx->inf.l = 0; + cx->inf.b[0] = 10 * 16; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + return EXIT_SUCCESS; +} + +#endif + +#if defined(AES_192) || defined( AES_VAR ) + +#define kef6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ + k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; \ + k[6*(i)+ 9] = ss[3] ^= ss[2]; \ +} + +#define ke6(k,i) \ +{ kef6(k,i); \ + k[6*(i)+10] = ss[4] ^= ss[3]; \ + k[6*(i)+11] = ss[5] ^= ss[4]; \ +} + +AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ uint32_t ss[6]; + + cx->ks[0] = ss[0] = word_in(key, 0); + cx->ks[1] = ss[1] = word_in(key, 1); + cx->ks[2] = ss[2] = word_in(key, 2); + cx->ks[3] = ss[3] = word_in(key, 3); + cx->ks[4] = ss[4] = word_in(key, 4); + cx->ks[5] = ss[5] = word_in(key, 5); + +#ifdef ENC_KS_UNROLL + ke6(cx->ks, 0); ke6(cx->ks, 1); + ke6(cx->ks, 2); ke6(cx->ks, 3); + ke6(cx->ks, 4); ke6(cx->ks, 5); + ke6(cx->ks, 6); +#else + { uint32_t i; + for(i = 0; i < 7; ++i) + ke6(cx->ks, i); + } +#endif + kef6(cx->ks, 7); + cx->inf.l = 0; + cx->inf.b[0] = 12 * 16; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + return EXIT_SUCCESS; +} + +#endif + +#if defined(AES_256) || defined( AES_VAR ) + +#define kef8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ + k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; \ + k[8*(i)+11] = ss[3] ^= ss[2]; \ +} + +#define ke8(k,i) \ +{ kef8(k,i); \ + k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \ + k[8*(i)+13] = ss[5] ^= ss[4]; \ + k[8*(i)+14] = ss[6] ^= ss[5]; \ + k[8*(i)+15] = ss[7] ^= ss[6]; \ +} + +AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ uint32_t ss[8]; + + cx->ks[0] = ss[0] = word_in(key, 0); + cx->ks[1] = ss[1] = word_in(key, 1); + cx->ks[2] = ss[2] = word_in(key, 2); + cx->ks[3] = ss[3] = word_in(key, 3); + cx->ks[4] = ss[4] = word_in(key, 4); + cx->ks[5] = ss[5] = word_in(key, 5); + cx->ks[6] = ss[6] = word_in(key, 6); + cx->ks[7] = ss[7] = word_in(key, 7); + +#ifdef ENC_KS_UNROLL + ke8(cx->ks, 0); ke8(cx->ks, 1); + ke8(cx->ks, 2); ke8(cx->ks, 3); + ke8(cx->ks, 4); ke8(cx->ks, 5); +#else + { uint32_t i; + for(i = 0; i < 6; ++i) + ke8(cx->ks, i); + } +#endif + kef8(cx->ks, 6); + cx->inf.l = 0; + cx->inf.b[0] = 14 * 16; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + return EXIT_SUCCESS; +} + +#endif + +#endif + +#if (FUNCS_IN_C & DEC_KEYING_IN_C) + +/* this is used to store the decryption round keys */ +/* in forward or reverse order */ + +#ifdef AES_REV_DKS +#define v(n,i) ((n) - (i) + 2 * ((i) & 3)) +#else +#define v(n,i) (i) +#endif + +#if DEC_ROUND == NO_TABLES +#define ff(x) (x) +#else +#define ff(x) inv_mcol(x) +#if defined( dec_imvars ) +#define d_vars dec_imvars +#endif +#endif + +#if defined(AES_128) || defined( AES_VAR ) + +#define k4e(k,i) \ +{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ + k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \ + k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \ + k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \ +} + +#if 1 + +#define kdf4(k,i) \ +{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \ + ss[1] = ss[1] ^ ss[3]; \ + ss[2] = ss[2] ^ ss[3]; \ + ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ + ss[i % 4] ^= ss[4]; \ + ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \ + ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \ + ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \ + ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \ +} + +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ + ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ + k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \ + k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \ + k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \ + k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \ +} + +#define kdl4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \ + k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \ + k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \ + k[v(40,(4*(i))+6)] = ss[0]; \ + k[v(40,(4*(i))+7)] = ss[1]; \ +} + +#else + +#define kdf4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \ + ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \ + ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \ +} + +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \ + ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \ + ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \ + ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \ +} + +#define kdl4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \ + ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \ + ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \ + ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \ +} + +#endif + +AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ uint32_t ss[5]; +#if defined( d_vars ) + d_vars; +#endif + + cx->ks[v(40,(0))] = ss[0] = word_in(key, 0); + cx->ks[v(40,(1))] = ss[1] = word_in(key, 1); + cx->ks[v(40,(2))] = ss[2] = word_in(key, 2); + cx->ks[v(40,(3))] = ss[3] = word_in(key, 3); + +#ifdef DEC_KS_UNROLL + kdf4(cx->ks, 0); kd4(cx->ks, 1); + kd4(cx->ks, 2); kd4(cx->ks, 3); + kd4(cx->ks, 4); kd4(cx->ks, 5); + kd4(cx->ks, 6); kd4(cx->ks, 7); + kd4(cx->ks, 8); kdl4(cx->ks, 9); +#else + { uint32_t i; + for(i = 0; i < 10; ++i) + k4e(cx->ks, i); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 10 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } +#endif + cx->inf.l = 0; + cx->inf.b[0] = 10 * 16; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + return EXIT_SUCCESS; +} + +#endif + +#if defined(AES_192) || defined( AES_VAR ) + +#define k6ef(k,i) \ +{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ + k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \ + k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \ + k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \ +} + +#define k6e(k,i) \ +{ k6ef(k,i); \ + k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \ + k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \ +} + +#define kdf6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \ + ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \ + ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \ + ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \ + ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \ +} + +#define kd6(k,i) \ +{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \ + ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \ + ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \ + ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \ + ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \ + ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \ +} + +#define kdl6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \ + ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \ + ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \ + ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \ +} + +AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ uint32_t ss[7]; +#if defined( d_vars ) + d_vars; +#endif + + cx->ks[v(48,(0))] = ss[0] = word_in(key, 0); + cx->ks[v(48,(1))] = ss[1] = word_in(key, 1); + cx->ks[v(48,(2))] = ss[2] = word_in(key, 2); + cx->ks[v(48,(3))] = ss[3] = word_in(key, 3); + +#ifdef DEC_KS_UNROLL + ss[4] = word_in(key, 4); + ss[5] = word_in(key, 5); + + cx->ks[v(48,(4))] = ff(ss[4]); + cx->ks[v(48,(5))] = ff(ss[5]); + kdf6(cx->ks, 0); kd6(cx->ks, 1); + kd6(cx->ks, 2); kd6(cx->ks, 3); + kd6(cx->ks, 4); kd6(cx->ks, 5); + kd6(cx->ks, 6); kdl6(cx->ks, 7); +#else + cx->ks[v(48,(4))] = ss[4] = word_in(key, 4); + cx->ks[v(48,(5))] = ss[5] = word_in(key, 5); + { uint32_t i; + + for(i = 0; i < 7; ++i) + k6e(cx->ks, i); + k6ef(cx->ks, 7); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 12 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } +#endif + cx->inf.l = 0; + cx->inf.b[0] = 12 * 16; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + return EXIT_SUCCESS; +} + +#endif + +#if defined(AES_256) || defined( AES_VAR ) + +#define k8ef(k,i) \ +{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ + k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \ + k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \ + k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \ +} + +#define k8e(k,i) \ +{ k8ef(k,i); \ + k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \ + k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \ + k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \ + k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \ +} + +#define kdf8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \ + ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \ + ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \ + ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \ + ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \ + ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \ + ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \ +} + +#define kd8(k,i) \ +{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \ + ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \ + ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \ + ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \ + ss[8] = ls_box(ss[3],0); \ + ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \ + ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \ + ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \ + ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \ +} + +#define kdl8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \ + ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \ + ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \ + ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \ +} + +AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ uint32_t ss[9]; +#if defined( d_vars ) + d_vars; +#endif + + cx->ks[v(56,(0))] = ss[0] = word_in(key, 0); + cx->ks[v(56,(1))] = ss[1] = word_in(key, 1); + cx->ks[v(56,(2))] = ss[2] = word_in(key, 2); + cx->ks[v(56,(3))] = ss[3] = word_in(key, 3); + +#ifdef DEC_KS_UNROLL + ss[4] = word_in(key, 4); + ss[5] = word_in(key, 5); + ss[6] = word_in(key, 6); + ss[7] = word_in(key, 7); + + cx->ks[v(56,(4))] = ff(ss[4]); + cx->ks[v(56,(5))] = ff(ss[5]); + cx->ks[v(56,(6))] = ff(ss[6]); + cx->ks[v(56,(7))] = ff(ss[7]); + kdf8(cx->ks, 0); kd8(cx->ks, 1); + kd8(cx->ks, 2); kd8(cx->ks, 3); + kd8(cx->ks, 4); kd8(cx->ks, 5); + kdl8(cx->ks, 6); +#else + cx->ks[v(56,(4))] = ss[4] = word_in(key, 4); + cx->ks[v(56,(5))] = ss[5] = word_in(key, 5); + cx->ks[v(56,(6))] = ss[6] = word_in(key, 6); + cx->ks[v(56,(7))] = ss[7] = word_in(key, 7); + { uint32_t i; + + for(i = 0; i < 6; ++i) + k8e(cx->ks, i); + k8ef(cx->ks, 6); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 14 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } +#endif + cx->inf.l = 0; + cx->inf.b[0] = 14 * 16; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + return EXIT_SUCCESS; +} + +#endif + +#endif + +#if defined( AES_VAR ) + +AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) +{ + switch(key_len) + { + case 16: case 128: return aes_encrypt_key128(key, cx); + case 24: case 192: return aes_encrypt_key192(key, cx); + case 32: case 256: return aes_encrypt_key256(key, cx); + default: return EXIT_FAILURE; + } +} + +AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) +{ + switch(key_len) + { + case 16: case 128: return aes_decrypt_key128(key, cx); + case 24: case 192: return aes_decrypt_key192(key, cx); + case 32: case 256: return aes_decrypt_key256(key, cx); + default: return EXIT_FAILURE; + } +} + +#endif + +#if defined(__cplusplus) +} +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aesopt.h b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aesopt.h new file mode 100644 index 00000000..a1ef045d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aesopt.h @@ -0,0 +1,778 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 + + This file contains the compilation options for AES (Rijndael) and code + that is common across encryption, key scheduling and table generation. + + OPERATION + + These source code files implement the AES algorithm Rijndael designed by + Joan Daemen and Vincent Rijmen. This version is designed for the standard + block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24 + and 32 bytes). + + This version is designed for flexibility and speed using operations on + 32-bit words rather than operations on bytes. It can be compiled with + either big or little endian internal byte order but is faster when the + native byte order for the processor is used. + + THE CIPHER INTERFACE + + The cipher interface is implemented as an array of bytes in which lower + AES bit sequence indexes map to higher numeric significance within bytes. + + uint8_t (an unsigned 8-bit type) + uint32_t (an unsigned 32-bit type) + struct aes_encrypt_ctx (structure for the cipher encryption context) + struct aes_decrypt_ctx (structure for the cipher decryption context) + AES_RETURN the function return type + + C subroutine calls: + + AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); + AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); + AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); + AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, + const aes_encrypt_ctx cx[1]); + + AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); + AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); + AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); + AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, + const aes_decrypt_ctx cx[1]); + + IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that + you call aes_init() before AES is used so that the tables are initialised. + + C++ aes class subroutines: + + Class AESencrypt for encryption + + Construtors: + AESencrypt(void) + AESencrypt(const unsigned char *key) - 128 bit key + Members: + AES_RETURN key128(const unsigned char *key) + AES_RETURN key192(const unsigned char *key) + AES_RETURN key256(const unsigned char *key) + AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const + + Class AESdecrypt for encryption + Construtors: + AESdecrypt(void) + AESdecrypt(const unsigned char *key) - 128 bit key + Members: + AES_RETURN key128(const unsigned char *key) + AES_RETURN key192(const unsigned char *key) + AES_RETURN key256(const unsigned char *key) + AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const +*/ + +#if !defined( _AESOPT_H ) +#define _AESOPT_H + +#if defined( __cplusplus ) +#include "aescpp.h" +#else +#include "aes.h" +#endif + +/* PLATFORM SPECIFIC INCLUDES */ + +#define IS_BIG_ENDIAN 4321 +#define IS_LITTLE_ENDIAN 1234 +#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN + +/* CONFIGURATION - THE USE OF DEFINES + + Later in this section there are a number of defines that control the + operation of the code. In each section, the purpose of each define is + explained so that the relevant form can be included or excluded by + setting either 1's or 0's respectively on the branches of the related + #if clauses. The following local defines should not be changed. +*/ + +#define ENCRYPTION_IN_C 1 +#define DECRYPTION_IN_C 2 +#define ENC_KEYING_IN_C 4 +#define DEC_KEYING_IN_C 8 + +#define NO_TABLES 0 +#define ONE_TABLE 1 +#define FOUR_TABLES 4 +#define NONE 0 +#define PARTIAL 1 +#define FULL 2 + +/* --- START OF USER CONFIGURED OPTIONS --- */ + +/* 1. BYTE ORDER WITHIN 32 BIT WORDS + + The fundamental data processing units in Rijndael are 8-bit bytes. The + input, output and key input are all enumerated arrays of bytes in which + bytes are numbered starting at zero and increasing to one less than the + number of bytes in the array in question. This enumeration is only used + for naming bytes and does not imply any adjacency or order relationship + from one byte to another. When these inputs and outputs are considered + as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to + byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. + In this implementation bits are numbered from 0 to 7 starting at the + numerically least significant end of each byte (bit n represents 2^n). + + However, Rijndael can be implemented more efficiently using 32-bit + words by packing bytes into words so that bytes 4*n to 4*n+3 are placed + into word[n]. While in principle these bytes can be assembled into words + in any positions, this implementation only supports the two formats in + which bytes in adjacent positions within words also have adjacent byte + numbers. This order is called big-endian if the lowest numbered bytes + in words have the highest numeric significance and little-endian if the + opposite applies. + + This code can work in either order irrespective of the order used by the + machine on which it runs. Normally the internal byte order will be set + to the order of the processor on which the code is to be run but this + define can be used to reverse this in special situations + + WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set. + This define will hence be redefined later (in section 4) if necessary +*/ + +#if 1 +# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER +#elif 0 +# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN +#elif 0 +# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN +#else +# error The algorithm byte order is not defined +#endif + +/* 2. Intel AES AND VIA ACE SUPPORT */ + +#if defined( __GNUC__ ) && defined( __i386__ ) \ + || defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \ + || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 )) +# define VIA_ACE_POSSIBLE +#endif + +#if (defined( _WIN64 ) && defined( _MSC_VER )) \ + || (defined( __GNUC__ ) && defined( __x86_64__ )) \ + && !(defined( INTEL_AES_POSSIBLE )) +# define INTEL_AES_POSSIBLE +#endif + +/* Define this option if support for the Intel AESNI is required + If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used + if it is detected (both present and enabled). + + AESNI uses a decryption key schedule with the first decryption + round key at the high end of the key scedule with the following + round keys at lower positions in memory. So AES_REV_DKS must NOT + be defined when AESNI will be used. ALthough it is unlikely that + assembler code will be used with an AESNI build, if it is then + AES_REV_DKS must NOT be defined when the assembler files are + built +*/ + +#if 0 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT ) +# define USE_INTEL_AES_IF_PRESENT +#endif + +/* Define this option if support for the VIA ACE is required. This uses + inline assembler instructions and is only implemented for the Microsoft, + Intel and GCC compilers. If VIA ACE is known to be present, then defining + ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption + code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if + it is detected (both present and enabled) but the normal AES code will + also be present. + + When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte + aligned; other input/output buffers do not need to be 16 byte aligned + but there are very large performance gains if this can be arranged. + VIA ACE also requires the decryption key schedule to be in reverse + order (which later checks below ensure). + + AES_REV_DKS must be set for assembler code used with a VIA ACE build +*/ + +#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT ) +# define USE_VIA_ACE_IF_PRESENT +#endif + +#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT ) +# define ASSUME_VIA_ACE_PRESENT +# endif + +/* 3. ASSEMBLER SUPPORT + + This define (which can be on the command line) enables the use of the + assembler code routines for encryption, decryption and key scheduling + as follows: + + ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for + encryption and decryption and but with key scheduling in C + ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for + encryption, decryption and key scheduling + ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for + encryption and decryption and but with key scheduling in C + ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for + encryption and decryption and but with key scheduling in C + + Change one 'if 0' below to 'if 1' to select the version or define + as a compilation option. +*/ + +#if 0 && !defined( ASM_X86_V1C ) +# define ASM_X86_V1C +#elif 0 && !defined( ASM_X86_V2 ) +# define ASM_X86_V2 +#elif 0 && !defined( ASM_X86_V2C ) +# define ASM_X86_V2C +#elif 0 && !defined( ASM_AMD64_C ) +# define ASM_AMD64_C +#endif + +#if defined( __i386 ) || defined( _M_IX86 ) +# define A32_ +#elif defined( __x86_64__ ) || defined( _M_X64 ) +# define A64_ +#endif + +#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \ + && !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ ) +# error Assembler code is only available for x86 and AMD64 systems +#endif + +/* 4. FAST INPUT/OUTPUT OPERATIONS. + + On some machines it is possible to improve speed by transferring the + bytes in the input and output arrays to and from the internal 32-bit + variables by addressing these arrays as if they are arrays of 32-bit + words. On some machines this will always be possible but there may + be a large performance penalty if the byte arrays are not aligned on + the normal word boundaries. On other machines this technique will + lead to memory access errors when such 32-bit word accesses are not + properly aligned. The option SAFE_IO avoids such problems but will + often be slower on those machines that support misaligned access + (especially so if care is taken to align the input and output byte + arrays on 32-bit word boundaries). If SAFE_IO is not defined it is + assumed that access to byte arrays as if they are arrays of 32-bit + words will not cause problems when such accesses are misaligned. +*/ +#if 1 && !defined( _MSC_VER ) +# define SAFE_IO +#endif + +/* 5. LOOP UNROLLING + + The code for encryption and decrytpion cycles through a number of rounds + that can be implemented either in a loop or by expanding the code into a + long sequence of instructions, the latter producing a larger program but + one that will often be much faster. The latter is called loop unrolling. + There are also potential speed advantages in expanding two iterations in + a loop with half the number of iterations, which is called partial loop + unrolling. The following options allow partial or full loop unrolling + to be set independently for encryption and decryption +*/ +#if 1 +# define ENC_UNROLL FULL +#elif 0 +# define ENC_UNROLL PARTIAL +#else +# define ENC_UNROLL NONE +#endif + +#if 1 +# define DEC_UNROLL FULL +#elif 0 +# define DEC_UNROLL PARTIAL +#else +# define DEC_UNROLL NONE +#endif + +#if 1 +# define ENC_KS_UNROLL +#endif + +#if 1 +# define DEC_KS_UNROLL +#endif + +/* 6. FAST FINITE FIELD OPERATIONS + + If this section is included, tables are used to provide faster finite + field arithmetic (this has no effect if STATIC_TABLES is defined). +*/ +#if 1 +# define FF_TABLES +#endif + +/* 7. INTERNAL STATE VARIABLE FORMAT + + The internal state of Rijndael is stored in a number of local 32-bit + word varaibles which can be defined either as an array or as individual + names variables. Include this section if you want to store these local + varaibles in arrays. Otherwise individual local variables will be used. +*/ +#if 1 +# define ARRAYS +#endif + +/* 8. FIXED OR DYNAMIC TABLES + + When this section is included the tables used by the code are compiled + statically into the binary file. Otherwise the subroutine aes_init() + must be called to compute them before the code is first used. +*/ +#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) +# define STATIC_TABLES +#endif + +/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES + + In some systems it is better to mask longer values to extract bytes + rather than using a cast. This option allows this choice. +*/ +#if 0 +# define to_byte(x) ((uint8_t)(x)) +#else +# define to_byte(x) ((x) & 0xff) +#endif + +/* 10. TABLE ALIGNMENT + + On some sytsems speed will be improved by aligning the AES large lookup + tables on particular boundaries. This define should be set to a power of + two giving the desired alignment. It can be left undefined if alignment + is not needed. This option is specific to the Microsft VC++ compiler - + it seems to sometimes cause trouble for the VC++ version 6 compiler. +*/ + +#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) +# define TABLE_ALIGN 32 +#endif + +/* 11. REDUCE CODE AND TABLE SIZE + + This replaces some expanded macros with function calls if AES_ASM_V2 or + AES_ASM_V2C are defined +*/ + +#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) +# define REDUCE_CODE_SIZE +#endif + +/* 12. TABLE OPTIONS + + This cipher proceeds by repeating in a number of cycles known as 'rounds' + which are implemented by a round function which can optionally be speeded + up using tables. The basic tables are each 256 32-bit words, with either + one or four tables being required for each round function depending on + how much speed is required. The encryption and decryption round functions + are different and the last encryption and decrytpion round functions are + different again making four different round functions in all. + + This means that: + 1. Normal encryption and decryption rounds can each use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + 2. The last encryption and decryption rounds can also use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + + Include or exclude the appropriate definitions below to set the number + of tables used by this implementation. +*/ + +#if 1 /* set tables for the normal encryption round */ +# define ENC_ROUND FOUR_TABLES +#elif 0 +# define ENC_ROUND ONE_TABLE +#else +# define ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last encryption round */ +# define LAST_ENC_ROUND FOUR_TABLES +#elif 0 +# define LAST_ENC_ROUND ONE_TABLE +#else +# define LAST_ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the normal decryption round */ +# define DEC_ROUND FOUR_TABLES +#elif 0 +# define DEC_ROUND ONE_TABLE +#else +# define DEC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last decryption round */ +# define LAST_DEC_ROUND FOUR_TABLES +#elif 0 +# define LAST_DEC_ROUND ONE_TABLE +#else +# define LAST_DEC_ROUND NO_TABLES +#endif + +/* The decryption key schedule can be speeded up with tables in the same + way that the round functions can. Include or exclude the following + defines to set this requirement. +*/ +#if 1 +# define KEY_SCHED FOUR_TABLES +#elif 0 +# define KEY_SCHED ONE_TABLE +#else +# define KEY_SCHED NO_TABLES +#endif + +/* ---- END OF USER CONFIGURED OPTIONS ---- */ + +/* VIA ACE support is only available for VC++ and GCC */ + +#if !defined( _MSC_VER ) && !defined( __GNUC__ ) +# if defined( ASSUME_VIA_ACE_PRESENT ) +# undef ASSUME_VIA_ACE_PRESENT +# endif +# if defined( USE_VIA_ACE_IF_PRESENT ) +# undef USE_VIA_ACE_IF_PRESENT +# endif +#endif + +#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT ) +# define USE_VIA_ACE_IF_PRESENT +#endif + +/* define to reverse decryption key schedule */ +#if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS ) +# define AES_REV_DKS +#endif + +/* Intel AESNI uses a decryption key schedule in the encryption order */ +#if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS ) +# undef AES_REV_DKS +#endif + +/* Assembler support requires the use of platform byte order */ + +#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \ + && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER) +# undef ALGORITHM_BYTE_ORDER +# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER +#endif + +/* In this implementation the columns of the state array are each held in + 32-bit words. The state array can be held in various ways: in an array + of words, in a number of individual word variables or in a number of + processor registers. The following define maps a variable name x and + a column number c to the way the state array variable is to be held. + The first define below maps the state into an array x[c] whereas the + second form maps the state into a number of individual variables x0, + x1, etc. Another form could map individual state colums to machine + register names. +*/ + +#if defined( ARRAYS ) +# define s(x,c) x[c] +#else +# define s(x,c) x##c +#endif + +/* This implementation provides subroutines for encryption, decryption + and for setting the three key lengths (separately) for encryption + and decryption. Since not all functions are needed, masks are set + up here to determine which will be implemented in C +*/ + +#if !defined( AES_ENCRYPT ) +# define EFUNCS_IN_C 0 +#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ + || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) +# define EFUNCS_IN_C ENC_KEYING_IN_C +#elif !defined( ASM_X86_V2 ) +# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C ) +#else +# define EFUNCS_IN_C 0 +#endif + +#if !defined( AES_DECRYPT ) +# define DFUNCS_IN_C 0 +#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ + || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) +# define DFUNCS_IN_C DEC_KEYING_IN_C +#elif !defined( ASM_X86_V2 ) +# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C ) +#else +# define DFUNCS_IN_C 0 +#endif + +#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C ) + +/* END OF CONFIGURATION OPTIONS */ + +#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) + +/* Disable or report errors on some combinations of options */ + +#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES +# undef LAST_ENC_ROUND +# define LAST_ENC_ROUND NO_TABLES +#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES +# undef LAST_ENC_ROUND +# define LAST_ENC_ROUND ONE_TABLE +#endif + +#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE +# undef ENC_UNROLL +# define ENC_UNROLL NONE +#endif + +#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES +# undef LAST_DEC_ROUND +# define LAST_DEC_ROUND NO_TABLES +#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES +# undef LAST_DEC_ROUND +# define LAST_DEC_ROUND ONE_TABLE +#endif + +#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE +# undef DEC_UNROLL +# define DEC_UNROLL NONE +#endif + +#if defined( bswap32 ) +# define aes_sw32 bswap32 +#elif defined( bswap_32 ) +# define aes_sw32 bswap_32 +#else +# define brot(x,n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n))) +# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00)) +#endif + +/* upr(x,n): rotates bytes within words by n positions, moving bytes to + higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word + + WARNING: The definitions given here are intended only for use with + unsigned variables and with shift counts that are compile + time constants +*/ + +#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN ) +# define upr(x,n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n)))) +# define ups(x,n) ((uint32_t) (x) << (8 * (n))) +# define bval(x,n) to_byte((x) >> (8 * (n))) +# define bytes2word(b0, b1, b2, b3) \ + (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0)) +#endif + +#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN ) +# define upr(x,n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n)))) +# define ups(x,n) ((uint32_t) (x) >> (8 * (n))) +# define bval(x,n) to_byte((x) >> (24 - 8 * (n))) +# define bytes2word(b0, b1, b2, b3) \ + (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3)) +#endif + +#if defined( SAFE_IO ) +# define word_in(x,c) bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \ + ((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3]) +# define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \ + ((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); } +#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER ) +# define word_in(x,c) (*((uint32_t*)(x)+(c))) +# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v)) +#else +# define word_in(x,c) aes_sw32(*((uint32_t*)(x)+(c))) +# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v)) +#endif + +/* the finite field modular polynomial and elements */ + +#define WPOLY 0x011b +#define BPOLY 0x1b + +/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + +#define gf_c1 0x80808080 +#define gf_c2 0x7f7f7f7f +#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY)) + +/* The following defines provide alternative definitions of gf_mulx that might + give improved performance if a fast 32-bit multiply is not available. Note + that a temporary variable u needs to be defined where gf_mulx is used. + +#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6)) +#define gf_c4 (0x01010101 * BPOLY) +#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4) +*/ + +/* Work out which tables are needed for the different options */ + +#if defined( ASM_X86_V1C ) +# if defined( ENC_ROUND ) +# undef ENC_ROUND +# endif +# define ENC_ROUND FOUR_TABLES +# if defined( LAST_ENC_ROUND ) +# undef LAST_ENC_ROUND +# endif +# define LAST_ENC_ROUND FOUR_TABLES +# if defined( DEC_ROUND ) +# undef DEC_ROUND +# endif +# define DEC_ROUND FOUR_TABLES +# if defined( LAST_DEC_ROUND ) +# undef LAST_DEC_ROUND +# endif +# define LAST_DEC_ROUND FOUR_TABLES +# if defined( KEY_SCHED ) +# undef KEY_SCHED +# define KEY_SCHED FOUR_TABLES +# endif +#endif + +#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C ) +# if ENC_ROUND == ONE_TABLE +# define FT1_SET +# elif ENC_ROUND == FOUR_TABLES +# define FT4_SET +# else +# define SBX_SET +# endif +# if LAST_ENC_ROUND == ONE_TABLE +# define FL1_SET +# elif LAST_ENC_ROUND == FOUR_TABLES +# define FL4_SET +# elif !defined( SBX_SET ) +# define SBX_SET +# endif +#endif + +#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C ) +# if DEC_ROUND == ONE_TABLE +# define IT1_SET +# elif DEC_ROUND == FOUR_TABLES +# define IT4_SET +# else +# define ISB_SET +# endif +# if LAST_DEC_ROUND == ONE_TABLE +# define IL1_SET +# elif LAST_DEC_ROUND == FOUR_TABLES +# define IL4_SET +# elif !defined(ISB_SET) +# define ISB_SET +# endif +#endif + +#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) +# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)) +# if KEY_SCHED == ONE_TABLE +# if !defined( FL1_SET ) && !defined( FL4_SET ) +# define LS1_SET +# endif +# elif KEY_SCHED == FOUR_TABLES +# if !defined( FL4_SET ) +# define LS4_SET +# endif +# elif !defined( SBX_SET ) +# define SBX_SET +# endif +# endif +# if (FUNCS_IN_C & DEC_KEYING_IN_C) +# if KEY_SCHED == ONE_TABLE +# define IM1_SET +# elif KEY_SCHED == FOUR_TABLES +# define IM4_SET +# elif !defined( SBX_SET ) +# define SBX_SET +# endif +# endif +#endif + +/* generic definitions of Rijndael macros that use tables */ + +#define no_table(x,box,vf,rf,c) bytes2word( \ + box[bval(vf(x,0,c),rf(0,c))], \ + box[bval(vf(x,1,c),rf(1,c))], \ + box[bval(vf(x,2,c),rf(2,c))], \ + box[bval(vf(x,3,c),rf(3,c))]) + +#define one_table(x,op,tab,vf,rf,c) \ + ( tab[bval(vf(x,0,c),rf(0,c))] \ + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) + +#define four_tables(x,tab,vf,rf,c) \ + ( tab[0][bval(vf(x,0,c),rf(0,c))] \ + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ + ^ tab[3][bval(vf(x,3,c),rf(3,c))]) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((8+r-c)&3) + +/* perform forward and inverse column mix operation on four bytes in long word x in */ +/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ + +#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) + +#if defined( FM4_SET ) /* not currently used */ +# define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0) +#elif defined( FM1_SET ) /* not currently used */ +# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0) +#else +# define dec_fmvars uint32_t g2 +# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1)) +#endif + +#if defined( IM4_SET ) +# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0) +#elif defined( IM1_SET ) +# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0) +#else +# define dec_imvars uint32_t g2, g4, g9 +# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \ + (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1)) +#endif + +#if defined( FL4_SET ) +# define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c) +#elif defined( LS4_SET ) +# define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c) +#elif defined( FL1_SET ) +# define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c) +#elif defined( LS1_SET ) +# define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c) +#else +# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c) +#endif + +#endif + +#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET ) +# define ISB_SET +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.c b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.c new file mode 100644 index 00000000..3d48edf3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.c @@ -0,0 +1,418 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 +*/ + +#define DO_TABLES + +#include "aes.h" +#include "aesopt.h" + +#if defined(STATIC_TABLES) + +#define sb_data(w) {\ + w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ + w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ + w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ + w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ + w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ + w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ + w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ + w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ + w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ + w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ + w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ + w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ + w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ + w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ + w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ + w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ + w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ + w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ + w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ + w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ + w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ + w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ + w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ + w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ + w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ + w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ + w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ + w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ + w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ + w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ + w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ + w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } + +#define isb_data(w) {\ + w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ + w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ + w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ + w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ + w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ + w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ + w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ + w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ + w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ + w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ + w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ + w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ + w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ + w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ + w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ + w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ + w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ + w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ + w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ + w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ + w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ + w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ + w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ + w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ + w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ + w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ + w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ + w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ + w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ + w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ + w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ + w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) } + +#define mm_data(w) {\ + w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ + w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ + w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ + w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ + w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ + w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ + w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ + w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ + w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ + w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ + w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ + w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ + w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ + w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ + w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ + w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ + w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ + w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ + w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ + w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ + w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ + w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ + w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ + w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ + w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ + w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ + w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ + w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ + w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ + w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ + w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ + w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) } + +#define rc_data(w) {\ + w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\ + w(0x1b), w(0x36) } + +#define h0(x) (x) + +#define w0(p) bytes2word(p, 0, 0, 0) +#define w1(p) bytes2word(0, p, 0, 0) +#define w2(p) bytes2word(0, 0, p, 0) +#define w3(p) bytes2word(0, 0, 0, p) + +#define u0(p) bytes2word(f2(p), p, p, f3(p)) +#define u1(p) bytes2word(f3(p), f2(p), p, p) +#define u2(p) bytes2word(p, f3(p), f2(p), p) +#define u3(p) bytes2word(p, p, f3(p), f2(p)) + +#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) +#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) +#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) +#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) + +#endif + +#if defined(STATIC_TABLES) || !defined(FF_TABLES) + +#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) +#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) +#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ + ^ (((x>>5) & 4) * WPOLY)) +#define f3(x) (f2(x) ^ x) +#define f9(x) (f8(x) ^ x) +#define fb(x) (f8(x) ^ f2(x) ^ x) +#define fd(x) (f8(x) ^ f4(x) ^ x) +#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) + +#else + +#define f2(x) ((x) ? pow[log[x] + 0x19] : 0) +#define f3(x) ((x) ? pow[log[x] + 0x01] : 0) +#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0) +#define fb(x) ((x) ? pow[log[x] + 0x68] : 0) +#define fd(x) ((x) ? pow[log[x] + 0xee] : 0) +#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0) + +#endif + +#include "aestab.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if defined(STATIC_TABLES) + +/* implemented in case of wrong call for fixed tables */ + +AES_RETURN aes_init(void) +{ + return EXIT_SUCCESS; +} + +#else /* Generate the tables for the dynamic table option */ + +#if defined(FF_TABLES) + +#define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0) + +#else + +/* It will generally be sensible to use tables to compute finite + field multiplies and inverses but where memory is scarse this + code might sometimes be better. But it only has effect during + initialisation so its pretty unimportant in overall terms. +*/ + +/* return 2 ^ (n - 1) where n is the bit number of the highest bit + set in x with x in the range 1 < x < 0x00000200. This form is + used so that locals within fi can be bytes rather than words +*/ + +static uint8_t hibit(const uint32_t x) +{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2)); + + r |= (r >> 2); + r |= (r >> 4); + return (r + 1) >> 1; +} + +/* return the inverse of the finite field element x */ + +static uint8_t gf_inv(const uint8_t x) +{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; + + if(x < 2) + return x; + + for( ; ; ) + { + if(n1) + while(n2 >= n1) /* divide polynomial p2 by p1 */ + { + n2 /= n1; /* shift smaller polynomial left */ + p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */ + v2 ^= v1 * n2; /* shift accumulated value and */ + n2 = hibit(p2); /* add into result */ + } + else + return v1; + + if(n2) /* repeat with values swapped */ + while(n1 >= n2) + { + n1 /= n2; + p1 ^= p2 * n1; + v1 ^= v2 * n1; + n1 = hibit(p1); + } + else + return v2; + } +} + +#endif + +/* The forward and inverse affine transformations used in the S-box */ +uint8_t fwd_affine(const uint8_t x) +{ uint32_t w = x; + w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4); + return 0x63 ^ ((w ^ (w >> 8)) & 0xff); +} + +uint8_t inv_affine(const uint8_t x) +{ uint32_t w = x; + w = (w << 1) ^ (w << 3) ^ (w << 6); + return 0x05 ^ ((w ^ (w >> 8)) & 0xff); +} + +static int init = 0; + +AES_RETURN aes_init(void) +{ uint32_t i, w; + +#if defined(FF_TABLES) + + uint8_t pow[512], log[256]; + + if(init) + return EXIT_SUCCESS; + /* log and power tables for GF(2^8) finite field with + WPOLY as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables + */ + + i = 0; w = 1; + do + { + pow[i] = (uint8_t)w; + pow[i + 255] = (uint8_t)w; + log[w] = (uint8_t)i++; + w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); + } + while (w != 1); + +#else + if(init) + return EXIT_SUCCESS; +#endif + + for(i = 0, w = 1; i < RC_LENGTH; ++i) + { + t_set(r,c)[i] = bytes2word(w, 0, 0, 0); + w = f2(w); + } + + for(i = 0; i < 256; ++i) + { uint8_t b; + + b = fwd_affine(gf_inv((uint8_t)i)); + w = bytes2word(f2(b), b, b, f3(b)); + +#if defined( SBX_SET ) + t_set(s,box)[i] = b; +#endif + +#if defined( FT1_SET ) /* tables for a normal encryption round */ + t_set(f,n)[i] = w; +#endif +#if defined( FT4_SET ) + t_set(f,n)[0][i] = w; + t_set(f,n)[1][i] = upr(w,1); + t_set(f,n)[2][i] = upr(w,2); + t_set(f,n)[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); + +#if defined( FL1_SET ) /* tables for last encryption round (may also */ + t_set(f,l)[i] = w; /* be used in the key schedule) */ +#endif +#if defined( FL4_SET ) + t_set(f,l)[0][i] = w; + t_set(f,l)[1][i] = upr(w,1); + t_set(f,l)[2][i] = upr(w,2); + t_set(f,l)[3][i] = upr(w,3); +#endif + +#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/ + t_set(l,s)[i] = w; /* not of the required form */ +#endif +#if defined( LS4_SET ) + t_set(l,s)[0][i] = w; + t_set(l,s)[1][i] = upr(w,1); + t_set(l,s)[2][i] = upr(w,2); + t_set(l,s)[3][i] = upr(w,3); +#endif + + b = gf_inv(inv_affine((uint8_t)i)); + w = bytes2word(fe(b), f9(b), fd(b), fb(b)); + +#if defined( IM1_SET ) /* tables for the inverse mix column operation */ + t_set(i,m)[b] = w; +#endif +#if defined( IM4_SET ) + t_set(i,m)[0][b] = w; + t_set(i,m)[1][b] = upr(w,1); + t_set(i,m)[2][b] = upr(w,2); + t_set(i,m)[3][b] = upr(w,3); +#endif + +#if defined( ISB_SET ) + t_set(i,box)[i] = b; +#endif +#if defined( IT1_SET ) /* tables for a normal decryption round */ + t_set(i,n)[i] = w; +#endif +#if defined( IT4_SET ) + t_set(i,n)[0][i] = w; + t_set(i,n)[1][i] = upr(w,1); + t_set(i,n)[2][i] = upr(w,2); + t_set(i,n)[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); +#if defined( IL1_SET ) /* tables for last decryption round */ + t_set(i,l)[i] = w; +#endif +#if defined( IL4_SET ) + t_set(i,l)[0][i] = w; + t_set(i,l)[1][i] = upr(w,1); + t_set(i,l)[2][i] = upr(w,2); + t_set(i,l)[3][i] = upr(w,3); +#endif + } + init = 1; + return EXIT_SUCCESS; +} + +/* + Automatic code initialisation (suggested by by Henrik S. Gaßmann) + based on code provided by Joe Lowe and placed in the public domain at: + http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc +*/ + +#ifdef _MSC_VER + +#pragma section(".CRT$XCU", read) + +__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init; + +#elif defined(__GNUC__) + +static void aes_startup(void) __attribute__((constructor)); + +static void aes_startup(void) +{ + aes_init(); +} + +#else + +#pragma message( "dynamic tables must be initialised manually on your system" ) + +#endif + +#endif + +#if defined(__cplusplus) +} +#endif + diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.h b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.h new file mode 100644 index 00000000..8fe32d18 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestab.h @@ -0,0 +1,173 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 + + This file contains the code for declaring the tables needed to implement + AES. The file aesopt.h is assumed to be included before this header file. + If there are no global variables, the definitions here can be used to put + the AES tables in a structure so that a pointer can then be added to the + AES context to pass them to the AES routines that need them. If this + facility is used, the calling program has to ensure that this pointer is + managed appropriately. In particular, the value of the t_dec(in,it) item + in the table structure must be set to zero in order to ensure that the + tables are initialised. In practice the three code sequences in aeskey.c + that control the calls to aes_init() and the aes_init() routine itself will + have to be changed for a specific implementation. If global variables are + available it will generally be preferable to use them with the precomputed + STATIC_TABLES option that uses static global tables. + + The following defines can be used to control the way the tables + are defined, initialised and used in embedded environments that + require special features for these purposes + + the 't_dec' construction is used to declare fixed table arrays + the 't_set' construction is used to set fixed table values + the 't_use' construction is used to access fixed table values + + 256 byte tables: + + t_xxx(s,box) => forward S box + t_xxx(i,box) => inverse S box + + 256 32-bit word OR 4 x 256 32-bit word tables: + + t_xxx(f,n) => forward normal round + t_xxx(f,l) => forward last round + t_xxx(i,n) => inverse normal round + t_xxx(i,l) => inverse last round + t_xxx(l,s) => key schedule table + t_xxx(i,m) => key schedule table + + Other variables and tables: + + t_xxx(r,c) => the rcon table +*/ + +#if !defined( _AESTAB_H ) +#define _AESTAB_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#define t_dec(m,n) t_##m##n +#define t_set(m,n) t_##m##n +#define t_use(m,n) t_##m##n + +#if defined(STATIC_TABLES) +# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ )) +/* make tables far data to avoid using too much DGROUP space (PG) */ +# define CONST const far +# else +# define CONST const +# endif +#else +# define CONST +#endif + +#if defined(DO_TABLES) +# define EXTERN +#else +# define EXTERN extern +#endif + +#if defined(_MSC_VER) && defined(TABLE_ALIGN) +#define ALIGN __declspec(align(TABLE_ALIGN)) +#else +#define ALIGN +#endif + +#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 ) +# define XP_DIR __cdecl +#else +# define XP_DIR +#endif + +#if defined(DO_TABLES) && defined(STATIC_TABLES) +#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) +#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) } +EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0); +#else +#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] +#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] +EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH]; +#endif + +#if defined( SBX_SET ) + d_1(uint8_t, t_dec(s,box), sb_data, h0); +#endif +#if defined( ISB_SET ) + d_1(uint8_t, t_dec(i,box), isb_data, h0); +#endif + +#if defined( FT1_SET ) + d_1(uint32_t, t_dec(f,n), sb_data, u0); +#endif +#if defined( FT4_SET ) + d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3); +#endif + +#if defined( FL1_SET ) + d_1(uint32_t, t_dec(f,l), sb_data, w0); +#endif +#if defined( FL4_SET ) + d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3); +#endif + +#if defined( IT1_SET ) + d_1(uint32_t, t_dec(i,n), isb_data, v0); +#endif +#if defined( IT4_SET ) + d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3); +#endif + +#if defined( IL1_SET ) + d_1(uint32_t, t_dec(i,l), isb_data, w0); +#endif +#if defined( IL4_SET ) + d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3); +#endif + +#if defined( LS1_SET ) +#if defined( FL1_SET ) +#undef LS1_SET +#else + d_1(uint32_t, t_dec(l,s), sb_data, w0); +#endif +#endif + +#if defined( LS4_SET ) +#if defined( FL4_SET ) +#undef LS4_SET +#else + d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3); +#endif +#endif + +#if defined( IM1_SET ) + d_1(uint32_t, t_dec(i,m), mm_data, v0); +#endif +#if defined( IM4_SET ) + d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.c b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.c new file mode 100644 index 00000000..bc54814b --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.c @@ -0,0 +1,178 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 20/12/2007 +*/ + +// Correct Output (for variable block size - AES_BLOCK_SIZE undefined): + +// lengths: block = 16 bytes, key = 16 bytes +// key = 2b7e151628aed2a6abf7158809cf4f3c +// input = 3243f6a8885a308d313198a2e0370734 +// encrypt = 3925841d02dc09fbdc118597196a0b32 +// decrypt = 3243f6a8885a308d313198a2e0370734 + +// lengths: block = 16 bytes, key = 24 bytes +// key = 2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da5 +// input = 3243f6a8885a308d313198a2e0370734 +// encrypt = f9fb29aefc384a250340d833b87ebc00 +// decrypt = 3243f6a8885a308d313198a2e0370734 + +// lengths: block = 16 bytes, key = 32 bytes +// key = 2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe +// input = 3243f6a8885a308d313198a2e0370734 +// encrypt = 1a6e6c2c662e7da6501ffb62bc9e93f3 +// decrypt = 3243f6a8885a308d313198a2e0370734 + +#include +#include + +#include "aes.h" +#include "aestst.h" + +void out_state(long s0, long s1, long s2, long s3) +{ + printf("\n%08lx%08lx%08lx%08lx", s0, s1, s2, s3); +} + +void oblk(char m[], unsigned char v[], unsigned long n) +{ unsigned long i; + + printf("\n%s", m); + + for(i = 0; i < n; ++i) + printf("%02x", v[i]); +} + +void message(const char *s) { printf("%s", s); } + +unsigned char pih[32] = // hex digits of pi +{ + 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, + 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34, + 0x4a, 0x40, 0x93, 0x82, 0x22, 0x99, 0xf3, 0x1d, + 0x00, 0x82, 0xef, 0xa9, 0x8e, 0xc4, 0xe6, 0xc8 +}; + +unsigned char exh[32] = // hex digits of e +{ + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + 0x76, 0x2e, 0x71, 0x60, 0xf3, 0x8b, 0x4d, 0xa5, + 0x6a, 0x78, 0x4d, 0x90, 0x45, 0x19, 0x0c, 0xfe +}; + +unsigned char res[3][32] = +{ + { 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, + 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 + }, + { 0xf9, 0xfb, 0x29, 0xae, 0xfc, 0x38, 0x4a, 0x25, + 0x03, 0x40, 0xd8, 0x33, 0xb8, 0x7e, 0xbc, 0x00 + }, + { 0x1a, 0x6e, 0x6c, 0x2c, 0x66, 0x2e, 0x7d, 0xa6, + 0x50, 0x1f, 0xfb, 0x62, 0xbc, 0x9e, 0x93, 0xf3 + } +}; + +void cycles(volatile uint64_t *rtn) +{ +#if defined( _MSCVER ) + __asm // read the Pentium Time Stamp Counter + { cpuid + rdtsc + mov ecx,rtn + mov [ecx],eax + mov [ecx+4],edx + cpuid + } +#elif defined( __GNUC__ ) + __asm__ __volatile__("rdtsc": "=A" (*rtn)); +#endif +} + +int main(void) +{ unsigned char out[32], ret[32], err = 0; + f_ectx alge[1]; + f_dctx algd[1]; + + aes_init(); + + message("\nRun tests for the AES algorithm"); + + memset(&alge, 0, sizeof(aes_encrypt_ctx)); + memset(&algd, 0, sizeof(aes_decrypt_ctx)); + +#if defined( AES_128 ) + memset(out, 0xcc, 16); memset(ret, 0xcc, 16); + printf("\n\n// lengths: block = 16, bytes, key = 16 bytes"); + f_enc_key128(alge, exh); + oblk("// key = ", exh, 16); + oblk("// input = ", pih, 16); + do_enc(alge, pih, out, 1); + oblk("// encrypt = ", out, 16); + if(memcmp(out, res[0], 16)) { message (" error"); err += 1; } + f_dec_key128(algd, exh); + do_dec(algd, out, ret, 1); + oblk("// decrypt = ", ret, 16); + if(memcmp(ret, pih, 16)) { message (" error"); err += 2; } +#endif + +#if defined( AES_192 ) + memset(out, 0xcc, 16); memset(ret, 0xcc, 16); + printf("\n\n// lengths: block = 16, bytes, key = 24 bytes"); + f_enc_key192(alge, exh); + oblk("// key = ", exh, 24); + oblk("// input = ", pih, 16); + do_enc(alge, pih, out, 1); + oblk("// encrypt = ", out, 16); + if(memcmp(out, res[1], 16)) { message (" error"); err += 4; } + f_dec_key192(algd, exh); + do_dec(algd, out, ret, 1); + oblk("// decrypt = ", ret, 16); + if(memcmp(ret, pih, 16)) { message (" error"); err += 8; } +#endif + +#if defined( AES_256 ) + memset(out, 0xcc, 16); memset(ret, 0xcc, 16); + printf("\n\n// lengths: block = 16, bytes, key = 32 bytes"); + f_enc_key256(alge, exh); + oblk("// key = ", exh, 32); + oblk("// input = ", pih, 16); + do_enc(alge, pih, out, 1); + oblk("// encrypt = ", out, 16); + if(memcmp(out, res[2], 16)) { message (" error"); err += 16; } + f_dec_key256(algd, exh); + do_dec(algd, out, ret, 1); + oblk("// decrypt = ", ret, 16); + if(memcmp(ret, pih, 16)) { message (" error"); err += 32; } +#endif + + if(!err) + message("\n\nThese values are all correct\n\n"); + else + message("\n\nSome values are in error\n\n"); + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.h b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.h new file mode 100644 index 00000000..1689e63c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/aestst.h @@ -0,0 +1,85 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 +*/ + +// The following definitions are required for testing only, They are not needed +// for AES (Rijndael) implementation. They are used to allow C, C++ and DLL +// data access and subroutine calls to be expressed in the same form in the +// testing code. + +#ifndef AESTST_H +#define AESTST_H + +#define f_info(x) (x)->inf.b[2] +#define f_ectx aes_encrypt_ctx +#define f_enc_key128(a,b) aes_encrypt_key128((b),(a)) +#define f_enc_key192(a,b) aes_encrypt_key192((b),(a)) +#define f_enc_key256(a,b) aes_encrypt_key256((b),(a)) +#define f_enc_key(a,b,c) aes_encrypt_key((b),(c),(a)) +#define f_enc_blk(a,b,c) aes_encrypt((b),(c),(a)) + +#define f_dctx aes_decrypt_ctx +#define f_dec_key128(a,b) aes_decrypt_key128((b),(a)) +#define f_dec_key192(a,b) aes_decrypt_key192((b),(a)) +#define f_dec_key256(a,b) aes_decrypt_key256((b),(a)) +#define f_dec_key(a,b,c) aes_decrypt_key((b),(c),(a)) +#define f_dec_blk(a,b,c) aes_decrypt((b),(c),(a)) + +#define f_talign(a,b) aes_test_alignment_detection(b) +#define f_mode_reset(a) aes_mode_reset(a) +#define f_ecb_enc(a,b,c,d) aes_ecb_encrypt((b),(c),(d),(a)) +#define f_ecb_dec(a,b,c,d) aes_ecb_decrypt((b),(c),(d),(a)) +#define f_cbc_enc(a,b,c,d,e) aes_cbc_encrypt((b),(c),(d),(e),(a)) +#define f_cbc_dec(a,b,c,d,e) aes_cbc_decrypt((b),(c),(d),(e),(a)) +#define f_cfb_enc(a,b,c,d,e) aes_cfb_encrypt((b),(c),(d),(e),(a)) +#define f_cfb_dec(a,b,c,d,e) aes_cfb_decrypt((b),(c),(d),(e),(a)) +#define f_ofb_cry(a,b,c,d,e) aes_ofb_crypt((b),(c),(d),(e),(a)) +#define f_ctr_cry(a,b,c,d,e,f) aes_ctr_crypt((b),(c),(d),(e),(f),(a)) + +#define ek_name128 "aes_encrypt_key128" +#define ek_name192 "aes_encrypt_key192" +#define ek_name256 "aes_encrypt_key256" +#define ek_name "aes_encrypt_key" +#define eb_name "aes_encrypt" + +#define dk_name128 "aes_decrypt_key128" +#define dk_name192 "aes_decrypt_key192" +#define dk_name256 "aes_decrypt_key256" +#define dk_name "aes_decrypt_key" +#define db_name "aes_decrypt" + +#define eres_name "aes_mode_reset" +#define ecbe_name "aes_ecb_encrypt" +#define ecbd_name "aes_ecb_decrypt" +#define cbce_name "aes_cbc_encrypt" +#define cbcd_name "aes_cbc_decrypt" +#define cfbe_name "aes_cfb_encrypt" +#define cfbd_name "aes_cfb_decrypt" +#define ofb_name "aes_ofb_crypt" +#define ctr_name "aes_ctr_crypt" + +#ifndef AES_N_BLOCK +#define do_enc(a,b,c,d) f_enc_blk(a, b, c) +#define do_dec(a,b,c,d) f_dec_blk(a, b, c) +#else +#define do_enc(a,b,c,d) f_ecb_enc(a, b, c, AES_BLOCK_SIZE) +#define do_dec(a,b,c,d) f_ecb_dec(a, b, c, AES_BLOCK_SIZE) +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/aes/brg_types.h b/hardware-wallet/firmware/vendor/trezor-crypto/aes/brg_types.h new file mode 100644 index 00000000..307319bf --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/aes/brg_types.h @@ -0,0 +1,191 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 + + The unsigned integer types defined here are of the form uint_t where + is the length of the type; for example, the unsigned 32-bit type is + 'uint32_t'. These are NOT the same as the 'C99 integer types' that are + defined in the inttypes.h and stdint.h headers since attempts to use these + types have shown that support for them is still highly variable. However, + since the latter are of the form uint_t, a regular expression search + and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t') + can be used to convert the types used here to the C99 standard types. +*/ + +#ifndef _BRG_TYPES_H +#define _BRG_TYPES_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include + +#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) +# include +# define ptrint_t intptr_t +#elif defined( __ECOS__ ) +# define intptr_t unsigned int +# define ptrint_t intptr_t +#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) +# define ptrint_t intptr_t +#else +# define ptrint_t int +#endif + +#ifndef BRG_UI32 +# define BRG_UI32 +# if UINT_MAX == 4294967295u +# define li_32(h) 0x##h##u +# elif ULONG_MAX == 4294967295u +# define li_32(h) 0x##h##ul +# elif defined( _CRAY ) +# error This code needs 32-bit data types, which Cray machines do not provide +# else +# error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h +# endif +#endif + +#ifndef BRG_UI64 +# if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 +# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */ +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 +# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# elif defined( __MVS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u +# if UINT_MAX == 18446744073709551615u +# define BRG_UI64 +# define li_64(h) 0x##h##u +# endif +# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u +# if ULONG_MAX == 18446744073709551615ul +# define BRG_UI64 +# define li_64(h) 0x##h##ul +# endif +# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u +# if ULLONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# endif +# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u +# if ULONG_LONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# endif +# endif +#endif + +#if !defined( BRG_UI64 ) +# if defined( NEED_UINT_64T ) +# error Please define uint64_t as an unsigned 64 bit type in brg_types.h +# endif +#endif + +#ifndef RETURN_VALUES +# define RETURN_VALUES +# if defined( DLL_EXPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllexport ) void __stdcall +# define INT_RETURN __declspec( dllexport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllexport__ ) void +# define INT_RETURN __declspec( __dllexport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( DLL_IMPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllimport ) void __stdcall +# define INT_RETURN __declspec( dllimport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllimport__ ) void +# define INT_RETURN __declspec( __dllimport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( __WATCOMC__ ) +# define VOID_RETURN void __cdecl +# define INT_RETURN int __cdecl +# else +# define VOID_RETURN void +# define INT_RETURN int +# endif +#endif + +/* These defines are used to detect and set the memory alignment of pointers. + Note that offsets are in bytes. + + ALIGN_OFFSET(x,n) return the positive or zero offset of + the memory addressed by the pointer 'x' + from an address that is aligned on an + 'n' byte boundary ('n' is a power of 2) + + ALIGN_FLOOR(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not higher than the memory address + pointed to by 'x' ('n' is a power of 2) + + ALIGN_CEIL(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not lower than the memory address + pointed to by 'x' ('n' is a power of 2) +*/ + +#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1)) +#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1))) +#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1))) + +/* These defines are used to declare buffers in a way that allows + faster operations on longer variables to be used. In all these + defines 'size' must be a power of 2 and >= 8. NOTE that the + buffer size is in bytes but the type length is in bits + + UNIT_TYPEDEF(x,size) declares a variable 'x' of length + 'size' bits + + BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize' + bytes defined as an array of variables + each of 'size' bits (bsize must be a + multiple of size / 8) + + UNIT_CAST(x,size) casts a variable to a type of + length 'size' bits + + UPTR_CAST(x,size) casts a pointer to a pointer to a + varaiable of length 'size' bits +*/ + +#define UI_TYPE(size) uint##size##_t +#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x +#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)] +#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x)) +#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x)) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/base32.c b/hardware-wallet/firmware/vendor/trezor-crypto/base32.c new file mode 100644 index 00000000..06760cca --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/base32.c @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, E1PRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "base32.h" + +#include + +const char *BASE32_ALPHABET_RFC4648 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789"; + +static inline void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out); +static inline bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out, const char *alphabet); +static inline void base32_8to5_raw(const uint8_t *in, uint8_t length, uint8_t *out); + +static inline int base32_encode_character(uint8_t decoded, const char *alphabet); +static inline int base32_decode_character(char encoded, const char *alphabet); + +char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, const char *alphabet) { + size_t length = base32_encoded_length(inlen); + if (outlen <= length) { + return NULL; + } + + base32_encode_unsafe(in, inlen, (uint8_t *) out); + + for (size_t i = 0; i < length; i++) { + int ret = base32_encode_character(out[i], alphabet); + + if (ret == -1) { + return false; + } else { + out[i] = ret; + } + } + + out[length] = '\0'; + return &out[length]; +} + +uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out, size_t outlen, const char *alphabet) { + size_t length = base32_decoded_length(inlen); + if (outlen < length) { + return NULL; + } + + if (!base32_decode_unsafe((uint8_t *) in, inlen, (uint8_t *) out, alphabet)) { + return NULL; + } + + return &out[length]; +} + +void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out) { + uint8_t remainder = inlen % 5; + size_t limit = inlen - remainder; + + size_t i, j; + for (i = 0, j = 0; i < limit; i += 5, j += 8) { + base32_5to8(&in[i], 5, &out[j]); + } + + if (remainder) base32_5to8(&in[i], remainder, &out[j]); +} + +bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, const char *alphabet) { + uint8_t remainder = inlen % 8; + size_t limit = inlen - remainder; + + size_t i, j; + for (i = 0, j = 0; i < limit; i += 8, j += 5) { + if (!base32_8to5(&in[i], 8, &out[j], alphabet)) { + return false; + } + } + + if (remainder && !base32_8to5(&in[i], remainder, &out[j], alphabet)) { + return false; + } + + return true; +} + +size_t base32_encoded_length(size_t inlen) { + uint8_t remainder = inlen % 5; + + return (inlen / 5) * 8 + (remainder * 8 + 4) / 5; +} + +size_t base32_decoded_length(size_t inlen) { + uint8_t remainder = inlen % 8; + + return (inlen / 8) * 5 + (remainder * 5) / 8; +} + +void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out) { + if (length >= 1) { + out[0] = (in[0] >> 3); + out[1] = (in[0] & 7) << 2; + } + + if (length >= 2) { + out[1] |= (in[1] >> 6); + out[2] = (in[1] >> 1) & 31; + out[3] = (in[1] & 1) << 4; + } + + if (length >= 3) { + out[3] |= (in[2] >> 4); + out[4] = (in[2] & 15) << 1; + } + + if (length >= 4) { + out[4] |= (in[3] >> 7); + out[5] = (in[3] >> 2) & 31; + out[6] = (in[3] & 3) << 3; + } + + if (length >= 5) { + out[6] |= (in[4] >> 5); + out[7] = (in[4] & 31); + } +} + +bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out, const char *alphabet) { + if (length == 1 || length == 3 || length == 6 || length > 8) { + return false; + } + + if (alphabet) { + uint8_t decoded[length]; + + for (size_t i = 0; i < length; i++) { + int ret = base32_decode_character(in[i], alphabet); + + if (ret == -1) { + return false; + } else { + decoded[i] = ret; + } + } + + base32_8to5_raw(decoded, length, out); + } else { + base32_8to5_raw(in, length, out); + } + + return true; +} + +void base32_8to5_raw(const uint8_t *in, uint8_t length, uint8_t *out) { + if (length >= 2) { + out[0] = (in[0] << 3); + out[0] |= (in[1] >> 2); + } + + if (length >= 4) { + out[1] = (in[1] & 3) << 6; + out[1] |= (in[2] << 1); + out[1] |= (in[3] >> 4); + } + + if (length >= 5) { + out[2] = (in[3] & 15) << 4; + out[2] |= (in[4] >> 1); + } + + if (length >= 7) { + out[3] = (in[4] & 1) << 7; + out[3] |= (in[5] << 2); + out[3] |= (in[6] >> 3); + } + + if (length >= 8) { + out[4] = (in[6] & 7) << 5; + out[4] |= (in[7] & 31); + } +} + +int base32_encode_character(uint8_t decoded, const char *alphabet) { + if (decoded >> 5) { + return -1; + } + + if (alphabet == BASE32_ALPHABET_RFC4648) { + if (decoded < 26) { + return 'A' + decoded; + } else { + return '2' - 26 + decoded; + } + } + + return alphabet[decoded]; +} + +int base32_decode_character(char encoded, const char *alphabet) { + if (alphabet == BASE32_ALPHABET_RFC4648) { + if (encoded >= 'A' && encoded <= 'Z') { + return encoded - 'A'; + } else if (encoded >= 'a' && encoded <= 'z') { + return encoded - 'a'; + } else if (encoded >= '2' && encoded <= '7') { + return encoded - '2' + 26; + } else { + return -1; + } + } + + const char *occurrence = strchr(alphabet, encoded); + + if (occurrence) { + return occurrence - alphabet; + } else { + return -1; + } +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/base32.h b/hardware-wallet/firmware/vendor/trezor-crypto/base32.h new file mode 100644 index 00000000..25099796 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/base32.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __BASE32_H__ +#define __BASE32_H__ + +#include +#include +#include + +extern const char *BASE32_ALPHABET_RFC4648; + +char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, const char *alphabet); +void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out); + +uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out, size_t outlen, const char *alphabet); +bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, const char *alphabet); + +size_t base32_encoded_length(size_t inlen); +size_t base32_decoded_length(size_t inlen); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/base58.c b/hardware-wallet/firmware/vendor/trezor-crypto/base58.c new file mode 100644 index 00000000..c3e96069 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/base58.c @@ -0,0 +1,278 @@ +/** + * Copyright (c) 2012-2014 Luke Dashjr + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "base58.h" +#include "sha2.h" +#include "ripemd160.h" +#include "memzero.h" + +static const int8_t b58digits_map[] = { + -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, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1, + -1, 9,10,11,12,13,14,15,16,-1,17,18,19,20,21,-1, + 22,23,24,25,26,27,28,29,30,31,32,-1,-1,-1,-1,-1, + -1,33,34,35,36,37,38,39,40,41,42,43,-1,44,45,46, + 47,48,49,50,51,52,53,54,55,56,57,-1,-1,-1,-1,-1, +}; + +bool b58tobin(void *bin, size_t *binszp, const char *b58) +{ + size_t binsz = *binszp; + const unsigned char *b58u = (const unsigned char*)b58; + unsigned char *binu = bin; + size_t outisz = (binsz + 3) / 4; + uint32_t outi[outisz]; + uint64_t t; + uint32_t c; + size_t i, j; + uint8_t bytesleft = binsz % 4; + uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0; + unsigned zerocount = 0; + size_t b58sz; + + b58sz = strlen(b58); + + memset(outi, 0, outisz * sizeof(*outi)); + + // Leading zeros, just count + for (i = 0; i < b58sz && b58u[i] == '1'; ++i) + ++zerocount; + + for ( ; i < b58sz; ++i) + { + if (b58u[i] & 0x80) + // High-bit set on invalid digit + return false; + if (b58digits_map[b58u[i]] == -1) + // Invalid base58 digit + return false; + c = (unsigned)b58digits_map[b58u[i]]; + for (j = outisz; j--; ) + { + t = ((uint64_t)outi[j]) * 58 + c; + c = (t & 0x3f00000000) >> 32; + outi[j] = t & 0xffffffff; + } + if (c) + // Output number too big (carry to the next int32) + return false; + if (outi[0] & zeromask) + // Output number too big (last int32 filled too far) + return false; + } + + j = 0; + switch (bytesleft) { + case 3: + *(binu++) = (outi[0] & 0xff0000) >> 16; + //-fallthrough + case 2: + *(binu++) = (outi[0] & 0xff00) >> 8; + //-fallthrough + case 1: + *(binu++) = (outi[0] & 0xff); + ++j; + //-fallthrough + default: + break; + } + + for (; j < outisz; ++j) + { + *(binu++) = (outi[j] >> 0x18) & 0xff; + *(binu++) = (outi[j] >> 0x10) & 0xff; + *(binu++) = (outi[j] >> 8) & 0xff; + *(binu++) = (outi[j] >> 0) & 0xff; + } + + // Count canonical base58 byte count + binu = bin; + for (i = 0; i < binsz; ++i) + { + if (binu[i]) + break; + --*binszp; + } + *binszp += zerocount; + + return true; +} + +int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str) +{ + unsigned char buf[32]; + const uint8_t *binc = bin; + unsigned i; + if (binsz < 4) + return -4; + hasher_Raw(hasher_type, bin, binsz - 4, buf); + hasher_Raw(hasher_type, buf, 32, buf); + if (memcmp(&binc[binsz - 4], buf, 4)) + return -1; + + // Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end) + for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) + {} // Just finding the end of zeros, nothing to do in loop + if (binc[i] == '\0' || base58str[i] == '1') + return -3; + + return binc[0]; +} + +static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) +{ + const uint8_t *bin = data; + int carry; + ssize_t i, j, high, zcount = 0; + size_t size; + + while (zcount < (ssize_t)binsz && !bin[zcount]) + ++zcount; + + size = (binsz - zcount) * 138 / 100 + 1; + uint8_t buf[size]; + memset(buf, 0, size); + + for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) + { + for (carry = bin[i], j = size - 1; (j > high) || carry; --j) + { + carry += 256 * buf[j]; + buf[j] = carry % 58; + carry /= 58; + } + } + + for (j = 0; j < (ssize_t)size && !buf[j]; ++j); + + if (*b58sz <= zcount + size - j) + { + *b58sz = zcount + size - j + 1; + return false; + } + + if (zcount) + memset(b58, '1', zcount); + for (i = zcount; j < (ssize_t)size; ++i, ++j) + b58[i] = b58digits_ordered[buf[j]]; + b58[i] = '\0'; + *b58sz = i + 1; + + return true; +} + +int base58_encode_check(const uint8_t *data, int datalen, HasherType hasher_type, char *str, int strsize) +{ + if (datalen > 128) { + return 0; + } + uint8_t buf[datalen + 32]; + uint8_t *hash = buf + datalen; + memcpy(buf, data, datalen); + hasher_Raw(hasher_type, data, datalen, hash); + hasher_Raw(hasher_type, hash, 32, hash); + size_t res = strsize; + bool success = b58enc(str, &res, buf, datalen + 4); + memzero(buf, sizeof(buf)); + return success ? res : 0; +} + +int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen) +{ + if (datalen > 128) { + return 0; + } + uint8_t d[datalen + 4]; + size_t res = datalen + 4; + if (b58tobin(d, &res, str) != true) { + return 0; + } + uint8_t *nd = d + datalen + 4 - res; + if (b58check(nd, res, hasher_type, str) < 0) { + return 0; + } + memcpy(data, nd, res - 4); + return res - 4; +} + +#if USE_GRAPHENE +int b58gphcheck(const void *bin, size_t binsz, const char *base58str) +{ + unsigned char buf[32]; + const uint8_t *binc = bin; + unsigned i; + if (binsz < 4) + return -4; + ripemd160(bin, binsz - 4, buf); // No double SHA256, but a single RIPEMD160 + if (memcmp(&binc[binsz - 4], buf, 4)) + return -1; + + // Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end) + for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) + {} // Just finding the end of zeros, nothing to do in loop + if (binc[i] == '\0' || base58str[i] == '1') + return -3; + + return binc[0]; +} + +int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize) +{ + if (datalen > 128) { + return 0; + } + uint8_t buf[datalen + 32]; + uint8_t *hash = buf + datalen; + memcpy(buf, data, datalen); + ripemd160(data, datalen, hash); // No double SHA256, but a single RIPEMD160 + size_t res = strsize; + bool success = b58enc(str, &res, buf, datalen + 4); + memzero(buf, sizeof(buf)); + return success ? res : 0; +} + +int base58gph_decode_check(const char *str, uint8_t *data, int datalen) +{ + if (datalen > 128) { + return 0; + } + uint8_t d[datalen + 4]; + size_t res = datalen + 4; + if (b58tobin(d, &res, str) != true) { + return 0; + } + uint8_t *nd = d + datalen + 4 - res; + if (b58gphcheck(nd, res, str) < 0) { + return 0; + } + memcpy(data, nd, res - 4); + return res - 4; +} +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/base58.h b/hardware-wallet/firmware/vendor/trezor-crypto/base58.h new file mode 100644 index 00000000..41b0b7d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/base58.h @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __BASE58_H__ +#define __BASE58_H__ + +#include +#include +#include "hasher.h" +#include "options.h" + +int base58_encode_check(const uint8_t *data, int len, HasherType hasher_type, char *str, int strsize); +int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen); + +// Private +bool b58tobin(void *bin, size_t *binszp, const char *b58); +int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str); +bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz); + +#if USE_GRAPHENE +int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize); +int base58gph_decode_check(const char *str, uint8_t *data, int datalen); +int b58gphcheck(const void *bin, size_t binsz, const char *base58str); +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/bignum.c b/hardware-wallet/firmware/vendor/trezor-crypto/bignum.c new file mode 100644 index 00000000..27e361d6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/bignum.c @@ -0,0 +1,1095 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * Copyright (c) 2015 Jochen Hoenicke + * Copyright (c) 2016 Alex Beregszaszi + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "bignum.h" +#include "memzero.h" + +/* big number library */ + +/* The structure bignum256 is an array of nine 32-bit values, which + * are digits in base 2^30 representation. I.e. the number + * bignum256 a; + * represents the value + * sum_{i=0}^8 a.val[i] * 2^{30 i}. + * + * The number is *normalized* iff every digit is < 2^30. + * + * As the name suggests, a bignum256 is intended to represent a 256 + * bit number, but it can represent 270 bits. Numbers are usually + * reduced using a prime, either the group order or the field prime. + * The reduction is often partly done by bn_fast_mod, and similarly + * implicitly in bn_multiply. A *partly reduced number* is a + * normalized number between 0 (inclusive) and 2*prime (exclusive). + * + * A partly reduced number can be fully reduced by calling bn_mod. + * Only a fully reduced number is guaranteed to fit in 256 bit. + * + * All functions assume that the prime in question is slightly smaller + * than 2^256. In particular it must be between 2^256-2^224 and + * 2^256 and it must be a prime number. + */ + +inline uint32_t read_be(const uint8_t *data) +{ + return (((uint32_t)data[0]) << 24) | + (((uint32_t)data[1]) << 16) | + (((uint32_t)data[2]) << 8) | + (((uint32_t)data[3])); +} + +inline void write_be(uint8_t *data, uint32_t x) +{ + data[0] = x >> 24; + data[1] = x >> 16; + data[2] = x >> 8; + data[3] = x; +} + +inline uint32_t read_le(const uint8_t *data) +{ + return (((uint32_t)data[3]) << 24) | + (((uint32_t)data[2]) << 16) | + (((uint32_t)data[1]) << 8) | + (((uint32_t)data[0])); +} + +inline void write_le(uint8_t *data, uint32_t x) +{ + data[3] = x >> 24; + data[2] = x >> 16; + data[1] = x >> 8; + data[0] = x; +} + +// convert a raw bigendian 256 bit value into a normalized bignum. +// out_number is partly reduced (since it fits in 256 bit). +void bn_read_be(const uint8_t *in_number, bignum256 *out_number) +{ + int i; + uint32_t temp = 0; + for (i = 0; i < 8; i++) { + // invariant: temp = (in_number % 2^(32i)) >> 30i + // get next limb = (in_number % 2^(32(i+1))) >> 32i + uint32_t limb = read_be(in_number + (7 - i) * 4); + // temp = (in_number % 2^(32(i+1))) << 30i + temp |= limb << (2*i); + // store 30 bits into val[i] + out_number->val[i]= temp & 0x3FFFFFFF; + // prepare temp for next round + temp = limb >> (30 - 2*i); + } + out_number->val[8] = temp; +} + +// convert a normalized bignum to a raw bigendian 256 bit number. +// in_number must be fully reduced. +void bn_write_be(const bignum256 *in_number, uint8_t *out_number) +{ + int i; + uint32_t temp = in_number->val[8] << 16; + for (i = 0; i < 8; i++) { + // invariant: temp = (in_number >> 30*(8-i)) << (16 + 2i) + uint32_t limb = in_number->val[7 - i]; + temp |= limb >> (14 - 2*i); + write_be(out_number + i * 4, temp); + temp = limb << (18 + 2*i); + } +} + +// convert a raw little endian 256 bit value into a normalized bignum. +// out_number is partly reduced (since it fits in 256 bit). +void bn_read_le(const uint8_t *in_number, bignum256 *out_number) +{ + int i; + uint32_t temp = 0; + for (i = 0; i < 8; i++) { + // invariant: temp = (in_number % 2^(32i)) >> 30i + // get next limb = (in_number % 2^(32(i+1))) >> 32i + uint32_t limb = read_le(in_number + i * 4); + // temp = (in_number % 2^(32(i+1))) << 30i + temp |= limb << (2*i); + // store 30 bits into val[i] + out_number->val[i]= temp & 0x3FFFFFFF; + // prepare temp for next round + temp = limb >> (30 - 2*i); + } + out_number->val[8] = temp; +} + +// convert a normalized bignum to a raw little endian 256 bit number. +// in_number must be fully reduced. +void bn_write_le(const bignum256 *in_number, uint8_t *out_number) +{ + int i; + uint32_t temp = in_number->val[8] << 16; + for (i = 0; i < 8; i++) { + // invariant: temp = (in_number >> 30*(8-i)) << (16 + 2i) + uint32_t limb = in_number->val[7 - i]; + temp |= limb >> (14 - 2*i); + write_le(out_number + (7 - i) * 4, temp); + temp = limb << (18 + 2*i); + } +} + +void bn_read_uint32(uint32_t in_number, bignum256 *out_number) +{ + out_number->val[0] = in_number & 0x3FFFFFFF; + out_number->val[1] = in_number >> 30; + out_number->val[2] = 0; + out_number->val[3] = 0; + out_number->val[4] = 0; + out_number->val[5] = 0; + out_number->val[6] = 0; + out_number->val[7] = 0; + out_number->val[8] = 0; +} + +void bn_read_uint64(uint64_t in_number, bignum256 *out_number) +{ + out_number->val[0] = in_number & 0x3FFFFFFF; + out_number->val[1] = (in_number >>= 30) & 0x3FFFFFFF; + out_number->val[2] = in_number >>= 30; + out_number->val[3] = 0; + out_number->val[4] = 0; + out_number->val[5] = 0; + out_number->val[6] = 0; + out_number->val[7] = 0; + out_number->val[8] = 0; +} + +// a must be normalized +int bn_bitcount(const bignum256 *a) +{ + int i; + for (i = 8; i >= 0; i--) { + int tmp = a->val[i]; + if (tmp != 0) { + return i * 30 + (32 - __builtin_clz(tmp)); + } + } + return 0; +} + +#define DIGITS 78 // log10(2 ^ 256) + +unsigned int bn_digitcount(const bignum256 *a) +{ + bignum256 val; + memcpy(&val, a, sizeof(bignum256)); + + unsigned int digits = 1; + + for (unsigned int i = 0; i < DIGITS; i += 3) { + uint32_t limb; + bn_divmod1000(&val, &limb); + + if (limb >= 100) { + digits = i + 3; + } else if (limb >= 10) { + digits = i + 2; + } else if (limb >= 1) { + digits = i + 1; + } + } + + return digits; +} + +// sets a bignum to zero. +void bn_zero(bignum256 *a) +{ + int i; + for (i = 0; i < 9; i++) { + a->val[i] = 0; + } +} + +// sets a bignum to one. +void bn_one(bignum256 *a) +{ + a->val[0] = 1; + a->val[1] = 0; + a->val[2] = 0; + a->val[3] = 0; + a->val[4] = 0; + a->val[5] = 0; + a->val[6] = 0; + a->val[7] = 0; + a->val[8] = 0; +} + +// checks that a bignum is zero. +// a must be normalized +// function is constant time (on some architectures, in particular ARM). +int bn_is_zero(const bignum256 *a) +{ + int i; + uint32_t result = 0; + for (i = 0; i < 9; i++) { + result |= a->val[i]; + } + return !result; +} + +// Check whether a < b +// a and b must be normalized +// function is constant time (on some architectures, in particular ARM). +int bn_is_less(const bignum256 *a, const bignum256 *b) +{ + int i; + uint32_t res1 = 0; + uint32_t res2 = 0; + for (i = 8; i >= 0; i--) { + res1 = (res1 << 1) | (a->val[i] < b->val[i]); + res2 = (res2 << 1) | (a->val[i] > b->val[i]); + } + return res1 > res2; +} + +// Check whether a == b +// a and b must be normalized +// function is constant time (on some architectures, in particular ARM). +int bn_is_equal(const bignum256 *a, const bignum256 *b) { + int i; + uint32_t result = 0; + for (i = 0; i < 9; i++) { + result |= (a->val[i] ^ b->val[i]); + } + return !result; +} + +// Assigns res = cond ? truecase : falsecase +// assumes that cond is either 0 or 1. +// function is constant time. +void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase, const bignum256 *falsecase) +{ + int i; + uint32_t tmask = (uint32_t) -cond; + uint32_t fmask = ~tmask; + + assert (cond == 1 || cond == 0); + for (i = 0; i < 9; i++) { + res->val[i] = (truecase->val[i] & tmask) | + (falsecase->val[i] & fmask); + } +} + +// shift number to the left, i.e multiply it by 2. +// a must be normalized. The result is normalized but not reduced. +void bn_lshift(bignum256 *a) +{ + int i; + for (i = 8; i > 0; i--) { + a->val[i] = ((a->val[i] << 1) & 0x3FFFFFFF) | ((a->val[i - 1] & 0x20000000) >> 29); + } + a->val[0] = (a->val[0] << 1) & 0x3FFFFFFF; +} + +// shift number to the right, i.e divide by 2 while rounding down. +// a must be normalized. The result is normalized. +void bn_rshift(bignum256 *a) +{ + int i; + for (i = 0; i < 8; i++) { + a->val[i] = (a->val[i] >> 1) | ((a->val[i + 1] & 1) << 29); + } + a->val[8] >>= 1; +} + +// sets bit in bignum +void bn_setbit(bignum256 *a, uint8_t bit) +{ + a->val[bit / 30] |= (1 << (bit % 30)); +} + +// clears bit in bignum +void bn_clearbit(bignum256 *a, uint8_t bit) +{ + a->val[bit / 30] &= ~(1 << (bit % 30)); +} + +// tests bit in bignum +uint32_t bn_testbit(bignum256 *a, uint8_t bit) +{ + return a->val[bit / 30] & (1 << (bit % 30)); +} + +// a = b ^ c +void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c) +{ + int i; + for (i = 0; i < 9; i++) { + a->val[i] = b->val[i] ^ c->val[i]; + } +} + +// multiply x by 1/2 modulo prime. +// it computes x = (x & 1) ? (x + prime) >> 1 : x >> 1. +// assumes x is normalized. +// if x was partly reduced, it is also partly reduced on exit. +// function is constant time. +void bn_mult_half(bignum256 * x, const bignum256 *prime) +{ + int j; + uint32_t xodd = -(x->val[0] & 1); + // compute x = x/2 mod prime + // if x is odd compute (x+prime)/2 + uint32_t tmp1 = (x->val[0] + (prime->val[0] & xodd)) >> 1; + for (j = 0; j < 8; j++) { + uint32_t tmp2 = (x->val[j+1] + (prime->val[j+1] & xodd)); + tmp1 += (tmp2 & 1) << 29; + x->val[j] = tmp1 & 0x3fffffff; + tmp1 >>= 30; + tmp1 += tmp2 >> 1; + } + x->val[8] = tmp1; +} + +// multiply x by k modulo prime. +// assumes x is normalized, 0 <= k <= 4. +// guarantees x is partly reduced. +void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime) +{ + int j; + for (j = 0; j < 9; j++) { + x->val[j] = k * x->val[j]; + } + bn_fast_mod(x, prime); +} + +// compute x = x mod prime by computing x >= prime ? x - prime : x. +// assumes x partly reduced, guarantees x fully reduced. +void bn_mod(bignum256 *x, const bignum256 *prime) +{ + const int flag = bn_is_less(x, prime); // x < prime + bignum256 temp; + bn_subtract(x, prime, &temp); // temp = x - prime + bn_cmov(x, flag, x, &temp); +} + +// auxiliary function for multiplication. +// compute k * x as a 540 bit number in base 2^30 (normalized). +// assumes that k and x are normalized. +void bn_multiply_long(const bignum256 *k, const bignum256 *x, uint32_t res[18]) +{ + int i, j; + uint64_t temp = 0; + + // compute lower half of long multiplication + for (i = 0; i < 9; i++) + { + for (j = 0; j <= i; j++) { + // no overflow, since 9*2^60 < 2^64 + temp += k->val[j] * (uint64_t)x->val[i - j]; + } + res[i] = temp & 0x3FFFFFFFu; + temp >>= 30; + } + // compute upper half + for (; i < 17; i++) + { + for (j = i - 8; j < 9 ; j++) { + // no overflow, since 9*2^60 < 2^64 + temp += k->val[j] * (uint64_t)x->val[i - j]; + } + res[i] = temp & 0x3FFFFFFFu; + temp >>= 30; + } + res[17] = temp; +} + +// auxiliary function for multiplication. +// reduces res modulo prime. +// assumes res normalized, res < 2^(30(i-7)) * 2 * prime +// guarantees res normalized, res < 2^(30(i-8)) * 2 * prime +void bn_multiply_reduce_step(uint32_t res[18], const bignum256 *prime, uint32_t i) { + // let k = i-8. + // on entry: + // 0 <= res < 2^(30k + 31) * prime + // estimate coef = (res / prime / 2^30k) + // by coef = res / 2^(30k + 256) rounded down + // 0 <= coef < 2^31 + // subtract (coef * 2^(30k) * prime) from res + // note that we unrolled the first iteration + uint32_t j; + uint32_t coef = (res[i] >> 16) + (res[i + 1] << 14); + uint64_t temp = 0x2000000000000000ull + res[i - 8] - prime->val[0] * (uint64_t)coef; + assert (coef < 0x80000000u); + res[i - 8] = temp & 0x3FFFFFFF; + for (j = 1; j < 9; j++) { + temp >>= 30; + // Note: coeff * prime->val[j] <= (2^31-1) * (2^30-1) + // Hence, this addition will not underflow. + temp += 0x1FFFFFFF80000000ull + res[i - 8 + j] - prime->val[j] * (uint64_t)coef; + res[i - 8 + j] = temp & 0x3FFFFFFF; + // 0 <= temp < 2^61 + 2^30 + } + temp >>= 30; + temp += 0x1FFFFFFF80000000ull + res[i - 8 + j]; + res[i - 8 + j] = temp & 0x3FFFFFFF; + // we rely on the fact that prime > 2^256 - 2^224 + // res = oldres - coef*2^(30k) * prime; + // and + // coef * 2^(30k + 256) <= oldres < (coef+1) * 2^(30k + 256) + // Hence, 0 <= res < 2^30k (2^256 + coef * (2^256 - prime)) + // < 2^30k (2^256 + 2^31 * 2^224) + // < 2^30k (2 * prime) +} + + +// auxiliary function for multiplication. +// reduces x = res modulo prime. +// assumes res normalized, res < 2^270 * 2 * prime +// guarantees x partly reduced, i.e., x < 2 * prime +void bn_multiply_reduce(bignum256 *x, uint32_t res[18], const bignum256 *prime) +{ + int i; + // res = k * x is a normalized number (every limb < 2^30) + // 0 <= res < 2^270 * 2 * prime. + for (i = 16; i >= 8; i--) { + bn_multiply_reduce_step(res, prime, i); + assert(res[i + 1] == 0); + } + // store the result + for (i = 0; i < 9; i++) { + x->val[i] = res[i]; + } +} + +// Compute x := k * x (mod prime) +// both inputs must be smaller than 180 * prime. +// result is partly reduced (0 <= x < 2 * prime) +// This only works for primes between 2^256-2^224 and 2^256. +void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime) +{ + uint32_t res[18] = {0}; + bn_multiply_long(k, x, res); + bn_multiply_reduce(x, res, prime); + memzero(res, sizeof(res)); +} + +// partly reduce x modulo prime +// input x does not have to be normalized. +// x can be any number that fits. +// prime must be between (2^256 - 2^224) and 2^256 +// result is partly reduced, smaller than 2*prime +void bn_fast_mod(bignum256 *x, const bignum256 *prime) +{ + int j; + uint32_t coef; + uint64_t temp; + + coef = x->val[8] >> 16; + // substract (coef * prime) from x + // note that we unrolled the first iteration + temp = 0x2000000000000000ull + x->val[0] - prime->val[0] * (uint64_t)coef; + x->val[0] = temp & 0x3FFFFFFF; + for (j = 1; j < 9; j++) { + temp >>= 30; + temp += 0x1FFFFFFF80000000ull + x->val[j] - prime->val[j] * (uint64_t)coef; + x->val[j] = temp & 0x3FFFFFFF; + } +} + +// square root of x = x^((p+1)/4) +// http://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus +// assumes x is normalized but not necessarily reduced. +// guarantees x is reduced +void bn_sqrt(bignum256 *x, const bignum256 *prime) +{ + // this method compute x^1/2 = x^(prime+1)/4 + uint32_t i, j, limb; + bignum256 res, p; + bn_one(&res); + // compute p = (prime+1)/4 + memcpy(&p, prime, sizeof(bignum256)); + bn_addi(&p, 1); + bn_rshift(&p); + bn_rshift(&p); + for (i = 0; i < 9; i++) { + // invariants: + // x = old(x)^(2^(i*30)) + // res = old(x)^(p % 2^(i*30)) + // get the i-th limb of prime - 2 + limb = p.val[i]; + for (j = 0; j < 30; j++) { + // invariants: + // x = old(x)^(2^(i*30+j)) + // res = old(x)^(p % 2^(i*30+j)) + // limb = (p % 2^(i*30+30)) / 2^(i*30+j) + if (i == 8 && limb == 0) break; + if (limb & 1) { + bn_multiply(x, &res, prime); + } + limb >>= 1; + bn_multiply(x, x, prime); + } + } + bn_mod(&res, prime); + memcpy(x, &res, sizeof(bignum256)); + memzero(&res, sizeof(res)); + memzero(&p, sizeof(p)); +} + +#if ! USE_INVERSE_FAST + +// in field G_prime, small but slow +void bn_inverse(bignum256 *x, const bignum256 *prime) +{ + // this method compute x^-1 = x^(prime-2) + uint32_t i, j, limb; + bignum256 res; + bn_one(&res); + for (i = 0; i < 9; i++) { + // invariants: + // x = old(x)^(2^(i*30)) + // res = old(x)^((prime-2) % 2^(i*30)) + // get the i-th limb of prime - 2 + limb = prime->val[i]; + // this is not enough in general but fine for secp256k1 & nist256p1 because prime->val[0] > 1 + if (i == 0) limb -= 2; + for (j = 0; j < 30; j++) { + // invariants: + // x = old(x)^(2^(i*30+j)) + // res = old(x)^((prime-2) % 2^(i*30+j)) + // limb = ((prime-2) % 2^(i*30+30)) / 2^(i*30+j) + // early abort when only zero bits follow + if (i == 8 && limb == 0) break; + if (limb & 1) { + bn_multiply(x, &res, prime); + } + limb >>= 1; + bn_multiply(x, x, prime); + } + } + bn_mod(&res, prime); + memcpy(x, &res, sizeof(bignum256)); +} + +#else + +// in field G_prime, big and complicated but fast +// the input must not be 0 mod prime. +// the result is smaller than prime +void bn_inverse(bignum256 *x, const bignum256 *prime) +{ + int i, j, k, cmp; + struct combo { + uint32_t a[9]; + int len1; + } us, vr, *odd, *even; + uint32_t pp[8]; + uint32_t temp32; + uint64_t temp; + + // The algorithm is based on Schroeppel et. al. "Almost Modular Inverse" + // algorithm. We keep four values u,v,r,s in the combo registers + // us and vr. us stores u in the first len1 limbs (little endian) + // and s in the last 9-len1 limbs (big endian). vr stores v and r. + // This is because both u*s and v*r are guaranteed to fit in 8 limbs, so + // their components are guaranteed to fit in 9. During the algorithm, + // the length of u and v shrinks while r and s grow. + // u,v,r,s correspond to F,G,B,C in Schroeppel's algorithm. + + // reduce x modulo prime. This is necessary as it has to fit in 8 limbs. + bn_fast_mod(x, prime); + bn_mod(x, prime); + // convert x and prime to 8x32 bit limb form + temp32 = prime->val[0]; + for (i = 0; i < 8; i++) { + temp32 |= prime->val[i + 1] << (30-2*i); + us.a[i] = pp[i] = temp32; + temp32 = prime->val[i + 1] >> (2+2*i); + } + temp32 = x->val[0]; + for (i = 0; i < 8; i++) { + temp32 |= x->val[i + 1] << (30-2*i); + vr.a[i] = temp32; + temp32 = x->val[i + 1] >> (2+2*i); + } + us.len1 = 8; + vr.len1 = 8; + // set s = 1 and r = 0 + us.a[8] = 1; + vr.a[8] = 0; + // set k = 0. + k = 0; + + // only one of the numbers u,v can be even at any time. We + // let even point to that number and odd to the other. + // Initially the prime u is guaranteed to be odd. + odd = &us; + even = &vr; + + // u = prime, v = x + // r = 0 , s = 1 + // k = 0 + for (;;) { + // invariants: + // let u = limbs us.a[0..u.len1-1] in little endian, + // let s = limbs us.a[u.len..8] in big endian, + // let v = limbs vr.a[0..u.len1-1] in little endian, + // let r = limbs vr.a[u.len..8] in big endian, + // r,s >= 0 ; u,v >= 1 + // x*-r = u*2^k mod prime + // x*s = v*2^k mod prime + // u*s + v*r = prime + // floor(log2(u)) + floor(log2(v)) + k <= 510 + // max(u,v) <= 2^k (*) see comment at end of loop + // gcd(u,v) = 1 + // {odd,even} = {&us, &vr} + // odd->a[0] and odd->a[8] are odd + // even->a[0] or even->a[8] is even + // + // first u/v are large and r/s small + // later u/v are small and r/s large + assert(odd->a[0] & 1); + assert(odd->a[8] & 1); + + // adjust length of even. + while (even->a[even->len1 - 1] == 0) { + even->len1--; + // if input was 0, return. + // This simple check prevents crashing with stack underflow + // or worse undesired behaviour for illegal input. + if (even->len1 < 0) + return; + } + + // reduce even->a while it is even + while (even->a[0] == 0) { + // shift right first part of even by a limb + // and shift left second part of even by a limb. + for (i = 0; i < 8; i++) { + even->a[i] = even->a[i+1]; + } + even->a[i] = 0; + even->len1--; + k += 32; + } + // count up to 32 zero bits of even->a. + j = 0; + while ((even->a[0] & (1 << j)) == 0) { + j++; + } + if (j > 0) { + // shift first part of even right by j bits. + for (i = 0; i + 1 < even->len1; i++) { + even->a[i] = (even->a[i] >> j) | (even->a[i + 1] << (32 - j)); + } + even->a[i] = (even->a[i] >> j); + if (even->a[i] == 0) { + even->len1--; + } else { + i++; + } + + // shift second part of even left by j bits. + for (; i < 8; i++) { + even->a[i] = (even->a[i] << j) | (even->a[i + 1] >> (32 - j)); + } + even->a[i] = (even->a[i] << j); + // add j bits to k. + k += j; + } + // invariant is reestablished. + // now both a[0] are odd. + assert(odd->a[0] & 1); + assert(odd->a[8] & 1); + assert(even->a[0] & 1); + assert((even->a[8] & 1) == 0); + + // cmp > 0 if us.a[0..len1-1] > vr.a[0..len1-1], + // cmp = 0 if equal, < 0 if less. + cmp = us.len1 - vr.len1; + if (cmp == 0) { + i = us.len1 - 1; + while (i >= 0 && us.a[i] == vr.a[i]) i--; + // both are equal to 1 and we are done. + if (i == -1) + break; + cmp = us.a[i] > vr.a[i] ? 1 : -1; + } + if (cmp > 0) { + even = &us; + odd = &vr; + } else { + even = &vr; + odd = &us; + } + + // now even > odd. + + // even->a[0..len1-1] = (even->a[0..len1-1] - odd->a[0..len1-1]); + temp = 1; + for (i = 0; i < odd->len1; i++) { + temp += 0xFFFFFFFFull + even->a[i] - odd->a[i]; + even->a[i] = temp & 0xFFFFFFFF; + temp >>= 32; + } + for (; i < even->len1; i++) { + temp += 0xFFFFFFFFull + even->a[i]; + even->a[i] = temp & 0xFFFFFFFF; + temp >>= 32; + } + // odd->a[len1..8] = (odd->b[len1..8] + even->b[len1..8]); + temp = 0; + for (i = 8; i >= even->len1; i--) { + temp += (uint64_t) odd->a[i] + even->a[i]; + odd->a[i] = temp & 0xFFFFFFFF; + temp >>= 32; + } + for (; i >= odd->len1; i--) { + temp += (uint64_t) odd->a[i]; + odd->a[i] = temp & 0xFFFFFFFF; + temp >>= 32; + } + // note that + // if u > v: + // u'2^k = (u - v) 2^k = x(-r) - xs = x(-(r+s)) = x(-r') mod prime + // u's' + v'r' = (u-v)s + v(r+s) = us + vr + // if u < v: + // v'2^k = (v - u) 2^k = xs - x(-r) = x(s+r) = xs' mod prime + // u's' + v'r' = u(s+r) + (v-u)r = us + vr + + // even->a[0] is difference between two odd numbers, hence even. + // odd->a[8] is sum of even and odd number, hence odd. + assert(odd->a[0] & 1); + assert(odd->a[8] & 1); + assert((even->a[0] & 1) == 0); + + // The invariants are (almost) reestablished. + // The invariant max(u,v) <= 2^k can be invalidated at this point, + // because odd->a[len1..8] was changed. We only have + // + // odd->a[len1..8] <= 2^{k+1} + // + // Since even->a[0] is even, k will be incremented at the beginning + // of the next loop while odd->a[len1..8] remains unchanged. + // So after that, odd->a[len1..8] <= 2^k will hold again. + } + // In the last iteration we had u = v and gcd(u,v) = 1. + // Hence, u=1, v=1, s+r = prime, k <= 510, 2^k > max(s,r) >= prime/2 + // This implies 0 <= s < prime and 255 <= k <= 510. + // + // The invariants also give us x*s = 2^k mod prime, + // hence s = 2^k * x^-1 mod prime. + // We need to compute s/2^k mod prime. + + // First we compute inverse = -prime^-1 mod 2^32, which we need later. + // We use the Explicit Quadratic Modular inverse algorithm. + // http://arxiv.org/pdf/1209.6626.pdf + // a^-1 = (2-a) * PROD_i (1 + (a - 1)^(2^i)) mod 2^32 + // the product will converge quickly, because (a-1)^(2^i) will be + // zero mod 2^32 after at most five iterations. + // We want to compute -prime^-1 so we start with (pp[0]-2). + assert(pp[0] & 1); + uint32_t amone = pp[0]-1; + uint32_t inverse = pp[0] - 2; + while (amone) { + amone *= amone; + inverse *= (amone + 1); + } + + while (k >= 32) { + // compute s / 2^32 modulo prime. + // Idea: compute factor, such that + // s + factor*prime mod 2^32 == 0 + // i.e. factor = s * -1/prime mod 2^32. + // Then compute s + factor*prime and shift right by 32 bits. + uint32_t factor = (inverse * us.a[8]) & 0xffffffff; + temp = us.a[8] + (uint64_t) pp[0] * factor; + assert((temp & 0xffffffff) == 0); + temp >>= 32; + for (i = 0; i < 7; i++) { + temp += us.a[8-(i+1)] + (uint64_t) pp[i+1] * factor; + us.a[8-i] = temp & 0xffffffff; + temp >>= 32; + } + us.a[8-i] = temp & 0xffffffff; + k -= 32; + } + if (k > 0) { + // compute s / 2^k modulo prime. + // Same idea: compute factor, such that + // s + factor*prime mod 2^k == 0 + // i.e. factor = s * -1/prime mod 2^k. + // Then compute s + factor*prime and shift right by k bits. + uint32_t mask = (1 << k) - 1; + uint32_t factor = (inverse * us.a[8]) & mask; + temp = (us.a[8] + (uint64_t) pp[0] * factor) >> k; + assert(((us.a[8] + pp[0] * factor) & mask) == 0); + for (i = 0; i < 7; i++) { + temp += (us.a[8-(i+1)] + (uint64_t) pp[i+1] * factor) << (32 - k); + us.a[8-i] = temp & 0xffffffff; + temp >>= 32; + } + us.a[8-i] = temp & 0xffffffff; + } + + // convert s to bignum style + temp32 = 0; + for (i = 0; i < 8; i++) { + x->val[i] = ((us.a[8-i] << (2 * i)) & 0x3FFFFFFFu) | temp32; + temp32 = us.a[8-i] >> (30 - 2 * i); + } + x->val[i] = temp32; + + // let's wipe all temp buffers + memzero(pp, sizeof(pp)); + memzero(&us, sizeof(us)); + memzero(&vr, sizeof(vr)); +} +#endif + +void bn_normalize(bignum256 *a) { + bn_addi(a, 0); +} + +// add two numbers a = a + b +// assumes that a, b are normalized +// guarantees that a is normalized +void bn_add(bignum256 *a, const bignum256 *b) +{ + int i; + uint32_t tmp = 0; + for (i = 0; i < 9; i++) { + tmp += a->val[i] + b->val[i]; + a->val[i] = tmp & 0x3FFFFFFF; + tmp >>= 30; + } +} + +void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime) +{ + int i; + for (i = 0; i < 9; i++) { + a->val[i] += b->val[i]; + } + bn_fast_mod(a, prime); +} + +void bn_addi(bignum256 *a, uint32_t b) { + int i; + uint32_t tmp = b; + for (i = 0; i < 9; i++) { + tmp += a->val[i]; + a->val[i] = tmp & 0x3FFFFFFF; + tmp >>= 30; + } +} + +void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime) { + assert (b <= prime->val[0]); + // the possible underflow will be taken care of when adding the prime + a->val[0] -= b; + bn_add(a, prime); +} + +// res = a - b mod prime. More exactly res = a + (2*prime - b). +// b must be a partly reduced number +// result is normalized but not reduced. +void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res, const bignum256 *prime) +{ + int i; + uint32_t temp = 1; + for (i = 0; i < 9; i++) { + temp += 0x3FFFFFFF + a->val[i] + 2u * prime->val[i] - b->val[i]; + res->val[i] = temp & 0x3FFFFFFF; + temp >>= 30; + } +} + +// res = a - b ; a > b +void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res) +{ + int i; + uint32_t tmp = 1; + for (i = 0; i < 9; i++) { + tmp += 0x3FFFFFFF + a->val[i] - b->val[i]; + res->val[i] = tmp & 0x3FFFFFFF; + tmp >>= 30; + } +} + +// a / 58 = a (+r) +void bn_divmod58(bignum256 *a, uint32_t *r) +{ + int i; + uint32_t rem, tmp; + rem = a->val[8] % 58; + a->val[8] /= 58; + for (i = 7; i >= 0; i--) { + // invariants: + // rem = old(a) >> 30(i+1) % 58 + // a[i+1..8] = old(a[i+1..8])/58 + // a[0..i] = old(a[0..i]) + // 2^30 == 18512790*58 + 4 + tmp = rem * 4 + a->val[i]; + // set a[i] = (rem * 2^30 + a[i])/58 + // = rem * 18512790 + (rem * 4 + a[i])/58 + a->val[i] = rem * 18512790 + (tmp / 58); + // set rem = (rem * 2^30 + a[i]) mod 58 + // = (rem * 4 + a[i]) mod 58 + rem = tmp % 58; + } + *r = rem; +} + +// a / 1000 = a (+r) +void bn_divmod1000(bignum256 *a, uint32_t *r) +{ + int i; + uint32_t rem, tmp; + rem = a->val[8] % 1000; + a->val[8] /= 1000; + for (i = 7; i >= 0; i--) { + // invariants: + // rem = old(a) >> 30(i+1) % 1000 + // a[i+1..8] = old(a[i+1..8])/1000 + // a[0..i] = old(a[0..i]) + // 2^30 == 1073741*1000 + 824 + tmp = rem * 824 + a->val[i]; + // set a[i] = (rem * 2^30 + a[i])/1000 + // = rem * 1073741 + (rem * 824 + a[i])/1000 + a->val[i] = rem * 1073741 + (tmp / 1000); + // set rem = (rem * 2^30 + a[i]) mod 1000 + // = (rem * 824 + a[i]) mod 1000 + rem = tmp % 1000; + } + *r = rem; +} + +size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix, unsigned int decimals, int exponent, bool trailing, char *out, size_t outlen) +{ + size_t prefixlen = prefix ? strlen(prefix) : 0; + size_t suffixlen = suffix ? strlen(suffix) : 0; + + char *start = &out[prefixlen + suffixlen], *end = &out[outlen]; + char *str = end; + +#define BN_FORMAT_PUSH_CHECKED(c) \ + do { \ + if (str == start) return 0; \ + *--str = (c); \ + } while (0) + +#define BN_FORMAT_PUSH(n) \ + do { \ + if (exponent < 0) { \ + exponent++; \ + } else { \ + if ((n) > 0 || trailing || str != end || decimals <= 1) { \ + BN_FORMAT_PUSH_CHECKED('0' + (n)); \ + } \ + if (decimals > 0 && decimals-- == 1) { \ + BN_FORMAT_PUSH_CHECKED('.'); \ + } \ + } \ + } while (0) + + bignum256 val; + memcpy(&val, amnt, sizeof(bignum256)); + + if (bn_is_zero(&val)) { + exponent = 0; + } + + for (; exponent > 0; exponent--) { + BN_FORMAT_PUSH(0); + } + + unsigned int digits = bn_digitcount(&val); + for (unsigned int i = 0; i < digits / 3; i++) { + uint32_t limb; + bn_divmod1000(&val, &limb); + + BN_FORMAT_PUSH(limb % 10); + limb /= 10; + BN_FORMAT_PUSH(limb % 10); + limb /= 10; + BN_FORMAT_PUSH(limb % 10); + } + + if (digits % 3 != 0) { + uint32_t limb; + bn_divmod1000(&val, &limb); + + switch (digits % 3) { + case 2: + BN_FORMAT_PUSH(limb % 10); + limb /= 10; + //-fallthrough + + case 1: + BN_FORMAT_PUSH(limb % 10); + break; + } + } + + while (decimals > 0 || str[0] == '\0' || str[0] == '.') { + BN_FORMAT_PUSH(0); + } + + size_t len = end - str; + memmove(&out[prefixlen], str, len); + + if (prefixlen) { + memcpy(out, prefix, prefixlen); + } + if (suffixlen) { + memcpy(&out[prefixlen + len], suffix, suffixlen); + } + + size_t length = prefixlen + len + suffixlen; + out[length] = '\0'; + return length; +} + +#if USE_BN_PRINT +void bn_print(const bignum256 *a) +{ + printf("%04x", a->val[8] & 0x0000FFFF); + printf("%08x", (a->val[7] << 2) | ((a->val[6] & 0x30000000) >> 28)); + printf("%07x", a->val[6] & 0x0FFFFFFF); + printf("%08x", (a->val[5] << 2) | ((a->val[4] & 0x30000000) >> 28)); + printf("%07x", a->val[4] & 0x0FFFFFFF); + printf("%08x", (a->val[3] << 2) | ((a->val[2] & 0x30000000) >> 28)); + printf("%07x", a->val[2] & 0x0FFFFFFF); + printf("%08x", (a->val[1] << 2) | ((a->val[0] & 0x30000000) >> 28)); + printf("%07x", a->val[0] & 0x0FFFFFFF); +} + +void bn_print_raw(const bignum256 *a) +{ + int i; + for (i = 0; i <= 8; i++) { + printf("0x%08x, ", a->val[i]); + } +} +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/bignum.h b/hardware-wallet/firmware/vendor/trezor-crypto/bignum.h new file mode 100644 index 00000000..f96cad66 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/bignum.h @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * Copyright (c) 2016 Alex Beregszaszi + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __BIGNUM_H__ +#define __BIGNUM_H__ + +#include +#include +#include +#include "options.h" + +// bignum256 are 256 bits stored as 8*30 bit + 1*16 bit +// val[0] are lowest 30 bits, val[8] highest 16 bits +typedef struct { + uint32_t val[9]; +} bignum256; + +// read 4 big endian bytes into uint32 +uint32_t read_be(const uint8_t *data); + +// write 4 big endian bytes +void write_be(uint8_t *data, uint32_t x); + +// read 4 little endian bytes into uint32 +uint32_t read_le(const uint8_t *data); + +// write 4 little endian bytes +void write_le(uint8_t *data, uint32_t x); + +void bn_read_be(const uint8_t *in_number, bignum256 *out_number); + +void bn_write_be(const bignum256 *in_number, uint8_t *out_number); + +void bn_read_le(const uint8_t *in_number, bignum256 *out_number); + +void bn_write_le(const bignum256 *in_number, uint8_t *out_number); + +void bn_read_uint32(uint32_t in_number, bignum256 *out_number); + +void bn_read_uint64(uint64_t in_number, bignum256 *out_number); + +static inline uint32_t bn_write_uint32(const bignum256 *in_number) +{ + return in_number->val[0] | (in_number->val[1] << 30); +} + +static inline uint64_t bn_write_uint64(const bignum256 *in_number) +{ + uint64_t tmp; + tmp = in_number->val[2]; + tmp <<= 30; + tmp |= in_number->val[1]; + tmp <<= 30; + tmp |= in_number->val[0]; + return tmp; +} + +// copies number a to b +static inline void bn_copy(const bignum256 *a, bignum256 *b) { + *b = *a; +} + +int bn_bitcount(const bignum256 *a); + +unsigned int bn_digitcount(const bignum256 *a); + +void bn_zero(bignum256 *a); + +int bn_is_zero(const bignum256 *a); + +void bn_one(bignum256 *a); + +static inline int bn_is_even(const bignum256 *a) { + return (a->val[0] & 1) == 0; +} + +static inline int bn_is_odd(const bignum256 *a) { + return (a->val[0] & 1) == 1; +} + +int bn_is_less(const bignum256 *a, const bignum256 *b); + +int bn_is_equal(const bignum256 *a, const bignum256 *b); + +void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase, const bignum256 *falsecase); + +void bn_lshift(bignum256 *a); + +void bn_rshift(bignum256 *a); + +void bn_setbit(bignum256 *a, uint8_t bit); + +void bn_clearbit(bignum256 *a, uint8_t bit); + +uint32_t bn_testbit(bignum256 *a, uint8_t bit); + +void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c); + +void bn_mult_half(bignum256 *x, const bignum256 *prime); + +void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime); + +void bn_mod(bignum256 *x, const bignum256 *prime); + +void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime); + +void bn_fast_mod(bignum256 *x, const bignum256 *prime); + +void bn_sqrt(bignum256 *x, const bignum256 *prime); + +void bn_inverse(bignum256 *x, const bignum256 *prime); + +void bn_normalize(bignum256 *a); + +void bn_add(bignum256 *a, const bignum256 *b); + +void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime); + +void bn_addi(bignum256 *a, uint32_t b); + +void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime); + +void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res, const bignum256 *prime); + +void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res); + +void bn_divmod58(bignum256 *a, uint32_t *r); + +void bn_divmod1000(bignum256 *a, uint32_t *r); + +size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix, unsigned int decimals, int exponent, bool trailing, char *out, size_t outlen); + +static inline size_t bn_format_uint64(uint64_t amount, const char *prefix, const char *suffix, unsigned int decimals, int exponent, bool trailing, char *out, size_t outlen) +{ + bignum256 amnt; + bn_read_uint64(amount, &amnt); + + return bn_format(&amnt, prefix, suffix, decimals, exponent, trailing, out, outlen); +} + +#if USE_BN_PRINT +void bn_print(const bignum256 *a); +void bn_print_raw(const bignum256 *a); +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/bip32.c b/hardware-wallet/firmware/vendor/trezor-crypto/bip32.c new file mode 100644 index 00000000..fbccb971 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/bip32.c @@ -0,0 +1,686 @@ +/** + * Copyright (c) 2013-2016 Tomas Dzetkulic + * Copyright (c) 2013-2016 Pavol Rusnak + * Copyright (c) 2015-2016 Jochen Hoenicke + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "aes/aes.h" +#include "address.h" +#include "bignum.h" +#include "hmac.h" +#include "ecdsa.h" +#include "bip32.h" +#include "sha2.h" +#include "sha3.h" +#include "ripemd160.h" +#include "base58.h" +#include "curves.h" +#include "secp256k1.h" +#include "nist256p1.h" +#include "ed25519-donna/ed25519.h" +#include "ed25519-donna/ed25519-sha3.h" +#if USE_KECCAK +#include "ed25519-donna/ed25519-keccak.h" +#endif +#if USE_NEM +#include "nem.h" +#endif +#include "memzero.h" + +const curve_info ed25519_info = { + .bip32_name = "ed25519 seed", + .params = NULL, + .hasher_type = HASHER_SHA2, +}; + +const curve_info ed25519_sha3_info = { + .bip32_name = "ed25519-sha3 seed", + .params = NULL, + .hasher_type = HASHER_SHA2, +}; + +#if USE_KECCAK +const curve_info ed25519_keccak_info = { + .bip32_name = "ed25519-keccak seed", + .params = NULL, + .hasher_type = HASHER_SHA2, +}; +#endif + +const curve_info curve25519_info = { + .bip32_name = "curve25519 seed", + .params = NULL, + .hasher_type = HASHER_SHA2, +}; + +int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char* curve, HDNode *out) +{ + const curve_info *info = get_curve_by_name(curve); + if (info == 0) { + return 0; + } + if (public_key[0] != 0x02 && public_key[0] != 0x03) { // invalid pubkey + return 0; + } + out->curve = info; + out->depth = depth; + out->child_num = child_num; + memcpy(out->chain_code, chain_code, 32); + memzero(out->private_key, 32); + memcpy(out->public_key, public_key, 33); + return 1; +} + +int hdnode_from_xprv(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, const char* curve, HDNode *out) +{ + bool failed = false; + const curve_info *info = get_curve_by_name(curve); + if (info == 0) { + failed = true; + } else if (info->params) { + bignum256 a; + bn_read_be(private_key, &a); + if (bn_is_zero(&a)) { // == 0 + failed = true; + } else { + if (!bn_is_less(&a, &info->params->order)) { // >= order + failed = true; + } + } + memzero(&a, sizeof(a)); + } + + if (failed) { + return 0; + } + + out->curve = info; + out->depth = depth; + out->child_num = child_num; + memcpy(out->chain_code, chain_code, 32); + memcpy(out->private_key, private_key, 32); + memzero(out->public_key, sizeof(out->public_key)); + return 1; +} + +int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNode *out) +{ + static CONFIDENTIAL uint8_t I[32 + 32]; + memset(out, 0, sizeof(HDNode)); + out->depth = 0; + out->child_num = 0; + out->curve = get_curve_by_name(curve); + if (out->curve == 0) { + return 0; + } + static CONFIDENTIAL HMAC_SHA512_CTX ctx; + hmac_sha512_Init(&ctx, (const uint8_t*) out->curve->bip32_name, strlen(out->curve->bip32_name)); + hmac_sha512_Update(&ctx, seed, seed_len); + hmac_sha512_Final(&ctx, I); + + if (out->curve->params) { + bignum256 a; + while (true) { + bn_read_be(I, &a); + if (!bn_is_zero(&a) // != 0 + && bn_is_less(&a, &out->curve->params->order)) { // < order + break; + } + hmac_sha512_Init(&ctx, (const uint8_t*) out->curve->bip32_name, strlen(out->curve->bip32_name)); + hmac_sha512_Update(&ctx, I, sizeof(I)); + hmac_sha512_Final(&ctx, I); + } + memzero(&a, sizeof(a)); + } + memcpy(out->private_key, I, 32); + memcpy(out->chain_code, I + 32, 32); + memzero(out->public_key, sizeof(out->public_key)); + memzero(I, sizeof(I)); + return 1; +} + +uint32_t hdnode_fingerprint(HDNode *node) +{ + uint8_t digest[32]; + uint32_t fingerprint; + + hdnode_fill_public_key(node); + hasher_Raw(node->curve->hasher_type, node->public_key, 33, digest); + ripemd160(digest, 32, digest); + fingerprint = (digest[0] << 24) + (digest[1] << 16) + (digest[2] << 8) + digest[3]; + memzero(digest, sizeof(digest)); + return fingerprint; +} + +int hdnode_private_ckd(HDNode *inout, uint32_t i) +{ + static CONFIDENTIAL uint8_t data[1 + 32 + 4]; + static CONFIDENTIAL uint8_t I[32 + 32]; + static CONFIDENTIAL bignum256 a, b; + + if (i & 0x80000000) { // private derivation + data[0] = 0; + memcpy(data + 1, inout->private_key, 32); + } else { // public derivation + if (!inout->curve->params) { + return 0; + } + hdnode_fill_public_key(inout); + memcpy(data, inout->public_key, 33); + } + write_be(data + 33, i); + + bn_read_be(inout->private_key, &a); + + static CONFIDENTIAL HMAC_SHA512_CTX ctx; + hmac_sha512_Init(&ctx, inout->chain_code, 32); + hmac_sha512_Update(&ctx, data, sizeof(data)); + hmac_sha512_Final(&ctx, I); + + if (inout->curve->params) { + while (true) { + bool failed = false; + bn_read_be(I, &b); + if (!bn_is_less(&b, &inout->curve->params->order)) { // >= order + failed = true; + } else { + bn_add(&b, &a); + bn_mod(&b, &inout->curve->params->order); + if (bn_is_zero(&b)) { + failed = true; + } + } + + if (!failed) { + bn_write_be(&b, inout->private_key); + break; + } + + data[0] = 1; + memcpy(data + 1, I + 32, 32); + hmac_sha512_Init(&ctx, inout->chain_code, 32); + hmac_sha512_Update(&ctx, data, sizeof(data)); + hmac_sha512_Final(&ctx, I); + } + } else { + memcpy(inout->private_key, I, 32); + } + + memcpy(inout->chain_code, I + 32, 32); + inout->depth++; + inout->child_num = i; + memzero(inout->public_key, sizeof(inout->public_key)); + + // making sure to wipe our memory + memzero(&a, sizeof(a)); + memzero(&b, sizeof(b)); + memzero(I, sizeof(I)); + memzero(data, sizeof(data)); + return 1; +} + +int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, const uint8_t *parent_chain_code, uint32_t i, curve_point *child, uint8_t *child_chain_code) { + uint8_t data[1 + 32 + 4]; + uint8_t I[32 + 32]; + bignum256 c; + + if (i & 0x80000000) { // private derivation + return 0; + } + + data[0] = 0x02 | (parent->y.val[0] & 0x01); + bn_write_be(&parent->x, data + 1); + write_be(data + 33, i); + + while (true) { + hmac_sha512(parent_chain_code, 32, data, sizeof(data), I); + bn_read_be(I, &c); + if (bn_is_less(&c, &curve->order)) { // < order + scalar_multiply(curve, &c, child); // b = c * G + point_add(curve, parent, child); // b = a + b + if (!point_is_infinity(child)) { + if (child_chain_code) { + memcpy(child_chain_code, I + 32, 32); + } + + // Wipe all stack data. + memzero(data, sizeof(data)); + memzero(I, sizeof(I)); + memzero(&c, sizeof(c)); + return 1; + } + } + + data[0] = 1; + memcpy(data + 1, I + 32, 32); + } +} + +int hdnode_public_ckd(HDNode *inout, uint32_t i) +{ + curve_point parent, child; + + if (!ecdsa_read_pubkey(inout->curve->params, inout->public_key, &parent)) { + return 0; + } + if (!hdnode_public_ckd_cp(inout->curve->params, &parent, inout->chain_code, i, &child, inout->chain_code)) { + return 0; + } + memzero(inout->private_key, 32); + inout->depth++; + inout->child_num = i; + inout->public_key[0] = 0x02 | (child.y.val[0] & 0x01); + bn_write_be(&child.x, inout->public_key + 1); + + // Wipe all stack data. + memzero(&parent, sizeof(parent)); + memzero(&child, sizeof(child)); + + return 1; +} + +void hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *chain_code, uint32_t i, uint32_t version, HasherType hasher_type, char *addr, int addrsize, int addrformat) +{ + uint8_t child_pubkey[33]; + curve_point b; + + hdnode_public_ckd_cp(&secp256k1, pub, chain_code, i, &b, NULL); + child_pubkey[0] = 0x02 | (b.y.val[0] & 0x01); + bn_write_be(&b.x, child_pubkey + 1); + + switch (addrformat) { + case 1: // Segwit-in-P2SH + ecdsa_get_address_segwit_p2sh(child_pubkey, version, hasher_type, addr, addrsize); + break; + default: // normal address + ecdsa_get_address(child_pubkey, version, hasher_type, addr, addrsize); + break; + } +} + +#if USE_BIP32_CACHE +static bool private_ckd_cache_root_set = false; +static CONFIDENTIAL HDNode private_ckd_cache_root; +static int private_ckd_cache_index = 0; + +static CONFIDENTIAL struct { + bool set; + size_t depth; + uint32_t i[BIP32_CACHE_MAXDEPTH]; + HDNode node; +} private_ckd_cache[BIP32_CACHE_SIZE]; + +int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, uint32_t *fingerprint) +{ + if (i_count == 0) { + // no way how to compute parent fingerprint + return 1; + } + if (i_count == 1) { + if (fingerprint) { + *fingerprint = hdnode_fingerprint(inout); + } + if (hdnode_private_ckd(inout, i[0]) == 0) return 0; + return 1; + } + + bool found = false; + // if root is not set or not the same + if (!private_ckd_cache_root_set || memcmp(&private_ckd_cache_root, inout, sizeof(HDNode)) != 0) { + // clear the cache + private_ckd_cache_index = 0; + memzero(private_ckd_cache, sizeof(private_ckd_cache)); + // setup new root + memcpy(&private_ckd_cache_root, inout, sizeof(HDNode)); + private_ckd_cache_root_set = true; + } else { + // try to find parent + int j; + for (j = 0; j < BIP32_CACHE_SIZE; j++) { + if (private_ckd_cache[j].set && + private_ckd_cache[j].depth == i_count - 1 && + memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) == 0 && + private_ckd_cache[j].node.curve == inout->curve) { + memcpy(inout, &(private_ckd_cache[j].node), sizeof(HDNode)); + found = true; + break; + } + } + } + + // else derive parent + if (!found) { + size_t k; + for (k = 0; k < i_count - 1; k++) { + if (hdnode_private_ckd(inout, i[k]) == 0) return 0; + } + // and save it + memset(&(private_ckd_cache[private_ckd_cache_index]), 0, sizeof(private_ckd_cache[private_ckd_cache_index])); + private_ckd_cache[private_ckd_cache_index].set = true; + private_ckd_cache[private_ckd_cache_index].depth = i_count - 1; + memcpy(private_ckd_cache[private_ckd_cache_index].i, i, (i_count - 1) * sizeof(uint32_t)); + memcpy(&(private_ckd_cache[private_ckd_cache_index].node), inout, sizeof(HDNode)); + private_ckd_cache_index = (private_ckd_cache_index + 1) % BIP32_CACHE_SIZE; + } + + if (fingerprint) { + *fingerprint = hdnode_fingerprint(inout); + } + if (hdnode_private_ckd(inout, i[i_count - 1]) == 0) return 0; + + return 1; +} +#endif + +void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw) +{ + hdnode_fill_public_key(node); + ecdsa_get_address_raw(node->public_key, version, node->curve->hasher_type, addr_raw); +} + +void hdnode_get_address(HDNode *node, uint32_t version, char *addr, int addrsize) +{ + hdnode_fill_public_key(node); + ecdsa_get_address(node->public_key, version, node->curve->hasher_type, addr, addrsize); +} + +void hdnode_fill_public_key(HDNode *node) +{ + if (node->public_key[0] != 0) + return; + if (node->curve->params) { + ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key); + } else { + node->public_key[0] = 1; + if (node->curve == &ed25519_info) { + ed25519_publickey(node->private_key, node->public_key + 1); + } else if (node->curve == &ed25519_sha3_info) { + ed25519_publickey_sha3(node->private_key, node->public_key + 1); +#if USE_KECCAK + } else if (node->curve == &ed25519_keccak_info) { + ed25519_publickey_keccak(node->private_key, node->public_key + 1); +#endif + } else if (node->curve == &curve25519_info) { + curve25519_scalarmult_basepoint(node->public_key + 1, node->private_key); + } + } +} + +#if USE_ETHEREUM +int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) +{ + uint8_t buf[65]; + SHA3_CTX ctx; + + /* get uncompressed public key */ + ecdsa_get_public_key65(node->curve->params, node->private_key, buf); + + /* compute sha3 of x and y coordinate without 04 prefix */ + sha3_256_Init(&ctx); + sha3_Update(&ctx, buf + 1, 64); + keccak_Final(&ctx, buf); + + /* result are the least significant 160 bits */ + memcpy(pubkeyhash, buf + 12, 20); + + return 1; +} +#endif + +#if USE_NEM +int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address) { + if (node->curve != &ed25519_keccak_info) { + return 0; + } + + hdnode_fill_public_key(node); + return nem_get_address(&node->public_key[1], version, address); +} + +int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_public_key, const uint8_t *salt, ed25519_public_key mul, uint8_t *shared_key) { + if (node->curve != &ed25519_keccak_info) { + return 0; + } + + // sizeof(ed25519_public_key) == SHA3_256_DIGEST_LENGTH + if (mul == NULL) mul = shared_key; + + if (ed25519_scalarmult_keccak(mul, node->private_key, peer_public_key)) { + return 0; + } + + for (size_t i = 0; i < 32; i++) { + shared_key[i] = mul[i] ^ salt[i]; + } + + keccak_256(shared_key, 32, shared_key); + return 1; +} + +int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key, uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer) { + uint8_t last_block[AES_BLOCK_SIZE]; + uint8_t remainder = size % AES_BLOCK_SIZE; + + // Round down to last whole block + size -= remainder; + // Copy old last block + memcpy(last_block, &payload[size], remainder); + // Pad new last block with number of missing bytes + memset(&last_block[remainder], AES_BLOCK_SIZE - remainder, AES_BLOCK_SIZE - remainder); + + uint8_t shared_key[SHA3_256_DIGEST_LENGTH]; + if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { + return 0; + } + + aes_encrypt_ctx ctx; + + int ret = aes_encrypt_key256(shared_key, &ctx); + memzero(shared_key, sizeof(shared_key)); + + if (ret != EXIT_SUCCESS) { + return 0; + } + + if (aes_cbc_encrypt(payload, buffer, size, iv, &ctx) != EXIT_SUCCESS) { + return 0; + } + + if (aes_cbc_encrypt(last_block, &buffer[size], sizeof(last_block), iv, &ctx) != EXIT_SUCCESS) { + return 0; + } + + return 1; +} + +int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key, uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer) { + uint8_t shared_key[SHA3_256_DIGEST_LENGTH]; + + if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { + return 0; + } + + aes_decrypt_ctx ctx; + + int ret = aes_decrypt_key256(shared_key, &ctx); + memzero(shared_key, sizeof(shared_key)); + + if (ret != EXIT_SUCCESS) { + return 0; + } + + if (aes_cbc_decrypt(payload, buffer, size, iv, &ctx) != EXIT_SUCCESS) { + return 0; + } + + return 1; +} +#endif + +// msg is a data to be signed +// msg_len is the message length +int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])) +{ + if (node->curve->params) { + return ecdsa_sign(node->curve->params, node->curve->hasher_type, node->private_key, msg, msg_len, sig, pby, is_canonical); + } else if (node->curve == &curve25519_info) { + return 1; // signatures are not supported + } else { + hdnode_fill_public_key(node); + if (node->curve == &ed25519_info) { + ed25519_sign(msg, msg_len, node->private_key, node->public_key + 1, sig); + } else if (node->curve == &ed25519_sha3_info) { + ed25519_sign_sha3(msg, msg_len, node->private_key, node->public_key + 1, sig); +#if USE_KECCAK + } else if (node->curve == &ed25519_keccak_info) { + ed25519_sign_keccak(msg, msg_len, node->private_key, node->public_key + 1, sig); +#endif + } + return 0; + } +} + +int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])) +{ + if (node->curve->params) { + return ecdsa_sign_digest(node->curve->params, node->private_key, digest, sig, pby, is_canonical); + } else if (node->curve == &curve25519_info) { + return 1; // signatures are not supported + } else { + return hdnode_sign(node, digest, 32, sig, pby, is_canonical); + } +} + +int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key, int *result_size) +{ + // Use elliptic curve Diffie-Helman to compute shared session key + if (node->curve->params) { + if (ecdh_multiply(node->curve->params, node->private_key, peer_public_key, session_key) != 0) { + return 1; + } + *result_size = 65; + return 0; + } else if (node->curve == &curve25519_info) { + session_key[0] = 0x04; + if (peer_public_key[0] != 0x40) { + return 1; // Curve25519 public key should start with 0x40 byte. + } + curve25519_scalarmult(session_key + 1, node->private_key, peer_public_key + 1); + *result_size = 33; + return 0; + } else { + *result_size = 0; + return 1; // ECDH is not supported + } +} + +static int hdnode_serialize(const HDNode *node, uint32_t fingerprint, uint32_t version, char use_public, char *str, int strsize) +{ + uint8_t node_data[78]; + write_be(node_data, version); + node_data[4] = node->depth; + write_be(node_data + 5, fingerprint); + write_be(node_data + 9, node->child_num); + memcpy(node_data + 13, node->chain_code, 32); + if (use_public) { + memcpy(node_data + 45, node->public_key, 33); + } else { + node_data[45] = 0; + memcpy(node_data + 46, node->private_key, 32); + } + int ret = base58_encode_check(node_data, sizeof(node_data), node->curve->hasher_type, str, strsize); + memzero(node_data, sizeof(node_data)); + return ret; +} + +int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize) +{ + return hdnode_serialize(node, fingerprint, version, 1, str, strsize); +} + +int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize) +{ + return hdnode_serialize(node, fingerprint, version, 0, str, strsize); +} + +// check for validity of curve point in case of public data not performed +int hdnode_deserialize(const char *str, uint32_t version_public, uint32_t version_private, const char *curve, HDNode *node, uint32_t *fingerprint) +{ + uint8_t node_data[78]; + memset(node, 0, sizeof(HDNode)); + node->curve = get_curve_by_name(curve); + if (base58_decode_check(str, node->curve->hasher_type, node_data, sizeof(node_data)) != sizeof(node_data)) { + return -1; + } + uint32_t version = read_be(node_data); + if (version == version_public) { + memzero(node->private_key, sizeof(node->private_key)); + memcpy(node->public_key, node_data + 45, 33); + } else if (version == version_private) { // private node + if (node_data[45]) { // invalid data + return -2; + } + memcpy(node->private_key, node_data + 46, 32); + memzero(node->public_key, sizeof(node->public_key)); + } else { + return -3; // invalid version + } + node->depth = node_data[4]; + if (fingerprint) { + *fingerprint = read_be(node_data + 5); + } + node->child_num = read_be(node_data + 9); + memcpy(node->chain_code, node_data + 13, 32); + return 0; +} + +const curve_info *get_curve_by_name(const char *curve_name) { + if (curve_name == 0) { + return 0; + } + if (strcmp(curve_name, SECP256K1_NAME) == 0) { + return &secp256k1_info; + } + if (strcmp(curve_name, SECP256K1_DECRED_NAME) == 0) { + return &secp256k1_decred_info; + } + if (strcmp(curve_name, NIST256P1_NAME) == 0) { + return &nist256p1_info; + } + if (strcmp(curve_name, ED25519_NAME) == 0) { + return &ed25519_info; + } + if (strcmp(curve_name, ED25519_SHA3_NAME) == 0) { + return &ed25519_sha3_info; + } +#if USE_KECCAK + if (strcmp(curve_name, ED25519_KECCAK_NAME) == 0) { + return &ed25519_keccak_info; + } +#endif + if (strcmp(curve_name, CURVE25519_NAME) == 0) { + return &curve25519_info; + } + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/bip32.h b/hardware-wallet/firmware/vendor/trezor-crypto/bip32.h new file mode 100644 index 00000000..9e73d75c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/bip32.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __BIP32_H__ +#define __BIP32_H__ + +#include +#include +#include +#include "ecdsa.h" +#include "ed25519-donna/ed25519.h" +#include "options.h" + +typedef struct { + const char *bip32_name; // string for generating BIP32 xprv from seed + const ecdsa_curve *params; // ecdsa curve parameters, null for ed25519 + HasherType hasher_type; // hasher type for BIP32 and ECDSA +} curve_info; + +typedef struct { + uint32_t depth; + uint32_t child_num; + uint8_t chain_code[32]; + uint8_t private_key[32]; + uint8_t public_key[33]; + const curve_info *curve; +} HDNode; + +int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char *curve, HDNode *out); + +int hdnode_from_xprv(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, const char *curve, HDNode *out); + +int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve, HDNode *out); + +#define hdnode_private_ckd_prime(X, I) hdnode_private_ckd((X), ((I) | 0x80000000)) + +int hdnode_private_ckd(HDNode *inout, uint32_t i); + +int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, const uint8_t *parent_chain_code, uint32_t i, curve_point *child, uint8_t *child_chain_code); + +int hdnode_public_ckd(HDNode *inout, uint32_t i); + +void hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *chain_code, uint32_t i, uint32_t version, HasherType hasher_type, char *addr, int addrsize, int addrformat); + +#if USE_BIP32_CACHE +int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, uint32_t *fingerprint); +#endif + +uint32_t hdnode_fingerprint(HDNode *node); + +void hdnode_fill_public_key(HDNode *node); + +#if USE_ETHEREUM +int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash); +#endif + +#if USE_NEM +int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address); +int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_public_key, const uint8_t *salt, ed25519_public_key mul, uint8_t *shared_key); +int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key, uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer); +int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key, uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer); +#endif + +int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])); +int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])); + +int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key, int *result_size); + +int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize); + +int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize); + +int hdnode_deserialize(const char *str, uint32_t version_public, uint32_t version_private, const char *curve, HDNode *node, uint32_t *fingerprint); + +void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw); +void hdnode_get_address(HDNode *node, uint32_t version, char *addr, int addrsize); + +const curve_info *get_curve_by_name(const char *curve_name); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/bip39.c b/hardware-wallet/firmware/vendor/trezor-crypto/bip39.c new file mode 100644 index 00000000..b1bea445 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/bip39.c @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "bip39.h" +#include "hmac.h" +#include "rand.h" +#include "sha2.h" +#include "pbkdf2.h" +#include "bip39_english.h" +#include "options.h" +#include "memzero.h" + +#if USE_BIP39_CACHE + +static int bip39_cache_index = 0; + +static CONFIDENTIAL struct { + bool set; + char mnemonic[256]; + char passphrase[64]; + uint8_t seed[512 / 8]; +} bip39_cache[BIP39_CACHE_SIZE]; + +#endif + +const char *mnemonic_generate(int strength) +{ + if (strength % 32 || strength < 128 || strength > 256) { + return 0; + } + uint8_t data[32]; + random_buffer(data, 32); + const char *r = mnemonic_from_data(data, strength / 8); + memzero(data, sizeof(data)); + return r; +} + +const uint16_t *mnemonic_generate_indexes(int strength) +{ + if (strength % 32 || strength < 128 || strength > 256) { + return 0; + } + uint8_t data[32]; + random_buffer(data, 32); + const uint16_t *r = mnemonic_from_data_indexes(data, strength / 8); + memzero(data, sizeof(data)); + return r; +} + +const char *mnemonic_from_data(const uint8_t *data, int len) +{ + if (len % 4 || len < 16 || len > 32) { + return 0; + } + + uint8_t bits[32 + 1]; + + sha256_Raw(data, len, bits); + // checksum + bits[len] = bits[0]; + // data + memcpy(bits, data, len); + + int mlen = len * 3 / 4; + static CONFIDENTIAL char mnemo[24 * 10]; + + int i, j, idx; + char *p = mnemo; + for (i = 0; i < mlen; i++) { + idx = 0; + for (j = 0; j < 11; j++) { + idx <<= 1; + idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0; + } + strcpy(p, wordlist[idx]); + p += strlen(wordlist[idx]); + *p = (i < mlen - 1) ? ' ' : 0; + p++; + } + memzero(bits, sizeof(bits)); + + return mnemo; +} + +const uint16_t *mnemonic_from_data_indexes(const uint8_t *data, int len) +{ + if (len % 4 || len < 16 || len > 32) { + return 0; + } + + uint8_t bits[32 + 1]; + + sha256_Raw(data, len, bits); + // checksum + bits[len] = bits[0]; + // data + memcpy(bits, data, len); + + int mlen = len * 3 / 4; + static CONFIDENTIAL uint16_t mnemo[24]; + + int i, j, idx; + for (i = 0; i < mlen; i++) { + idx = 0; + for (j = 0; j < 11; j++) { + idx <<= 1; + idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0; + } + mnemo[i] = idx; + } + memzero(bits, sizeof(bits)); + + return mnemo; +} + +int mnemonic_check(const char *mnemonic) +{ + if (!mnemonic) { + return 0; + } + + uint32_t i, n; + + i = 0; n = 0; + while (mnemonic[i]) { + if (mnemonic[i] == ' ') { + n++; + } + i++; + } + n++; + // check number of words + if (n != 12 && n != 18 && n != 24) { + return 0; + } + + char current_word[10]; + uint32_t j, k, ki, bi; + uint8_t bits[32 + 1]; + + memzero(bits, sizeof(bits)); + i = 0; bi = 0; + while (mnemonic[i]) { + j = 0; + while (mnemonic[i] != ' ' && mnemonic[i] != 0) { + if (j >= sizeof(current_word) - 1) { + return 0; + } + current_word[j] = mnemonic[i]; + i++; j++; + } + current_word[j] = 0; + if (mnemonic[i] != 0) i++; + k = 0; + for (;;) { + if (!wordlist[k]) { // word not found + return 0; + } + if (strcmp(current_word, wordlist[k]) == 0) { // word found on index k + for (ki = 0; ki < 11; ki++) { + if (k & (1 << (10 - ki))) { + bits[bi / 8] |= 1 << (7 - (bi % 8)); + } + bi++; + } + break; + } + k++; + } + } + if (bi != n * 11) { + return 0; + } + bits[32] = bits[n * 4 / 3]; + sha256_Raw(bits, n * 4 / 3, bits); + if (n == 12) { + return (bits[0] & 0xF0) == (bits[32] & 0xF0); // compare first 4 bits + } else + if (n == 18) { + return (bits[0] & 0xFC) == (bits[32] & 0xFC); // compare first 6 bits + } else + if (n == 24) { + return bits[0] == bits[32]; // compare 8 bits + } + return 0; +} + +// passphrase must be at most 256 characters or code may crash +void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total)) +{ + int passphraselen = strlen(passphrase); +#if USE_BIP39_CACHE + int mnemoniclen = strlen(mnemonic); + // check cache + if (mnemoniclen < 256 && passphraselen < 64) { + for (int i = 0; i < BIP39_CACHE_SIZE; i++) { + if (!bip39_cache[i].set) continue; + if (strcmp(bip39_cache[i].mnemonic, mnemonic) != 0) continue; + if (strcmp(bip39_cache[i].passphrase, passphrase) != 0) continue; + // found the correct entry + memcpy(seed, bip39_cache[i].seed, 512 / 8); + return; + } + } +#endif + uint8_t salt[8 + 256]; + memcpy(salt, "mnemonic", 8); + memcpy(salt + 8, passphrase, passphraselen); + static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx; + pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)mnemonic, strlen(mnemonic), salt, passphraselen + 8); + if (progress_callback) { + progress_callback(0, BIP39_PBKDF2_ROUNDS); + } + for (int i = 0; i < 16; i++) { + pbkdf2_hmac_sha512_Update(&pctx, BIP39_PBKDF2_ROUNDS / 16); + if (progress_callback) { + progress_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 16, BIP39_PBKDF2_ROUNDS); + } + } + pbkdf2_hmac_sha512_Final(&pctx, seed); + memzero(salt, sizeof(salt)); +#if USE_BIP39_CACHE + // store to cache + if (mnemoniclen < 256 && passphraselen < 64) { + bip39_cache[bip39_cache_index].set = true; + strcpy(bip39_cache[bip39_cache_index].mnemonic, mnemonic); + strcpy(bip39_cache[bip39_cache_index].passphrase, passphrase); + memcpy(bip39_cache[bip39_cache_index].seed, seed, 512 / 8); + bip39_cache_index = (bip39_cache_index + 1) % BIP39_CACHE_SIZE; + } +#endif +} + +const char * const *mnemonic_wordlist(void) +{ + return wordlist; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/bip39.h b/hardware-wallet/firmware/vendor/trezor-crypto/bip39.h new file mode 100644 index 00000000..385f3d4f --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/bip39.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __BIP39_H__ +#define __BIP39_H__ + +#include + +#define BIP39_PBKDF2_ROUNDS 2048 + +const char *mnemonic_generate(int strength); // strength in bits +const uint16_t *mnemonic_generate_indexes(int strength); // strength in bits + +const char *mnemonic_from_data(const uint8_t *data, int len); +const uint16_t *mnemonic_from_data_indexes(const uint8_t *data, int len); + +int mnemonic_check(const char *mnemonic); + +// passphrase must be at most 256 characters or code may crash +void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total)); + +const char * const *mnemonic_wordlist(void); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/bip39_english.h b/hardware-wallet/firmware/vendor/trezor-crypto/bip39_english.h new file mode 100644 index 00000000..77607ba7 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/bip39_english.h @@ -0,0 +1,2074 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +static const char * const wordlist[] = { +"abandon", +"ability", +"able", +"about", +"above", +"absent", +"absorb", +"abstract", +"absurd", +"abuse", +"access", +"accident", +"account", +"accuse", +"achieve", +"acid", +"acoustic", +"acquire", +"across", +"act", +"action", +"actor", +"actress", +"actual", +"adapt", +"add", +"addict", +"address", +"adjust", +"admit", +"adult", +"advance", +"advice", +"aerobic", +"affair", +"afford", +"afraid", +"again", +"age", +"agent", +"agree", +"ahead", +"aim", +"air", +"airport", +"aisle", +"alarm", +"album", +"alcohol", +"alert", +"alien", +"all", +"alley", +"allow", +"almost", +"alone", +"alpha", +"already", +"also", +"alter", +"always", +"amateur", +"amazing", +"among", +"amount", +"amused", +"analyst", +"anchor", +"ancient", +"anger", +"angle", +"angry", +"animal", +"ankle", +"announce", +"annual", +"another", +"answer", +"antenna", +"antique", +"anxiety", +"any", +"apart", +"apology", +"appear", +"apple", +"approve", +"april", +"arch", +"arctic", +"area", +"arena", +"argue", +"arm", +"armed", +"armor", +"army", +"around", +"arrange", +"arrest", +"arrive", +"arrow", +"art", +"artefact", +"artist", +"artwork", +"ask", +"aspect", +"assault", +"asset", +"assist", +"assume", +"asthma", +"athlete", +"atom", +"attack", +"attend", +"attitude", +"attract", +"auction", +"audit", +"august", +"aunt", +"author", +"auto", +"autumn", +"average", +"avocado", +"avoid", +"awake", +"aware", +"away", +"awesome", +"awful", +"awkward", +"axis", +"baby", +"bachelor", +"bacon", +"badge", +"bag", +"balance", +"balcony", +"ball", +"bamboo", +"banana", +"banner", +"bar", +"barely", +"bargain", +"barrel", +"base", +"basic", +"basket", +"battle", +"beach", +"bean", +"beauty", +"because", +"become", +"beef", +"before", +"begin", +"behave", +"behind", +"believe", +"below", +"belt", +"bench", +"benefit", +"best", +"betray", +"better", +"between", +"beyond", +"bicycle", +"bid", +"bike", +"bind", +"biology", +"bird", +"birth", +"bitter", +"black", +"blade", +"blame", +"blanket", +"blast", +"bleak", +"bless", +"blind", +"blood", +"blossom", +"blouse", +"blue", +"blur", +"blush", +"board", +"boat", +"body", +"boil", +"bomb", +"bone", +"bonus", +"book", +"boost", +"border", +"boring", +"borrow", +"boss", +"bottom", +"bounce", +"box", +"boy", +"bracket", +"brain", +"brand", +"brass", +"brave", +"bread", +"breeze", +"brick", +"bridge", +"brief", +"bright", +"bring", +"brisk", +"broccoli", +"broken", +"bronze", +"broom", +"brother", +"brown", +"brush", +"bubble", +"buddy", +"budget", +"buffalo", +"build", +"bulb", +"bulk", +"bullet", +"bundle", +"bunker", +"burden", +"burger", +"burst", +"bus", +"business", +"busy", +"butter", +"buyer", +"buzz", +"cabbage", +"cabin", +"cable", +"cactus", +"cage", +"cake", +"call", +"calm", +"camera", +"camp", +"can", +"canal", +"cancel", +"candy", +"cannon", +"canoe", +"canvas", +"canyon", +"capable", +"capital", +"captain", +"car", +"carbon", +"card", +"cargo", +"carpet", +"carry", +"cart", +"case", +"cash", +"casino", +"castle", +"casual", +"cat", +"catalog", +"catch", +"category", +"cattle", +"caught", +"cause", +"caution", +"cave", +"ceiling", +"celery", +"cement", +"census", +"century", +"cereal", +"certain", +"chair", +"chalk", +"champion", +"change", +"chaos", +"chapter", +"charge", +"chase", +"chat", +"cheap", +"check", +"cheese", +"chef", +"cherry", +"chest", +"chicken", +"chief", +"child", +"chimney", +"choice", +"choose", +"chronic", +"chuckle", +"chunk", +"churn", +"cigar", +"cinnamon", +"circle", +"citizen", +"city", +"civil", +"claim", +"clap", +"clarify", +"claw", +"clay", +"clean", +"clerk", +"clever", +"click", +"client", +"cliff", +"climb", +"clinic", +"clip", +"clock", +"clog", +"close", +"cloth", +"cloud", +"clown", +"club", +"clump", +"cluster", +"clutch", +"coach", +"coast", +"coconut", +"code", +"coffee", +"coil", +"coin", +"collect", +"color", +"column", +"combine", +"come", +"comfort", +"comic", +"common", +"company", +"concert", +"conduct", +"confirm", +"congress", +"connect", +"consider", +"control", +"convince", +"cook", +"cool", +"copper", +"copy", +"coral", +"core", +"corn", +"correct", +"cost", +"cotton", +"couch", +"country", +"couple", +"course", +"cousin", +"cover", +"coyote", +"crack", +"cradle", +"craft", +"cram", +"crane", +"crash", +"crater", +"crawl", +"crazy", +"cream", +"credit", +"creek", +"crew", +"cricket", +"crime", +"crisp", +"critic", +"crop", +"cross", +"crouch", +"crowd", +"crucial", +"cruel", +"cruise", +"crumble", +"crunch", +"crush", +"cry", +"crystal", +"cube", +"culture", +"cup", +"cupboard", +"curious", +"current", +"curtain", +"curve", +"cushion", +"custom", +"cute", +"cycle", +"dad", +"damage", +"damp", +"dance", +"danger", +"daring", +"dash", +"daughter", +"dawn", +"day", +"deal", +"debate", +"debris", +"decade", +"december", +"decide", +"decline", +"decorate", +"decrease", +"deer", +"defense", +"define", +"defy", +"degree", +"delay", +"deliver", +"demand", +"demise", +"denial", +"dentist", +"deny", +"depart", +"depend", +"deposit", +"depth", +"deputy", +"derive", +"describe", +"desert", +"design", +"desk", +"despair", +"destroy", +"detail", +"detect", +"develop", +"device", +"devote", +"diagram", +"dial", +"diamond", +"diary", +"dice", +"diesel", +"diet", +"differ", +"digital", +"dignity", +"dilemma", +"dinner", +"dinosaur", +"direct", +"dirt", +"disagree", +"discover", +"disease", +"dish", +"dismiss", +"disorder", +"display", +"distance", +"divert", +"divide", +"divorce", +"dizzy", +"doctor", +"document", +"dog", +"doll", +"dolphin", +"domain", +"donate", +"donkey", +"donor", +"door", +"dose", +"double", +"dove", +"draft", +"dragon", +"drama", +"drastic", +"draw", +"dream", +"dress", +"drift", +"drill", +"drink", +"drip", +"drive", +"drop", +"drum", +"dry", +"duck", +"dumb", +"dune", +"during", +"dust", +"dutch", +"duty", +"dwarf", +"dynamic", +"eager", +"eagle", +"early", +"earn", +"earth", +"easily", +"east", +"easy", +"echo", +"ecology", +"economy", +"edge", +"edit", +"educate", +"effort", +"egg", +"eight", +"either", +"elbow", +"elder", +"electric", +"elegant", +"element", +"elephant", +"elevator", +"elite", +"else", +"embark", +"embody", +"embrace", +"emerge", +"emotion", +"employ", +"empower", +"empty", +"enable", +"enact", +"end", +"endless", +"endorse", +"enemy", +"energy", +"enforce", +"engage", +"engine", +"enhance", +"enjoy", +"enlist", +"enough", +"enrich", +"enroll", +"ensure", +"enter", +"entire", +"entry", +"envelope", +"episode", +"equal", +"equip", +"era", +"erase", +"erode", +"erosion", +"error", +"erupt", +"escape", +"essay", +"essence", +"estate", +"eternal", +"ethics", +"evidence", +"evil", +"evoke", +"evolve", +"exact", +"example", +"excess", +"exchange", +"excite", +"exclude", +"excuse", +"execute", +"exercise", +"exhaust", +"exhibit", +"exile", +"exist", +"exit", +"exotic", +"expand", +"expect", +"expire", +"explain", +"expose", +"express", +"extend", +"extra", +"eye", +"eyebrow", +"fabric", +"face", +"faculty", +"fade", +"faint", +"faith", +"fall", +"false", +"fame", +"family", +"famous", +"fan", +"fancy", +"fantasy", +"farm", +"fashion", +"fat", +"fatal", +"father", +"fatigue", +"fault", +"favorite", +"feature", +"february", +"federal", +"fee", +"feed", +"feel", +"female", +"fence", +"festival", +"fetch", +"fever", +"few", +"fiber", +"fiction", +"field", +"figure", +"file", +"film", +"filter", +"final", +"find", +"fine", +"finger", +"finish", +"fire", +"firm", +"first", +"fiscal", +"fish", +"fit", +"fitness", +"fix", +"flag", +"flame", +"flash", +"flat", +"flavor", +"flee", +"flight", +"flip", +"float", +"flock", +"floor", +"flower", +"fluid", +"flush", +"fly", +"foam", +"focus", +"fog", +"foil", +"fold", +"follow", +"food", +"foot", +"force", +"forest", +"forget", +"fork", +"fortune", +"forum", +"forward", +"fossil", +"foster", +"found", +"fox", +"fragile", +"frame", +"frequent", +"fresh", +"friend", +"fringe", +"frog", +"front", +"frost", +"frown", +"frozen", +"fruit", +"fuel", +"fun", +"funny", +"furnace", +"fury", +"future", +"gadget", +"gain", +"galaxy", +"gallery", +"game", +"gap", +"garage", +"garbage", +"garden", +"garlic", +"garment", +"gas", +"gasp", +"gate", +"gather", +"gauge", +"gaze", +"general", +"genius", +"genre", +"gentle", +"genuine", +"gesture", +"ghost", +"giant", +"gift", +"giggle", +"ginger", +"giraffe", +"girl", +"give", +"glad", +"glance", +"glare", +"glass", +"glide", +"glimpse", +"globe", +"gloom", +"glory", +"glove", +"glow", +"glue", +"goat", +"goddess", +"gold", +"good", +"goose", +"gorilla", +"gospel", +"gossip", +"govern", +"gown", +"grab", +"grace", +"grain", +"grant", +"grape", +"grass", +"gravity", +"great", +"green", +"grid", +"grief", +"grit", +"grocery", +"group", +"grow", +"grunt", +"guard", +"guess", +"guide", +"guilt", +"guitar", +"gun", +"gym", +"habit", +"hair", +"half", +"hammer", +"hamster", +"hand", +"happy", +"harbor", +"hard", +"harsh", +"harvest", +"hat", +"have", +"hawk", +"hazard", +"head", +"health", +"heart", +"heavy", +"hedgehog", +"height", +"hello", +"helmet", +"help", +"hen", +"hero", +"hidden", +"high", +"hill", +"hint", +"hip", +"hire", +"history", +"hobby", +"hockey", +"hold", +"hole", +"holiday", +"hollow", +"home", +"honey", +"hood", +"hope", +"horn", +"horror", +"horse", +"hospital", +"host", +"hotel", +"hour", +"hover", +"hub", +"huge", +"human", +"humble", +"humor", +"hundred", +"hungry", +"hunt", +"hurdle", +"hurry", +"hurt", +"husband", +"hybrid", +"ice", +"icon", +"idea", +"identify", +"idle", +"ignore", +"ill", +"illegal", +"illness", +"image", +"imitate", +"immense", +"immune", +"impact", +"impose", +"improve", +"impulse", +"inch", +"include", +"income", +"increase", +"index", +"indicate", +"indoor", +"industry", +"infant", +"inflict", +"inform", +"inhale", +"inherit", +"initial", +"inject", +"injury", +"inmate", +"inner", +"innocent", +"input", +"inquiry", +"insane", +"insect", +"inside", +"inspire", +"install", +"intact", +"interest", +"into", +"invest", +"invite", +"involve", +"iron", +"island", +"isolate", +"issue", +"item", +"ivory", +"jacket", +"jaguar", +"jar", +"jazz", +"jealous", +"jeans", +"jelly", +"jewel", +"job", +"join", +"joke", +"journey", +"joy", +"judge", +"juice", +"jump", +"jungle", +"junior", +"junk", +"just", +"kangaroo", +"keen", +"keep", +"ketchup", +"key", +"kick", +"kid", +"kidney", +"kind", +"kingdom", +"kiss", +"kit", +"kitchen", +"kite", +"kitten", +"kiwi", +"knee", +"knife", +"knock", +"know", +"lab", +"label", +"labor", +"ladder", +"lady", +"lake", +"lamp", +"language", +"laptop", +"large", +"later", +"latin", +"laugh", +"laundry", +"lava", +"law", +"lawn", +"lawsuit", +"layer", +"lazy", +"leader", +"leaf", +"learn", +"leave", +"lecture", +"left", +"leg", +"legal", +"legend", +"leisure", +"lemon", +"lend", +"length", +"lens", +"leopard", +"lesson", +"letter", +"level", +"liar", +"liberty", +"library", +"license", +"life", +"lift", +"light", +"like", +"limb", +"limit", +"link", +"lion", +"liquid", +"list", +"little", +"live", +"lizard", +"load", +"loan", +"lobster", +"local", +"lock", +"logic", +"lonely", +"long", +"loop", +"lottery", +"loud", +"lounge", +"love", +"loyal", +"lucky", +"luggage", +"lumber", +"lunar", +"lunch", +"luxury", +"lyrics", +"machine", +"mad", +"magic", +"magnet", +"maid", +"mail", +"main", +"major", +"make", +"mammal", +"man", +"manage", +"mandate", +"mango", +"mansion", +"manual", +"maple", +"marble", +"march", +"margin", +"marine", +"market", +"marriage", +"mask", +"mass", +"master", +"match", +"material", +"math", +"matrix", +"matter", +"maximum", +"maze", +"meadow", +"mean", +"measure", +"meat", +"mechanic", +"medal", +"media", +"melody", +"melt", +"member", +"memory", +"mention", +"menu", +"mercy", +"merge", +"merit", +"merry", +"mesh", +"message", +"metal", +"method", +"middle", +"midnight", +"milk", +"million", +"mimic", +"mind", +"minimum", +"minor", +"minute", +"miracle", +"mirror", +"misery", +"miss", +"mistake", +"mix", +"mixed", +"mixture", +"mobile", +"model", +"modify", +"mom", +"moment", +"monitor", +"monkey", +"monster", +"month", +"moon", +"moral", +"more", +"morning", +"mosquito", +"mother", +"motion", +"motor", +"mountain", +"mouse", +"move", +"movie", +"much", +"muffin", +"mule", +"multiply", +"muscle", +"museum", +"mushroom", +"music", +"must", +"mutual", +"myself", +"mystery", +"myth", +"naive", +"name", +"napkin", +"narrow", +"nasty", +"nation", +"nature", +"near", +"neck", +"need", +"negative", +"neglect", +"neither", +"nephew", +"nerve", +"nest", +"net", +"network", +"neutral", +"never", +"news", +"next", +"nice", +"night", +"noble", +"noise", +"nominee", +"noodle", +"normal", +"north", +"nose", +"notable", +"note", +"nothing", +"notice", +"novel", +"now", +"nuclear", +"number", +"nurse", +"nut", +"oak", +"obey", +"object", +"oblige", +"obscure", +"observe", +"obtain", +"obvious", +"occur", +"ocean", +"october", +"odor", +"off", +"offer", +"office", +"often", +"oil", +"okay", +"old", +"olive", +"olympic", +"omit", +"once", +"one", +"onion", +"online", +"only", +"open", +"opera", +"opinion", +"oppose", +"option", +"orange", +"orbit", +"orchard", +"order", +"ordinary", +"organ", +"orient", +"original", +"orphan", +"ostrich", +"other", +"outdoor", +"outer", +"output", +"outside", +"oval", +"oven", +"over", +"own", +"owner", +"oxygen", +"oyster", +"ozone", +"pact", +"paddle", +"page", +"pair", +"palace", +"palm", +"panda", +"panel", +"panic", +"panther", +"paper", +"parade", +"parent", +"park", +"parrot", +"party", +"pass", +"patch", +"path", +"patient", +"patrol", +"pattern", +"pause", +"pave", +"payment", +"peace", +"peanut", +"pear", +"peasant", +"pelican", +"pen", +"penalty", +"pencil", +"people", +"pepper", +"perfect", +"permit", +"person", +"pet", +"phone", +"photo", +"phrase", +"physical", +"piano", +"picnic", +"picture", +"piece", +"pig", +"pigeon", +"pill", +"pilot", +"pink", +"pioneer", +"pipe", +"pistol", +"pitch", +"pizza", +"place", +"planet", +"plastic", +"plate", +"play", +"please", +"pledge", +"pluck", +"plug", +"plunge", +"poem", +"poet", +"point", +"polar", +"pole", +"police", +"pond", +"pony", +"pool", +"popular", +"portion", +"position", +"possible", +"post", +"potato", +"pottery", +"poverty", +"powder", +"power", +"practice", +"praise", +"predict", +"prefer", +"prepare", +"present", +"pretty", +"prevent", +"price", +"pride", +"primary", +"print", +"priority", +"prison", +"private", +"prize", +"problem", +"process", +"produce", +"profit", +"program", +"project", +"promote", +"proof", +"property", +"prosper", +"protect", +"proud", +"provide", +"public", +"pudding", +"pull", +"pulp", +"pulse", +"pumpkin", +"punch", +"pupil", +"puppy", +"purchase", +"purity", +"purpose", +"purse", +"push", +"put", +"puzzle", +"pyramid", +"quality", +"quantum", +"quarter", +"question", +"quick", +"quit", +"quiz", +"quote", +"rabbit", +"raccoon", +"race", +"rack", +"radar", +"radio", +"rail", +"rain", +"raise", +"rally", +"ramp", +"ranch", +"random", +"range", +"rapid", +"rare", +"rate", +"rather", +"raven", +"raw", +"razor", +"ready", +"real", +"reason", +"rebel", +"rebuild", +"recall", +"receive", +"recipe", +"record", +"recycle", +"reduce", +"reflect", +"reform", +"refuse", +"region", +"regret", +"regular", +"reject", +"relax", +"release", +"relief", +"rely", +"remain", +"remember", +"remind", +"remove", +"render", +"renew", +"rent", +"reopen", +"repair", +"repeat", +"replace", +"report", +"require", +"rescue", +"resemble", +"resist", +"resource", +"response", +"result", +"retire", +"retreat", +"return", +"reunion", +"reveal", +"review", +"reward", +"rhythm", +"rib", +"ribbon", +"rice", +"rich", +"ride", +"ridge", +"rifle", +"right", +"rigid", +"ring", +"riot", +"ripple", +"risk", +"ritual", +"rival", +"river", +"road", +"roast", +"robot", +"robust", +"rocket", +"romance", +"roof", +"rookie", +"room", +"rose", +"rotate", +"rough", +"round", +"route", +"royal", +"rubber", +"rude", +"rug", +"rule", +"run", +"runway", +"rural", +"sad", +"saddle", +"sadness", +"safe", +"sail", +"salad", +"salmon", +"salon", +"salt", +"salute", +"same", +"sample", +"sand", +"satisfy", +"satoshi", +"sauce", +"sausage", +"save", +"say", +"scale", +"scan", +"scare", +"scatter", +"scene", +"scheme", +"school", +"science", +"scissors", +"scorpion", +"scout", +"scrap", +"screen", +"script", +"scrub", +"sea", +"search", +"season", +"seat", +"second", +"secret", +"section", +"security", +"seed", +"seek", +"segment", +"select", +"sell", +"seminar", +"senior", +"sense", +"sentence", +"series", +"service", +"session", +"settle", +"setup", +"seven", +"shadow", +"shaft", +"shallow", +"share", +"shed", +"shell", +"sheriff", +"shield", +"shift", +"shine", +"ship", +"shiver", +"shock", +"shoe", +"shoot", +"shop", +"short", +"shoulder", +"shove", +"shrimp", +"shrug", +"shuffle", +"shy", +"sibling", +"sick", +"side", +"siege", +"sight", +"sign", +"silent", +"silk", +"silly", +"silver", +"similar", +"simple", +"since", +"sing", +"siren", +"sister", +"situate", +"six", +"size", +"skate", +"sketch", +"ski", +"skill", +"skin", +"skirt", +"skull", +"slab", +"slam", +"sleep", +"slender", +"slice", +"slide", +"slight", +"slim", +"slogan", +"slot", +"slow", +"slush", +"small", +"smart", +"smile", +"smoke", +"smooth", +"snack", +"snake", +"snap", +"sniff", +"snow", +"soap", +"soccer", +"social", +"sock", +"soda", +"soft", +"solar", +"soldier", +"solid", +"solution", +"solve", +"someone", +"song", +"soon", +"sorry", +"sort", +"soul", +"sound", +"soup", +"source", +"south", +"space", +"spare", +"spatial", +"spawn", +"speak", +"special", +"speed", +"spell", +"spend", +"sphere", +"spice", +"spider", +"spike", +"spin", +"spirit", +"split", +"spoil", +"sponsor", +"spoon", +"sport", +"spot", +"spray", +"spread", +"spring", +"spy", +"square", +"squeeze", +"squirrel", +"stable", +"stadium", +"staff", +"stage", +"stairs", +"stamp", +"stand", +"start", +"state", +"stay", +"steak", +"steel", +"stem", +"step", +"stereo", +"stick", +"still", +"sting", +"stock", +"stomach", +"stone", +"stool", +"story", +"stove", +"strategy", +"street", +"strike", +"strong", +"struggle", +"student", +"stuff", +"stumble", +"style", +"subject", +"submit", +"subway", +"success", +"such", +"sudden", +"suffer", +"sugar", +"suggest", +"suit", +"summer", +"sun", +"sunny", +"sunset", +"super", +"supply", +"supreme", +"sure", +"surface", +"surge", +"surprise", +"surround", +"survey", +"suspect", +"sustain", +"swallow", +"swamp", +"swap", +"swarm", +"swear", +"sweet", +"swift", +"swim", +"swing", +"switch", +"sword", +"symbol", +"symptom", +"syrup", +"system", +"table", +"tackle", +"tag", +"tail", +"talent", +"talk", +"tank", +"tape", +"target", +"task", +"taste", +"tattoo", +"taxi", +"teach", +"team", +"tell", +"ten", +"tenant", +"tennis", +"tent", +"term", +"test", +"text", +"thank", +"that", +"theme", +"then", +"theory", +"there", +"they", +"thing", +"this", +"thought", +"three", +"thrive", +"throw", +"thumb", +"thunder", +"ticket", +"tide", +"tiger", +"tilt", +"timber", +"time", +"tiny", +"tip", +"tired", +"tissue", +"title", +"toast", +"tobacco", +"today", +"toddler", +"toe", +"together", +"toilet", +"token", +"tomato", +"tomorrow", +"tone", +"tongue", +"tonight", +"tool", +"tooth", +"top", +"topic", +"topple", +"torch", +"tornado", +"tortoise", +"toss", +"total", +"tourist", +"toward", +"tower", +"town", +"toy", +"track", +"trade", +"traffic", +"tragic", +"train", +"transfer", +"trap", +"trash", +"travel", +"tray", +"treat", +"tree", +"trend", +"trial", +"tribe", +"trick", +"trigger", +"trim", +"trip", +"trophy", +"trouble", +"truck", +"true", +"truly", +"trumpet", +"trust", +"truth", +"try", +"tube", +"tuition", +"tumble", +"tuna", +"tunnel", +"turkey", +"turn", +"turtle", +"twelve", +"twenty", +"twice", +"twin", +"twist", +"two", +"type", +"typical", +"ugly", +"umbrella", +"unable", +"unaware", +"uncle", +"uncover", +"under", +"undo", +"unfair", +"unfold", +"unhappy", +"uniform", +"unique", +"unit", +"universe", +"unknown", +"unlock", +"until", +"unusual", +"unveil", +"update", +"upgrade", +"uphold", +"upon", +"upper", +"upset", +"urban", +"urge", +"usage", +"use", +"used", +"useful", +"useless", +"usual", +"utility", +"vacant", +"vacuum", +"vague", +"valid", +"valley", +"valve", +"van", +"vanish", +"vapor", +"various", +"vast", +"vault", +"vehicle", +"velvet", +"vendor", +"venture", +"venue", +"verb", +"verify", +"version", +"very", +"vessel", +"veteran", +"viable", +"vibrant", +"vicious", +"victory", +"video", +"view", +"village", +"vintage", +"violin", +"virtual", +"virus", +"visa", +"visit", +"visual", +"vital", +"vivid", +"vocal", +"voice", +"void", +"volcano", +"volume", +"vote", +"voyage", +"wage", +"wagon", +"wait", +"walk", +"wall", +"walnut", +"want", +"warfare", +"warm", +"warrior", +"wash", +"wasp", +"waste", +"water", +"wave", +"way", +"wealth", +"weapon", +"wear", +"weasel", +"weather", +"web", +"wedding", +"weekend", +"weird", +"welcome", +"west", +"wet", +"whale", +"what", +"wheat", +"wheel", +"when", +"where", +"whip", +"whisper", +"wide", +"width", +"wife", +"wild", +"will", +"win", +"window", +"wine", +"wing", +"wink", +"winner", +"winter", +"wire", +"wisdom", +"wise", +"wish", +"witness", +"wolf", +"woman", +"wonder", +"wood", +"wool", +"word", +"work", +"world", +"worry", +"worth", +"wrap", +"wreck", +"wrestle", +"wrist", +"write", +"wrong", +"yard", +"year", +"yellow", +"you", +"young", +"youth", +"zebra", +"zero", +"zone", +"zoo", +0, +}; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/blake256.c b/hardware-wallet/firmware/vendor/trezor-crypto/blake256.c new file mode 100644 index 00000000..99871e5e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/blake256.c @@ -0,0 +1,235 @@ +/* + BLAKE reference C implementation + + Copyright (c) 2012 Jean-Philippe Aumasson + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . + */ +#include "blake256.h" + +#include + +#define U8TO32_BIG(p) \ + (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ + ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) + +#define U32TO8_BIG(p, v) \ + (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ + (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); + +static const uint8_t sigma[][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } +}; + +static const uint32_t u256[16] = +{ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917 +}; + +static const uint8_t padding[129] = +{ + 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, 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, 0, 0 +}; + +static void blake256_compress( BLAKE256_CTX *S, const uint8_t *block ) +{ + uint32_t v[16], m[16], i; +#define ROT(x,n) (((x)<<(32-n))|( (x)>>(n))) +#define G(a,b,c,d,e) \ + v[a] += (m[sigma[i][e]] ^ u256[sigma[i][e+1]]) + v[b]; \ + v[d] = ROT( v[d] ^ v[a],16); \ + v[c] += v[d]; \ + v[b] = ROT( v[b] ^ v[c],12); \ + v[a] += (m[sigma[i][e+1]] ^ u256[sigma[i][e]])+v[b]; \ + v[d] = ROT( v[d] ^ v[a], 8); \ + v[c] += v[d]; \ + v[b] = ROT( v[b] ^ v[c], 7); + + for( i = 0; i < 16; ++i ) m[i] = U8TO32_BIG( block + i * 4 ); + + for( i = 0; i < 8; ++i ) v[i] = S->h[i]; + + v[ 8] = S->s[0] ^ u256[0]; + v[ 9] = S->s[1] ^ u256[1]; + v[10] = S->s[2] ^ u256[2]; + v[11] = S->s[3] ^ u256[3]; + v[12] = u256[4]; + v[13] = u256[5]; + v[14] = u256[6]; + v[15] = u256[7]; + + /* don't xor t when the block is only padding */ + if ( !S->nullt ) + { + v[12] ^= S->t[0]; + v[13] ^= S->t[0]; + v[14] ^= S->t[1]; + v[15] ^= S->t[1]; + } + + for( i = 0; i < 14; ++i ) + { + /* column step */ + G( 0, 4, 8, 12, 0 ); + G( 1, 5, 9, 13, 2 ); + G( 2, 6, 10, 14, 4 ); + G( 3, 7, 11, 15, 6 ); + /* diagonal step */ + G( 0, 5, 10, 15, 8 ); + G( 1, 6, 11, 12, 10 ); + G( 2, 7, 8, 13, 12 ); + G( 3, 4, 9, 14, 14 ); + } + + for( i = 0; i < 16; ++i ) S->h[i % 8] ^= v[i]; + + for( i = 0; i < 8 ; ++i ) S->h[i] ^= S->s[i % 4]; +} + + +void blake256_Init( BLAKE256_CTX *S ) +{ + S->h[0] = 0x6a09e667; + S->h[1] = 0xbb67ae85; + S->h[2] = 0x3c6ef372; + S->h[3] = 0xa54ff53a; + S->h[4] = 0x510e527f; + S->h[5] = 0x9b05688c; + S->h[6] = 0x1f83d9ab; + S->h[7] = 0x5be0cd19; + S->t[0] = S->t[1] = S->buflen = S->nullt = 0; + S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; +} + + +void blake256_Update( BLAKE256_CTX *S, const uint8_t *in, size_t inlen ) +{ + size_t left = S->buflen; + size_t fill = 64 - left; + + /* data left and data received fill a block */ + if( left && ( inlen >= fill ) ) + { + memcpy( ( void * ) ( S->buf + left ), ( void * ) in, fill ); + S->t[0] += 512; + + if ( S->t[0] == 0 ) S->t[1]++; + + blake256_compress( S, S->buf ); + in += fill; + inlen -= fill; + left = 0; + } + + /* compress blocks of data received */ + while( inlen >= 64 ) + { + S->t[0] += 512; + + if ( S->t[0] == 0 ) S->t[1]++; + + blake256_compress( S, in ); + in += 64; + inlen -= 64; + } + + /* store any data left */ + if( inlen > 0 ) + { + memcpy( ( void * ) ( S->buf + left ), \ + ( void * ) in, ( size_t ) inlen ); + S->buflen = left + ( int )inlen; + } + else S->buflen = 0; +} + + +void blake256_Final( BLAKE256_CTX *S, uint8_t *out ) +{ + uint8_t msglen[8], zo = 0x01, oo = 0x81; + uint32_t lo = S->t[0] + ( S->buflen << 3 ), hi = S->t[1]; + + /* support for hashing more than 2^32 bits */ + if ( lo < ( S->buflen << 3 ) ) hi++; + + U32TO8_BIG( msglen + 0, hi ); + U32TO8_BIG( msglen + 4, lo ); + + if ( S->buflen == 55 ) /* one padding byte */ + { + S->t[0] -= 8; + blake256_Update( S, &oo, 1 ); + } + else + { + if ( S->buflen < 55 ) /* enough space to fill the block */ + { + if ( !S->buflen ) S->nullt = 1; + + S->t[0] -= 440 - ( S->buflen << 3 ); + blake256_Update( S, padding, 55 - S->buflen ); + } + else /* need 2 compressions */ + { + S->t[0] -= 512 - ( S->buflen << 3 ); + blake256_Update( S, padding, 64 - S->buflen ); + S->t[0] -= 440; + blake256_Update( S, padding + 1, 55 ); + S->nullt = 1; + } + + blake256_Update( S, &zo, 1 ); + S->t[0] -= 8; + } + + S->t[0] -= 64; + blake256_Update( S, msglen, 8 ); + U32TO8_BIG( out + 0, S->h[0] ); + U32TO8_BIG( out + 4, S->h[1] ); + U32TO8_BIG( out + 8, S->h[2] ); + U32TO8_BIG( out + 12, S->h[3] ); + U32TO8_BIG( out + 16, S->h[4] ); + U32TO8_BIG( out + 20, S->h[5] ); + U32TO8_BIG( out + 24, S->h[6] ); + U32TO8_BIG( out + 28, S->h[7] ); +} + + +void blake256( const uint8_t *in, size_t inlen, uint8_t *out ) +{ + BLAKE256_CTX S; + blake256_Init( &S ); + blake256_Update( &S, in, inlen ); + blake256_Final( &S, out ); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/blake256.h b/hardware-wallet/firmware/vendor/trezor-crypto/blake256.h new file mode 100644 index 00000000..313b6260 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/blake256.h @@ -0,0 +1,53 @@ +// Copyright (c) 2014-2017, The Monero Project +// +// 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. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#ifndef __BLAKE256_H__ +#define __BLAKE256_H__ + +#include +#include + +#define BLAKE256_DIGEST_LENGTH 32 +#define BLAKE256_BLOCK_LENGTH 64 + +typedef struct { + uint32_t h[8], s[4], t[2]; + size_t buflen; + uint8_t nullt; + uint8_t buf[64]; +} BLAKE256_CTX; + +void blake256_Init(BLAKE256_CTX *); +void blake256_Update(BLAKE256_CTX *, const uint8_t *, size_t); +void blake256_Final(BLAKE256_CTX *, uint8_t *); + +void blake256(const uint8_t *, size_t, uint8_t *); + +#endif /* __BLAKE256_H__ */ diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/blake2_common.h b/hardware-wallet/firmware/vendor/trezor-crypto/blake2_common.h new file mode 100644 index 00000000..40c6da3b --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/blake2_common.h @@ -0,0 +1,39 @@ +static inline uint32_t load32( const void *src ) +{ + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +} + +static inline uint64_t load64( const void *src ) +{ + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +} + +static inline void store16( void *dst, uint16_t w ) +{ + memcpy(dst, &w, sizeof w); +} + +static inline void store32( void *dst, uint32_t w ) +{ + memcpy(dst, &w, sizeof w); +} + +static inline void store64( void *dst, uint64_t w ) +{ + memcpy(dst, &w, sizeof w); +} + +static inline uint32_t rotr32( const uint32_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + +static inline uint64_t rotr64( const uint64_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/blake2b.c b/hardware-wallet/firmware/vendor/trezor-crypto/blake2b.c new file mode 100644 index 00000000..15df0119 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/blake2b.c @@ -0,0 +1,303 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include + +#include "blake2b.h" +#include "blake2_common.h" +#include "memzero.h" + +typedef struct blake2b_param__ +{ + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint32_t xof_length; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +} __attribute__((packed)) blake2b_param; + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + + +static void blake2b_set_lastnode( blake2b_state *S ) +{ + S->f[1] = (uint64_t)-1; +} + +/* Some helper functions, not necessarily useful */ +static int blake2b_is_lastblock( const blake2b_state *S ) +{ + return S->f[0] != 0; +} + +static void blake2b_set_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_set_lastnode( S ); + + S->f[0] = (uint64_t)-1; +} + +static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +} + +static void blake2b_init0( blake2b_state *S ) +{ + size_t i; + memset( S, 0, sizeof( blake2b_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; +} + +/* init xors IV with input parameter block */ +int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + const uint8_t *p = ( const uint8_t * )( P ); + size_t i; + + blake2b_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + + S->outlen = P->digest_length; + return 0; +} + + +/* Sequential blake2b initialization */ +int blake2b_Init( blake2b_state *S, size_t outlen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store32( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2b_init_param( S, P ); +} + + +int blake2b_InitKey( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store32( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2b_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_Update( S, block, BLAKE2B_BLOCKBYTES ); + memzero( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2*i+0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2*i+1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +{ + uint64_t m[16]; + uint64_t v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) { + m[i] = load64( block + i * sizeof( m[i] ) ); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2b_IV[0]; + v[ 9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ S->t[0]; + v[13] = blake2b_IV[5] ^ S->t[1]; + v[14] = blake2b_IV[6] ^ S->f[0]; + v[15] = blake2b_IV[7] ^ S->f[1]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + +int blake2b_Update( blake2b_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2B_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress( S, in ); + in += BLAKE2B_BLOCKBYTES; + inlen -= BLAKE2B_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } + return 0; +} + +int blake2b_Final( blake2b_state *S, void *out, size_t outlen ) +{ + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + size_t i; + + if( out == NULL || outlen < S->outlen ) + return -1; + + if( blake2b_is_lastblock( S ) ) + return -1; + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, S->outlen ); + memzero(buffer, sizeof(buffer)); + return 0; +} + +int blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen) +{ + BLAKE2B_CTX ctx; + if (0 != blake2b_Init(&ctx, outlen)) return -1; + if (0 != blake2b_Update(&ctx, msg, msg_len)) return -1; + if (0 != blake2b_Final(&ctx, out, outlen)) return -1; + return 0; +} + +int blake2b_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen) +{ + BLAKE2B_CTX ctx; + if (0 != blake2b_InitKey(&ctx, outlen, key, keylen)) return -1; + if (0 != blake2b_Update(&ctx, msg, msg_len)) return -1; + if (0 != blake2b_Final(&ctx, out, outlen)) return -1; + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/blake2b.h b/hardware-wallet/firmware/vendor/trezor-crypto/blake2b.h new file mode 100644 index 00000000..772a5cfe --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/blake2b.h @@ -0,0 +1,40 @@ +#ifndef __BLAKE2B_H__ +#define __BLAKE2B_H__ + +#include +#include + +enum blake2b_constant +{ + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 +}; + +typedef struct __blake2b_state +{ + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + size_t buflen; + size_t outlen; + uint8_t last_node; +} blake2b_state; + +#define BLAKE2B_CTX blake2b_state +#define BLAKE2B_BLOCK_LENGTH BLAKE2B_BLOCKBYTES +#define BLAKE2B_DIGEST_LENGTH BLAKE2B_OUTBYTES +#define BLAKE2B_KEY_LENGTH BLAKE2B_KEYBYTES + +int blake2b_Init(blake2b_state *S, size_t outlen); +int blake2b_InitKey(blake2b_state *S, size_t outlen, const void *key, size_t keylen); +int blake2b_Update(blake2b_state *S, const void *pin, size_t inlen); +int blake2b_Final(blake2b_state *S, void *out, size_t outlen); + +int blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen); +int blake2b_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/blake2s.c b/hardware-wallet/firmware/vendor/trezor-crypto/blake2s.c new file mode 100644 index 00000000..636479b9 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/blake2s.c @@ -0,0 +1,295 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include + +#include "blake2s.h" +#include "blake2_common.h" +#include "memzero.h" + +typedef struct blake2s_param__ +{ + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint16_t xof_length; /* 14 */ + uint8_t node_depth; /* 15 */ + uint8_t inner_length; /* 16 */ + /* uint8_t reserved[0]; */ + uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ + uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ +} __attribute__((packed)) blake2s_param; + +static const uint32_t blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8_t blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + +static void blake2s_set_lastnode( blake2s_state *S ) +{ + S->f[1] = (uint32_t)-1; +} + +/* Some helper functions, not necessarily useful */ +static int blake2s_is_lastblock( const blake2s_state *S ) +{ + return S->f[0] != 0; +} + +static void blake2s_set_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_set_lastnode( S ); + + S->f[0] = (uint32_t)-1; +} + +static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +} + +static void blake2s_init0( blake2s_state *S ) +{ + size_t i; + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; +} + +/* init2 xors IV with input parameter block */ +int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + const unsigned char *p = ( const unsigned char * )( P ); + size_t i; + + blake2s_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load32( &p[i * 4] ); + + S->outlen = P->digest_length; + return 0; +} + + +/* Sequential blake2s initialization */ +int blake2s_Init( blake2s_state *S, size_t outlen ) +{ + blake2s_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2s_init_param( S, P ); +} + +int blake2s_InitKey( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2s_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2s_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2s_Update( S, block, BLAKE2S_BLOCKBYTES ); + memzero( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) +{ + uint32_t m[16]; + uint32_t v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) { + m[i] = load32( in + i * sizeof( m[i] ) ); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2s_IV[0]; + v[ 9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + +int blake2s_Update( blake2s_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2S_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress( S, in ); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } + return 0; +} + +int blake2s_Final( blake2s_state *S, void *out, size_t outlen ) +{ + uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; + size_t i; + + if( out == NULL || outlen < S->outlen ) + return -1; + + if( blake2s_is_lastblock( S ) ) + return -1; + + blake2s_increment_counter( S, ( uint32_t )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + memzero(buffer, sizeof(buffer)); + return 0; +} + +int blake2s(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen) +{ + BLAKE2S_CTX ctx; + if (0 != blake2s_Init(&ctx, outlen)) return -1; + if (0 != blake2s_Update(&ctx, msg, msg_len)) return -1; + if (0 != blake2s_Final(&ctx, out, outlen)) return -1; + return 0; +} + +int blake2s_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen) +{ + BLAKE2S_CTX ctx; + if (0 != blake2s_InitKey(&ctx, outlen, key, keylen)) return -1; + if (0 != blake2s_Update(&ctx, msg, msg_len)) return -1; + if (0 != blake2s_Final(&ctx, out, outlen)) return -1; + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/blake2s.h b/hardware-wallet/firmware/vendor/trezor-crypto/blake2s.h new file mode 100644 index 00000000..dd34bf19 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/blake2s.h @@ -0,0 +1,40 @@ +#ifndef __BLAKE2S_H__ +#define __BLAKE2S_H__ + +#include +#include + +enum blake2s_constant +{ + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8 +}; + +typedef struct __blake2s_state +{ + uint32_t h[8]; + uint32_t t[2]; + uint32_t f[2]; + uint8_t buf[BLAKE2S_BLOCKBYTES]; + uint32_t buflen; + uint8_t outlen; + uint8_t last_node; +} blake2s_state; + +#define BLAKE2S_CTX blake2s_state +#define BLAKE2S_BLOCK_LENGTH BLAKE2S_BLOCKBYTES +#define BLAKE2S_DIGEST_LENGTH BLAKE2S_OUTBYTES +#define BLAKE2S_KEY_LENGTH BLAKE2S_KEYBYTES + +int blake2s_Init(blake2s_state *S, size_t outlen); +int blake2s_InitKey(blake2s_state *S, size_t outlen, const void *key, size_t keylen); +int blake2s_Update(blake2s_state *S, const void *pin, size_t inlen); +int blake2s_Final(blake2s_state *S, void *out, size_t outlen); + +int blake2s(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen); +int blake2s_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.c b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.c new file mode 100644 index 00000000..70662a03 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.c @@ -0,0 +1,59 @@ +// Implementations of the XChaCha20 + Poly1305 and ChaCha20 + Poly1305 +// AEAD constructions with a goal of simplicity and correctness rather +// than performance. + +#include "chacha20poly1305.h" + +void hchacha20(ECRYPT_ctx *x,u8 *c); + +// Initialize the XChaCha20 + Poly1305 context for encryption or decryption +// using a 32 byte key and 24 byte nonce. The key and the first 16 bytes of +// the nonce are used as input to HChaCha20 to derive the Chacha20 key. +void xchacha20poly1305_init(chacha20poly1305_ctx *ctx, uint8_t key[32], uint8_t nonce[24]) { + unsigned char subkey[32] = {0}; + unsigned char block0[64] = {0}; + ECRYPT_ctx tmp; + + // Generate the Chacha20 key by applying HChaCha20 to the + // original key and the first 16 bytes of the nonce. + ECRYPT_keysetup(&tmp, key, 256, 16); + tmp.input[12] = U8TO32_LITTLE(nonce + 0); + tmp.input[13] = U8TO32_LITTLE(nonce + 4); + tmp.input[14] = U8TO32_LITTLE(nonce + 8); + tmp.input[15] = U8TO32_LITTLE(nonce + 12); + hchacha20(&tmp, subkey); + + // Initialize Chacha20 with the newly generated key and + // the last 8 bytes of the nonce. + ECRYPT_keysetup(&ctx->chacha20, subkey, 256, 16); + ECRYPT_ivsetup(&ctx->chacha20, nonce+16); + + // Encrypt 64 bytes of zeros and use the first 32 bytes + // as the Poly1305 key. + ECRYPT_encrypt_bytes(&ctx->chacha20, block0, block0, 64); + poly1305_init(&ctx->poly1305, block0); +} + +// Encrypt n bytes of plaintext where n must be evenly divisible by the +// Chacha20 blocksize of 64, except for the final n bytes of plaintext. +void chacha20poly1305_encrypt(chacha20poly1305_ctx *ctx, uint8_t *in, uint8_t *out, size_t n) { + ECRYPT_encrypt_bytes(&ctx->chacha20, in, out, n); + poly1305_update(&ctx->poly1305, out, n); +} + +// Decrypt n bytes of ciphertext where n must be evenly divisible by the +// Chacha20 blocksize of 64, except for the final n bytes of ciphertext. +void chacha20poly1305_decrypt(chacha20poly1305_ctx *ctx, uint8_t *in, uint8_t *out, size_t n) { + poly1305_update(&ctx->poly1305, in, n); + ECRYPT_encrypt_bytes(&ctx->chacha20, in, out, n); +} + +// Include authenticated data in the Poly1305 MAC. +void chacha20poly1305_auth(chacha20poly1305_ctx *ctx, uint8_t *in, size_t n) { + poly1305_update(&ctx->poly1305, in, n); +} + +// Compute NaCl secretbox-style Poly1305 MAC. +void chacha20poly1305_finish(chacha20poly1305_ctx *ctx, uint8_t mac[16]) { + poly1305_finish(&ctx->poly1305, mac); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.h new file mode 100644 index 00000000..d02ea0c6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.h @@ -0,0 +1,19 @@ +#ifndef CHACHA20POLY1305_H +#define CHACHA20POLY1305_H + +#include +#include "ecrypt-sync.h" +#include "poly1305-donna.h" + +typedef struct { + ECRYPT_ctx chacha20; + poly1305_context poly1305; +} chacha20poly1305_ctx; + +void xchacha20poly1305_init(chacha20poly1305_ctx *ctx, uint8_t key[32], uint8_t nonce[24]); +void chacha20poly1305_encrypt(chacha20poly1305_ctx *ctx, uint8_t *in, uint8_t *out, size_t n); +void chacha20poly1305_decrypt(chacha20poly1305_ctx *ctx, uint8_t *in, uint8_t *out, size_t n); +void chacha20poly1305_auth(chacha20poly1305_ctx *ctx, uint8_t *in, size_t n); +void chacha20poly1305_finish(chacha20poly1305_ctx *ctx, uint8_t mac[16]); + +#endif // CHACHA20POLY1305_H diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha_merged.c b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha_merged.c new file mode 100644 index 00000000..f2845846 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/chacha_merged.c @@ -0,0 +1,245 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#include "ecrypt-sync.h" + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +void ECRYPT_init(void) +{ + return; +} + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits) +{ + (void)ivbits; + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +void ECRYPT_ivsetup(ECRYPT_ctx *x,const u8 *iv) +{ + x->input[12] = 0; + x->input[13] = 0; + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +void ECRYPT_encrypt_bytes(ECRYPT_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget = 0; + u8 tmp[64]; + int i; + + if (!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0;i < (int)bytes;++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20;i > 0;i -= 2) { + QUARTERROUND( x0, x4, x8,x12) + QUARTERROUND( x1, x5, x9,x13) + QUARTERROUND( x2, x6,x10,x14) + QUARTERROUND( x3, x7,x11,x15) + QUARTERROUND( x0, x5,x10,x15) + QUARTERROUND( x1, x6,x11,x12) + QUARTERROUND( x2, x7, x8,x13) + QUARTERROUND( x3, x4, x9,x14) + } + x0 = PLUS(x0,j0); + x1 = PLUS(x1,j1); + x2 = PLUS(x2,j2); + x3 = PLUS(x3,j3); + x4 = PLUS(x4,j4); + x5 = PLUS(x5,j5); + x6 = PLUS(x6,j6); + x7 = PLUS(x7,j7); + x8 = PLUS(x8,j8); + x9 = PLUS(x9,j9); + x10 = PLUS(x10,j10); + x11 = PLUS(x11,j11); + x12 = PLUS(x12,j12); + x13 = PLUS(x13,j13); + x14 = PLUS(x14,j14); + x15 = PLUS(x15,j15); + + x0 = XOR(x0,U8TO32_LITTLE(m + 0)); + x1 = XOR(x1,U8TO32_LITTLE(m + 4)); + x2 = XOR(x2,U8TO32_LITTLE(m + 8)); + x3 = XOR(x3,U8TO32_LITTLE(m + 12)); + x4 = XOR(x4,U8TO32_LITTLE(m + 16)); + x5 = XOR(x5,U8TO32_LITTLE(m + 20)); + x6 = XOR(x6,U8TO32_LITTLE(m + 24)); + x7 = XOR(x7,U8TO32_LITTLE(m + 28)); + x8 = XOR(x8,U8TO32_LITTLE(m + 32)); + x9 = XOR(x9,U8TO32_LITTLE(m + 36)); + x10 = XOR(x10,U8TO32_LITTLE(m + 40)); + x11 = XOR(x11,U8TO32_LITTLE(m + 44)); + x12 = XOR(x12,U8TO32_LITTLE(m + 48)); + x13 = XOR(x13,U8TO32_LITTLE(m + 52)); + x14 = XOR(x14,U8TO32_LITTLE(m + 56)); + x15 = XOR(x15,U8TO32_LITTLE(m + 60)); + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x4); + U32TO8_LITTLE(c + 20,x5); + U32TO8_LITTLE(c + 24,x6); + U32TO8_LITTLE(c + 28,x7); + U32TO8_LITTLE(c + 32,x8); + U32TO8_LITTLE(c + 36,x9); + U32TO8_LITTLE(c + 40,x10); + U32TO8_LITTLE(c + 44,x11); + U32TO8_LITTLE(c + 48,x12); + U32TO8_LITTLE(c + 52,x13); + U32TO8_LITTLE(c + 56,x14); + U32TO8_LITTLE(c + 60,x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0;i < (int)bytes;++i) ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} + +void ECRYPT_decrypt_bytes(ECRYPT_ctx *x,const u8 *c,u8 *m,u32 bytes) +{ + ECRYPT_encrypt_bytes(x,c,m,bytes); +} + +void ECRYPT_keystream_bytes(ECRYPT_ctx *x,u8 *stream,u32 bytes) +{ + u32 i; + for (i = 0;i < bytes;++i) stream[i] = 0; + ECRYPT_encrypt_bytes(x,stream,stream,bytes); +} + +void hchacha20(ECRYPT_ctx *x,u8 *c) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + int i; + + x0 = x->input[0]; + x1 = x->input[1]; + x2 = x->input[2]; + x3 = x->input[3]; + x4 = x->input[4]; + x5 = x->input[5]; + x6 = x->input[6]; + x7 = x->input[7]; + x8 = x->input[8]; + x9 = x->input[9]; + x10 = x->input[10]; + x11 = x->input[11]; + x12 = x->input[12]; + x13 = x->input[13]; + x14 = x->input[14]; + x15 = x->input[15]; + + for (i = 20;i > 0;i -= 2) { + QUARTERROUND( x0, x4, x8,x12) + QUARTERROUND( x1, x5, x9,x13) + QUARTERROUND( x2, x6,x10,x14) + QUARTERROUND( x3, x7,x11,x15) + QUARTERROUND( x0, x5,x10,x15) + QUARTERROUND( x1, x6,x11,x12) + QUARTERROUND( x2, x7, x8,x13) + QUARTERROUND( x3, x4, x9,x14) + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x12); + U32TO8_LITTLE(c + 20,x13); + U32TO8_LITTLE(c + 24,x14); + U32TO8_LITTLE(c + 28,x15); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-config.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-config.h new file mode 100644 index 00000000..5c0d3810 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-config.h @@ -0,0 +1,316 @@ +/* ecrypt-config.h */ + +/* *** Normally, it should not be necessary to edit this file. *** */ + +#ifndef ECRYPT_CONFIG +#define ECRYPT_CONFIG + +/* ------------------------------------------------------------------------- */ + +/* Guess the endianness of the target architecture. */ + +/* + * The LITTLE endian machines: + */ +#if defined(__ultrix) /* Older MIPS */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__alpha) /* Alpha */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(i386) /* x86 (gcc) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__i386) /* x86 (gcc) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__x86_64) /* x86_64 (gcc) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(_M_IX86) /* x86 (MSC, Borland) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(_MSC_VER) /* x86 (surely MSC) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */ +#define ECRYPT_LITTLE_ENDIAN + +/* + * The BIG endian machines: + */ +#elif defined(__sparc) /* Newer Sparc's */ +#define ECRYPT_BIG_ENDIAN +#elif defined(__powerpc__) /* PowerPC */ +#define ECRYPT_BIG_ENDIAN +#elif defined(__ppc__) /* PowerPC */ +#define ECRYPT_BIG_ENDIAN +#elif defined(__hppa) /* HP-PA */ +#define ECRYPT_BIG_ENDIAN + +/* + * Finally machines with UNKNOWN endianness: + */ +#elif defined (_AIX) /* RS6000 */ +#define ECRYPT_UNKNOWN +#elif defined(__aux) /* 68K */ +#define ECRYPT_UNKNOWN +#elif defined(__dgux) /* 88K (but P6 in latest boxes) */ +#define ECRYPT_UNKNOWN +#elif defined(__sgi) /* Newer MIPS */ +#define ECRYPT_UNKNOWN +#else /* Any other processor */ +#define ECRYPT_UNKNOWN +#endif + +/* ------------------------------------------------------------------------- */ + +/* + * Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit + * integers. + * + * Note: to enable 64-bit types on 32-bit compilers, it might be + * necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc + * -std=c99), or to allow compiler-specific extensions. + */ + +#include + +/* --- check char --- */ + +#if (UCHAR_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T char +#define U8C(v) (v##U) + +#if (UCHAR_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (UCHAR_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T char +#define U16C(v) (v##U) +#endif + +#if (UCHAR_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T char +#define U32C(v) (v##U) +#endif + +#if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T char +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check short --- */ + +#if (USHRT_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T short +#define U8C(v) (v##U) + +#if (USHRT_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (USHRT_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T short +#define U16C(v) (v##U) +#endif + +#if (USHRT_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T short +#define U32C(v) (v##U) +#endif + +#if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T short +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check int --- */ + +#if (UINT_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T int +#define U8C(v) (v##U) + +#if (ULONG_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (UINT_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T int +#define U16C(v) (v##U) +#endif + +#if (UINT_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T int +#define U32C(v) (v##U) +#endif + +#if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T int +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check long --- */ + +#if (ULONG_MAX / 0xFUL > 0xFUL) +#ifndef I8T +#define I8T long +#define U8C(v) (v##UL) + +#if (ULONG_MAX == 0xFFUL) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (ULONG_MAX / 0xFFUL > 0xFFUL) +#ifndef I16T +#define I16T long +#define U16C(v) (v##UL) +#endif + +#if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL) +#ifndef I32T +#define I32T long +#define U32C(v) (v##UL) +#endif + +#if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL) +#ifndef I64T +#define I64T long +#define U64C(v) (v##UL) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check long long --- */ + +#ifdef ULLONG_MAX + +#if (ULLONG_MAX / 0xFULL > 0xFULL) +#ifndef I8T +#define I8T long long +#define U8C(v) (v##ULL) + +#if (ULLONG_MAX == 0xFFULL) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (ULLONG_MAX / 0xFFULL > 0xFFULL) +#ifndef I16T +#define I16T long long +#define U16C(v) (v##ULL) +#endif + +#if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL) +#ifndef I32T +#define I32T long long +#define U32C(v) (v##ULL) +#endif + +#if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL) +#ifndef I64T +#define I64T long long +#define U64C(v) (v##ULL) +#endif + +#endif +#endif +#endif +#endif + +#endif + +/* --- check __int64 --- */ + +#if !defined(__STDC__) && defined(_UI64_MAX) + +#ifndef I64T +#define I64T __int64 +#define U64C(v) (v##ui64) +#endif + +#endif + +/* --- if platform doesn't announce anything, use most common choices --- */ + +#ifndef I8T +#define I8T char +#define U8C(v) (v##U) +#endif +#ifndef I16T +#define I16T short +#define U16C(v) (v##U) +#endif +#ifndef I32T +#define I32T int +#define U32C(v) (v##U) +#endif +#ifndef I64T +#define I64T long long +#define U64C(v) (v##ULL) +#endif + +/* ------------------------------------------------------------------------- */ + +/* find the largest type on this platform (used for alignment) */ + +#if defined(__SSE__) || (defined(_MSC_VER) && (_MSC_VER >= 1300)) + +#include +#define MAXT __m128 + +#elif defined(__MMX__) + +#include +#define MAXT __m64 + +#elif defined(__ALTIVEC__) + +#define MAXT __vector int + +#else + +#define MAXT long + +#endif + +/* ------------------------------------------------------------------------- */ + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-machine.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-machine.h new file mode 100644 index 00000000..d006bede --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-machine.h @@ -0,0 +1,49 @@ +/* ecrypt-machine.h */ + +/* + * This file is included by 'ecrypt-portable.h'. It allows to override + * the default macros for specific platforms. Please carefully check + * the machine code generated by your compiler (with optimisations + * turned on) before deciding to edit this file. + */ + +/* ------------------------------------------------------------------------- */ + +#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) + +#define ECRYPT_MACHINE_ROT + +#if (defined(WIN32) && defined(_MSC_VER)) + +#undef ROTL32 +#undef ROTR32 +#undef ROTL64 +#undef ROTR64 + +#include + +#pragma intrinsic(_lrotl) /* compile rotations "inline" */ +#pragma intrinsic(_lrotr) + +#define ROTL32(v, n) _lrotl(v, n) +#define ROTR32(v, n) _lrotr(v, n) +#define ROTL64(v, n) _rotl64(v, n) +#define ROTR64(v, n) _rotr64(v, n) + +#endif + +#endif + +/* ------------------------------------------------------------------------- */ + +#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) + +#define ECRYPT_MACHINE_SWAP + +/* + * If you want to overwrite the default swap macros, put it here. And so on. + */ + +#endif + +/* ------------------------------------------------------------------------- */ diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-portable.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-portable.h new file mode 100644 index 00000000..438a464a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-portable.h @@ -0,0 +1,310 @@ +/* ecrypt-portable.h */ + +/* + * WARNING: the conversions defined below are implemented as macros, + * and should be used carefully. They should NOT be used with + * parameters which perform some action. E.g., the following two lines + * are not equivalent: + * + * 1) ++x; y = ROTL32(x, n); + * 2) y = ROTL32(++x, n); + */ + +/* + * *** Please do not edit this file. *** + * + * The default macros can be overridden for specific architectures by + * editing 'ecrypt-machine.h'. + */ + +#ifndef ECRYPT_PORTABLE +#define ECRYPT_PORTABLE + +#include "ecrypt-config.h" + +/* ------------------------------------------------------------------------- */ + +/* + * The following types are defined (if available): + * + * u8: unsigned integer type, at least 8 bits + * u16: unsigned integer type, at least 16 bits + * u32: unsigned integer type, at least 32 bits + * u64: unsigned integer type, at least 64 bits + * + * s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64 + * + * The selection of minimum-width integer types is taken care of by + * 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit + * compilers, it might be necessary to switch from ISO C90 mode to ISO + * C99 mode (e.g., gcc -std=c99). + */ + +#ifdef I8T +typedef signed I8T s8; +typedef unsigned I8T u8; +#endif + +#ifdef I16T +typedef signed I16T s16; +typedef unsigned I16T u16; +#endif + +#ifdef I32T +typedef signed I32T s32; +typedef unsigned I32T u32; +#endif + +#ifdef I64T +typedef signed I64T s64; +typedef unsigned I64T u64; +#endif + +/* + * The following macros are used to obtain exact-width results. + */ + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U16V(v) ((u16)(v) & U16C(0xFFFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) +#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF)) + +/* ------------------------------------------------------------------------- */ + +/* + * The following macros return words with their bits rotated over n + * positions to the left/right. + */ + +#define ECRYPT_DEFAULT_ROT + +#define ROTL8(v, n) \ + (U8V((v) << (n)) | ((v) >> (8 - (n)))) + +#define ROTL16(v, n) \ + (U16V((v) << (n)) | ((v) >> (16 - (n)))) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define ROTL64(v, n) \ + (U64V((v) << (n)) | ((v) >> (64 - (n)))) + +#define ROTR8(v, n) ROTL8(v, 8 - (n)) +#define ROTR16(v, n) ROTL16(v, 16 - (n)) +#define ROTR32(v, n) ROTL32(v, 32 - (n)) +#define ROTR64(v, n) ROTL64(v, 64 - (n)) + +#include "ecrypt-machine.h" + +/* ------------------------------------------------------------------------- */ + +/* + * The following macros return a word with bytes in reverse order. + */ + +#define ECRYPT_DEFAULT_SWAP + +#define SWAP16(v) \ + ROTL16(v, 8) + +#define SWAP32(v) \ + ((ROTL32(v, 8) & U32C(0x00FF00FF)) | \ + (ROTL32(v, 24) & U32C(0xFF00FF00))) + +#ifdef ECRYPT_NATIVE64 +#define SWAP64(v) \ + ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \ + (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ + (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \ + (ROTL64(v, 56) & U64C(0xFF000000FF000000))) +#else +#define SWAP64(v) \ + (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) +#endif + +#include "ecrypt-machine.h" + +#define ECRYPT_DEFAULT_WTOW + +#ifdef ECRYPT_LITTLE_ENDIAN +#define U16TO16_LITTLE(v) (v) +#define U32TO32_LITTLE(v) (v) +#define U64TO64_LITTLE(v) (v) + +#define U16TO16_BIG(v) SWAP16(v) +#define U32TO32_BIG(v) SWAP32(v) +#define U64TO64_BIG(v) SWAP64(v) +#endif + +#ifdef ECRYPT_BIG_ENDIAN +#define U16TO16_LITTLE(v) SWAP16(v) +#define U32TO32_LITTLE(v) SWAP32(v) +#define U64TO64_LITTLE(v) SWAP64(v) + +#define U16TO16_BIG(v) (v) +#define U32TO32_BIG(v) (v) +#define U64TO64_BIG(v) (v) +#endif + +#include "ecrypt-machine.h" + +/* + * The following macros load words from an array of bytes with + * different types of endianness, and vice versa. + */ + +#define ECRYPT_DEFAULT_BTOW + +#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) + +#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) +#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) +#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) + +#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) +#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) +#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) + +#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) +#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) +#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) + +#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) +#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) +#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) + +#else + +#define U8TO16_LITTLE(p) \ + (((u16)((p)[0]) ) | \ + ((u16)((p)[1]) << 8)) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_LITTLE(p) \ + (((u64)((p)[0]) ) | \ + ((u64)((p)[1]) << 8) | \ + ((u64)((p)[2]) << 16) | \ + ((u64)((p)[3]) << 24) | \ + ((u64)((p)[4]) << 32) | \ + ((u64)((p)[5]) << 40) | \ + ((u64)((p)[6]) << 48) | \ + ((u64)((p)[7]) << 56)) +#else +#define U8TO64_LITTLE(p) \ + ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) +#endif + +#define U8TO16_BIG(p) \ + (((u16)((p)[0]) << 8) | \ + ((u16)((p)[1]) )) + +#define U8TO32_BIG(p) \ + (((u32)((p)[0]) << 24) | \ + ((u32)((p)[1]) << 16) | \ + ((u32)((p)[2]) << 8) | \ + ((u32)((p)[3]) )) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_BIG(p) \ + (((u64)((p)[0]) << 56) | \ + ((u64)((p)[1]) << 48) | \ + ((u64)((p)[2]) << 40) | \ + ((u64)((p)[3]) << 32) | \ + ((u64)((p)[4]) << 24) | \ + ((u64)((p)[5]) << 16) | \ + ((u64)((p)[6]) << 8) | \ + ((u64)((p)[7]) )) +#else +#define U8TO64_BIG(p) \ + (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) +#endif + +#define U16TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + } while (0) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + (p)[4] = U8V((v) >> 32); \ + (p)[5] = U8V((v) >> 40); \ + (p)[6] = U8V((v) >> 48); \ + (p)[7] = U8V((v) >> 56); \ + } while (0) +#else +#define U64TO8_LITTLE(p, v) \ + do { \ + U32TO8_LITTLE((p), U32V((v) )); \ + U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ + } while (0) +#endif + +#define U16TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + } while (0) + +#define U32TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 24); \ + (p)[1] = U8V((v) >> 16); \ + (p)[2] = U8V((v) >> 8); \ + (p)[3] = U8V((v) ); \ + } while (0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 56); \ + (p)[1] = U8V((v) >> 48); \ + (p)[2] = U8V((v) >> 40); \ + (p)[3] = U8V((v) >> 32); \ + (p)[4] = U8V((v) >> 24); \ + (p)[5] = U8V((v) >> 16); \ + (p)[6] = U8V((v) >> 8); \ + (p)[7] = U8V((v) ); \ + } while (0) +#else +#define U64TO8_BIG(p, v) \ + do { \ + U32TO8_BIG((p), U32V((v) >> 32)); \ + U32TO8_BIG((p) + 4, U32V((v) )); \ + } while (0) +#endif + +#endif + +#include "ecrypt-machine.h" + +/* ------------------------------------------------------------------------- */ + +#define AT_LEAST_ONE(n) (((n) < 1) ? 1 : (n)) + +#define ALIGN(t, v, n) \ + union { t b[n]; MAXT l[AT_LEAST_ONE(n * sizeof(t) / sizeof(MAXT))]; } v + +/* ------------------------------------------------------------------------- */ + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-sync.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-sync.h new file mode 100644 index 00000000..5f363d4c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/ecrypt-sync.h @@ -0,0 +1,281 @@ +#define ECRYPT_VARIANT 1 +#define ECRYPT_API +/* ecrypt-sync.h */ + +/* + * Header file for synchronous stream ciphers without authentication + * mechanism. + * + * *** Please only edit parts marked with "[edit]". *** + */ + +#ifndef ECRYPT_SYNC +#define ECRYPT_SYNC + +#include "ecrypt-portable.h" + +/* ------------------------------------------------------------------------- */ + +/* Cipher parameters */ + +/* + * The name of your cipher. + */ +#define ECRYPT_NAME "ChaCha20" +#define ECRYPT_PROFILE "_____" + +/* + * Specify which key and IV sizes are supported by your cipher. A user + * should be able to enumerate the supported sizes by running the + * following code: + * + * for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i) + * { + * keysize = ECRYPT_KEYSIZE(i); + * + * ... + * } + * + * All sizes are in bits. + */ + +#define ECRYPT_MAXKEYSIZE 256 /* [edit] */ +#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */ + +#define ECRYPT_MAXIVSIZE 64 /* [edit] */ +#define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */ + +/* ------------------------------------------------------------------------- */ + +/* Data structures */ + +/* + * ECRYPT_ctx is the structure containing the representation of the + * internal state of your cipher. + */ + +typedef struct +{ + u32 input[16]; /* could be compressed */ + /* + * [edit] + * + * Put here all state variable needed during the encryption process. + */ +} ECRYPT_ctx; + +/* ------------------------------------------------------------------------- */ + +/* Mandatory functions */ + +/* + * Key and message independent initialization. This function will be + * called once when the program starts (e.g., to build expanded S-box + * tables). + */ +void ECRYPT_init(void); + +/* + * Key setup. It is the user's responsibility to select the values of + * keysize and ivsize from the set of supported values specified + * above. + */ +void ECRYPT_keysetup( + ECRYPT_ctx* ctx, + const u8* key, + u32 keysize, /* Key size in bits. */ + u32 ivsize); /* IV size in bits. */ + +/* + * IV setup. After having called ECRYPT_keysetup(), the user is + * allowed to call ECRYPT_ivsetup() different times in order to + * encrypt/decrypt different messages with the same key but different + * IV's. + */ +void ECRYPT_ivsetup( + ECRYPT_ctx* ctx, + const u8* iv); + +/* + * Encryption/decryption of arbitrary length messages. + * + * For efficiency reasons, the API provides two types of + * encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function + * (declared here) encrypts byte strings of arbitrary length, while + * the ECRYPT_encrypt_blocks() function (defined later) only accepts + * lengths which are multiples of ECRYPT_BLOCKLENGTH. + * + * The user is allowed to make multiple calls to + * ECRYPT_encrypt_blocks() to incrementally encrypt a long message, + * but he is NOT allowed to make additional encryption calls once he + * has called ECRYPT_encrypt_bytes() (unless he starts a new message + * of course). For example, this sequence of calls is acceptable: + * + * ECRYPT_keysetup(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_bytes(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_blocks(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_bytes(); + * + * The following sequence is not: + * + * ECRYPT_keysetup(); + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_bytes(); + * ECRYPT_encrypt_blocks(); + */ + +void ECRYPT_encrypt_bytes( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 msglen); /* Message length in bytes. */ + +void ECRYPT_decrypt_bytes( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 msglen); /* Message length in bytes. */ + +/* ------------------------------------------------------------------------- */ + +/* Optional features */ + +/* + * For testing purposes it can sometimes be useful to have a function + * which immediately generates keystream without having to provide it + * with a zero plaintext. If your cipher cannot provide this function + * (e.g., because it is not strictly a synchronous cipher), please + * reset the ECRYPT_GENERATES_KEYSTREAM flag. + */ + +#define ECRYPT_GENERATES_KEYSTREAM +#ifdef ECRYPT_GENERATES_KEYSTREAM + +void ECRYPT_keystream_bytes( + ECRYPT_ctx* ctx, + u8* keystream, + u32 length); /* Length of keystream in bytes. */ + +#endif + +/* ------------------------------------------------------------------------- */ + +/* Optional optimizations */ + +/* + * By default, the functions in this section are implemented using + * calls to functions declared above. However, you might want to + * implement them differently for performance reasons. + */ + +/* + * All-in-one encryption/decryption of (short) packets. + * + * The default definitions of these functions can be found in + * "ecrypt-sync.c". If you want to implement them differently, please + * undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag. + */ +#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ + +void ECRYPT_encrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* plaintext, + u8* ciphertext, + u32 msglen); + +void ECRYPT_decrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* ciphertext, + u8* plaintext, + u32 msglen); + +/* + * Encryption/decryption of blocks. + * + * By default, these functions are defined as macros. If you want to + * provide a different implementation, please undef the + * ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions + * declared below. + */ + +#define ECRYPT_BLOCKLENGTH 64 /* [edit] */ + +#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ +#ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS + +#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ + ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ + ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#ifdef ECRYPT_GENERATES_KEYSTREAM + +#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ + ECRYPT_keystream_bytes(ctx, keystream, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#endif + +#else + +void ECRYPT_encrypt_blocks( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 blocks); /* Message length in blocks. */ + +void ECRYPT_decrypt_blocks( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 blocks); /* Message length in blocks. */ + +#ifdef ECRYPT_GENERATES_KEYSTREAM + +void ECRYPT_keystream_blocks( + ECRYPT_ctx* ctx, + const u8* keystream, + u32 blocks); /* Keystream length in blocks. */ + +#endif + +#endif + +/* + * If your cipher can be implemented in different ways, you can use + * the ECRYPT_VARIANT parameter to allow the user to choose between + * them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please + * only use this possibility if you really think it could make a + * significant difference and keep the number of variants + * (ECRYPT_MAXVARIANT) as small as possible (definitely not more than + * 10). Note also that all variants should have exactly the same + * external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.). + */ +#define ECRYPT_MAXVARIANT 1 /* [edit] */ + +#ifndef ECRYPT_VARIANT +#define ECRYPT_VARIANT 1 +#endif + +#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT) +#error this variant does not exist +#endif + +/* ------------------------------------------------------------------------- */ + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna-32.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna-32.h new file mode 100644 index 00000000..6a570f06 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna-32.h @@ -0,0 +1,219 @@ +/* + poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition +*/ + +#if defined(_MSC_VER) + #define POLY1305_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) + #define POLY1305_NOINLINE __attribute__((noinline)) +#else + #define POLY1305_NOINLINE +#endif + +#define poly1305_block_size 16 + +/* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */ +typedef struct poly1305_state_internal_t { + unsigned long r[5]; + unsigned long h[5]; + unsigned long pad[4]; + size_t leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; + +/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */ +static unsigned long +U8TO32(const unsigned char *p) { + return + (((unsigned long)(p[0] & 0xff) ) | + ((unsigned long)(p[1] & 0xff) << 8) | + ((unsigned long)(p[2] & 0xff) << 16) | + ((unsigned long)(p[3] & 0xff) << 24)); +} + +/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */ +static void +U32TO8(unsigned char *p, unsigned long v) { + p[0] = (v ) & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; +} + +void +poly1305_init(poly1305_context *ctx, const unsigned char key[32]) { + poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + st->r[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff; + st->r[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03; + st->r[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff; + st->r[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff; + st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + st->pad[0] = U8TO32(&key[16]); + st->pad[1] = U8TO32(&key[20]); + st->pad[2] = U8TO32(&key[24]); + st->pad[3] = U8TO32(&key[28]); + + st->leftover = 0; + st->final = 0; +} + +static void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) { + const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */ + unsigned long r0,r1,r2,r3,r4; + unsigned long s1,s2,s3,s4; + unsigned long h0,h1,h2,h3,h4; + unsigned long long d0,d1,d2,d3,d4; + unsigned long c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while (bytes >= poly1305_block_size) { + /* h += m[i] */ + h0 += (U8TO32(m+ 0) ) & 0x3ffffff; + h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff; + h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff; + h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff; + h4 += (U8TO32(m+12) >> 8) | hibit; + + /* h *= r */ + d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1); + d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2); + d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3); + d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4); + d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0); + + /* (partial) h %= p */ + c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff; + d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff; + d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff; + d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff; + d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff; + h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +POLY1305_NOINLINE void +poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) { + poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; + unsigned long h0,h1,h2,h3,h4,c; + unsigned long g0,g1,g2,g3,g4; + unsigned long long f; + unsigned long mask; + + /* process the remaining block */ + if (st->leftover) { + size_t i = st->leftover; + st->buffer[i++] = 1; + for (; i < poly1305_block_size; i++) + st->buffer[i] = 0; + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + c - (1UL << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (unsigned long long)h0 + st->pad[0] ; h0 = (unsigned long)f; + f = (unsigned long long)h1 + st->pad[1] + (f >> 32); h1 = (unsigned long)f; + f = (unsigned long long)h2 + st->pad[2] + (f >> 32); h2 = (unsigned long)f; + f = (unsigned long long)h3 + st->pad[3] + (f >> 32); h3 = (unsigned long)f; + + U32TO8(mac + 0, h0); + U32TO8(mac + 4, h1); + U32TO8(mac + 8, h2); + U32TO8(mac + 12, h3); + + /* zero out the state */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + st->r[0] = 0; + st->r[1] = 0; + st->r[2] = 0; + st->r[3] = 0; + st->r[4] = 0; + st->pad[0] = 0; + st->pad[1] = 0; + st->pad[2] = 0; + st->pad[3] = 0; +} + diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c new file mode 100644 index 00000000..f8964e01 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c @@ -0,0 +1,179 @@ +#include "poly1305-donna.h" +#include "poly1305-donna-32.h" + +void +poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) { + poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; + size_t i; + + /* handle leftover */ + if (st->leftover) { + size_t want = (poly1305_block_size - st->leftover); + if (want > bytes) + want = bytes; + for (i = 0; i < want; i++) + st->buffer[st->leftover + i] = m[i]; + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) + return; + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + size_t want = (bytes & ~(poly1305_block_size - 1)); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) + st->buffer[st->leftover + i] = m[i]; + st->leftover += bytes; + } +} + +void +poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]) { + poly1305_context ctx; + poly1305_init(&ctx, key); + poly1305_update(&ctx, m, bytes); + poly1305_finish(&ctx, mac); +} + +int +poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]) { + size_t i; + unsigned int dif = 0; + for (i = 0; i < 16; i++) + dif |= (mac1[i] ^ mac2[i]); + dif = (dif - 1) >> ((sizeof(unsigned int) * 8) - 1); + return (dif & 1); +} + + +/* test a few basic operations */ +int +poly1305_power_on_self_test(void) { + /* example from nacl */ + static const unsigned char nacl_key[32] = { + 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91, + 0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25, + 0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65, + 0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80, + }; + + static const unsigned char nacl_msg[131] = { + 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73, + 0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce, + 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4, + 0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a, + 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b, + 0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72, + 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2, + 0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38, + 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a, + 0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae, + 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea, + 0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda, + 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde, + 0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3, + 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6, + 0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74, + 0xe3,0x55,0xa5 + }; + + static const unsigned char nacl_mac[16] = { + 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5, + 0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 + }; + + /* generates a final value of (2^130 - 2) == 3 */ + static const unsigned char wrap_key[32] = { + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; + + static const unsigned char wrap_msg[16] = { + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff + }; + + static const unsigned char wrap_mac[16] = { + 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; + + /* + mac of the macs of messages of length 0 to 256, where the key and messages + have all their values set to the length + */ + static const unsigned char total_key[32] = { + 0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff + }; + + static const unsigned char total_mac[16] = { + 0x64,0xaf,0xe2,0xe8,0xd6,0xad,0x7b,0xbd, + 0xd2,0x87,0xf9,0x7c,0x44,0x62,0x3d,0x39 + }; + + poly1305_context ctx; + poly1305_context total_ctx; + unsigned char all_key[32]; + unsigned char all_msg[256]; + unsigned char mac[16]; + size_t i, j; + int result = 1; + + for (i = 0; i < sizeof(mac); i++) + mac[i] = 0; + poly1305_auth(mac, nacl_msg, sizeof(nacl_msg), nacl_key); + result &= poly1305_verify(nacl_mac, mac); + + for (i = 0; i < sizeof(mac); i++) + mac[i] = 0; + poly1305_init(&ctx, nacl_key); + poly1305_update(&ctx, nacl_msg + 0, 32); + poly1305_update(&ctx, nacl_msg + 32, 64); + poly1305_update(&ctx, nacl_msg + 96, 16); + poly1305_update(&ctx, nacl_msg + 112, 8); + poly1305_update(&ctx, nacl_msg + 120, 4); + poly1305_update(&ctx, nacl_msg + 124, 2); + poly1305_update(&ctx, nacl_msg + 126, 1); + poly1305_update(&ctx, nacl_msg + 127, 1); + poly1305_update(&ctx, nacl_msg + 128, 1); + poly1305_update(&ctx, nacl_msg + 129, 1); + poly1305_update(&ctx, nacl_msg + 130, 1); + poly1305_finish(&ctx, mac); + result &= poly1305_verify(nacl_mac, mac); + + for (i = 0; i < sizeof(mac); i++) + mac[i] = 0; + poly1305_auth(mac, wrap_msg, sizeof(wrap_msg), wrap_key); + result &= poly1305_verify(wrap_mac, mac); + + poly1305_init(&total_ctx, total_key); + for (i = 0; i < 256; i++) { + /* set key and message to 'i,i,i..' */ + for (j = 0; j < sizeof(all_key); j++) + all_key[j] = i; + for (j = 0; j < i; j++) + all_msg[j] = i; + poly1305_auth(mac, all_msg, i, all_key); + poly1305_update(&total_ctx, mac, 16); + } + poly1305_finish(&total_ctx, mac); + result &= poly1305_verify(total_mac, mac); + + return result; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.h new file mode 100644 index 00000000..94e23533 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/poly1305-donna.h @@ -0,0 +1,20 @@ +#ifndef POLY1305_DONNA_H +#define POLY1305_DONNA_H + +#include + +typedef struct poly1305_context { + size_t aligner; + unsigned char opaque[136]; +} poly1305_context; + +void poly1305_init(poly1305_context *ctx, const unsigned char key[32]); +void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes); +void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]); +void poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]); + +int poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]); +int poly1305_power_on_self_test(void); + +#endif /* POLY1305_DONNA_H */ + diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.c b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.c new file mode 100644 index 00000000..585a695d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.c @@ -0,0 +1,44 @@ +// Implementation of the ChaCha20 + Poly1305 AEAD construction +// as described in RFC 7539. + +#include +#include "rfc7539.h" + +// Initialize the ChaCha20 + Poly1305 context for encryption or decryption +// using a 32 byte key and 12 byte nonce as in the RFC 7539 style. +void rfc7539_init(chacha20poly1305_ctx *ctx, uint8_t key[32], uint8_t nonce[12]) { + unsigned char block0[64] = {0}; + + ECRYPT_keysetup(&ctx->chacha20, key, 256, 16); + ctx->chacha20.input[13] = U8TO32_LITTLE(nonce + 0); + ctx->chacha20.input[14] = U8TO32_LITTLE(nonce + 4); + ctx->chacha20.input[15] = U8TO32_LITTLE(nonce + 8); + + // Encrypt 64 bytes of zeros and use the first 32 bytes + // as the Poly1305 key. + ECRYPT_encrypt_bytes(&ctx->chacha20, block0, block0, 64); + poly1305_init(&ctx->poly1305, block0); +} + +// Include authenticated data in the Poly1305 MAC using the RFC 7539 +// style with 16 byte padding. This must only be called once and prior +// to encryption or decryption. +void rfc7539_auth(chacha20poly1305_ctx *ctx, uint8_t *in, size_t n) { + uint8_t padding[16] = {0}; + poly1305_update(&ctx->poly1305, in, n); + poly1305_update(&ctx->poly1305, padding, 16 - n%16); +} + +// Compute RFC 7539-style Poly1305 MAC. +void rfc7539_finish(chacha20poly1305_ctx *ctx, int64_t alen, int64_t plen, uint8_t mac[16]) { + uint8_t padding[16] = {0}; + uint8_t lengths[16] = {0}; + + memcpy(lengths, &alen, sizeof(int64_t)); + memcpy(lengths + 8, &plen, sizeof(int64_t)); + + poly1305_update(&ctx->poly1305, padding, 16 - plen%16); + poly1305_update(&ctx->poly1305, lengths, 16); + + poly1305_finish(&ctx->poly1305, mac); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.h b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.h new file mode 100644 index 00000000..2bd4990b --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/chacha20poly1305/rfc7539.h @@ -0,0 +1,10 @@ +#ifndef RFC7539_H +#define RFC7539_H + +#include "chacha20poly1305.h" + +void rfc7539_init(chacha20poly1305_ctx *ctx, uint8_t key[32], uint8_t nonce[12]); +void rfc7539_auth(chacha20poly1305_ctx *ctx, uint8_t *in, size_t n); +void rfc7539_finish(chacha20poly1305_ctx *ctx, int64_t alen, int64_t plen, uint8_t mac[16]); + +#endif // RFC7539_H diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/check_mem.h b/hardware-wallet/firmware/vendor/trezor-crypto/check_mem.h new file mode 100644 index 00000000..be8a43cd --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/check_mem.h @@ -0,0 +1,30 @@ +#ifndef CHECK_MEM_H +#define CHECK_MEM_H + +#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 11 + +#define _ck_assert_mem(X, Y, L, OP) do { \ + const char* _ck_x = (const char*)(void*)(X); \ + const char* _ck_y = (const char*)(void*)(Y); \ + size_t _ck_l = (L); \ + char _ck_x_str[129]; \ + char _ck_y_str[129]; \ + static char _ck_hexdigits[] = "0123456789abcdef"; \ + size_t _ck_i; \ + for (_ck_i = 0; _ck_i < ((_ck_l > 64) ? 64 : _ck_l); _ck_i++) { \ + _ck_x_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_x[_ck_i] >> 4) & 0xF]; \ + _ck_y_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_y[_ck_i] >> 4) & 0xF]; \ + _ck_x_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_x[_ck_i] & 0xF]; \ + _ck_y_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_y[_ck_i] & 0xF]; \ + } \ + _ck_x_str[_ck_i * 2] = 0; \ + _ck_y_str[_ck_i * 2] = 0; \ + ck_assert_msg(0 OP memcmp(_ck_y, _ck_x, _ck_l), \ + "Assertion '"#X#OP#Y"' failed: "#X"==\"%s\", "#Y"==\"%s\"", _ck_x_str, _ck_y_str); \ +} while (0) +#define ck_assert_mem_eq(X, Y, L) _ck_assert_mem(X, Y, L, ==) +#define ck_assert_mem_ne(X, Y, L) _ck_assert_mem(X, Y, L, !=) + +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/curves.c b/hardware-wallet/firmware/vendor/trezor-crypto/curves.c new file mode 100644 index 00000000..f81ea28a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/curves.c @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2016 Jochen Hoenicke + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "curves.h" + +const char SECP256K1_NAME[] = "secp256k1"; +const char SECP256K1_DECRED_NAME[] = "secp256k1-decred"; +const char NIST256P1_NAME[] = "nist256p1"; +const char ED25519_NAME[] = "ed25519"; +const char ED25519_SHA3_NAME[] = "ed25519-sha3"; +#if USE_KECCAK +const char ED25519_KECCAK_NAME[] = "ed25519-keccak"; +#endif +const char CURVE25519_NAME[] = "curve25519"; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/curves.h b/hardware-wallet/firmware/vendor/trezor-crypto/curves.h new file mode 100644 index 00000000..9257dcc1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/curves.h @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2016 Jochen Hoenicke + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __CURVES_H__ +#define __CURVES_H__ + +#include "options.h" + +extern const char SECP256K1_NAME[]; +extern const char SECP256K1_DECRED_NAME[]; +extern const char NIST256P1_NAME[]; +extern const char ED25519_NAME[]; +extern const char ED25519_SHA3_NAME[]; +#if USE_KECCAK +extern const char ED25519_KECCAK_NAME[]; +#endif +extern const char CURVE25519_NAME[]; + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.c b/hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.c new file mode 100644 index 00000000..2e679a8a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.c @@ -0,0 +1,1191 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * Copyright (c) 2015 Jochen Hoenicke + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "address.h" +#include "bignum.h" +#include "rand.h" +#include "sha2.h" +#include "ripemd160.h" +#include "hmac.h" +#include "ecdsa.h" +#include "base58.h" +#include "secp256k1.h" +#include "rfc6979.h" +#include "memzero.h" + +// Set cp2 = cp1 +void point_copy(const curve_point *cp1, curve_point *cp2) +{ + *cp2 = *cp1; +} + +// cp2 = cp1 + cp2 +void point_add(const ecdsa_curve *curve, const curve_point *cp1, curve_point *cp2) +{ + bignum256 lambda, inv, xr, yr; + + if (point_is_infinity(cp1)) { + return; + } + if (point_is_infinity(cp2)) { + point_copy(cp1, cp2); + return; + } + if (point_is_equal(cp1, cp2)) { + point_double(curve, cp2); + return; + } + if (point_is_negative_of(cp1, cp2)) { + point_set_infinity(cp2); + return; + } + + bn_subtractmod(&(cp2->x), &(cp1->x), &inv, &curve->prime); + bn_inverse(&inv, &curve->prime); + bn_subtractmod(&(cp2->y), &(cp1->y), &lambda, &curve->prime); + bn_multiply(&inv, &lambda, &curve->prime); + + // xr = lambda^2 - x1 - x2 + xr = lambda; + bn_multiply(&xr, &xr, &curve->prime); + yr = cp1->x; + bn_addmod(&yr, &(cp2->x), &curve->prime); + bn_subtractmod(&xr, &yr, &xr, &curve->prime); + bn_fast_mod(&xr, &curve->prime); + bn_mod(&xr, &curve->prime); + + // yr = lambda (x1 - xr) - y1 + bn_subtractmod(&(cp1->x), &xr, &yr, &curve->prime); + bn_multiply(&lambda, &yr, &curve->prime); + bn_subtractmod(&yr, &(cp1->y), &yr, &curve->prime); + bn_fast_mod(&yr, &curve->prime); + bn_mod(&yr, &curve->prime); + + cp2->x = xr; + cp2->y = yr; +} + +// cp = cp + cp +void point_double(const ecdsa_curve *curve, curve_point *cp) +{ + bignum256 lambda, xr, yr; + + if (point_is_infinity(cp)) { + return; + } + if (bn_is_zero(&(cp->y))) { + point_set_infinity(cp); + return; + } + + // lambda = (3 x^2 + a) / (2 y) + lambda = cp->y; + bn_mult_k(&lambda, 2, &curve->prime); + bn_inverse(&lambda, &curve->prime); + + xr = cp->x; + bn_multiply(&xr, &xr, &curve->prime); + bn_mult_k(&xr, 3, &curve->prime); + bn_subi(&xr, -curve->a, &curve->prime); + bn_multiply(&xr, &lambda, &curve->prime); + + // xr = lambda^2 - 2*x + xr = lambda; + bn_multiply(&xr, &xr, &curve->prime); + yr = cp->x; + bn_lshift(&yr); + bn_subtractmod(&xr, &yr, &xr, &curve->prime); + bn_fast_mod(&xr, &curve->prime); + bn_mod(&xr, &curve->prime); + + // yr = lambda (x - xr) - y + bn_subtractmod(&(cp->x), &xr, &yr, &curve->prime); + bn_multiply(&lambda, &yr, &curve->prime); + bn_subtractmod(&yr, &(cp->y), &yr, &curve->prime); + bn_fast_mod(&yr, &curve->prime); + bn_mod(&yr, &curve->prime); + + cp->x = xr; + cp->y = yr; +} + +// set point to internal representation of point at infinity +void point_set_infinity(curve_point *p) +{ + bn_zero(&(p->x)); + bn_zero(&(p->y)); +} + +// return true iff p represent point at infinity +// both coords are zero in internal representation +int point_is_infinity(const curve_point *p) +{ + return bn_is_zero(&(p->x)) && bn_is_zero(&(p->y)); +} + +// return true iff both points are equal +int point_is_equal(const curve_point *p, const curve_point *q) +{ + return bn_is_equal(&(p->x), &(q->x)) && bn_is_equal(&(p->y), &(q->y)); +} + +// returns true iff p == -q +// expects p and q be valid points on curve other than point at infinity +int point_is_negative_of(const curve_point *p, const curve_point *q) +{ + // if P == (x, y), then -P would be (x, -y) on this curve + if (!bn_is_equal(&(p->x), &(q->x))) { + return 0; + } + + // we shouldn't hit this for a valid point + if (bn_is_zero(&(p->y))) { + return 0; + } + + return !bn_is_equal(&(p->y), &(q->y)); +} + +// Negate a (modulo prime) if cond is 0xffffffff, keep it if cond is 0. +// The timing of this function does not depend on cond. +void conditional_negate(uint32_t cond, bignum256 *a, const bignum256 *prime) +{ + int j; + uint32_t tmp = 1; + assert(a->val[8] < 0x20000); + for (j = 0; j < 8; j++) { + tmp += 0x3fffffff + 2*prime->val[j] - a->val[j]; + a->val[j] = ((tmp & 0x3fffffff) & cond) | (a->val[j] & ~cond); + tmp >>= 30; + } + tmp += 0x3fffffff + 2*prime->val[j] - a->val[j]; + a->val[j] = ((tmp & 0x3fffffff) & cond) | (a->val[j] & ~cond); + assert(a->val[8] < 0x20000); +} + +typedef struct jacobian_curve_point { + bignum256 x, y, z; +} jacobian_curve_point; + +// generate random K for signing/side-channel noise +static void generate_k_random(bignum256 *k, const bignum256 *prime) { + do { + int i; + for (i = 0; i < 8; i++) { + k->val[i] = random32() & 0x3FFFFFFF; + } + k->val[8] = random32() & 0xFFFF; + // check that k is in range and not zero. + } while (bn_is_zero(k) || !bn_is_less(k, prime)); +} + +void curve_to_jacobian(const curve_point *p, jacobian_curve_point *jp, const bignum256 *prime) { + // randomize z coordinate + generate_k_random(&jp->z, prime); + + jp->x = jp->z; + bn_multiply(&jp->z, &jp->x, prime); + // x = z^2 + jp->y = jp->x; + bn_multiply(&jp->z, &jp->y, prime); + // y = z^3 + + bn_multiply(&p->x, &jp->x, prime); + bn_multiply(&p->y, &jp->y, prime); +} + +void jacobian_to_curve(const jacobian_curve_point *jp, curve_point *p, const bignum256 *prime) { + p->y = jp->z; + bn_inverse(&p->y, prime); + // p->y = z^-1 + p->x = p->y; + bn_multiply(&p->x, &p->x, prime); + // p->x = z^-2 + bn_multiply(&p->x, &p->y, prime); + // p->y = z^-3 + bn_multiply(&jp->x, &p->x, prime); + // p->x = jp->x * z^-2 + bn_multiply(&jp->y, &p->y, prime); + // p->y = jp->y * z^-3 + bn_mod(&p->x, prime); + bn_mod(&p->y, prime); +} + +void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2, const ecdsa_curve *curve) { + bignum256 r, h, r2; + bignum256 hcby, hsqx; + bignum256 xz, yz, az; + int is_doubling; + const bignum256 *prime = &curve->prime; + int a = curve->a; + + assert (-3 <= a && a <= 0); + + /* First we bring p1 to the same denominator: + * x1' := x1 * z2^2 + * y1' := y1 * z2^3 + */ + /* + * lambda = ((y1' - y2)/z2^3) / ((x1' - x2)/z2^2) + * = (y1' - y2) / (x1' - x2) z2 + * x3/z3^2 = lambda^2 - (x1' + x2)/z2^2 + * y3/z3^3 = 1/2 lambda * (2x3/z3^2 - (x1' + x2)/z2^2) + (y1'+y2)/z2^3 + * + * For the special case x1=x2, y1=y2 (doubling) we have + * lambda = 3/2 ((x2/z2^2)^2 + a) / (y2/z2^3) + * = 3/2 (x2^2 + a*z2^4) / y2*z2) + * + * to get rid of fraction we write lambda as + * lambda = r / (h*z2) + * with r = is_doubling ? 3/2 x2^2 + az2^4 : (y1 - y2) + * h = is_doubling ? y1+y2 : (x1 - x2) + * + * With z3 = h*z2 (the denominator of lambda) + * we get x3 = lambda^2*z3^2 - (x1' + x2)/z2^2*z3^2 + * = r^2 - h^2 * (x1' + x2) + * and y3 = 1/2 r * (2x3 - h^2*(x1' + x2)) + h^3*(y1' + y2) + */ + + /* h = x1 - x2 + * r = y1 - y2 + * x3 = r^2 - h^3 - 2*h^2*x2 + * y3 = r*(h^2*x2 - x3) - h^3*y2 + * z3 = h*z2 + */ + + xz = p2->z; + bn_multiply(&xz, &xz, prime); // xz = z2^2 + yz = p2->z; + bn_multiply(&xz, &yz, prime); // yz = z2^3 + + if (a != 0) { + az = xz; + bn_multiply(&az, &az, prime); // az = z2^4 + bn_mult_k(&az, -a, prime); // az = -az2^4 + } + + bn_multiply(&p1->x, &xz, prime); // xz = x1' = x1*z2^2; + h = xz; + bn_subtractmod(&h, &p2->x, &h, prime); + bn_fast_mod(&h, prime); + // h = x1' - x2; + + bn_add(&xz, &p2->x); + // xz = x1' + x2 + + // check for h == 0 % prime. Note that h never normalizes to + // zero, since h = x1' + 2*prime - x2 > 0 and a positive + // multiple of prime is always normalized to prime by + // bn_fast_mod. + is_doubling = bn_is_equal(&h, prime); + + bn_multiply(&p1->y, &yz, prime); // yz = y1' = y1*z2^3; + bn_subtractmod(&yz, &p2->y, &r, prime); + // r = y1' - y2; + + bn_add(&yz, &p2->y); + // yz = y1' + y2 + + r2 = p2->x; + bn_multiply(&r2, &r2, prime); + bn_mult_k(&r2, 3, prime); + + if (a != 0) { + // subtract -a z2^4, i.e, add a z2^4 + bn_subtractmod(&r2, &az, &r2, prime); + } + bn_cmov(&r, is_doubling, &r2, &r); + bn_cmov(&h, is_doubling, &yz, &h); + + + // hsqx = h^2 + hsqx = h; + bn_multiply(&hsqx, &hsqx, prime); + + // hcby = h^3 + hcby = h; + bn_multiply(&hsqx, &hcby, prime); + + // hsqx = h^2 * (x1 + x2) + bn_multiply(&xz, &hsqx, prime); + + // hcby = h^3 * (y1 + y2) + bn_multiply(&yz, &hcby, prime); + + // z3 = h*z2 + bn_multiply(&h, &p2->z, prime); + + // x3 = r^2 - h^2 (x1 + x2) + p2->x = r; + bn_multiply(&p2->x, &p2->x, prime); + bn_subtractmod(&p2->x, &hsqx, &p2->x, prime); + bn_fast_mod(&p2->x, prime); + + // y3 = 1/2 (r*(h^2 (x1 + x2) - 2x3) - h^3 (y1 + y2)) + bn_subtractmod(&hsqx, &p2->x, &p2->y, prime); + bn_subtractmod(&p2->y, &p2->x, &p2->y, prime); + bn_multiply(&r, &p2->y, prime); + bn_subtractmod(&p2->y, &hcby, &p2->y, prime); + bn_mult_half(&p2->y, prime); + bn_fast_mod(&p2->y, prime); +} + +void point_jacobian_double(jacobian_curve_point *p, const ecdsa_curve *curve) { + bignum256 az4, m, msq, ysq, xysq; + const bignum256 *prime = &curve->prime; + + assert (-3 <= curve->a && curve->a <= 0); + /* usual algorithm: + * + * lambda = (3((x/z^2)^2 + a) / 2y/z^3) = (3x^2 + az^4)/2yz + * x3/z3^2 = lambda^2 - 2x/z^2 + * y3/z3^3 = lambda * (x/z^2 - x3/z3^2) - y/z^3 + * + * to get rid of fraction we set + * m = (3 x^2 + az^4) / 2 + * Hence, + * lambda = m / yz = m / z3 + * + * With z3 = yz (the denominator of lambda) + * we get x3 = lambda^2*z3^2 - 2*x/z^2*z3^2 + * = m^2 - 2*xy^2 + * and y3 = (lambda * (x/z^2 - x3/z3^2) - y/z^3) * z3^3 + * = m * (xy^2 - x3) - y^4 + */ + + /* m = (3*x^2 + a z^4) / 2 + * x3 = m^2 - 2*xy^2 + * y3 = m*(xy^2 - x3) - 8y^4 + * z3 = y*z + */ + + m = p->x; + bn_multiply(&m, &m, prime); + bn_mult_k(&m, 3, prime); + + az4 = p->z; + bn_multiply(&az4, &az4, prime); + bn_multiply(&az4, &az4, prime); + bn_mult_k(&az4, -curve->a, prime); + bn_subtractmod(&m, &az4, &m, prime); + bn_mult_half(&m, prime); + + // msq = m^2 + msq = m; + bn_multiply(&msq, &msq, prime); + // ysq = y^2 + ysq = p->y; + bn_multiply(&ysq, &ysq, prime); + // xysq = xy^2 + xysq = p->x; + bn_multiply(&ysq, &xysq, prime); + + // z3 = yz + bn_multiply(&p->y, &p->z, prime); + + // x3 = m^2 - 2*xy^2 + p->x = xysq; + bn_lshift(&p->x); + bn_fast_mod(&p->x, prime); + bn_subtractmod(&msq, &p->x, &p->x, prime); + bn_fast_mod(&p->x, prime); + + // y3 = m*(xy^2 - x3) - y^4 + bn_subtractmod(&xysq, &p->x, &p->y, prime); + bn_multiply(&m, &p->y, prime); + bn_multiply(&ysq, &ysq, prime); + bn_subtractmod(&p->y, &ysq, &p->y, prime); + bn_fast_mod(&p->y, prime); +} + +// res = k * p +void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_point *p, curve_point *res) +{ + // this algorithm is loosely based on + // Katsuyuki Okeya and Tsuyoshi Takagi, The Width-w NAF Method Provides + // Small Memory and Fast Elliptic Scalar Multiplications Secure against + // Side Channel Attacks. + assert (bn_is_less(k, &curve->order)); + + int i, j; + static CONFIDENTIAL bignum256 a; + uint32_t *aptr; + uint32_t abits; + int ashift; + uint32_t is_even = (k->val[0] & 1) - 1; + uint32_t bits, sign, nsign; + static CONFIDENTIAL jacobian_curve_point jres; + curve_point pmult[8]; + const bignum256 *prime = &curve->prime; + + // is_even = 0xffffffff if k is even, 0 otherwise. + + // add 2^256. + // make number odd: subtract curve->order if even + uint32_t tmp = 1; + uint32_t is_non_zero = 0; + for (j = 0; j < 8; j++) { + is_non_zero |= k->val[j]; + tmp += 0x3fffffff + k->val[j] - (curve->order.val[j] & is_even); + a.val[j] = tmp & 0x3fffffff; + tmp >>= 30; + } + is_non_zero |= k->val[j]; + a.val[j] = tmp + 0xffff + k->val[j] - (curve->order.val[j] & is_even); + assert((a.val[0] & 1) != 0); + + // special case 0*p: just return zero. We don't care about constant time. + if (!is_non_zero) { + point_set_infinity(res); + return; + } + + // Now a = k + 2^256 (mod curve->order) and a is odd. + // + // The idea is to bring the new a into the form. + // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. + // a[0] is odd, since a is odd. If a[i] would be even, we can + // add 1 to it and subtract 16 from a[i-1]. Afterwards, + // a[64] = 1, which is the 2^256 that we added before. + // + // Since k = a - 2^256 (mod curve->order), we can compute + // k*p = sum_{i=0..63} a[i] 16^i * p + // + // We compute |a[i]| * p in advance for all possible + // values of |a[i]| * p. pmult[i] = (2*i+1) * p + // We compute p, 3*p, ..., 15*p and store it in the table pmult. + // store p^2 temporarily in pmult[7] + pmult[7] = *p; + point_double(curve, &pmult[7]); + // compute 3*p, etc by repeatedly adding p^2. + pmult[0] = *p; + for (i = 1; i < 8; i++) { + pmult[i] = pmult[7]; + point_add(curve, &pmult[i-1], &pmult[i]); + } + + // now compute res = sum_{i=0..63} a[i] * 16^i * p step by step, + // starting with i = 63. + // initialize jres = |a[63]| * p. + // Note that a[i] = a>>(4*i) & 0xf if (a&0x10) != 0 + // and - (16 - (a>>(4*i) & 0xf)) otherwise. We can compute this as + // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 + // since a is odd. + aptr = &a.val[8]; + abits = *aptr; + ashift = 12; + bits = abits >> ashift; + sign = (bits >> 4) - 1; + bits ^= sign; + bits &= 15; + curve_to_jacobian(&pmult[bits>>1], &jres, prime); + for (i = 62; i >= 0; i--) { + // sign = sign(a[i+1]) (0xffffffff for negative, 0 for positive) + // invariant jres = (-1)^sign sum_{j=i+1..63} (a[j] * 16^{j-i-1} * p) + // abits >> (ashift - 4) = lowbits(a >> (i*4)) + + point_jacobian_double(&jres, curve); + point_jacobian_double(&jres, curve); + point_jacobian_double(&jres, curve); + point_jacobian_double(&jres, curve); + + // get lowest 5 bits of a >> (i*4). + ashift -= 4; + if (ashift < 0) { + // the condition only depends on the iteration number and + // leaks no private information to a side-channel. + bits = abits << (-ashift); + abits = *(--aptr); + ashift += 30; + bits |= abits >> ashift; + } else { + bits = abits >> ashift; + } + bits &= 31; + nsign = (bits >> 4) - 1; + bits ^= nsign; + bits &= 15; + + // negate last result to make signs of this round and the + // last round equal. + conditional_negate(sign ^ nsign, &jres.z, prime); + + // add odd factor + point_jacobian_add(&pmult[bits >> 1], &jres, curve); + sign = nsign; + } + conditional_negate(sign, &jres.z, prime); + jacobian_to_curve(&jres, res, prime); + memzero(&a, sizeof(a)); + memzero(&jres, sizeof(jres)); +} + +#if USE_PRECOMPUTED_CP + +// res = k * G +// k must be a normalized number with 0 <= k < curve->order +void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *res) +{ + assert (bn_is_less(k, &curve->order)); + + int i, j; + static CONFIDENTIAL bignum256 a; + uint32_t is_even = (k->val[0] & 1) - 1; + uint32_t lowbits; + static CONFIDENTIAL jacobian_curve_point jres; + const bignum256 *prime = &curve->prime; + + // is_even = 0xffffffff if k is even, 0 otherwise. + + // add 2^256. + // make number odd: subtract curve->order if even + uint32_t tmp = 1; + uint32_t is_non_zero = 0; + for (j = 0; j < 8; j++) { + is_non_zero |= k->val[j]; + tmp += 0x3fffffff + k->val[j] - (curve->order.val[j] & is_even); + a.val[j] = tmp & 0x3fffffff; + tmp >>= 30; + } + is_non_zero |= k->val[j]; + a.val[j] = tmp + 0xffff + k->val[j] - (curve->order.val[j] & is_even); + assert((a.val[0] & 1) != 0); + + // special case 0*G: just return zero. We don't care about constant time. + if (!is_non_zero) { + point_set_infinity(res); + return; + } + + // Now a = k + 2^256 (mod curve->order) and a is odd. + // + // The idea is to bring the new a into the form. + // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. + // a[0] is odd, since a is odd. If a[i] would be even, we can + // add 1 to it and subtract 16 from a[i-1]. Afterwards, + // a[64] = 1, which is the 2^256 that we added before. + // + // Since k = a - 2^256 (mod curve->order), we can compute + // k*G = sum_{i=0..63} a[i] 16^i * G + // + // We have a big table curve->cp that stores all possible + // values of |a[i]| 16^i * G. + // curve->cp[i][j] = (2*j+1) * 16^i * G + + // now compute res = sum_{i=0..63} a[i] * 16^i * G step by step. + // initial res = |a[0]| * G. Note that a[0] = a & 0xf if (a&0x10) != 0 + // and - (16 - (a & 0xf)) otherwise. We can compute this as + // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 + // since a is odd. + lowbits = a.val[0] & ((1 << 5) - 1); + lowbits ^= (lowbits >> 4) - 1; + lowbits &= 15; + curve_to_jacobian(&curve->cp[0][lowbits >> 1], &jres, prime); + for (i = 1; i < 64; i ++) { + // invariant res = sign(a[i-1]) sum_{j=0..i-1} (a[j] * 16^j * G) + + // shift a by 4 places. + for (j = 0; j < 8; j++) { + a.val[j] = (a.val[j] >> 4) | ((a.val[j + 1] & 0xf) << 26); + } + a.val[j] >>= 4; + // a = old(a)>>(4*i) + // a is even iff sign(a[i-1]) = -1 + + lowbits = a.val[0] & ((1 << 5) - 1); + lowbits ^= (lowbits >> 4) - 1; + lowbits &= 15; + // negate last result to make signs of this round and the + // last round equal. + conditional_negate((lowbits & 1) - 1, &jres.y, prime); + + // add odd factor + point_jacobian_add(&curve->cp[i][lowbits >> 1], &jres, curve); + } + conditional_negate(((a.val[0] >> 4) & 1) - 1, &jres.y, prime); + jacobian_to_curve(&jres, res, prime); + memzero(&a, sizeof(a)); + memzero(&jres, sizeof(jres)); +} + +#else + +void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *res) +{ + point_multiply(curve, k, &curve->G, res); +} + +#endif + +int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *pub_key, uint8_t *session_key) +{ + curve_point point; + if (!ecdsa_read_pubkey(curve, pub_key, &point)) { + return 1; + } + + bignum256 k; + bn_read_be(priv_key, &k); + point_multiply(curve, &k, &point, &point); + memzero(&k, sizeof(k)); + + session_key[0] = 0x04; + bn_write_be(&point.x, session_key + 1); + bn_write_be(&point.y, session_key + 33); + memzero(&point, sizeof(point)); + + return 0; +} + +void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *state) { + uint8_t bx[2*32]; + uint8_t buf[32 + 1 + 2*32]; + + memcpy(bx, priv_key, 32); + memcpy(bx+32, hash, 32); + + memset(state->v, 1, sizeof(state->v)); + memset(state->k, 0, sizeof(state->k)); + + memcpy(buf, state->v, sizeof(state->v)); + buf[sizeof(state->v)] = 0x00; + memcpy(buf + sizeof(state->v) + 1, bx, 64); + hmac_sha256(state->k, sizeof(state->k), buf, sizeof(buf), state->k); + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + + memcpy(buf, state->v, sizeof(state->v)); + buf[sizeof(state->v)] = 0x01; + memcpy(buf + sizeof(state->v) + 1, bx, 64); + hmac_sha256(state->k, sizeof(state->k), buf, sizeof(buf), state->k); + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + + memzero(bx, sizeof(bx)); + memzero(buf, sizeof(buf)); +} + +// generate next number from deterministic random number generator +void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state) +{ + uint8_t buf[32 + 1]; + + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + memcpy(buf, state->v, sizeof(state->v)); + buf[sizeof(state->v)] = 0x00; + hmac_sha256(state->k, sizeof(state->k), buf, sizeof(state->v) + 1, state->k); + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + memcpy(rnd, buf, 32); + memzero(buf, sizeof(buf)); +} + +// generate K in a deterministic way, according to RFC6979 +// http://tools.ietf.org/html/rfc6979 +void generate_k_rfc6979(bignum256 *k, rfc6979_state *state) +{ + uint8_t buf[32]; + generate_rfc6979(buf, state); + bn_read_be(buf, k); + memzero(buf, sizeof(buf)); +} + +// msg is a data to be signed +// msg_len is the message length +int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])) +{ + uint8_t hash[32]; + hasher_Raw(hasher_type, msg, msg_len, hash); + int res = ecdsa_sign_digest(curve, priv_key, hash, sig, pby, is_canonical); + memzero(hash, sizeof(hash)); + return res; + +} + +// msg is a data to be signed +// msg_len is the message length +int ecdsa_sign_double(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])) +{ + uint8_t hash[32]; + hasher_Raw(hasher_type, msg, msg_len, hash); + hasher_Raw(hasher_type, hash, 32, hash); + int res = ecdsa_sign_digest(curve, priv_key, hash, sig, pby, is_canonical); + memzero(hash, sizeof(hash)); + return res; +} + +// uses secp256k1 curve +// priv_key is a 32 byte big endian stored number +// sig is 64 bytes long array for the signature +// digest is 32 bytes of digest +// is_canonical is an optional function that checks if the signature +// conforms to additional coin-specific rules. +int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])) +{ + int i; + curve_point R; + bignum256 k, z, randk; + bignum256 *s = &R.y; + uint8_t by; // signature recovery byte + +#if USE_RFC6979 + rfc6979_state rng; + init_rfc6979(priv_key, digest, &rng); +#endif + + bn_read_be(digest, &z); + + for (i = 0; i < 10000; i++) { + +#if USE_RFC6979 + // generate K deterministically + generate_k_rfc6979(&k, &rng); + // if k is too big or too small, we don't like it + if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { + continue; + } +#else + // generate random number k + generate_k_random(&k, &curve->order); +#endif + + // compute k*G + scalar_multiply(curve, &k, &R); + by = R.y.val[0] & 1; + // r = (rx mod n) + if (!bn_is_less(&R.x, &curve->order)) { + bn_subtract(&R.x, &curve->order, &R.x); + by |= 2; + } + // if r is zero, we retry + if (bn_is_zero(&R.x)) { + continue; + } + + // randomize operations to counter side-channel attacks + generate_k_random(&randk, &curve->order); + bn_multiply(&randk, &k, &curve->order); // k*rand + bn_inverse(&k, &curve->order); // (k*rand)^-1 + bn_read_be(priv_key, s); // priv + bn_multiply(&R.x, s, &curve->order); // R.x*priv + bn_add(s, &z); // R.x*priv + z + bn_multiply(&k, s, &curve->order); // (k*rand)^-1 (R.x*priv + z) + bn_multiply(&randk, s, &curve->order); // k^-1 (R.x*priv + z) + bn_mod(s, &curve->order); + // if s is zero, we retry + if (bn_is_zero(s)) { + continue; + } + + // if S > order/2 => S = -S + if (bn_is_less(&curve->order_half, s)) { + bn_subtract(&curve->order, s, s); + by ^= 1; + } + // we are done, R.x and s is the result signature + bn_write_be(&R.x, sig); + bn_write_be(s, sig + 32); + + // check if the signature is acceptable or retry + if (is_canonical && !is_canonical(by, sig)) { + continue; + } + + if (pby) { + *pby = by; + } + + memzero(&k, sizeof(k)); + memzero(&randk, sizeof(randk)); +#if USE_RFC6979 + memzero(&rng, sizeof(rng)); +#endif + return 0; + } + + // Too many retries without a valid signature + // -> fail with an error + memzero(&k, sizeof(k)); + memzero(&randk, sizeof(randk)); +#if USE_RFC6979 + memzero(&rng, sizeof(rng)); +#endif + return -1; +} + +void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key) +{ + curve_point R; + bignum256 k; + + bn_read_be(priv_key, &k); + // compute k*G + scalar_multiply(curve, &k, &R); + pub_key[0] = 0x02 | (R.y.val[0] & 0x01); + bn_write_be(&R.x, pub_key + 1); + memzero(&R, sizeof(R)); + memzero(&k, sizeof(k)); +} + +void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key) +{ + curve_point R; + bignum256 k; + + bn_read_be(priv_key, &k); + // compute k*G + scalar_multiply(curve, &k, &R); + pub_key[0] = 0x04; + bn_write_be(&R.x, pub_key + 1); + bn_write_be(&R.y, pub_key + 33); + memzero(&R, sizeof(R)); + memzero(&k, sizeof(k)); +} + +int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, uint8_t *uncompressed) +{ + curve_point pub; + + if (!ecdsa_read_pubkey(curve, pub_key, &pub)) { + return 0; + } + + uncompressed[0] = 4; + bn_write_be(&pub.x, uncompressed + 1); + bn_write_be(&pub.y, uncompressed + 33); + + return 1; +} + +void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_type, uint8_t *pubkeyhash) +{ + uint8_t h[HASHER_DIGEST_LENGTH]; + if (pub_key[0] == 0x04) { // uncompressed format + hasher_Raw(hasher_type, pub_key, 65, h); + } else if (pub_key[0] == 0x00) { // point at infinity + hasher_Raw(hasher_type, pub_key, 1, h); + } else { // expecting compressed format + hasher_Raw(hasher_type, pub_key, 33, h); + } + ripemd160(h, HASHER_DIGEST_LENGTH, pubkeyhash); + memzero(h, sizeof(h)); +} + +void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, uint8_t *addr_raw) +{ + size_t prefix_len = address_prefix_bytes_len(version); + address_write_prefix_bytes(version, addr_raw); + ecdsa_get_pubkeyhash(pub_key, hasher_type, addr_raw + prefix_len); +} + +void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, char *addr, int addrsize) +{ + uint8_t raw[MAX_ADDR_RAW_SIZE]; + size_t prefix_len = address_prefix_bytes_len(version); + ecdsa_get_address_raw(pub_key, version, hasher_type, raw); + base58_encode_check(raw, 20 + prefix_len, hasher_type, addr, addrsize); + // not as important to clear this one, but we might as well + memzero(raw, sizeof(raw)); +} + +void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, uint8_t *addr_raw) +{ + size_t prefix_len = address_prefix_bytes_len(version); + uint8_t digest[32]; + addr_raw[0] = 0; // version byte + addr_raw[1] = 20; // push 20 bytes + ecdsa_get_pubkeyhash(pub_key, hasher_type, addr_raw + 2); + hasher_Raw(hasher_type, addr_raw, 22, digest); + address_write_prefix_bytes(version, addr_raw); + ripemd160(digest, 32, addr_raw + prefix_len); +} + +void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, char *addr, int addrsize) +{ + uint8_t raw[MAX_ADDR_RAW_SIZE]; + size_t prefix_len = address_prefix_bytes_len(version); + ecdsa_get_address_segwit_p2sh_raw(pub_key, version, hasher_type, raw); + base58_encode_check(raw, prefix_len + 20, hasher_type, addr, addrsize); + memzero(raw, sizeof(raw)); +} + +void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, HasherType hasher_type, char *wif, int wifsize) +{ + uint8_t wif_raw[MAX_WIF_RAW_SIZE]; + size_t prefix_len = address_prefix_bytes_len(version); + address_write_prefix_bytes(version, wif_raw); + memcpy(wif_raw + prefix_len, priv_key, 32); + wif_raw[prefix_len + 32] = 0x01; + base58_encode_check(wif_raw, prefix_len + 32 + 1, hasher_type, wif, wifsize); + // private keys running around our stack can cause trouble + memzero(wif_raw, sizeof(wif_raw)); +} + +int ecdsa_address_decode(const char *addr, uint32_t version, HasherType hasher_type, uint8_t *out) +{ + if (!addr) return 0; + int prefix_len = address_prefix_bytes_len(version); + return base58_decode_check(addr, hasher_type, out, 20 + prefix_len) == 20 + prefix_len + && address_check_prefix(out, version); +} + +void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x, bignum256 *y) +{ + // y^2 = x^3 + a*x + b + memcpy(y, x, sizeof(bignum256)); // y is x + bn_multiply(x, y, &curve->prime); // y is x^2 + bn_subi(y, -curve->a, &curve->prime); // y is x^2 + a + bn_multiply(x, y, &curve->prime); // y is x^3 + ax + bn_add(y, &curve->b); // y is x^3 + ax + b + bn_sqrt(y, &curve->prime); // y = sqrt(y) + if ((odd & 0x01) != (y->val[0] & 1)) { + bn_subtract(&curve->prime, y, y); // y = -y + } +} + +int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_point *pub) +{ + if (!curve) { + curve = &secp256k1; + } + if (pub_key[0] == 0x04) { + bn_read_be(pub_key + 1, &(pub->x)); + bn_read_be(pub_key + 33, &(pub->y)); + return ecdsa_validate_pubkey(curve, pub); + } + if (pub_key[0] == 0x02 || pub_key[0] == 0x03) { // compute missing y coords + bn_read_be(pub_key + 1, &(pub->x)); + uncompress_coords(curve, pub_key[0], &(pub->x), &(pub->y)); + return ecdsa_validate_pubkey(curve, pub); + } + // error + return 0; +} + +// Verifies that: +// - pub is not the point at infinity. +// - pub->x and pub->y are in range [0,p-1]. +// - pub is on the curve. + +int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub) +{ + bignum256 y_2, x3_ax_b; + + if (point_is_infinity(pub)) { + return 0; + } + + if (!bn_is_less(&(pub->x), &curve->prime) || !bn_is_less(&(pub->y), &curve->prime)) { + return 0; + } + + memcpy(&y_2, &(pub->y), sizeof(bignum256)); + memcpy(&x3_ax_b, &(pub->x), sizeof(bignum256)); + + // y^2 + bn_multiply(&(pub->y), &y_2, &curve->prime); + bn_mod(&y_2, &curve->prime); + + // x^3 + ax + b + bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^2 + bn_subi(&x3_ax_b, -curve->a, &curve->prime); // x^2 + a + bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^3 + ax + bn_addmod(&x3_ax_b, &curve->b, &curve->prime); // x^3 + ax + b + bn_mod(&x3_ax_b, &curve->prime); + + if (!bn_is_equal(&x3_ax_b, &y_2)) { + return 0; + } + + return 1; +} + +// uses secp256k1 curve +// pub_key - 65 bytes uncompressed key +// signature - 64 bytes signature +// msg is a data that was signed +// msg_len is the message length + +int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len) +{ + uint8_t hash[32]; + hasher_Raw(hasher_type, msg, msg_len, hash); + int res = ecdsa_verify_digest(curve, pub_key, sig, hash); + memzero(hash, sizeof(hash)); + return res; +} + +int ecdsa_verify_double(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len) +{ + uint8_t hash[32]; + hasher_Raw(hasher_type, msg, msg_len, hash); + hasher_Raw(hasher_type, hash, 32, hash); + int res = ecdsa_verify_digest(curve, pub_key, sig, hash); + memzero(hash, sizeof(hash)); + return res; +} + +// Compute public key from signature and recovery id. +// returns 0 if verification succeeded +int ecdsa_verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest, int recid) +{ + bignum256 r, s, e; + curve_point cp, cp2; + + // read r and s + bn_read_be(sig, &r); + bn_read_be(sig + 32, &s); + if (!bn_is_less(&r, &curve->order) || bn_is_zero(&r)) { + return 1; + } + if (!bn_is_less(&s, &curve->order) || bn_is_zero(&s)) { + return 1; + } + // cp = R = k * G (k is secret nonce when signing) + memcpy(&cp.x, &r, sizeof(bignum256)); + if (recid & 2) { + bn_add(&cp.x, &curve->order); + if (!bn_is_less(&cp.x, &curve->prime)) { + return 1; + } + } + // compute y from x + uncompress_coords(curve, recid & 1, &cp.x, &cp.y); + if (!ecdsa_validate_pubkey(curve, &cp)) { + return 1; + } + // e = -digest + bn_read_be(digest, &e); + bn_subtractmod(&curve->order, &e, &e, &curve->order); + bn_fast_mod(&e, &curve->order); + bn_mod(&e, &curve->order); + // r := r^-1 + bn_inverse(&r, &curve->order); + // cp := s * R = s * k *G + point_multiply(curve, &s, &cp, &cp); + // cp2 := -digest * G + scalar_multiply(curve, &e, &cp2); + // cp := (s * k - digest) * G = (r*priv) * G = r * Pub + point_add(curve, &cp2, &cp); + // cp := r^{-1} * r * Pub = Pub + point_multiply(curve, &r, &cp, &cp); + pub_key[0] = 0x04; + bn_write_be(&cp.x, pub_key + 1); + bn_write_be(&cp.y, pub_key + 33); + return 0; +} + +// returns 0 if verification succeeded +int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest) +{ + curve_point pub, res; + bignum256 r, s, z; + + if (!ecdsa_read_pubkey(curve, pub_key, &pub)) { + return 1; + } + + bn_read_be(sig, &r); + bn_read_be(sig + 32, &s); + + bn_read_be(digest, &z); + + if (bn_is_zero(&r) || bn_is_zero(&s) || + (!bn_is_less(&r, &curve->order)) || + (!bn_is_less(&s, &curve->order))) return 2; + + bn_inverse(&s, &curve->order); // s^-1 + bn_multiply(&s, &z, &curve->order); // z*s^-1 + bn_mod(&z, &curve->order); + bn_multiply(&r, &s, &curve->order); // r*s^-1 + bn_mod(&s, &curve->order); + + int result = 0; + if (bn_is_zero(&z)) { + // our message hashes to zero + // I don't expect this to happen any time soon + result = 3; + } else { + scalar_multiply(curve, &z, &res); + } + + if (result == 0) { + // both pub and res can be infinity, can have y = 0 OR can be equal -> false negative + point_multiply(curve, &s, &pub, &pub); + point_add(curve, &pub, &res); + bn_mod(&(res.x), &curve->order); + // signature does not match + if (!bn_is_equal(&res.x, &r)) { + result = 5; + } + } + + memzero(&pub, sizeof(pub)); + memzero(&res, sizeof(res)); + memzero(&r, sizeof(r)); + memzero(&s, sizeof(s)); + memzero(&z, sizeof(z)); + + // all OK + return result; +} + +int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der) +{ + int i; + uint8_t *p = der, *len, *len1, *len2; + *p = 0x30; p++; // sequence + *p = 0x00; len = p; p++; // len(sequence) + + *p = 0x02; p++; // integer + *p = 0x00; len1 = p; p++; // len(integer) + + // process R + i = 0; + while (sig[i] == 0 && i < 32) { i++; } // skip leading zeroes + if (sig[i] >= 0x80) { // put zero in output if MSB set + *p = 0x00; p++; *len1 = *len1 + 1; + } + while (i < 32) { // copy bytes to output + *p = sig[i]; p++; *len1 = *len1 + 1; i++; + } + + *p = 0x02; p++; // integer + *p = 0x00; len2 = p; p++; // len(integer) + + // process S + i = 32; + while (sig[i] == 0 && i < 64) { i++; } // skip leading zeroes + if (sig[i] >= 0x80) { // put zero in output if MSB set + *p = 0x00; p++; *len2 = *len2 + 1; + } + while (i < 64) { // copy bytes to output + *p = sig[i]; p++; *len2 = *len2 + 1; i++; + } + + *len = *len1 + *len2 + 4; + return *len + 2; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.h b/hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.h new file mode 100644 index 00000000..d9bd1d1e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ecdsa.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __ECDSA_H__ +#define __ECDSA_H__ + +#include +#include "options.h" +#include "bignum.h" +#include "hasher.h" + +// curve point x and y +typedef struct { + bignum256 x, y; +} curve_point; + +typedef struct { + + bignum256 prime; // prime order of the finite field + curve_point G; // initial curve point + bignum256 order; // order of G + bignum256 order_half; // order of G divided by 2 + int a; // coefficient 'a' of the elliptic curve + bignum256 b; // coefficient 'b' of the elliptic curve + +#if USE_PRECOMPUTED_CP + const curve_point cp[64][8]; +#endif + +} ecdsa_curve; + +// 4 byte prefix + 40 byte data (segwit) +#define MAX_ADDR_RAW_SIZE (4 + 40) +// bottle neck is segwit bech32: +// 4 human readable prefix + 1 separator + 64 data + 6 checksum + 1 NUL +// the standard says 83 characters in hrp, but currently all coins use max 4 +#define MAX_ADDR_SIZE (4 + 1 + 64 + 6 + 1) +// 4 byte prefix + 32 byte privkey + 1 byte compressed marker +#define MAX_WIF_RAW_SIZE (4 + 32 + 1) +// (4 + 32 + 1 + 4 [checksum]) * 8 / log2(58) plus NUL. +#define MAX_WIF_SIZE (57) + +void point_copy(const curve_point *cp1, curve_point *cp2); +void point_add(const ecdsa_curve *curve, const curve_point *cp1, curve_point *cp2); +void point_double(const ecdsa_curve *curve, curve_point *cp); +void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_point *p, curve_point *res); +void point_set_infinity(curve_point *p); +int point_is_infinity(const curve_point *p); +int point_is_equal(const curve_point *p, const curve_point *q); +int point_is_negative_of(const curve_point *p, const curve_point *q); +void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *res); +int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *pub_key, uint8_t *session_key); +void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x, bignum256 *y); +int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, uint8_t *uncompressed); + +int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])); +int ecdsa_sign_double(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])); +int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])); +void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key); +void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key); +void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_type, uint8_t *pubkeyhash); +void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, uint8_t *addr_raw); +void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, char *addr, int addrsize); +void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, uint8_t *addr_raw); +void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, HasherType hasher_type, char *addr, int addrsize); +void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, HasherType hasher_type, char *wif, int wifsize); + +int ecdsa_address_decode(const char *addr, uint32_t version, HasherType hasher_type, uint8_t *out); +int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_point *pub); +int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub); +int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len); +int ecdsa_verify_double(const ecdsa_curve *curve, HasherType hasher_type, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len); +int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest); +int ecdsa_verify_digest_recover(const ecdsa_curve *curve, uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest, int recid); +int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/README.md b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/README.md new file mode 100644 index 00000000..e09fc27e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/README.md @@ -0,0 +1,183 @@ +[ed25519](http://ed25519.cr.yp.to/) is an +[Elliptic Curve Digital Signature Algortithm](http://en.wikipedia.org/wiki/Elliptic_Curve_DSA), +developed by [Dan Bernstein](http://cr.yp.to/djb.html), +[Niels Duif](http://www.nielsduif.nl/), +[Tanja Lange](http://hyperelliptic.org/tanja), +[Peter Schwabe](http://www.cryptojedi.org/users/peter/), +and [Bo-Yin Yang](http://www.iis.sinica.edu.tw/pages/byyang/). + +This project provides performant, portable 32-bit & 64-bit implementations. All implementations are +of course constant time in regard to secret data. + +#### Performance + +SSE2 code and benches have not been updated yet. I will do those next. + +Compilers versions are gcc 4.6.3, icc 13.1.1, clang 3.4-1~exp1. + +Batch verification time (in parentheses) is the average time per 1 verification in a batch of 64 signatures. Counts are in thousands of cycles. + +Note that SSE2 performance may be less impressive on AMD & older CPUs with slower SSE ops! + +Visual Studio performance for `ge25519_scalarmult_base_niels` will lag behind a bit until optimized assembler versions of `ge25519_scalarmult_base_choose_niels` +are made. + +##### E5200 @ 2.5ghz, march=core2 + + + + + + + + + + + +
ImplementationSigngcciccclangVerifygcciccclang
ed25519-donna 64bit 100k110k137k327k (144k) 342k (163k) 422k (194k)
amd64-64-24k 102k 355k (158k)
ed25519-donna-sse2 64bit108k111k116k353k (155k) 345k (154k) 360k (161k)
amd64-51-32k 116k 380k (175k)
ed25519-donna-sse2 32bit147k147k156k380k (178k) 381k (173k) 430k (192k)
ed25519-donna 32bit 597k335k380k1693k (720k)1052k (453k)1141k (493k)
+ +##### E3-1270 @ 3.4ghz, march=corei7-avx + + + + + + + + + + + +
ImplementationSigngcciccclangVerifygcciccclang
amd64-64-24k 68k 225k (104k)
ed25519-donna 64bit 71k 75k 90k226k (105k) 226k (112k) 277k (125k)
amd64-51-32k 72k 218k (107k)
ed25519-donna-sse2 64bit 79k 82k 92k252k (122k) 259k (124k) 282k (131k)
ed25519-donna-sse2 32bit 94k 95k103k296k (146k) 294k (137k) 306k (147k)
ed25519-donna 32bit 525k299k316k1502k (645k)959k (418k) 954k (416k)
+ +#### Compilation + +No configuration is needed **if you are compiling against OpenSSL**. + +##### Hash Options + +If you are not compiling aginst OpenSSL, you will need a hash function. + +To use a simple/**slow** implementation of SHA-512, use `-DED25519_REFHASH` when compiling `ed25519.c`. +This should never be used except to verify the code works when OpenSSL is not available. + +To use a custom hash function, use `-DED25519_CUSTOMHASH` when compiling `ed25519.c` and put your +custom hash implementation in ed25519-hash-custom.h. The hash must have a 512bit digest and implement + + struct ed25519_hash_context; + + void ed25519_hash_init(ed25519_hash_context *ctx); + void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen); + void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash); + void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen); + +##### Random Options + +If you are not compiling aginst OpenSSL, you will need a random function for batch verification. + +To use a custom random function, use `-DED25519_CUSTOMRANDOM` when compiling `ed25519.c` and put your +custom hash implementation in ed25519-randombytes-custom.h. The random function must implement: + + void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len); + +Use `-DED25519_TEST` when compiling `ed25519.c` to use a deterministically seeded, non-thread safe CSPRNG +variant of Bob Jenkins [ISAAC](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29) + +##### Minor options + +Use `-DED25519_INLINE_ASM` to disable the use of custom assembler routines and instead rely on portable C. + +Use `-DED25519_FORCE_32BIT` to force the use of 32 bit routines even when compiling for 64 bit. + +##### 32-bit + + gcc ed25519.c -m32 -O3 -c + +##### 64-bit + + gcc ed25519.c -m64 -O3 -c + +##### SSE2 + + gcc ed25519.c -m32 -O3 -c -DED25519_SSE2 -msse2 + gcc ed25519.c -m64 -O3 -c -DED25519_SSE2 + +clang and icc are also supported + + +#### Usage + +To use the code, link against `ed25519.o -mbits` and: + + #include "ed25519.h" + +Add `-lssl -lcrypto` when using OpenSSL (Some systems don't need -lcrypto? It might be trial and error). + +To generate a private key, simply generate 32 bytes from a secure +cryptographic source: + + ed25519_secret_key sk; + randombytes(sk, sizeof(ed25519_secret_key)); + +To generate a public key: + + ed25519_public_key pk; + ed25519_publickey(sk, pk); + +To sign a message: + + ed25519_signature sig; + ed25519_sign(message, message_len, sk, pk, signature); + +To verify a signature: + + int valid = ed25519_sign_open(message, message_len, pk, signature) == 0; + +To batch verify signatures: + + const unsigned char *mp[num] = {message1, message2..} + size_t ml[num] = {message_len1, message_len2..} + const unsigned char *pkp[num] = {pk1, pk2..} + const unsigned char *sigp[num] = {signature1, signature2..} + int valid[num] + + /* valid[i] will be set to 1 if the individual signature was valid, 0 otherwise */ + int all_valid = ed25519_sign_open_batch(mp, ml, pkp, sigp, num, valid) == 0; + +**Note**: Batch verification uses `ed25519_randombytes_unsafe`, implemented in +`ed25519-randombytes.h`, to generate random scalars for the verification code. +The default implementation now uses OpenSSLs `RAND_bytes`. + +Unlike the [SUPERCOP](http://bench.cr.yp.to/supercop.html) version, signatures are +not appended to messages, and there is no need for padding in front of messages. +Additionally, the secret key does not contain a copy of the public key, so it is +32 bytes instead of 64 bytes, and the public key must be provided to the signing +function. + +##### Curve25519 + +Curve25519 public keys can be generated thanks to +[Adam Langley](http://www.imperialviolet.org/2013/05/10/fastercurve25519.html) +leveraging Ed25519's precomputed basepoint scalar multiplication. + + curved25519_key sk, pk; + randombytes(sk, sizeof(curved25519_key)); + curved25519_scalarmult_basepoint(pk, sk); + +Note the name is curved25519, a combination of curve and ed25519, to prevent +name clashes. Performance is slightly faster than short message ed25519 +signing due to both using the same code for the scalar multiply. + +#### Testing + +Fuzzing against reference implemenations is now available. See [fuzz/README](fuzz/README.md). + +Building `ed25519.c` with `-DED25519_TEST` and linking with `test.c` will run basic sanity tests +and benchmark each function. `test-batch.c` has been incorporated in to `test.c`. + +`test-internals.c` is standalone and built the same way as `ed25519.c`. It tests the math primitives +with extreme values to ensure they function correctly. SSE2 is now supported. + +#### Papers + +[Available on the Ed25519 website](http://ed25519.cr.yp.to/papers.html) \ No newline at end of file diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c new file mode 100644 index 00000000..2579c60d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c @@ -0,0 +1,545 @@ +/* + Public domain by Andrew M. + See: https://github.com/floodyberry/curve25519-donna + + 32 bit integer curve25519 implementation +*/ + +#include "ed25519-donna.h" + +static const uint32_t reduce_mask_25 = (1 << 25) - 1; +static const uint32_t reduce_mask_26 = (1 << 26) - 1; + +/* out = in */ +void curve25519_copy(bignum25519 out, const bignum25519 in) { + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + out[4] = in[4]; + out[5] = in[5]; + out[6] = in[6]; + out[7] = in[7]; + out[8] = in[8]; + out[9] = in[9]; +} + +/* out = a + b */ +void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + out[9] = a[9] + b[9]; +} + +void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c; + out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c; + out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* multiples of p */ +static const uint32_t twoP0 = 0x07ffffda; +static const uint32_t twoP13579 = 0x03fffffe; +static const uint32_t twoP2468 = 0x07fffffe; +static const uint32_t fourP0 = 0x0fffffb4; +static const uint32_t fourP13579 = 0x07fffffc; +static const uint32_t fourP2468 = 0x0ffffffc; + +/* out = a - b */ +void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c; + out[0] = twoP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = twoP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = twoP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = twoP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = twoP2468 + a[4] - b[4] + c; + out[5] = twoP13579 + a[5] - b[5] ; + out[6] = twoP2468 + a[6] - b[6] ; + out[7] = twoP13579 + a[7] - b[7] ; + out[8] = twoP2468 + a[8] - b[8] ; + out[9] = twoP13579 + a[9] - b[9] ; +} + +/* out = in * scalar */ +void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar) { + uint64_t a; + uint32_t c; + a = mul32x32_64(in[0], scalar); out[0] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); + a = mul32x32_64(in[1], scalar) + c; out[1] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); + a = mul32x32_64(in[2], scalar) + c; out[2] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); + a = mul32x32_64(in[3], scalar) + c; out[3] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); + a = mul32x32_64(in[4], scalar) + c; out[4] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); + a = mul32x32_64(in[5], scalar) + c; out[5] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); + a = mul32x32_64(in[6], scalar) + c; out[6] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); + a = mul32x32_64(in[7], scalar) + c; out[7] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); + a = mul32x32_64(in[8], scalar) + c; out[8] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); + a = mul32x32_64(in[9], scalar) + c; out[9] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); + out[0] += c * 19; +} + +/* out = a - b, where a is the result of a basic op (add,sub) */ +void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c; + out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c; + out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = -a */ +void curve25519_neg(bignum25519 out, const bignum25519 a) { + uint32_t c; + out[0] = twoP0 - a[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; + out[1] = twoP13579 - a[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; + out[2] = twoP2468 - a[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; + out[3] = twoP13579 - a[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; + out[4] = twoP2468 - a[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; + out[5] = twoP13579 - a[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; + out[6] = twoP2468 - a[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; + out[7] = twoP13579 - a[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; + out[8] = twoP2468 - a[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; + out[9] = twoP13579 - a[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = a * b */ +#define curve25519_mul_noinline curve25519_mul +void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + uint32_t s0,s1,s2,s3,s4,s5,s6,s7,s8,s9; + uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + uint32_t p; + + r0 = b[0]; + r1 = b[1]; + r2 = b[2]; + r3 = b[3]; + r4 = b[4]; + r5 = b[5]; + r6 = b[6]; + r7 = b[7]; + r8 = b[8]; + r9 = b[9]; + + s0 = a[0]; + s1 = a[1]; + s2 = a[2]; + s3 = a[3]; + s4 = a[4]; + s5 = a[5]; + s6 = a[6]; + s7 = a[7]; + s8 = a[8]; + s9 = a[9]; + + m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0); + m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0); + m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0); + m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0); + m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0); + + r1 *= 2; + r3 *= 2; + r5 *= 2; + r7 *= 2; + + m0 = mul32x32_64(r0, s0); + m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0); + m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0); + m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0); + m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0); + + r1 *= 19; + r2 *= 19; + r3 = (r3 / 2) * 19; + r4 *= 19; + r5 = (r5 / 2) * 19; + r6 *= 19; + r7 = (r7 / 2) * 19; + r8 *= 19; + r9 *= 19; + + m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9)); + m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9)); + m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9)); + m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9)); + + r3 *= 2; + r5 *= 2; + r7 *= 2; + r9 *= 2; + + m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9)); + m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9)); + m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9)); + m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9)); + m8 += (mul32x32_64(r9, s9)); + + r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); + r1 += p; + + out[0] = r0; + out[1] = r1; + out[2] = r2; + out[3] = r3; + out[4] = r4; + out[5] = r5; + out[6] = r6; + out[7] = r7; + out[8] = r8; + out[9] = r9; +} + +/* out = in * in */ +void curve25519_square(bignum25519 out, const bignum25519 in) { + uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + uint32_t d6,d7,d8,d9; + uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + uint32_t p; + + r0 = in[0]; + r1 = in[1]; + r2 = in[2]; + r3 = in[3]; + r4 = in[4]; + r5 = in[5]; + r6 = in[6]; + r7 = in[7]; + r8 = in[8]; + r9 = in[9]; + + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; + d7 = r7 * 2 * 19; + d8 = r8 * 19; + d9 = r9 * 2 * 19; + + m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); + m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); + m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); + m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); + m7 += (mul32x32_64(d9, r8 )); + m8 += (mul32x32_64(d9, r9 )); + + r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); + r1 += p; + + out[0] = r0; + out[1] = r1; + out[2] = r2; + out[3] = r3; + out[4] = r4; + out[5] = r5; + out[6] = r6; + out[7] = r7; + out[8] = r8; + out[9] = r9; +} + +/* out = in ^ (2 * count) */ +void curve25519_square_times(bignum25519 out, const bignum25519 in, int count) { + uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; + uint32_t d6,d7,d8,d9; + uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; + uint32_t p; + + r0 = in[0]; + r1 = in[1]; + r2 = in[2]; + r3 = in[3]; + r4 = in[4]; + r5 = in[5]; + r6 = in[6]; + r7 = in[7]; + r8 = in[8]; + r9 = in[9]; + + do { + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; + d7 = r7 * 2 * 19; + d8 = r8 * 19; + d9 = r9 * 2 * 19; + + m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); + m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); + m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); + m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); + m7 += (mul32x32_64(d9, r8 )); + m8 += (mul32x32_64(d9, r9 )); + + r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); + m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); + m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); + m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); + m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); + m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); + m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); + m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); + m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); + m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); + m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); + r1 += p; + } while (--count); + + out[0] = r0; + out[1] = r1; + out[2] = r2; + out[3] = r3; + out[4] = r4; + out[5] = r5; + out[6] = r6; + out[7] = r7; + out[8] = r8; + out[9] = r9; +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +void curve25519_expand(bignum25519 out, const unsigned char in[32]) { + const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}}; + uint32_t x0,x1,x2,x3,x4,x5,x6,x7; + if (endian_check.s == 1) { + /* Take care, this only works when in is aligned */ + x0 = *(uint32_t *)(in + 0); + x1 = *(uint32_t *)(in + 4); + x2 = *(uint32_t *)(in + 8); + x3 = *(uint32_t *)(in + 12); + x4 = *(uint32_t *)(in + 16); + x5 = *(uint32_t *)(in + 20); + x6 = *(uint32_t *)(in + 24); + x7 = *(uint32_t *)(in + 28); + } else { + #define F(s) \ + ((((uint32_t)in[s + 0]) ) | \ + (((uint32_t)in[s + 1]) << 8) | \ + (((uint32_t)in[s + 2]) << 16) | \ + (((uint32_t)in[s + 3]) << 24)) + x0 = F(0); + x1 = F(4); + x2 = F(8); + x3 = F(12); + x4 = F(16); + x5 = F(20); + x6 = F(24); + x7 = F(28); + #undef F + } + + out[0] = ( x0 ) & reduce_mask_26; + out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & reduce_mask_25; + out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & reduce_mask_26; + out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & reduce_mask_25; + out[4] = (( x3) >> 6) & reduce_mask_26; + out[5] = ( x4 ) & reduce_mask_25; + out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & reduce_mask_26; + out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & reduce_mask_25; + out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & reduce_mask_26; + out[9] = (( x7) >> 6) & reduce_mask_25; /* ignore the top bit */ +} + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array + */ +void curve25519_contract(unsigned char out[32], const bignum25519 in) { + bignum25519 f; + curve25519_copy(f, in); + + #define carry_pass() \ + f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \ + f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \ + f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \ + f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \ + f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \ + f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \ + f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \ + f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \ + f[9] += f[8] >> 26; f[8] &= reduce_mask_26; + + #define carry_pass_full() \ + carry_pass() \ + f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25; + + #define carry_pass_final() \ + carry_pass() \ + f[9] &= reduce_mask_25; + + carry_pass_full() + carry_pass_full() + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + f[0] += 19; + carry_pass_full() + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + f[0] += (reduce_mask_26 + 1) - 19; + f[1] += (reduce_mask_25 + 1) - 1; + f[2] += (reduce_mask_26 + 1) - 1; + f[3] += (reduce_mask_25 + 1) - 1; + f[4] += (reduce_mask_26 + 1) - 1; + f[5] += (reduce_mask_25 + 1) - 1; + f[6] += (reduce_mask_26 + 1) - 1; + f[7] += (reduce_mask_25 + 1) - 1; + f[8] += (reduce_mask_26 + 1) - 1; + f[9] += (reduce_mask_25 + 1) - 1; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + carry_pass_final() + + #undef carry_pass + #undef carry_full + #undef carry_final + + f[1] <<= 2; + f[2] <<= 3; + f[3] <<= 5; + f[4] <<= 6; + f[6] <<= 1; + f[7] <<= 3; + f[8] <<= 4; + f[9] <<= 6; + + #define F(i, s) \ + out[s+0] |= (unsigned char )(f[i] & 0xff); \ + out[s+1] = (unsigned char )((f[i] >> 8) & 0xff); \ + out[s+2] = (unsigned char )((f[i] >> 16) & 0xff); \ + out[s+3] = (unsigned char )((f[i] >> 24) & 0xff); + + out[0] = 0; + out[16] = 0; + F(0,0); + F(1,3); + F(2,6); + F(3,9); + F(4,12); + F(5,16); + F(6,19); + F(7,22); + F(8,25); + F(9,28); + #undef F +} + +/* if (iswap) swap(a, b) */ +void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap) { + const uint32_t swap = (uint32_t)(-(int32_t)iswap); + uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9; + + x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; + x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; + x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; + x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; + x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; + x5 = swap & (a[5] ^ b[5]); a[5] ^= x5; b[5] ^= x5; + x6 = swap & (a[6] ^ b[6]); a[6] ^= x6; b[6] ^= x6; + x7 = swap & (a[7] ^ b[7]); a[7] ^= x7; b[7] ^= x7; + x8 = swap & (a[8] ^ b[8]); a[8] ^= x8; b[8] ^= x8; + x9 = swap & (a[9] ^ b[9]); a[9] ^= x9; b[9] ^= x9; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.h new file mode 100644 index 00000000..19de6325 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.h @@ -0,0 +1,53 @@ +/* + Public domain by Andrew M. + See: https://github.com/floodyberry/curve25519-donna + + 32 bit integer curve25519 implementation +*/ + +typedef uint32_t bignum25519[10]; + +/* out = in */ +void curve25519_copy(bignum25519 out, const bignum25519 in); + +/* out = a + b */ +void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b); + +void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b); + +void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b); + +/* out = a - b */ +void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b); + +/* out = in * scalar */ +void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar); + +/* out = a - b, where a is the result of a basic op (add,sub) */ +void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b); + +void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b); + +/* out = -a */ +void curve25519_neg(bignum25519 out, const bignum25519 a); + +/* out = a * b */ +#define curve25519_mul_noinline curve25519_mul +void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b); + +/* out = in * in */ +void curve25519_square(bignum25519 out, const bignum25519 in); + +/* out = in ^ (2 * count) */ +void curve25519_square_times(bignum25519 out, const bignum25519 in, int count); + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +void curve25519_expand(bignum25519 out, const unsigned char in[32]); + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array + */ +void curve25519_contract(unsigned char out[32], const bignum25519 in); + +/* if (iswap) swap(a, b) */ +void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap); diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c new file mode 100644 index 00000000..fe926d39 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c @@ -0,0 +1,66 @@ +/* + Public domain by Andrew M. + See: https://github.com/floodyberry/curve25519-donna + + Curve25519 implementation agnostic helpers +*/ + +#include "ed25519-donna.h" + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { + bignum25519 ALIGN(16) t0,c; + + /* 2^5 - 2^0 */ /* b */ + /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); + /* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b); + /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); + /* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b); + /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); + /* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c); + /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); + /* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b); + /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); + /* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b); + /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); + /* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c); + /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); + /* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b); +} + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void curve25519_recip(bignum25519 out, const bignum25519 z) { + bignum25519 ALIGN(16) a,t0,b; + + /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ + /* 8 */ curve25519_square_times(t0, a, 2); + /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */ + /* 22 */ curve25519_square_times(t0, a, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); + /* 2^255 - 21 */ curve25519_mul_noinline(out, b, a); +} + +/* + * z^((p-5)/8) = z^(2^252 - 3) + */ +void curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { + bignum25519 ALIGN(16) b,c,t0; + + /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ + /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ + /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */ + /* 22 */ curve25519_square_times(t0, c, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2); + /* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.h new file mode 100644 index 00000000..62fde909 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.h @@ -0,0 +1,22 @@ +/* + Public domain by Andrew M. + See: https://github.com/floodyberry/curve25519-donna + + Curve25519 implementation agnostic helpers +*/ + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b); + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void curve25519_recip(bignum25519 out, const bignum25519 z); + +/* + * z^((p-5)/8) = z^(2^252 - 3) + */ +void curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z); diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c new file mode 100644 index 00000000..6feacb37 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c @@ -0,0 +1,67 @@ +#include "ed25519-donna.h" +#include "ed25519.h" + +/* Calculates nQ where Q is the x-coordinate of a point on the curve + * + * mypublic: the packed little endian x coordinate of the resulting curve point + * n: a little endian, 32-byte number + * basepoint: a packed little endian point of the curve + */ + +void curve25519_scalarmult_donna(curve25519_key mypublic, const curve25519_key n, const curve25519_key basepoint) { + bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx; + bignum25519 q, qx, qpqx, qqx, zzz, zmone; + size_t bit, lastbit; + int32_t i; + + curve25519_expand(q, basepoint); + curve25519_copy(nqx, q); + + /* bit 255 is always 0, and bit 254 is always 1, so skip bit 255 and + start pre-swapped on bit 254 */ + lastbit = 1; + + /* we are doing bits 254..3 in the loop, but are swapping in bits 253..2 */ + for (i = 253; i >= 2; i--) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_add(qpqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_mul(nqpqx, qpqx, nqz); + curve25519_mul(nqpqz, qx, nqpqz); + curve25519_add(qqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_square(nqpqz, nqpqz); + curve25519_square(nqpqx, qqx); + curve25519_mul(nqpqz, nqpqz, q); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + + bit = (n[i/8] >> (i & 7)) & 1; + curve25519_swap_conditional(nqx, nqpqx, bit ^ lastbit); + curve25519_swap_conditional(nqz, nqpqz, bit ^ lastbit); + lastbit = bit; + } + + /* the final 3 bits are always zero, so we only need to double */ + for (i = 0; i < 3; i++) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + } + + curve25519_recip(zmone, nqz); + curve25519_mul(nqz, nqx, zmone); + curve25519_contract(mypublic, nqz); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.h new file mode 100644 index 00000000..9f3d7989 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.h @@ -0,0 +1,8 @@ +/* Calculates nQ where Q is the x-coordinate of a point on the curve + * + * mypublic: the packed little endian x coordinate of the resulting curve point + * n: a little endian, 32-byte number + * basepoint: a packed little endian point of the curve + */ + +void curve25519_scalarmult_donna(curve25519_key mypublic, const curve25519_key n, const curve25519_key basepoint); diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.c new file mode 100644 index 00000000..fd2236b0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.c @@ -0,0 +1,63 @@ +#include "ed25519-donna.h" + +const ge25519 ALIGN(16) ge25519_basepoint = { + {0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db}, + {0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999}, + {0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000}, + {0x01b7dda3,0x01a2ace9,0x025eadbb,0x0003ba8a,0x0083c27e,0x00abe37d,0x01274732,0x00ccacdd,0x00fd78b7,0x019e1d7c} +}; + +/* + d +*/ + +const bignum25519 ALIGN(16) ge25519_ecd = { + 0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3 +}; + +const bignum25519 ALIGN(16) ge25519_ec2d = { + 0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67 +}; + +/* + sqrt(-1) +*/ + +const bignum25519 ALIGN(16) ge25519_sqrtneg1 = { + 0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92 +}; + +const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = { + {{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}}, + {{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}}, + {{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}}, + {{0x023221b1,0x01cb26aa,0x0074f74d,0x0099ddd1,0x01b28085,0x00192c3a,0x013b27c9,0x00fc13bd,0x01d2e531,0x0075bb75},{0x004ea3bf,0x00973425,0x001a4d63,0x01d59cee,0x01d1c0d4,0x00542e49,0x01294114,0x004fce36,0x029283c9,0x01186fa9},{0x01b8b3a2,0x00db7200,0x00935e30,0x003829f5,0x02cc0d7d,0x0077adf3,0x0220dd2c,0x0014ea53,0x01c6a0f9,0x01ea7eec}}, + {{0x039d8064,0x01885f80,0x00337e6d,0x01b7a902,0x02628206,0x015eb044,0x01e30473,0x0191f2d9,0x011fadc9,0x01270169},{0x02a8632f,0x0199e2a9,0x00d8b365,0x017a8de2,0x02994279,0x0086f5b5,0x0119e4e3,0x01eb39d6,0x0338add7,0x00d2e7b4},{0x0045af1b,0x013a2fe4,0x0245e0d6,0x014538ce,0x038bfe0f,0x01d4cf16,0x037e14c9,0x0160d55e,0x0021b008,0x01cf05c8}}, + {{0x01864348,0x01d6c092,0x0070262b,0x014bb844,0x00fb5acd,0x008deb95,0x003aaab5,0x00eff474,0x00029d5c,0x0062ad66},{0x02802ade,0x01c02122,0x01c4e5f7,0x00781181,0x039767fb,0x01703406,0x0342388b,0x01f5e227,0x022546d8,0x0109d6ab},{0x016089e9,0x00cb317f,0x00949b05,0x01099417,0x000c7ad2,0x011a8622,0x0088ccda,0x01290886,0x022b53df,0x00f71954}}, + {{0x027fbf93,0x01c04ecc,0x01ed6a0d,0x004cdbbb,0x02bbf3af,0x00ad5968,0x01591955,0x0094f3a2,0x02d17602,0x00099e20},{0x02007f6d,0x003088a8,0x03db77ee,0x00d5ade6,0x02fe12ce,0x0107ba07,0x0107097d,0x00482a6f,0x02ec346f,0x008d3f5f},{0x032ea378,0x0028465c,0x028e2a6c,0x018efc6e,0x0090df9a,0x01a7e533,0x039bfc48,0x010c745d,0x03daa097,0x0125ee9b}}, + {{0x028ccf0b,0x00f36191,0x021ac081,0x012154c8,0x034e0a6e,0x01b25192,0x00180403,0x01d7eea1,0x00218d05,0x010ed735},{0x03cfeaa0,0x01b300c4,0x008da499,0x0068c4e1,0x0219230a,0x01f2d4d0,0x02defd60,0x00e565b7,0x017f12de,0x018788a4},{0x03d0b516,0x009d8be6,0x03ddcbb3,0x0071b9fe,0x03ace2bd,0x01d64270,0x032d3ec9,0x01084065,0x0210ae4d,0x01447584}}, + {{0x0020de87,0x00e19211,0x01b68102,0x00b5ac97,0x022873c0,0x01942d25,0x01271394,0x0102073f,0x02fe2482,0x01c69ff9},{0x010e9d81,0x019dbbe5,0x0089f258,0x006e06b8,0x02951883,0x018f1248,0x019b3237,0x00bc7553,0x024ddb85,0x01b4c964},{0x01c8c854,0x0060ae29,0x01406d8e,0x01cff2f9,0x00cff451,0x01778d0c,0x03ac8c41,0x01552e59,0x036559ee,0x011d1b12}}, + {{0x00741147,0x0151b219,0x01092690,0x00e877e6,0x01f4d6bb,0x0072a332,0x01cd3b03,0x00dadff2,0x0097db5e,0x0086598d},{0x01c69a2b,0x01decf1b,0x02c2fa6e,0x013b7c4f,0x037beac8,0x013a16b5,0x028e7bda,0x01f6e8ac,0x01e34fe9,0x01726947},{0x01f10e67,0x003c73de,0x022b7ea2,0x010f32c2,0x03ff776a,0x00142277,0x01d38b88,0x00776138,0x03c60822,0x01201140}}, + {{0x0236d175,0x0008748e,0x03c6476d,0x013f4cdc,0x02eed02a,0x00838a47,0x032e7210,0x018bcbb3,0x00858de4,0x01dc7826},{0x00a37fc7,0x0127b40b,0x01957884,0x011d30ad,0x02816683,0x016e0e23,0x00b76be4,0x012db115,0x02516506,0x0154ce62},{0x00451edf,0x00bd749e,0x03997342,0x01cc2c4c,0x00eb6975,0x01a59508,0x03a516cf,0x00c228ef,0x0168ff5a,0x01697b47}}, + {{0x00527359,0x01783156,0x03afd75c,0x00ce56dc,0x00e4b970,0x001cabe9,0x029e0f6d,0x0188850c,0x0135fefd,0x00066d80},{0x02150e83,0x01448abf,0x02bb0232,0x012bf259,0x033c8268,0x00711e20,0x03fc148f,0x005e0e70,0x017d8bf9,0x0112b2e2},{0x02134b83,0x001a0517,0x0182c3cc,0x00792182,0x0313d799,0x001a3ed7,0x0344547e,0x01f24a0d,0x03de6ad2,0x00543127}}, + {{0x00dca868,0x00618f27,0x015a1709,0x00ddc38a,0x0320fd13,0x0036168d,0x0371ab06,0x01783fc7,0x0391e05f,0x01e29b5d},{0x01471138,0x00fca542,0x00ca31cf,0x01ca7bad,0x0175bfbc,0x01a708ad,0x03bce212,0x01244215,0x0075bb99,0x01acad68},{0x03a0b976,0x01dc12d1,0x011aab17,0x00aba0ba,0x029806cd,0x0142f590,0x018fd8ea,0x01a01545,0x03c4ad55,0x01c971ff}}, + {{0x00d098c0,0x000afdc7,0x006cd230,0x01276af3,0x03f905b2,0x0102994c,0x002eb8a4,0x015cfbeb,0x025f855f,0x01335518},{0x01cf99b2,0x0099c574,0x01a69c88,0x00881510,0x01cd4b54,0x0112109f,0x008abdc5,0x0074647a,0x0277cb1f,0x01e53324},{0x02ac5053,0x01b109b0,0x024b095e,0x016997b3,0x02f26bb6,0x00311021,0x00197885,0x01d0a55a,0x03b6fcc8,0x01c020d5}}, + {{0x02584a34,0x00e7eee0,0x03257a03,0x011e95a3,0x011ead91,0x00536202,0x00b1ce24,0x008516c6,0x03669d6d,0x004ea4a8},{0x00773f01,0x0019c9ce,0x019f6171,0x01d4afde,0x02e33323,0x01ad29b6,0x02ead1dc,0x01ed51a5,0x01851ad0,0x001bbdfa},{0x00577de5,0x00ddc730,0x038b9952,0x00f281ae,0x01d50390,0x0002e071,0x000780ec,0x010d448d,0x01f8a2af,0x00f0a5b7}}, + {{0x031f2541,0x00d34bae,0x0323ff9d,0x003a056d,0x02e25443,0x00a1ad05,0x00d1bee8,0x002f7f8e,0x03007477,0x002a24b1},{0x0114a713,0x01457e76,0x032255d5,0x01cc647f,0x02a4bdef,0x0153d730,0x00118bcf,0x00f755ff,0x013490c7,0x01ea674e},{0x02bda3e8,0x00bb490d,0x00f291ea,0x000abf40,0x01dea321,0x002f9ce0,0x00b2b193,0x00fa54b5,0x0128302f,0x00a19d8b}}, + {{0x022ef5bd,0x01638af3,0x038c6f8a,0x01a33a3d,0x039261b2,0x01bb89b8,0x010bcf9d,0x00cf42a9,0x023d6f17,0x01da1bca},{0x00e35b25,0x000d824f,0x0152e9cf,0x00ed935d,0x020b8460,0x01c7b83f,0x00c969e5,0x01a74198,0x0046a9d9,0x00cbc768},{0x01597c6a,0x0144a99b,0x00a57551,0x0018269c,0x023c464c,0x0009b022,0x00ee39e1,0x0114c7f2,0x038a9ad2,0x01584c17}}, + {{0x03b0c0d5,0x00b30a39,0x038a6ce4,0x01ded83a,0x01c277a6,0x01010a61,0x0346d3eb,0x018d995e,0x02f2c57c,0x000c286b},{0x0092aed1,0x0125e37b,0x027ca201,0x001a6b6b,0x03290f55,0x0047ba48,0x018d916c,0x01a59062,0x013e35d4,0x0002abb1},{0x003ad2aa,0x007ddcc0,0x00c10f76,0x0001590b,0x002cfca6,0x000ed23e,0x00ee4329,0x00900f04,0x01c24065,0x0082fa70}}, + {{0x02025e60,0x003912b8,0x0327041c,0x017e5ee5,0x02c0ecec,0x015a0d1c,0x02b1ce7c,0x0062220b,0x0145067e,0x01a5d931},{0x009673a6,0x00e1f609,0x00927c2a,0x016faa37,0x01650ef0,0x016f63b5,0x03cd40e1,0x003bc38f,0x0361f0ac,0x01d42acc},{0x02f81037,0x008ca0e8,0x017e23d1,0x011debfe,0x01bcbb68,0x002e2563,0x03e8add6,0x000816e5,0x03fb7075,0x0153e5ac}}, + {{0x02b11ecd,0x016bf185,0x008f22ef,0x00e7d2bb,0x0225d92e,0x00ece785,0x00508873,0x017e16f5,0x01fbe85d,0x01e39a0e},{0x01669279,0x017c810a,0x024941f5,0x0023ebeb,0x00eb7688,0x005760f1,0x02ca4146,0x0073cde7,0x0052bb75,0x00f5ffa7},{0x03b8856b,0x00cb7dcd,0x02f14e06,0x001820d0,0x01d74175,0x00e59e22,0x03fba550,0x00484641,0x03350088,0x01c3c9a3}}, + {{0x00dcf355,0x0104481c,0x0022e464,0x01f73fe7,0x00e03325,0x0152b698,0x02ef769a,0x00973663,0x00039b8c,0x0101395b},{0x01805f47,0x019160ec,0x03832cd0,0x008b06eb,0x03d4d717,0x004cb006,0x03a75b8f,0x013b3d30,0x01cfad88,0x01f034d1},{0x0078338a,0x01c7d2e3,0x02bc2b23,0x018b3f05,0x0280d9aa,0x005f3d44,0x0220a95a,0x00eeeb97,0x0362aaec,0x00835d51}}, + {{0x01b9f543,0x013fac4d,0x02ad93ae,0x018ef464,0x0212cdf7,0x01138ba9,0x011583ab,0x019c3d26,0x028790b4,0x00e2e2b6},{0x033bb758,0x01f0dbf1,0x03734bd1,0x0129b1e5,0x02b3950e,0x003bc922,0x01a53ec8,0x018c5532,0x006f3cee,0x00ae3c79},{0x0351f95d,0x0012a737,0x03d596b8,0x017658fe,0x00ace54a,0x008b66da,0x0036c599,0x012a63a2,0x032ceba1,0x00126bac}}, + {{0x03dcfe7e,0x019f4f18,0x01c81aee,0x0044bc2b,0x00827165,0x014f7c13,0x03b430f0,0x00bf96cc,0x020c8d62,0x01471997},{0x01fc7931,0x001f42dd,0x00ba754a,0x005bd339,0x003fbe49,0x016b3930,0x012a159c,0x009f83b0,0x03530f67,0x01e57b85},{0x02ecbd81,0x0096c294,0x01fce4a9,0x017701a5,0x0175047d,0x00ee4a31,0x012686e5,0x008efcd4,0x0349dc54,0x01b3466f}}, + {{0x02179ca3,0x01d86414,0x03f0afd0,0x00305964,0x015c7428,0x0099711e,0x015d5442,0x00c71014,0x01b40b2e,0x01d483cf},{0x01afc386,0x01984859,0x036203ff,0x0045c6a8,0x0020a8aa,0x00990baa,0x03313f10,0x007ceede,0x027429e4,0x017806ce},{0x039357a1,0x0142f8f4,0x0294a7b6,0x00eaccf4,0x0259edb3,0x01311e6e,0x004d326f,0x0130c346,0x01ccef3c,0x01c424b2}}, + {{0x0364918c,0x00148fc0,0x01638a7b,0x01a1fd5b,0x028ad013,0x0081e5a4,0x01a54f33,0x0174e101,0x003d0257,0x003a856c},{0x00051dcf,0x00f62b1d,0x0143d0ad,0x0042adbd,0x000fda90,0x01743ceb,0x0173e5e4,0x017bc749,0x03b7137a,0x0105ce96},{0x00f9218a,0x015b8c7c,0x00e102f8,0x0158d7e2,0x0169a5b8,0x00b2f176,0x018b347a,0x014cfef2,0x0214a4e3,0x017f1595}}, + {{0x006d7ae5,0x0195c371,0x0391e26d,0x0062a7c6,0x003f42ab,0x010dad86,0x024f8198,0x01542b2a,0x0014c454,0x0189c471},{0x0390988e,0x00b8799d,0x02e44912,0x0078e2e6,0x00075654,0x01923eed,0x0040cd72,0x00a37c76,0x0009d466,0x00c8531d},{0x02651770,0x00609d01,0x0286c265,0x0134513c,0x00ee9281,0x005d223c,0x035c760c,0x00679b36,0x0073ecb8,0x016faa50}}, + {{0x02c89be4,0x016fc244,0x02f38c83,0x018beb72,0x02b3ce2c,0x0097b065,0x034f017b,0x01dd957f,0x00148f61,0x00eab357},{0x0343d2f8,0x003398fc,0x011e368e,0x00782a1f,0x00019eea,0x00117b6f,0x0128d0d1,0x01a5e6bb,0x01944f1b,0x012b41e1},{0x03318301,0x018ecd30,0x0104d0b1,0x0038398b,0x03726701,0x019da88c,0x002d9769,0x00a7a681,0x031d9028,0x00ebfc32}}, + {{0x0220405e,0x0171face,0x02d930f8,0x017f6d6a,0x023b8c47,0x0129d5f9,0x02972456,0x00a3a524,0x006f4cd2,0x004439fa},{0x00c53505,0x0190c2fd,0x00507244,0x009930f9,0x01a39270,0x01d327c6,0x0399bc47,0x01cfe13d,0x0332bd99,0x00b33e7d},{0x0203f5e4,0x003627b5,0x00018af8,0x01478581,0x004a2218,0x002e3bb7,0x039384d0,0x0146ea62,0x020b9693,0x0017155f}}, + {{0x03c97e6f,0x00738c47,0x03b5db1f,0x01808fcf,0x01e8fc98,0x01ed25dd,0x01bf5045,0x00eb5c2b,0x0178fe98,0x01b85530},{0x01c20eb0,0x01aeec22,0x030b9eee,0x01b7d07e,0x0187e16f,0x014421fb,0x009fa731,0x0040b6d7,0x00841861,0x00a27fbc},{0x02d69abf,0x0058cdbf,0x0129f9ec,0x013c19ae,0x026c5b93,0x013a7fe7,0x004bb2ba,0x0063226f,0x002a95ca,0x01abefd9}}, + {{0x02f5d2c1,0x00378318,0x03734fb5,0x01258073,0x0263f0f6,0x01ad70e0,0x01b56d06,0x01188fbd,0x011b9503,0x0036d2e1},{0x0113a8cc,0x01541c3e,0x02ac2bbc,0x01d95867,0x01f47459,0x00ead489,0x00ab5b48,0x01db3b45,0x00edb801,0x004b024f},{0x00b8190f,0x011fe4c2,0x00621f82,0x010508d7,0x001a5a76,0x00c7d7fd,0x03aab96d,0x019cd9dc,0x019c6635,0x00ceaa1e}}, + {{0x01085cf2,0x01fd47af,0x03e3f5e1,0x004b3e99,0x01e3d46a,0x0060033c,0x015ff0a8,0x0150cdd8,0x029e8e21,0x008cf1bc},{0x00156cb1,0x003d623f,0x01a4f069,0x00d8d053,0x01b68aea,0x01ca5ab6,0x0316ae43,0x0134dc44,0x001c8d58,0x0084b343},{0x0318c781,0x0135441f,0x03a51a5e,0x019293f4,0x0048bb37,0x013d3341,0x0143151e,0x019c74e1,0x00911914,0x0076ddde}}, + {{0x006bc26f,0x00d48e5f,0x00227bbe,0x00629ea8,0x01ea5f8b,0x0179a330,0x027a1d5f,0x01bf8f8e,0x02d26e2a,0x00c6b65e},{0x01701ab6,0x0051da77,0x01b4b667,0x00a0ce7c,0x038ae37b,0x012ac852,0x03a0b0fe,0x0097c2bb,0x00a017d2,0x01eb8b2a},{0x0120b962,0x0005fb42,0x0353b6fd,0x0061f8ce,0x007a1463,0x01560a64,0x00e0a792,0x01907c92,0x013a6622,0x007b47f1}} +}; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.h new file mode 100644 index 00000000..f76a832c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.h @@ -0,0 +1,17 @@ +extern const ge25519 ALIGN(16) ge25519_basepoint; + +/* + d +*/ + +extern const bignum25519 ALIGN(16) ge25519_ecd; + +extern const bignum25519 ALIGN(16) ge25519_ec2d; + +/* + sqrt(-1) +*/ + +extern const bignum25519 ALIGN(16) ge25519_sqrtneg1; + +extern const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32]; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.c new file mode 100644 index 00000000..cd5d1872 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.c @@ -0,0 +1,261 @@ +#include "ed25519-donna.h" + +/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ +const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = { + {0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f}, + {0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49}, + {0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54}, + {0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44}, + {0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68}, + {0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78}, + {0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23}, + {0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58}, + {0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10}, + {0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56}, + {0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14}, + {0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37}, + {0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02}, + {0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12}, + {0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f}, + {0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41}, + {0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e}, + {0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14}, + {0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41}, + {0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59}, + {0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49}, + {0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20}, + {0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b}, + {0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74}, + {0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69}, + {0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b}, + {0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e}, + {0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39}, + {0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33}, + {0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61}, + {0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45}, + {0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d}, + {0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c}, + {0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21}, + {0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a}, + {0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39}, + {0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22}, + {0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50}, + {0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d}, + {0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45}, + {0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d}, + {0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c}, + {0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27}, + {0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f}, + {0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f}, + {0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22}, + {0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c}, + {0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19}, + {0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71}, + {0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c}, + {0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a}, + {0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02}, + {0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31}, + {0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48}, + {0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c}, + {0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f}, + {0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60}, + {0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63}, + {0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70}, + {0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41}, + {0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24}, + {0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16}, + {0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78}, + {0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13}, + {0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a}, + {0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b}, + {0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d}, + {0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74}, + {0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58}, + {0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12}, + {0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d}, + {0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b}, + {0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c}, + {0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04}, + {0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76}, + {0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11}, + {0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f}, + {0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55}, + {0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57}, + {0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21}, + {0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a}, + {0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19}, + {0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60}, + {0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36}, + {0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07}, + {0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57}, + {0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05}, + {0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f}, + {0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72}, + {0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00}, + {0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c}, + {0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06}, + {0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15}, + {0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07}, + {0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51}, + {0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77}, + {0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e}, + {0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09}, + {0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56}, + {0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43}, + {0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27}, + {0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b}, + {0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46}, + {0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69}, + {0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14}, + {0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55}, + {0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13}, + {0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d}, + {0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31}, + {0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05}, + {0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f}, + {0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a}, + {0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10}, + {0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25}, + {0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08}, + {0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a}, + {0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f}, + {0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38}, + {0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65}, + {0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c}, + {0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e}, + {0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35}, + {0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47}, + {0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47}, + {0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74}, + {0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a}, + {0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56}, + {0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d}, + {0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44}, + {0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58}, + {0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70}, + {0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e}, + {0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41}, + {0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11}, + {0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f}, + {0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10}, + {0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72}, + {0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00}, + {0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05}, + {0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00}, + {0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b}, + {0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05}, + {0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f}, + {0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f}, + {0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40}, + {0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b}, + {0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02}, + {0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c}, + {0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f}, + {0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29}, + {0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71}, + {0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a}, + {0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06}, + {0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30}, + {0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b}, + {0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24}, + {0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49}, + {0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53}, + {0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02}, + {0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e}, + {0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d}, + {0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f}, + {0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07}, + {0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f}, + {0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b}, + {0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f}, + {0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12}, + {0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30}, + {0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45}, + {0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a}, + {0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13}, + {0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f}, + {0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a}, + {0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12}, + {0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b}, + {0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10}, + {0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b}, + {0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e}, + {0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f}, + {0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00}, + {0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33}, + {0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63}, + {0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b}, + {0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16}, + {0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57}, + {0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e}, + {0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73}, + {0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76}, + {0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e}, + {0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16}, + {0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45}, + {0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67}, + {0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a}, + {0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a}, + {0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e}, + {0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62}, + {0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e}, + {0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e}, + {0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78}, + {0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46}, + {0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a}, + {0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26}, + {0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b}, + {0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d}, + {0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45}, + {0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26}, + {0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62}, + {0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d}, + {0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61}, + {0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79}, + {0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39}, + {0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63}, + {0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34}, + {0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56}, + {0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e}, + {0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26}, + {0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f}, + {0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f}, + {0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b}, + {0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39}, + {0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51}, + {0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f}, + {0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f}, + {0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13}, + {0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c}, + {0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60}, + {0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15}, + {0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32}, + {0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b}, + {0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02}, + {0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c}, + {0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05}, + {0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67}, + {0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c}, + {0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37}, + {0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63}, + {0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68}, + {0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c}, + {0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c}, + {0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26}, + {0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08}, + {0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19}, + {0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41}, + {0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b}, + {0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08}, + {0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48}, + {0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54}, + {0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c}, + {0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f}, + {0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25}, + {0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55}, + {0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a}, + {0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59}, + {0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70}, + {0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27}, + {0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f} +}; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.h new file mode 100644 index 00000000..9c0cdfc0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.h @@ -0,0 +1,2 @@ +/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ +extern const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96]; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.c new file mode 100644 index 00000000..28ac7581 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.c @@ -0,0 +1,454 @@ +#include "ed25519-donna.h" + +/* + Timing safe memory compare +*/ +int ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) { + size_t differentbits = 0; + while (len--) + differentbits |= (*x++ ^ *y++); + return (int) (1 & ((differentbits - 1) >> 8)); +} + +/* + conversions +*/ + +void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); +} + +void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); + curve25519_mul(r->t, p->x, p->y); +} + +void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) { + curve25519_sub(p->ysubx, r->y, r->x); + curve25519_add(p->xaddy, r->y, r->x); + curve25519_copy(p->z, r->z); + curve25519_mul(p->t2d, r->t, ge25519_ec2d); +} + +/* + adding & doubling +*/ + +void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) { + bignum25519 a,b,c; + + curve25519_square(a, p->x); + curve25519_square(b, p->y); + curve25519_square(c, p->z); + curve25519_add_reduce(c, c, c); + curve25519_add(r->x, p->x, p->y); + curve25519_square(r->x, r->x); + curve25519_add(r->y, b, a); + curve25519_sub(r->z, b, a); + curve25519_sub_after_basic(r->x, r->x, r->y); + curve25519_sub_after_basic(r->t, c, r->z); +} + +#ifndef ED25519_NO_PRECOMP +void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) { + const bignum25519 *qb = (const bignum25519 *)q; + bignum25519 *rb = (bignum25519 *)r; + bignum25519 a,b,c; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */ + curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_add_reduce(r->t, p->z, p->z); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ +} +#endif + +void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) { + const bignum25519 *qb = (const bignum25519 *)q; + bignum25519 *rb = (bignum25519 *)r; + bignum25519 a,b,c; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */ + curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(r->t, p->z, q->z); + curve25519_add_reduce(r->t, r->t, r->t); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ +} + +void ge25519_double_partial(ge25519 *r, const ge25519 *p) { + ge25519_p1p1 t; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_partial(r, &t); +} + +void ge25519_double(ge25519 *r, const ge25519 *p) { + ge25519_p1p1 t; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_full(r, &t); +} + +void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) { + bignum25519 a,b,c,e,f,g,h; + + curve25519_sub(a, r->y, r->x); + curve25519_add(b, r->y, r->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(e, b, q->xaddy); + curve25519_add(h, e, a); + curve25519_sub(e, e, a); + curve25519_mul(c, r->t, q->t2d); + curve25519_add(f, r->z, r->z); + curve25519_add_after_basic(g, f, c); + curve25519_sub_after_basic(f, f, c); + curve25519_mul(r->x, e, f); + curve25519_mul(r->y, h, g); + curve25519_mul(r->z, g, f); + curve25519_mul(r->t, e, h); +} + +void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) { + bignum25519 a,b,c,x,y,z,t; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(x, b, q->xaddy); + curve25519_add(y, x, a); + curve25519_sub(x, x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(t, p->z, q->z); + curve25519_add(t, t, t); + curve25519_add_after_basic(z, t, c); + curve25519_sub_after_basic(t, t, c); + curve25519_mul(r->xaddy, x, t); + curve25519_mul(r->ysubx, y, z); + curve25519_mul(r->z, z, t); + curve25519_mul(r->t2d, x, y); + curve25519_copy(y, r->ysubx); + curve25519_sub(r->ysubx, r->ysubx, r->xaddy); + curve25519_add(r->xaddy, r->xaddy, y); + curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); +} + + +/* + pack & unpack +*/ + +void ge25519_pack(unsigned char r[32], const ge25519 *p) { + bignum25519 tx, ty, zi; + unsigned char parity[32]; + curve25519_recip(zi, p->z); + curve25519_mul(tx, p->x, zi); + curve25519_mul(ty, p->y, zi); + curve25519_contract(r, ty); + curve25519_contract(parity, tx); + r[31] ^= ((parity[0] & 1) << 7); +} + +int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) { + const unsigned char zero[32] = {0}; + const bignum25519 one = {1}; + unsigned char parity = p[31] >> 7; + unsigned char check[32]; + bignum25519 t, root, num, den, d3; + + curve25519_expand(r->y, p); + curve25519_copy(r->z, one); + curve25519_square(num, r->y); /* x = y^2 */ + curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */ + curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */ + curve25519_add(den, den, r->z); /* den = dy^2 + 1 */ + + /* Computation of sqrt(num/den) */ + /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ + curve25519_square(t, den); + curve25519_mul(d3, t, den); + curve25519_square(r->x, d3); + curve25519_mul(r->x, r->x, den); + curve25519_mul(r->x, r->x, num); + curve25519_pow_two252m3(r->x, r->x); + + /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */ + curve25519_mul(r->x, r->x, d3); + curve25519_mul(r->x, r->x, num); + + /* 3. Check if either of the roots works: */ + curve25519_square(t, r->x); + curve25519_mul(t, t, den); + curve25519_sub_reduce(root, t, num); + curve25519_contract(check, root); + if (!ed25519_verify(check, zero, 32)) { + curve25519_add_reduce(t, t, num); + curve25519_contract(check, t); + if (!ed25519_verify(check, zero, 32)) + return 0; + curve25519_mul(r->x, r->x, ge25519_sqrtneg1); + } + + curve25519_contract(check, r->x); + if ((check[0] & 1) == parity) { + curve25519_copy(t, r->x); + curve25519_neg(r->x, t); + } + curve25519_mul(r->t, r->x, r->y); + return 1; +} + +/* + scalarmults +*/ + +void ge25519_set_neutral(ge25519 *r) +{ + memset(r, 0, sizeof(ge25519)); + r->y[0] = 1; + r->z[0] = 1; +} + +#define S1_SWINDOWSIZE 5 +#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2)) +#ifdef ED25519_NO_PRECOMP +#define S2_SWINDOWSIZE 5 +#else +#define S2_SWINDOWSIZE 7 +#endif +#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2)) + +/* computes [s1]p1 + [s2]base */ +void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) { + signed char slide1[256], slide2[256]; + ge25519_pniels pre1[S1_TABLE_SIZE]; +#ifdef ED25519_NO_PRECOMP + ge25519_pniels pre2[S2_TABLE_SIZE]; +#endif + ge25519 dp; + ge25519_p1p1 t; + int32_t i; + + contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); + contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE); + + ge25519_double(&dp, p1); + ge25519_full_to_pniels(pre1, p1); + for (i = 0; i < S1_TABLE_SIZE - 1; i++) + ge25519_pnielsadd(&pre1[i+1], &dp, &pre1[i]); + +#ifdef ED25519_NO_PRECOMP + ge25519_double(&dp, &ge25519_basepoint); + ge25519_full_to_pniels(pre2, &ge25519_basepoint); + for (i = 0; i < S2_TABLE_SIZE - 1; i++) + ge25519_pnielsadd(&pre2[i+1], &dp, &pre2[i]); +#endif + + ge25519_set_neutral(r); + + i = 255; + while ((i >= 0) && !(slide1[i] | slide2[i])) + i--; + + for (; i >= 0; i--) { + ge25519_double_p1p1(&t, r); + + if (slide1[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); + } + + if (slide2[i]) { + ge25519_p1p1_to_full(r, &t); +#ifdef ED25519_NO_PRECOMP + ge25519_pnielsadd_p1p1(&t, r, &pre2[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); +#else + ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); +#endif + } + + ge25519_p1p1_to_partial(r, &t); + } +} + +/* + * The following conditional move stuff uses conditional moves. + * I will check on which compilers this works, and provide suitable + * workarounds for those where it doesn't. + * + * This works on gcc 4.x and above with -O3. Don't use -O2, this will + * cause the code to not generate conditional moves. Don't use any -march= + * with less than i686 on x86 + */ +static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int stride) { + long x0=r[0], x1=r[1], x2=r[2], x3=r[3], y0, y1, y2, y3; + for(; p= 0; i--) { + int k=abs(slide1[i]); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_p1p1(&t, r); + ge25519_move_conditional_pniels_array(&pre, pre1, k, 9); + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1(&t, r, &pre, (unsigned char)slide1[i] >> 7); + ge25519_p1p1_to_partial(r, &t); + } +} + +void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { + bignum25519 neg; + uint32_t sign = (uint32_t)((unsigned char)b >> 7); + uint32_t mask = ~(sign - 1); + uint32_t u = (b + mask) ^ mask; + + /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */ + uint8_t packed[96] = {0}; + packed[0] = 1; + packed[32] = 1; + + ge25519_move_conditional_niels_array((ge25519_niels *)packed, &table[pos*8], u-1, 8); + + /* expand in to t */ + curve25519_expand(t->ysubx, packed + 0); + curve25519_expand(t->xaddy, packed + 32); + curve25519_expand(t->t2d , packed + 64); + + /* adjust for sign */ + curve25519_swap_conditional(t->ysubx, t->xaddy, sign); + curve25519_neg(neg, t->t2d); + curve25519_swap_conditional(t->t2d, neg, sign); +} + +/* computes [s]basepoint */ +void ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s) { + signed char b[64]; + uint32_t i; + ge25519_niels t; + + contract256_window4_modm(b, s); + + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); + curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); + curve25519_add_reduce(r->y, t.xaddy, t.ysubx); + memset(r->z, 0, sizeof(bignum25519)); + curve25519_copy(r->t, t.t2d); + r->z[0] = 2; + for (i = 3; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double(r, r); + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); + curve25519_mul(t.t2d, t.t2d, ge25519_ecd); + ge25519_nielsadd2(r, &t); + for(i = 2; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.h new file mode 100644 index 00000000..559c837d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.h @@ -0,0 +1,60 @@ +/* + Timing safe memory compare +*/ +int ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len); + +/* + conversions +*/ + +void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p); + +void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p); + +void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r); + +/* + adding & doubling +*/ + +void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p); + +#ifndef ED25519_NO_PRECOMP +void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit); +#endif + +void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit); + +void ge25519_double_partial(ge25519 *r, const ge25519 *p); + +void ge25519_double(ge25519 *r, const ge25519 *p); + +void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q); + +void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q); + + +/* + pack & unpack +*/ + +void ge25519_pack(unsigned char r[32], const ge25519 *p); + +int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]); + +/* + scalarmults +*/ + +void ge25519_set_neutral(ge25519 *r); + +/* computes [s1]p1 + [s2]base */ +void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2); + +/* computes [s1]p1, constant time */ +void ge25519_scalarmult(ge25519 *r, const ge25519 *p1, const bignum256modm s1); + +void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b); + +/* computes [s]basepoint */ +void ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s); diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-portable.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-portable.h new file mode 100644 index 00000000..2fa0ac56 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna-portable.h @@ -0,0 +1,26 @@ +#define mul32x32_64(a,b) (((uint64_t)(a))*(b)) + +#include +#include +#include + +#define DONNA_INLINE +#undef ALIGN +#define ALIGN(x) __attribute__((aligned(x))) +#define ROTL32(a,b) (((a) << (b)) | ((a) >> (32 - b))) +#define ROTR32(a,b) (((a) >> (b)) | ((a) << (32 - b))) + +static inline void U32TO8_LE(unsigned char *p, const uint32_t v) { + p[0] = (unsigned char)(v ); + p[1] = (unsigned char)(v >> 8); + p[2] = (unsigned char)(v >> 16); + p[3] = (unsigned char)(v >> 24); +} + +static inline uint32_t U8TO32_LE(const unsigned char *p) { + return + (((uint32_t)(p[0]) ) | + ((uint32_t)(p[1]) << 8) | + ((uint32_t)(p[2]) << 16) | + ((uint32_t)(p[3]) << 24)); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna.h new file mode 100644 index 00000000..1cf3186e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-donna.h @@ -0,0 +1,47 @@ +/* + Public domain by Andrew M. + Modified from the amd64-51-30k implementation by + Daniel J. Bernstein + Niels Duif + Tanja Lange + Peter Schwabe + Bo-Yin Yang +*/ + +#include "ed25519-donna-portable.h" + +#include "curve25519-donna-32bit.h" + +#include "curve25519-donna-helpers.h" + +#include "modm-donna-32bit.h" + +typedef unsigned char hash_512bits[64]; + +/* + * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2 + * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555 + * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960); + */ + +typedef struct ge25519_t { + bignum25519 x, y, z, t; +} ge25519; + +typedef struct ge25519_p1p1_t { + bignum25519 x, y, z, t; +} ge25519_p1p1; + +typedef struct ge25519_niels_t { + bignum25519 ysubx, xaddy, t2d; +} ge25519_niels; + +typedef struct ge25519_pniels_t { + bignum25519 ysubx, xaddy, z, t2d; +} ge25519_pniels; + +#include "ed25519-donna-basepoint-table.h" + +#include "ed25519-donna-32bit-tables.h" + +#include "ed25519-donna-impl-base.h" diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-keccak.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-keccak.h new file mode 100644 index 00000000..4cfe148e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-keccak.h @@ -0,0 +1,23 @@ +/* + a custom hash must have a 512bit digest and implement: + + struct ed25519_hash_context; + + void ed25519_hash_init(ed25519_hash_context *ctx); + void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen); + void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash); + void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen); +*/ + +#ifndef ED25519_HASH_CUSTOM +#define ED25519_HASH_CUSTOM + +#include "sha3.h" + +#define ed25519_hash_context SHA3_CTX +#define ed25519_hash_init(ctx) keccak_512_Init(ctx) +#define ed25519_hash_update(ctx, in, inlen) keccak_Update((ctx), (in), (inlen)) +#define ed25519_hash_final(ctx, hash) keccak_Final((ctx), (hash)) +#define ed25519_hash(hash, in, inlen) keccak_512((in), (inlen), (hash)) + +#endif // ED25519_HASH_CUSTOM diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-sha3.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-sha3.h new file mode 100644 index 00000000..6d0bd8f2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom-sha3.h @@ -0,0 +1,23 @@ +/* + a custom hash must have a 512bit digest and implement: + + struct ed25519_hash_context; + + void ed25519_hash_init(ed25519_hash_context *ctx); + void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen); + void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash); + void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen); +*/ + +#ifndef ED25519_HASH_CUSTOM +#define ED25519_HASH_CUSTOM + +#include "sha3.h" + +#define ed25519_hash_context SHA3_CTX +#define ed25519_hash_init(ctx) sha3_512_Init(ctx) +#define ed25519_hash_update(ctx, in, inlen) sha3_Update((ctx), (in), (inlen)) +#define ed25519_hash_final(ctx, hash) sha3_Final((ctx), (hash)) +#define ed25519_hash(hash, in, inlen) sha3_512((in), (inlen), (hash)) + +#endif // ED25519_HASH_CUSTOM diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom.h new file mode 100644 index 00000000..5d8236ee --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-hash-custom.h @@ -0,0 +1,23 @@ +/* + a custom hash must have a 512bit digest and implement: + + struct ed25519_hash_context; + + void ed25519_hash_init(ed25519_hash_context *ctx); + void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen); + void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash); + void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen); +*/ + +#ifndef ED25519_HASH_CUSTOM +#define ED25519_HASH_CUSTOM + +#include "sha2.h" + +#define ed25519_hash_context SHA512_CTX +#define ed25519_hash_init(ctx) sha512_Init(ctx) +#define ed25519_hash_update(ctx, in, inlen) sha512_Update((ctx), (in), (inlen)) +#define ed25519_hash_final(ctx, hash) sha512_Final((ctx), (hash)) +#define ed25519_hash(hash, in, inlen) sha512_Raw((in), (inlen), (hash)) + +#endif // ED25519_HASH_CUSTOM diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.c new file mode 100644 index 00000000..b109360a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.c @@ -0,0 +1,8 @@ +#include + +#include "ed25519-keccak.h" +#include "ed25519-hash-custom-keccak.h" + +#define ED25519_SUFFIX _keccak + +#include "ed25519.c" diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.h new file mode 100644 index 00000000..d5321800 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-keccak.h @@ -0,0 +1,21 @@ +#ifndef ED25519_KECCAK_H +#define ED25519_KECCAK_H + +#include "ed25519.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void ed25519_publickey_keccak(const ed25519_secret_key sk, ed25519_public_key pk); + +int ed25519_sign_open_keccak(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); +void ed25519_sign_keccak(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS); + +int ed25519_scalarmult_keccak(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); + +#if defined(__cplusplus) +} +#endif + +#endif // ED25519_KECCAK_H diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.c new file mode 100644 index 00000000..6a7687d0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.c @@ -0,0 +1,8 @@ +#include + +#include "ed25519-sha3.h" +#include "ed25519-hash-custom-sha3.h" + +#define ED25519_SUFFIX _sha3 + +#include "ed25519.c" diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.h new file mode 100644 index 00000000..58748a55 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519-sha3.h @@ -0,0 +1,21 @@ +#ifndef ED25519_SHA3_H +#define ED25519_SHA3_H + +#include "ed25519.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void ed25519_publickey_sha3(const ed25519_secret_key sk, ed25519_public_key pk); + +int ed25519_sign_open_sha3(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); +void ed25519_sign_sha3(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS); + +int ed25519_scalarmult_sha3(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); + +#if defined(__cplusplus) +} +#endif + +#endif // ED25519_SHA3_H diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.c new file mode 100644 index 00000000..a8946cbb --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.c @@ -0,0 +1,253 @@ +/* + Public domain by Andrew M. + + Ed25519 reference implementation using Ed25519-donna +*/ + + +/* define ED25519_SUFFIX to have it appended to the end of each public function */ +#ifdef ED25519_SUFFIX +#define ED25519_FN3(fn,suffix) fn##suffix +#define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix) +#define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX) +#else +#define ED25519_FN(fn) fn +#endif + +#include "ed25519-donna.h" +#include "ed25519.h" + +#include "ed25519-hash-custom.h" + +/* + Generates a (extsk[0..31]) and aExt (extsk[32..63]) +*/ +DONNA_INLINE static void +ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) { + ed25519_hash(extsk, sk, 32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; +} + +static void +ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) { + ed25519_hash_context ctx; + ed25519_hash_init(&ctx); + ed25519_hash_update(&ctx, RS, 32); + ed25519_hash_update(&ctx, pk, 32); + ed25519_hash_update(&ctx, m, mlen); + ed25519_hash_final(&ctx, hram); +} + +void +ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) { + bignum256modm a; + ge25519 ALIGN(16) A; + hash_512bits extsk; + + /* A = aB */ + ed25519_extsk(extsk, sk); + expand256_modm(a, extsk, 32); + ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); + ge25519_pack(pk, &A); +} + +void +ED25519_FN(ed25519_cosi_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig) { + bignum256modm r, S, a; + hash_512bits extsk, extnonce, hram; + + ed25519_extsk(extsk, sk); + ed25519_extsk(extnonce, nonce); + + /* r = nonce */ + expand256_modm(r, extnonce, 32); + + /* S = H(R,A,m).. */ + ed25519_hram(hram, R, pk, m, mlen); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + expand256_modm(a, extsk, 32); + mul256_modm(S, S, a); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(sig, S); +} + +void +ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) { + ed25519_hash_context ctx; + bignum256modm r, S, a; + ge25519 ALIGN(16) R; + hash_512bits extsk, hashr, hram; + + ed25519_extsk(extsk, sk); + + /* r = H(aExt[32..64], m) */ + ed25519_hash_init(&ctx); + ed25519_hash_update(&ctx, extsk + 32, 32); + ed25519_hash_update(&ctx, m, mlen); + ed25519_hash_final(&ctx, hashr); + expand256_modm(r, hashr, 64); + + /* R = rB */ + ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); + ge25519_pack(RS, &R); + + /* S = H(R,A,m).. */ + ed25519_hram(hram, RS, pk, m, mlen); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + expand256_modm(a, extsk, 32); + mul256_modm(S, S, a); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(RS + 32, S); +} + +int +ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) { + ge25519 ALIGN(16) R, A; + hash_512bits hash; + bignum256modm hram, S; + unsigned char checkR[32]; + + if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) + return -1; + + /* hram = H(R,A,m) */ + ed25519_hram(hash, RS, pk, m, mlen); + expand256_modm(hram, hash, 64); + + /* S */ + expand256_modm(S, RS + 32, 32); + + /* SB - H(R,A,m)A */ + ge25519_double_scalarmult_vartime(&R, &A, hram, S); + ge25519_pack(checkR, &R); + + /* check that R = SB - H(R,A,m)A */ + return ed25519_verify(RS, checkR, 32) ? 0 : -1; +} + +int +ED25519_FN(ed25519_scalarmult) (ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk) { + bignum256modm a; + ge25519 ALIGN(16) A, P; + hash_512bits extsk; + + ed25519_extsk(extsk, sk); + expand256_modm(a, extsk, 32); + + if (!ge25519_unpack_negative_vartime(&P, pk)) { + return -1; + } + + ge25519_scalarmult(&A, &P, a); + curve25519_neg(A.x, A.x); + ge25519_pack(res, &A); + return 0; +} + + +#ifndef ED25519_SUFFIX + +#include "curve25519-donna-scalarmult-base.h" + +int +ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n) { + size_t i = 0; + ge25519 P; + ge25519_pniels sump; + ge25519_p1p1 sump1; + + if (n == 1) { + memcpy(res, pks, sizeof(ed25519_public_key)); + return 0; + } + if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { + return -1; + } + ge25519_full_to_pniels(&sump, &P); + while (i < n - 1) { + if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { + return -1; + } + ge25519_pnielsadd(&sump, &P, &sump); + } + if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { + return -1; + } + ge25519_pnielsadd_p1p1(&sump1, &P, &sump, 0); + ge25519_p1p1_to_partial(&P, &sump1); + curve25519_neg(P.x, P.x); + ge25519_pack(res, &P); + return 0; +} + +void +ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n) { + bignum256modm s, t; + size_t i = 0; + + expand256_modm(s, sigs[i++], 32); + while (i < n) { + expand256_modm(t, sigs[i++], 32); + add256_modm(s, s, t); + } + memcpy(res, R, 32); + contract256_modm(res + 32, s); +} + +/* + Fast Curve25519 basepoint scalar multiplication +*/ +void +curve25519_scalarmult_basepoint(curve25519_key pk, const curve25519_key e) { + curve25519_key ec; + bignum256modm s; + bignum25519 ALIGN(16) yplusz, zminusy; + ge25519 ALIGN(16) p; + size_t i; + + /* clamp */ + for (i = 0; i < 32; i++) ec[i] = e[i]; + ec[0] &= 248; + ec[31] &= 127; + ec[31] |= 64; + + expand_raw256_modm(s, ec); + + /* scalar * basepoint */ + ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s); + + /* u = (y + z) / (z - y) */ + curve25519_add(yplusz, p.y, p.z); + curve25519_sub(zminusy, p.z, p.y); + curve25519_recip(zminusy, zminusy); + curve25519_mul(yplusz, yplusz, zminusy); + curve25519_contract(pk, yplusz); +} + +void +curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, const curve25519_key basepoint) { + curve25519_key e; + size_t i; + + for (i = 0;i < 32;++i) e[i] = secret[i]; + e[0] &= 0xf8; + e[31] &= 0x7f; + e[31] |= 0x40; + curve25519_scalarmult_donna(mypublic, e, basepoint); +} + +#endif // ED25519_SUFFIX diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.h new file mode 100644 index 00000000..b42afdc1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/ed25519.h @@ -0,0 +1,40 @@ +#ifndef ED25519_H +#define ED25519_H + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef unsigned char ed25519_signature[64]; +typedef unsigned char ed25519_public_key[32]; +typedef unsigned char ed25519_secret_key[32]; + +typedef unsigned char curve25519_key[32]; + +typedef unsigned char ed25519_cosi_signature[32]; + +void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk); + +int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); +void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS); + +int ed25519_scalarmult(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); + +void curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, const curve25519_key basepoint); +void curve25519_scalarmult_basepoint(curve25519_key mypublic, const curve25519_key secret); + +#if !defined(__GNUC__) || __GNUC__ > 4 +#define CONST const +#else +#define CONST +#endif + +int ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n); +void ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n); +void ed25519_cosi_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key key, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig); + +#if defined(__cplusplus) +} +#endif + +#endif // ED25519_H diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.c b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.c new file mode 100644 index 00000000..9ed296cf --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.c @@ -0,0 +1,358 @@ +/* + Public domain by Andrew M. +*/ + +#include "ed25519-donna.h" + +/* + Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 + + k = 32 + b = 1 << 8 = 256 + m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed + mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b +*/ + +static const bignum256modm modm_m = { + 0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8, + 0x00000014, 0x00000000, 0x00000000, 0x00000000, + 0x00001000 +}; + +static const bignum256modm modm_mu = { + 0x0a2c131b, 0x3673968c, 0x06329a7e, 0x01885742, + 0x3fffeb21, 0x3fffffff, 0x3fffffff, 0x3fffffff, + 0x000fffff +}; + +static bignum256modm_element_t +lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { + return (a - b) >> 31; +} + +/* see HAC, Alg. 14.42 Step 4 */ +void reduce256_modm(bignum256modm r) { + bignum256modm t; + bignum256modm_element_t b = 0, pb, mask; + + /* t = r - m */ + pb = 0; + pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 30)); pb = b; + pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 30)); pb = b; + pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 30)); pb = b; + pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 30)); pb = b; + pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 30)); pb = b; + pb += modm_m[5]; b = lt_modm(r[5], pb); t[5] = (r[5] - pb + (b << 30)); pb = b; + pb += modm_m[6]; b = lt_modm(r[6], pb); t[6] = (r[6] - pb + (b << 30)); pb = b; + pb += modm_m[7]; b = lt_modm(r[7], pb); t[7] = (r[7] - pb + (b << 30)); pb = b; + pb += modm_m[8]; b = lt_modm(r[8], pb); t[8] = (r[8] - pb + (b << 16)); + + /* keep r if r was smaller than m */ + mask = b - 1; + r[0] ^= mask & (r[0] ^ t[0]); + r[1] ^= mask & (r[1] ^ t[1]); + r[2] ^= mask & (r[2] ^ t[2]); + r[3] ^= mask & (r[3] ^ t[3]); + r[4] ^= mask & (r[4] ^ t[4]); + r[5] ^= mask & (r[5] ^ t[5]); + r[6] ^= mask & (r[6] ^ t[6]); + r[7] ^= mask & (r[7] ^ t[7]); + r[8] ^= mask & (r[8] ^ t[8]); +} + +/* + Barrett reduction, see HAC, Alg. 14.42 + + Instead of passing in x, pre-process in to q1 and r1 for efficiency +*/ +void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { + bignum256modm q3, r2; + uint64_t c; + bignum256modm_element_t f, b, pb; + + /* q1 = x >> 248 = 264 bits = 9 30 bit elements + q2 = mu * q1 + q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */ + c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]); + c >>= 30; + c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + mul32x32_64(modm_mu[8], q1[0]); + f = (bignum256modm_element_t)c; q3[0] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]); + f = (bignum256modm_element_t)c; q3[0] |= (f << 6) & 0x3fffffff; q3[1] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + mul32x32_64(modm_mu[8], q1[2]); + f = (bignum256modm_element_t)c; q3[1] |= (f << 6) & 0x3fffffff; q3[2] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]); + f = (bignum256modm_element_t)c; q3[2] |= (f << 6) & 0x3fffffff; q3[3] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + mul32x32_64(modm_mu[8], q1[4]); + f = (bignum256modm_element_t)c; q3[3] |= (f << 6) & 0x3fffffff; q3[4] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]); + f = (bignum256modm_element_t)c; q3[4] |= (f << 6) & 0x3fffffff; q3[5] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + mul32x32_64(modm_mu[8], q1[6]); + f = (bignum256modm_element_t)c; q3[5] |= (f << 6) & 0x3fffffff; q3[6] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]); + f = (bignum256modm_element_t)c; q3[6] |= (f << 6) & 0x3fffffff; q3[7] = (f >> 24) & 0x3f; c >>= 30; + c += mul32x32_64(modm_mu[8], q1[8]); + f = (bignum256modm_element_t)c; q3[7] |= (f << 6) & 0x3fffffff; q3[8] = (bignum256modm_element_t)(c >> 24); + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) + r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) */ + c = mul32x32_64(modm_m[0], q3[0]); + r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]); + r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + mul32x32_64(modm_m[2], q3[0]); + r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]); + r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + mul32x32_64(modm_m[4], q3[0]); + r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]); + r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + mul32x32_64(modm_m[6], q3[0]); + r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]); + r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; + c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + mul32x32_64(modm_m[8], q3[0]); + r2[8] = (bignum256modm_element_t)(c & 0xffffff); + + /* r = r1 - r2 + if (r < 0) r += (1 << 264) */ + pb = 0; + pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 30)); pb = b; + pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 30)); pb = b; + pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 30)); pb = b; + pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 30)); pb = b; + pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 30)); pb = b; + pb += r2[5]; b = lt_modm(r1[5], pb); r[5] = (r1[5] - pb + (b << 30)); pb = b; + pb += r2[6]; b = lt_modm(r1[6], pb); r[6] = (r1[6] - pb + (b << 30)); pb = b; + pb += r2[7]; b = lt_modm(r1[7], pb); r[7] = (r1[7] - pb + (b << 30)); pb = b; + pb += r2[8]; b = lt_modm(r1[8], pb); r[8] = (r1[8] - pb + (b << 24)); + + reduce256_modm(r); + reduce256_modm(r); +} + +/* addition modulo m */ +void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm_element_t c; + + c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30; + c += x[1] + y[1]; r[1] = c & 0x3fffffff; c >>= 30; + c += x[2] + y[2]; r[2] = c & 0x3fffffff; c >>= 30; + c += x[3] + y[3]; r[3] = c & 0x3fffffff; c >>= 30; + c += x[4] + y[4]; r[4] = c & 0x3fffffff; c >>= 30; + c += x[5] + y[5]; r[5] = c & 0x3fffffff; c >>= 30; + c += x[6] + y[6]; r[6] = c & 0x3fffffff; c >>= 30; + c += x[7] + y[7]; r[7] = c & 0x3fffffff; c >>= 30; + c += x[8] + y[8]; r[8] = c; + + reduce256_modm(r); +} + +/* multiplication modulo m */ +void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm r1, q1; + uint64_t c; + bignum256modm_element_t f; + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) + q1 = x >> 248 = 264 bits = 9 30 bit elements */ + c = mul32x32_64(x[0], y[0]); + f = (bignum256modm_element_t)c; r1[0] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]); + f = (bignum256modm_element_t)c; r1[1] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]); + f = (bignum256modm_element_t)c; r1[2] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + mul32x32_64(x[3], y[0]); + f = (bignum256modm_element_t)c; r1[3] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]); + f = (bignum256modm_element_t)c; r1[4] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]); + f = (bignum256modm_element_t)c; r1[5] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + mul32x32_64(x[6], y[0]); + f = (bignum256modm_element_t)c; r1[6] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]); + f = (bignum256modm_element_t)c; r1[7] = (f & 0x3fffffff); c >>= 30; + c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]); + f = (bignum256modm_element_t)c; r1[8] = (f & 0x00ffffff); q1[0] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]); + f = (bignum256modm_element_t)c; q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; q1[1] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + mul32x32_64(x[8], y[2]); + f = (bignum256modm_element_t)c; q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; q1[2] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]); + f = (bignum256modm_element_t)c; q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; q1[3] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]); + f = (bignum256modm_element_t)c; q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; q1[4] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + mul32x32_64(x[8], y[5]); + f = (bignum256modm_element_t)c; q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; q1[5] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]); + f = (bignum256modm_element_t)c; q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; q1[6] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]); + f = (bignum256modm_element_t)c; q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; q1[7] = (f >> 8) & 0x3fffff; c >>= 30; + c += mul32x32_64(x[8], y[8]); + f = (bignum256modm_element_t)c; q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; q1[8] = (f >> 8) & 0x3fffff; + + barrett_reduce256_modm(r, q1, r1); +} + +void expand256_modm(bignum256modm out, const unsigned char *in, size_t len) { + unsigned char work[64] = {0}; + bignum256modm_element_t x[16]; + bignum256modm q1; + + memcpy(work, in, len); + x[0] = U8TO32_LE(work + 0); + x[1] = U8TO32_LE(work + 4); + x[2] = U8TO32_LE(work + 8); + x[3] = U8TO32_LE(work + 12); + x[4] = U8TO32_LE(work + 16); + x[5] = U8TO32_LE(work + 20); + x[6] = U8TO32_LE(work + 24); + x[7] = U8TO32_LE(work + 28); + x[8] = U8TO32_LE(work + 32); + x[9] = U8TO32_LE(work + 36); + x[10] = U8TO32_LE(work + 40); + x[11] = U8TO32_LE(work + 44); + x[12] = U8TO32_LE(work + 48); + x[13] = U8TO32_LE(work + 52); + x[14] = U8TO32_LE(work + 56); + x[15] = U8TO32_LE(work + 60); + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ + out[0] = ( x[0]) & 0x3fffffff; + out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; + out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; + out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; + out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; + out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; + out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; + out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; + out[8] = ((x[ 7] >> 16) | (x[ 8] << 16)) & 0x00ffffff; + + /* 8*31 = 248 bits, no need to reduce */ + if (len < 32) + return; + + /* q1 = x >> 248 = 264 bits = 9 30 bit elements */ + q1[0] = ((x[ 7] >> 24) | (x[ 8] << 8)) & 0x3fffffff; + q1[1] = ((x[ 8] >> 22) | (x[ 9] << 10)) & 0x3fffffff; + q1[2] = ((x[ 9] >> 20) | (x[10] << 12)) & 0x3fffffff; + q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff; + q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff; + q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff; + q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff; + q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff; + q1[8] = ((x[15] >> 8) ); + + barrett_reduce256_modm(out, q1, out); +} + +void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) { + bignum256modm_element_t x[8]; + + x[0] = U8TO32_LE(in + 0); + x[1] = U8TO32_LE(in + 4); + x[2] = U8TO32_LE(in + 8); + x[3] = U8TO32_LE(in + 12); + x[4] = U8TO32_LE(in + 16); + x[5] = U8TO32_LE(in + 20); + x[6] = U8TO32_LE(in + 24); + x[7] = U8TO32_LE(in + 28); + + out[0] = ( x[0]) & 0x3fffffff; + out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; + out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; + out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; + out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; + out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; + out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; + out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; + out[8] = ((x[ 7] >> 16) ) & 0x0000ffff; +} + +void contract256_modm(unsigned char out[32], const bignum256modm in) { + U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30)); + U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28)); + U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26)); + U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24)); + U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22)); + U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20)); + U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18)); + U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16)); +} + +void contract256_window4_modm(signed char r[64], const bignum256modm in) { + char carry; + signed char *quads = r; + bignum256modm_element_t i, j, v; + + for (i = 0; i < 8; i += 2) { + v = in[i]; + for (j = 0; j < 7; j++) { + *quads++ = (v & 15); + v >>= 4; + } + v |= (in[i+1] << 2); + for (j = 0; j < 8; j++) { + *quads++ = (v & 15); + v >>= 4; + } + } + v = in[8]; + *quads++ = (v & 15); v >>= 4; + *quads++ = (v & 15); v >>= 4; + *quads++ = (v & 15); v >>= 4; + *quads++ = (v & 15); v >>= 4; + + /* making it signed */ + carry = 0; + for(i = 0; i < 63; i++) { + r[i] += carry; + r[i+1] += (r[i] >> 4); + r[i] &= 15; + carry = (r[i] >> 3); + r[i] -= (carry << 4); + } + r[63] += carry; +} + +void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { + int i,j,k,b; + int m = (1 << (windowsize - 1)) - 1, soplen = 256; + signed char *bits = r; + bignum256modm_element_t v; + + /* first put the binary expansion into r */ + for (i = 0; i < 8; i++) { + v = s[i]; + for (j = 0; j < 30; j++, v >>= 1) + *bits++ = (v & 1); + } + v = s[8]; + for (j = 0; j < 16; j++, v >>= 1) + *bits++ = (v & 1); + + /* Making it sliding window */ + for (j = 0; j < soplen; j++) { + if (!r[j]) + continue; + + for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { + if ((r[j] + (r[j + b] << b)) <= m) { + r[j] += r[j + b] << b; + r[j + b] = 0; + } else if ((r[j] - (r[j + b] << b)) >= -m) { + r[j] -= r[j + b] << b; + for (k = j + b; k < soplen; k++) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else if (r[j + b]) { + break; + } + } + } +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.h b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.h new file mode 100644 index 00000000..129e3b11 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.h @@ -0,0 +1,45 @@ +/* + Public domain by Andrew M. +*/ + + +/* + Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 + + k = 32 + b = 1 << 8 = 256 + m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed + mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b +*/ + +#define bignum256modm_bits_per_limb 30 +#define bignum256modm_limb_size 9 + +typedef uint32_t bignum256modm_element_t; +typedef bignum256modm_element_t bignum256modm[9]; + +/* see HAC, Alg. 14.42 Step 4 */ +void reduce256_modm(bignum256modm r); + +/* + Barrett reduction, see HAC, Alg. 14.42 + + Instead of passing in x, pre-process in to q1 and r1 for efficiency +*/ +void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1); + +/* addition modulo m */ +void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y); + +/* multiplication modulo m */ +void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y); + +void expand256_modm(bignum256modm out, const unsigned char *in, size_t len); + +void expand_raw256_modm(bignum256modm out, const unsigned char in[32]); + +void contract256_modm(unsigned char out[32], const bignum256modm in); + +void contract256_window4_modm(signed char r[64], const bignum256modm in); + +void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize); diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/gui/.gitignore b/hardware-wallet/firmware/vendor/trezor-crypto/gui/.gitignore new file mode 100644 index 00000000..b44cbb24 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/gui/.gitignore @@ -0,0 +1,4 @@ +gui.pro.user +moc_mainwindow.cpp +ui_mainwindow.h +Makefile diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/gui/gui.pro b/hardware-wallet/firmware/vendor/trezor-crypto/gui/gui.pro new file mode 100644 index 00000000..0197efe1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/gui/gui.pro @@ -0,0 +1,32 @@ +QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = gui +TEMPLATE = app + +SOURCES += ../address.c +SOURCES += ../bip32.c +SOURCES += ../bip39.c +SOURCES += ../sha2.c +SOURCES += ../pbkdf2.c +SOURCES += ../hmac.c +SOURCES += ../rand.c +SOURCES += ../bignum.c +SOURCES += ../ecdsa.c +SOURCES += ../ripemd160.c +SOURCES += ../base58.c +SOURCES += ../secp256k1.c +SOURCES += ../nist256p1.c +SOURCES += ../curves.c +SOURCES += ../ed25519-donna/ed25519.c +SOURCES += mainwindow.cpp +SOURCES += main.cpp + +HEADERS += mainwindow.h +HEADERS += ../bip32.h +HEADERS += ../bip39.h + +FORMS += mainwindow.ui + +INCLUDEPATH += .. +INCLUDEPATH += ../ed25519-donna diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/gui/main.cpp b/hardware-wallet/firmware/vendor/trezor-crypto/gui/main.cpp new file mode 100644 index 00000000..115a22bf --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/gui/main.cpp @@ -0,0 +1,10 @@ +#include "mainwindow.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.cpp b/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.cpp new file mode 100644 index 00000000..1bc7ea5c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.cpp @@ -0,0 +1,78 @@ +#include +#include "mainwindow.h" +#include "ui_mainwindow.h" +extern "C" { +#include "../bip32.h" +#include "../bip39.h" +#include "../ecdsa.h" +#include "../curves.h" +} + +bool root_set = false; +HDNode root; + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + for (int i = 0; i < 100; i++) { + ui->listAddress->insertRow(i); + ui->listChange->insertRow(i); + + } +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +// abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about + +void MainWindow::on_buttonLoad_clicked() +{ + if (!mnemonic_check(ui->editMnemonic->text().toLocal8Bit().data())) { + QMessageBox::critical(this, "Error", "Text is not a valid BIP39 mnemonic.", QMessageBox::Ok); + return; + } + uint8_t seed[64]; + mnemonic_to_seed(ui->editMnemonic->text().toLocal8Bit().data(), ui->editPassphrase->text().toLocal8Bit().data(), seed, 0); + hdnode_from_seed(seed, 64, SECP256K1_NAME, &root); + root_set = true; + ui->spinAccount->setValue(1); + on_spinAccount_valueChanged(1); +} + +void MainWindow::on_spinAccount_valueChanged(int arg1) +{ + if (!root_set) return; + // constants for Bitcoin + const uint32_t version_public = 0x0488b21e; + const uint32_t version_private = 0x0488ade4; + const char addr_version = 0x00, wif_version = 0x80; + const size_t buflen = 128; + char buf[buflen + 1]; + HDNode node; + uint32_t fingerprint; + // external chain + for (int chain = 0; chain < 2; chain++) { + QTableWidget *list = chain == 0 ? ui->listAddress : ui->listChange; + node = root; + hdnode_private_ckd(&node, 44 | 0x80000000); + hdnode_private_ckd(&node, 0 | 0x80000000); // bitcoin + hdnode_private_ckd(&node, (arg1 - 1) | 0x80000000); + fingerprint = hdnode_fingerprint(&node); + hdnode_serialize_private(&node, fingerprint, version_private, buf, buflen); QString xprv = QString(buf); ui->lineXprv->setText(xprv); + hdnode_serialize_public(&node, fingerprint, version_public, buf, buflen); QString xpub = QString(buf); ui->lineXpub->setText(xpub); + hdnode_private_ckd(&node, chain); // external / internal + for (int i = 0; i < 100; i++) { + HDNode node2 = node; + hdnode_private_ckd(&node2, i); + hdnode_fill_public_key(&node2); + ecdsa_get_address(node2.public_key, addr_version, buf, buflen); QString address = QString(buf); + ecdsa_get_wif(node2.private_key, wif_version, buf, buflen); QString wif = QString(buf); + list->setItem(i, 0, new QTableWidgetItem(address)); + list->setItem(i, 1, new QTableWidgetItem(wif)); + list->setItem(i, 2, new QTableWidgetItem("0.0")); + } + } +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.h b/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.h new file mode 100644 index 00000000..7275167d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.h @@ -0,0 +1,27 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + void on_buttonLoad_clicked(); + void on_spinAccount_valueChanged(int arg1); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.ui b/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.ui new file mode 100644 index 00000000..46566990 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/gui/mainwindow.ui @@ -0,0 +1,161 @@ + + + MainWindow + + + + 0 + 0 + 1000 + 600 + + + + + DejaVu Sans Mono + 8 + + + + TREZOR + + + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 120 + 16777215 + + + + Load + + + + + + + + address + + + + + private key + + + + + balance + + + + + + + + + address + + + + + private key + + + + + balance + + + + + + + + Mnemonic: + + + + + + + Passphrase: + + + + + + + External Chain: + + + + + + + Internal Chain: + + + + + + + + 130 + 16777215 + + + + Account # + + + 1 + + + 2147483647 + + + + + + + + + + + + + + + editMnemonic + editPassphrase + buttonLoad + spinAccount + listAddress + listChange + + + + diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/hasher.c b/hardware-wallet/firmware/vendor/trezor-crypto/hasher.c new file mode 100644 index 00000000..edd1ac76 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/hasher.c @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "hasher.h" + +void hasher_Init(Hasher *hasher, HasherType type) { + hasher->type = type; + + switch (hasher->type) { + case HASHER_SHA2: + sha256_Init(&hasher->ctx.sha2); + break; + case HASHER_BLAKE: + blake256_Init(&hasher->ctx.blake); + break; + } +} + +void hasher_Reset(Hasher *hasher) { + hasher_Init(hasher, hasher->type); +} + +void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length) { + switch (hasher->type) { + case HASHER_SHA2: + sha256_Update(&hasher->ctx.sha2, data, length); + break; + case HASHER_BLAKE: + blake256_Update(&hasher->ctx.blake, data, length); + break; + } +} + +void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) { + switch (hasher->type) { + case HASHER_SHA2: + sha256_Final(&hasher->ctx.sha2, hash); + break; + case HASHER_BLAKE: + blake256_Final(&hasher->ctx.blake, hash); + break; + } +} + +void hasher_Double(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) { + hasher_Final(hasher, hash); + hasher_Raw(hasher->type, hash, HASHER_DIGEST_LENGTH, hash); +} + +void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]) { + Hasher hasher; + + hasher_Init(&hasher, type); + hasher_Update(&hasher, data, length); + hasher_Final(&hasher, hash); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/hasher.h b/hardware-wallet/firmware/vendor/trezor-crypto/hasher.h new file mode 100644 index 00000000..57b70b23 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/hasher.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __HASHER_H__ +#define __HASHER_H__ + +#include +#include + +#include "sha2.h" +#include "blake256.h" + +#define HASHER_DIGEST_LENGTH 32 + +typedef enum { + HASHER_SHA2, + HASHER_BLAKE, +} HasherType; + +typedef struct { + HasherType type; + + union { + SHA256_CTX sha2; + BLAKE256_CTX blake; + } ctx; +} Hasher; + +void hasher_Init(Hasher *hasher, HasherType type); +void hasher_Reset(Hasher *hasher); +void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length); +void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]); +void hasher_Double(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]); + +void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/hmac.c b/hardware-wallet/firmware/vendor/trezor-crypto/hmac.c new file mode 100644 index 00000000..04448c8f --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/hmac.c @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "hmac.h" +#include "options.h" +#include "memzero.h" + +void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t keylen) +{ + static CONFIDENTIAL uint8_t i_key_pad[SHA256_BLOCK_LENGTH]; + memset(i_key_pad, 0, SHA256_BLOCK_LENGTH); + if (keylen > SHA256_BLOCK_LENGTH) { + sha256_Raw(key, keylen, i_key_pad); + } else { + memcpy(i_key_pad, key, keylen); + } + for (int i = 0; i < SHA256_BLOCK_LENGTH; i++) { + hctx->o_key_pad[i] = i_key_pad[i] ^ 0x5c; + i_key_pad[i] ^= 0x36; + } + sha256_Init(&(hctx->ctx)); + sha256_Update(&(hctx->ctx), i_key_pad, SHA256_BLOCK_LENGTH); + memzero(i_key_pad, sizeof(i_key_pad)); +} + +void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, const uint32_t msglen) +{ + sha256_Update(&(hctx->ctx), msg, msglen); +} + +void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac) +{ + sha256_Final(&(hctx->ctx), hmac); + sha256_Init(&(hctx->ctx)); + sha256_Update(&(hctx->ctx), hctx->o_key_pad, SHA256_BLOCK_LENGTH); + sha256_Update(&(hctx->ctx), hmac, SHA256_DIGEST_LENGTH); + sha256_Final(&(hctx->ctx), hmac); + memzero(hctx, sizeof(HMAC_SHA256_CTX)); +} + +void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac) +{ + static CONFIDENTIAL HMAC_SHA256_CTX hctx; + hmac_sha256_Init(&hctx, key, keylen); + hmac_sha256_Update(&hctx, msg, msglen); + hmac_sha256_Final(&hctx, hmac); +} + +void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *opad_digest, uint32_t *ipad_digest) +{ + static CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH/sizeof(uint32_t)]; + + memzero(key_pad, sizeof(key_pad)); + if (keylen > SHA256_BLOCK_LENGTH) { + static CONFIDENTIAL SHA256_CTX context; + sha256_Init(&context); + sha256_Update(&context, key, keylen); + sha256_Final(&context, (uint8_t*)key_pad); + } else { + memcpy(key_pad, key, keylen); + } + + /* compute o_key_pad and its digest */ + for (int i = 0; i < SHA256_BLOCK_LENGTH/(int)sizeof(uint32_t); i++) { + uint32_t data; +#if BYTE_ORDER == LITTLE_ENDIAN + REVERSE32(key_pad[i], data); +#else + data = key_pad[i]; +#endif + key_pad[i] = data ^ 0x5c5c5c5c; + } + sha256_Transform(sha256_initial_hash_value, key_pad, opad_digest); + + /* convert o_key_pad to i_key_pad and compute its digest */ + for (int i = 0; i < SHA256_BLOCK_LENGTH/(int)sizeof(uint32_t); i++) { + key_pad[i] = key_pad[i] ^ 0x5c5c5c5c ^ 0x36363636; + } + sha256_Transform(sha256_initial_hash_value, key_pad, ipad_digest); + memzero(key_pad, sizeof(key_pad)); +} + +void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t keylen) +{ + static CONFIDENTIAL uint8_t i_key_pad[SHA512_BLOCK_LENGTH]; + memset(i_key_pad, 0, SHA512_BLOCK_LENGTH); + if (keylen > SHA512_BLOCK_LENGTH) { + sha512_Raw(key, keylen, i_key_pad); + } else { + memcpy(i_key_pad, key, keylen); + } + for (int i = 0; i < SHA512_BLOCK_LENGTH; i++) { + hctx->o_key_pad[i] = i_key_pad[i] ^ 0x5c; + i_key_pad[i] ^= 0x36; + } + sha512_Init(&(hctx->ctx)); + sha512_Update(&(hctx->ctx), i_key_pad, SHA512_BLOCK_LENGTH); + memzero(i_key_pad, sizeof(i_key_pad)); +} + +void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, const uint32_t msglen) +{ + sha512_Update(&(hctx->ctx), msg, msglen); +} + +void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac) +{ + sha512_Final(&(hctx->ctx), hmac); + sha512_Init(&(hctx->ctx)); + sha512_Update(&(hctx->ctx), hctx->o_key_pad, SHA512_BLOCK_LENGTH); + sha512_Update(&(hctx->ctx), hmac, SHA512_DIGEST_LENGTH); + sha512_Final(&(hctx->ctx), hmac); + memzero(hctx, sizeof(HMAC_SHA512_CTX)); +} + +void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac) +{ + HMAC_SHA512_CTX hctx; + hmac_sha512_Init(&hctx, key, keylen); + hmac_sha512_Update(&hctx, msg, msglen); + hmac_sha512_Final(&hctx, hmac); +} + +void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *opad_digest, uint64_t *ipad_digest) +{ + static CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH/sizeof(uint64_t)]; + + memzero(key_pad, sizeof(key_pad)); + if (keylen > SHA512_BLOCK_LENGTH) { + static CONFIDENTIAL SHA512_CTX context; + sha512_Init(&context); + sha512_Update(&context, key, keylen); + sha512_Final(&context, (uint8_t*)key_pad); + } else { + memcpy(key_pad, key, keylen); + } + + /* compute o_key_pad and its digest */ + for (int i = 0; i < SHA512_BLOCK_LENGTH/(int)sizeof(uint64_t); i++) { + uint64_t data; +#if BYTE_ORDER == LITTLE_ENDIAN + REVERSE64(key_pad[i], data); +#else + data = key_pad[i]; +#endif + key_pad[i] = data ^ 0x5c5c5c5c5c5c5c5c; + } + sha512_Transform(sha512_initial_hash_value, key_pad, opad_digest); + + /* convert o_key_pad to i_key_pad and compute its digest */ + for (int i = 0; i < SHA512_BLOCK_LENGTH/(int)sizeof(uint64_t); i++) { + key_pad[i] = key_pad[i] ^ 0x5c5c5c5c5c5c5c5c ^ 0x3636363636363636; + } + sha512_Transform(sha512_initial_hash_value, key_pad, ipad_digest); + memzero(key_pad, sizeof(key_pad)); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/hmac.h b/hardware-wallet/firmware/vendor/trezor-crypto/hmac.h new file mode 100644 index 00000000..3cfc0cd0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/hmac.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT HMAC_SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __HMAC_H__ +#define __HMAC_H__ + +#include +#include "sha2.h" + +typedef struct _HMAC_SHA256_CTX { + uint8_t o_key_pad[SHA256_BLOCK_LENGTH]; + SHA256_CTX ctx; +} HMAC_SHA256_CTX; + +typedef struct _HMAC_SHA512_CTX { + uint8_t o_key_pad[SHA512_BLOCK_LENGTH]; + SHA512_CTX ctx; +} HMAC_SHA512_CTX; + +void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t keylen); +void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, const uint32_t msglen); +void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac); +void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac); +void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *opad_digest, uint32_t *ipad_digest); + +void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t keylen); +void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, const uint32_t msglen); +void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac); +void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac); +void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *opad_digest, uint64_t *ipad_digest); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/memzero.c b/hardware-wallet/firmware/vendor/trezor-crypto/memzero.c new file mode 100644 index 00000000..68fad584 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/memzero.c @@ -0,0 +1,6 @@ +#include + +void memzero(void *s, size_t n) +{ + memset(s, 0, n); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/memzero.h b/hardware-wallet/firmware/vendor/trezor-crypto/memzero.h new file mode 100644 index 00000000..ce51acae --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/memzero.h @@ -0,0 +1,8 @@ +#ifndef __MEMZERO_H__ +#define __MEMZERO_H__ + +#include + +void memzero(void *s, size_t n); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/nem.c b/hardware-wallet/firmware/vendor/trezor-crypto/nem.c new file mode 100644 index 00000000..d5faff00 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/nem.c @@ -0,0 +1,617 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, E1PRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "nem.h" + +#include + +#include "base32.h" +#include "ed25519-donna/ed25519-keccak.h" +#include "ripemd160.h" +#include "sha3.h" +#include "memzero.h" + +const char *nem_network_name(uint8_t network) { + switch (network) { + case NEM_NETWORK_MAINNET: + return "NEM Mainnet"; + case NEM_NETWORK_TESTNET: + return "NEM Testnet"; + case NEM_NETWORK_MIJIN: + return "Mijin"; + default: + return NULL; + } +} + +static inline void nem_write_u32(nem_transaction_ctx *ctx, uint32_t data) { + ctx->buffer[ctx->offset++] = (data >> 0) & 0xff; + ctx->buffer[ctx->offset++] = (data >> 8) & 0xff; + ctx->buffer[ctx->offset++] = (data >> 16) & 0xff; + ctx->buffer[ctx->offset++] = (data >> 24) & 0xff; +} + +static inline void nem_write_u64(nem_transaction_ctx *ctx, uint64_t data) { + nem_write_u32(ctx, (data >> 0) & 0xffffffff); + nem_write_u32(ctx, (data >> 32) & 0xffffffff); +} + +static inline void nem_write(nem_transaction_ctx *ctx, const uint8_t *data, uint32_t length) { + nem_write_u32(ctx, length); + + memcpy(&ctx->buffer[ctx->offset], data, length); + ctx->offset += length; +} + +static inline bool nem_can_write(nem_transaction_ctx *ctx, size_t needed) { + return (ctx->offset + needed) <= ctx->size; +} + +static inline bool nem_write_mosaic_str(nem_transaction_ctx *ctx, const char *name, const char *value) { + uint32_t name_length = strlen(name); + uint32_t value_length = strlen(value); + +#define NEM_SERIALIZE \ + serialize_u32(sizeof(uint32_t) + name_length + sizeof(uint32_t) + value_length) \ + serialize_write((uint8_t *) name, name_length) \ + serialize_write((uint8_t *) value, value_length) + +#include "nem_serialize.h" + + return true; +} + +static inline bool nem_write_mosaic_bool(nem_transaction_ctx *ctx, const char *name, bool value) { + return nem_write_mosaic_str(ctx, name, value ? "true" : "false"); +} + +static inline bool nem_write_mosaic_u64(nem_transaction_ctx *ctx, const char *name, uint64_t value) { + char buffer[21]; + + if (bn_format_uint64(value, NULL, NULL, 0, 0, false, buffer, sizeof(buffer)) == 0) { + return false; + } + + return nem_write_mosaic_str(ctx, name, buffer); +} + +void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t *address) { + uint8_t hash[SHA3_256_DIGEST_LENGTH]; + + /* 1. Perform 256-bit Sha3 on the public key */ + keccak_256(public_key, sizeof(ed25519_public_key), hash); + + /* 2. Perform 160-bit Ripemd of hash resulting from step 1. */ + ripemd160(hash, SHA3_256_DIGEST_LENGTH, &address[1]); + + /* 3. Prepend version byte to Ripemd hash (either 0x68 or 0x98) */ + address[0] = version; + + /* 4. Perform 256-bit Sha3 on the result, take the first four bytes as a checksum */ + keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); + + /* 5. Concatenate output of step 3 and the checksum from step 4 */ + memcpy(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4); + + memzero(hash, sizeof(hash)); +} + +bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char *address) { + uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW]; + + nem_get_address_raw(public_key, version, pubkeyhash); + + char *ret = base32_encode(pubkeyhash, sizeof(pubkeyhash), address, NEM_ADDRESS_SIZE + 1, BASE32_ALPHABET_RFC4648); + + memzero(pubkeyhash, sizeof(pubkeyhash)); + return (ret != NULL); +} + +bool nem_validate_address_raw(const uint8_t *address, uint8_t network) { + if (!nem_network_name(network) || address[0] != network) { + return false; + } + + uint8_t hash[SHA3_256_DIGEST_LENGTH]; + + keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); + bool valid = (memcmp(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4) == 0); + + memzero(hash, sizeof(hash)); + return valid; +} + +bool nem_validate_address(const char *address, uint8_t network) { + uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW]; + + if (strlen(address) != NEM_ADDRESS_SIZE) { + return false; + } + + uint8_t *ret = base32_decode(address, NEM_ADDRESS_SIZE, pubkeyhash, sizeof(pubkeyhash), BASE32_ALPHABET_RFC4648); + bool valid = (ret != NULL) && nem_validate_address_raw(pubkeyhash, network); + + memzero(pubkeyhash, sizeof(pubkeyhash)); + return valid; +} + +void nem_transaction_start(nem_transaction_ctx *ctx, const ed25519_public_key public_key, uint8_t *buffer, size_t size) { + memcpy(ctx->public_key, public_key, sizeof(ctx->public_key)); + + ctx->buffer = buffer; + ctx->offset = 0; + ctx->size = size; +} + +size_t nem_transaction_end(nem_transaction_ctx *ctx, const ed25519_secret_key private_key, ed25519_signature signature) { + if (private_key != NULL && signature != NULL) { + ed25519_sign_keccak(ctx->buffer, ctx->offset, private_key, ctx->public_key, signature); + } + + return ctx->offset; +} + +bool nem_transaction_write_common(nem_transaction_ctx *ctx, + uint32_t type, + uint32_t version, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline) { + +#define NEM_SERIALIZE \ + serialize_u32(type) \ + serialize_u32(version) \ + serialize_u32(timestamp) \ + serialize_write(signer, sizeof(ed25519_public_key)) \ + serialize_u64(fee) \ + serialize_u32(deadline) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_create_transfer(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *recipient, + uint64_t amount, + const uint8_t *payload, + uint32_t length, + bool encrypted, + uint32_t mosaics) { + + if (!signer) { + signer = ctx->public_key; + } + + if (!payload) { + length = 0; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_TRANSFER, + network << 24 | (mosaics ? 2 : 1), + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + +#define NEM_SERIALIZE \ + serialize_write((uint8_t *) recipient, NEM_ADDRESS_SIZE) \ + serialize_u64(amount) + +#include "nem_serialize.h" + + if (length) { + +#define NEM_SERIALIZE \ + serialize_u32(sizeof(uint32_t) + sizeof(uint32_t) + length) \ + serialize_u32(encrypted ? 0x02 : 0x01) \ + serialize_write(payload, length) + +#include "nem_serialize.h" + + } else { + +#define NEM_SERIALIZE \ + serialize_u32(0) + +#include "nem_serialize.h" + + } + + if (mosaics) { + +#define NEM_SERIALIZE \ + serialize_u32(mosaics) + +#include "nem_serialize.h" + + } + + return true; +} + +bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx, + const char *namespace, + const char *mosaic, + uint64_t quantity) { + + size_t namespace_length = strlen(namespace); + size_t mosaic_length = strlen(mosaic); + size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; + +#define NEM_SERIALIZE \ + serialize_u32(sizeof(uint32_t) + sizeof(uint64_t) + identifier_length) \ + serialize_u32(identifier_length) \ + serialize_write((uint8_t *) namespace, namespace_length) \ + serialize_write((uint8_t *) mosaic, mosaic_length) \ + serialize_u64(quantity) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx *inner) { + + if (!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_MULTISIG, + network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + +#define NEM_SERIALIZE \ + serialize_write(inner->buffer, inner->offset) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_create_multisig_signature(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx *inner) { + + if (!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE, + network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + + char address[NEM_ADDRESS_SIZE + 1]; + nem_get_address(inner->public_key, network, address); + + uint8_t hash[SHA3_256_DIGEST_LENGTH]; + keccak_256(inner->buffer, inner->offset, hash); + +#define NEM_SERIALIZE \ + serialize_u32(sizeof(uint32_t) + SHA3_256_DIGEST_LENGTH) \ + serialize_write(hash, SHA3_256_DIGEST_LENGTH) \ + serialize_write((uint8_t *) address, NEM_ADDRESS_SIZE) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_create_provision_namespace(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *namespace, + const char *parent, + const char *rental_sink, + uint64_t rental_fee) { + + if (!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE, + network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + + if (parent) { + +#define NEM_SERIALIZE \ + serialize_write((uint8_t *) rental_sink, NEM_ADDRESS_SIZE) \ + serialize_u64(rental_fee) \ + serialize_write((uint8_t *) namespace, strlen(namespace)) \ + serialize_write((uint8_t *) parent, strlen(parent)) + +#include "nem_serialize.h" + + } else { + +#define NEM_SERIALIZE \ + serialize_write((uint8_t *) rental_sink, NEM_ADDRESS_SIZE) \ + serialize_u64(rental_fee) \ + serialize_write((uint8_t *) namespace, strlen(namespace)) \ + serialize_u32(0xffffffff) + +#include "nem_serialize.h" + + } + + return true; +} + +bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *namespace, + const char *mosaic, + const char *description, + uint32_t divisibility, + uint64_t supply, + bool mutable_supply, + bool transferable, + uint32_t levy_type, + uint64_t levy_fee, + const char *levy_address, + const char *levy_namespace, + const char *levy_mosaic, + const char *creation_sink, + uint64_t creation_fee) { + + if (!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + + size_t namespace_length = strlen(namespace); + size_t mosaic_length = strlen(mosaic); + size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; + + // This length will be rewritten later on + nem_transaction_ctx state; + memcpy(&state, ctx, sizeof(state)); + +#define NEM_SERIALIZE \ + serialize_u32(0) \ + serialize_write(signer, sizeof(ed25519_public_key)) \ + serialize_u32(identifier_length) \ + serialize_write((uint8_t *) namespace, namespace_length) \ + serialize_write((uint8_t *) mosaic, mosaic_length) \ + serialize_write((uint8_t *) description, strlen(description)) \ + serialize_u32(4) // Number of properties + +#include "nem_serialize.h" + + if (!nem_write_mosaic_u64(ctx, "divisibility", divisibility)) return false; + if (!nem_write_mosaic_u64(ctx, "initialSupply", supply)) return false; + if (!nem_write_mosaic_bool(ctx, "supplyMutable", mutable_supply)) return false; + if (!nem_write_mosaic_bool(ctx, "transferable", transferable)) return false; + + if (levy_type) { + size_t levy_namespace_length = strlen(levy_namespace); + size_t levy_mosaic_length = strlen(levy_mosaic); + size_t levy_identifier_length = sizeof(uint32_t) + levy_namespace_length + sizeof(uint32_t) + levy_mosaic_length; + +#define NEM_SERIALIZE \ + serialize_u32(sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE + sizeof(uint32_t) + levy_identifier_length + sizeof(uint64_t)) \ + serialize_u32(levy_type) \ + serialize_write((uint8_t *) levy_address, NEM_ADDRESS_SIZE) \ + serialize_u32(levy_identifier_length) \ + serialize_write((uint8_t *) levy_namespace, levy_namespace_length) \ + serialize_write((uint8_t *) levy_mosaic, levy_mosaic_length) \ + serialize_u64(levy_fee) + +#include "nem_serialize.h" + + } else { + +#define NEM_SERIALIZE \ + serialize_u32(0) + +#include "nem_serialize.h" + + } + + // Rewrite length + nem_write_u32(&state, ctx->offset - state.offset - sizeof(uint32_t)); + +#define NEM_SERIALIZE \ + serialize_write((uint8_t *) creation_sink, NEM_ADDRESS_SIZE) \ + serialize_u64(creation_fee) + +#include "nem_serialize.h" + + return true; + +} + +bool nem_transaction_create_mosaic_supply_change(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *namespace, + const char *mosaic, + uint32_t type, + uint64_t delta) { + + if (!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE, + network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + + size_t namespace_length = strlen(namespace); + size_t mosaic_length = strlen(mosaic); + size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; + +#define NEM_SERIALIZE \ + serialize_u32(identifier_length) \ + serialize_write((uint8_t *) namespace, namespace_length) \ + serialize_write((uint8_t *) mosaic, mosaic_length) \ + serialize_u32(type) \ + serialize_u64(delta) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_create_aggregate_modification(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t modifications, + bool relative_change) { + + if (!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION, + network << 24 | (relative_change ? 2 : 1), + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + +#define NEM_SERIALIZE \ + serialize_u32(modifications) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_write_cosignatory_modification(nem_transaction_ctx *ctx, + uint32_t type, + const ed25519_public_key cosignatory) { + +#define NEM_SERIALIZE \ + serialize_u32(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(ed25519_public_key)) \ + serialize_u32(type) \ + serialize_write(cosignatory, sizeof(ed25519_public_key)) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx, + int32_t relative_change) { + +#define NEM_SERIALIZE \ + serialize_u32(sizeof(uint32_t)) \ + serialize_u32((uint32_t) relative_change) + +#include "nem_serialize.h" + + return true; +} + +bool nem_transaction_create_importance_transfer(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t mode, + const ed25519_public_key remote) { + + if (!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common(ctx, + NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER, + network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if (!ret) return false; + +#define NEM_SERIALIZE \ + serialize_u32(mode) \ + serialize_write(remote, sizeof(ed25519_public_key)) + +#include "nem_serialize.h" + + return true; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/nem.h b/hardware-wallet/firmware/vendor/trezor-crypto/nem.h new file mode 100644 index 00000000..fe7f7b68 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/nem.h @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __NEM_H__ +#define __NEM_H__ + +#include +#include +#include + +#include "bip32.h" +#include "ed25519-donna/ed25519.h" + +#define NEM_LEVY_PERCENTILE_DIVISOR 4 +#define NEM_MAX_DIVISIBILITY 6 +#define NEM_MAX_SUPPLY 9000000000 + +#define NEM_NETWORK_MAINNET 0x68 +#define NEM_NETWORK_TESTNET 0x98 +#define NEM_NETWORK_MIJIN 0x60 + +#define NEM_ADDRESS_SIZE 40 +#define NEM_ADDRESS_SIZE_RAW 25 + +#define NEM_TRANSACTION_TYPE_TRANSFER 0x0101 +#define NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER 0x0801 +#define NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION 0x1001 +#define NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE 0x1002 +#define NEM_TRANSACTION_TYPE_MULTISIG 0x1004 +#define NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE 0x2001 +#define NEM_TRANSACTION_TYPE_MOSAIC_CREATION 0x4001 +#define NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE 0x4002 + +#define NEM_SALT_SIZE sizeof(ed25519_public_key) + +#define NEM_ENCRYPTED_SIZE(size) (((size) + AES_BLOCK_SIZE) / AES_BLOCK_SIZE * AES_BLOCK_SIZE) +#define NEM_ENCRYPTED_PAYLOAD_SIZE(size) (AES_BLOCK_SIZE + NEM_SALT_SIZE + NEM_ENCRYPTED_SIZE(size)) + +#define _NEM_PADDING_SIZE(buffer, size) ((buffer)[(size) - 1]) +#define NEM_PADDING_SIZE(buffer, size) (_NEM_PADDING_SIZE(buffer, size) > (size) ? (size) : _NEM_PADDING_SIZE(buffer, size)) + +#define NEM_DECRYPTED_SIZE(buffer, size) ((size) - NEM_PADDING_SIZE(buffer, size)) + +typedef struct { + ed25519_public_key public_key; + uint8_t *buffer; + size_t offset; + size_t size; +} nem_transaction_ctx; + +const char *nem_network_name(uint8_t network); + +void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t *address); +bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char *address); + +bool nem_validate_address_raw(const uint8_t *address, uint8_t network); +bool nem_validate_address(const char *address, uint8_t network); + +void nem_transaction_start(nem_transaction_ctx *ctx, const ed25519_public_key public_key, uint8_t *buffer, size_t size); +size_t nem_transaction_end(nem_transaction_ctx *ctx, const ed25519_secret_key private_key, ed25519_signature signature); + +bool nem_transaction_write_common(nem_transaction_ctx *context, + uint32_t type, + uint32_t version, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline); + +bool nem_transaction_create_transfer(nem_transaction_ctx *context, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *recipient, + uint64_t amount, + const uint8_t *payload, + uint32_t length, + bool encrypted, + uint32_t mosaics); + +bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx, + const char *namespace, + const char *mosaic, + uint64_t quantity); + +bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx *inner); + +bool nem_transaction_create_multisig_signature(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx *inner); + +bool nem_transaction_create_provision_namespace(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *namespace, + const char *parent, + const char *rental_sink, + uint64_t rental_fee); + +bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *namespace, + const char *mosaic, + const char *description, + uint32_t divisibility, + uint64_t supply, + bool mutable_supply, + bool transferable, + uint32_t levy_type, + uint64_t levy_fee, + const char *levy_address, + const char *levy_namespace, + const char *levy_mosaic, + const char *creation_sink, + uint64_t creation_fee); + +bool nem_transaction_create_mosaic_supply_change(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char *namespace, + const char *mosaic, + uint32_t type, + uint64_t delta); + +bool nem_transaction_create_aggregate_modification(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t modifications, + bool relative_change); + +bool nem_transaction_write_cosignatory_modification(nem_transaction_ctx *ctx, + uint32_t type, + const ed25519_public_key cosignatory); + +bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx, + int32_t relative_change); + +bool nem_transaction_create_importance_transfer(nem_transaction_ctx *ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t mode, + const ed25519_public_key remote); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/nem_serialize.h b/hardware-wallet/firmware/vendor/trezor-crypto/nem_serialize.h new file mode 100644 index 00000000..479581fc --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/nem_serialize.h @@ -0,0 +1,23 @@ +#define serialize_u32(data) + sizeof(uint32_t) +#define serialize_u64(data) + sizeof(uint64_t) +#define serialize_write(data, length) + (length) + +if (!nem_can_write(ctx, NEM_SERIALIZE)) { + return false; +} + +#undef serialize_u32 +#undef serialize_u64 +#undef serialize_write + +#define serialize_u32(data) nem_write_u32(ctx, (data)); +#define serialize_u64(data) nem_write_u64(ctx, (data)); +#define serialize_write(data, length) nem_write(ctx, (data), (length)); + +NEM_SERIALIZE + +#undef serialize_u32 +#undef serialize_u64 +#undef serialize_write + +#undef NEM_SERIALIZE diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.c b/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.c new file mode 100644 index 00000000..ef61ac5e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.c @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "nist256p1.h" + +const ecdsa_curve nist256p1 = { + /* .prime */ { + /*.val =*/ {0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3f, 0x0, 0x0, 0x1000, 0x3fffc000, 0xffff} + }, + + /* G */ { + /*.x =*/{/*.val =*/{0x1898c296, 0x1284e517, 0x1eb33a0f, 0xdf604b, 0x2440f277, 0x339b958e, 0x4247f8b, 0x347cb84b, 0x6b17}}, + /*.y =*/{/*.val =*/{0x37bf51f5, 0x2ed901a0, 0x3315ecec, 0x338cd5da, 0xf9e162b, 0x1fad29f0, 0x27f9b8ee, 0x10b8bf86, 0x4fe3}} + }, + + /* order */ { + /*.val =*/{0x3c632551, 0xee72b0b, 0x3179e84f, 0x39beab69, 0x3fffffbc, 0x3fffffff, 0xfff, 0x3fffc000, 0xffff} + }, + + /* order_half */ { + /*.val =*/{0x3e3192a8, 0x27739585, 0x38bcf427, 0x1cdf55b4, 0x3fffffde, 0x3fffffff, 0x7ff, 0x3fffe000, 0x7fff} + }, + + /* a */ -3, + + /* b */ { + /*.val =*/{0x27d2604b, 0x2f38f0f8, 0x53b0f63, 0x741ac33, 0x1886bc65, 0x2ef555da, 0x293e7b3e, 0xd762a8e, 0x5ac6} + } + +#if USE_PRECOMPUTED_CP + , + /* cp */ { +#include "nist256p1.table" + } +#endif +}; + +const curve_info nist256p1_info = { + .bip32_name = "Nist256p1 seed", + .params = &nist256p1, + .hasher_type = HASHER_SHA2, +}; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.h b/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.h new file mode 100644 index 00000000..a1a767ef --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.h @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __NIST256P1_H__ +#define __NIST256P1_H__ + +#include + +#include "ecdsa.h" +#include "bip32.h" + +extern const ecdsa_curve nist256p1; +extern const curve_info nist256p1_info; + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.table b/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.table new file mode 100644 index 00000000..c4fc2247 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/nist256p1.table @@ -0,0 +1,1664 @@ + { + /* 1*16^0*G: */ + {{{0x1898c296, 0x1284e517, 0x1eb33a0f, 0x00df604b, 0x2440f277, 0x339b958e, 0x04247f8b, 0x347cb84b, 0x6b17}}, + {{0x37bf51f5, 0x2ed901a0, 0x3315ecec, 0x338cd5da, 0x0f9e162b, 0x1fad29f0, 0x27f9b8ee, 0x10b8bf86, 0x4fe3}}}, + /* 3*16^0*G: */ + {{{0x06e7fd6c, 0x2d05986f, 0x3ada985f, 0x31adc87b, 0x0bf165e6, 0x1fbe5475, 0x30a44c8f, 0x3934698c, 0x5ecb}}, + {{0x227d5032, 0x29e6c49e, 0x04fb83d9, 0x0aac0d8e, 0x24a2ecd8, 0x2c1b3869, 0x0ff7e374, 0x19031266, 0x8734}}}, + /* 5*16^0*G: */ + {{{0x03d033ed, 0x05552837, 0x35be5242, 0x2320bf47, 0x268fdfef, 0x13215821, 0x140d2d78, 0x02de9454, 0x5159}}, + {{0x3da16da4, 0x0742ed13, 0x0d80888d, 0x004bc035, 0x0a79260d, 0x06fcdafe, 0x2727d8ae, 0x1f6a2412, 0xe0c1}}}, + /* 7*16^0*G: */ + {{{0x3187b2a3, 0x0018a1c0, 0x00fef5b3, 0x3e7e2e2a, 0x01fb607e, 0x2cc199f0, 0x37b4625b, 0x0edbe82f, 0x8e53}}, + {{0x01f400b4, 0x15786a1b, 0x3041b21c, 0x31cd8cf2, 0x35900053, 0x1a7e0e9b, 0x318366d0, 0x076f780c, 0x73eb}}}, + /* 9*16^0*G: */ + {{{0x10949ee0, 0x1e7a292e, 0x06df8b3d, 0x02b2e30b, 0x31f8729e, 0x24e35475, 0x30b71878, 0x35edbfb7, 0xea68}}, + {{0x0dd048fa, 0x21688929, 0x0de823fe, 0x1c53faa9, 0x0ea0c84d, 0x052a592a, 0x1fce7870, 0x11325cb2, 0x2a27}}}, + /* 11*16^0*G: */ + {{{0x34bc21d1, 0x0cce474d, 0x15048bf4, 0x1d0bb409, 0x021cda16, 0x20de76c3, 0x34c59063, 0x04ede20e, 0x3ed1}}, + {{0x282a3740, 0x0be3bbf3, 0x29889dae, 0x03413697, 0x34c68a09, 0x210ebe93, 0x0c8a224c, 0x0826b331, 0x9099}}}, + /* 13*16^0*G: */ + {{{0x06072c01, 0x23857675, 0x1ead58a9, 0x0b8a12d9, 0x1ee2fc79, 0x0177cb61, 0x0495a618, 0x20deb82b, 0x177c}}, + {{0x2fc7bfd8, 0x310eef8b, 0x1fb4df39, 0x3b8530e8, 0x0f4e7226, 0x0246b6d0, 0x2a558a24, 0x163353af, 0x63bb}}}, + /* 15*16^0*G: */ + {{{0x259b9d5f, 0x0d9a318f, 0x23a0ef16, 0x00ebe4b7, 0x088265ae, 0x2cde2666, 0x2bae7adf, 0x1371a5c6, 0xf045}}, + {{0x0d034f36, 0x1f967378, 0x1b5fa3f4, 0x0ec8739d, 0x1643e62a, 0x1653947e, 0x22d1f4e6, 0x0fb8d64b, 0xb5b9}}} + }, + { + /* 1*16^1*G: */ + {{{0x21277c6e, 0x17ad1e1f, 0x36ca038a, 0x0a0e4bbf, 0x36315fcd, 0x08718a60, 0x341858b8, 0x1344e29a, 0x76a9}}, + {{0x0b8c5110, 0x3a7775c9, 0x3c78baa0, 0x26680103, 0x1e872085, 0x0286d784, 0x3260e6cb, 0x3f984d07, 0xa985}}}, + /* 3*16^1*G: */ + {{{0x1e4536ca, 0x2fee771a, 0x2201a61a, 0x0ba4a582, 0x30cda11c, 0x39d16f81, 0x139ec8cc, 0x3ec39249, 0x9482}}, + {{0x358cc1c8, 0x3eb618ef, 0x307bfbb1, 0x0f578a55, 0x134e63f6, 0x358e329d, 0x157f91a5, 0x2729d17c, 0x351d}}}, + /* 5*16^1*G: */ + {{{0x15ecff13, 0x26c76b8a, 0x3d0633c4, 0x1d928736, 0x081eeb63, 0x0d69454c, 0x131195b8, 0x2df05eba, 0xb2e1}}, + {{0x32187d44, 0x0ee92626, 0x3dea2e6a, 0x3686a605, 0x1758c387, 0x0e868aab, 0x3ebccf23, 0x1104c4e8, 0xe6c0}}}, + /* 7*16^1*G: */ + {{{0x2ef87286, 0x22eeccd3, 0x02309e43, 0x00fa1f7f, 0x06ee3407, 0x105df72f, 0x36bc2cb3, 0x118b9fc6, 0xb433}}, + {{0x041496d9, 0x2b011fda, 0x22cea4b7, 0x3388201a, 0x292e6f9d, 0x3d39cb05, 0x2b5fe383, 0x15149bb4, 0xa0da}}}, + /* 9*16^1*G: */ + {{{0x19794381, 0x2e61ad6c, 0x2b0c7601, 0x245621d7, 0x167b1918, 0x1ba416d5, 0x1a24cc18, 0x0833934f, 0xa474}}, + {{0x22769c52, 0x25b38e9f, 0x1f6ac786, 0x2970236e, 0x167afff3, 0x37e4d866, 0x1bfe0e73, 0x3ff7def8, 0x2ebb}}}, + /* 11*16^1*G: */ + {{{0x09a5185a, 0x31d11992, 0x35e6f2be, 0x21c2b227, 0x0da3195b, 0x335004ac, 0x091485fe, 0x1e866e74, 0x05ba}}, + {{0x01de3a4e, 0x150f2238, 0x105ae001, 0x018882f2, 0x23d48e76, 0x1e08f893, 0x01896e46, 0x34ad7a0b, 0x30e0}}}, + /* 13*16^1*G: */ + {{{0x399b85fe, 0x2a8e62d7, 0x23a5dfd5, 0x03bfa6ab, 0x03e0b79c, 0x26364602, 0x3e2fd697, 0x1d327437, 0xb29f}}, + {{0x2da604dc, 0x2e990a5d, 0x3f59e80d, 0x3bd8f4c2, 0x17c6d92d, 0x01c4ba5b, 0x29785d5d, 0x16f0e9b0, 0xa3ce}}}, + /* 15*16^1*G: */ + {{{0x07e030ef, 0x1d9d15ba, 0x0d50e962, 0x1acac15f, 0x082b0857, 0x32fc0fc9, 0x1bcf5076, 0x26eaa2e4, 0x9929}}, + {{0x18d9aa9a, 0x3639adf7, 0x34008444, 0x304b1267, 0x0eaa7957, 0x0e04069b, 0x38e18bf3, 0x38f4cccf, 0x5cc2}}} + }, + { + /* 1*16^2*G: */ + {{{0x12d0441b, 0x36cb8d7c, 0x16a564c2, 0x0342dc43, 0x03ed6119, 0x3f454a18, 0x1165987f, 0x3528ec02, 0x34a2}}, + {{0x1e93b146, 0x10939e11, 0x2ddd81db, 0x35d9ae77, 0x377fc0e7, 0x29c411b9, 0x1e3c22bc, 0x3b5a94e8, 0xbeaa}}}, + /* 3*16^2*G: */ + {{{0x3da08424, 0x3392b8ce, 0x0f644a9d, 0x2fedeadd, 0x1d23ed3a, 0x2317fea5, 0x359aa1b5, 0x0281eb70, 0xa98b}}, + {{0x2831800c, 0x184a1e83, 0x0df582d3, 0x0afa02e8, 0x1d132075, 0x067a3238, 0x19b66e53, 0x3191c892, 0x4754}}}, + /* 5*16^2*G: */ + {{{0x083c2d6a, 0x14b5f97a, 0x1bd29b3b, 0x0be46360, 0x1a696dd2, 0x2dade321, 0x1aac5d21, 0x3c027223, 0xa034}}, + {{0x02c30e72, 0x10cdbbcb, 0x2267e7cf, 0x0180d7c5, 0x2ceb06be, 0x36e15173, 0x19c1fb0c, 0x000db2a2, 0xfe1b}}}, + /* 7*16^2*G: */ + {{{0x28be8c78, 0x05a94774, 0x3793e4d7, 0x025b3e0a, 0x22e9a14a, 0x1b8ad025, 0x14401a07, 0x09bfcc67, 0xb522}}, + {{0x11686903, 0x00cd9f29, 0x1b58ff32, 0x27dff239, 0x12851a81, 0x2cd9a5fa, 0x1f540ca1, 0x38327d4e, 0x701e}}}, + /* 9*16^2*G: */ + {{{0x2058b5a4, 0x0103f902, 0x131979b7, 0x11193e1e, 0x0c4713de, 0x233b33f3, 0x205b3d96, 0x221861a3, 0xa3e3}}, + {{0x27113aef, 0x3cc1b643, 0x371a2948, 0x3ba116ed, 0x17e68f3c, 0x239aceba, 0x0d12c384, 0x15e21f7c, 0xcfd4}}}, + /* 11*16^2*G: */ + {{{0x04a08314, 0x017d7b24, 0x1c7dff7a, 0x3f8db6cb, 0x21197a82, 0x332ae688, 0x3a539333, 0x151284c7, 0x2099}}, + {{0x27573ccc, 0x1fe32717, 0x2fcfe96e, 0x01b969cd, 0x1048dfd4, 0x2ea3972e, 0x33b1890f, 0x0f7f4aa8, 0xa5cf}}}, + /* 13*16^2*G: */ + {{{0x29078c18, 0x00bfe52b, 0x2ede9295, 0x3830f2bb, 0x1fd39b99, 0x3db9caab, 0x0ec70308, 0x1944eb30, 0x751d}}, + {{0x0ece0d67, 0x2635ba57, 0x3e05ac79, 0x02523072, 0x2a2a4ef0, 0x152ebda8, 0x24158853, 0x0fff7292, 0xba9c}}}, + /* 15*16^2*G: */ + {{{0x1e86d900, 0x0b3f3572, 0x3a3db449, 0x17b82745, 0x3a3b3640, 0x120c2280, 0x3801117b, 0x3d489711, 0x5be0}}, + {{0x358a5755, 0x13375a6f, 0x1b34f5ac, 0x085c9490, 0x35423df9, 0x1f8e939e, 0x2c422d34, 0x3679b7fc, 0x83d1}}} + }, + { + /* 1*16^3*G: */ + {{{0x2245573f, 0x01dfa36a, 0x0fd0a64f, 0x219dbcbd, 0x2d6bd250, 0x1e259cb9, 0x29e4d997, 0x2bb4b3c1, 0xe716}}, + {{0x069218d1, 0x017f09ad, 0x207c9b35, 0x0f437cbe, 0x39a851d1, 0x0ac19a1e, 0x072ab591, 0x18f9a53f, 0x3536}}}, + /* 3*16^3*G: */ + {{{0x257008ac, 0x3e61e4c1, 0x329edfb7, 0x3387b3b8, 0x1da22d19, 0x15562930, 0x07ce864e, 0x22635bd4, 0xd2bf}}, + {{0x327beb55, 0x04454d29, 0x1ff07988, 0x273842ad, 0x290c5667, 0x06576cfe, 0x377aa3f8, 0x2c72d69a, 0x69c0}}}, + /* 5*16^3*G: */ + {{{0x382f1580, 0x3435f2a5, 0x0203eb7f, 0x39377b89, 0x3064f8b0, 0x295ce47c, 0x3ce6087f, 0x0c13b960, 0x4d88}}, + {{0x1616edd7, 0x303ec5b5, 0x0eb1e110, 0x3f28ef5a, 0x3d6518aa, 0x1a002263, 0x0636ce8d, 0x139c26ac, 0x28a9}}}, + /* 7*16^3*G: */ + {{{0x20c38e11, 0x3e130f6b, 0x26e26ba5, 0x159086fa, 0x25af9e71, 0x1ce6480b, 0x00eeb326, 0x09c9f23f, 0x17c7}}, + {{0x2e90decd, 0x360d9aee, 0x20cdae3c, 0x14e65169, 0x01802e7e, 0x00bf33a4, 0x24b3c406, 0x293d3f99, 0x95c5}}}, + /* 9*16^3*G: */ + {{{0x232f36ea, 0x2557f62b, 0x13541c3d, 0x13d1a9ca, 0x0cb8b3cd, 0x0ec73f21, 0x050a8846, 0x3f6ab11d, 0x7e03}}, + {{0x0a68b8af, 0x2b308ff2, 0x05009d68, 0x27a5e693, 0x04af9941, 0x39ac5c06, 0x228da668, 0x357c4804, 0xdcf6}}}, + /* 11*16^3*G: */ + {{{0x1953baa9, 0x10f94a9b, 0x1e18de8d, 0x056ba192, 0x20b21426, 0x0deb0772, 0x3cf07616, 0x369a12c6, 0x8ce6}}, + {{0x352689e5, 0x239d70a3, 0x2a9341d7, 0x3ce61aed, 0x21b56807, 0x2cef2401, 0x3120be69, 0x13ee3ea4, 0x3d9f}}}, + /* 13*16^3*G: */ + {{{0x2f22a96a, 0x2ae3614e, 0x06ab8f94, 0x2c6ea767, 0x3ae2b008, 0x14d525d6, 0x0054a20a, 0x39cc1037, 0xb570}}, + {{0x085d1b00, 0x2ccfd987, 0x055cc9cc, 0x326ede96, 0x00cfbda7, 0x30dda6d7, 0x1e77f028, 0x2898e3dc, 0xdcd8}}}, + /* 15*16^3*G: */ + {{{0x189a7509, 0x3903ae51, 0x1fa80549, 0x09c2e590, 0x07f20de1, 0x0468f9d7, 0x3943b04a, 0x10c8f2ea, 0x44d9}}, + {{0x20437234, 0x0828ae6d, 0x14dd126e, 0x24f87f7c, 0x3b93586f, 0x08ef349d, 0x01f0a034, 0x2ce00210, 0xb2c5}}} + }, + { + /* 1*16^4*G: */ + {{{0x2eade3c4, 0x0fa11971, 0x1052a050, 0x12add272, 0x2586b471, 0x3190cd03, 0x1e90d8e5, 0x0d9bd3a4, 0xa018}}, + {{0x2b26e8d0, 0x11710809, 0x0614f37f, 0x3dca1391, 0x1d8369d5, 0x3395e0d2, 0x10b167c6, 0x3b05c504, 0xe2bb}}}, + /* 3*16^4*G: */ + {{{0x19e0af06, 0x38737ab1, 0x2ed958d6, 0x3ce62958, 0x05055c92, 0x34ed69b5, 0x1896450b, 0x07c02e23, 0x9cdf}}, + {{0x2216ade7, 0x35e8cb6d, 0x17ca5468, 0x2148b706, 0x0d94b082, 0x162ef372, 0x2ad664d9, 0x097fb4fc, 0x916d}}}, + /* 5*16^4*G: */ + {{{0x1305097e, 0x04dcae4e, 0x03ba5198, 0x3585c3a1, 0x00448338, 0x2c6cb415, 0x263edab6, 0x36757469, 0x45bf}}, + {{0x108ddc04, 0x12e8163a, 0x3d2c1595, 0x0ee74cef, 0x0ce90868, 0x220c151c, 0x2fd2bbad, 0x3704a156, 0x09d1}}}, + /* 7*16^4*G: */ + {{{0x363bd6df, 0x34c7c682, 0x166aec3c, 0x3f08f0b7, 0x095e6fd1, 0x3a7e700a, 0x2693b671, 0x2b45591d, 0xb599}}, + {{0x0efa09ac, 0x3a873a8e, 0x1134b458, 0x10313da4, 0x23c4166a, 0x1cd82e2c, 0x2b332463, 0x3477b13e, 0x6979}}}, + /* 9*16^4*G: */ + {{{0x27142d62, 0x3e184fcc, 0x03bc26da, 0x269a8d7e, 0x2854c11d, 0x18ac489f, 0x2ac0e926, 0x287c59cc, 0xf4dc}}, + {{0x3a618fc9, 0x327b3301, 0x1cd3d7fa, 0x25e6b3bf, 0x2bc659bb, 0x3ce06e46, 0x0cd46d49, 0x19f96d2d, 0x5511}}}, + /* 11*16^4*G: */ + {{{0x215fae61, 0x3b2c7fd1, 0x3395f821, 0x0571f713, 0x16bb5a7f, 0x1389039c, 0x09b66d9c, 0x1e2839b8, 0xf072}}, + {{0x096376f9, 0x1f432dd2, 0x037eabcf, 0x09c1c56e, 0x18f7d42c, 0x1e820862, 0x31ea5f7d, 0x06cac529, 0x1a68}}}, + /* 13*16^4*G: */ + {{{0x2466591f, 0x31381054, 0x3c68d6a0, 0x05cbaa3f, 0x2858ccbe, 0x0ead4cee, 0x20db0f14, 0x0915ebc2, 0x1fc5}}, + {{0x396f8cdb, 0x13bfbd5c, 0x2ec78224, 0x3e32b08c, 0x034e1629, 0x31dbf96d, 0x2bc11e9e, 0x060e0227, 0x489c}}}, + /* 15*16^4*G: */ + {{{0x322a8ebc, 0x09742e30, 0x0f967151, 0x24736dc6, 0x0a56d5a2, 0x3c2d6cc3, 0x0c5f4fd7, 0x006cc692, 0xfa25}}, + {{0x2a8a775b, 0x03649ed6, 0x0bc83318, 0x1638239b, 0x2fa8cbea, 0x14799869, 0x18962338, 0x0cac53e1, 0x71c9}}} + }, + { + /* 1*16^5*G: */ + {{{0x3d96dff1, 0x3df73b2d, 0x2d5fcfe8, 0x390c706a, 0x0d98d530, 0x1a82d5c3, 0x3e54ffef, 0x0e214507, 0x0ec7}}, + {{0x3c7b552c, 0x3b2106b1, 0x3ed78aa9, 0x149933a1, 0x0652511d, 0x3313bd60, 0x2875d91a, 0x13d3a1eb, 0xd622}}}, + /* 3*16^5*G: */ + {{{0x088d58e9, 0x070c92ac, 0x0e318385, 0x12970719, 0x02a7b6e9, 0x0a91a9f1, 0x24a86e99, 0x30ff71c1, 0x96da}}, + {{0x2ebebc5e, 0x00d24c4a, 0x087e6e38, 0x16fa26e5, 0x02c43968, 0x3312524e, 0x2c1ad856, 0x2bfceb51, 0xcb1f}}}, + /* 5*16^5*G: */ + {{{0x2db29f92, 0x254ab44c, 0x147b2c58, 0x08749c6e, 0x2b8f811d, 0x1770de2b, 0x0f312a10, 0x2c8f3ac5, 0xe297}}, + {{0x25e58ddb, 0x03ca5322, 0x1ed41416, 0x08f3aee1, 0x0d914912, 0x036eaee3, 0x370b4b48, 0x09483e32, 0xe137}}}, + /* 7*16^5*G: */ + {{{0x0ad88c33, 0x3650edee, 0x1746bcaf, 0x06b8e536, 0x24da97d9, 0x1af24834, 0x394b66b0, 0x08ce3eca, 0x1cd2}}, + {{0x248fb1b2, 0x0a3a9e10, 0x2ca1e496, 0x3f944c57, 0x36bc2713, 0x21902ac4, 0x348b096c, 0x337e0e2a, 0xfc3a}}}, + /* 9*16^5*G: */ + {{{0x3b26aa73, 0x14eb2270, 0x063a0e0f, 0x3df846c3, 0x3b1ee0cd, 0x32b4c37f, 0x1fbbfcb1, 0x35eb6e7a, 0xf462}}, + {{0x38479e73, 0x117ab05d, 0x0502cca2, 0x3a3828c0, 0x333c7a49, 0x0ee929a1, 0x053140d5, 0x03469e0d, 0x406a}}}, + /* 11*16^5*G: */ + {{{0x3cd015e3, 0x3b8780aa, 0x26502273, 0x243a565f, 0x095168af, 0x36facf2a, 0x30caf75b, 0x224974fd, 0xe0f6}}, + {{0x12157cce, 0x2a89350b, 0x22936bbd, 0x2e2d4e47, 0x34c77c55, 0x09a5b1c9, 0x03aa9536, 0x078c4392, 0x0853}}}, + /* 13*16^5*G: */ + {{{0x0bb76b12, 0x39b10c45, 0x21927691, 0x239d9dcf, 0x375a00ea, 0x20acc4ab, 0x3f57fc1d, 0x2b70554a, 0x28e4}}, + {{0x2c4747bd, 0x1f914e9f, 0x31628ff5, 0x282983c5, 0x1ea3f703, 0x12d96dae, 0x201b3f4e, 0x1313bf66, 0x14d7}}}, + /* 15*16^5*G: */ + {{{0x276ff697, 0x2fd6007f, 0x20764628, 0x26da2194, 0x2097c636, 0x07b6aece, 0x2805ed27, 0x2e89e52e, 0x85a0}}, + {{0x12142721, 0x027b5369, 0x10a58b93, 0x3a5ffe9e, 0x2daa551d, 0x1e434f73, 0x3e24a554, 0x0b987ab0, 0xadf3}}} + }, + { + /* 1*16^6*G: */ + {{{0x2392d805, 0x1c971773, 0x35405d43, 0x1ea01a61, 0x23449aa8, 0x1536abea, 0x293d7a4a, 0x3733d31a, 0xf8f5}}, + {{0x2cda02fa, 0x09986545, 0x12143ba0, 0x3cf69929, 0x21327351, 0x34f8cd91, 0x23054389, 0x1db3d9b5, 0xe581}}}, + /* 3*16^6*G: */ + {{{0x3fa046f7, 0x2752cc59, 0x207309d1, 0x0443ce40, 0x2e2d4517, 0x212b2251, 0x083a94e0, 0x2392a196, 0xe12c}}, + {{0x212646ad, 0x0e9568a2, 0x33119345, 0x03013844, 0x3126f6dd, 0x2cfb54e4, 0x1a2f3433, 0x011843f6, 0x7cec}}}, + /* 5*16^6*G: */ + {{{0x02853c43, 0x26c49fa3, 0x222e466b, 0x059b15eb, 0x11323648, 0x238bbf8f, 0x292093d0, 0x351d05e5, 0x394b}}, + {{0x2064469d, 0x05e0a332, 0x10fcf0cb, 0x0bd9c4b6, 0x160767d5, 0x38ff0bc7, 0x1c6b9207, 0x1b548547, 0x2b4d}}}, + /* 7*16^6*G: */ + {{{0x3c722e94, 0x30b75ce7, 0x1058961e, 0x36040e5b, 0x1404334e, 0x31995b16, 0x282e9445, 0x0e37ce37, 0xca85}}, + {{0x1049a527, 0x28298b7c, 0x08b26a43, 0x0254ea29, 0x3b9f12f2, 0x1cc49a87, 0x205c311e, 0x3f10bae7, 0x3b27}}}, + /* 9*16^6*G: */ + {{{0x1cad6309, 0x1c5d18a7, 0x239ff488, 0x0687f0bc, 0x267b3dd3, 0x2dd18932, 0x17b75a1b, 0x06967c8d, 0x663e}}, + {{0x09981f28, 0x0ca1ae8e, 0x2eb52bd5, 0x01f51100, 0x1cf918b9, 0x0b060f2c, 0x2a8c3c10, 0x2dcee019, 0x292f}}}, + /* 11*16^6*G: */ + {{{0x22c23d03, 0x09d6c914, 0x3c7ff249, 0x286c1363, 0x3beeab3b, 0x0db08dc1, 0x3667096c, 0x3bf9cc18, 0xa2d9}}, + {{0x3085db74, 0x00b93013, 0x039df451, 0x0269fa56, 0x101b92ea, 0x0c10db1c, 0x01b8f155, 0x148a3321, 0x1cc8}}}, + /* 13*16^6*G: */ + {{{0x07d4c6d1, 0x1d57e59c, 0x2d9fffb1, 0x18b35466, 0x3f35d0f6, 0x2442d49c, 0x1a9efe0b, 0x384ad22c, 0x5657}}, + {{0x0106bdec, 0x20c0fca6, 0x052c1418, 0x3e68d685, 0x2e6a0abf, 0x2ce43cce, 0x149f9acf, 0x2fbd2e37, 0x72b5}}}, + /* 15*16^6*G: */ + {{{0x1933564a, 0x21953755, 0x1e3af44f, 0x1a2d3ebb, 0x2d8d2b7a, 0x13b7199d, 0x2e001086, 0x18857502, 0x5b68}}, + {{0x0204ef63, 0x2d7c1162, 0x078869f3, 0x0abb88a2, 0x1d95de39, 0x0c315346, 0x2264552d, 0x3a9a73ce, 0x76b5}}} + }, + { + /* 1*16^7*G: */ + {{{0x2f922dbd, 0x21288c5d, 0x399218f9, 0x298c4587, 0x0d71b91c, 0x17aab639, 0x1af313f8, 0x2dafff53, 0x6d28}}, + {{0x20ef3cff, 0x12affc0a, 0x04da2994, 0x093a7c2e, 0x0b4a1c4c, 0x2f869873, 0x1d2fa40f, 0x36414507, 0xaf39}}}, + /* 3*16^7*G: */ + {{{0x1b168b64, 0x16437fe6, 0x186c840b, 0x14f40ab1, 0x14467ea1, 0x3c2417f0, 0x3e3ddd3d, 0x055e9fef, 0x7cd3}}, + {{0x1abbb16b, 0x15b034ad, 0x2e02e358, 0x2b1366dc, 0x1bfafb13, 0x1a39e2f3, 0x12c62205, 0x234845ca, 0x9ca0}}}, + /* 5*16^7*G: */ + {{{0x06ef29e8, 0x0ac71be8, 0x1d9aee3b, 0x371552c2, 0x05356264, 0x090c6675, 0x1f8c456b, 0x02f6d7cb, 0xed86}}, + {{0x39b90f8f, 0x00687126, 0x18daa335, 0x18c3d70b, 0x017bb1e7, 0x2fdacd01, 0x1a7fd7c6, 0x39d0dd75, 0xb837}}}, + /* 7*16^7*G: */ + {{{0x3636e617, 0x37e462cf, 0x1f1cf599, 0x37340ef0, 0x272c9d47, 0x3870b9f8, 0x21243735, 0x3323f474, 0x6868}}, + {{0x3cbb3d27, 0x323773cf, 0x0384cd71, 0x3f8c3229, 0x313f0a60, 0x1640e1e4, 0x3f9e6b3c, 0x02296e46, 0xeed0}}}, + /* 9*16^7*G: */ + {{{0x113e2a34, 0x1e768a98, 0x23a11e2c, 0x074b9973, 0x2fd31829, 0x32d27c42, 0x0fe202c5, 0x2cd83ab2, 0xec03}}, + {{0x384566d6, 0x10890fba, 0x1a136b7a, 0x2a055b99, 0x2122728a, 0x3f788404, 0x058437be, 0x03fed828, 0x8602}}}, + /* 11*16^7*G: */ + {{{0x087c1b18, 0x3ab83397, 0x04991a25, 0x078b2d52, 0x1056fa10, 0x0c0d6964, 0x0b90de6a, 0x1928e79e, 0xa794}}, + {{0x3b94809a, 0x3ad61425, 0x1562821b, 0x2637a71c, 0x1a89f60d, 0x295e1e7a, 0x058cc249, 0x3d38fdca, 0x1361}}}, + /* 13*16^7*G: */ + {{{0x1ed10d26, 0x2538a31b, 0x1e595f65, 0x26afbe0a, 0x330ccc5a, 0x247eda53, 0x3bcc790e, 0x3ca02aa3, 0x544e}}, + {{0x36dafcc2, 0x3f093dc9, 0x22c06ae2, 0x0f5be5db, 0x0d70d368, 0x2c77fa36, 0x2c2ce9d6, 0x07277116, 0x95b9}}}, + /* 15*16^7*G: */ + {{{0x37ad18e6, 0x1251e7e2, 0x13cad5e2, 0x2b4f9e63, 0x0aff9b57, 0x14f211ad, 0x0c6214de, 0x1b2217cd, 0xe2c2}}, + {{0x2554cfad, 0x36bf946a, 0x1981de4a, 0x3145729c, 0x17ba113b, 0x3899ba84, 0x0818851c, 0x06ca13d2, 0xb212}}} + }, + { + /* 1*16^8*G: */ + {{{0x185a5943, 0x296a7888, 0x065dfb63, 0x2e464d97, 0x2c71da1a, 0x15acc898, 0x2af89216, 0x1ad02bc8, 0x7fe3}}, + {{0x299ca101, 0x143454b1, 0x38af212d, 0x2cf5619e, 0x1ca6f174, 0x27d0101f, 0x236249f0, 0x3516096d, 0xe697}}}, + /* 3*16^8*G: */ + {{{0x1f0922a8, 0x1a9e0247, 0x05cf8d97, 0x243a7495, 0x2f8b808e, 0x09395808, 0x22d73809, 0x1a9016d3, 0x4b65}}, + {{0x199a80bb, 0x36b72b16, 0x1850f694, 0x1cee78ae, 0x18c4d6d4, 0x01330957, 0x3783920d, 0x28c744b9, 0xee1e}}}, + /* 5*16^8*G: */ + {{{0x29d07e9e, 0x1413e221, 0x2a60c36b, 0x279f287d, 0x3d8e5ea0, 0x2caf83ec, 0x1e13d93d, 0x255baf59, 0x9d78}}, + {{0x03d8c8ee, 0x1375856b, 0x394c7b2f, 0x1828b68e, 0x3210ce74, 0x0aa27074, 0x2a8cd654, 0x279bbd23, 0xd514}}}, + /* 7*16^8*G: */ + {{{0x3dc4950f, 0x19dd4219, 0x13942076, 0x106cab6f, 0x1b631657, 0x0da11b93, 0x13fa9572, 0x049cb84d, 0x4acb}}, + {{0x23d8b4df, 0x1b1b9111, 0x1866ac56, 0x2790a02d, 0x31e29fdf, 0x0a63db31, 0x3cdad8cf, 0x3483edd0, 0x726c}}}, + /* 9*16^8*G: */ + {{{0x2d7e8cbd, 0x1031e9ef, 0x007d816f, 0x199fe2bc, 0x01464a2a, 0x114d5432, 0x317b4234, 0x17afc69a, 0x640c}}, + {{0x3ec5a5db, 0x1b8a40f2, 0x0ff9b020, 0x01a7ec63, 0x1eab9eba, 0x271badc0, 0x0fd2f2ae, 0x223f60a7, 0xd6ae}}}, + /* 11*16^8*G: */ + {{{0x3e86bddc, 0x1c2812c1, 0x35ce3d5f, 0x349ae5e5, 0x1b6b9bf1, 0x158b2437, 0x04b32451, 0x012c6d0a, 0x8bba}}, + {{0x29e349c4, 0x088f1687, 0x0196e5f5, 0x2b3f793d, 0x19437ac6, 0x2fe4859a, 0x08ebf659, 0x26702708, 0xc340}}}, + /* 13*16^8*G: */ + {{{0x0257f582, 0x05c39e01, 0x2c3a258d, 0x26427ab7, 0x1a5fe41f, 0x1a50fdf1, 0x137e210a, 0x15d13fb3, 0x8b0a}}, + {{0x37372d4b, 0x205ffb7c, 0x31607664, 0x36d1ae9e, 0x237d4656, 0x285684df, 0x2c739662, 0x2913b035, 0x9e57}}}, + /* 15*16^8*G: */ + {{{0x185e797e, 0x3c5127e6, 0x23c31683, 0x1b8893cb, 0x1678a6f0, 0x15bd24f6, 0x078971f8, 0x3fe5f099, 0x0a13}}, + {{0x139d666f, 0x0c9eae7d, 0x180c3928, 0x1fdbc29d, 0x21dc3ff2, 0x36063a3e, 0x083d5917, 0x2592c897, 0xeb1a}}} + }, + { + /* 1*16^9*G: */ + {{{0x3dde3445, 0x2bfd3f87, 0x2aea7817, 0x2eea7768, 0x26519e76, 0x1c7f9ffc, 0x061e6853, 0x2d8e135c, 0x6965}}, + {{0x18855113, 0x3310e278, 0x25f99d97, 0x1f398146, 0x332dbef4, 0x392598e1, 0x02511325, 0x36b8e712, 0xd1bc}}}, + /* 3*16^9*G: */ + {{{0x088acfc5, 0x17903e5a, 0x2689789f, 0x3bd626cd, 0x091a71b1, 0x39f76f50, 0x1c7da027, 0x3147779d, 0xe1cb}}, + {{0x2249a225, 0x2f17fb56, 0x2bfba523, 0x34ca4afb, 0x39e23ce7, 0x09d93ff6, 0x3daedb31, 0x20e5f379, 0xec67}}}, + /* 5*16^9*G: */ + {{{0x2107ccc6, 0x163a94ff, 0x03c82287, 0x0e25f855, 0x2900481d, 0x3a74a116, 0x38aa1731, 0x099e5c44, 0x9c3f}}, + {{0x3dea9152, 0x101e5334, 0x1f9b1868, 0x2a3f53a5, 0x3e6eca51, 0x0dd7d2fc, 0x11d9c8be, 0x0306d92d, 0xdaee}}}, + /* 7*16^9*G: */ + {{{0x15a449e7, 0x0717ad0e, 0x13c2be42, 0x28a80d39, 0x00922b2f, 0x3eb05ec5, 0x32d72796, 0x3655df1a, 0x5c30}}, + {{0x2e2677d0, 0x1c3a9206, 0x3ce790e7, 0x179014f0, 0x0592d0b7, 0x2d97de67, 0x21b92164, 0x38ed6c23, 0x8025}}}, + /* 9*16^9*G: */ + {{{0x0b8ceb07, 0x2956300a, 0x3ee271cf, 0x1e494aff, 0x28d99553, 0x138ac1fa, 0x29682afe, 0x2fc8c323, 0xaa3b}}, + {{0x1fd83984, 0x26a118ba, 0x2b3f9eb9, 0x1c6caf1e, 0x1162ec3b, 0x32c3f932, 0x2c26844d, 0x032c2707, 0xe632}}}, + /* 11*16^9*G: */ + {{{0x03bfd1f1, 0x103a9556, 0x1d65732e, 0x0db70d45, 0x0001943a, 0x183f2645, 0x3418179e, 0x0c9444cc, 0xab4a}}, + {{0x08e1c233, 0x044e5843, 0x39e98cf2, 0x1f64c909, 0x2fe057a5, 0x2cef4104, 0x08668b4e, 0x192ec0db, 0xea6c}}}, + /* 13*16^9*G: */ + {{{0x0b1d6d3f, 0x2101b5e0, 0x2eebb890, 0x0dd9a293, 0x25a8105f, 0x0dfd7362, 0x15d77f73, 0x2c96777b, 0xdba9}}, + {{0x09cd8133, 0x10ba4a0a, 0x12bd93cc, 0x2f66f114, 0x2b871448, 0x2a653d3f, 0x35b7b5ac, 0x0b4fd5d4, 0xb386}}}, + /* 15*16^9*G: */ + {{{0x31fa2a6a, 0x1e680e00, 0x30e4b256, 0x3f075616, 0x23cdfe34, 0x375d0ac6, 0x0274507a, 0x3d310ba6, 0x1998}}, + {{0x06415142, 0x01fb6d2f, 0x37258b56, 0x1b008e1e, 0x38a1e94c, 0x03e0022d, 0x2fa10970, 0x105b4642, 0x2ebb}}} + }, + { + /* 1*16^10*G: */ + {{{0x0d9aefbd, 0x163f29b1, 0x3b957752, 0x3f91ec9c, 0x3c43dc1e, 0x2a7c3506, 0x29d7632c, 0x0d072319, 0x0fbc}}, + {{0x13e71ca0, 0x34edbaa7, 0x00a9ff1e, 0x02c1a788, 0x17d3d395, 0x052c7525, 0x20e3fe40, 0x0898cbcd, 0xbd80}}}, + /* 3*16^10*G: */ + {{{0x29434837, 0x1e5b7ffb, 0x220c1bb8, 0x2cc502e1, 0x0fb06dad, 0x1071bfed, 0x07aedb13, 0x062af12a, 0xd76d}}, + {{0x3b215b4c, 0x3ea813e6, 0x1b7ccc24, 0x291639dd, 0x2b933290, 0x390853de, 0x16644de0, 0x1368cbb6, 0xf6bc}}}, + /* 5*16^10*G: */ + {{{0x1c07f222, 0x0ba27c86, 0x060fe7d0, 0x388718eb, 0x1753d1c5, 0x2074687c, 0x3ff604f4, 0x31941859, 0xd5c0}}, + {{0x0c6ffd57, 0x0bbda478, 0x0813a86e, 0x3cfd469e, 0x1f75b9ba, 0x3831dfd2, 0x3b8850cd, 0x02e18205, 0x15a3}}}, + /* 7*16^10*G: */ + {{{0x0e93bfa6, 0x291c5a89, 0x1a1362a4, 0x274a5682, 0x0c9fe0d3, 0x272e99ad, 0x2f62ce54, 0x0d939291, 0x734c}}, + {{0x18d10774, 0x31be9e66, 0x10297c4f, 0x284d8822, 0x0c5f48ec, 0x26078d48, 0x39d049de, 0x0540eaa9, 0x0995}}}, + /* 9*16^10*G: */ + {{{0x1fa194ae, 0x03ad45fd, 0x2054aecf, 0x100a4766, 0x1eb14906, 0x1d7674aa, 0x26a89011, 0x367681ed, 0x79a3}}, + {{0x1fcf634b, 0x3f197a72, 0x379bc4d4, 0x35097ccb, 0x2f03d86b, 0x19c6e162, 0x0b1b34b3, 0x36f29c95, 0x84e1}}}, + /* 11*16^10*G: */ + {{{0x21e8b7fe, 0x2b241800, 0x385b26a6, 0x3438b85d, 0x3c98e05d, 0x3932ab73, 0x305828a3, 0x3f425356, 0x3393}}, + {{0x023c6821, 0x30509108, 0x29b94b70, 0x15acc2a2, 0x1a668d8e, 0x3fabb671, 0x3beb82ea, 0x0defb219, 0x1304}}}, + /* 13*16^10*G: */ + {{{0x21528cf6, 0x0255e755, 0x250694ea, 0x280942bd, 0x1b0a52e6, 0x2d161bb9, 0x227e15e1, 0x0a2184d1, 0xa16b}}, + {{0x3ce93f3b, 0x02e483e7, 0x3cc80138, 0x24fef204, 0x1150f434, 0x33b5e760, 0x3ad99913, 0x262ba14d, 0xf405}}}, + /* 15*16^10*G: */ + {{{0x0c8db2e0, 0x144299ae, 0x30d73583, 0x0f2f7057, 0x1a74f647, 0x3226aea5, 0x3474cbf6, 0x33880638, 0xd317}}, + {{0x274bc9a9, 0x16cd28ac, 0x2b860f3a, 0x289d3408, 0x179136ca, 0x0b0fa38e, 0x3844b99c, 0x0842a424, 0xd61a}}} + }, + { + /* 1*16^11*G: */ + {{{0x23fe67b2, 0x1b8c65ea, 0x22e3338c, 0x2a2ff9c2, 0x3323b234, 0x19ae6ea5, 0x085dcbc6, 0x3090ddcf, 0x6608}}, + {{0x25b47a28, 0x248ff973, 0x0c543081, 0x0ac567d0, 0x06e03fc2, 0x3d90369d, 0x1c168846, 0x05afb148, 0xa1a9}}}, + /* 3*16^11*G: */ + {{{0x2bc73e02, 0x0f9baab4, 0x365312c1, 0x259853ba, 0x17863184, 0x2a6045f5, 0x1dc23206, 0x1ab8a9b1, 0xf095}}, + {{0x0611219d, 0x34b3da66, 0x3ae94572, 0x0b41236e, 0x03935667, 0x08162bca, 0x0e03c76e, 0x39980451, 0x433f}}}, + /* 5*16^11*G: */ + {{{0x1c5fe45c, 0x3788b794, 0x07c0f597, 0x2ca06a0e, 0x37283488, 0x3c9275f3, 0x2a60ca52, 0x3afa8f28, 0xdb98}}, + {{0x3ef45a22, 0x129c0710, 0x2480e1c4, 0x20c813ea, 0x112c8ce9, 0x144a7762, 0x185a2de1, 0x3cc2dd6f, 0xe0c0}}}, + /* 7*16^11*G: */ + {{{0x22128eac, 0x3d679837, 0x0af1ccba, 0x11d63573, 0x2a51690c, 0x29acedf5, 0x1a5f421b, 0x300582b7, 0x0a73}}, + {{0x24f1180d, 0x2164a475, 0x355d9ca3, 0x0dd67c5d, 0x350a7c79, 0x32db7653, 0x2838ca55, 0x36958113, 0x443f}}}, + /* 9*16^11*G: */ + {{{0x23ccbc30, 0x196a4cc5, 0x1349618c, 0x37f97487, 0x0997249e, 0x34dd99e8, 0x34f2370e, 0x0830d1f2, 0x3787}}, + {{0x1315729e, 0x2880c9fc, 0x1348f846, 0x2f3e5574, 0x279b6d16, 0x062b02aa, 0x2538c931, 0x376e73dc, 0x8f1b}}}, + /* 11*16^11*G: */ + {{{0x03bb1b6b, 0x192a3795, 0x07c2bfaa, 0x17fbccbd, 0x15a62157, 0x20463041, 0x31a619d9, 0x34876de2, 0xfe8f}}, + {{0x30eaaf93, 0x1ed766e8, 0x0abf8899, 0x053773fc, 0x2d13c00f, 0x0a3a57d6, 0x16e3769e, 0x08abb0c9, 0x791e}}}, + /* 13*16^11*G: */ + {{{0x344b7cea, 0x20156672, 0x16cf87de, 0x111a5024, 0x33dcca47, 0x010089e2, 0x37e2ee82, 0x07f55e7e, 0x2c33}}, + {{0x15d1c9c2, 0x3f0ad1ab, 0x13094077, 0x249447fc, 0x3dd65061, 0x0fcf630e, 0x21e76fcf, 0x1ec73381, 0x2056}}}, + /* 15*16^11*G: */ + {{{0x0112278c, 0x3e4a6cde, 0x28d9a158, 0x00592742, 0x044b66dd, 0x22d321fe, 0x1a320a34, 0x301b1194, 0x509b}}, + {{0x0e178f66, 0x321d7262, 0x335f945e, 0x197fa1b9, 0x0f64570f, 0x03d3c5ee, 0x246ec176, 0x1a30adc8, 0xb4b1}}} + }, + { + /* 1*16^12*G: */ + {{{0x17e55104, 0x0baebe00, 0x38e9c71c, 0x0ea0d7ee, 0x0b561cf7, 0x3a4f0d36, 0x3873763d, 0x1d9489ed, 0xd8de}}, + {{0x252e08cd, 0x280bbe03, 0x140db1b2, 0x3dcff386, 0x1cf924c2, 0x318a2b47, 0x3f2d15c4, 0x25196f84, 0x2fd2}}}, + /* 3*16^12*G: */ + {{{0x2987bfd3, 0x24e70b1f, 0x0c4284c6, 0x3151cbfd, 0x1dd19187, 0x37efabeb, 0x18e33551, 0x1e1bef54, 0xe3a5}}, + {{0x0cc23e7d, 0x3b4c6db2, 0x128e0817, 0x373cbb36, 0x18210ca3, 0x1ee7fd2b, 0x040e6847, 0x2b4254d6, 0xf74b}}}, + /* 5*16^12*G: */ + {{{0x22d5056e, 0x19e54748, 0x247a07cb, 0x372d69f8, 0x2e5e480e, 0x097ff3a5, 0x120d4115, 0x1c107b29, 0x42a9}}, + {{0x30f7db11, 0x21053722, 0x29fd1fd4, 0x13920f5b, 0x163b26b6, 0x0db749ad, 0x087066ec, 0x1fd9b3c0, 0xf2fc}}}, + /* 7*16^12*G: */ + {{{0x13dafd3b, 0x19d17e47, 0x1cb3956c, 0x2e267c0b, 0x1379d66f, 0x0cb0bb59, 0x3964cfe2, 0x29c6c709, 0x0d6c}}, + {{0x1a6fe6e8, 0x1ab7c508, 0x288771ad, 0x08922afb, 0x07de58a0, 0x1252809c, 0x2293d9fe, 0x0c2ce3f7, 0xa851}}}, + /* 9*16^12*G: */ + {{{0x31131f8b, 0x1afe71ff, 0x3a20d4df, 0x191a5833, 0x031fb469, 0x308b7e71, 0x1a3d97d4, 0x329eb619, 0x05ed}}, + {{0x3a6f779f, 0x3b3c2c66, 0x0e89d490, 0x1494017c, 0x0271be33, 0x275c6d7c, 0x086bc01c, 0x2207923a, 0x9e58}}}, + /* 11*16^12*G: */ + {{{0x2b597e4d, 0x323e7d07, 0x37d1a319, 0x1d3cc979, 0x371c1149, 0x2d168ced, 0x3a0a4121, 0x301582f1, 0x5a13}}, + {{0x241856e0, 0x3df921a7, 0x1136664a, 0x37a1ead6, 0x2d73ce7b, 0x346283c8, 0x397ff51f, 0x0f04e243, 0xc9e7}}}, + /* 13*16^12*G: */ + {{{0x0260faf0, 0x2a9e2585, 0x3e95935d, 0x2ef4d165, 0x0f272ea2, 0x113869a0, 0x36e75431, 0x1595805e, 0x96b2}}, + {{0x2366d412, 0x03909483, 0x07d4f5ac, 0x02efe61c, 0x3f99e189, 0x36395cce, 0x37cac00a, 0x29a8006c, 0xdcf8}}}, + /* 15*16^12*G: */ + {{{0x2ad13276, 0x12686f92, 0x1c043c7a, 0x18d43aba, 0x3771a3ca, 0x04acace1, 0x0de2426f, 0x06443107, 0x0b97}}, + {{0x0a84dadb, 0x0ce3cd08, 0x270fae3b, 0x0f5e4a60, 0x36811f59, 0x0b916cef, 0x2eefbd4e, 0x121bbc01, 0xac28}}} + }, + { + /* 1*16^13*G: */ + {{{0x071e5c83, 0x3a9af248, 0x142a0bee, 0x349fc661, 0x18e5b18b, 0x2116dca9, 0x2d73f20a, 0x32505409, 0x54cc}}, + {{0x140916a1, 0x3f423bdc, 0x18ee496c, 0x2782f317, 0x12bf2292, 0x3e1c576b, 0x145323a8, 0x0fd16d14, 0x1c43}}}, + /* 3*16^13*G: */ + {{{0x2f76167c, 0x3178d88a, 0x07467394, 0x0bd08b31, 0x0cd9f22f, 0x08b1a4b7, 0x2ff9539c, 0x0bb72dcf, 0x8758}}, + {{0x2f4d7ff6, 0x31beed85, 0x3197be86, 0x00a3c19d, 0x3236a888, 0x040b0f0d, 0x24a7bfde, 0x250d42b5, 0x075b}}}, + /* 5*16^13*G: */ + {{{0x34de6611, 0x19c8fba1, 0x3821fb04, 0x3d95ce52, 0x26f11e33, 0x16dcd8d5, 0x336db1c2, 0x1eb287c9, 0x4a10}}, + {{0x18a805fe, 0x0d63afb9, 0x02132ac0, 0x17551e97, 0x00052e07, 0x3993a3dc, 0x3ef3934c, 0x09944018, 0x809b}}}, + /* 7*16^13*G: */ + {{{0x2dcfecb0, 0x32e93b41, 0x0a8d846f, 0x20ff474c, 0x3f49f6e9, 0x28383526, 0x2dfc9654, 0x0bacdcaa, 0xfd40}}, + {{0x2da08de8, 0x0164fcf7, 0x1e65e791, 0x12d3092f, 0x2ba86b1a, 0x1898e26e, 0x23a22e9a, 0x100c3769, 0xd6b3}}}, + /* 9*16^13*G: */ + {{{0x154659ed, 0x2d37583d, 0x15d966e5, 0x2b8f4886, 0x09d0a07f, 0x2e381ffb, 0x075155df, 0x2cd19186, 0x467b}}, + {{0x2800cf83, 0x2c81f42c, 0x1013e009, 0x06f04373, 0x382cd370, 0x0b3561b6, 0x178e8a1f, 0x3ff416aa, 0xd01e}}}, + /* 11*16^13*G: */ + {{{0x1c97e515, 0x3992612b, 0x1885a5fe, 0x0535b0ce, 0x1ec7e569, 0x1e6d8c3a, 0x1c0e46c8, 0x2e63e337, 0xcf66}}, + {{0x006c8a51, 0x160853aa, 0x190033a9, 0x3c1d1636, 0x2c6a7b33, 0x16d040d3, 0x061211c2, 0x1c5ee411, 0x0a70}}}, + /* 13*16^13*G: */ + {{{0x186154e5, 0x2e94a840, 0x2afa0dd3, 0x100a99a6, 0x08677086, 0x32254eb5, 0x3aa34751, 0x14b183ef, 0x3d92}}, + {{0x1603a8a2, 0x1ff24fda, 0x07dd7077, 0x287edf5f, 0x2b4cf3ae, 0x24cd0a25, 0x29d7fc44, 0x007734be, 0x3d0d}}}, + /* 15*16^13*G: */ + {{{0x2a4a8daa, 0x0ed8ed8a, 0x28a5ca3d, 0x041803bc, 0x0a968ce5, 0x3ad6d23d, 0x1769c760, 0x0e2c9a22, 0x2bbe}}, + {{0x1236e49b, 0x3821dd3a, 0x3eb6e7d7, 0x00ace938, 0x16085099, 0x33fbe47e, 0x3b36f5e2, 0x01fd8034, 0xf857}}} + }, + { + /* 1*16^14*G: */ + {{{0x22d32936, 0x0c3eddc4, 0x2847f01c, 0x03340b8c, 0x3d7f38e4, 0x331f4544, 0x0a47d9f6, 0x03165e05, 0xc544}}, + {{0x07cabfd4, 0x290be8dd, 0x1e41e5d9, 0x29b4a18c, 0x2cf4acd8, 0x3078748f, 0x21fa72ed, 0x3a6e8e0f, 0xd27e}}}, + /* 3*16^14*G: */ + {{{0x3989a8e1, 0x361407b1, 0x0ee4bdd7, 0x0765bcdd, 0x1cfe0a7c, 0x03811e6e, 0x3a79b750, 0x00f11737, 0x3e4d}}, + {{0x041c240a, 0x21e44e21, 0x3bd67409, 0x2bc6357c, 0x0aa719ff, 0x045f2b5f, 0x26475aac, 0x11342056, 0x12f7}}}, + /* 5*16^14*G: */ + {{{0x19bb7902, 0x24e6a343, 0x2b7c73f6, 0x309b1ca1, 0x085e9fd8, 0x28927a51, 0x210359a9, 0x21126cf5, 0x01b6}}, + {{0x203ee653, 0x35fd12c7, 0x1836682c, 0x3ac9811c, 0x2d1581fc, 0x0663970d, 0x39c3e0bf, 0x18e87a4d, 0xe590}}}, + /* 7*16^14*G: */ + {{{0x0371d9fe, 0x0a6d5b53, 0x199d6bbc, 0x12cd5b06, 0x2b3a4cf0, 0x25569f0e, 0x09ca2335, 0x0f2c6b33, 0x952c}}, + {{0x0189a13f, 0x1db39b49, 0x008c75ed, 0x11193c46, 0x2ce5d066, 0x3e44dbdb, 0x22f06a7d, 0x2151bdf5, 0x59b9}}}, + /* 9*16^14*G: */ + {{{0x0bc2c885, 0x11fff1da, 0x264e57c8, 0x147b9dd4, 0x17cde515, 0x2601142e, 0x26eac858, 0x13b856c5, 0xdfcb}}, + {{0x1345d92e, 0x1752990c, 0x3abe9757, 0x1dce251e, 0x2c0f411c, 0x13f09b20, 0x213a153c, 0x08e55541, 0x536a}}}, + /* 11*16^14*G: */ + {{{0x3510208e, 0x0e2e14af, 0x0d794387, 0x23338b61, 0x3c97bbdb, 0x1ebce811, 0x2500c8a8, 0x19b026f9, 0x1579}}, + {{0x0d207357, 0x183bb894, 0x2da43dfd, 0x23f1910c, 0x0cbe0700, 0x3fdedeee, 0x2264eabd, 0x1b56adc4, 0x4044}}}, + /* 13*16^14*G: */ + {{{0x0b96fe13, 0x327f32fa, 0x0852ea81, 0x2492b4ed, 0x3f6e23e4, 0x06a3fe04, 0x2990ad6e, 0x078f12c7, 0xc6b2}}, + {{0x37bb1417, 0x001ae5ab, 0x1e6d2d6a, 0x1954245e, 0x2b28a2ff, 0x2de078d3, 0x34d48e54, 0x337630cc, 0x335b}}}, + /* 15*16^14*G: */ + {{{0x03936565, 0x0d96066b, 0x37fa4c7c, 0x29ecdb65, 0x1522d997, 0x2f2a754e, 0x3296f0b4, 0x39311e31, 0xa231}}, + {{0x35ec5f19, 0x2b95a818, 0x2f154268, 0x295b8025, 0x03cf942b, 0x253b1a20, 0x3be91c0d, 0x3262fb1f, 0x80e0}}} + }, + { + /* 1*16^15*G: */ + {{{0x3066fd48, 0x3e7d05ca, 0x0971583b, 0x0dc4072e, 0x3adca61c, 0x1e6e5e9a, 0x3f1c506c, 0x159e9089, 0x241c}}, + {{0x12857b08, 0x3df4b19e, 0x2a366057, 0x2a1c4e2b, 0x3203a48e, 0x0e05f010, 0x02d4b936, 0x0b64f50c, 0x40a6}}}, + /* 3*16^15*G: */ + {{{0x0df9591d, 0x187df6e4, 0x2b4c82a8, 0x3b0eb090, 0x327218dc, 0x034f12ac, 0x178e9cba, 0x348ee09a, 0xde2f}}, + {{0x0457ad84, 0x13865cf4, 0x0c036a4b, 0x26a287e2, 0x392ebbda, 0x32dfb212, 0x243f305e, 0x1c44ced8, 0x400d}}}, + /* 5*16^15*G: */ + {{{0x3562282c, 0x3aa0952b, 0x0fbc3772, 0x0bcebe4e, 0x211340f0, 0x2522c093, 0x0cbdd993, 0x226c0c13, 0x8df8}}, + {{0x21d195cd, 0x095aaf65, 0x2f9bb157, 0x1fdc1133, 0x0af35e24, 0x10798c62, 0x1ceed6c7, 0x16d9cc81, 0x7452}}}, + /* 7*16^15*G: */ + {{{0x0dddb2dd, 0x2754a254, 0x02c0da6f, 0x22193373, 0x12f24507, 0x3ee033c5, 0x380f8001, 0x1d633662, 0xa0fd}}, + {{0x33ede6b2, 0x3f653fe1, 0x1409a7c7, 0x233a5be2, 0x308f311c, 0x247f4c4e, 0x368d5f86, 0x360d704c, 0x53e5}}}, + /* 9*16^15*G: */ + {{{0x0f542e36, 0x0232ea81, 0x13415c2e, 0x08bfebe8, 0x2335d84e, 0x16499e51, 0x1a0f67de, 0x31611cb4, 0x3170}}, + {{0x363288b5, 0x1b11d6bb, 0x199be1bc, 0x1bdd5a56, 0x39773d00, 0x05424ffa, 0x27fe2375, 0x0d84bf0e, 0xb208}}}, + /* 11*16^15*G: */ + {{{0x1c7548e9, 0x266c8e97, 0x092d54c7, 0x376a01c2, 0x063fe5d8, 0x1205a53c, 0x13e029db, 0x2c2a428b, 0x92fa}}, + {{0x0917758f, 0x31c4b341, 0x32d08488, 0x28371a3b, 0x2679ffc8, 0x05c53830, 0x246bcf43, 0x2d1a032c, 0x55e7}}}, + /* 13*16^15*G: */ + {{{0x1498f7f8, 0x0360142e, 0x2411622e, 0x37d9f4c9, 0x2c8712c4, 0x2f846c64, 0x355179d0, 0x196f8600, 0x91b0}}, + {{0x3f23195b, 0x31d03678, 0x389639e3, 0x0b1ed095, 0x17e264df, 0x3fcd2400, 0x31620ff9, 0x1bddfed9, 0x035b}}}, + /* 15*16^15*G: */ + {{{0x0060e322, 0x0772fb89, 0x1c4d14b5, 0x3371cdea, 0x1ab9923e, 0x241a5d22, 0x1cb3a9c3, 0x07d332b2, 0x8e4a}}, + {{0x104619d7, 0x38860f36, 0x14fbfe04, 0x002a6365, 0x2e7bc4fb, 0x017b4901, 0x0d7752fb, 0x2dd7acca, 0x4936}}} + }, + { + /* 1*16^16*G: */ + {{{0x0e14db63, 0x039d72d2, 0x1651f7e9, 0x124eeaab, 0x2e25de29, 0x0964b8c9, 0x1aaa5849, 0x08af0a04, 0x0fa8}}, + {{0x1f462ee7, 0x10449151, 0x0fe82f5e, 0x2c699414, 0x1f188b34, 0x2b52f2cf, 0x3a80d6f4, 0x12ba3d76, 0xbff4}}}, + /* 3*16^16*G: */ + {{{0x3db3cdec, 0x14b114fd, 0x228ebf57, 0x3bce84ac, 0x2a4bc8db, 0x199179ef, 0x12f5ce59, 0x30193fe4, 0x85b2}}, + {{0x0a03f81f, 0x3d342081, 0x24cf8e08, 0x2602cd39, 0x0c6d00dc, 0x1fe8b4bf, 0x1153663c, 0x09e3ce74, 0xf64b}}}, + /* 5*16^16*G: */ + {{{0x0607b030, 0x22296b92, 0x184d6732, 0x36bfd8f9, 0x16f29c24, 0x07eeb3b0, 0x21467785, 0x00ddb100, 0x110b}}, + {{0x33617c3a, 0x10ea844a, 0x3298749f, 0x2f8555be, 0x21c70c87, 0x3ae27e11, 0x2e6734c6, 0x0ae14c63, 0x8443}}}, + /* 7*16^16*G: */ + {{{0x35a76f08, 0x13b76071, 0x3bbed4e5, 0x257c94e2, 0x1caaf832, 0x1b8490ac, 0x071d714f, 0x139127d9, 0x1878}}, + {{0x2b824993, 0x2ce58175, 0x20a25320, 0x275d29e9, 0x31e671fc, 0x1ea3f6b1, 0x21ae7177, 0x3b5fd287, 0x8d76}}}, + /* 9*16^16*G: */ + {{{0x3a6fad81, 0x3a38cf27, 0x00cb03ec, 0x0cd95d23, 0x3a037d9c, 0x15b75dc0, 0x1e6b9aef, 0x3e781f41, 0x58a2}}, + {{0x3b109594, 0x10018578, 0x1300b825, 0x22ecb4cb, 0x3fa6bd79, 0x1a0be1c5, 0x160e0c1b, 0x19316b15, 0x06ab}}}, + /* 11*16^16*G: */ + {{{0x1eb52583, 0x2c8bc47e, 0x10cc13af, 0x22a673b0, 0x0f676fea, 0x39b6ec9e, 0x2bba240e, 0x0837339f, 0x1ef0}}, + {{0x3a3f17ae, 0x16c9e065, 0x012d4cb5, 0x30c03e5c, 0x1695306a, 0x3db03d2e, 0x214b0097, 0x1dac969e, 0x5944}}}, + /* 13*16^16*G: */ + {{{0x30a1958f, 0x1708fb07, 0x3b56643b, 0x0e6d491b, 0x3fa32c4f, 0x345133ea, 0x2a21395d, 0x2058f075, 0x4e4a}}, + {{0x08636f8a, 0x10ecfd45, 0x2c43d66a, 0x010217ec, 0x1c6fa840, 0x3d28fb8a, 0x0c8d1033, 0x2916de7a, 0x2574}}}, + /* 15*16^16*G: */ + {{{0x24935db5, 0x209d6a11, 0x06bdb0ee, 0x05e60987, 0x14519e28, 0x09f83b56, 0x21104e33, 0x1a85ab75, 0xf696}}, + {{0x1d166838, 0x28d20db0, 0x001bf013, 0x1d14e8d1, 0x3c755e2d, 0x17b95cb0, 0x31db2c1a, 0x38c1ea40, 0xba0d}}} + }, + { + /* 1*16^17*G: */ + {{{0x376a6987, 0x23d04c16, 0x3da43ff6, 0x1206ad10, 0x2e1b3f2b, 0x31a6235f, 0x099547dd, 0x0635ea66, 0x54bc}}, + {{0x1b9aae49, 0x3915f341, 0x373b119f, 0x3ae3b52e, 0x33e2fd52, 0x06e146e9, 0x2eaf3739, 0x23048479, 0x4b2c}}}, + /* 3*16^17*G: */ + {{{0x3d1fd820, 0x22fd1fd7, 0x07675003, 0x21e15192, 0x31271b78, 0x0d40898a, 0x1c52aa86, 0x2f3da030, 0xbafb}}, + {{0x1bf074f0, 0x2bb6b548, 0x31fcad6e, 0x070d2848, 0x1bc0fde8, 0x1efd6b22, 0x0dd812ce, 0x265f276d, 0x1487}}}, + /* 5*16^17*G: */ + {{{0x14299b7e, 0x245c204a, 0x186e0d0e, 0x39e7cb42, 0x0220ec24, 0x30eff1d7, 0x389fe2a3, 0x0e3dc40c, 0x9b19}}, + {{0x047b84de, 0x15eca15d, 0x06b8232c, 0x337a147e, 0x2a3ec90a, 0x03a63872, 0x10283314, 0x2a9bbc5c, 0xfb12}}}, + /* 7*16^17*G: */ + {{{0x110cc4c4, 0x35041d03, 0x0a53da0f, 0x074d68b1, 0x361b2cb7, 0x207f7019, 0x175907c3, 0x06617300, 0xa677}}, + {{0x3c976570, 0x083cec8d, 0x2ff3094c, 0x1d15dce9, 0x1d9c3dbc, 0x2f598079, 0x0dd98f29, 0x18617dd4, 0x8550}}}, + /* 9*16^17*G: */ + {{{0x14242a28, 0x104200b5, 0x13ca7715, 0x16f2c849, 0x374eca45, 0x22bde12d, 0x2afc109e, 0x3b54dac3, 0x88b7}}, + {{0x394ed8ce, 0x2e5a07b1, 0x383e347f, 0x0d9a8723, 0x07bd934e, 0x2fe774d6, 0x1345e47f, 0x14c81891, 0x22b0}}}, + /* 11*16^17*G: */ + {{{0x1bc1a94c, 0x058513b2, 0x271daf80, 0x19c74acf, 0x1e875751, 0x35cac089, 0x2b3d2052, 0x05004aa1, 0x0371}}, + {{0x2fc2073c, 0x30302db3, 0x2c424838, 0x14630d8a, 0x105335c8, 0x3086952b, 0x17390ef8, 0x1a4f5477, 0x4d1d}}}, + /* 13*16^17*G: */ + {{{0x077f88ba, 0x3ef47826, 0x29bed36e, 0x2601de7b, 0x2a2cc350, 0x168cba13, 0x0293e34b, 0x08532261, 0xcc98}}, + {{0x07885278, 0x2918bbf2, 0x3354c4e0, 0x3d839fbb, 0x3d63abef, 0x3129919d, 0x1afa9114, 0x2d3a3949, 0x04eb}}}, + /* 15*16^17*G: */ + {{{0x3d70187c, 0x15cc6537, 0x3640c7f1, 0x06b218a6, 0x0f5bf875, 0x139780a4, 0x2a10f981, 0x2b80a690, 0x0ad3}}, + {{0x3fc775a7, 0x37ff3d2c, 0x262a0f67, 0x0d3ec205, 0x2bb33dd0, 0x3157c17e, 0x046e3785, 0x10351d62, 0x2af0}}} + }, + { + /* 1*16^18*G: */ + {{{0x30aae231, 0x02abeb45, 0x1f96b7c6, 0x252e149e, 0x27756f51, 0x09208e49, 0x1e3f285f, 0x325a65d8, 0x1d35}}, + {{0x0cd6ac71, 0x219c18eb, 0x29a66f15, 0x3d62a91c, 0x2bf810ed, 0x182ad88b, 0x208231d6, 0x1b2d8b7d, 0xc722}}}, + /* 3*16^18*G: */ + {{{0x0cfa3fac, 0x3834ff86, 0x32b8193c, 0x2b61a7f0, 0x0d803023, 0x3aed1758, 0x2234ce2c, 0x1011e9b4, 0xdf3d}}, + {{0x0fc7d419, 0x1189b64e, 0x2882975f, 0x358f3925, 0x0f9dbfaf, 0x2887ca70, 0x140db24a, 0x1bd48a7f, 0x48fa}}}, + /* 5*16^18*G: */ + {{{0x1f1322d4, 0x3b6496b8, 0x2ccdcbba, 0x029a5012, 0x11f822cb, 0x39b1328c, 0x16144ea1, 0x2bdaac7e, 0xdbb2}}, + {{0x0a8c5311, 0x2924ad3d, 0x37e3a5fa, 0x27f25e1e, 0x033f9d9a, 0x18347b59, 0x3561aa1b, 0x1d6e4bc4, 0xebae}}}, + /* 7*16^18*G: */ + {{{0x21138f7b, 0x01a68cf2, 0x1f2e8f2f, 0x30724f8b, 0x1b5f0bc4, 0x2a2899fe, 0x21fd4caf, 0x1ed65fc9, 0x1dba}}, + {{0x239bf268, 0x320b631e, 0x18232c0d, 0x0db9ade6, 0x0007f581, 0x06401aee, 0x3efc63ae, 0x1f4f9779, 0x6aaf}}}, + /* 9*16^18*G: */ + {{{0x179a70af, 0x36a1ddc0, 0x364df288, 0x2750a6a6, 0x1305c6ec, 0x2fa0b57d, 0x2919d31b, 0x0b910989, 0x348a}}, + {{0x07b66e82, 0x2a121852, 0x3e13e5ac, 0x29f0b16d, 0x230105b2, 0x11ef3800, 0x23e808c7, 0x3e9e7d56, 0xa1b9}}}, + /* 11*16^18*G: */ + {{{0x04d3a201, 0x1d1db5db, 0x19b9eefc, 0x3a49a93f, 0x1adf5f36, 0x293efe4c, 0x09e1ca86, 0x32146667, 0x3a4e}}, + {{0x28635f89, 0x36165bdd, 0x33cd55bd, 0x34c796bd, 0x374a8b27, 0x00f04691, 0x262de69e, 0x0bbe0bd8, 0xc99a}}}, + /* 13*16^18*G: */ + {{{0x1c978567, 0x3beb9cbf, 0x0dc1f981, 0x1769a210, 0x31f60be1, 0x24d758bf, 0x0d45784e, 0x14b620cd, 0xb1ba}}, + {{0x362dc291, 0x1fe920a8, 0x2fcd40a7, 0x291b2c2e, 0x1bb78fd9, 0x3df3dc4f, 0x143a77c5, 0x2bb1ea1a, 0xa46b}}}, + /* 15*16^18*G: */ + {{{0x12350da1, 0x08a3ba94, 0x175f043d, 0x10531df0, 0x212c2f19, 0x22dee5a5, 0x2aafd271, 0x3acf63bc, 0x0ae6}}, + {{0x30a14bc3, 0x1cf827cd, 0x143da4bc, 0x351a3c3b, 0x0189b566, 0x00d3dff1, 0x06cae2dd, 0x3ba7ed80, 0x99cd}}} + }, + { + /* 1*16^19*G: */ + {{{0x350e4f5f, 0x15cabaa1, 0x167e0e65, 0x3d72a6a9, 0x02f29acb, 0x3fc3dea8, 0x35aef388, 0x2a566112, 0x55d9}}, + {{0x3ca97db0, 0x2163adda, 0x3ad1b15c, 0x2604318c, 0x08ec524c, 0x355d3ef3, 0x2d203766, 0x1fe6a976, 0x69cb}}}, + /* 3*16^19*G: */ + {{{0x3eb142e9, 0x01aa621f, 0x207fcfbc, 0x1dbac191, 0x2ed480c1, 0x361a0e3e, 0x33e11794, 0x10faf91b, 0x4b00}}, + {{0x22c68552, 0x12cb14b5, 0x21258880, 0x08ca43ce, 0x222d870f, 0x1e2118d8, 0x1ac1adb1, 0x33c8e8c3, 0x173c}}}, + /* 5*16^19*G: */ + {{{0x17f1aa96, 0x1b752b9c, 0x0ff6481f, 0x35e97dcd, 0x3463c513, 0x0a372edc, 0x16fc2327, 0x349e64ab, 0x79ea}}, + {{0x0b0a3fb7, 0x02e9c739, 0x1b3955a8, 0x2135c444, 0x256542de, 0x390e4d58, 0x2dabf1a6, 0x3a73feea, 0xa95d}}}, + /* 7*16^19*G: */ + {{{0x393a9ae6, 0x201729cb, 0x077f8adc, 0x382a8167, 0x2d743f8e, 0x1e78d8c6, 0x1a1ceb52, 0x00143c93, 0x318e}}, + {{0x1c447d79, 0x212d5a53, 0x2d3a8ee1, 0x14dbf6eb, 0x104bd094, 0x05f29479, 0x29299f4d, 0x3b844673, 0x2792}}}, + /* 9*16^19*G: */ + {{{0x1d30585a, 0x0de516d3, 0x35014951, 0x3fe286a8, 0x00a4b495, 0x00cbd243, 0x1e43bb88, 0x151c74bc, 0x6bbc}}, + {{0x348b05f3, 0x2be5fbbc, 0x2f9ead96, 0x3c10a040, 0x2226be09, 0x3b8ac57c, 0x129f04a9, 0x0626c305, 0x467b}}}, + /* 11*16^19*G: */ + {{{0x00136275, 0x1893e023, 0x38775352, 0x11f0005c, 0x360d78a6, 0x146a43dd, 0x1fd1189b, 0x12318430, 0x9401}}, + {{0x1997aa47, 0x358e8445, 0x04e1a425, 0x12ceb958, 0x05d6695d, 0x09312ad4, 0x3a4f77aa, 0x3e57c4d9, 0x6967}}}, + /* 13*16^19*G: */ + {{{0x1f0fe850, 0x0e84f74e, 0x111a7bdc, 0x1348c2f9, 0x25f98e86, 0x15b24a36, 0x1b49c91b, 0x0ce4980e, 0xc418}}, + {{0x3d38666d, 0x0d63d11a, 0x01a0af01, 0x169fb278, 0x2fd55806, 0x0257509a, 0x00f7aeb8, 0x3fb27235, 0x3537}}}, + /* 15*16^19*G: */ + {{{0x34937fbe, 0x3f9104dd, 0x051ba6ec, 0x2c13777c, 0x16f546c0, 0x050006be, 0x27d70e0c, 0x28fd89f1, 0x2bab}}, + {{0x173a1df4, 0x0e43955d, 0x0ac81109, 0x0b712c64, 0x0eabc9ec, 0x0ec33649, 0x08b88d78, 0x31d96c88, 0x77e5}}} + }, + { + /* 1*16^20*G: */ + {{{0x0351964c, 0x134f4b79, 0x35412c1d, 0x1a490ddb, 0x355c0834, 0x2af28615, 0x0c47fae5, 0x3e566f8a, 0x6e29}}, + {{0x163fd88f, 0x062092f5, 0x20bfb631, 0x1903149e, 0x04246def, 0x0bb1b306, 0x332f6505, 0x1767d403, 0x3456}}}, + /* 3*16^20*G: */ + {{{0x0c0e49cc, 0x3e54040e, 0x3c5400d3, 0x08cb6a16, 0x3740ed41, 0x0a237b2e, 0x30f6edd8, 0x352a5e25, 0xd691}}, + {{0x100f4152, 0x342ed307, 0x2d043f2d, 0x16f8740a, 0x3e0c52ac, 0x2ef6d5d8, 0x0f397f7f, 0x39e1d2de, 0x7a79}}}, + /* 5*16^20*G: */ + {{{0x2b9b930a, 0x361dae7c, 0x130f58f3, 0x2c4d4a91, 0x3bbc49de, 0x16df7de9, 0x0d7c5dee, 0x1a11a8b8, 0x2a5d}}, + {{0x3b2caeca, 0x1bfcd17c, 0x22716858, 0x16dcd0d7, 0x04ab58ea, 0x33c0e40f, 0x2476de5c, 0x1f025a1d, 0xdc3d}}}, + /* 7*16^20*G: */ + {{{0x016959ef, 0x29f72f4a, 0x01db59af, 0x1e74159d, 0x275df876, 0x10c504b8, 0x3b5262f0, 0x125a8e26, 0x8764}}, + {{0x20cd5010, 0x180c472f, 0x2f9e3f16, 0x15ab505c, 0x2d961f28, 0x2d049e5b, 0x02ffd9e0, 0x1a758740, 0x599b}}}, + /* 9*16^20*G: */ + {{{0x3aef0f84, 0x0e502738, 0x31c75b96, 0x2ed41aa1, 0x2db8cab0, 0x38feb05e, 0x071b133d, 0x24ef2049, 0x94d3}}, + {{0x378ba7c1, 0x16b986e4, 0x0acf12a8, 0x0fd00994, 0x239a07dd, 0x32f0e1ac, 0x363f21e1, 0x1aad3ad2, 0x5a82}}}, + /* 11*16^20*G: */ + {{{0x2ffed1b7, 0x35155e13, 0x24aa3b4e, 0x36f44995, 0x34bd2ee2, 0x1425c0b4, 0x24e2dd17, 0x2d682227, 0x4a72}}, + {{0x1601dc5f, 0x17ca7f62, 0x34d9845b, 0x3992e3b1, 0x08ea9685, 0x0cff011f, 0x120e2c8c, 0x39ba9287, 0x3531}}}, + /* 13*16^20*G: */ + {{{0x10467317, 0x0810fc97, 0x0d9186a0, 0x10771076, 0x1e790091, 0x199bcbeb, 0x31e15a78, 0x073f168d, 0xd7f0}}, + {{0x0f7d014e, 0x32e55f57, 0x17fbd895, 0x2805d0da, 0x15ef5728, 0x0d8501b0, 0x26c26ec7, 0x2ef661dc, 0x888d}}}, + /* 15*16^20*G: */ + {{{0x3dea02c1, 0x2f5d6429, 0x374087c3, 0x3eee6df1, 0x231206e4, 0x02fe7647, 0x0371bbe8, 0x282e7ddf, 0x7e50}}, + {{0x2d45c201, 0x0f251b7f, 0x18e1b283, 0x08e4d3c5, 0x0b951774, 0x31bc776e, 0x3e29c616, 0x174f1383, 0xc340}}} + }, + { + /* 1*16^21*G: */ + {{{0x0cb71280, 0x229f5044, 0x04563112, 0x1070966a, 0x2f458ec1, 0x3cbbc1e5, 0x3eed9c00, 0x1aa7acaf, 0xff04}}, + {{0x1ec33919, 0x3b0c9c7d, 0x128487a7, 0x0adb9baf, 0x0cfcc901, 0x07b76f75, 0x13a170a0, 0x156b3025, 0x432f}}}, + /* 3*16^21*G: */ + {{{0x33ca3ce3, 0x3c9e0aa8, 0x36a77e25, 0x0ac6196a, 0x12231fef, 0x16f07d4c, 0x3dcd31a9, 0x31174534, 0xf717}}, + {{0x10ed88e9, 0x2253336d, 0x0176df06, 0x14f8af77, 0x2dee55af, 0x2d53b42a, 0x1512dca9, 0x101da326, 0x422c}}}, + /* 5*16^21*G: */ + {{{0x1b28cd88, 0x0da10c35, 0x2a9bd9ac, 0x23825d40, 0x11b32c73, 0x3ad589fe, 0x30b20c2f, 0x1a6d3ccd, 0x60e2}}, + {{0x2be2066c, 0x0a6ea290, 0x2c846b0e, 0x11584e31, 0x28df7602, 0x0846225c, 0x1f0a9609, 0x05d6995e, 0xfe00}}}, + /* 7*16^21*G: */ + {{{0x061cc594, 0x14ec64ca, 0x0d0536b1, 0x12f745c1, 0x34685596, 0x16e817f2, 0x399490aa, 0x25e8799c, 0x7992}}, + {{0x0f8d309e, 0x3a444248, 0x3ac6e909, 0x36a1ab82, 0x1fe50127, 0x1a4461e2, 0x3c9b0e10, 0x3c633548, 0x132f}}}, + /* 9*16^21*G: */ + {{{0x172d0aba, 0x32311e89, 0x37e1b16d, 0x34642b71, 0x01241dd8, 0x383bad54, 0x2807079e, 0x3a53bf90, 0x2d9b}}, + {{0x31fa0876, 0x23dcc7ec, 0x0b710e6f, 0x34719e62, 0x19d91bba, 0x3be4d2d8, 0x098a2295, 0x236d7a7a, 0xa970}}}, + /* 11*16^21*G: */ + {{{0x355e8732, 0x0301ed20, 0x06d1e31e, 0x298bb794, 0x12c243cf, 0x2f194c52, 0x2421660c, 0x00e7b220, 0x2127}}, + {{0x20cacc07, 0x1648d7d1, 0x2d7bd68d, 0x24fcfcee, 0x3f0a5cd6, 0x12e76eed, 0x235aa019, 0x271bc8eb, 0x8521}}}, + /* 13*16^21*G: */ + {{{0x32083347, 0x0244d033, 0x31a53226, 0x06b8f99d, 0x02b42b9e, 0x343d6ae8, 0x0e0eb97a, 0x2d52caf6, 0xfab5}}, + {{0x3d38fd2f, 0x33327360, 0x2a69afa9, 0x178de985, 0x0a3eafc0, 0x1eabc898, 0x141503c8, 0x3445861b, 0x5758}}}, + /* 15*16^21*G: */ + {{{0x3f572554, 0x3d9c9853, 0x0f4dab73, 0x210b91c6, 0x3ea56ff3, 0x0259dc2d, 0x31fca579, 0x09d5c9e5, 0x685d}}, + {{0x20979e03, 0x1c6bdb42, 0x0f4cca4b, 0x22aa8ab0, 0x20377cc5, 0x0e720107, 0x345fc06e, 0x2270882a, 0xa82f}}} + }, + { + /* 1*16^22*G: */ + {{{0x05852e50, 0x1f42c933, 0x3570cc5c, 0x0b1f98f3, 0x2e7eff8b, 0x26a88d27, 0x3b058c1f, 0x31f7ffaa, 0xe486}}, + {{0x2ecf107d, 0x1ae8f2b6, 0x392ebd86, 0x1118f58c, 0x11e05a69, 0x2229727d, 0x2a12e9ee, 0x1d7b5581, 0x51fd}}}, + /* 3*16^22*G: */ + {{{0x1c881907, 0x19aa9915, 0x300b1dac, 0x0b219cd6, 0x2e041514, 0x0417319a, 0x3fb7c964, 0x112ee38b, 0x4acf}}, + {{0x363cdafc, 0x249ad15b, 0x0d84b252, 0x0d4acbdf, 0x0a545799, 0x10a16b44, 0x1587b354, 0x2a3f83ff, 0xad99}}}, + /* 5*16^22*G: */ + {{{0x3439383f, 0x0aeb81a5, 0x201a2aa8, 0x3fe958ad, 0x234eec34, 0x2a8a4b20, 0x0a649dd7, 0x08a0d062, 0x4ddf}}, + {{0x23d52337, 0x0cbea060, 0x31f82696, 0x35741144, 0x0c0c6b3d, 0x2eba5f4e, 0x1883d74a, 0x189ec364, 0xe71c}}}, + /* 7*16^22*G: */ + {{{0x1822b4f4, 0x1b722055, 0x065df8f2, 0x0d4ebf3e, 0x3bf39ba5, 0x13a781e5, 0x1879e133, 0x195e44de, 0x58b0}}, + {{0x0c60fbca, 0x181ea084, 0x04e52596, 0x29281dbf, 0x22836c1c, 0x32957c09, 0x22c37027, 0x22a90516, 0x55a9}}}, + /* 9*16^22*G: */ + {{{0x34fe39b0, 0x2caf4430, 0x0b4ded14, 0x0c5cf35d, 0x381f358a, 0x2910708c, 0x33529763, 0x38162992, 0xa345}}, + {{0x2baf79dc, 0x1c25202e, 0x3369df53, 0x231a9d6a, 0x39d949ce, 0x02156ca3, 0x2a70f91f, 0x3569b572, 0x7c6d}}}, + /* 11*16^22*G: */ + {{{0x126695fb, 0x3ef81ee6, 0x03adee13, 0x342ee7f9, 0x16ccb6af, 0x2b2e1d1b, 0x0a2c8201, 0x2fe0c064, 0x3a10}}, + {{0x24eb7e47, 0x1571caca, 0x3d452887, 0x23fa9b10, 0x0a65c5f2, 0x00e121a2, 0x22715762, 0x216cfb06, 0xb5d5}}}, + /* 13*16^22*G: */ + {{{0x3d2c8614, 0x106a3a59, 0x05845962, 0x2c258298, 0x112876a7, 0x33d6b0c2, 0x10433ca5, 0x377eb240, 0x12fb}}, + {{0x18b0b174, 0x01def075, 0x019f495f, 0x109608e7, 0x12cfb54d, 0x36450a33, 0x3806833f, 0x0834a409, 0xa5ff}}}, + /* 15*16^22*G: */ + {{{0x2d9aeeaf, 0x0fdd90c0, 0x05afc865, 0x341e5328, 0x399a3005, 0x2b8e87eb, 0x178777b8, 0x3a1668ae, 0x8bec}}, + {{0x05f9eb5e, 0x168368f2, 0x38980f75, 0x0880e3db, 0x3fc368bb, 0x22442c3b, 0x251fcfbb, 0x0cf13141, 0x35f9}}} + }, + { + /* 1*16^23*G: */ + {{{0x2b519178, 0x12dae3b0, 0x03d1fc58, 0x0ee66629, 0x22ee0ab6, 0x0233e2d7, 0x10430cfe, 0x1fd2ed79, 0xf41d}}, + {{0x0a6a3551, 0x1e859977, 0x119e1f9a, 0x126b30da, 0x282347ab, 0x11b78fea, 0x2f8d6f10, 0x1a6faf66, 0xe6a6}}}, + /* 3*16^23*G: */ + {{{0x1e3501d9, 0x29c4c4f8, 0x361fc8b1, 0x3a0b386e, 0x2d3e611b, 0x0b5a4758, 0x14e7f333, 0x209fb58b, 0xd65f}}, + {{0x2b55759e, 0x2e511b1b, 0x1730be1a, 0x304eab57, 0x2b87fc61, 0x2df29459, 0x290fe537, 0x183f3c26, 0xf24b}}}, + /* 5*16^23*G: */ + {{{0x0f2ed84e, 0x2d8bf890, 0x3e2ea12c, 0x26537cd7, 0x2cc0ade7, 0x1b22d5e0, 0x05c385ee, 0x2d6db7ac, 0x55a9}}, + {{0x146495a3, 0x1e771541, 0x2a0d8f05, 0x3fed35c4, 0x17f43ae8, 0x1d34643b, 0x319ab291, 0x0865ab27, 0xc4f2}}}, + /* 7*16^23*G: */ + {{{0x075495a2, 0x2f4b3e1c, 0x0bc00b29, 0x3787ad92, 0x148bc49f, 0x3b582989, 0x371da1f7, 0x15db71f6, 0x79de}}, + {{0x2aec6fb8, 0x00b231aa, 0x093a7468, 0x053d4259, 0x1c79c683, 0x39b6b91f, 0x06a02785, 0x0f439ac6, 0x3b2d}}}, + /* 9*16^23*G: */ + {{{0x02d1e7bb, 0x3ba4ab32, 0x111964ce, 0x30ffe40d, 0x17e55524, 0x12cda565, 0x004b6e26, 0x138c8589, 0x8fe0}}, + {{0x1a62e84f, 0x29d66b43, 0x3046a8cd, 0x2459191b, 0x0db34e5b, 0x1b3a95ea, 0x2358fe5d, 0x36d408bd, 0x3987}}}, + /* 11*16^23*G: */ + {{{0x29f7c360, 0x00692bb1, 0x08085c21, 0x3f355df9, 0x1224e24e, 0x25298da3, 0x1f8f150a, 0x264255fb, 0x3af4}}, + {{0x287d7a7b, 0x0e770aa9, 0x360895cd, 0x15537589, 0x333c3348, 0x3e1920b9, 0x1d91d531, 0x180c34ec, 0xd170}}}, + /* 13*16^23*G: */ + {{{0x370373be, 0x26948eb9, 0x263d3b53, 0x0f418884, 0x227c4e21, 0x160bcff8, 0x08076c1a, 0x3817188f, 0x31a7}}, + {{0x290950a8, 0x3b5e1e43, 0x1a254308, 0x3a0ae654, 0x23db1e8c, 0x2c2ab8d0, 0x1de67021, 0x0bbcfe34, 0xc23d}}}, + /* 15*16^23*G: */ + {{{0x0b923b45, 0x109843b7, 0x13e24bdb, 0x0ea7effc, 0x198458a3, 0x144d18b7, 0x2d23ed15, 0x199204d5, 0x740a}}, + {{0x11ecaa5f, 0x2304f8e1, 0x3c8480ba, 0x25e64e41, 0x1606cfa8, 0x391e229d, 0x1523f2f4, 0x01230973, 0x7f6d}}} + }, + { + /* 1*16^24*G: */ + {{{0x3512218e, 0x212aa4e5, 0x0ca0141a, 0x29486c1d, 0x22e902e9, 0x202ce862, 0x277a6578, 0x141984a9, 0x4a5b}}, + {{0x0c4f3840, 0x2fab69e9, 0x1e26d9d0, 0x1b6c5506, 0x227d4062, 0x1813ef85, 0x089f1c42, 0x11873ab0, 0xeb13}}}, + /* 3*16^24*G: */ + {{{0x118473fd, 0x0bbd0389, 0x29733915, 0x2e409af1, 0x28a9e3bb, 0x24aae65c, 0x18ba0852, 0x018c8ccc, 0x1064}}, + {{0x385cf805, 0x3e9858b9, 0x021d039a, 0x2f864343, 0x05883ccf, 0x1e0a7996, 0x3a2d8c8e, 0x0ca08ee2, 0x9c68}}}, + /* 5*16^24*G: */ + {{{0x253f30f3, 0x159fbb21, 0x1a238dd3, 0x108fb4bb, 0x083f212b, 0x29043550, 0x327bf5ed, 0x2b63fc17, 0x38c8}}, + {{0x2be9217b, 0x01839d27, 0x159df37a, 0x20fea60a, 0x3d641f65, 0x02595376, 0x0b116f39, 0x185e1db7, 0x83c2}}}, + /* 7*16^24*G: */ + {{{0x36ef1584, 0x10f9a446, 0x3920cbf5, 0x2a68a8e3, 0x35184277, 0x23ef8ff4, 0x0bb09585, 0x232f3a18, 0x6fcb}}, + {{0x1d3110f2, 0x0f27df08, 0x28a4325c, 0x24bdb5a4, 0x30459d59, 0x30208eb0, 0x21d76d54, 0x2a0f62dc, 0xa8f1}}}, + /* 9*16^24*G: */ + {{{0x062255ef, 0x23d44d01, 0x364078ce, 0x35c74d19, 0x05b0ee50, 0x05724379, 0x2e2bd735, 0x342e4fdd, 0x7811}}, + {{0x1be3252e, 0x162fbe6c, 0x2d43768a, 0x07b4144e, 0x385132f5, 0x00ba5006, 0x1ac7a54c, 0x1d8dc2ed, 0x99bb}}}, + /* 11*16^24*G: */ + {{{0x353d2ea7, 0x0f8443c4, 0x3fa86509, 0x3b4208e8, 0x016f2a9e, 0x2dca757e, 0x350ce0c7, 0x0f6512a2, 0xc358}}, + {{0x0b667bbd, 0x2c60fa78, 0x15f1c432, 0x32496994, 0x1fcccdd6, 0x1189fbe2, 0x1e90f596, 0x1eb024e4, 0x5396}}}, + /* 13*16^24*G: */ + {{{0x102e3099, 0x3b77c381, 0x28401658, 0x3c84e998, 0x3ad00d53, 0x03c062ed, 0x2e501f3a, 0x33ca0f37, 0xd591}}, + {{0x055ac5af, 0x0ef09d95, 0x3116fd63, 0x3cbbfe22, 0x0bc5825c, 0x04cc34d4, 0x0e6e44e5, 0x3973f11e, 0x87eb}}}, + /* 15*16^24*G: */ + {{{0x32a940a5, 0x2c995918, 0x014e6b12, 0x10d7ad69, 0x39e8714a, 0x09078693, 0x235c4c01, 0x03584bcc, 0xa0aa}}, + {{0x0b950422, 0x0fe20a9a, 0x3d1bf939, 0x1a473769, 0x181f3e6c, 0x0d33e680, 0x3642819b, 0x03ae9dbd, 0x2234}}} + }, + { + /* 1*16^25*G: */ + {{{0x008e2df0, 0x18a360dc, 0x328e5f76, 0x30ec95d0, 0x3e0f5032, 0x30a77e2e, 0x2b995012, 0x2442f78a, 0x2eb3}}, + {{0x1274eaae, 0x2443313b, 0x0f65f490, 0x1034483b, 0x24999f95, 0x0df4d236, 0x34b3a77d, 0x3008cdd1, 0x3f29}}}, + /* 3*16^25*G: */ + {{{0x282867f0, 0x3c0ae12d, 0x3190a39b, 0x0509b886, 0x0900f0a2, 0x2f45a9e0, 0x07ce22aa, 0x36e23993, 0xf6e9}}, + {{0x0f1861ea, 0x1d6cebc4, 0x170b6234, 0x0106e97e, 0x00d5b127, 0x24eddba3, 0x2ab7481d, 0x1e42deb4, 0x53ca}}}, + /* 5*16^25*G: */ + {{{0x320d6102, 0x2b7410e3, 0x34539409, 0x1b54de28, 0x199a5ef0, 0x3056e6d8, 0x2449d785, 0x36ce1d83, 0xfd1d}}, + {{0x2e003b7c, 0x28299246, 0x1513983d, 0x0f864484, 0x03b70016, 0x287c7de2, 0x0638aeda, 0x2e1ce414, 0xcb54}}}, + /* 7*16^25*G: */ + {{{0x02c77cb7, 0x0fdcd077, 0x2dc15b6f, 0x1b650240, 0x2e698fef, 0x129cf997, 0x1901d9fe, 0x1cf08966, 0x61a2}}, + {{0x1ddb25ed, 0x151847e0, 0x0ae1f748, 0x316b669c, 0x2b0cc9c5, 0x28867d7b, 0x2d3d3f4e, 0x334cd34e, 0x5bba}}}, + /* 9*16^25*G: */ + {{{0x377d8976, 0x266355b8, 0x30f292db, 0x05ce8e38, 0x1d04b55e, 0x00b2608a, 0x201b64cb, 0x23997bdd, 0xcd2e}}, + {{0x0867bc22, 0x05a5bd07, 0x1428c051, 0x03b783cd, 0x06ff68f6, 0x073a3cb5, 0x2a31ffc3, 0x2b4d88d0, 0xf58e}}}, + /* 11*16^25*G: */ + {{{0x2c67c998, 0x026cc1b0, 0x3cf1b866, 0x26c1faa8, 0x304c259a, 0x097aa290, 0x23efb402, 0x07e70e08, 0x9bd6}}, + {{0x28199514, 0x0d02be70, 0x0424b18c, 0x1f6707a4, 0x1450fa92, 0x3c825a5a, 0x06f5c5c8, 0x0102645b, 0x77b2}}}, + /* 13*16^25*G: */ + {{{0x2aafa568, 0x291785ef, 0x01e22766, 0x335ea5dc, 0x17a016b4, 0x389e9044, 0x0777512a, 0x3ad3de5c, 0x7afa}}, + {{0x01c1f2df, 0x3b54e8be, 0x1d390233, 0x0b9a50ca, 0x01365a97, 0x34504d41, 0x3d27d895, 0x39864cfe, 0xc6ef}}}, + /* 15*16^25*G: */ + {{{0x0e59ddeb, 0x1f9c0f94, 0x11e98a8b, 0x0f98a72b, 0x2b0c3b48, 0x36530525, 0x012f9061, 0x00889f89, 0xd9a0}}, + {{0x0f0af5a4, 0x3ce4ffe0, 0x35f18ce5, 0x18aa2f2a, 0x27058185, 0x183e290d, 0x2022c43c, 0x2cbe4ede, 0x975e}}} + }, + { + /* 1*16^26*G: */ + {{{0x3ecca7e0, 0x1ce697a8, 0x343333ec, 0x34b263d9, 0x0d9428a7, 0x3d8cd489, 0x12a0c0fe, 0x3b8f171e, 0x7ef2}}, + {{0x152ac094, 0x00ac8b75, 0x3bd3d203, 0x2c851437, 0x2609db81, 0x19fd4757, 0x0c011a4f, 0x2189cc2b, 0xafb6}}}, + /* 3*16^26*G: */ + {{{0x233f0ffa, 0x0bcd60f6, 0x1807a417, 0x3932b184, 0x19c641ca, 0x1295db27, 0x07acd762, 0x15c9c5a2, 0x3704}}, + {{0x20fa35ac, 0x3fb4ff19, 0x28bf2fc5, 0x2e8fadea, 0x15ff4c57, 0x2ed2ee22, 0x1e74f841, 0x0231869c, 0x5c64}}}, + /* 5*16^26*G: */ + {{{0x32603513, 0x31be6194, 0x14a00953, 0x319371a0, 0x0bb697f6, 0x3aa90b02, 0x0db722d1, 0x1e7950a6, 0xc2a9}}, + {{0x3c3505b9, 0x15d56cb0, 0x01514499, 0x3199b7d2, 0x1bce7e8c, 0x1e02064d, 0x2b5c8542, 0x35d2879b, 0xef9d}}}, + /* 7*16^26*G: */ + {{{0x19fdee3e, 0x191bfec7, 0x0302e01e, 0x07e5dc5b, 0x17afb968, 0x2ec5736c, 0x059e1172, 0x061aac7f, 0xc9f4}}, + {{0x0ced22e7, 0x0799b317, 0x358df4f5, 0x3854c71e, 0x03214344, 0x1cc50ae2, 0x3a3410df, 0x029fcf2c, 0x0942}}}, + /* 9*16^26*G: */ + {{{0x0814f217, 0x032cf99d, 0x356cffaf, 0x368fdee1, 0x3bb6a4a9, 0x280093e0, 0x00256b08, 0x3d56e012, 0x27dc}}, + {{0x0cf2ed4c, 0x13252d62, 0x11fc3bf1, 0x13a3eac6, 0x202a380a, 0x22eac252, 0x15dee0bc, 0x3d53d523, 0xbe18}}}, + /* 11*16^26*G: */ + {{{0x1b9e310c, 0x168a93f5, 0x04cfd4a7, 0x0f396e6e, 0x15918731, 0x3492b0ce, 0x2ea4b9c8, 0x0080ec95, 0x3b8b}}, + {{0x2d19fc9b, 0x25059816, 0x2b305839, 0x3fe012e0, 0x0117a6a8, 0x1db8ddf1, 0x3615bd61, 0x1f13ac0c, 0x9111}}}, + /* 13*16^26*G: */ + {{{0x27615b36, 0x3c7878ae, 0x3f3c15f8, 0x13fc7a31, 0x14c3372a, 0x30901be4, 0x0103a105, 0x0e6316f3, 0xa5e7}}, + {{0x09136d80, 0x3660b8e5, 0x0b613c04, 0x3ff064dc, 0x15f8c547, 0x0e37bca8, 0x0e4ce464, 0x3d63725d, 0x1f3f}}}, + /* 15*16^26*G: */ + {{{0x2d3e10db, 0x2dec10cb, 0x0b87159b, 0x1ccb86b2, 0x2b61fa47, 0x0110ffd3, 0x1532bdee, 0x060d56b2, 0xaad2}}, + {{0x2fa05fb3, 0x0d4d6af5, 0x31cba276, 0x00c9dcac, 0x1f8b4a72, 0x3778a3f5, 0x02e3b3a7, 0x07bbaebe, 0x793b}}} + }, + { + /* 1*16^27*G: */ + {{{0x2c49e853, 0x1c07c243, 0x175e04a6, 0x32d4d4a6, 0x1fa77aa9, 0x009553ad, 0x00aeb578, 0x10590859, 0x0e51}}, + {{0x36405cb2, 0x0db8f44d, 0x0c9ee363, 0x1a0e5064, 0x11030df5, 0x3ad294ea, 0x05469278, 0x073a9964, 0xcf33}}}, + /* 3*16^27*G: */ + {{{0x1dc6afad, 0x1288fc70, 0x1f80f46c, 0x34f648a5, 0x00c6771b, 0x3b497d93, 0x2cf25de8, 0x2819d972, 0x977b}}, + {{0x1d7faa09, 0x358b3714, 0x1da1a154, 0x1d684907, 0x01d9992f, 0x0fea8342, 0x38fa2883, 0x2f10ebb6, 0x1bc3}}}, + /* 5*16^27*G: */ + {{{0x1d81983b, 0x17dd175f, 0x38eab786, 0x0883f40b, 0x3ffacc10, 0x32d81dc7, 0x23abe4c3, 0x0a184a84, 0x3bc3}}, + {{0x11a637b6, 0x3667ca14, 0x3bb848db, 0x0d2216a3, 0x300a7f43, 0x2cc172ab, 0x08a20250, 0x209b7b43, 0xa6b5}}}, + /* 7*16^27*G: */ + {{{0x37c8537b, 0x17ddb07f, 0x01f80617, 0x232b2dd1, 0x396c21ca, 0x2bbf872b, 0x004ac51b, 0x293a3a7b, 0x67cb}}, + {{0x385726da, 0x33ad415c, 0x0403f6e1, 0x37c10fb4, 0x31cc047b, 0x07187cbe, 0x08984a1e, 0x3b7b7a87, 0x5b65}}}, + /* 9*16^27*G: */ + {{{0x0b6a1226, 0x1a08a339, 0x35465393, 0x3e7a722a, 0x28f3922a, 0x1cf5a191, 0x099931a0, 0x23a9b55d, 0xc595}}, + {{0x066961d4, 0x30401a23, 0x22108b91, 0x21db6fae, 0x05bd8296, 0x3865c675, 0x37dd7ecb, 0x2a20bdc3, 0xa031}}}, + /* 11*16^27*G: */ + {{{0x33713a52, 0x1378fe16, 0x03c5417e, 0x31d6e31a, 0x0a5fa025, 0x33030f1d, 0x25ca7c1f, 0x1efe0b90, 0x83f0}}, + {{0x1fb0ffb6, 0x04449cfe, 0x1fb45d2a, 0x2d6dd838, 0x07d3cfca, 0x1e53244b, 0x38bb9049, 0x13c42896, 0xf2ec}}}, + /* 13*16^27*G: */ + {{{0x21ba21b0, 0x2b668244, 0x0c265539, 0x15763480, 0x2e0076d8, 0x1a01a1ba, 0x242d4e6f, 0x2e93e6d6, 0x938d}}, + {{0x0d5b4325, 0x1d366579, 0x32b697c3, 0x3c6efb8f, 0x36b90bcb, 0x2ab6f744, 0x356566e9, 0x302a26bd, 0x48af}}}, + /* 15*16^27*G: */ + {{{0x3f2b24f1, 0x14f92698, 0x3e76bcfb, 0x2bb193d7, 0x349779cf, 0x076ab3ce, 0x031e73a8, 0x226ddb28, 0x7efa}}, + {{0x2f8e4b83, 0x19771752, 0x154a455d, 0x2eb7ceb1, 0x16ab211d, 0x3b488bf0, 0x0aeff78c, 0x3cfb187d, 0xa99f}}} + }, + { + /* 1*16^28*G: */ + {{{0x22f2b734, 0x01a66fe7, 0x101d267f, 0x30eed6d5, 0x16445779, 0x129e1bc4, 0x0c99a063, 0x008a67bb, 0x224a}}, + {{0x11ec7fdf, 0x103d6152, 0x3c7afd08, 0x2dc12d9c, 0x1d7fff07, 0x2822b61c, 0x122b4149, 0x2a34a6db, 0xfa41}}}, + /* 3*16^28*G: */ + {{{0x1d254033, 0x27a4bd1d, 0x2a4707ac, 0x0da0a030, 0x36f24078, 0x2b7e9a22, 0x0ec59fcd, 0x00bb854f, 0xe635}}, + {{0x28f05e3f, 0x3a2aa225, 0x3fcf3607, 0x24568312, 0x09ce482c, 0x13a03c1c, 0x21e11ad7, 0x20dec7d8, 0xa7c5}}}, + /* 5*16^28*G: */ + {{{0x21e08f33, 0x2e5826bf, 0x3982cca2, 0x3f58c772, 0x3000e2b1, 0x2d1714cf, 0x3968712a, 0x37b09cba, 0x5648}}, + {{0x0269f1c9, 0x1bbb66b1, 0x01179512, 0x1caefcb8, 0x37a2693e, 0x23d71935, 0x37043f47, 0x371c1c23, 0x95fd}}}, + /* 7*16^28*G: */ + {{{0x3ab98c43, 0x0ee0802f, 0x23e8aa4e, 0x2e95dd5f, 0x2c8f03c5, 0x14be3b2f, 0x0ed26951, 0x3067cce0, 0x1941}}, + {{0x22abe217, 0x3e884368, 0x0df56398, 0x3d8b4f6e, 0x3b8c53d8, 0x1b6ca923, 0x1b2b6e2b, 0x2e0d1657, 0x8e66}}}, + /* 9*16^28*G: */ + {{{0x02d8c2f4, 0x199c3441, 0x39c0189e, 0x0cc86e7d, 0x0d8a0bd7, 0x1cef78d9, 0x34bd67fa, 0x190c7442, 0xfc58}}, + {{0x3cfd274a, 0x0463223f, 0x3c338b40, 0x38b2c17a, 0x3db4ab29, 0x0f09e79a, 0x2d9564a3, 0x3794b3a2, 0x99fa}}}, + /* 11*16^28*G: */ + {{{0x11ff0f18, 0x0ac1dfc7, 0x149a42d1, 0x382f39c1, 0x32d6c207, 0x3eeb3e6b, 0x0f1dea9b, 0x0ee9ac31, 0xee99}}, + {{0x250782ad, 0x004e1db2, 0x30f2cb18, 0x0d72037d, 0x05bcfeb4, 0x3175633a, 0x0db2c1f6, 0x3536515e, 0xd87f}}}, + /* 13*16^28*G: */ + {{{0x0fdde3fc, 0x11e9fdd5, 0x1628cc9e, 0x2a222781, 0x2f31fbe5, 0x03710694, 0x3e2428da, 0x145eaba7, 0xba49}}, + {{0x2fcb7d01, 0x0fbf48cb, 0x3292caaa, 0x37872078, 0x13359adf, 0x3b90dd80, 0x055950b4, 0x2db872a5, 0xa88f}}}, + /* 15*16^28*G: */ + {{{0x3d14da68, 0x2224a8bd, 0x1d201737, 0x19307e13, 0x3612b54a, 0x0b3e09cd, 0x2f1ba4de, 0x23c5d08a, 0xd339}}, + {{0x15a90e3d, 0x3c1d8c6d, 0x141453a3, 0x31e9e48b, 0x22b020af, 0x094b47a2, 0x13d60eb7, 0x3535347f, 0xa34a}}} + }, + { + /* 1*16^29*G: */ + {{{0x3789b84d, 0x298196b5, 0x1041ce2e, 0x1f57b934, 0x2493fe16, 0x174446d5, 0x34b4ccdb, 0x298515cd, 0x4a89}}, + {{0x018e3ea8, 0x3e6df5fc, 0x0711999e, 0x0b8a018d, 0x2677e6a7, 0x0baa5e7f, 0x00d5c08c, 0x13a1fb52, 0x45b0}}}, + /* 3*16^29*G: */ + {{{0x02e14c34, 0x39dac8dd, 0x33275936, 0x1317af81, 0x1377c983, 0x26cc39e0, 0x0ef92a2a, 0x25922a1c, 0xcc9f}}, + {{0x14be556b, 0x224855ea, 0x28c7e058, 0x2645fc60, 0x2689db29, 0x0598cf6f, 0x0c96f431, 0x3fcb2d7e, 0x829b}}}, + /* 5*16^29*G: */ + {{{0x15de4837, 0x1f79b216, 0x1e5e74e8, 0x10a1b20b, 0x198a758d, 0x1630742b, 0x1041af4f, 0x23687eab, 0x5c61}}, + {{0x234a7dee, 0x02e160ed, 0x02278cac, 0x34d99259, 0x3d9671ec, 0x2038e127, 0x3a19d88b, 0x2445ef3c, 0x4c71}}}, + /* 7*16^29*G: */ + {{{0x16635396, 0x1624d099, 0x28a6c0c2, 0x32b8568d, 0x31c11ef2, 0x178b7799, 0x206a2e58, 0x221aa456, 0xab8a}}, + {{0x3fc92c23, 0x38e3e9a8, 0x3d2d6ad7, 0x0d8160fd, 0x3cd5abb9, 0x23fe0922, 0x04319566, 0x33df1f6a, 0xe773}}}, + /* 9*16^29*G: */ + {{{0x01df49c3, 0x3090f962, 0x1069a35a, 0x3a24219b, 0x15604aa9, 0x1992e2da, 0x1838cdec, 0x32145090, 0x62b7}}, + {{0x36341c21, 0x2f8da03f, 0x07cb5509, 0x2d4ed84e, 0x0922db8f, 0x225aba35, 0x20335594, 0x358854ab, 0xa71e}}}, + /* 11*16^29*G: */ + {{{0x244f47d0, 0x2bc51b8b, 0x09f002f3, 0x167d77a5, 0x1fc9791b, 0x147c21a7, 0x089c5f97, 0x2f6fe917, 0x4897}}, + {{0x0e1320bf, 0x079406ab, 0x0f011958, 0x1b68006a, 0x3b093f52, 0x23b2a505, 0x0138c34e, 0x3083debf, 0xe77d}}}, + /* 13*16^29*G: */ + {{{0x31581bd3, 0x186f3a6d, 0x2190786e, 0x3e8c637d, 0x322f2ecb, 0x0781ef69, 0x06576c45, 0x3f2d5592, 0xeb1c}}, + {{0x1cd98a09, 0x2f3a3661, 0x1bd1a645, 0x273cc671, 0x0d6e3cb3, 0x10017af9, 0x14d20504, 0x339d5c7e, 0xfd47}}}, + /* 15*16^29*G: */ + {{{0x273a3111, 0x0048af6d, 0x34c818f9, 0x2e0b905e, 0x2576a018, 0x152b0b9c, 0x21e09c0d, 0x22eef923, 0xa1fd}}, + {{0x38c704ef, 0x221f9942, 0x3d51169b, 0x3b12516f, 0x0916c0c7, 0x1df81ef0, 0x308569bd, 0x17628d28, 0xad21}}} + }, + { + /* 1*16^30*G: */ + {{{0x32bd05a0, 0x10e32129, 0x31fc80d3, 0x208cdf42, 0x2d1f90ba, 0x0be657cd, 0x1885cedc, 0x248d8e8c, 0xe5e8}}, + {{0x21a69f5d, 0x24db78af, 0x0d099aec, 0x1ce656e7, 0x1b5c3eca, 0x07ac079e, 0x387d2130, 0x27793686, 0x7743}}}, + /* 3*16^30*G: */ + {{{0x01467d6b, 0x3c254a04, 0x2a24b514, 0x1f5c4a54, 0x2cf1d835, 0x06184590, 0x1ccf5d10, 0x24f7e50d, 0x5d23}}, + {{0x31bc5458, 0x1f19cf1a, 0x10473a80, 0x29c1e9d4, 0x1af46d72, 0x2f616cb5, 0x10f7d7ac, 0x18fc98ff, 0xe66e}}}, + /* 5*16^30*G: */ + {{{0x1d159f7a, 0x02c7a4f2, 0x242e590f, 0x3e4ea73c, 0x3f873fec, 0x33ecaf4b, 0x3893f3ad, 0x15e94eaa, 0x4536}}, + {{0x0a02fb78, 0x2708adc2, 0x01dda5d9, 0x2526f53a, 0x01c7286f, 0x3bc244e8, 0x23dc5da2, 0x2bbfe200, 0xbfb5}}}, + /* 7*16^30*G: */ + {{{0x146cb42a, 0x07b7b7cf, 0x32390933, 0x014a14e9, 0x3d73e7bc, 0x12b7aa84, 0x04c464d1, 0x1532c1ec, 0x435b}}, + {{0x1af72dd0, 0x1f8937b7, 0x33949a6b, 0x37131e50, 0x20585d5e, 0x12953307, 0x18a1a49f, 0x300c791c, 0xd726}}}, + /* 9*16^30*G: */ + {{{0x1d2fc263, 0x25f6506c, 0x365d57ba, 0x33e04f96, 0x13da0e89, 0x2f11f138, 0x2dd7e19f, 0x2e067853, 0x1805}}, + {{0x30870ec7, 0x1991c2d3, 0x151ecaf2, 0x2306be39, 0x0b31489c, 0x236aa1af, 0x38171585, 0x190a0250, 0x101f}}}, + /* 11*16^30*G: */ + {{{0x0076d1df, 0x28ac6dc3, 0x27fa1b39, 0x07882050, 0x375f45f4, 0x05ea28a9, 0x3194f406, 0x2bd0d9b4, 0xc73a}}, + {{0x25ad6605, 0x09e7545b, 0x1893720d, 0x16d5e947, 0x3cdcfef7, 0x3806f8ee, 0x3916ef9c, 0x3b1a7b33, 0x9201}}}, + /* 13*16^30*G: */ + {{{0x05a745c7, 0x0da0fde6, 0x17eac07d, 0x2289ce30, 0x1d52c1bc, 0x226dabd8, 0x036d2771, 0x3ba3df57, 0xe3dd}}, + {{0x378efcc2, 0x0e7c2501, 0x3d027b1a, 0x0a30bc5e, 0x3bd8f47c, 0x146e1aa9, 0x32b871be, 0x2674e464, 0x4871}}}, + /* 15*16^30*G: */ + {{{0x0d4170b3, 0x131ccfa1, 0x03a3587f, 0x051055bf, 0x00a1d540, 0x22a8461b, 0x1f1e5af6, 0x2377080d, 0x45c7}}, + {{0x111faa1d, 0x1bbe8fb5, 0x020cc731, 0x2c119819, 0x3b3a512c, 0x06a74513, 0x15c0cb0e, 0x265188e3, 0x11af}}} + }, + { + /* 1*16^31*G: */ + {{{0x3ab5c2cf, 0x055e664b, 0x3b084de2, 0x04bc3087, 0x3a90a453, 0x1d1d0413, 0x21f5071e, 0x1f90c788, 0xe410}}, + {{0x2b955c2b, 0x00a100fc, 0x37b2410d, 0x1e24b73f, 0x1c2b323c, 0x2319a1d0, 0x01c9a394, 0x0479b3dc, 0x1e5f}}}, + /* 3*16^31*G: */ + {{{0x09b67b7e, 0x2ed6d8f0, 0x11c3d485, 0x1adecae4, 0x3c114276, 0x3e5c077a, 0x39f7daac, 0x26997b85, 0x85df}}, + {{0x030a36e3, 0x22ce1a7a, 0x3bc6ea58, 0x3ea52747, 0x0e297386, 0x2df57bfc, 0x36308bb6, 0x2dea8e6b, 0xa6b4}}}, + /* 5*16^31*G: */ + {{{0x0b3510d3, 0x09f3f798, 0x0a1d6e41, 0x34c599c1, 0x2d292885, 0x22861970, 0x3cd08a8d, 0x24ff9fe7, 0x23c4}}, + {{0x3ae89a47, 0x0d18bb10, 0x2b9dbd71, 0x2678d789, 0x3fe6d8f7, 0x1d76793b, 0x014230c2, 0x15aa790d, 0xadf4}}}, + /* 7*16^31*G: */ + {{{0x0b49a71f, 0x331a4602, 0x0227c39a, 0x0dbadb19, 0x3235ddac, 0x264faeab, 0x1d0edde5, 0x1b42cc53, 0x9440}}, + {{0x10b249a9, 0x1c706513, 0x263cf944, 0x389c9872, 0x2fe897d0, 0x01f24241, 0x1f179cd2, 0x39dfa193, 0x61aa}}}, + /* 9*16^31*G: */ + {{{0x20e50c32, 0x17378cf1, 0x0c6873fe, 0x3c425cba, 0x2e8d3877, 0x04db7d6f, 0x06c14337, 0x2fd0f7a2, 0x3c2e}}, + {{0x0a93c124, 0x38be245f, 0x2e8c9989, 0x0b4230e6, 0x2e28e7be, 0x16e4f480, 0x0399c652, 0x3669b17a, 0xa703}}}, + /* 11*16^31*G: */ + {{{0x03a2355a, 0x020f677b, 0x06049907, 0x1946fcd7, 0x055f1299, 0x0796e27b, 0x00eb9f39, 0x0db5c9e5, 0x9875}}, + {{0x1bd05276, 0x031d7130, 0x03adccdf, 0x17db1f1a, 0x257b48b8, 0x02c70527, 0x1117243e, 0x26b59d3c, 0x12f1}}}, + /* 13*16^31*G: */ + {{{0x12f3ec22, 0x03c151f1, 0x1a8f8a6b, 0x3e1b73dc, 0x32ddddd1, 0x34e2c5fb, 0x04468f19, 0x2b102693, 0xd515}}, + {{0x25a2863b, 0x28518bac, 0x31b806ec, 0x355f7c00, 0x12bd464c, 0x17921001, 0x09b2e1ea, 0x12050891, 0x51c0}}}, + /* 15*16^31*G: */ + {{{0x1971c857, 0x16687a69, 0x3e6093fa, 0x32679b6a, 0x21cf3dde, 0x14f30e2d, 0x1b0bae24, 0x27526179, 0x070b}}, + {{0x0ac8dfc1, 0x3e72d8f7, 0x05461aaf, 0x2a0f687b, 0x373cfb33, 0x2042b918, 0x3625086b, 0x1186ffd2, 0xed80}}} + }, + { + /* 1*16^32*G: */ + {{{0x1789bd85, 0x1f213f27, 0x297eac35, 0x0d7fdf70, 0x06766efc, 0x20bf5623, 0x35e67fb9, 0x1ce6fbb6, 0x447d}}, + {{0x32e25b32, 0x31f8cf25, 0x3fae5000, 0x0d26e569, 0x0aaff73d, 0x3a7654e9, 0x131eee12, 0x096ae0d0, 0x2d48}}}, + /* 3*16^32*G: */ + {{{0x1ea6db68, 0x0f86663b, 0x02632c27, 0x3eb61582, 0x1ef4f6dd, 0x0537e597, 0x2017f58b, 0x14cf80f2, 0xf8b6}}, + {{0x2e760da9, 0x26f496c2, 0x05ca0ed6, 0x2f5c3767, 0x2a3ec66b, 0x11b76942, 0x054862f0, 0x13bd7b11, 0xc30f}}}, + /* 5*16^32*G: */ + {{{0x3924e753, 0x1b5753af, 0x0f8727c6, 0x005cc1cb, 0x2dfb755f, 0x3bc61ca7, 0x2847c548, 0x2274d560, 0xf352}}, + {{0x2b13a20c, 0x2916d70b, 0x12d0f04a, 0x18bf15ca, 0x0e1bd8c5, 0x3c2286d4, 0x013fb93d, 0x1e07b17b, 0x75c1}}}, + /* 7*16^32*G: */ + {{{0x3018017e, 0x0e572d9c, 0x2df23d72, 0x0507fff5, 0x334e01af, 0x10617ed9, 0x01716483, 0x1add3691, 0xcfd0}}, + {{0x0e0dff50, 0x02b9ef93, 0x3779777a, 0x0c0c1e1a, 0x1a795000, 0x0ece561f, 0x3a913810, 0x2dea6dca, 0xb647}}}, + /* 9*16^32*G: */ + {{{0x392db860, 0x13206415, 0x29a247b0, 0x0224a20c, 0x15dbe981, 0x0b5b423c, 0x1dcd1151, 0x39d312b5, 0x0755}}, + {{0x20d09849, 0x3598036e, 0x3c2777a7, 0x24dd1933, 0x015bc2b2, 0x26cb608e, 0x19e4dd24, 0x2be9d4eb, 0xfe16}}}, + /* 11*16^32*G: */ + {{{0x2a26ba6b, 0x27bda557, 0x2da12c3a, 0x0b28a925, 0x30bbdedd, 0x043035fa, 0x2c96968a, 0x2a1330dc, 0x88fb}}, + {{0x244972f8, 0x01051e07, 0x00cfdce8, 0x12a78a38, 0x14788d48, 0x1b6916d4, 0x1be0fd26, 0x3bd9274e, 0x512a}}}, + /* 13*16^32*G: */ + {{{0x14720cab, 0x2712290a, 0x339b17e3, 0x07a97505, 0x1c6f2c1a, 0x03db9d55, 0x15beb8e5, 0x2b32fb01, 0xe1a0}}, + {{0x34b185c9, 0x1b514fd5, 0x080254ea, 0x128a9c74, 0x2ebcbf08, 0x1be0c1df, 0x0c854183, 0x1a3edfa6, 0xe079}}}, + /* 15*16^32*G: */ + {{{0x2c26c42a, 0x2a0a3f7f, 0x2b11bb62, 0x26fedf91, 0x27e6a024, 0x2cd624c7, 0x33c7e50d, 0x0ee1b9a9, 0x0ae9}}, + {{0x39f808ca, 0x0418cd0e, 0x1aadb649, 0x228e7bbd, 0x220b3727, 0x0b8fb707, 0x07e13a94, 0x3db7451e, 0x7028}}} + }, + { + /* 1*16^33*G: */ + {{{0x137de736, 0x3af62eb0, 0x288ce241, 0x3e355861, 0x1ec18ea2, 0x1d50ae33, 0x0cf3e893, 0x38c52527, 0x9022}}, + {{0x04c42ecc, 0x13bd7021, 0x0ea7657f, 0x124d9b11, 0x26ce087f, 0x02ec1148, 0x0a39466d, 0x1793ca41, 0x2fae}}}, + /* 3*16^33*G: */ + {{{0x109b01f5, 0x05c1b2e3, 0x273c0519, 0x0fcd460c, 0x37857af7, 0x3cb4fc6b, 0x3e945fb0, 0x1cb8c1db, 0x6e58}}, + {{0x2bcd5fde, 0x0c1d6366, 0x09a85a7c, 0x0c5e7538, 0x3ef0ebc1, 0x30752bce, 0x3717180c, 0x300bb235, 0x4213}}}, + /* 5*16^33*G: */ + {{{0x2fe45b1f, 0x14e6dd1f, 0x26168c2b, 0x34557ecb, 0x17df827b, 0x3478d130, 0x23f504af, 0x082c6976, 0x2922}}, + {{0x134bb026, 0x3f902e2d, 0x0dd41045, 0x30d10c13, 0x298d7ff7, 0x31e57feb, 0x175aee37, 0x2814cafc, 0xe316}}}, + /* 7*16^33*G: */ + {{{0x23abd540, 0x3a14198a, 0x3166de43, 0x20101952, 0x093a340e, 0x093e1c84, 0x04f0ac32, 0x385201e9, 0x3644}}, + {{0x155da631, 0x071bf873, 0x26fa14de, 0x05df3b69, 0x21e29300, 0x0a14c27e, 0x2797611c, 0x245436f0, 0xec5a}}}, + /* 9*16^33*G: */ + {{{0x09142ccb, 0x28bf487a, 0x287ede31, 0x248296b1, 0x3bb4824c, 0x2ce3d264, 0x0d838e55, 0x1f6b85ff, 0xedfe}}, + {{0x2c593d75, 0x2e5474c6, 0x151142eb, 0x2910ada7, 0x15beb81d, 0x1574ad3d, 0x1af21618, 0x24848b83, 0xc886}}}, + /* 11*16^33*G: */ + {{{0x0a41b208, 0x0f69c719, 0x2e27000f, 0x3dd1d737, 0x2a0de8e7, 0x05009af3, 0x1a695987, 0x25a2d016, 0x5311}}, + {{0x048e4b69, 0x24787e78, 0x036877f6, 0x0f077009, 0x33da113b, 0x196078ce, 0x22978a6c, 0x1ccacf70, 0xb78d}}}, + /* 13*16^33*G: */ + {{{0x095daae7, 0x0f406d71, 0x07033bcb, 0x11b9bb1f, 0x20e1d5af, 0x08afdbd5, 0x3a594f7a, 0x347c8bfe, 0xf65d}}, + {{0x02556738, 0x35396a67, 0x2acd9b28, 0x018603e7, 0x3c4cd0eb, 0x1bf98df3, 0x366e820e, 0x2e083386, 0x9d71}}}, + /* 15*16^33*G: */ + {{{0x3afcf1ee, 0x2fbf0578, 0x2069a11a, 0x3eaa011c, 0x2807c60a, 0x2fd202aa, 0x2e248b41, 0x039fb732, 0xa667}}, + {{0x20c67fc8, 0x1e21c2af, 0x13cf38a3, 0x3ce62472, 0x17ac131e, 0x17dcbd25, 0x1c2f3a39, 0x05324e94, 0xa7fd}}} + }, + { + /* 1*16^34*G: */ + {{{0x04cd3397, 0x10451705, 0x1515eb57, 0x0d304186, 0x156deddc, 0x21b3cad4, 0x1a723893, 0x3fc1067b, 0x73ba}}, + {{0x1adcb8e4, 0x07bca84e, 0x02613494, 0x27be4b3e, 0x0f825e77, 0x0347a306, 0x3ac5f6a0, 0x3798d25d, 0x1e97}}}, + /* 3*16^34*G: */ + {{{0x161fb913, 0x3ac3e548, 0x2d312977, 0x04091855, 0x3ed04e3e, 0x0e237912, 0x20a18344, 0x0cc30cf9, 0x45f8}}, + {{0x0c15c3bc, 0x035205f0, 0x2fc33737, 0x1b421e7d, 0x3a7760f0, 0x3a01db62, 0x2906ef80, 0x33db6ff5, 0xc212}}}, + /* 5*16^34*G: */ + {{{0x2e393654, 0x2bbe5a47, 0x3edd7c75, 0x1752f87c, 0x0d599196, 0x1680722f, 0x3bdab65f, 0x37126b35, 0x5544}}, + {{0x0f53206f, 0x0d842efe, 0x3d58e732, 0x07bfa5c0, 0x13519224, 0x3016d6e2, 0x3fd4ac04, 0x21625421, 0xed3e}}}, + /* 7*16^34*G: */ + {{{0x28a15dfd, 0x0fcd6650, 0x1fa9e551, 0x076eb009, 0x22f69574, 0x34bb556b, 0x2e7734b3, 0x2de41867, 0x2757}}, + {{0x3042c341, 0x323a1033, 0x0a7156df, 0x1a25e28f, 0x15500d17, 0x25d484f3, 0x2b12e5cc, 0x34b55530, 0xdf46}}}, + /* 9*16^34*G: */ + {{{0x3f840a5b, 0x3fb7d09a, 0x3ad4984e, 0x232b6974, 0x143ccd14, 0x10873304, 0x22bc8d98, 0x10df7943, 0xe872}}, + {{0x1377e86a, 0x21396154, 0x1396464b, 0x0e8d1b3e, 0x248bf5ac, 0x2f247d98, 0x29616593, 0x2f22449c, 0xf984}}}, + /* 11*16^34*G: */ + {{{0x336afd6a, 0x255aa6e2, 0x1781e3d4, 0x187f1428, 0x33334a92, 0x3bdb579b, 0x375c0392, 0x372ae935, 0xc56c}}, + {{0x33f87c26, 0x1821afbb, 0x28cc723e, 0x3d20ec95, 0x194ef566, 0x3b7ac5fd, 0x2b070cd2, 0x15b8bce1, 0xd160}}}, + /* 13*16^34*G: */ + {{{0x2cfd2cd0, 0x36b66034, 0x19c0c131, 0x2504cd10, 0x08abb123, 0x34a160f9, 0x3f2869cf, 0x399ce3cf, 0xd3d6}}, + {{0x394ae2dc, 0x315e71dd, 0x2f6f8f14, 0x07e95a30, 0x3de59b00, 0x36a3fdcd, 0x19b68536, 0x23d7f345, 0xff44}}}, + /* 15*16^34*G: */ + {{{0x1ab7a64c, 0x25622157, 0x209ab7a0, 0x14235a8e, 0x37d40656, 0x04cb5c88, 0x05c07b03, 0x1de215b9, 0x88f9}}, + {{0x1575f103, 0x017a6384, 0x16d2673a, 0x30c02488, 0x169e5836, 0x0c6bc95e, 0x15c74345, 0x173751ad, 0x4a74}}} + }, + { + /* 1*16^35*G: */ + {{{0x1fa4e33c, 0x38b97ecc, 0x3098cb30, 0x20efb1e2, 0x36fb9826, 0x1111b0a5, 0x025bbc97, 0x11ae4693, 0x9cf6}}, + {{0x0e0d4563, 0x27117818, 0x3c160321, 0x081609fa, 0x021f319e, 0x0238962e, 0x25a891e4, 0x1893707d, 0x37b0}}}, + /* 3*16^35*G: */ + {{{0x06bf1e67, 0x262d8633, 0x25caf63e, 0x1599d27f, 0x364e0f4c, 0x2994e09d, 0x364999d7, 0x10f78546, 0x83cb}}, + {{0x099acc97, 0x09fba2cc, 0x1d1169ea, 0x1d108b2f, 0x0418f828, 0x0601b989, 0x0f6f8efb, 0x232892e6, 0xbce2}}}, + /* 5*16^35*G: */ + {{{0x1c0f057e, 0x0c2b5d23, 0x1d53dd82, 0x3a18a1c0, 0x25022484, 0x103f0578, 0x2b08c033, 0x2cf95833, 0x3ff3}}, + {{0x2817965e, 0x3507df6a, 0x07017622, 0x0408dbb1, 0x067843a0, 0x3f45c15e, 0x2578f6f7, 0x2b5bceed, 0x7f17}}}, + /* 7*16^35*G: */ + {{{0x325e69f1, 0x14452d00, 0x022bcb51, 0x19ea3cb5, 0x16af9963, 0x067785cf, 0x3d83fdda, 0x36cb763f, 0x6e9e}}, + {{0x002b7e9b, 0x08385f8d, 0x19f281b7, 0x1c9d151e, 0x33bff61c, 0x155aad97, 0x3954eab3, 0x0885b3bf, 0xc082}}}, + /* 9*16^35*G: */ + {{{0x2288f038, 0x3c94bd9a, 0x35ff820b, 0x21da253a, 0x2c2d32f0, 0x2f06779b, 0x01c4befa, 0x203a0131, 0x5ee2}}, + {{0x36f1ee6e, 0x316aae1a, 0x0e6c6f41, 0x35e0cea6, 0x09eec011, 0x0161bfb3, 0x3e39284c, 0x1a7e519d, 0xbcd9}}}, + /* 11*16^35*G: */ + {{{0x00c708c8, 0x02fcc95b, 0x370a86aa, 0x0d0c13cb, 0x3e288c2c, 0x38d97647, 0x205736df, 0x059b8170, 0xe1f0}}, + {{0x3896ed38, 0x1c635cec, 0x3b5a00ae, 0x1957c8bb, 0x233016fb, 0x118cafa2, 0x03b52044, 0x194fa45b, 0xe647}}}, + /* 13*16^35*G: */ + {{{0x076edefb, 0x383c2729, 0x00e7d5d7, 0x162f6004, 0x39c7badd, 0x086ad0a5, 0x2345c7f1, 0x25a1eafd, 0x2808}}, + {{0x1d1b0ae0, 0x3bd15c8a, 0x20392122, 0x34c6c1ef, 0x0541c44d, 0x3867af64, 0x33191a67, 0x073ccf4e, 0x5d07}}}, + /* 15*16^35*G: */ + {{{0x3344897a, 0x04b666f3, 0x24c269dd, 0x27b4c1d6, 0x25edab7b, 0x217a1490, 0x104cb705, 0x2c378a06, 0xeb15}}, + {{0x25bfe7ee, 0x3677a0f3, 0x17d0b82a, 0x11a62cbe, 0x332f8581, 0x22abe335, 0x26071089, 0x3745a709, 0x096c}}} + }, + { + /* 1*16^36*G: */ + {{{0x123b716d, 0x09beb701, 0x34e1a6b8, 0x08e259bd, 0x18df9e0d, 0x171e4e34, 0x0a534e8a, 0x16f8e2e3, 0xf81f}}, + {{0x12632401, 0x19000bd4, 0x28783304, 0x01d6140e, 0x0e032866, 0x1b4a74e0, 0x306df1d5, 0x124ca707, 0xdc7f}}}, + /* 3*16^36*G: */ + {{{0x39d19d8a, 0x1315a140, 0x1a552158, 0x1049e254, 0x2d490a3b, 0x1bb0d705, 0x286385af, 0x21143ec4, 0xa600}}, + {{0x190d2c4f, 0x36576ecd, 0x326573df, 0x3f8023e9, 0x29ca84f0, 0x1b5179ef, 0x37c72c8f, 0x1e7019e8, 0x7b4b}}}, + /* 5*16^36*G: */ + {{{0x096cac9f, 0x1a61ece5, 0x044de722, 0x38e33a97, 0x2b0e1c59, 0x3025e63f, 0x1f354c64, 0x20ac659f, 0xde53}}, + {{0x2fa473d3, 0x33820bf6, 0x3d841157, 0x38f8a51c, 0x0f9f2bc2, 0x0ec02647, 0x0918562c, 0x2d9e2da7, 0x9c47}}}, + /* 7*16^36*G: */ + {{{0x06807a23, 0x32ca58de, 0x225ff3e7, 0x0008145a, 0x194ec840, 0x12e67544, 0x2a908534, 0x1ec201fc, 0xa722}}, + {{0x14115894, 0x311c660f, 0x328cdc91, 0x2fe055ed, 0x2075abe7, 0x2a11e482, 0x139e845d, 0x1d497517, 0xf550}}}, + /* 9*16^36*G: */ + {{{0x044d14c0, 0x29e5ff08, 0x1a8f35e5, 0x172ad7e8, 0x261d3900, 0x2af9ce8d, 0x04596465, 0x0ba3508d, 0xcd2b}}, + {{0x22496315, 0x1582b3c8, 0x1accecea, 0x36dbc32e, 0x00f671fd, 0x017bb76b, 0x070a24d5, 0x04b7e6c2, 0xf130}}}, + /* 11*16^36*G: */ + {{{0x399a1566, 0x1bd3ac48, 0x3228f696, 0x171956bf, 0x1f9dd8f2, 0x3ef26e0f, 0x1f7eb4ce, 0x3a1323c3, 0x11b2}}, + {{0x1c56bb73, 0x2692cf01, 0x0d809685, 0x12d56103, 0x3405cc82, 0x0b5a61e5, 0x23175d04, 0x1da76f28, 0x6103}}}, + /* 13*16^36*G: */ + {{{0x1ba6f34a, 0x3427aca3, 0x245c6f87, 0x0a1a83f8, 0x19148531, 0x36828fbe, 0x3a070759, 0x064a57ca, 0xfb6d}}, + {{0x2bcf0452, 0x2d7cf208, 0x1685b1f9, 0x3f3e8b72, 0x2791b9ec, 0x223f5312, 0x346dd9e3, 0x0b4a75ef, 0xf29b}}}, + /* 15*16^36*G: */ + {{{0x0a435427, 0x1328b4a8, 0x3e4db507, 0x24042609, 0x106651a6, 0x3d9d9436, 0x013c10aa, 0x27f3040f, 0xff42}}, + {{0x39853824, 0x39411434, 0x23a0da28, 0x16fb94d2, 0x18687620, 0x10272158, 0x2cdb094d, 0x3e59a293, 0x2add}}} + }, + { + /* 1*16^37*G: */ + {{{0x07354b7a, 0x3b671f9e, 0x3915c978, 0x0bb295b0, 0x3cde1d02, 0x1fd18f94, 0x20848239, 0x151d35df, 0x8568}}, + {{0x116e04c6, 0x255100af, 0x3d6fdbd8, 0x2a247707, 0x2f728706, 0x3244eca9, 0x187b6eeb, 0x03ad42fd, 0x20b5}}}, + /* 3*16^37*G: */ + {{{0x3b26165d, 0x3db31fe9, 0x277137ea, 0x04e8857d, 0x0c92dea7, 0x274824bf, 0x23e6549e, 0x1131d4ac, 0x6173}}, + {{0x06b2a286, 0x126ff72e, 0x37171a4c, 0x266b05b8, 0x0220b298, 0x1f442f46, 0x3835a49b, 0x0585e90d, 0xe990}}}, + /* 5*16^37*G: */ + {{{0x10442770, 0x086fdd99, 0x101bad10, 0x063de9b8, 0x00fc2e90, 0x13076a79, 0x36a22da0, 0x00fb957e, 0xf8ac}}, + {{0x1b00c82d, 0x28a193c4, 0x1041d023, 0x1d80afe5, 0x0e6d17a9, 0x1b1d46cd, 0x11e8ea43, 0x23995667, 0x5a35}}}, + /* 7*16^37*G: */ + {{{0x365460de, 0x2f81b61b, 0x2bf77b8f, 0x1cfe342a, 0x0c8ea60c, 0x32f2f8c3, 0x095c66c6, 0x07ed496f, 0x8a73}}, + {{0x3f8dc207, 0x26166877, 0x2508ee3e, 0x219f8f14, 0x304dc435, 0x0a552ffe, 0x363198f5, 0x157178aa, 0x5858}}}, + /* 9*16^37*G: */ + {{{0x351634a5, 0x10aaeb7e, 0x1ed524e6, 0x3e429e0d, 0x17967f3c, 0x29ae80b3, 0x0f224bf0, 0x18184caa, 0xa20b}}, + {{0x3226afad, 0x1b04de57, 0x0d45edf2, 0x1d1d5f8f, 0x3b315bc6, 0x357fa0dc, 0x1b99dad3, 0x33a7da5f, 0x9c43}}}, + /* 11*16^37*G: */ + {{{0x33ba54a8, 0x010c8912, 0x03aa9707, 0x22c98d58, 0x05cc0ab5, 0x0e3b0d3f, 0x16709914, 0x07e4fc49, 0x016f}}, + {{0x264f2889, 0x35f187e9, 0x2a3b4e6e, 0x0ebc9d51, 0x1ce658d9, 0x26c46f92, 0x151576f2, 0x34d04562, 0x08bc}}}, + /* 13*16^37*G: */ + {{{0x27c16d94, 0x3bb924f3, 0x02845fdd, 0x160742a8, 0x0ec31fe2, 0x23f59f33, 0x034788c0, 0x2199c2f4, 0xe615}}, + {{0x314810ab, 0x2d3b466a, 0x3a443bbf, 0x19734791, 0x36f0ee4e, 0x2cae4fd2, 0x124be8c5, 0x00eba79c, 0x65ca}}}, + /* 15*16^37*G: */ + {{{0x13ce728d, 0x35b72999, 0x071cd0bc, 0x33641f8a, 0x085347f4, 0x2822885b, 0x16a26555, 0x1fc2ce35, 0xdcd3}}, + {{0x17cacbcb, 0x35f44da6, 0x29dabeb8, 0x2b34d1b4, 0x06d6f3ca, 0x0ded8acf, 0x24c1872c, 0x36f5df36, 0x6574}}} + }, + { + /* 1*16^38*G: */ + {{{0x12378c16, 0x371b706c, 0x215622ad, 0x0d81d551, 0x39597d9e, 0x2794b5af, 0x33b11b31, 0x2dd6704a, 0x1136}}, + {{0x33488127, 0x27d66f42, 0x351cce37, 0x052a8a39, 0x29ecb296, 0x02af183f, 0x28fdd09f, 0x03f3d145, 0x7dec}}}, + /* 3*16^38*G: */ + {{{0x3b299740, 0x1c39b609, 0x13db1349, 0x03d19f5c, 0x3aad48f4, 0x2b44de4f, 0x14336cc4, 0x0fadc737, 0x5389}}, + {{0x3fff7509, 0x07a9bc6c, 0x1fde8cd5, 0x284cbbc8, 0x35dc8dd8, 0x0738a3a9, 0x1fbd8384, 0x229fa521, 0x2772}}}, + /* 5*16^38*G: */ + {{{0x338000fc, 0x02cf2559, 0x3f03bc13, 0x0789dc1e, 0x3ae5604e, 0x0ddaebc7, 0x0da2757e, 0x3a775d53, 0xdd64}}, + {{0x1df4ac12, 0x3ea87143, 0x11e48f8b, 0x117408ae, 0x0a79ffbe, 0x2278f867, 0x132c96df, 0x24fac30a, 0x4321}}}, + /* 7*16^38*G: */ + {{{0x33878c4a, 0x3e08545c, 0x151c055e, 0x20f40f21, 0x291b21d8, 0x1a718392, 0x3d516f2c, 0x116a1fbf, 0xff98}}, + {{0x3488df68, 0x2e9a11f5, 0x25cfebc6, 0x3ccdd1ad, 0x35e8ddf1, 0x22923b7f, 0x2428f8fd, 0x26bd2938, 0x835b}}}, + /* 9*16^38*G: */ + {{{0x00f51524, 0x32a6e205, 0x3af86fc8, 0x2bada856, 0x1293de5f, 0x19e8c211, 0x1609ce87, 0x04fa2ee4, 0x954e}}, + {{0x05e30a69, 0x27f6cf65, 0x01e7cbde, 0x3ba90c45, 0x1ecbcfa9, 0x31890d1e, 0x24041d93, 0x0d8ffe4a, 0xecc8}}}, + /* 11*16^38*G: */ + {{{0x04f77287, 0x3de6354f, 0x130d9e31, 0x0a54f0da, 0x18049741, 0x35431707, 0x1fb93dfc, 0x1fbdbe90, 0xb221}}, + {{0x24e7b5da, 0x1e8129dc, 0x05e93cb9, 0x02771ce7, 0x38c843d7, 0x3ef3e234, 0x0f3a2b5d, 0x14f8339f, 0xfb51}}}, + /* 13*16^38*G: */ + {{{0x05c723e9, 0x2bd4e5b2, 0x2a781718, 0x25ceeaa6, 0x1d5c351f, 0x31baba45, 0x1bdad122, 0x142c5ede, 0x3c39}}, + {{0x36834763, 0x38e1dd7d, 0x04906ae5, 0x076b2d5f, 0x06a8b0b0, 0x12edfa86, 0x110dbb49, 0x1cd88824, 0xb99b}}}, + /* 15*16^38*G: */ + {{{0x3c18abeb, 0x1c5f5b88, 0x325d62a3, 0x27734641, 0x3aa944d5, 0x3b4be112, 0x21cdad1d, 0x1e8b33e5, 0x803c}}, + {{0x229bfa78, 0x290e6fc3, 0x26721cd6, 0x1f110f0a, 0x0b4409ed, 0x2b3c5a71, 0x2e9286b1, 0x141029e5, 0x83fb}}} + }, + { + /* 1*16^39*G: */ + {{{0x143e832a, 0x31d8bbc6, 0x386df709, 0x3942ac05, 0x09f18e07, 0x15cea096, 0x2a51a90f, 0x3ca2e9f0, 0x0d2b}}, + {{0x1b20d37c, 0x2098ebc5, 0x05514464, 0x3b276e58, 0x34e7ed27, 0x1e842a52, 0x100ac708, 0x0fd0c4ef, 0x0cac}}}, + /* 3*16^39*G: */ + {{{0x112c9666, 0x07ab12f0, 0x1ffcdf36, 0x3e31b0d9, 0x19531b1c, 0x2f30d6df, 0x3f82cfd9, 0x3a17ae59, 0x34e5}}, + {{0x192a3666, 0x168614f2, 0x1e3a526b, 0x11fb58f0, 0x3c46330f, 0x1195d732, 0x1a36b828, 0x1a0c4c88, 0xc0ce}}}, + /* 5*16^39*G: */ + {{{0x11209502, 0x0594af8d, 0x1d92665c, 0x105c8009, 0x19e15459, 0x124fbc24, 0x0d863a6c, 0x18b3167d, 0x7273}}, + {{0x17042b0d, 0x19df474f, 0x32760bbc, 0x234dfe6e, 0x291d20a1, 0x002e30b3, 0x3ab589f1, 0x3d08a6ea, 0x17b0}}}, + /* 7*16^39*G: */ + {{{0x2447f959, 0x1579e4a2, 0x271d3684, 0x11f6aea0, 0x09eee9f9, 0x285312ed, 0x26cec973, 0x3c980152, 0xa0c3}}, + {{0x168b671f, 0x00e74922, 0x0d272c9b, 0x2d550096, 0x228208b1, 0x3e30432d, 0x32c4f382, 0x1cc24392, 0x508c}}}, + /* 9*16^39*G: */ + {{{0x1b37e1d3, 0x087e7c09, 0x0e4de230, 0x1d86f84f, 0x15fd0410, 0x2d0cef90, 0x1ca7a40c, 0x2c8c7de5, 0x7e81}}, + {{0x0155681a, 0x3d7f2899, 0x1c2e0e03, 0x3212fcac, 0x2c7c4e4e, 0x3a25b3b9, 0x3ed13125, 0x1686c3a6, 0xf385}}}, + /* 11*16^39*G: */ + {{{0x16c051a0, 0x125dc57d, 0x35b3e6dc, 0x37ca491b, 0x0f2abddc, 0x1b639b6c, 0x026d84a3, 0x38871f60, 0x8035}}, + {{0x32d0dd12, 0x007aecbe, 0x18b62356, 0x39f718c2, 0x3dd318b3, 0x36f9a0de, 0x22bef375, 0x042912de, 0x0b88}}}, + /* 13*16^39*G: */ + {{{0x3f12c69e, 0x38030c27, 0x1651963c, 0x396bbd62, 0x04fcecaf, 0x2bc00408, 0x0a53306b, 0x0237f586, 0x1969}}, + {{0x1d114831, 0x34cc6410, 0x3fb886b8, 0x2cb8cdc7, 0x21054eb6, 0x3877ab74, 0x16e040be, 0x2fdacbe4, 0x3f65}}}, + /* 15*16^39*G: */ + {{{0x0b89c5ed, 0x1263807f, 0x17a78c7e, 0x2d4c33de, 0x2d0f3577, 0x1b874842, 0x1a2af46e, 0x3f3ae258, 0xdb77}}, + {{0x2d25b46e, 0x27fc71fb, 0x0899afa5, 0x05b1eada, 0x19ad411f, 0x0ce6f932, 0x2e5ceecf, 0x370e1c73, 0x7fd1}}} + }, + { + /* 1*16^40*G: */ + {{{0x37f82f2a, 0x3ba71d77, 0x2fdf43aa, 0x130d61d2, 0x3713269e, 0x08b7d0dc, 0x33617f56, 0x17d59bb1, 0x8a53}}, + {{0x223094b7, 0x17e682b0, 0x08c7669c, 0x394ce193, 0x1a92bfcd, 0x00a06421, 0x08bd737e, 0x30211a2c, 0x0455}}}, + /* 3*16^40*G: */ + {{{0x2b348fa0, 0x2c53c85e, 0x11541ddf, 0x3f891641, 0x24b4bce0, 0x088c8db0, 0x3882dc2a, 0x324f777a, 0x86ea}}, + {{0x0da51cee, 0x3b8e0255, 0x1cfee8a4, 0x09b658d4, 0x2f46716c, 0x0dbe7a35, 0x04d8d5a4, 0x0e14f2ef, 0x948f}}}, + /* 5*16^40*G: */ + {{{0x19222c03, 0x2bd07ff2, 0x3e5e1037, 0x2339dfa1, 0x19f40794, 0x39f5e121, 0x33aae3f5, 0x27aebe7e, 0x8bf0}}, + {{0x2a72bb54, 0x0517dd0b, 0x220e1d4a, 0x27b03877, 0x25ba309c, 0x22c76f9f, 0x27a733b4, 0x2eabf8b8, 0x509c}}}, + /* 7*16^40*G: */ + {{{0x11ae9300, 0x114e8b07, 0x1c48280b, 0x0711c11d, 0x33735b5e, 0x0c2eb68b, 0x30fc6191, 0x0b72edf9, 0xe85e}}, + {{0x1546e25e, 0x0a837f74, 0x38c31bb7, 0x2df86177, 0x3c2707de, 0x29ed6e08, 0x0e0bfc7b, 0x2be9b547, 0x451a}}}, + /* 9*16^40*G: */ + {{{0x05260cb8, 0x14975558, 0x2b2152f2, 0x1bd2a033, 0x27dbf683, 0x009f686e, 0x12f82a3f, 0x2c3c8a32, 0x3f5f}}, + {{0x1852c964, 0x0bed2d10, 0x05ec3327, 0x0fa1d47f, 0x2783f2fa, 0x237854d9, 0x199870e3, 0x0d36b692, 0xc558}}}, + /* 11*16^40*G: */ + {{{0x1a1cd60f, 0x2a91110b, 0x03092ea4, 0x25a62a73, 0x1a002b9f, 0x3b41d2d3, 0x1999657a, 0x1588ac63, 0x3368}}, + {{0x0fd57d67, 0x2fdcdd94, 0x050b8b24, 0x3bd6932f, 0x27af175f, 0x1630037a, 0x07cd9ba8, 0x1427bc49, 0xd42f}}}, + /* 13*16^40*G: */ + {{{0x37576342, 0x014edbae, 0x199222af, 0x0b2220ce, 0x0979d95b, 0x03e76258, 0x00080f7d, 0x3ad7023c, 0x4813}}, + {{0x17376316, 0x130557ae, 0x06a904f6, 0x0b719f54, 0x33524aca, 0x005a1238, 0x24240f66, 0x0ff508ce, 0x0004}}}, + /* 15*16^40*G: */ + {{{0x3f69b2be, 0x3d9c5c77, 0x01111c09, 0x107dd3b7, 0x386e56ba, 0x08b6eeb8, 0x2997af13, 0x3c7e696b, 0x80c3}}, + {{0x0102d2f5, 0x2412e5f1, 0x0b7a8bf8, 0x12dd2cd7, 0x1d5a9bf1, 0x0389d96c, 0x1de85298, 0x08502802, 0x0a93}}} + }, + { + /* 1*16^41*G: */ + {{{0x2476c81d, 0x320dfd3f, 0x1e53d5e9, 0x28c0c3a6, 0x28a366b7, 0x1f349cf6, 0x01a019af, 0x2437f72d, 0xad60}}, + {{0x2e6705dd, 0x062af213, 0x33048df8, 0x0ff70d93, 0x1bd8a839, 0x35d70b31, 0x0c91eacc, 0x3477523d, 0x77b5}}}, + /* 3*16^41*G: */ + {{{0x22725490, 0x2891cdf3, 0x3cb59900, 0x30c90188, 0x09863c4a, 0x36a94cec, 0x1697ca2a, 0x116edc6b, 0xd90b}}, + {{0x2feb1299, 0x03e13e12, 0x3c466ccb, 0x3701effc, 0x38cbd80c, 0x22d5a1cd, 0x3350f09d, 0x24a3b06e, 0x3326}}}, + /* 5*16^41*G: */ + {{{0x3e933668, 0x1dace995, 0x06babf0a, 0x00b6133e, 0x1f06befb, 0x14e4ebe8, 0x13fc7ac0, 0x2485cc48, 0xac25}}, + {{0x32776fb5, 0x1b9dfd9c, 0x29e1e7a1, 0x21906271, 0x18ed7c6f, 0x3b04fbaf, 0x3a8ba850, 0x280e1c36, 0x6c79}}}, + /* 7*16^41*G: */ + {{{0x128de7e3, 0x2985f048, 0x3ea996d9, 0x210ab0ea, 0x3431bf86, 0x083ef69e, 0x1f3a8873, 0x0dd2ba5e, 0x7bc3}}, + {{0x2e6e5e29, 0x1e82ccba, 0x0c0ccf06, 0x3cb6ce6d, 0x0bacbd55, 0x31deb9b9, 0x14e5de00, 0x3c091821, 0xb431}}}, + /* 9*16^41*G: */ + {{{0x035e057d, 0x2b2c8c8e, 0x2d89a5b4, 0x33c436bd, 0x01119329, 0x321cbf0d, 0x202b268b, 0x052514eb, 0xbf9c}}, + {{0x2da20fea, 0x3d592ca0, 0x05c479b6, 0x02e78607, 0x07a54244, 0x14c4fc17, 0x23be0f38, 0x2e27c97c, 0x92ac}}}, + /* 11*16^41*G: */ + {{{0x021d6584, 0x0ab35f08, 0x3b3d9e5d, 0x1c175910, 0x1f014ef2, 0x25f68d6b, 0x04f8a96e, 0x020e6d5e, 0x55bf}}, + {{0x0ed744ea, 0x35593d0a, 0x2e5a5a80, 0x2785080a, 0x3c7dcf08, 0x32fdaea2, 0x21ccf27a, 0x01ccf92d, 0x3d98}}}, + /* 13*16^41*G: */ + {{{0x01068c5e, 0x35a77db9, 0x3e573d0d, 0x117b9b92, 0x15d4872a, 0x2b8539e0, 0x38d519f2, 0x138594cd, 0xfcf2}}, + {{0x27c19d75, 0x187d14fc, 0x014855b7, 0x05da92ca, 0x12e7aee9, 0x1d7886d6, 0x3ffe35c6, 0x2c394cdb, 0x186b}}}, + /* 15*16^41*G: */ + {{{0x220da860, 0x2df657c1, 0x049d1008, 0x0d146a92, 0x191f2f84, 0x36d94d0f, 0x167eca1f, 0x20340bd4, 0x7bc2}}, + {{0x07aac76d, 0x38a44104, 0x0c1632eb, 0x38668bf7, 0x1ee6e0f2, 0x09afe9c1, 0x131e5e26, 0x1b5deeef, 0xb33f}}} + }, + { + /* 1*16^42*G: */ + {{{0x13c4a205, 0x14bcb0da, 0x110a848a, 0x06b7e27d, 0x3929fcde, 0x1955c1d6, 0x1bbc4e46, 0x1b1458c1, 0xb6e0}}, + {{0x1db36d05, 0x0dfd3619, 0x02a9f875, 0x3e65066a, 0x1ed73b63, 0x07c49b9e, 0x323f5c5e, 0x09df086c, 0xbdb4}}}, + /* 3*16^42*G: */ + {{{0x39e27907, 0x0be087db, 0x0d9e4d69, 0x06b52ce2, 0x1fbd6877, 0x257575bf, 0x01c4e6b3, 0x390fe109, 0x0ed9}}, + {{0x2e78c4fb, 0x04fd3d41, 0x0ba1905f, 0x05473fae, 0x120e0ce9, 0x303f63ac, 0x32347f5b, 0x21d2bfda, 0xb5af}}}, + /* 5*16^42*G: */ + {{{0x35b38f54, 0x1b415c94, 0x0af07ce3, 0x0aa18397, 0x3ee1f92e, 0x09a36d23, 0x18f7dc55, 0x390401db, 0x57a7}}, + {{0x245f2809, 0x3e9e0798, 0x107eba75, 0x35db8e6a, 0x02dd21df, 0x32288ef2, 0x0ad24194, 0x03c0f23b, 0xfd7f}}}, + /* 7*16^42*G: */ + {{{0x27a79593, 0x1bfaefe6, 0x25c49794, 0x1e9c9274, 0x0a5cf334, 0x366c9633, 0x35dbef52, 0x26b8bcfb, 0x2479}}, + {{0x10920d55, 0x18e235d7, 0x3eb1398d, 0x250d87e6, 0x23e30099, 0x0f46a74d, 0x07b7b32c, 0x2d498bb2, 0x9436}}}, + /* 9*16^42*G: */ + {{{0x0bf5abdc, 0x0085bad4, 0x10b65066, 0x1b34ebef, 0x0d5d6045, 0x04472c20, 0x07026ed3, 0x05f1a213, 0xf150}}, + {{0x2def85b7, 0x1d778ae2, 0x3b85584b, 0x3719d709, 0x05e232cb, 0x20d078ff, 0x302a8ecd, 0x3bc70b17, 0xdea7}}}, + /* 11*16^42*G: */ + {{{0x3e78e9b1, 0x27c94ac7, 0x2c141e86, 0x1e39b713, 0x12dfcc89, 0x3e0c7dd4, 0x0beaa6e0, 0x3883e26d, 0xe196}}, + {{0x0a77eed7, 0x105d587f, 0x2ed35f44, 0x234044af, 0x32ed9a90, 0x1022f9da, 0x285a62a6, 0x1b617e06, 0xa5d6}}}, + /* 13*16^42*G: */ + {{{0x3b1cb64b, 0x1bb8cf95, 0x18ac3d57, 0x02794958, 0x39ed14d6, 0x1ff35c54, 0x30302f39, 0x3d779b06, 0x7779}}, + {{0x3aba3aab, 0x23863472, 0x0aa9533d, 0x2a0a508f, 0x22e3fae2, 0x2ac4d29e, 0x03ebeadf, 0x108fd1d3, 0x09a8}}}, + /* 15*16^42*G: */ + {{{0x11d1b492, 0x3b6161da, 0x019a6f53, 0x28186308, 0x328ce8df, 0x3db66aba, 0x3a2f11e5, 0x2e52f908, 0x8605}}, + {{0x38ac6598, 0x1c75defd, 0x01e925c5, 0x08d49b52, 0x03d1a8ee, 0x3db83085, 0x35758f3e, 0x184a1f79, 0xa8e5}}} + }, + { + /* 1*16^43*G: */ + {{{0x29aa52df, 0x3357d392, 0x02a627f3, 0x3114ac6d, 0x11ece618, 0x31062766, 0x08bf76db, 0x04725fd8, 0x45a5}}, + {{0x125ec16c, 0x2d4af448, 0x22955ce7, 0x2466c9f4, 0x225ad25a, 0x0ccdff2d, 0x29b6d3fe, 0x03b1dcfa, 0x73be}}}, + /* 3*16^43*G: */ + {{{0x2e75bc7f, 0x159d4fbe, 0x2f7fb1f6, 0x31c5c36d, 0x0d4c7b95, 0x103c485f, 0x393438ef, 0x2b13f9ca, 0x0b57}}, + {{0x0972e9a9, 0x13c5cb74, 0x049fc620, 0x3e5b0390, 0x3e94fab1, 0x30d33e95, 0x1f3b5f28, 0x2fe09dea, 0xceed}}}, + /* 5*16^43*G: */ + {{{0x033125ff, 0x0dd0cf3e, 0x25a81421, 0x1155ec16, 0x1cae9935, 0x1a0b6728, 0x3d148cf4, 0x2cfedb92, 0x1178}}, + {{0x18486abd, 0x203e5c27, 0x0e54d1be, 0x322b7342, 0x310ed10d, 0x3798dfa8, 0x3d95b382, 0x25faa6ea, 0xdfd6}}}, + /* 7*16^43*G: */ + {{{0x3662d955, 0x2cda5733, 0x08ce44f3, 0x1135a16d, 0x27569384, 0x20edfa34, 0x0e907f8a, 0x28209be5, 0x8ac7}}, + {{0x246b3dae, 0x31a8b6f9, 0x16c138db, 0x3d20716f, 0x359ad9e3, 0x1f948d32, 0x3231cc9d, 0x102483cc, 0xc80f}}}, + /* 9*16^43*G: */ + {{{0x288803e5, 0x3361e6b7, 0x13465cb7, 0x06adf383, 0x169e02cc, 0x1fea1c01, 0x1f2111ab, 0x22ca1677, 0xc0f4}}, + {{0x076619ee, 0x1a4c880a, 0x3828edba, 0x0b9381c2, 0x20d7d393, 0x2991c9f9, 0x3ca369c9, 0x09adbe20, 0x3d43}}}, + /* 11*16^43*G: */ + {{{0x1e1f515c, 0x25b59c26, 0x16539afa, 0x2d228c88, 0x37b8c0e2, 0x2723843f, 0x1766da01, 0x1c03c0d4, 0x2ce8}}, + {{0x052eed6e, 0x1464d926, 0x2c3d52c9, 0x2a7734f8, 0x2f5d2ca7, 0x2cbd0bdf, 0x2c4a7bac, 0x27d3ced7, 0x7387}}}, + /* 13*16^43*G: */ + {{{0x24dcf274, 0x16a8ddd7, 0x0acea244, 0x1c801a0b, 0x3cca1d80, 0x386ec3f5, 0x3c109145, 0x1098772d, 0xfac4}}, + {{0x312f0472, 0x0da61803, 0x34594b16, 0x0809f189, 0x2e97bd73, 0x1c8f5753, 0x2a8a87cc, 0x3f718559, 0x9713}}}, + /* 15*16^43*G: */ + {{{0x3dc39d21, 0x2d792daa, 0x09adc682, 0x0dcfaf50, 0x19281368, 0x24790e86, 0x03e00465, 0x398596d0, 0xf891}}, + {{0x05ca579f, 0x1642385f, 0x1460254d, 0x2a5fb13d, 0x1bc43b73, 0x3ae2a38b, 0x1fced18a, 0x14ec4aef, 0x129f}}} + }, + { + /* 1*16^44*G: */ + {{{0x1076f57b, 0x233c6ae6, 0x2cac6072, 0x02e1b8f3, 0x32a53f03, 0x1f8d4073, 0x0c79cb92, 0x06159220, 0x20e1}}, + {{0x2da7afe6, 0x160efb6e, 0x0e1b71e8, 0x383726d0, 0x2de9979f, 0x370f8fed, 0x37ef731b, 0x2cd4ab10, 0xff67}}}, + /* 3*16^44*G: */ + {{{0x0b661da4, 0x1278ebb5, 0x0a84a5c8, 0x02946b19, 0x061a2194, 0x31ff640c, 0x206ce8f7, 0x0a96ee19, 0xffca}}, + {{0x2f9b8a5a, 0x26120d7a, 0x1687f6f8, 0x23e1eb79, 0x346c8c47, 0x33268523, 0x1cdc8a53, 0x2c38cadc, 0xce1c}}}, + /* 5*16^44*G: */ + {{{0x1c8cfd22, 0x32b0784e, 0x236be583, 0x0ac19c6d, 0x2d354a4e, 0x14d45436, 0x116ab636, 0x273b7ff0, 0xff20}}, + {{0x13bc5535, 0x0e26c53a, 0x1684b942, 0x13d2e4b2, 0x0ff1c80d, 0x35074933, 0x10f7e207, 0x3ce5d1a7, 0xad79}}}, + /* 7*16^44*G: */ + {{{0x0f4e983e, 0x201f9616, 0x017f77ce, 0x279bb21c, 0x3b4b156d, 0x0102034c, 0x39ba9586, 0x3c0b42c1, 0x33d5}}, + {{0x11ea37a9, 0x35c36e1e, 0x1630c956, 0x1c6aa496, 0x3ba1eb7a, 0x0f585956, 0x0478473c, 0x169db4e7, 0x01eb}}}, + /* 9*16^44*G: */ + {{{0x21e52a73, 0x1a569e7d, 0x305a1bcb, 0x38c45b25, 0x3b5e65d0, 0x25d366b6, 0x21690a9e, 0x348f6989, 0x8f1b}}, + {{0x2bea8f2e, 0x1f685147, 0x31850a85, 0x0140b992, 0x03eade59, 0x1a790c1d, 0x1a8b8b87, 0x23d8e4eb, 0x4c7a}}}, + /* 11*16^44*G: */ + {{{0x3d2bc078, 0x210bfb0b, 0x1f3ef5a5, 0x281d814a, 0x1880aec4, 0x0a62df6b, 0x237f3ee6, 0x327fbded, 0x963b}}, + {{0x1afb8657, 0x376c8c7d, 0x043a3c27, 0x3b010a3d, 0x00a4f1c5, 0x0f9424a6, 0x2762280a, 0x0e0ff347, 0x7ed3}}}, + /* 13*16^44*G: */ + {{{0x2fb608ad, 0x21c79dba, 0x08fd93a6, 0x20159536, 0x08bc4974, 0x06b772df, 0x1a844e63, 0x1b6b6187, 0x89fe}}, + {{0x064d4dad, 0x00501b9e, 0x0f0a87b6, 0x2a7544f8, 0x25df39ae, 0x15f7fedc, 0x0e8fc87b, 0x09e08c7d, 0x2898}}}, + /* 15*16^44*G: */ + {{{0x19ae4a29, 0x1c62606c, 0x2232a0b0, 0x0bf69ba8, 0x166984df, 0x35eb1384, 0x39759510, 0x011fcef5, 0xc348}}, + {{0x0eb09235, 0x12566b13, 0x149aebf3, 0x08ba67c1, 0x0dae9a84, 0x2a374838, 0x21c5613d, 0x207c815a, 0x5847}}} + }, + { + /* 1*16^45*G: */ + {{{0x19273a8f, 0x34514ba2, 0x14fd54ad, 0x3751e39a, 0x17dac93f, 0x23b1ff7f, 0x2027b031, 0x313e1c8e, 0x5c9c}}, + {{0x1ce80d6e, 0x376b29a5, 0x11acab5a, 0x000d9d68, 0x08af964f, 0x1d6274dc, 0x2d259a82, 0x381e877f, 0x84ef}}}, + /* 3*16^45*G: */ + {{{0x0883e382, 0x32326151, 0x15536f38, 0x1813f3bd, 0x007431d0, 0x0900e548, 0x3d85c5be, 0x3864aef7, 0x5ac8}}, + {{0x1dfeaadc, 0x04dcf66f, 0x14d9d2e5, 0x1dbb284f, 0x163976de, 0x23ffcbc2, 0x28c8039c, 0x3940131e, 0xfcb7}}}, + /* 5*16^45*G: */ + {{{0x2f01a3e8, 0x3290c1df, 0x248094eb, 0x3ad950cb, 0x167362c6, 0x05751383, 0x121182d5, 0x01a62de4, 0x99dc}}, + {{0x00f61114, 0x0a1917f9, 0x3f8f2945, 0x299c0d35, 0x180044b7, 0x2b1c45c7, 0x182bc697, 0x273748ee, 0x67c6}}}, + /* 7*16^45*G: */ + {{{0x0cd535ab, 0x20fdec01, 0x0764dc33, 0x093620fa, 0x0fb9f377, 0x090d5f3f, 0x00616440, 0x3cd86381, 0xabe2}}, + {{0x117b9c1a, 0x01c46cd1, 0x3ac8dd99, 0x379e8630, 0x2df7957f, 0x36fcac80, 0x1b293de0, 0x35932dd5, 0x4f02}}}, + /* 9*16^45*G: */ + {{{0x2909970c, 0x2d2d9acd, 0x1e6e4e0d, 0x0636e966, 0x26099e45, 0x1bec7ddf, 0x1e72137c, 0x3435e30e, 0x227c}}, + {{0x1f809727, 0x21692b8c, 0x2b99ec42, 0x043b0fdf, 0x3f5defa2, 0x1b21d073, 0x1391d87d, 0x39dc7206, 0x2225}}}, + /* 11*16^45*G: */ + {{{0x09e65b59, 0x366b7f26, 0x144ff77c, 0x10408bdf, 0x0d053b7a, 0x3ba4c2a3, 0x1c5b6827, 0x11a082bb, 0x3631}}, + {{0x29b4c2cf, 0x20285909, 0x1c5b6e9c, 0x10f240ed, 0x227fc1c1, 0x09e3e480, 0x172928e8, 0x36d885e2, 0x1d87}}}, + /* 13*16^45*G: */ + {{{0x0d4c2506, 0x05ec562f, 0x19e9faf0, 0x1b1771fc, 0x1d1fec5b, 0x29a33862, 0x318a3e74, 0x35ad9a1a, 0xf65e}}, + {{0x3913dfac, 0x314b7094, 0x0d6542bc, 0x0a3bf0d3, 0x36e7bd41, 0x1770bf4d, 0x3aae8525, 0x2f1a0ca2, 0xd6d0}}}, + /* 15*16^45*G: */ + {{{0x3b47a80b, 0x0793e5d4, 0x02497578, 0x25f16999, 0x2bdba8ff, 0x36709dbe, 0x2135729d, 0x37be847d, 0x66a0}}, + {{0x3f795e8b, 0x3dc657e3, 0x26edd200, 0x0c290a14, 0x2ef474c2, 0x237c9586, 0x2ca41cad, 0x2a9b78de, 0x3e24}}} + }, + { + /* 1*16^46*G: */ + {{{0x28523eb3, 0x1f766acc, 0x16c6c4ae, 0x068e9d55, 0x3dcde335, 0x3061113c, 0x0b5ab46a, 0x353afe2a, 0xbaff}}, + {{0x15acf387, 0x25e0c033, 0x348b6ee1, 0x144733ef, 0x1ac09c24, 0x2a3acde5, 0x15e83003, 0x0f7176f2, 0x0fa9}}}, + /* 3*16^46*G: */ + {{{0x34737641, 0x00266d3b, 0x2c2e13ad, 0x3eb03059, 0x163fb71a, 0x22d448d9, 0x089ed777, 0x11489107, 0x91b4}}, + {{0x2101bbe0, 0x0944aca7, 0x2077d03f, 0x35f7199b, 0x2fb428c9, 0x0c8d6ac0, 0x1a9762c1, 0x18ef4dff, 0x3f44}}}, + /* 5*16^46*G: */ + {{{0x26dd01df, 0x1a8aeae0, 0x38fefb9c, 0x0fbfdd94, 0x28916574, 0x3a9b1f21, 0x1b07aa37, 0x04d77a0b, 0x296d}}, + {{0x2a3a0dc8, 0x25434c82, 0x1e66f604, 0x3ebd8639, 0x0777cadf, 0x1c4a5ddb, 0x145e42b8, 0x13b764b8, 0x1405}}}, + /* 7*16^46*G: */ + {{{0x1650f5dd, 0x19f9bc1b, 0x191b2c8c, 0x3ff84908, 0x1e4a9654, 0x0f0bc7c6, 0x27a318f1, 0x10bce44d, 0x4b09}}, + {{0x3aeddc6d, 0x0ba96f31, 0x0e73a62c, 0x0f19e0b9, 0x13c25f02, 0x17040558, 0x0abc0e05, 0x2aa98d9b, 0x7432}}}, + /* 9*16^46*G: */ + {{{0x04e4a96f, 0x28dd7a3c, 0x1655b147, 0x2218ad0d, 0x12e4af18, 0x3b6e3f13, 0x0c11a833, 0x1de98bfb, 0x0363}}, + {{0x11e08cdb, 0x2ebedf81, 0x30913268, 0x02630850, 0x14626384, 0x0c3155e1, 0x3df838d9, 0x06474d53, 0xa1de}}}, + /* 11*16^46*G: */ + {{{0x279b5a59, 0x107f4f85, 0x269e62a1, 0x087a27ac, 0x183251c6, 0x2fb55c27, 0x1e162bcb, 0x06bdcc3d, 0xa104}}, + {{0x2c5514a3, 0x234ad008, 0x2ac66d9d, 0x0c1a4387, 0x3c2afbfb, 0x194361ce, 0x18b19422, 0x05daaa3d, 0xad42}}}, + /* 13*16^46*G: */ + {{{0x0ddd597b, 0x2ba36c1b, 0x085758de, 0x224c5c33, 0x292007d8, 0x1c6b43e7, 0x25647033, 0x19eb42c7, 0xda21}}, + {{0x3de7fa04, 0x1a05c9f8, 0x04f9f462, 0x378a9485, 0x18ebf6cd, 0x19c03a9e, 0x2ed361ff, 0x24ad8951, 0xa219}}}, + /* 15*16^46*G: */ + {{{0x33f7dbb0, 0x24d2888a, 0x2bf29c09, 0x3b88f709, 0x24f29df4, 0x18ee1c85, 0x2c678bc8, 0x36f08dfd, 0x1c3f}}, + {{0x32e16d32, 0x1932f725, 0x020f8add, 0x01918e00, 0x0b18d41f, 0x3a94e529, 0x29813f0a, 0x03c40de4, 0x3926}}} + }, + { + /* 1*16^47*G: */ + {{{0x3a111101, 0x0d482362, 0x2db3c5f8, 0x27c2c69d, 0x3e4c9647, 0x0a8d3495, 0x2d766ed2, 0x0a8263f3, 0x06ad}}, + {{0x1fb37ef4, 0x069eea75, 0x30e89aec, 0x10a760ad, 0x2b62a0de, 0x13006ee7, 0x05e3559a, 0x22c7163e, 0x2d5b}}}, + /* 3*16^47*G: */ + {{{0x302bef6f, 0x1bf0e11d, 0x131ee437, 0x2b93c611, 0x18d475bb, 0x1e2f59af, 0x3cd7204f, 0x32955b0e, 0xf1a2}}, + {{0x0f6c1ca3, 0x06cb47f6, 0x3d52b401, 0x2d1faa07, 0x020168b0, 0x15505f70, 0x0313edf4, 0x166bc122, 0xb39b}}}, + /* 5*16^47*G: */ + {{{0x20455367, 0x0180a3f2, 0x0d613e08, 0x313cb209, 0x3f1851e6, 0x2405963a, 0x38030ee1, 0x2b527f8e, 0xe924}}, + {{0x28257e92, 0x3f4633e0, 0x3a6752b5, 0x368c6a93, 0x2fbb6f52, 0x0214e4f5, 0x03ed5752, 0x1f65e685, 0xfcc9}}}, + /* 7*16^47*G: */ + {{{0x02f8f1e7, 0x247c24e5, 0x1d1f9e2e, 0x352a9753, 0x3b22f68d, 0x2e4d4417, 0x3026fa00, 0x271f717d, 0xf49d}}, + {{0x114d9972, 0x088a2ac6, 0x24d7a839, 0x2c004f13, 0x14f67901, 0x174ecee6, 0x3acae6ae, 0x175080f8, 0xf558}}}, + /* 9*16^47*G: */ + {{{0x3b219a79, 0x2cea59df, 0x29827a77, 0x1335105f, 0x1189e65c, 0x0f0d55d5, 0x29d48b0e, 0x1340f91a, 0x28b0}}, + {{0x102dbe24, 0x22fdf364, 0x2004be5f, 0x059b33e1, 0x3e206b86, 0x3f95c860, 0x0cf1459c, 0x36a79685, 0xf658}}}, + /* 11*16^47*G: */ + {{{0x17774af9, 0x0a08b671, 0x1460ad8b, 0x05ae9944, 0x2aefb54c, 0x140e4a21, 0x1fe93d68, 0x19af9f30, 0x3f47}}, + {{0x1d4de990, 0x1f35fd93, 0x1b7326ff, 0x2a533f7e, 0x2e5f511c, 0x05e241b9, 0x31cba3ab, 0x0375a9cc, 0xcc81}}}, + /* 13*16^47*G: */ + {{{0x08e57705, 0x21067c79, 0x04d598e7, 0x33adfeb2, 0x2f361721, 0x2b6ad075, 0x0ee791f2, 0x2780b03e, 0xe324}}, + {{0x38caec0c, 0x252c67a0, 0x27384220, 0x065175c5, 0x086b5a50, 0x1de307c9, 0x29507dcb, 0x1961c04d, 0xa666}}}, + /* 15*16^47*G: */ + {{{0x325b93ac, 0x1e2f3abe, 0x187f8d2c, 0x38809441, 0x3bb4e917, 0x279da4f7, 0x3961cbdf, 0x1602f7ed, 0xa689}}, + {{0x2f589aab, 0x28f47135, 0x1c4fd3ae, 0x3c7e05f6, 0x059ff2fc, 0x3cbc057c, 0x0783eaa7, 0x32a52d3c, 0x4657}}} + }, + { + /* 1*16^48*G: */ + {{{0x313728be, 0x33c83fec, 0x3c6b94a6, 0x10e56468, 0x315fc596, 0x1bfe0d10, 0x09276273, 0x259de9e1, 0xa6d3}}, + {{0x0357f5f4, 0x0aeae0cf, 0x284059bf, 0x12a48308, 0x27ecdf82, 0x22eaf4b4, 0x3881666b, 0x211d26c2, 0x674f}}}, + /* 3*16^48*G: */ + {{{0x0f15d864, 0x0152d5a7, 0x1cc8d3cc, 0x01bf71a8, 0x26cf3524, 0x23b39ef8, 0x2db0dafc, 0x19b5f177, 0x07ef}}, + {{0x340907fe, 0x1189509d, 0x0ce4a8b5, 0x11c38ec7, 0x3d505e9f, 0x10314887, 0x1e6a506d, 0x0c976e27, 0x2db3}}}, + /* 5*16^48*G: */ + {{{0x17c7c05e, 0x1a5450f0, 0x0e5416ac, 0x20f2e54b, 0x328c0bb2, 0x0e9cbdd7, 0x1c46014f, 0x1397f01b, 0x82df}}, + {{0x18fff26b, 0x2584f40b, 0x02db300b, 0x057651a1, 0x17cbd1cf, 0x08588448, 0x2420a275, 0x22326325, 0xe4e1}}}, + /* 7*16^48*G: */ + {{{0x140368b0, 0x02b87505, 0x3ee949d8, 0x09308be3, 0x247a6213, 0x396e34e3, 0x30c6a7d9, 0x3f26f04a, 0x261e}}, + {{0x3deb011f, 0x0eb49566, 0x39b5d301, 0x0d02f878, 0x0fff797e, 0x2214b359, 0x2fce9fdc, 0x0ab6f8e1, 0x8a9d}}}, + /* 9*16^48*G: */ + {{{0x15eb8034, 0x040cfa54, 0x2e8ca4af, 0x02ccd7d5, 0x27692df3, 0x29f96767, 0x0279149a, 0x37f5de8b, 0x6d48}}, + {{0x1ab0ce30, 0x21cc21e9, 0x23e8961e, 0x00843a8a, 0x05476308, 0x39e59278, 0x1d12f3d5, 0x1c914597, 0x3cb4}}}, + /* 11*16^48*G: */ + {{{0x140535c8, 0x1450f7f1, 0x08db13eb, 0x3c2958c3, 0x054e6f65, 0x048fed3f, 0x18923a49, 0x30079eee, 0x93a5}}, + {{0x3d59b844, 0x1255d020, 0x35bedffc, 0x28588124, 0x15a5c166, 0x2a10d638, 0x0c2f4c16, 0x03a41260, 0x2d44}}}, + /* 13*16^48*G: */ + {{{0x1e2047ba, 0x0986959a, 0x3b0f652a, 0x11c1265a, 0x167031e5, 0x3683805f, 0x272bbb35, 0x2e4a4584, 0x3fb0}}, + {{0x1db24158, 0x1ffb353b, 0x17009d35, 0x1082b9dc, 0x266dc86c, 0x09887265, 0x3df94ca7, 0x1eb9a085, 0x9d46}}}, + /* 15*16^48*G: */ + {{{0x22df71c1, 0x02f6f6eb, 0x3bb723a0, 0x0c61afab, 0x33e4381c, 0x18eea778, 0x283d5d07, 0x250e7823, 0xdab0}}, + {{0x24c3a1e3, 0x21cd2104, 0x0b44e3bb, 0x258cc329, 0x120b3d6e, 0x2ba1bc83, 0x21cef385, 0x2f079513, 0x763c}}} + }, + { + /* 1*16^49*G: */ + {{{0x0514c6fd, 0x3bbd8bfd, 0x1ab013e6, 0x1a0ed343, 0x3f5936fd, 0x136d5c43, 0x0f4e033d, 0x36a00227, 0xac25}}, + {{0x05830541, 0x02d4e5dc, 0x03bf37a6, 0x0260fa09, 0x1b338c81, 0x36a4c4a8, 0x04c7b883, 0x2766172d, 0xebc6}}}, + /* 3*16^49*G: */ + {{{0x32fd0e3d, 0x065071f8, 0x027ad608, 0x0c793715, 0x165547e6, 0x1d219c78, 0x23c8bb4d, 0x399b126e, 0xeea7}}, + {{0x191d5868, 0x01047da3, 0x019e3cc1, 0x32eb688c, 0x1b7d985a, 0x10fc9efa, 0x09261288, 0x3516e7e2, 0x83fe}}}, + /* 5*16^49*G: */ + {{{0x2ccb63b3, 0x067c53c9, 0x0408e5d1, 0x37ff9b11, 0x03c67b7d, 0x0652cd50, 0x221bdbad, 0x38b4fa4f, 0x9a3d}}, + {{0x3df93fcf, 0x0714ca5d, 0x35822600, 0x300767fb, 0x013c4c49, 0x3c9cdbba, 0x112c8809, 0x26e41844, 0x2f80}}}, + /* 7*16^49*G: */ + {{{0x163f1117, 0x13b28d37, 0x27f6d8be, 0x225bdc2e, 0x3fadaf34, 0x0034c048, 0x392db051, 0x20bd2d4e, 0xa7c3}}, + {{0x1934cb9a, 0x04883178, 0x3c4a68cc, 0x13addbb4, 0x1dcfb5ae, 0x27ddddc1, 0x1bf88045, 0x394459d8, 0x1b91}}}, + /* 9*16^49*G: */ + {{{0x26774a96, 0x02f20716, 0x038e3e85, 0x08c7f646, 0x26f497e8, 0x10eff20e, 0x21213871, 0x2a663361, 0x555a}}, + {{0x06db0e34, 0x35025cb6, 0x0e26fa69, 0x035752f2, 0x10bbb89a, 0x11079c4d, 0x3bc6999d, 0x0a1a3481, 0xb053}}}, + /* 11*16^49*G: */ + {{{0x2f7dac7d, 0x0bdfbbce, 0x12412123, 0x15cae484, 0x37c36916, 0x335e3e35, 0x27ad7b58, 0x0bd6cd22, 0x01a4}}, + {{0x0195e46e, 0x1e2528c6, 0x0cea96b2, 0x0abca4ca, 0x3f921617, 0x1fe552e2, 0x07781349, 0x270e1548, 0x957a}}}, + /* 13*16^49*G: */ + {{{0x202afc36, 0x00ae8750, 0x03071d3e, 0x137bb545, 0x05d3a313, 0x2c27bc6d, 0x1ce3d3a5, 0x3d4dfac1, 0x4b47}}, + {{0x2f8133ff, 0x3a27dda9, 0x25fbda34, 0x16b2fa6c, 0x0df57334, 0x2c1be83a, 0x05f0c2dc, 0x1140e672, 0xf2fc}}}, + /* 15*16^49*G: */ + {{{0x37d17f68, 0x2afcb8f1, 0x38bad86a, 0x056877f2, 0x2e418f79, 0x145bd4da, 0x0e8ced56, 0x3b273149, 0x6b3d}}, + {{0x09232402, 0x3eb9e883, 0x2dccb68c, 0x3caa5aa9, 0x0d5d4747, 0x2606d05b, 0x3d9ef050, 0x0e4dff7b, 0xb865}}} + }, + { + /* 1*16^50*G: */ + {{{0x2fd20bae, 0x17538de8, 0x1b4a8115, 0x00d59cb5, 0x2d343a26, 0x2ee8485d, 0x0fcd9027, 0x143b70ef, 0x2852}}, + {{0x14e0ab97, 0x27791569, 0x1eff323f, 0x26c68b3c, 0x06c1716e, 0x0a12b441, 0x17ea83f7, 0x3021bd2b, 0x7866}}}, + /* 3*16^50*G: */ + {{{0x2636a50b, 0x3221daae, 0x3b75196c, 0x0bbd85aa, 0x38baf65d, 0x1be84bf1, 0x1a75c583, 0x31595175, 0xf1e3}}, + {{0x2b3128b6, 0x3dde453a, 0x22d7a6ed, 0x1fe95db4, 0x25f3136b, 0x0da99fda, 0x2fce76c7, 0x211e9b87, 0x12b8}}}, + /* 5*16^50*G: */ + {{{0x0e583340, 0x05fc4c85, 0x134f3b25, 0x1706dad7, 0x1b228cf4, 0x1f36afea, 0x134a76d8, 0x1ca72078, 0x584d}}, + {{0x34fb24b9, 0x0bdb97a5, 0x094c0707, 0x05dc2999, 0x30affa8f, 0x01f164c0, 0x180abcd3, 0x20291583, 0x2fdd}}}, + /* 7*16^50*G: */ + {{{0x0235809b, 0x0b20fb78, 0x1eb81739, 0x15cb7c2d, 0x383c453c, 0x380a3708, 0x3df7d1e2, 0x2b80320d, 0xbaae}}, + {{0x0154fd62, 0x35876297, 0x1d2e7e5c, 0x170f10a8, 0x09f29983, 0x08c1ef2d, 0x24b80b4a, 0x2220cfcc, 0x3257}}}, + /* 9*16^50*G: */ + {{{0x0d612268, 0x18010b10, 0x25ed016f, 0x33d677c2, 0x14b8b906, 0x0e7be90e, 0x2131a651, 0x3918d830, 0x06c7}}, + {{0x260166a0, 0x32d2d804, 0x02e7098b, 0x2362969e, 0x3453ca23, 0x3f1d738b, 0x1d8cd747, 0x35577dcb, 0xcb6a}}}, + /* 11*16^50*G: */ + {{{0x012fbdc8, 0x350e8d6e, 0x2c0e2a3b, 0x278832a8, 0x11a36db8, 0x0bb31edc, 0x2643e5bc, 0x0c77aaf5, 0x0641}}, + {{0x29f99380, 0x34ffcc26, 0x1fb020a5, 0x0eb89a2c, 0x15759860, 0x0e0364d2, 0x27028f2b, 0x1feb0cb5, 0x882c}}}, + /* 13*16^50*G: */ + {{{0x0bac9f32, 0x17ac0019, 0x1689b067, 0x0e087316, 0x1b640044, 0x1905bf86, 0x1c2378a1, 0x2deb309d, 0x366b}}, + {{0x3c85d47d, 0x0bc3973e, 0x3f0268a4, 0x37394301, 0x21cfc01f, 0x1e0eae35, 0x1af064f0, 0x1edc21e1, 0x7d10}}}, + /* 15*16^50*G: */ + {{{0x06dd27eb, 0x0f2d494a, 0x33b56230, 0x231570de, 0x3e32ecb9, 0x1f438e6e, 0x33c006b2, 0x36c95f31, 0xb767}}, + {{0x0f65dac4, 0x1548691f, 0x0600ed41, 0x2dc02d12, 0x19d85b64, 0x2b2e05ae, 0x229cb5ce, 0x0230c984, 0xdc13}}} + }, + { + /* 1*16^51*G: */ + {{{0x3e07e4f1, 0x1c7ce8a8, 0x0dc267c1, 0x31451f74, 0x38890e1f, 0x37af01fb, 0x0366f818, 0x30418bb4, 0xc472}}, + {{0x06b0daa9, 0x1c71a0f6, 0x22b5d8a5, 0x3cedec78, 0x1667d885, 0x0aad6a13, 0x370e9643, 0x03806517, 0x4182}}}, + /* 3*16^51*G: */ + {{{0x22f8acb1, 0x0da54d2a, 0x13f053f4, 0x27595518, 0x2cc31eb3, 0x06de92e3, 0x1e3d685e, 0x23ce6551, 0x86f8}}, + {{0x05098a19, 0x12c10b44, 0x11652711, 0x3a98afba, 0x11b1214e, 0x325e3ed6, 0x238d6b37, 0x375a69a0, 0x2ccf}}}, + /* 5*16^51*G: */ + {{{0x3cadab66, 0x220ddedb, 0x1d35602d, 0x31a8cf0f, 0x19f9a0e1, 0x1d9a5983, 0x08e747df, 0x2f87f265, 0xa2a3}}, + {{0x0c1aeb12, 0x3d284921, 0x080ad25e, 0x0b7a294d, 0x235ee1fb, 0x01fb5d34, 0x0be67065, 0x3639ad49, 0xa93b}}}, + /* 7*16^51*G: */ + {{{0x207c25bf, 0x2274884c, 0x22d8097b, 0x3ef1ddef, 0x0080be82, 0x384919df, 0x38db9367, 0x1f3b55b9, 0x354e}}, + {{0x1a864211, 0x048e8e65, 0x1a0aa215, 0x35d5b2c1, 0x0fe5585f, 0x2f609297, 0x14070e6e, 0x18ba6ee6, 0x629d}}}, + /* 9*16^51*G: */ + {{{0x35e1dad8, 0x29f60b81, 0x2c4bd2e4, 0x2029e161, 0x099f498b, 0x173dc830, 0x2805b79b, 0x326abd77, 0xc751}}, + {{0x2e4afc8b, 0x04dacd84, 0x20a8c02d, 0x3e25c28e, 0x09a4ffe6, 0x1307f5b7, 0x19de2beb, 0x190dff1e, 0xcb98}}}, + /* 11*16^51*G: */ + {{{0x099d9ba2, 0x0c486c84, 0x3aaa757d, 0x3d95f5a5, 0x0f9ca80c, 0x2d4a1ad4, 0x1d02178a, 0x33106e74, 0xaee9}}, + {{0x3ed2ad58, 0x2358120e, 0x217490e7, 0x0b9a389a, 0x06b1f531, 0x25efec03, 0x2a36f7be, 0x3cc0b6d4, 0xb72c}}}, + /* 13*16^51*G: */ + {{{0x094d208d, 0x0ffc2092, 0x3f391a46, 0x036a3fc3, 0x1ff0cefb, 0x3d82bcac, 0x12ec56bf, 0x0fd1a9e4, 0x0d0d}}, + {{0x1d45d1b1, 0x18bd4fde, 0x31ddabfd, 0x04f03469, 0x109ff0b2, 0x1d36997e, 0x37169b04, 0x06e02b87, 0xdc37}}}, + /* 15*16^51*G: */ + {{{0x19cfd890, 0x1ba08b20, 0x0071145c, 0x0db0dcdf, 0x1441e1cb, 0x3360e1f9, 0x37535f47, 0x051ad104, 0x778d}}, + {{0x16f057f2, 0x26a1fe9f, 0x2d20acac, 0x32915223, 0x06cd3796, 0x09c6365e, 0x11af72a5, 0x2e84cec0, 0x3c85}}} + }, + { + /* 1*16^52*G: */ + {{{0x039bb85f, 0x083c270e, 0x050e62c3, 0x007ec1a8, 0x15345801, 0x160b266b, 0x2432b557, 0x0e634599, 0x55d5}}, + {{0x0fed936f, 0x1fd8c461, 0x033d9e1f, 0x035a9fc6, 0x3aa72ad9, 0x31aa7a3a, 0x38e2d059, 0x08a4127f, 0x576e}}}, + /* 3*16^52*G: */ + {{{0x12ea285a, 0x01f8ae48, 0x3b910d1c, 0x007079bd, 0x00a7a39f, 0x20163777, 0x3888b785, 0x19022053, 0x1bb4}}, + {{0x107dc702, 0x303229e6, 0x12fa94ed, 0x14a8d2e6, 0x34a4fc1e, 0x3f66e24a, 0x21125a40, 0x05afebeb, 0x8a30}}}, + /* 5*16^52*G: */ + {{{0x1539785a, 0x1404a403, 0x0297f014, 0x22341dae, 0x227a548c, 0x1cf899e1, 0x3a14ee09, 0x139c380b, 0x04bc}}, + {{0x0a62e3bb, 0x0e6411d7, 0x23275c35, 0x1c05dc9e, 0x3dfb4f87, 0x16873cfc, 0x34cc3a5f, 0x3c892e32, 0x5729}}}, + /* 7*16^52*G: */ + {{{0x2114cfb5, 0x04b52ec7, 0x3d5a6a31, 0x0d8626a8, 0x1f0876d1, 0x1ce786df, 0x08173587, 0x24bf707e, 0xd3e4}}, + {{0x297f7045, 0x33ae6a95, 0x2754eefb, 0x223c1b91, 0x15fea39c, 0x3899dafc, 0x0c48b1fe, 0x29c29cfe, 0x3604}}}, + /* 9*16^52*G: */ + {{{0x2c55ddff, 0x2899d2ee, 0x0d4b7871, 0x2b46cfd9, 0x0dc1791d, 0x3948c43f, 0x042538a4, 0x3095618a, 0xbebf}}, + {{0x3ea2f303, 0x3536c328, 0x10baa706, 0x32a08b59, 0x36576c3c, 0x284712dd, 0x204ce8a3, 0x38997025, 0x850d}}}, + /* 11*16^52*G: */ + {{{0x099ead51, 0x06bd0793, 0x1d9224e9, 0x28d50e88, 0x0784715d, 0x0a4c7458, 0x20d602fb, 0x21371cf4, 0x36e9}}, + {{0x2e0e5e3e, 0x1bee7509, 0x04280afc, 0x2aefb05c, 0x232b203b, 0x2f7f26b3, 0x3485f4bf, 0x1c51c86f, 0x1437}}}, + /* 13*16^52*G: */ + {{{0x23093df0, 0x2a2ddeec, 0x376464d7, 0x17892059, 0x1793af78, 0x1451e553, 0x204aef31, 0x1d4010fd, 0x91b6}}, + {{0x12cc9f14, 0x337a30df, 0x1caf67f5, 0x0da17e3e, 0x221c5d93, 0x31eb6a5b, 0x0a00d477, 0x36c79609, 0x07fe}}}, + /* 15*16^52*G: */ + {{{0x3b7b8dc4, 0x08d9ee1b, 0x29b3848a, 0x0d24c0a2, 0x202fac5b, 0x25f8680d, 0x0883e7c4, 0x30f1e871, 0xc5d9}}, + {{0x1b2df0ea, 0x35925e34, 0x1fd4936e, 0x363dcbf4, 0x050af3d0, 0x230e1817, 0x1b79e580, 0x2e78973f, 0x3e59}}} + }, + { + /* 1*16^53*G: */ + {{{0x32513926, 0x18b6f270, 0x3ec85ecc, 0x09a2503b, 0x3c3383cc, 0x3aeac92f, 0x0872694f, 0x21918f28, 0x8842}}, + {{0x2fb8a54d, 0x3b90a0aa, 0x3dbc15a0, 0x03ac48ba, 0x181207ce, 0x1836cd97, 0x2dd5a696, 0x10a70070, 0xf778}}}, + /* 3*16^53*G: */ + {{{0x2520f1f1, 0x34aeb065, 0x07f7da4e, 0x3c6d2799, 0x0f6f4ad7, 0x17f45a33, 0x30819d5a, 0x274dbddb, 0x3bad}}, + {{0x1698df4d, 0x2865c1c9, 0x2b672586, 0x26606893, 0x2c0e8049, 0x27e9f677, 0x0e659bcd, 0x2778cf89, 0x49f9}}}, + /* 5*16^53*G: */ + {{{0x3185ae66, 0x2c7912a2, 0x3a783df0, 0x3b05b6fb, 0x24118ba6, 0x1f7d4f44, 0x0c46d67a, 0x292c6b6c, 0xa6b3}}, + {{0x0bfbf21b, 0x2fad54fe, 0x1b248dd7, 0x2fc2977d, 0x29e8d8bc, 0x06a47365, 0x09623136, 0x3a35d8e2, 0x0cb6}}}, + /* 7*16^53*G: */ + {{{0x2c630e3a, 0x25a13393, 0x3f3f1c2a, 0x0418305f, 0x3f10c1f6, 0x1f8e9f61, 0x114a4e22, 0x23d69b24, 0x1f84}}, + {{0x06ca610a, 0x3bb67fda, 0x2359724a, 0x28e49aff, 0x1da4264b, 0x2720f46a, 0x2f963862, 0x154b3341, 0xa028}}}, + /* 9*16^53*G: */ + {{{0x041bcd10, 0x37fbcf37, 0x1b44e154, 0x2e555d91, 0x0a2eb211, 0x2899df1b, 0x1c3588b1, 0x3952fa52, 0xcfd1}}, + {{0x2a62e732, 0x30057ae6, 0x0553965a, 0x36645742, 0x052fafac, 0x1d46f56c, 0x158bb9c5, 0x07d7d802, 0xf4e3}}}, + /* 11*16^53*G: */ + {{{0x228da5fb, 0x3e987648, 0x2870e724, 0x392fd78a, 0x31291b90, 0x1e578f9d, 0x09e5512c, 0x1cc3011b, 0x4b3e}}, + {{0x3c169e48, 0x3fc298e2, 0x023472bb, 0x28e84727, 0x20b48c65, 0x32e81ee3, 0x260e9e80, 0x2593688d, 0x8c40}}}, + /* 13*16^53*G: */ + {{{0x1f894780, 0x23a46962, 0x09aec5db, 0x3a7328d6, 0x02d8f737, 0x12e2952d, 0x38fe71d5, 0x0577dd10, 0xafe9}}, + {{0x1511d444, 0x3e5a554f, 0x2c0af452, 0x27a2f9ce, 0x3f2e3690, 0x2d0d08cc, 0x04686a94, 0x30d02348, 0x3cae}}}, + /* 15*16^53*G: */ + {{{0x1182fa6e, 0x168c7f2f, 0x181c8aff, 0x298cb75a, 0x35c9e7c0, 0x1a8e8db4, 0x3ac85586, 0x120a043f, 0x0c05}}, + {{0x261cd145, 0x3af3faad, 0x376d01f6, 0x39991612, 0x1d602bf5, 0x2a2e2519, 0x1f533d1a, 0x34b2b43c, 0x2f9c}}} + }, + { + /* 1*16^54*G: */ + {{{0x14441fbb, 0x382d756b, 0x1ed115e3, 0x2aa14829, 0x3925559e, 0x183157b6, 0x221d47fb, 0x23138877, 0xb495}}, + {{0x0add7118, 0x31f8f27d, 0x14638414, 0x2e7d84cb, 0x0cb7e12d, 0x0107ef0e, 0x240efe5c, 0x39efe659, 0xfcd6}}}, + /* 3*16^54*G: */ + {{{0x371f07f1, 0x2bb5a130, 0x0d70c4a5, 0x233b6dcc, 0x06684b87, 0x3a82d918, 0x0444d232, 0x0fd79ec8, 0xb3a4}}, + {{0x201dfda5, 0x0f348bd3, 0x1cb0ecc5, 0x1e1de833, 0x175ee7ec, 0x0c89cda6, 0x3d6b8418, 0x13d6c923, 0x34c6}}}, + /* 5*16^54*G: */ + {{{0x2b559d49, 0x3df25e91, 0x1dc9b44f, 0x386d1a43, 0x0008b148, 0x18bff613, 0x3e14ac26, 0x261a691a, 0x452e}}, + {{0x1a0d6ba7, 0x11f1811b, 0x31ee4257, 0x20a15b0e, 0x21ee5259, 0x0015ed9d, 0x380d0f5c, 0x22a3c657, 0x8c5e}}}, + /* 7*16^54*G: */ + {{{0x13ce94da, 0x0de99fad, 0x2829e605, 0x2c93d095, 0x0474ee8b, 0x378370eb, 0x162bb51c, 0x3d75231b, 0x19a7}}, + {{0x3025e7bb, 0x0c111c58, 0x225eb037, 0x1894c1ab, 0x00a2e8fb, 0x29475108, 0x075c32f6, 0x12e9ea4c, 0xa250}}}, + /* 9*16^54*G: */ + {{{0x147dc697, 0x25a5b31b, 0x1e15b9bb, 0x3b862bed, 0x3c6fa417, 0x3ac2cad7, 0x334dc011, 0x16c08293, 0xbdaf}}, + {{0x06a479e2, 0x24472f9e, 0x1b7a477b, 0x048b9e21, 0x17aa0855, 0x15d791ed, 0x2836c8cf, 0x031b2f7e, 0x3cec}}}, + /* 11*16^54*G: */ + {{{0x2ce05e10, 0x2802e46d, 0x3e106202, 0x3bdf27d0, 0x0e70db8a, 0x12dffa13, 0x1d15dab8, 0x2eba57ce, 0x265d}}, + {{0x171324f4, 0x3dfc062c, 0x164c67ff, 0x18fce4cf, 0x0b5dcb06, 0x0f3a2d5b, 0x037adf3b, 0x18f4268c, 0x58df}}}, + /* 13*16^54*G: */ + {{{0x33fe5938, 0x3456f156, 0x236d7cde, 0x320c0f6d, 0x1668669e, 0x1d2754e9, 0x2639689f, 0x020fc5f9, 0xc43e}}, + {{0x183732f3, 0x19e5d5bb, 0x24407477, 0x188c1c58, 0x04402eab, 0x240c0eaf, 0x3cc58350, 0x00a48e7e, 0x54c6}}}, + /* 15*16^54*G: */ + {{{0x1dd52975, 0x0c71c3de, 0x2b44180c, 0x33c3f4c1, 0x3266ba2b, 0x314369de, 0x3848665a, 0x3c5c028f, 0x7868}}, + {{0x3c626fac, 0x005bb540, 0x29690443, 0x3dbe7b29, 0x11276c68, 0x3e871b6c, 0x17ee1113, 0x25f3cc48, 0xe890}}} + }, + { + /* 1*16^55*G: */ + {{{0x2e12e1df, 0x3093990d, 0x1761d04a, 0x29ff42df, 0x06027cd8, 0x12fc4ecd, 0x132b6413, 0x2465a23a, 0xd0e0}}, + {{0x1fd28fbe, 0x2995136e, 0x046b8df6, 0x13312f66, 0x1bf86754, 0x2d82da47, 0x11452b4e, 0x26967f9f, 0x069c}}}, + /* 3*16^55*G: */ + {{{0x084aa098, 0x2c361440, 0x16e3e02b, 0x3040502a, 0x01fa8509, 0x29f6b2ff, 0x308eb398, 0x2915284c, 0xb517}}, + {{0x0540efbf, 0x0012d67d, 0x12447fd6, 0x3522d51a, 0x326fa3a4, 0x28f8bec3, 0x3879a60e, 0x21df4307, 0x0a3d}}}, + /* 5*16^55*G: */ + {{{0x0744bfa1, 0x3656b2a9, 0x093643d6, 0x09b49f38, 0x33e387cc, 0x089c4b63, 0x166f67bc, 0x050e12d4, 0xf8ec}}, + {{0x32b65f6d, 0x1a49398c, 0x3900060c, 0x18deb170, 0x160f610a, 0x1a3ec9a7, 0x3b9a6323, 0x0d2c844f, 0x7611}}}, + /* 7*16^55*G: */ + {{{0x3227a4bb, 0x18b0efa4, 0x38d99f2f, 0x39ac7c03, 0x14f2e64b, 0x1d3ab487, 0x3fae794e, 0x3fde36de, 0x320c}}, + {{0x30f3d2d4, 0x2073241a, 0x1e2f9705, 0x11c8dd02, 0x3f629960, 0x1e5a8953, 0x28692ab7, 0x3a3501ca, 0xaf9f}}}, + /* 9*16^55*G: */ + {{{0x1c2ca683, 0x2d6d6979, 0x295a7373, 0x1b3cd782, 0x03426a20, 0x377732d5, 0x2ed8517e, 0x379f1a9e, 0x0c08}}, + {{0x3db5f259, 0x0901b6d5, 0x0ea68c69, 0x3235edf8, 0x0e0e79c3, 0x20a6737f, 0x16e19b7c, 0x1b6157a8, 0xddb7}}}, + /* 11*16^55*G: */ + {{{0x252ae5cd, 0x319eb3e0, 0x0fdd7861, 0x2d94bebd, 0x24390995, 0x1bde9133, 0x07c3d18e, 0x31dab431, 0xd1f8}}, + {{0x3e6d2dda, 0x3ae5ef0f, 0x189f4fc7, 0x2eba055a, 0x21203239, 0x265ec07d, 0x0e802ac7, 0x17719848, 0x74d4}}}, + /* 13*16^55*G: */ + {{{0x2bdc603f, 0x1e4019aa, 0x3dffe5ab, 0x1b597359, 0x3620d8c9, 0x0cfb1899, 0x090c093e, 0x20da4fce, 0xa6cb}}, + {{0x096befcc, 0x2b380f83, 0x0661735c, 0x07b05a93, 0x110b72fb, 0x366f6931, 0x3cafc8f2, 0x3239187c, 0xd823}}}, + /* 15*16^55*G: */ + {{{0x22c374b0, 0x278e984b, 0x170db4a2, 0x16cd662d, 0x024ef0bf, 0x3b25c549, 0x0332136b, 0x27247a9b, 0x8a6c}}, + {{0x378c08bd, 0x2fdf3e36, 0x00f4d583, 0x054d3d0d, 0x0132a046, 0x1e217724, 0x1ffaf79a, 0x1fd3d973, 0xe4bc}}} + }, + { + /* 1*16^56*G: */ + {{{0x2895df07, 0x29c0fc43, 0x1876bd86, 0x1d7cfe80, 0x208ffefd, 0x2c1b9c33, 0x3dfeeeb5, 0x2e1509e0, 0x68f6}}, + {{0x38712655, 0x031dbe29, 0x310bf7f9, 0x14a4f4bc, 0x245028cf, 0x201137f6, 0x00ce6fbc, 0x3faea4b9, 0xcbe1}}}, + /* 3*16^56*G: */ + {{{0x3aa89692, 0x1063e88c, 0x14c2308e, 0x0ec235be, 0x18a77671, 0x1b990490, 0x28f4de99, 0x329c6059, 0x3bdf}}, + {{0x1a510308, 0x0f6f6d0c, 0x1e2ef139, 0x370318d1, 0x1a5333c7, 0x098546bb, 0x167b8494, 0x07da1594, 0x0a72}}}, + /* 5*16^56*G: */ + {{{0x037ea1d7, 0x1e6c8d0b, 0x09aae4d0, 0x0e4d963e, 0x0d9e4fb2, 0x0a154946, 0x21056353, 0x2b256dd4, 0xaca8}}, + {{0x1ba973a2, 0x37bec412, 0x13935e9d, 0x3b6ff710, 0x072189e1, 0x01312e4a, 0x1cc20943, 0x3159f75d, 0x7f12}}}, + /* 7*16^56*G: */ + {{{0x13245b7f, 0x36c9e073, 0x0597fbf5, 0x1f59a5a4, 0x185311a3, 0x3086be63, 0x27c0e206, 0x11c136d9, 0xfa90}}, + {{0x0ddf6bef, 0x3e0cf7c5, 0x24f1d47e, 0x27bb3498, 0x31c189cb, 0x3e8fb503, 0x036a42d6, 0x230d9d2a, 0x1a1c}}}, + /* 9*16^56*G: */ + {{{0x37f0953a, 0x187de3f5, 0x315439ab, 0x124520ff, 0x3a92a818, 0x0ae3874b, 0x17d8cd67, 0x06aae47d, 0x1d43}}, + {{0x1d68f260, 0x1f1675da, 0x0707e7c1, 0x238a6a42, 0x15fae0f4, 0x0c320f38, 0x1121ebc5, 0x19f0efc6, 0x08d6}}}, + /* 11*16^56*G: */ + {{{0x25227c70, 0x28c45c4d, 0x3a3ea705, 0x0afaaccc, 0x31c60ff3, 0x12cd6cb8, 0x21137dda, 0x3a83568f, 0x6dee}}, + {{0x0369b9b7, 0x35b68e04, 0x29083dba, 0x1ebb0795, 0x2acc8428, 0x132ebfbd, 0x03e40001, 0x0fc3f1d1, 0xcbb9}}}, + /* 13*16^56*G: */ + {{{0x0421b54d, 0x2d7f57a2, 0x1564a4ff, 0x26cae0e9, 0x3a9dca57, 0x3274aec7, 0x178d8d4a, 0x170418d5, 0x2813}}, + {{0x0ee5d868, 0x3733c26e, 0x1e310d8a, 0x01253324, 0x3f8c15ef, 0x2a75d041, 0x1be1506f, 0x12af8e14, 0x9ed8}}}, + /* 15*16^56*G: */ + {{{0x28e4ac10, 0x05f95647, 0x0e24a9a9, 0x25aa04ab, 0x3fb56879, 0x0f316827, 0x1077bd6c, 0x015d882c, 0x339a}}, + {{0x0d1312a0, 0x1db6a191, 0x01cc66ef, 0x0e79e23d, 0x0f553e50, 0x1537de2b, 0x2947f438, 0x17efb75a, 0xca98}}} + }, + { + /* 1*16^57*G: */ + {{{0x27ea1f34, 0x0d36ac5d, 0x0739e0dd, 0x1af4d501, 0x3353d664, 0x10745e4e, 0x34b66c3b, 0x18288f51, 0x7f94}}, + {{0x0d9063ec, 0x22fb0b2b, 0x0e34ffc5, 0x3fe05449, 0x076661c6, 0x07cafe3c, 0x0618769f, 0x059de3ec, 0xd0d5}}}, + /* 3*16^57*G: */ + {{{0x3dfc0a9d, 0x316dd326, 0x0f77aa0d, 0x1108d6c5, 0x20a2a2de, 0x038d91ab, 0x29e022a6, 0x39fe130c, 0xdb43}}, + {{0x1e9ad713, 0x02c424ea, 0x2d2f054f, 0x0e411cd5, 0x2f9fa488, 0x15b20533, 0x2b591b8a, 0x2368af8d, 0xb016}}}, + /* 5*16^57*G: */ + {{{0x0283808d, 0x02f2c5dd, 0x1643a893, 0x23c1f38d, 0x3a78980f, 0x057a4487, 0x121aeb85, 0x0c207b83, 0xe9af}}, + {{0x39b39d33, 0x19b0be38, 0x1136d199, 0x1ae49445, 0x2f497197, 0x3c99543f, 0x3126085a, 0x32122711, 0xa976}}}, + /* 7*16^57*G: */ + {{{0x2d8426df, 0x1a4bd0b2, 0x26f8a0a2, 0x104e5693, 0x3883590f, 0x2b24e0ef, 0x06980703, 0x0cd8cb20, 0x6eb7}}, + {{0x200b4267, 0x3fdd67b8, 0x3fe1b833, 0x14ba5f20, 0x008e8d92, 0x392cb3b3, 0x07a9a030, 0x1bb045cc, 0x96c5}}}, + /* 9*16^57*G: */ + {{{0x1a16453d, 0x1f45b5f0, 0x21033dbf, 0x1fa1ef9d, 0x34d0e68b, 0x106e47e2, 0x15f45e17, 0x275781e7, 0xd397}}, + {{0x27b6d737, 0x0f2ee0c5, 0x26961a4f, 0x377d98a2, 0x32456917, 0x02495d4d, 0x1adb9a4d, 0x24cd75e6, 0xc55f}}}, + /* 11*16^57*G: */ + {{{0x2d326504, 0x3a866697, 0x3b5202cc, 0x16a6d189, 0x2efc12f6, 0x20ee2306, 0x0c2342c3, 0x24a7396e, 0x54c3}}, + {{0x3ec9e107, 0x2fc047e9, 0x08a67268, 0x294f6798, 0x14ab4447, 0x26a8a124, 0x216d0c48, 0x0c09583a, 0x4696}}}, + /* 13*16^57*G: */ + {{{0x3b5ecce7, 0x0113d5da, 0x00d21353, 0x0a0562c3, 0x1659c873, 0x3a3a0f06, 0x2d6c5b84, 0x3a6ca199, 0x3744}}, + {{0x2a247721, 0x004c8505, 0x2a6f8392, 0x3a2d7c14, 0x29ec3c28, 0x39a55bac, 0x047aa0e0, 0x383e3664, 0x9546}}}, + /* 15*16^57*G: */ + {{{0x05fef996, 0x0324a379, 0x04253515, 0x01a3d8e5, 0x33f2de14, 0x3342907b, 0x16d53324, 0x0f85f8d9, 0x1134}}, + {{0x1792aded, 0x00542b9d, 0x086f18e4, 0x33935968, 0x273765d0, 0x377e4c18, 0x28eeeb04, 0x212037ae, 0x4a9e}}} + }, + { + /* 1*16^58*G: */ + {{{0x0e6d8483, 0x3b26d35e, 0x2967f0dc, 0x3cb5ea11, 0x2ee94582, 0x23d27c6d, 0x1563d295, 0x32d828cf, 0x9c39}}, + {{0x2b2c50fb, 0x12ccd5bd, 0x1be43689, 0x2b794bcf, 0x216546bb, 0x065adef2, 0x3e51003d, 0x2fc7b924, 0xf097}}}, + /* 3*16^58*G: */ + {{{0x07a14dda, 0x1570c7e1, 0x34b4df3f, 0x1b410a59, 0x01308360, 0x1da3dc90, 0x2dad7443, 0x1eb3243a, 0x18f3}}, + {{0x25ac8364, 0x08bf370c, 0x28536cbe, 0x363df1e2, 0x1bcd0b77, 0x2fffb3b8, 0x12c26d7b, 0x12eeaa82, 0x2f94}}}, + /* 5*16^58*G: */ + {{{0x0c7d59be, 0x19d3a3a3, 0x20932fb5, 0x3a861623, 0x32736b98, 0x17ffb91d, 0x279da4ec, 0x0d630a07, 0x5413}}, + {{0x24f80590, 0x35fa87db, 0x100b3672, 0x3896c572, 0x24515a53, 0x123f4805, 0x0b024e7c, 0x3537a5a7, 0x680f}}}, + /* 7*16^58*G: */ + {{{0x076051a8, 0x3ae0327e, 0x2457ea58, 0x35dce58e, 0x385280be, 0x3f068f06, 0x194f05dc, 0x3449a46c, 0x4e2f}}, + {{0x29cc9005, 0x2bfb1d3f, 0x2c4fe2e6, 0x2e2ea964, 0x0a31bceb, 0x2cd68542, 0x0fbb2371, 0x2ef6fd7d, 0x122a}}}, + /* 9*16^58*G: */ + {{{0x16a80e09, 0x19f2a3e9, 0x225f5fe3, 0x1d7c3dd9, 0x008fa0a2, 0x13d5a04f, 0x31b59200, 0x16352fbf, 0x2de7}}, + {{0x036a1cd3, 0x358bb7d5, 0x1dad6c99, 0x06b719a5, 0x1e64a07a, 0x00cac099, 0x0ee67d7c, 0x33cc5df6, 0xdd9a}}}, + /* 11*16^58*G: */ + {{{0x3a3628ac, 0x0940d6cb, 0x35b564ec, 0x22ee8b37, 0x2e12a456, 0x1685cf1b, 0x14a5728c, 0x282b3707, 0xf597}}, + {{0x2cd3550f, 0x3a80c435, 0x012106e7, 0x0bb3e475, 0x222cc077, 0x06edca25, 0x3d4557bb, 0x05a38cca, 0x0db9}}}, + /* 13*16^58*G: */ + {{{0x2b75d6c3, 0x235a0f52, 0x13a28567, 0x0a9515f5, 0x3e40f3c4, 0x041c6086, 0x04fb908a, 0x0aa1b5bd, 0xaa22}}, + {{0x244cb028, 0x0c996939, 0x1a8c8f61, 0x1c7f252d, 0x22df4260, 0x122896bb, 0x28e76ce4, 0x21e4c006, 0x5637}}}, + /* 15*16^58*G: */ + {{{0x235790c9, 0x3ea15ce4, 0x3f3c5037, 0x006e45dc, 0x335e2e9e, 0x03190e4b, 0x315b756f, 0x2c9af365, 0x8568}}, + {{0x26b1f5ac, 0x34fd54e0, 0x385479fd, 0x11797e3e, 0x363ce801, 0x1e382b90, 0x1d2ade90, 0x09869613, 0xd3f2}}} + }, + { + /* 1*16^59*G: */ + {{{0x1c38d4e4, 0x376a5f15, 0x1b173747, 0x3f597c6c, 0x181e25e2, 0x19b9d0c0, 0x29938975, 0x21498448, 0x3d92}}, + {{0x00ccf0d3, 0x3eabbc03, 0x17abc7f6, 0x02ac4e06, 0x2869eacc, 0x015c0d70, 0x0eab53ff, 0x2829751a, 0xd32c}}}, + /* 3*16^59*G: */ + {{{0x0dd7718a, 0x01c8c960, 0x1be4e4ed, 0x3206d946, 0x36dff891, 0x05668979, 0x02fc3f7c, 0x038dcae4, 0x3b18}}, + {{0x1afd82db, 0x099898a6, 0x02d14d07, 0x1244559c, 0x05211e58, 0x12f274a4, 0x358aafaa, 0x2c45fcda, 0xf2b6}}}, + /* 5*16^59*G: */ + {{{0x13d3653d, 0x2a069446, 0x0e467d5f, 0x13b12c9d, 0x283eb213, 0x3d3d0262, 0x29c9f45e, 0x3fc0e475, 0xf352}}, + {{0x0a44f28e, 0x27999e32, 0x2c582d07, 0x06657e5c, 0x26d5055c, 0x2f5cf7f6, 0x05ebd020, 0x189b32db, 0x4472}}}, + /* 7*16^59*G: */ + {{{0x2d4478da, 0x19877c6b, 0x00e0154d, 0x173db089, 0x393ca1f1, 0x2d1736fd, 0x18c230af, 0x391c40d3, 0x670e}}, + {{0x34f563f0, 0x0a3ff93f, 0x3f247706, 0x30ee0583, 0x0750e81c, 0x19816c4e, 0x022ca254, 0x31d096e8, 0x5ca0}}}, + /* 9*16^59*G: */ + {{{0x03dbd581, 0x3138a411, 0x0d6b35ba, 0x3face20a, 0x2c6fa93c, 0x2fe8c2b3, 0x19bdbefb, 0x38d50d27, 0x96f2}}, + {{0x28f59952, 0x36693ffb, 0x04f5d454, 0x2863c754, 0x0dbaf435, 0x17638e58, 0x126cf4fe, 0x36022175, 0x09fc}}}, + /* 11*16^59*G: */ + {{{0x24e9c2fc, 0x3acd0c92, 0x3bd706a1, 0x0b3c33cb, 0x209a35e7, 0x06082c51, 0x399ac804, 0x1b945fa0, 0xc494}}, + {{0x26398ce8, 0x10d1d8dd, 0x14623123, 0x22fce3b4, 0x3b8237e4, 0x283da3d1, 0x18a4ce99, 0x00482c61, 0x7489}}}, + /* 13*16^59*G: */ + {{{0x04960b03, 0x32e45cfa, 0x0808e8f5, 0x2b0eac32, 0x094d8fb6, 0x232315e0, 0x233dbfa4, 0x2d936a6f, 0x1653}}, + {{0x30f73c69, 0x201a953a, 0x1b564e7f, 0x0e383928, 0x15a8948b, 0x2caf60fa, 0x1d5609f4, 0x1c205a79, 0xa583}}}, + /* 15*16^59*G: */ + {{{0x3b63640e, 0x155df8c6, 0x0c72df2c, 0x26edfca4, 0x05cbf497, 0x319e729a, 0x3153f500, 0x1b75fb4b, 0x5107}}, + {{0x02e4476c, 0x3da5ca1e, 0x320ef021, 0x2fa93a79, 0x20fda6c8, 0x399405cb, 0x1df76aeb, 0x09d28b5b, 0xb397}}} + }, + { + /* 1*16^60*G: */ + {{{0x244e8de3, 0x018c12c6, 0x2cc1e076, 0x02259a8b, 0x3d17915c, 0x29f73c22, 0x010b73a5, 0x266dd1a2, 0xf50b}}, + {{0x1b7f3588, 0x28fcee9b, 0x1721e854, 0x1d7c6348, 0x2dcebbe9, 0x265ce8b7, 0x18f0c878, 0x0187957c, 0xe2b5}}}, + /* 3*16^60*G: */ + {{{0x02accf8b, 0x3771adae, 0x2816fa7d, 0x34a66460, 0x39430481, 0x3cc38944, 0x05770645, 0x1fd86954, 0x598d}}, + {{0x0f6cb808, 0x2e119cf0, 0x13540b91, 0x0a26a3cd, 0x33ebcad2, 0x31458ac9, 0x32609546, 0x087dd3e3, 0x9f31}}}, + /* 5*16^60*G: */ + {{{0x24aa7b3e, 0x3ece6951, 0x16c9cea9, 0x313bc6c1, 0x1c581013, 0x34824550, 0x34c4d64f, 0x0804bd27, 0x715a}}, + {{0x3c7d081d, 0x268ce512, 0x08b47d0d, 0x06f1622a, 0x113b6242, 0x24a23e2a, 0x06c0a1f7, 0x2cec6a98, 0x5922}}}, + /* 7*16^60*G: */ + {{{0x220db220, 0x06f6da5d, 0x287ace4d, 0x0732c405, 0x387876c7, 0x273a25fe, 0x1b125c40, 0x23179aaa, 0x49ec}}, + {{0x277338c2, 0x26e2b281, 0x13b9cce9, 0x0b0c1cf9, 0x1f542984, 0x2730d219, 0x2629b3da, 0x1f53f97a, 0x99a9}}}, + /* 9*16^60*G: */ + {{{0x1e771268, 0x07af28c5, 0x10a65685, 0x13c529f6, 0x207b7a2f, 0x3c643817, 0x0b4483e6, 0x2dc35214, 0x1f8f}}, + {{0x0909c8dd, 0x2bf4c043, 0x092b3ab1, 0x074f0c47, 0x2192a14e, 0x0bb5d1c9, 0x3a2bf12c, 0x1eb6d186, 0xf53e}}}, + /* 11*16^60*G: */ + {{{0x28d9819e, 0x17b03cac, 0x02dab1a5, 0x019e4bdd, 0x38732cd6, 0x3450ae99, 0x3f61fdd5, 0x31c69925, 0xb8d5}}, + {{0x29138ac4, 0x31e2fa3a, 0x1d45c3cd, 0x3d27c4d8, 0x23dc79e2, 0x3b90d66d, 0x37f823b6, 0x13bc4c84, 0x1cd1}}}, + /* 13*16^60*G: */ + {{{0x20bca3f3, 0x2a4f6f99, 0x16004906, 0x2cd0d451, 0x00d8c4ec, 0x0fad8722, 0x2ae3ddd6, 0x2d6b196e, 0x2265}}, + {{0x117409ff, 0x160a71b1, 0x2393d5a2, 0x202984b4, 0x0964983c, 0x0c4e8ec4, 0x0fe0f61a, 0x262fd72b, 0x97a1}}}, + /* 15*16^60*G: */ + {{{0x05bac36e, 0x1cb48ffd, 0x175dcd03, 0x26265166, 0x09abcb59, 0x362a7d7f, 0x0492521f, 0x073440d6, 0xaf38}}, + {{0x31b119a9, 0x3cf621ea, 0x34d4a90f, 0x26e0bc7b, 0x1a264858, 0x15fc8a54, 0x30fbdc94, 0x021fedf7, 0x681a}}} + }, + { + /* 1*16^61*G: */ + {{{0x2037cfb4, 0x38665015, 0x3cdaa859, 0x003c91b0, 0x20b0e074, 0x1fd22036, 0x1ed0b0d7, 0x0c608ffd, 0x0425}}, + {{0x18775d23, 0x02dcc97b, 0x0ec5dd40, 0x28f93d4d, 0x261facee, 0x32934321, 0x00f7e628, 0x22f33eb8, 0xc90e}}}, + /* 3*16^61*G: */ + {{{0x06c34577, 0x213d9cd5, 0x2a52af77, 0x1027b239, 0x00e4bde6, 0x178c23a3, 0x3ca48b1f, 0x1ea838c2, 0x2755}}, + {{0x0416193c, 0x37fae6e0, 0x0c4380ba, 0x28b29cdd, 0x3d34f318, 0x235d6927, 0x05b3b77c, 0x31d61184, 0x8399}}}, + /* 5*16^61*G: */ + {{{0x2401f4d3, 0x3963f6da, 0x295b301e, 0x1b0b943a, 0x21d7decf, 0x01e0efd5, 0x073648e5, 0x1e05f496, 0x8e68}}, + {{0x0294d86b, 0x00a07a51, 0x2a191289, 0x02e5bc4b, 0x2d3cae90, 0x20268141, 0x09bfa62f, 0x2ae21b8b, 0x989c}}}, + /* 7*16^61*G: */ + {{{0x2d2aa8e6, 0x1658f789, 0x0effe2dc, 0x14d67f10, 0x27dbee20, 0x0da00f29, 0x25cf6d10, 0x05d1894f, 0x98a4}}, + {{0x206cf75b, 0x25d02fb5, 0x37ed2196, 0x0085feaa, 0x35cec9e3, 0x150bd68b, 0x063d6b11, 0x31a51f8d, 0x579a}}}, + /* 9*16^61*G: */ + {{{0x352c2d31, 0x328b323d, 0x061eecd7, 0x002aec23, 0x21a94618, 0x05b910f8, 0x140fd922, 0x151088c1, 0xe168}}, + {{0x24a50fec, 0x32e20da0, 0x09983941, 0x1d864afe, 0x2bc9343e, 0x0b990b40, 0x272142fb, 0x215724a3, 0x0700}}}, + /* 11*16^61*G: */ + {{{0x33a7cdad, 0x28ceeb8d, 0x10bcfaf4, 0x2b60f4b9, 0x0951a53c, 0x0a8b94ce, 0x113ea1ca, 0x0c52c275, 0xbfa6}}, + {{0x295cb953, 0x17e224c0, 0x04047a1c, 0x04643e32, 0x2ed1a726, 0x3e16eec7, 0x02c782a5, 0x3a065320, 0xb452}}}, + /* 13*16^61*G: */ + {{{0x0ade0fb7, 0x36f32140, 0x26518d8e, 0x1b71d37a, 0x198e200c, 0x025d79b7, 0x21cd3ecf, 0x020b42a5, 0xe687}}, + {{0x1d4d6ece, 0x05e783cc, 0x08c22599, 0x307a17be, 0x11a72117, 0x3c394c87, 0x095555e5, 0x29121a13, 0x2135}}}, + /* 15*16^61*G: */ + {{{0x0e432daf, 0x20f2d7c3, 0x2827ac9c, 0x2fb6822a, 0x074975f3, 0x30a35e54, 0x1a9e94bf, 0x1bbe18aa, 0x7ab1}}, + {{0x271bdc48, 0x045d622a, 0x34fdb013, 0x3a738eb9, 0x1ba7c5c7, 0x2460f8a3, 0x328b1a35, 0x0382a5f0, 0x584e}}} + }, + { + /* 1*16^62*G: */ + {{{0x085fbd44, 0x01d1c4a6, 0x326267ac, 0x30b2a8e7, 0x15222c89, 0x11c7385b, 0x35905e05, 0x01b6b66a, 0x9bbf}}, + {{0x3a1d3e88, 0x0d11f7e9, 0x1036ed2a, 0x352f7705, 0x2f47e8c0, 0x176bcc29, 0x120a3675, 0x1fea1378, 0x1bcc}}}, + /* 3*16^62*G: */ + {{{0x34a7b506, 0x2deb9e4a, 0x3860be08, 0x1d62eeb9, 0x100ee922, 0x33ecab9d, 0x35bd3429, 0x3dfd96ce, 0x646f}}, + {{0x2b36f946, 0x25e70494, 0x08e6995c, 0x0b7f13f0, 0x0a8fe849, 0x078cc601, 0x218a55a6, 0x0aa74192, 0xbc11}}}, + /* 5*16^62*G: */ + {{{0x0103b553, 0x152dc727, 0x3385a801, 0x183a89e0, 0x3e507ebe, 0x304002c9, 0x3d39a9d0, 0x151ea985, 0x7cc0}}, + {{0x0d45a526, 0x1e672e8f, 0x0228b7d5, 0x061682ab, 0x3c94c400, 0x1ca32ce7, 0x0045abdd, 0x27af48ca, 0x7b32}}}, + /* 7*16^62*G: */ + {{{0x19e717a4, 0x30bbd150, 0x0f01b81a, 0x368af6ab, 0x2ee15468, 0x0fb54db6, 0x1db4e056, 0x146642f0, 0x9468}}, + {{0x3526dea3, 0x1d7c3f46, 0x30acd9ca, 0x2665643d, 0x267dc057, 0x23439ac9, 0x191a8b3b, 0x1e108371, 0xca5c}}}, + /* 9*16^62*G: */ + {{{0x08362735, 0x3e0b0dbc, 0x12b327bd, 0x3e2cdfbc, 0x12d1f5df, 0x163e3a91, 0x0e8fab12, 0x23c6f9f8, 0xe1b9}}, + {{0x0ecb11b7, 0x2584e327, 0x374090af, 0x067b8cf7, 0x3b2ba27e, 0x16d26a0e, 0x36a0b7e0, 0x3a6b66a5, 0xca83}}}, + /* 11*16^62*G: */ + {{{0x39046346, 0x2d02ef60, 0x01440083, 0x296379cc, 0x27962d56, 0x2281af65, 0x207ef6d0, 0x3c9723f5, 0x3536}}, + {{0x0c14fea6, 0x100418af, 0x2d9b3e29, 0x1b0f47a8, 0x29e1c39e, 0x285a8694, 0x3509e73b, 0x07f85f78, 0x1e27}}}, + /* 13*16^62*G: */ + {{{0x2847f6f8, 0x3ffe0fb5, 0x140ef530, 0x0a6d47ef, 0x3f8c3c10, 0x0547cd2d, 0x3d4de690, 0x0091af88, 0x0df5}}, + {{0x3b1633a6, 0x1332a29a, 0x1df3449b, 0x1b8599a2, 0x2174ab4c, 0x0cb13ef0, 0x2f1ca2b2, 0x011fca76, 0x2107}}}, + /* 15*16^62*G: */ + {{{0x3d4f1b81, 0x2173abb7, 0x0f4bb151, 0x1a69e923, 0x129330ad, 0x378eccd9, 0x13398f69, 0x3575133d, 0xca9d}}, + {{0x02b7c8bd, 0x3318b2b9, 0x2ada10f8, 0x325d82fe, 0x067b3e66, 0x11c7ed11, 0x22c56402, 0x2621946f, 0x6e4b}}} + }, + { + /* 1*16^63*G: */ + {{{0x044c0448, 0x3ab4c8cd, 0x10319e31, 0x0d5da1b0, 0x3893e796, 0x0ff32ced, 0x3dfa5494, 0x2b7d4a50, 0xb12f}}, + {{0x3369de57, 0x195d79da, 0x2fc4df29, 0x0179c0cc, 0x32a6a71d, 0x3e3d99de, 0x0f4ace96, 0x1165666c, 0x02e2}}}, + /* 3*16^63*G: */ + {{{0x24e9151f, 0x14db1151, 0x00d8418f, 0x3a8ce672, 0x18fb3e67, 0x15776a47, 0x10568432, 0x238d3c71, 0x4838}}, + {{0x0d7a9434, 0x2fb927b7, 0x3de83101, 0x2c504454, 0x082bcc99, 0x14ce4c55, 0x04e9e6a2, 0x18eafd39, 0xb0ec}}}, + /* 5*16^63*G: */ + {{{0x0e5b833d, 0x1f7ed296, 0x20b2419d, 0x0e801cf2, 0x0109c959, 0x177e0414, 0x053da5e6, 0x1911eb85, 0xde8e}}, + {{0x214c5cc7, 0x03f3066a, 0x101c6c9f, 0x1f80c4ca, 0x2de26598, 0x08a232f5, 0x113d8e33, 0x118f0542, 0x05e1}}}, + /* 7*16^63*G: */ + {{{0x01f7df48, 0x38964fab, 0x071317b3, 0x19d1cfae, 0x18f385b2, 0x156d3939, 0x07e9e8e5, 0x04b4293b, 0xb18b}}, + {{0x2846b546, 0x06cf5643, 0x3d1e5599, 0x20fdf920, 0x2cc33b3c, 0x3109af16, 0x1fb445ce, 0x0648a8d6, 0xff53}}}, + /* 9*16^63*G: */ + {{{0x19c9fd24, 0x094eb71a, 0x1211e0df, 0x33762611, 0x28694402, 0x072a931c, 0x09433c7c, 0x2b5c7237, 0x5f51}}, + {{0x2d2ffd3a, 0x30eeba21, 0x224a9969, 0x087d8911, 0x2e4d0387, 0x0c17ef30, 0x2714a0cd, 0x3bc477df, 0x2bbb}}}, + /* 11*16^63*G: */ + {{{0x17cec42e, 0x0f1018ff, 0x2e3bdb7e, 0x0f724cfb, 0x06d8556f, 0x208bb90d, 0x01ebbfa5, 0x10364dcc, 0xfdf3}}, + {{0x0db6908b, 0x23d8d2df, 0x0de30c83, 0x1b9aafd4, 0x0ad2c445, 0x307f9ce3, 0x0c6e1d70, 0x2698e5a3, 0xa3e5}}}, + /* 13*16^63*G: */ + {{{0x21dc4fe8, 0x30625153, 0x2072415f, 0x3a284ea5, 0x3dc983f9, 0x114a45ed, 0x25d79ec6, 0x3af22e7a, 0xe3ca}}, + {{0x1307b403, 0x1ad82dc8, 0x14f86a11, 0x0c00d968, 0x01f97651, 0x00d72e2c, 0x05928d22, 0x24f49efc, 0x97f0}}}, + /* 15*16^63*G: */ + {{{0x3c119eff, 0x10535974, 0x29f9b846, 0x240b8302, 0x0fa00339, 0x10697396, 0x065b89af, 0x0b6e50aa, 0x0331}}, + {{0x38b1b950, 0x3a568ea7, 0x3515585f, 0x3b1676d7, 0x09e86f0a, 0x3ba8c5e0, 0x324df104, 0x36991acd, 0x6e3e}}} + }, diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/options.h b/hardware-wallet/firmware/vendor/trezor-crypto/options.h new file mode 100644 index 00000000..2a542157 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/options.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __OPTIONS_H__ +#define __OPTIONS_H__ + +// use precomputed Curve Points (some scalar multiples of curve base point G) +#ifndef USE_PRECOMPUTED_CP +#define USE_PRECOMPUTED_CP 1 +#endif + +// use fast inverse method +#ifndef USE_INVERSE_FAST +#define USE_INVERSE_FAST 1 +#endif + +// support for printing bignum256 structures via printf +#ifndef USE_BN_PRINT +#define USE_BN_PRINT 0 +#endif + +// use deterministic signatures +#ifndef USE_RFC6979 +#define USE_RFC6979 1 +#endif + +// implement BIP32 caching +#ifndef USE_BIP32_CACHE +#define USE_BIP32_CACHE 1 +#define BIP32_CACHE_SIZE 10 +#define BIP32_CACHE_MAXDEPTH 8 +#endif + +// implement BIP39 caching +#ifndef USE_BIP39_CACHE +#define USE_BIP39_CACHE 1 +#define BIP39_CACHE_SIZE 4 +#endif + +// support Ethereum operations +#ifndef USE_ETHEREUM +#define USE_ETHEREUM 0 +#endif + +// support Graphene operations (STEEM, BitShares) +#ifndef USE_GRAPHENE +#define USE_GRAPHENE 0 +#endif + +// support NEM operations +#ifndef USE_NEM +#define USE_NEM 0 +#endif + +// support Keccak hashing +#ifndef USE_KECCAK +#define USE_KECCAK 1 +#endif + +// add way how to mark confidential data +#ifndef CONFIDENTIAL +#define CONFIDENTIAL +#endif + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.c b/hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.c new file mode 100644 index 00000000..e6dbd008 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.c @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "pbkdf2.h" +#include "hmac.h" +#include "sha2.h" +#include "memzero.h" + +void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen) +{ + SHA256_CTX ctx; + uint32_t blocknr = 1; +#if BYTE_ORDER == LITTLE_ENDIAN + REVERSE32(blocknr, blocknr); +#endif + + hmac_sha256_prepare(pass, passlen, pctx->odig, pctx->idig); + memset(pctx->g, 0, sizeof(pctx->g)); + pctx->g[8] = 0x80000000; + pctx->g[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; + + memcpy (ctx.state, pctx->idig, sizeof(pctx->idig)); + ctx.bitcount = SHA256_BLOCK_LENGTH * 8; + sha256_Update(&ctx, salt, saltlen); + sha256_Update(&ctx, (uint8_t*)&blocknr, sizeof(blocknr)); + sha256_Final(&ctx, (uint8_t*)pctx->g); +#if BYTE_ORDER == LITTLE_ENDIAN + for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) { + REVERSE32(pctx->g[k], pctx->g[k]); + } +#endif + sha256_Transform(pctx->odig, pctx->g, pctx->g); + memcpy(pctx->f, pctx->g, SHA256_DIGEST_LENGTH); + pctx->first = 1; +} + +void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations) +{ + for (uint32_t i = pctx->first; i < iterations; i++) { + sha256_Transform(pctx->idig, pctx->g, pctx->g); + sha256_Transform(pctx->odig, pctx->g, pctx->g); + for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH/sizeof(uint32_t); j++) { + pctx->f[j] ^= pctx->g[j]; + } + } + pctx->first = 0; +} + +void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH/sizeof(uint32_t); k++) { + REVERSE32(pctx->f[k], pctx->f[k]); + } +#endif + memcpy(key, pctx->f, SHA256_DIGEST_LENGTH); + memzero(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX)); +} + +void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key) +{ + PBKDF2_HMAC_SHA256_CTX pctx; + pbkdf2_hmac_sha256_Init(&pctx, pass, passlen, salt, saltlen); + pbkdf2_hmac_sha256_Update(&pctx, iterations); + pbkdf2_hmac_sha256_Final(&pctx, key); +} + +void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen) +{ + SHA512_CTX ctx; + uint32_t blocknr = 1; +#if BYTE_ORDER == LITTLE_ENDIAN + REVERSE32(blocknr, blocknr); +#endif + + hmac_sha512_prepare(pass, passlen, pctx->odig, pctx->idig); + memset(pctx->g, 0, sizeof(pctx->g)); + pctx->g[8] = 0x8000000000000000; + pctx->g[15] = (SHA512_BLOCK_LENGTH + SHA512_DIGEST_LENGTH) * 8; + + memcpy (ctx.state, pctx->idig, sizeof(pctx->idig)); + ctx.bitcount[0] = SHA512_BLOCK_LENGTH * 8; + ctx.bitcount[1] = 0; + sha512_Update(&ctx, salt, saltlen); + sha512_Update(&ctx, (uint8_t*)&blocknr, sizeof(blocknr)); + sha512_Final(&ctx, (uint8_t*)pctx->g); +#if BYTE_ORDER == LITTLE_ENDIAN + for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) { + REVERSE64(pctx->g[k], pctx->g[k]); + } +#endif + sha512_Transform(pctx->odig, pctx->g, pctx->g); + memcpy(pctx->f, pctx->g, SHA512_DIGEST_LENGTH); + pctx->first = 1; +} + +void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations) +{ + for (uint32_t i = pctx->first; i < iterations; i++) { + sha512_Transform(pctx->idig, pctx->g, pctx->g); + sha512_Transform(pctx->odig, pctx->g, pctx->g); + for (uint32_t j = 0; j < SHA512_DIGEST_LENGTH / sizeof(uint64_t); j++) { + pctx->f[j] ^= pctx->g[j]; + } + } + pctx->first = 0; +} + +void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH/sizeof(uint64_t); k++) { + REVERSE64(pctx->f[k], pctx->f[k]); + } +#endif + memcpy(key, pctx->f, SHA512_DIGEST_LENGTH); + memzero(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX)); +} + +void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key) +{ + PBKDF2_HMAC_SHA512_CTX pctx; + pbkdf2_hmac_sha512_Init(&pctx, pass, passlen, salt, saltlen); + pbkdf2_hmac_sha512_Update(&pctx, iterations); + pbkdf2_hmac_sha512_Final(&pctx, key); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.h b/hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.h new file mode 100644 index 00000000..e77f2918 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/pbkdf2.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __PBKDF2_H__ +#define __PBKDF2_H__ + +#include +#include "sha2.h" + +typedef struct _PBKDF2_HMAC_SHA256_CTX { + uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; + uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; + uint32_t f[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; + uint32_t g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; + char first; +} PBKDF2_HMAC_SHA256_CTX; + +typedef struct _PBKDF2_HMAC_SHA512_CTX { + uint64_t odig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; + uint64_t idig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; + uint64_t f[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; + uint64_t g[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; + char first; +} PBKDF2_HMAC_SHA512_CTX; + +void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen); +void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations); +void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key); +void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key); + +void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen); +void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations); +void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key); +void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/rand.c b/hardware-wallet/firmware/vendor/trezor-crypto/rand.c new file mode 100644 index 00000000..975bf18d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/rand.c @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "rand.h" + +#ifndef RAND_PLATFORM_INDEPENDENT + +#include +#ifdef _WIN32 +#include +#else +#include +#endif + +uint32_t random32(void) +{ +#ifdef _WIN32 + static int initialized = 0; + if (!initialized) { + srand((unsigned)time(NULL)); + initialized = 1; + } + return ((rand() % 0xFF) | ((rand() % 0xFF) << 8) | ((rand() % 0xFF) << 16) | ((rand() % 0xFF) << 24)); +#else + static FILE *frand = NULL; + if (!frand) { + frand = fopen("/dev/urandom", "r"); + } + uint32_t r; + size_t len_read = fread(&r, 1, sizeof(r), frand); + assert(len_read == sizeof(r)); + return r; +#endif +} + +#endif /* RAND_PLATFORM_INDEPENDENT */ + +// +// The following code is platform independent +// + +uint32_t random_uniform(uint32_t n) +{ + uint32_t x, max = 0xFFFFFFFF - (0xFFFFFFFF % n); + while ((x = random32()) >= max); + return x / (max / n); +} + +void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len) +{ + uint32_t r = 0; + for (size_t i = 0; i < len; i++) { + if (i % 4 == 0) { + r = random32(); + } + buf[i] = (r >> ((i % 4) * 8)) & 0xFF; + } +} + +void random_permute(char *str, size_t len) +{ + for (int i = len - 1; i >= 1; i--) { + int j = random_uniform(i + 1); + char t = str[j]; + str[j] = str[i]; + str[i] = t; + } +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/rand.h b/hardware-wallet/firmware/vendor/trezor-crypto/rand.h new file mode 100644 index 00000000..1053fef2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/rand.h @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __RAND_H__ +#define __RAND_H__ + +#include +#include + +uint32_t random32(void); +uint32_t random_uniform(uint32_t n); +void random_buffer(uint8_t *buf, size_t len); +void random_permute(char *buf, size_t len); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/rc4.c b/hardware-wallet/firmware/vendor/trezor-crypto/rc4.c new file mode 100644 index 00000000..db9eb1ff --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/rc4.c @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, E1PRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "rc4.h" + +static inline void rc4_swap(RC4_CTX *ctx, uint8_t i, uint8_t j) { + uint8_t temp = ctx->S[i]; + ctx->S[i] = ctx->S[j]; + ctx->S[j] = temp; +} + +void rc4_init(RC4_CTX *ctx, const uint8_t *key, size_t length) { + ctx->i = 0; + ctx->j = 0; + + for (size_t i = 0; i < 256; i++) { + ctx->S[i] = i; + } + + uint8_t j = 0; + for (size_t i = 0; i < 256; i++) { + j += ctx->S[i] + key[i % length]; + rc4_swap(ctx, i, j); + } +} + +void rc4_encrypt(RC4_CTX *ctx, uint8_t *buffer, size_t length) { + for (size_t idx = 0; idx < length; idx++) { + ctx->i++; + ctx->j += ctx->S[ctx->i]; + + rc4_swap(ctx, ctx->i, ctx->j); + + uint8_t K = ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256]; + buffer[idx] ^= K; + } +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/rc4.h b/hardware-wallet/firmware/vendor/trezor-crypto/rc4.h new file mode 100644 index 00000000..7b56e4a3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/rc4.h @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2017 Saleem Rashid + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __RC4_H__ +#define __RC4_H__ + +#include +#include + +typedef struct { + uint8_t S[256]; + uint8_t i, j; +} RC4_CTX; + +void rc4_init(RC4_CTX *ctx, const uint8_t *key, size_t length); +void rc4_encrypt(RC4_CTX *ctx, uint8_t *buffer, size_t length); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.c b/hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.c new file mode 100644 index 00000000..ec808a7c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * Copyright (c) 2015 Jochen Hoenicke + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "rfc6979.h" +#include "hmac.h" +#include "memzero.h" + +void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *state) { + uint8_t bx[2*32]; + uint8_t buf[32 + 1 + 2*32]; + + memcpy(bx, priv_key, 32); + memcpy(bx+32, hash, 32); + + memset(state->v, 1, sizeof(state->v)); + memset(state->k, 0, sizeof(state->k)); + + memcpy(buf, state->v, sizeof(state->v)); + buf[sizeof(state->v)] = 0x00; + memcpy(buf + sizeof(state->v) + 1, bx, 64); + hmac_sha256(state->k, sizeof(state->k), buf, sizeof(buf), state->k); + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + + memcpy(buf, state->v, sizeof(state->v)); + buf[sizeof(state->v)] = 0x01; + memcpy(buf + sizeof(state->v) + 1, bx, 64); + hmac_sha256(state->k, sizeof(state->k), buf, sizeof(buf), state->k); + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + + memzero(bx, sizeof(bx)); + memzero(buf, sizeof(buf)); +} + +// generate next number from deterministic random number generator +void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state) +{ + uint8_t buf[32 + 1]; + + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + memcpy(buf, state->v, sizeof(state->v)); + buf[sizeof(state->v)] = 0x00; + hmac_sha256(state->k, sizeof(state->k), buf, sizeof(state->v) + 1, state->k); + hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v); + memcpy(rnd, buf, 32); + memzero(buf, sizeof(buf)); +} + +// generate K in a deterministic way, according to RFC6979 +// http://tools.ietf.org/html/rfc6979 +void generate_k_rfc6979(bignum256 *k, rfc6979_state *state) +{ + uint8_t buf[32]; + generate_rfc6979(buf, state); + bn_read_be(buf, k); + memzero(buf, sizeof(buf)); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.h b/hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.h new file mode 100644 index 00000000..e541d6ad --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/rfc6979.h @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * Copyright (c) 2015-2017 Jochen Hoenicke + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __RFC6979_H__ +#define __RFC6979_H__ + +#include +#include "bignum.h" + +// rfc6979 pseudo random number generator state +typedef struct { + uint8_t v[32], k[32]; +} rfc6979_state; + +void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *rng); +void generate_rfc6979(uint8_t rnd[32], rfc6979_state *rng); +void generate_k_rfc6979(bignum256 *k, rfc6979_state *rng); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.c b/hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.c new file mode 100644 index 00000000..66b13ca3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.c @@ -0,0 +1,343 @@ +/* + * RIPE MD-160 implementation + * + * Copyright (C) 2006-2015, 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 + * + * 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. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * The RIPEMD-160 algorithm was designed by RIPE in 1996 + * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html + * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 + */ + +#include + +#include "ripemd160.h" +#include "memzero.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (uint8_t) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (uint8_t) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (uint8_t) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (uint8_t) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +/* + * RIPEMD-160 context setup + */ +void ripemd160_Init(RIPEMD160_CTX *ctx) +{ + memset(ctx, 0, sizeof(RIPEMD160_CTX)); + ctx->total[0] = 0; + ctx->total[1] = 0; + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) +/* + * Process one block + */ +void ripemd160_process( RIPEMD160_CTX *ctx, const uint8_t data[RIPEMD160_BLOCK_LENGTH] ) +{ + uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + + A = Ap = ctx->state[0]; + B = Bp = ctx->state[1]; + C = Cp = ctx->state[2]; + D = Dp = ctx->state[3]; + E = Ep = ctx->state[4]; + +#define F1( x, y, z ) ( x ^ y ^ z ) +#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) +#define F3( x, y, z ) ( ( x | ~y ) ^ z ) +#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) +#define F5( x, y, z ) ( x ^ ( y | ~z ) ) + +#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) + +#define P( a, b, c, d, e, r, s, f, k ) \ + a += f( b, c, d ) + X[r] + k; \ + a = S( a, s ) + e; \ + c = S( c, 10 ); + +#define P2( a, b, c, d, e, r, s, rp, sp ) \ + P( a, b, c, d, e, r, s, F, K ); \ + P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); + +#define F F1 +#define K 0x00000000 +#define Fp F5 +#define Kp 0x50A28BE6 + P2( A, B, C, D, E, 0, 11, 5, 8 ); + P2( E, A, B, C, D, 1, 14, 14, 9 ); + P2( D, E, A, B, C, 2, 15, 7, 9 ); + P2( C, D, E, A, B, 3, 12, 0, 11 ); + P2( B, C, D, E, A, 4, 5, 9, 13 ); + P2( A, B, C, D, E, 5, 8, 2, 15 ); + P2( E, A, B, C, D, 6, 7, 11, 15 ); + P2( D, E, A, B, C, 7, 9, 4, 5 ); + P2( C, D, E, A, B, 8, 11, 13, 7 ); + P2( B, C, D, E, A, 9, 13, 6, 7 ); + P2( A, B, C, D, E, 10, 14, 15, 8 ); + P2( E, A, B, C, D, 11, 15, 8, 11 ); + P2( D, E, A, B, C, 12, 6, 1, 14 ); + P2( C, D, E, A, B, 13, 7, 10, 14 ); + P2( B, C, D, E, A, 14, 9, 3, 12 ); + P2( A, B, C, D, E, 15, 8, 12, 6 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F2 +#define K 0x5A827999 +#define Fp F4 +#define Kp 0x5C4DD124 + P2( E, A, B, C, D, 7, 7, 6, 9 ); + P2( D, E, A, B, C, 4, 6, 11, 13 ); + P2( C, D, E, A, B, 13, 8, 3, 15 ); + P2( B, C, D, E, A, 1, 13, 7, 7 ); + P2( A, B, C, D, E, 10, 11, 0, 12 ); + P2( E, A, B, C, D, 6, 9, 13, 8 ); + P2( D, E, A, B, C, 15, 7, 5, 9 ); + P2( C, D, E, A, B, 3, 15, 10, 11 ); + P2( B, C, D, E, A, 12, 7, 14, 7 ); + P2( A, B, C, D, E, 0, 12, 15, 7 ); + P2( E, A, B, C, D, 9, 15, 8, 12 ); + P2( D, E, A, B, C, 5, 9, 12, 7 ); + P2( C, D, E, A, B, 2, 11, 4, 6 ); + P2( B, C, D, E, A, 14, 7, 9, 15 ); + P2( A, B, C, D, E, 11, 13, 1, 13 ); + P2( E, A, B, C, D, 8, 12, 2, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F3 +#define K 0x6ED9EBA1 +#define Fp F3 +#define Kp 0x6D703EF3 + P2( D, E, A, B, C, 3, 11, 15, 9 ); + P2( C, D, E, A, B, 10, 13, 5, 7 ); + P2( B, C, D, E, A, 14, 6, 1, 15 ); + P2( A, B, C, D, E, 4, 7, 3, 11 ); + P2( E, A, B, C, D, 9, 14, 7, 8 ); + P2( D, E, A, B, C, 15, 9, 14, 6 ); + P2( C, D, E, A, B, 8, 13, 6, 6 ); + P2( B, C, D, E, A, 1, 15, 9, 14 ); + P2( A, B, C, D, E, 2, 14, 11, 12 ); + P2( E, A, B, C, D, 7, 8, 8, 13 ); + P2( D, E, A, B, C, 0, 13, 12, 5 ); + P2( C, D, E, A, B, 6, 6, 2, 14 ); + P2( B, C, D, E, A, 13, 5, 10, 13 ); + P2( A, B, C, D, E, 11, 12, 0, 13 ); + P2( E, A, B, C, D, 5, 7, 4, 7 ); + P2( D, E, A, B, C, 12, 5, 13, 5 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F4 +#define K 0x8F1BBCDC +#define Fp F2 +#define Kp 0x7A6D76E9 + P2( C, D, E, A, B, 1, 11, 8, 15 ); + P2( B, C, D, E, A, 9, 12, 6, 5 ); + P2( A, B, C, D, E, 11, 14, 4, 8 ); + P2( E, A, B, C, D, 10, 15, 1, 11 ); + P2( D, E, A, B, C, 0, 14, 3, 14 ); + P2( C, D, E, A, B, 8, 15, 11, 14 ); + P2( B, C, D, E, A, 12, 9, 15, 6 ); + P2( A, B, C, D, E, 4, 8, 0, 14 ); + P2( E, A, B, C, D, 13, 9, 5, 6 ); + P2( D, E, A, B, C, 3, 14, 12, 9 ); + P2( C, D, E, A, B, 7, 5, 2, 12 ); + P2( B, C, D, E, A, 15, 6, 13, 9 ); + P2( A, B, C, D, E, 14, 8, 9, 12 ); + P2( E, A, B, C, D, 5, 6, 7, 5 ); + P2( D, E, A, B, C, 6, 5, 10, 15 ); + P2( C, D, E, A, B, 2, 12, 14, 8 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F5 +#define K 0xA953FD4E +#define Fp F1 +#define Kp 0x00000000 + P2( B, C, D, E, A, 4, 9, 12, 8 ); + P2( A, B, C, D, E, 0, 15, 15, 5 ); + P2( E, A, B, C, D, 5, 5, 10, 12 ); + P2( D, E, A, B, C, 9, 11, 4, 9 ); + P2( C, D, E, A, B, 7, 6, 1, 12 ); + P2( B, C, D, E, A, 12, 8, 5, 5 ); + P2( A, B, C, D, E, 2, 13, 8, 14 ); + P2( E, A, B, C, D, 10, 12, 7, 6 ); + P2( D, E, A, B, C, 14, 5, 6, 8 ); + P2( C, D, E, A, B, 1, 12, 2, 13 ); + P2( B, C, D, E, A, 3, 13, 13, 6 ); + P2( A, B, C, D, E, 8, 14, 14, 5 ); + P2( E, A, B, C, D, 11, 11, 0, 15 ); + P2( D, E, A, B, C, 6, 8, 3, 13 ); + P2( C, D, E, A, B, 15, 5, 9, 11 ); + P2( B, C, D, E, A, 13, 6, 11, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + + C = ctx->state[1] + C + Dp; + ctx->state[1] = ctx->state[2] + D + Ep; + ctx->state[2] = ctx->state[3] + E + Ap; + ctx->state[3] = ctx->state[4] + A + Bp; + ctx->state[4] = ctx->state[0] + B + Cp; + ctx->state[0] = C; +} +#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ + +/* + * RIPEMD-160 process buffer + */ +void ripemd160_Update( RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen ) +{ + uint32_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = RIPEMD160_BLOCK_LENGTH - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + ripemd160_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= RIPEMD160_BLOCK_LENGTH ) + { + ripemd160_process( ctx, input ); + input += RIPEMD160_BLOCK_LENGTH; + ilen -= RIPEMD160_BLOCK_LENGTH; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +static const uint8_t ripemd160_padding[RIPEMD160_BLOCK_LENGTH] = +{ + 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 +}; + +/* + * RIPEMD-160 final digest + */ +void ripemd160_Final( RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH] ) +{ + 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_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + ripemd160_Update( ctx, ripemd160_padding, padn ); + ripemd160_Update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); + PUT_UINT32_LE( ctx->state[4], output, 16 ); + + memzero(ctx, sizeof(RIPEMD160_CTX)); +} + +/* + * output = RIPEMD-160( input buffer ) + */ +void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]) +{ + RIPEMD160_CTX ctx; + ripemd160_Init( &ctx ); + ripemd160_Update( &ctx, msg, msg_len ); + ripemd160_Final( &ctx, hash ); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.h b/hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.h new file mode 100644 index 00000000..a62de5cf --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/ripemd160.h @@ -0,0 +1,20 @@ +#ifndef __RIPEMD160_H__ +#define __RIPEMD160_H__ + +#include + +#define RIPEMD160_BLOCK_LENGTH 64 +#define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct _RIPEMD160_CTX { + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + uint8_t buffer[RIPEMD160_BLOCK_LENGTH]; /*!< data block being processed */ +} RIPEMD160_CTX; + +void ripemd160_Init(RIPEMD160_CTX *ctx); +void ripemd160_Update(RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen); +void ripemd160_Final(RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH]); +void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/script.c b/hardware-wallet/firmware/vendor/trezor-crypto/script.c new file mode 100644 index 00000000..ed6f821a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/script.c @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2016 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "base58.h" +#include "script.h" + +int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, int addrsize) +{ + uint8_t raw[35]; + + // P2PKH + if (scriptlen == 25 && script[0] == 0x76 && script[1] == 0xA9 && script[2] == 0x14 && script[23] == 0x88 && script[24] == 0xAC) { + raw[0] = 0x00; + memcpy(raw + 1, script + 3, 20); + return base58_encode_check(raw, 1 + 20, HASHER_SHA2, addr, addrsize); + } + + // P2SH + if (scriptlen == 23 && script[0] == 0xA9 && script[1] == 0x14 && script[22] == 0x87) { + raw[0] = 0x05; + memcpy(raw + 1, script + 2, 20); + return base58_encode_check(raw, 1 + 20, HASHER_SHA2, addr, addrsize); + } + + // P2WPKH + if (scriptlen == 22 && script[0] == 0x00 && script[1] == 0x14) { + raw[0] = 0x06; + raw[1] = 0x00; + raw[2] = 0x00; + memcpy(raw + 3, script + 2, 20); + return base58_encode_check(raw, 3 + 20, HASHER_SHA2, addr, addrsize); + } + + // P2WSH + if (scriptlen == 34 && script[0] == 0x00 && script[1] == 0x20) { + raw[0] = 0x0A; + raw[1] = 0x00; + raw[2] = 0x00; + memcpy(raw + 3, script + 2, 32); + return base58_encode_check(raw, 3 + 32, HASHER_SHA2, addr, addrsize); + } + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/script.h b/hardware-wallet/firmware/vendor/trezor-crypto/script.h new file mode 100644 index 00000000..9544bf7c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/script.h @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2016 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __SCRIPT_H__ +#define __SCRIPT_H__ + +#include + +int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, int addrsize); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.c b/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.c new file mode 100644 index 00000000..155d2c17 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.c @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "secp256k1.h" + +const ecdsa_curve secp256k1 = { + /* .prime */ { + /*.val =*/ {0x3ffffc2f, 0x3ffffffb, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff} + }, + + /* G */ { + /*.x =*/{/*.val =*/{0x16f81798, 0x27ca056c, 0x1ce28d95, 0x26ff36cb, 0x70b0702, 0x18a573a, 0xbbac55a, 0x199fbe77, 0x79be}}, + /*.y =*/{/*.val =*/{0x3b10d4b8, 0x311f423f, 0x28554199, 0x5ed1229, 0x1108a8fd, 0x13eff038, 0x3c4655da, 0x369dc9a8, 0x483a}} + }, + + /* order */ { + /*.val =*/{0x10364141, 0x3f497a33, 0x348a03bb, 0x2bb739ab, 0x3ffffeba, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff} + }, + + /* order_half */ { + /*.val =*/{0x281b20a0, 0x3fa4bd19, 0x3a4501dd, 0x15db9cd5, 0x3fffff5d, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x7fff} + }, + + /* a */ 0, + + /* b */ { + /*.val =*/{7} + } + +#if USE_PRECOMPUTED_CP + , + /* cp */ { +#include "secp256k1.table" + } +#endif +}; + +const curve_info secp256k1_info = { + .bip32_name = "Bitcoin seed", + .params = &secp256k1, + .hasher_type = HASHER_SHA2, +}; + +const curve_info secp256k1_decred_info = { + .bip32_name = "Decred seed", + .params = &secp256k1, + .hasher_type = HASHER_BLAKE, +}; diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.h b/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.h new file mode 100644 index 00000000..803cde26 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.h @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 __SECP256K1_H__ +#define __SECP256K1_H__ + +#include + +#include "ecdsa.h" +#include "bip32.h" + +extern const ecdsa_curve secp256k1; +extern const curve_info secp256k1_info; +extern const curve_info secp256k1_decred_info; + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.table b/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.table new file mode 100644 index 00000000..9fd3c728 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/secp256k1.table @@ -0,0 +1,1664 @@ + { + /* 1*16^0*G: */ + {{{0x16f81798, 0x27ca056c, 0x1ce28d95, 0x26ff36cb, 0x070b0702, 0x018a573a, 0x0bbac55a, 0x199fbe77, 0x79be}}, + {{0x3b10d4b8, 0x311f423f, 0x28554199, 0x05ed1229, 0x1108a8fd, 0x13eff038, 0x3c4655da, 0x369dc9a8, 0x483a}}}, + /* 3*16^0*G: */ + {{{0x3ce036f9, 0x1807c44e, 0x36f99b08, 0x0c721160, 0x1d5229b5, 0x113e17e2, 0x0c310493, 0x22806496, 0xf930}}, + {{0x04b8e672, 0x32e7f5d6, 0x0c2231b6, 0x002a664d, 0x37f35665, 0x0cdf98a8, 0x1e8140fe, 0x1ec3d8cb, 0x388f}}}, + /* 5*16^0*G: */ + {{{0x3240efe4, 0x2ea355a6, 0x0619ab7c, 0x22e12f77, 0x1c5128e8, 0x129c9429, 0x3209355b, 0x37934681, 0x2f8b}}, + {{0x26ac62d6, 0x32a1f4ea, 0x30d6840d, 0x2209c6ea, 0x09c426f7, 0x2ea7769b, 0x1e3d6d4d, 0x08898db9, 0xd8ac}}}, + /* 7*16^0*G: */ + {{{0x0ac4f9bc, 0x24af77b7, 0x330e39ce, 0x1066df80, 0x2a7a0e3d, 0x23cd97cb, 0x1b4eaa39, 0x3c191b97, 0x5cbd}}, + {{0x087264da, 0x142098a0, 0x3fde7b5a, 0x04f42e04, 0x1a54dba8, 0x1e35b618, 0x15960a31, 0x32902e89, 0x6aeb}}}, + /* 9*16^0*G: */ + {{{0x3c27ccbe, 0x0d7c4437, 0x057e714c, 0x25e5a5d3, 0x159abde0, 0x345e2a7d, 0x3f65309a, 0x2138bc31, 0xacd4}}, + {{0x064f9c37, 0x173098ab, 0x35f8e0f0, 0x3622290d, 0x3b61e9ad, 0x2025c5d8, 0x3d9fd643, 0x22486c29, 0xcc33}}}, + /* 11*16^0*G: */ + {{{0x1da008cb, 0x2fb05e25, 0x1c17891b, 0x126602f9, 0x065aac56, 0x1091adc3, 0x1411e5ef, 0x39fe162a, 0x774a}}, + {{0x0953c61b, 0x0075d327, 0x3f9d6a83, 0x0b6c78b7, 0x37b36537, 0x0f755b5e, 0x35e19024, 0x280cbada, 0xd984}}}, + /* 13*16^0*G: */ + {{{0x19405aa8, 0x3bb77e3c, 0x10e58cdd, 0x1d7ef198, 0x348651b0, 0x0748170d, 0x1288bc7d, 0x1cf0b65d, 0xf287}}, + {{0x1b03ed81, 0x26d72d4b, 0x21fa91f2, 0x0681b694, 0x0daf473a, 0x084bad97, 0x00a89758, 0x240ba362, 0x0ab0}}}, + /* 15*16^0*G: */ + {{{0x227e080e, 0x12b6f3e3, 0x085f79e4, 0x39651bcf, 0x1ff41131, 0x196b8c25, 0x3ea965a4, 0x1353df50, 0xd792}}, + {{0x36a26b58, 0x1413727f, 0x096d3a5c, 0x102bcaf6, 0x0c6defea, 0x10bb08a3, 0x072a6838, 0x0a1caa1b, 0x581e}}} + }, + { + /* 1*16^1*G: */ + {{{0x2a6dec0a, 0x113ba278, 0x07a5ae9c, 0x28c4da6e, 0x023e97b2, 0x06aaf087, 0x29ec5301, 0x33a4ed67, 0xe60f}}, + {{0x29616821, 0x07ccb339, 0x0d23f0be, 0x25a24791, 0x39371012, 0x267cd3d5, 0x195929db, 0x141ce679, 0xf7e3}}}, + /* 3*16^1*G: */ + {{{0x1118e5c3, 0x2f61c2a8, 0x12bebc19, 0x15e6c9d1, 0x265b4bfc, 0x0595bbd3, 0x1307db44, 0x0cd76591, 0x6eca}}, + {{0x05a08668, 0x2628bde0, 0x3f8ec344, 0x125a8e8e, 0x3875a03a, 0x3d5e41d2, 0x20710592, 0x08ed5e9e, 0xd501}}}, + /* 5*16^1*G: */ + {{{0x0f87f62e, 0x3b34c785, 0x37161270, 0x39b98e18, 0x0659f010, 0x31d13b4d, 0x390ec0d7, 0x0eefbc6f, 0xe962}}, + {{0x244ee737, 0x0c04fabe, 0x168844e5, 0x1810f277, 0x1aa929fe, 0x3a54ea3b, 0x299e9e0f, 0x1d0ed2f0, 0x38a9}}}, + /* 7*16^1*G: */ + {{{0x2a8d733c, 0x2c2ab7e0, 0x2fca8f9e, 0x309d2fd8, 0x00d682ff, 0x128dbc82, 0x21dba088, 0x375cf945, 0xbc82}}, + {{0x347797f0, 0x39e18413, 0x33897301, 0x24e82eb9, 0x1f02dfae, 0x26d2fdc6, 0x31cac54a, 0x230e8112, 0xe5f2}}}, + /* 9*16^1*G: */ + {{{0x1fbc7671, 0x1fbf88c5, 0x2858e32d, 0x0fc6f214, 0x18f49074, 0x0a47385e, 0x17211d20, 0x049231d9, 0x8e3d}}, + {{0x18717dec, 0x3bc77190, 0x23e144a7, 0x0d4aeaa9, 0x13e90eb9, 0x1203864e, 0x3cb81f64, 0x123843b3, 0x099a}}}, + /* 11*16^1*G: */ + {{{0x3eb31db2, 0x0ca1d0ca, 0x0f506a0f, 0x32ba09e2, 0x08a2b68f, 0x2864fb42, 0x0a498896, 0x246a888d, 0x78a8}}, + {{0x39fa4343, 0x01a7588e, 0x000b82d3, 0x0de6f376, 0x302df654, 0x17c9549c, 0x035cbfcf, 0x28d6fad4, 0x6912}}}, + /* 13*16^1*G: */ + {{{0x0db0e595, 0x14d23dde, 0x3a082bb6, 0x058f2e7e, 0x2076eba7, 0x38dd9605, 0x31b17d7c, 0x1e061576, 0x7d86}}, + {{0x3c733de8, 0x265478ea, 0x225d5329, 0x0de11383, 0x0f883829, 0x18b8afb5, 0x2f8772e5, 0x26b7fb21, 0xe2b9}}}, + /* 15*16^1*G: */ + {{{0x16060dfc, 0x023fbe14, 0x05e6a2a0, 0x1517e108, 0x1ab08676, 0x252e7710, 0x02ac8484, 0x0c43c016, 0xddc5}}, + {{0x27820ca8, 0x2d7e2adb, 0x3d04730f, 0x36ebf1aa, 0x0f0e9041, 0x06adb732, 0x19692019, 0x0bcebc83, 0xba0d}}} + }, + { + /* 1*16^2*G: */ + {{{0x15f51508, 0x191b88ff, 0x1ac1ca10, 0x30e72af5, 0x2de238d8, 0x29b8f85c, 0x209d9ea2, 0x098c84b1, 0x8282}}, + {{0x36e26caf, 0x0c6dbabf, 0x37b17bed, 0x3584eb0b, 0x360ace62, 0x095ba0c2, 0x3dfe45e8, 0x2a026155, 0x11f8}}}, + /* 3*16^2*G: */ + {{{0x257e8dfa, 0x33f032e7, 0x3c7e184f, 0x20246468, 0x298ca009, 0x28c3e2b2, 0x19c4c0d9, 0x33cbfc1e, 0x8262}}, + {{0x3bac376a, 0x173fe363, 0x314c4783, 0x2dbb4cca, 0x334f3457, 0x3b88bb16, 0x09e4e66f, 0x25788244, 0x83fd}}}, + /* 5*16^2*G: */ + {{{0x026bdb6f, 0x014b922c, 0x3734b949, 0x2906f51e, 0x299c877c, 0x0416c933, 0x0ddd5168, 0x1722c768, 0x1982}}, + {{0x049cfc9b, 0x177dc213, 0x0f6d3a6b, 0x3a7bb323, 0x359f6ceb, 0x09873253, 0x0878f320, 0x0c43c353, 0x6294}}}, + /* 7*16^2*G: */ + {{{0x3d82824c, 0x03b42548, 0x21534e65, 0x29638d17, 0x02999edf, 0x17d5bb1b, 0x0191443c, 0x361b0458, 0x6f12}}, + {{0x06eb34d0, 0x15e70d20, 0x054bc5b8, 0x07249042, 0x22376939, 0x2653cff5, 0x3bfa0875, 0x3dfd12ac, 0x5c4f}}}, + /* 9*16^2*G: */ + {{{0x1b453629, 0x1db7700b, 0x359e6030, 0x33f73703, 0x3abef645, 0x189c5a88, 0x2aa5d142, 0x231be682, 0x203a}}, + {{0x3ff89f84, 0x25c71e14, 0x1285ed45, 0x1b7ac971, 0x01061268, 0x31db457d, 0x1d9b936c, 0x02d4f797, 0x3b0f}}}, + /* 11*16^2*G: */ + {{{0x246c7ecb, 0x20c4c377, 0x1bb4ce97, 0x0ebb4ff9, 0x26e1ec9d, 0x3bdccd21, 0x34181c81, 0x32bacf40, 0x6e2a}}, + {{0x2ebc8720, 0x1124807b, 0x367512c8, 0x31c1ae46, 0x3b643afa, 0x03136bc3, 0x3ee149d8, 0x2919e5fb, 0x9e61}}}, + /* 13*16^2*G: */ + {{{0x30a4147e, 0x2dc063cf, 0x375f201e, 0x11f762fd, 0x090a5827, 0x05c5fa29, 0x1156baf6, 0x0124ba7a, 0xd5a7}}, + {{0x33fb65ff, 0x392cf2e0, 0x167f57f8, 0x3136611e, 0x1e0532f4, 0x242641d9, 0x389c6fc4, 0x09bd76ea, 0x9db5}}}, + /* 15*16^2*G: */ + {{{0x18edcec6, 0x3b76d1af, 0x3634f454, 0x018730b4, 0x2cdac6a1, 0x0fbf18c0, 0x18ba8052, 0x0466aaf8, 0x38c5}}, + {{0x1933db08, 0x15b82fec, 0x35530a64, 0x285b208a, 0x1f282f28, 0x32cb689d, 0x1732a668, 0x3748a176, 0xe649}}} + }, + { + /* 1*16^3*G: */ + {{{0x11e5b739, 0x0ff396d5, 0x12222ed7, 0x2e4e0cff, 0x3c846de0, 0x26731b1b, 0x3865a72f, 0x0567dca2, 0x175e}}, + {{0x29fed695, 0x3be9bffb, 0x124345c6, 0x2d6556b7, 0x371f5eac, 0x3e5e947f, 0x079eba4e, 0x1b83678f, 0xd350}}}, + /* 3*16^3*G: */ + {{{0x05041216, 0x16dfe3c7, 0x02b836a6, 0x1ccd7da1, 0x2fed523f, 0x2d67bf70, 0x3acf4128, 0x0c5ec87d, 0xda75}}, + {{0x2e708572, 0x2bb4ca61, 0x37acedad, 0x2ab01eb9, 0x2d7fc6e9, 0x27886cd0, 0x2d5f0df1, 0x2811afdc, 0x73f8}}}, + /* 5*16^3*G: */ + {{{0x2465a930, 0x0050f9c7, 0x31352fdb, 0x21fc705a, 0x02eb1e25, 0x0f16312a, 0x349d7057, 0x316d23a5, 0x1c71}}, + {{0x034638b5, 0x361cfdb3, 0x3174d471, 0x0d178fed, 0x0bb68c79, 0x0fc7ca09, 0x1fa0c271, 0x30cd3a3d, 0x4a91}}}, + /* 7*16^3*G: */ + {{{0x3adb6ee7, 0x0c636b96, 0x344a077e, 0x143750c9, 0x1b4c9c78, 0x3a0dea42, 0x1a566936, 0x12bf07cc, 0xd84e}}, + {{0x142ebed2, 0x0b555b9b, 0x2a3e6498, 0x362b25d2, 0x25de4dfd, 0x0e3563d5, 0x379ce12a, 0x20269f1e, 0xe525}}}, + /* 9*16^3*G: */ + {{{0x249e6d10, 0x253a7b3e, 0x2ac99d23, 0x02b7fceb, 0x3f6ed3f6, 0x08ae4a17, 0x2814d41b, 0x1112f799, 0xf3d4}}, + {{0x1347da3f, 0x280e3301, 0x29d6c630, 0x06b69433, 0x0a4b5bfc, 0x2e56b066, 0x0163d4ba, 0x0937e9bc, 0x0a43}}}, + /* 11*16^3*G: */ + {{{0x29d33a07, 0x232cd01b, 0x239bcab4, 0x1cbb822a, 0x3df4044e, 0x21548336, 0x01d89f90, 0x194b2767, 0xae30}}, + {{0x20a0b2a6, 0x121c303d, 0x3d7e95c7, 0x270dfd77, 0x38d5cf1c, 0x339f4cf6, 0x3fe57efc, 0x3670e358, 0x6cb9}}}, + /* 13*16^3*G: */ + {{{0x0c28caca, 0x165952e4, 0x08281da7, 0x1a71eef3, 0x388c9a18, 0x05f9d60c, 0x1e1c815e, 0x06ca96f5, 0xd8dc}}, + {{0x23b3ec7a, 0x36d9dba8, 0x08128f6c, 0x0c574b3b, 0x247d947d, 0x36369080, 0x2c7d58c6, 0x02b649f3, 0x8cec}}}, + /* 15*16^3*G: */ + {{{0x3bc4416f, 0x2487ed98, 0x30b04028, 0x2bbf48fc, 0x32f31da7, 0x1096a340, 0x04eccd59, 0x38a4b17e, 0x2749}}, + {{0x3c6bbd8e, 0x3a62f78b, 0x2e961057, 0x27a7ed97, 0x0adb3ef5, 0x3652643f, 0x32bc4403, 0x0b538dd9, 0x50cc}}} + }, + { + /* 1*16^4*G: */ + {{{0x03ff4640, 0x09aeb63e, 0x1552ffe5, 0x11071f95, 0x262ee053, 0x3ab016d8, 0x00c9c99c, 0x243511ec, 0x363d}}, + {{0x3bee9de9, 0x0800f1fc, 0x0199ecb6, 0x2e6a2402, 0x33363145, 0x2d114e5f, 0x32221953, 0x1ceb7f1c, 0x04e2}}}, + /* 3*16^4*G: */ + {{{0x36e55dc8, 0x2e24485b, 0x2ca04394, 0x3e56adba, 0x1094426f, 0x12910301, 0x1ffb2ba8, 0x1011e431, 0x4431}}, + {{0x1be323b3, 0x076512bb, 0x2aa2e503, 0x1a8a6de7, 0x02fed7a6, 0x260dfd59, 0x366f8fe9, 0x3050b994, 0x96b0}}}, + /* 5*16^4*G: */ + {{{0x301b23a8, 0x3fa52175, 0x287ee0ad, 0x1edf51c2, 0x21089dab, 0x090f56e4, 0x0a87c126, 0x3fa3619b, 0x9e22}}, + {{0x0884edae, 0x1e904f14, 0x3511cecf, 0x3df2527e, 0x1c1533c0, 0x3cfc0826, 0x22d10177, 0x3c3a7284, 0xfd2f}}}, + /* 7*16^4*G: */ + {{{0x071a70e4, 0x35d022fc, 0x35cf475d, 0x17b947d7, 0x05306dcd, 0x35a7991c, 0x22a8d2ed, 0x3db540f3, 0x508d}}, + {{0x29950984, 0x3cb96fdc, 0x28aadfed, 0x300c8a3b, 0x3e49c54e, 0x0c12a9cc, 0x3c42d777, 0x10e6e4ce, 0x154c}}}, + /* 9*16^4*G: */ + {{{0x0e1abe11, 0x3abf69db, 0x1cb220f6, 0x2e487096, 0x0125b2da, 0x37d6064c, 0x09763338, 0x3fe11544, 0xe3db}}, + {{0x1fa8de63, 0x2d26b552, 0x06b5c414, 0x325f640f, 0x0a8ef3d3, 0x23e9d76e, 0x01421643, 0x3e42668d, 0x06f2}}}, + /* 11*16^4*G: */ + {{{0x03593449, 0x33c6c8d8, 0x02a46ffd, 0x06df04b9, 0x3d014af6, 0x36704e81, 0x2940d878, 0x381931f7, 0x19ac}}, + {{0x2df83631, 0x29052e4e, 0x084068a3, 0x1c42e7d0, 0x002c46ac, 0x2f5ce765, 0x0a333bfe, 0x2480d49a, 0xe379}}}, + /* 13*16^4*G: */ + {{{0x0cba6b63, 0x38fa624b, 0x10b3bb5e, 0x03f99d3f, 0x288e310a, 0x30cc8a3a, 0x07daa108, 0x033b083e, 0xd874}}, + {{0x2934c5f3, 0x3ba8db01, 0x381694ab, 0x0413d730, 0x3ac37d40, 0x29bba640, 0x132bf378, 0x304cf1ae, 0x6472}}}, + /* 15*16^4*G: */ + {{{0x1b3ec038, 0x0653fcb0, 0x20c6b276, 0x3f545ab9, 0x290a50d9, 0x20f9d8bc, 0x06083648, 0x0cce46d4, 0x58ac}}, + {{0x10246279, 0x1baa8fc4, 0x34fbbca1, 0x06410f02, 0x11fe9702, 0x1e4927a6, 0x092d9787, 0x35c1b557, 0x9163}}} + }, + { + /* 1*16^5*G: */ + {{{0x1ffdf80c, 0x27de6957, 0x15bcd1b6, 0x3929e068, 0x05638843, 0x0912d6dd, 0x3c2be8c6, 0x17c5977c, 0x8b4b}}, + {{0x1fd4fd36, 0x0fbfc319, 0x162ee56b, 0x38cd9518, 0x30da04f9, 0x2f5e04ea, 0x308b4b3f, 0x029bda34, 0x4aad}}}, + /* 3*16^5*G: */ + {{{0x355812dd, 0x028a960b, 0x12d30e2a, 0x1119c8d5, 0x18f78e3d, 0x2afb5b01, 0x3352f0b6, 0x2f5ea4bf, 0x7029}}, + {{0x1a2d2927, 0x087319ac, 0x3b2c73c7, 0x36ba1090, 0x0683ac47, 0x19512b8c, 0x0b3d27dd, 0x3eb6bf7a, 0xb0ee}}}, + /* 5*16^5*G: */ + {{{0x3d486ed1, 0x27395a0e, 0x1565b6a4, 0x116fae92, 0x0f756057, 0x35042763, 0x25c99009, 0x3b72bab9, 0x9ccf}}, + {{0x35e95d8d, 0x3db567b5, 0x1592aa24, 0x0859d65a, 0x0b341124, 0x08920480, 0x232cfb61, 0x135c4f5a, 0x7c2f}}}, + /* 7*16^5*G: */ + {{{0x1bd0eaca, 0x081ac69d, 0x22d4ab7a, 0x31d15dae, 0x24df19d0, 0x23f78cf2, 0x1414335a, 0x12e1d8d0, 0xcd9a}}, + {{0x2bff4acc, 0x39bebed6, 0x16f634f6, 0x09ece3bb, 0x3ea08b01, 0x1222ba4c, 0x0f23e815, 0x161e687a, 0xf045}}}, + /* 9*16^5*G: */ + {{{0x07bc57c6, 0x08254e8f, 0x2b276cbf, 0x00f5e88f, 0x16309449, 0x3cb4ba4f, 0x19bea884, 0x220be23b, 0xad09}}, + {{0x2e4a0ab8, 0x28cb03b6, 0x190e2d3c, 0x0c474dcd, 0x1abe5f7b, 0x061b1ca7, 0x3a52ba28, 0x302310be, 0x7243}}}, + /* 11*16^5*G: */ + {{{0x2ba56302, 0x2a0c31ca, 0x30f1862e, 0x01aa4deb, 0x3ad2e0f5, 0x368b4aa7, 0x0a41f1ea, 0x0a42bacf, 0xd9d1}}, + {{0x08291c29, 0x2ab76bea, 0x3a74f2ae, 0x0e6bb367, 0x2386e417, 0x1c5719c9, 0x13eed029, 0x0c44fb0b, 0x7eb5}}}, + /* 13*16^5*G: */ + {{{0x34d1243a, 0x2b34dc13, 0x354a5fdb, 0x2c49808f, 0x3f558402, 0x3486b018, 0x16cef91c, 0x1e7794e7, 0xbc50}}, + {{0x055db68a, 0x172545a2, 0x1f47169f, 0x1fb93d6c, 0x3fc8d75f, 0x31cae537, 0x05cbb8ee, 0x0a8ece9c, 0x6506}}}, + /* 15*16^5*G: */ + {{{0x374a3f9f, 0x2349139a, 0x00981690, 0x21e99977, 0x32625ac2, 0x37aab9f6, 0x3c7e8913, 0x29df9417, 0x4d31}}, + {{0x301e0ba7, 0x3f2c0904, 0x2e00a754, 0x3dbed46d, 0x002753cb, 0x063ce31e, 0x0575b06b, 0x07b25826, 0x2224}}} + }, + { + /* 1*16^6*G: */ + {{{0x1232fcda, 0x2d845649, 0x2c0e77bc, 0x0036ffe9, 0x1548c7b7, 0x1dc7002f, 0x3996d6bf, 0x2ea9b976, 0x723c}}, + {{0x1eb39f5f, 0x07701a76, 0x37949480, 0x1828194d, 0x024d6e26, 0x044dd222, 0x0c498a92, 0x19ed5657, 0x96e8}}}, + /* 3*16^6*G: */ + {{{0x00633cb1, 0x159f827a, 0x1d021132, 0x168892da, 0x181fcb57, 0x189cc848, 0x2cad400c, 0x273cc5ea, 0x6dde}}, + {{0x27ce6b34, 0x1f7526a9, 0x3859ef35, 0x2c9ff6b3, 0x3a66a880, 0x27be1a86, 0x3e41d5c9, 0x3ef9e9c1, 0x9188}}}, + /* 5*16^6*G: */ + {{{0x2933f3c5, 0x06694634, 0x1f125224, 0x1683dc45, 0x07b85008, 0x12edfe39, 0x1cde813c, 0x29cb356d, 0x486f}}, + {{0x0afb0f53, 0x2b529c6b, 0x30f23b79, 0x366de0f3, 0x08f19f62, 0x3122ebb3, 0x3dd43e48, 0x08c67d5a, 0x62e1}}}, + /* 7*16^6*G: */ + {{{0x1e99f728, 0x2f565089, 0x2f12204e, 0x1cdd7ef9, 0x2a530367, 0x13fc9edd, 0x0af4fb66, 0x1a5d2a25, 0x2479}}, + {{0x2baaebff, 0x1e80145b, 0x175a2d83, 0x36fcf025, 0x0d664a5a, 0x0ba1f9f6, 0x33001ec5, 0x23511a23, 0xe3d7}}}, + /* 9*16^6*G: */ + {{{0x2fb0079a, 0x27831b50, 0x3926049c, 0x1be7bdc8, 0x33832491, 0x2967b9da, 0x15ff0631, 0x32f6a8f5, 0x2f39}}, + {{0x2c5690ba, 0x388a5cc0, 0x02a0230f, 0x3ecfef22, 0x0da58b9b, 0x24db409e, 0x239834da, 0x36f784e1, 0xabea}}}, + /* 11*16^6*G: */ + {{{0x24f7ab73, 0x24cc02cb, 0x14443a77, 0x38f53aa7, 0x34aed262, 0x0e7a1b14, 0x161ba56a, 0x075b0c9f, 0xe5a3}}, + {{0x30561f42, 0x244e8ff1, 0x00cba213, 0x2311126a, 0x0ece5dbf, 0x062a5de9, 0x29d7a0c1, 0x230f6347, 0x3778}}}, + /* 13*16^6*G: */ + {{{0x014dcd86, 0x23e4a68f, 0x2bf71b58, 0x31750825, 0x11dcf11f, 0x03766081, 0x13447df5, 0x27528345, 0xcc38}}, + {{0x08f0a873, 0x23adb767, 0x27e78746, 0x315f863f, 0x2910ca05, 0x1a2f6efa, 0x2bbed9b5, 0x13f5983d, 0x93ae}}}, + /* 15*16^6*G: */ + {{{0x38819311, 0x13e71bad, 0x08771472, 0x0f87b884, 0x35ed1f0b, 0x0285f833, 0x1e902375, 0x2472275c, 0x7f92}}, + {{0x2c2eb125, 0x2a7e6d5e, 0x086a174a, 0x02aa9027, 0x2415b612, 0x037a3114, 0x03ef0f5d, 0x034418fb, 0x9da0}}} + }, + { + /* 1*16^7*G: */ + {{{0x0e7dd7fa, 0x294cfb28, 0x3a919839, 0x11e5848d, 0x02d3b509, 0x3fbb204b, 0x2bf98ba5, 0x293524ef, 0xeebf}}, + {{0x21de8999, 0x37f53f6b, 0x311f712d, 0x393370e9, 0x38089d9a, 0x39fb6bc5, 0x2f0f269e, 0x2328e5c3, 0x5d9a}}}, + /* 3*16^7*G: */ + {{{0x3b7ceceb, 0x0fd9e3fe, 0x097faf0f, 0x2967e4e2, 0x2e681473, 0x3ee049bd, 0x2d45036f, 0x2188109d, 0x437a}}, + {{0x16c181e1, 0x0d8ef30d, 0x08f97827, 0x0883f3f7, 0x1297ff87, 0x23fada67, 0x2c32f69b, 0x1ae84fba, 0x0b91}}}, + /* 5*16^7*G: */ + {{{0x097f96f2, 0x1635ca78, 0x2c8735cd, 0x208d4a74, 0x3cc27335, 0x2df8ee68, 0x089bc83c, 0x27c4f8a9, 0xa9ef}}, + {{0x16c04be4, 0x00f556c1, 0x29b4702c, 0x13e26bd6, 0x3b613db7, 0x1bb8583a, 0x19d7cd95, 0x33396515, 0xe814}}}, + /* 7*16^7*G: */ + {{{0x350cf77e, 0x302ad684, 0x0a8ab0db, 0x36fd5d15, 0x2a064207, 0x209f5a7e, 0x135be553, 0x01507b87, 0x66d8}}, + {{0x20eaa3a6, 0x297e5ebe, 0x3b1b76d2, 0x112d0ead, 0x1613f694, 0x0750814d, 0x3fb42c3f, 0x37f9ccbf, 0x51cf}}}, + /* 9*16^7*G: */ + {{{0x07213a5a, 0x0d5218a2, 0x05fa62b9, 0x1cc8129e, 0x0cc3c80b, 0x14228719, 0x03fa2bf3, 0x01784d94, 0x62ac}}, + {{0x346a9e45, 0x04348703, 0x17994efc, 0x16424060, 0x292579e5, 0x179e781e, 0x1a6e4d39, 0x2f7ce834, 0x236f}}}, + /* 11*16^7*G: */ + {{{0x27bad12b, 0x0c3f5261, 0x2f66e1ec, 0x357a803a, 0x2f2db385, 0x184ebd71, 0x08f5b5bf, 0x31125c91, 0xca13}}, + {{0x1723b0f2, 0x25a67d1a, 0x1a575668, 0x1c2adc44, 0x2da3d663, 0x17e993aa, 0x287c8ac1, 0x0260d870, 0x83aa}}}, + /* 13*16^7*G: */ + {{{0x1c80414e, 0x36bb97e5, 0x166cf7fd, 0x3be2a18b, 0x209e4914, 0x04713d11, 0x12ae85ac, 0x2c4069c1, 0x1cec}}, + {{0x12169a3b, 0x32ba524b, 0x07231d0d, 0x1d55f951, 0x2dad1690, 0x2a8ca0d7, 0x17cfb4e5, 0x1819a582, 0xf343}}}, + /* 15*16^7*G: */ + {{{0x0ed810a9, 0x13d6f231, 0x0700155c, 0x22274fcf, 0x1f23924f, 0x036bd7c7, 0x38f9cc95, 0x241d4135, 0x2a69}}, + {{0x3a9b4728, 0x3e1ace23, 0x2c145c7c, 0x1f51fa5f, 0x3b04fc66, 0x3161a553, 0x1ffdac3e, 0x00e6db0f, 0x54f9}}} + }, + { + /* 1*16^8*G: */ + {{{0x39a48db0, 0x3f5e0d6c, 0x33c03bfe, 0x048568a6, 0x3bde459f, 0x0742826d, 0x27167279, 0x11369a5b, 0x100f}}, + {{0x2bc65a09, 0x3ef57358, 0x35195ac0, 0x3fd2863f, 0x090666b7, 0x23ccc030, 0x00b772ec, 0x384c64a8, 0xcdd9}}}, + /* 3*16^8*G: */ + {{{0x15bc15b4, 0x32e684d2, 0x25a2ee69, 0x1d40a391, 0x17ca8d92, 0x163ba73b, 0x2adc9ed8, 0x038b947b, 0x10e9}}, + {{0x18aa258d, 0x13af9825, 0x2bb6a883, 0x296258c0, 0x2d1f754c, 0x1ea3185a, 0x1e0424d5, 0x0dc0e035, 0xc68a}}}, + /* 5*16^8*G: */ + {{{0x3fe75269, 0x374ff0c0, 0x13d33182, 0x1de8f301, 0x0b7dcda3, 0x16e42dc5, 0x01638457, 0x0bd0b695, 0xf742}}, + {{0x17e49bd5, 0x22603a1c, 0x0a398e01, 0x2ce88dfd, 0x3635977f, 0x339f72e7, 0x3093fd18, 0x0bc68cc4, 0x406c}}}, + /* 7*16^8*G: */ + {{{0x35a7175f, 0x14ed9a5b, 0x31cf42a6, 0x2e39dc74, 0x15debbed, 0x1e69560b, 0x03cff728, 0x2b4105f5, 0x2d8c}}, + {{0x3b9d592a, 0x3cdeee46, 0x0b5e5e0c, 0x211aff67, 0x2c9d377a, 0x08cbe984, 0x0a94a7bb, 0x0ee0cc63, 0xc73f}}}, + /* 9*16^8*G: */ + {{{0x14b51045, 0x0d326f0e, 0x31c25b3e, 0x31b225bc, 0x28cf73bb, 0x1cf53ac7, 0x26ea58ae, 0x3f476e62, 0x1ecb}}, + {{0x02c70026, 0x0e99c404, 0x036422d5, 0x240191ad, 0x1a9b38b1, 0x342ec612, 0x1c3a6447, 0x388c22e6, 0x1cf6}}}, + /* 11*16^8*G: */ + {{{0x29358533, 0x1eb35d9b, 0x0fb4b9df, 0x2a4cfe75, 0x132a8c10, 0x25568a47, 0x3752883e, 0x25317f95, 0x9a08}}, + {{0x0360ba08, 0x2cf87177, 0x380ddadf, 0x29b96f6e, 0x0fc32165, 0x05f57e55, 0x38fc31f9, 0x20f10806, 0xa798}}}, + /* 13*16^8*G: */ + {{{0x198ef7f6, 0x25101758, 0x2078f9f6, 0x08fcfdde, 0x38aea659, 0x272149ce, 0x3d2e35bd, 0x361276d3, 0x664d}}, + {{0x1d1eac94, 0x1d25bfcd, 0x38e6ecee, 0x0f4eacc6, 0x0458cffc, 0x12339774, 0x27932a14, 0x0805c5fc, 0xad51}}}, + /* 15*16^8*G: */ + {{{0x03c934b3, 0x03029adf, 0x30ae2c4e, 0x0c7d6016, 0x11a7022b, 0x07659a60, 0x0b863823, 0x0ea4ddf4, 0x8211}}, + {{0x042c6a0f, 0x1f9798ab, 0x24468037, 0x07df09a6, 0x20c628aa, 0x19b3cad6, 0x23666084, 0x2e36b26b, 0x8da1}}} + }, + { + /* 1*16^9*G: */ + {{{0x2534fd2d, 0x322b379b, 0x0f3b3852, 0x1fe35119, 0x04c017a7, 0x2489e928, 0x3ed1b1dc, 0x06f898b1, 0xe103}}, + {{0x1456a00d, 0x113c63ca, 0x21ced79a, 0x24b75067, 0x17535af2, 0x1a905d96, 0x0405e6bb, 0x1864a250, 0x9d70}}}, + /* 3*16^9*G: */ + {{{0x2f028d83, 0x1e588ebb, 0x27439615, 0x25649b6e, 0x1e69db61, 0x2af96857, 0x385ec6a5, 0x3df138f1, 0xa7eb}}, + {{0x19d0bed1, 0x1900e4ae, 0x30539199, 0x28e249d2, 0x04804b47, 0x271cddc1, 0x362d5cfd, 0x054beff8, 0x6205}}}, + /* 5*16^9*G: */ + {{{0x27dd5cfa, 0x2b839008, 0x309d4b5b, 0x227144df, 0x2346336a, 0x31a94d09, 0x24f4c1cd, 0x282372c0, 0x5b5c}}, + {{0x1e48e98c, 0x19929be6, 0x33269d3e, 0x3419f32b, 0x069094bf, 0x07c33aa2, 0x15825e99, 0x2dbdc2a8, 0x3ecc}}}, + /* 7*16^9*G: */ + {{{0x23531f82, 0x2e54a38c, 0x10c2c9f2, 0x144c9aec, 0x022c29ff, 0x3cf9d227, 0x14bb5cce, 0x09ab3044, 0x046f}}, + {{0x0bceda07, 0x1417f22c, 0x2b55c7fa, 0x09651736, 0x032579d0, 0x0dc2b0bf, 0x382eace2, 0x12cc58d6, 0x6b80}}}, + /* 9*16^9*G: */ + {{{0x10432711, 0x02c550dc, 0x1916b906, 0x0502cbf7, 0x19645acf, 0x25bc3c22, 0x0efb535f, 0x09b64c78, 0xc119}}, + {{0x2fe2610c, 0x1249878b, 0x0f34055e, 0x2ae48b28, 0x0cc6cf83, 0x252fc61b, 0x1b689184, 0x3e331f49, 0x8be1}}}, + /* 11*16^9*G: */ + {{{0x21257963, 0x05e61d3e, 0x34aa861c, 0x006354b0, 0x0979c45b, 0x2ed52d4e, 0x08f2e6cd, 0x11ba7ada, 0x6908}}, + {{0x066f9835, 0x295d9665, 0x1c92b253, 0x2f0f2a08, 0x2fbb7f6c, 0x05c093e4, 0x3ebc5b40, 0x17f2dfcf, 0xe248}}}, + /* 13*16^9*G: */ + {{{0x1ee23ace, 0x3444e52f, 0x14dd2fd2, 0x321f196d, 0x232915de, 0x1d54b7d2, 0x220babba, 0x3dfee324, 0xfb3d}}, + {{0x1722e8de, 0x0277bd32, 0x2d27f5ee, 0x1c9c50bf, 0x3ab58a9e, 0x09455036, 0x33c5652a, 0x0a6f0471, 0x510e}}}, + /* 15*16^9*G: */ + {{{0x10272351, 0x181f3fbd, 0x19ff1098, 0x1cd2cf7e, 0x31cd4170, 0x228facea, 0x0518b3eb, 0x17b093d7, 0x6dd8}}, + {{0x3fc7664b, 0x2c1fe8ad, 0x3e0817c9, 0x1f1bfdf0, 0x1c41b787, 0x101fe6bd, 0x3427e09d, 0x19fd0487, 0x16ea}}} + }, + { + /* 1*16^10*G: */ + {{{0x1094696d, 0x3579a236, 0x01d6af52, 0x3e2c99a9, 0x3bd7ec5c, 0x0a0e7c50, 0x15b530ac, 0x1b2b91b5, 0xfeea}}, + {{0x18090088, 0x05577afc, 0x041442d3, 0x072255f3, 0x3ecd5c98, 0x39384afc, 0x0e1bab06, 0x1adb25f7, 0xe57c}}}, + /* 3*16^10*G: */ + {{{0x08dfd587, 0x1e4d86ed, 0x1b026560, 0x312e8e32, 0x35a12d5e, 0x19eaa8b3, 0x0508b348, 0x2d06eb3d, 0x5084}}, + {{0x11470e89, 0x39e7a5fe, 0x091f5606, 0x2dbd581a, 0x2927475d, 0x2a9b2154, 0x00d31619, 0x18c68766, 0x34a9}}}, + /* 5*16^10*G: */ + {{{0x3ab34cc6, 0x0208c985, 0x0f30a12d, 0x030a5d9f, 0x0d7128c8, 0x2cfc7f46, 0x2d5ea53f, 0x300f8190, 0x4f14}}, + {{0x187e681f, 0x17b094be, 0x281dd022, 0x378f33a3, 0x262540b9, 0x0e9c3d0e, 0x0e894c65, 0x342a32a9, 0x7b53}}}, + /* 7*16^10*G: */ + {{{0x1241d90d, 0x109dc404, 0x32444f83, 0x073c5076, 0x1dd363e8, 0x10d8257b, 0x39ed1d41, 0x2e1f9271, 0xa74d}}, + {{0x3f7adad4, 0x0c9462e0, 0x0a0a313f, 0x3b9424d1, 0x0171c8a9, 0x37422962, 0x3eef327f, 0x24736bc8, 0xf786}}}, + /* 9*16^10*G: */ + {{{0x31c1ae1f, 0x17b32888, 0x2cd40b2a, 0x1b9631a2, 0x23565845, 0x373513ae, 0x2a2cf9ac, 0x3e95d12e, 0x6901}}, + {{0x122838b0, 0x3e0cc197, 0x1c77a930, 0x27cee979, 0x1c900dd7, 0x2d4e030a, 0x3c212461, 0x1722089c, 0x35de}}}, + /* 11*16^10*G: */ + {{{0x327a4bdb, 0x2c0c4206, 0x1494cac4, 0x1a9b410d, 0x3ba35d04, 0x12d90fc6, 0x38127a24, 0x360b4750, 0x8d3c}}, + {{0x269a8a2c, 0x0f4d31f3, 0x30ad296c, 0x38e01f4d, 0x36236ed4, 0x3efe7401, 0x241f470c, 0x0958603b, 0x9bd4}}}, + /* 13*16^10*G: */ + {{{0x34ec1d2d, 0x10334f1a, 0x27d8f454, 0x0267d71b, 0x3b691fd9, 0x2759ca59, 0x24739afe, 0x20d8f581, 0xeaf9}}, + {{0x0c838452, 0x33f9d581, 0x3e84b53f, 0x3d4b5515, 0x3199aaa9, 0x08a2839a, 0x38d22775, 0x060e9ff9, 0xe518}}}, + /* 15*16^10*G: */ + {{{0x045ae767, 0x32cd6fdc, 0x289771cb, 0x1cea72e7, 0x06e5d8c2, 0x103814b0, 0x1b63466f, 0x2f458ebb, 0xfb95}}, + {{0x3bbf0e11, 0x214fa82b, 0x259f1341, 0x05bd1c62, 0x02275bb8, 0x013674da, 0x0ddbc520, 0x0536046a, 0x664c}}} + }, + { + /* 1*16^11*G: */ + {{{0x01ec6cb1, 0x0fea5e2f, 0x08583de3, 0x3b595f60, 0x3fca3cfe, 0x1ef92f9b, 0x09cdcb36, 0x2a476441, 0xda67}}, + {{0x3a68be1d, 0x3a7aa389, 0x0f740a17, 0x31eb7142, 0x1780e5de, 0x118fdfb2, 0x242bc41f, 0x2a8d5205, 0x9bac}}}, + /* 3*16^11*G: */ + {{{0x15bc8a44, 0x3bf74194, 0x3e151a19, 0x10405df2, 0x1a5fc768, 0x159692e9, 0x0eda3d38, 0x20160f3f, 0x4d01}}, + {{0x1adbc09e, 0x3c7e5324, 0x182da362, 0x250811a1, 0x16381396, 0x26ea001f, 0x0f5d367e, 0x31b0632d, 0x3a33}}}, + /* 5*16^11*G: */ + {{{0x25daeb00, 0x306ad4a1, 0x2645f76b, 0x08fac933, 0x36e9d159, 0x32da89ce, 0x0f957082, 0x0541f7d7, 0x2f66}}, + {{0x033992c0, 0x089d9e26, 0x15d308c1, 0x337b89c6, 0x00add06e, 0x254dea08, 0x2b33f6ef, 0x0484dbd4, 0xfd5c}}}, + /* 7*16^11*G: */ + {{{0x116aa6d9, 0x20aa4282, 0x3702dcf1, 0x18b22d91, 0x035a3836, 0x3c5d3686, 0x247d2254, 0x045f417f, 0xf594}}, + {{0x3f2e50cf, 0x1f41a5ba, 0x26b5b86c, 0x249de20f, 0x14bceb7a, 0x176f6ac2, 0x31b12cf6, 0x18695ba5, 0xcaa7}}}, + /* 9*16^11*G: */ + {{{0x3ac6f4c0, 0x2ab80e55, 0x04bdc4cc, 0x13a37a33, 0x16711dda, 0x070e2f9a, 0x19cdec4e, 0x135fc7d3, 0x0f2d}}, + {{0x32339b58, 0x1f9eeeb5, 0x0242656e, 0x1a8429e4, 0x01e71e8f, 0x2c9ff7ce, 0x3de4d17f, 0x27e15fa4, 0x3ec8}}}, + /* 11*16^11*G: */ + {{{0x1f428cb2, 0x215414ff, 0x2a22b55d, 0x0e08bf59, 0x18d0f123, 0x1e860565, 0x14bbd1eb, 0x33b0b8a8, 0x1d5d}}, + {{0x095b189b, 0x397b4402, 0x36044a51, 0x0fa44be1, 0x2f0b88bd, 0x1e1e0921, 0x2c8c50d0, 0x1020ec50, 0x6e5c}}}, + /* 13*16^11*G: */ + {{{0x28381273, 0x2c3aa23e, 0x293dae5f, 0x10dda581, 0x0126ced8, 0x3aa6cb31, 0x167439fd, 0x28bf4c02, 0x89d9}}, + {{0x1309773d, 0x00facfbb, 0x1127324a, 0x1875a02b, 0x0f62f58f, 0x2abc81db, 0x26f50377, 0x096d1475, 0xdfca}}}, + /* 15*16^11*G: */ + {{{0x35c71d91, 0x330cacb2, 0x2894fd21, 0x25178b8a, 0x1afece23, 0x28704c45, 0x10ae1c52, 0x06e1e0e9, 0x8319}}, + {{0x22148a61, 0x02e7b023, 0x10445ee7, 0x2847d45d, 0x3cae8a17, 0x1b784f45, 0x01b709e0, 0x1fc55ce0, 0xe0ac}}} + }, + { + /* 1*16^12*G: */ + {{{0x1a37b7c0, 0x1d517330, 0x311069f5, 0x02343dee, 0x322151ec, 0x00024d7b, 0x34cdda6e, 0x13ea82cc, 0x5390}}, + {{0x022771c8, 0x372c25ac, 0x14434699, 0x26666078, 0x0d3c1c13, 0x27b32b08, 0x0106d88c, 0x21f42f20, 0x5bc0}}}, + /* 3*16^12*G: */ + {{{0x08a2050e, 0x06b10bf9, 0x15f8a677, 0x0bbd55d8, 0x079b8974, 0x1da731b9, 0x0731896b, 0x093f492f, 0x6737}}, + {{0x061d3d70, 0x24326924, 0x3349cc2b, 0x1aeb3f50, 0x086b6dbe, 0x120b026a, 0x24a20203, 0x2095e25a, 0xe4cf}}}, + /* 5*16^12*G: */ + {{{0x02de63bf, 0x2fdb920e, 0x3261c66c, 0x0ebd4ca1, 0x2166a8e0, 0x26298c7d, 0x34c309e5, 0x3be91cb7, 0x4366}}, + {{0x217924cd, 0x0b1a9023, 0x2aa6d6b0, 0x0ec31496, 0x0268eaf3, 0x094df84c, 0x2d7ce2ee, 0x36426fb8, 0x2e7d}}}, + /* 7*16^12*G: */ + {{{0x06f96190, 0x04149ffc, 0x3c9525ef, 0x3c0b7a41, 0x3aa75fd1, 0x3955a599, 0x1ab1f97b, 0x14d89e64, 0x7bd7}}, + {{0x2bda00f6, 0x0f45c812, 0x20ea695a, 0x03f31707, 0x3827d6ce, 0x3591d250, 0x26309d5e, 0x3cacf6ee, 0x8336}}}, + /* 9*16^12*G: */ + {{{0x16ad41ed, 0x0ec54c55, 0x0f035243, 0x022b0d7d, 0x18dc9203, 0x0d067a24, 0x2d5c1afa, 0x249ef76a, 0x4f7e}}, + {{0x3e642d57, 0x3d0d5e19, 0x2af775bd, 0x1cc51c53, 0x28f6a62e, 0x26037d4e, 0x08b10552, 0x1d1455aa, 0xdfe7}}}, + /* 11*16^12*G: */ + {{{0x27748690, 0x3e981449, 0x0630b01c, 0x15e41376, 0x133d007d, 0x114ac7b7, 0x11ccc94b, 0x32e19f4a, 0x2355}}, + {{0x0c89582b, 0x1f11d4c5, 0x11c93914, 0x0a1a1633, 0x2a7c5858, 0x2e17b056, 0x1e1f8f55, 0x3c62969c, 0x21c2}}}, + /* 13*16^12*G: */ + {{{0x0ade7f16, 0x36ba8858, 0x0be028c6, 0x272eba4f, 0x275d24ae, 0x164aadb0, 0x1a56c013, 0x2096e6cf, 0x0b66}}, + {{0x08c56217, 0x251109a1, 0x3e7cd2bd, 0x090f037c, 0x17a97fb7, 0x29daea2d, 0x09b3fef3, 0x282e0638, 0xa1fb}}}, + /* 15*16^12*G: */ + {{{0x19060d5b, 0x241ac08a, 0x03a3a7c2, 0x1184ec47, 0x3951cb90, 0x026cbf67, 0x1022cb61, 0x010f3c2f, 0xf602}}, + {{0x1af88f13, 0x1bdbd42c, 0x3dd1a3f7, 0x2a95b4ad, 0x0f7bea37, 0x2a3d92b1, 0x0cf19881, 0x2dc1b07c, 0xf036}}} + }, + { + /* 1*16^13*G: */ + {{{0x3ad86047, 0x3fe567d0, 0x29b8bcae, 0x2d4e810e, 0x0a906779, 0x3329dd93, 0x183a7719, 0x3342f4d6, 0x8e7b}}, + {{0x0460372a, 0x284011fa, 0x3fd68b3e, 0x3a238b91, 0x29514579, 0x0c410832, 0x1a4b3940, 0x1dc2ca8f, 0x10b7}}}, + /* 3*16^13*G: */ + {{{0x041ead4b, 0x3fa21e68, 0x11b03c1f, 0x1d7b7eda, 0x3e76be3a, 0x11cd3beb, 0x3337ec71, 0x03032323, 0xbfc9}}, + {{0x06fedaed, 0x114b1bc2, 0x2e0ae3e7, 0x11a3bfcc, 0x042d36fb, 0x29c63754, 0x0ded24db, 0x206c7827, 0x7a94}}}, + /* 5*16^13*G: */ + {{{0x35bb3b3e, 0x1b9ef41d, 0x39f73cb2, 0x1d4d85fb, 0x2d3f5b50, 0x1664fa30, 0x3aaa4dca, 0x3c472f8f, 0x732d}}, + {{0x17366693, 0x315df87b, 0x0c58436c, 0x276b5b59, 0x253916e6, 0x38956100, 0x39977cb7, 0x240fb7a3, 0x7f41}}}, + /* 7*16^13*G: */ + {{{0x088dc3b9, 0x17d6cf06, 0x1774c99c, 0x299a493a, 0x17ef6019, 0x2a210332, 0x147b428d, 0x252e580e, 0x4ce0}}, + {{0x25c0de52, 0x3053dedb, 0x1ea06502, 0x0816c832, 0x36aca216, 0x2d360329, 0x29b3ed57, 0x03eeafc6, 0x0539}}}, + /* 9*16^13*G: */ + {{{0x0aaafe5a, 0x30dd782c, 0x109aedd4, 0x151c2ce9, 0x023fd0e2, 0x229aa56c, 0x267de96d, 0x23addbf1, 0x9a96}}, + {{0x0ed975c0, 0x39aff509, 0x1e70cc0c, 0x2d620299, 0x061d0ee7, 0x319b40f6, 0x3ba2954f, 0x3ec1e9b4, 0xabf6}}}, + /* 11*16^13*G: */ + {{{0x334c6397, 0x1d472fe7, 0x074cd093, 0x374f6d40, 0x36b22107, 0x2bbe0094, 0x161954f0, 0x3efb405c, 0xd3c6}}, + {{0x28cb3f9c, 0x07f23415, 0x05e0e00b, 0x031dc224, 0x2ab6468a, 0x20e5364b, 0x22af1945, 0x34b15797, 0x4a0d}}}, + /* 13*16^13*G: */ + {{{0x0ac3137e, 0x26e0964c, 0x1af64461, 0x2496d8a9, 0x2b3953fe, 0x3c1a9daa, 0x243b8e02, 0x38e604a4, 0x4cbd}}, + {{0x2ec02fe6, 0x0023c573, 0x08ead60c, 0x24e9eb96, 0x14c370d1, 0x24a84d2e, 0x36159500, 0x151823c4, 0x6ce5}}}, + /* 15*16^13*G: */ + {{{0x20fbf84b, 0x1e88c1b3, 0x03f0b8a4, 0x3123f2ef, 0x14cebb03, 0x3671cc30, 0x16247b8b, 0x0ccf20ac, 0x4b9d}}, + {{0x236c3c48, 0x0e7b92d2, 0x2f5b5e62, 0x19b550f8, 0x39b7eb67, 0x04f66099, 0x0c152553, 0x31fef893, 0xfd7f}}} + }, + { + /* 1*16^14*G: */ + {{{0x19c43862, 0x2a107856, 0x397e6690, 0x29fd3c60, 0x381bde71, 0x02061a26, 0x1ff21e6d, 0x3b4d3073, 0x385e}}, + {{0x142e5453, 0x01163f95, 0x086dc8cc, 0x0c13bb08, 0x2bf4576b, 0x077867a7, 0x223f5670, 0x3af0fa3a, 0x283b}}}, + /* 3*16^14*G: */ + {{{0x36e2d9b3, 0x12f4c1aa, 0x338d6351, 0x36e4a0c6, 0x0f845641, 0x0ba984e7, 0x305e75e1, 0x053ce5f1, 0x19a3}}, + {{0x0baaaf33, 0x154bb897, 0x004be56d, 0x00874749, 0x3528b3a5, 0x2597e21f, 0x328dd234, 0x363d76b1, 0x6cac}}}, + /* 5*16^14*G: */ + {{{0x12f00480, 0x36161fac, 0x100dcee7, 0x0d620128, 0x36721920, 0x32618d93, 0x0daa355d, 0x3b52e56a, 0x5840}}, + {{0x3e22cf9e, 0x164b578a, 0x2ae38721, 0x1d489514, 0x1dd8daba, 0x1a37aa85, 0x3f141079, 0x369ac882, 0x670c}}}, + /* 7*16^14*G: */ + {{{0x23f54c42, 0x12137ba0, 0x29a3dc8e, 0x37068f09, 0x0e532545, 0x16307d3b, 0x118fb1dc, 0x00694d1a, 0x9f57}}, + {{0x2feb6a21, 0x18387124, 0x219e5278, 0x3b9e12ac, 0x29bfdd89, 0x256dad5c, 0x19e57bfb, 0x23ee2007, 0xce7b}}}, + /* 9*16^14*G: */ + {{{0x1522461a, 0x3a504cca, 0x3c718327, 0x2cc28996, 0x3ef9a0bc, 0x2e1c0419, 0x28cfc01b, 0x045a48d6, 0x27f6}}, + {{0x07301a2d, 0x2a932be7, 0x28639446, 0x2606c836, 0x028ee8e4, 0x2315849d, 0x26ad2ea4, 0x3c6a6402, 0xe512}}}, + /* 11*16^14*G: */ + {{{0x114f36b9, 0x338b26cb, 0x3b9f390c, 0x2632aed8, 0x34a98125, 0x2fcbd0d7, 0x2f941261, 0x1e615b3b, 0x6407}}, + {{0x24b4b50a, 0x252c7ba7, 0x19ceeb28, 0x36821c12, 0x1a7b6c8c, 0x035d7f61, 0x16efaef9, 0x24a3d139, 0xda61}}}, + /* 13*16^14*G: */ + {{{0x14d6b76f, 0x3bd8f7e6, 0x0c815dbc, 0x396a7eed, 0x1dfeae7f, 0x3dc22f02, 0x1669f452, 0x1438c721, 0xa237}}, + {{0x0dcca8da, 0x0764b332, 0x1b848d14, 0x1c1f047f, 0x011113e7, 0x0be8f935, 0x3de6dac3, 0x26c529b9, 0xf733}}}, + /* 15*16^14*G: */ + {{{0x3ceee475, 0x0bba7193, 0x0ed782b1, 0x1ab20a10, 0x0aff41ab, 0x0f0087cf, 0x2378d5ed, 0x2b01e8fc, 0xbbf1}}, + {{0x07fe5067, 0x1188a802, 0x38b41d68, 0x3ae76250, 0x315fe324, 0x20f320da, 0x060e6108, 0x2e37bab5, 0xb4bf}}} + }, + { + /* 1*16^15*G: */ + {{{0x03fac3a7, 0x181bb61b, 0x147fbc9c, 0x377e1296, 0x3dfa180f, 0x31ce9104, 0x0f191637, 0x366e00fb, 0x06f9}}, + {{0x3a842160, 0x21a24180, 0x0281002d, 0x29374bd7, 0x05c4d47e, 0x238a8c39, 0x059ba69b, 0x31a3980c, 0x7c80}}}, + /* 3*16^15*G: */ + {{{0x121ce204, 0x13b5d7a3, 0x26763d52, 0x29c96390, 0x26f72fb2, 0x1d361672, 0x3c64fb83, 0x107458ac, 0x43ca}}, + {{0x134a8f6b, 0x1494113a, 0x2a4a468e, 0x2db1eccf, 0x1ba31f9a, 0x143e4863, 0x023fa1c6, 0x16a0b8dc, 0xdcea}}}, + /* 5*16^15*G: */ + {{{0x2be6efda, 0x13f3a4b3, 0x07280596, 0x0b53fcfe, 0x1a506d92, 0x1bdc8de1, 0x12bf5b66, 0x01bbc8a2, 0x9c3e}}, + {{0x27aefc7d, 0x3c503cca, 0x336fdf7d, 0x0ef21a1e, 0x226fd5d4, 0x02cb5133, 0x2923d8af, 0x027979d8, 0xa7b7}}}, + /* 7*16^15*G: */ + {{{0x06c88be2, 0x2449ead7, 0x06ee5e27, 0x0b1e0834, 0x30775bea, 0x1c9d6760, 0x20f033bb, 0x22a8c4f8, 0x5d6f}}, + {{0x0d7ad75d, 0x24b954fc, 0x2bf92c28, 0x2adbe3a9, 0x08bc20ed, 0x2abcceac, 0x2d4e8c71, 0x2c636355, 0xadc4}}}, + /* 9*16^15*G: */ + {{{0x12d1b844, 0x0a24d46e, 0x173e484f, 0x2700e0b0, 0x388bc5c6, 0x2c570f04, 0x20d5fc86, 0x0d70c129, 0xf57d}}, + {{0x21266837, 0x192eaef5, 0x0915c6a4, 0x01a5c80c, 0x24634c70, 0x134fd6a7, 0x2f4d9790, 0x0f67aa63, 0x707f}}}, + /* 11*16^15*G: */ + {{{0x3cc7cb09, 0x0d3401fc, 0x1d1b4352, 0x31fada28, 0x1871463b, 0x1b87fb8f, 0x194a5f59, 0x181e8e99, 0x13e7}}, + {{0x08079160, 0x2f9d6a28, 0x2b576411, 0x3ab8aed9, 0x34299d65, 0x17f7616c, 0x3b8b1e32, 0x32237a3e, 0x284d}}}, + /* 13*16^15*G: */ + {{{0x18cdee05, 0x01833849, 0x32ec3b90, 0x1d87ec85, 0x06901da8, 0x00942c6c, 0x182e6240, 0x28c895a0, 0x29be}}, + {{0x262651c8, 0x39280d66, 0x0c698e39, 0x3f0c6db2, 0x305ec7f9, 0x026cfee1, 0x29a0ea90, 0x36689a43, 0x7c40}}}, + /* 15*16^15*G: */ + {{{0x12f18ada, 0x06db1d58, 0x3dbdbcc1, 0x182f64ee, 0x3d4a59d4, 0x0dbebfcc, 0x288e7d9c, 0x1e1b48e0, 0xf521}}, + {{0x23953516, 0x375a2bf4, 0x05bf0981, 0x17bd28db, 0x11d1d6aa, 0x09840af3, 0x0db57ecc, 0x1befd80e, 0xe068}}} + }, + { + /* 1*16^16*G: */ + {{{0x02d0e6bd, 0x0edf839d, 0x30f5e531, 0x1d3458f6, 0x0d6ecbf7, 0x0851f041, 0x04e2582a, 0x3500490f, 0x3322}}, + {{0x2c28b2a0, 0x13ce8ba5, 0x2873af62, 0x017d8fa8, 0x1af9b728, 0x0066f137, 0x24ef5bfb, 0x01e5fa59, 0x56e7}}}, + /* 3*16^16*G: */ + {{{0x059ab499, 0x2f674fc8, 0x273c330a, 0x04ca671b, 0x3f01bc0b, 0x065acf19, 0x005ba5d2, 0x2bfcc057, 0x78ba}}, + {{0x3ee097fd, 0x20748c63, 0x11251996, 0x18cbbba3, 0x02082e91, 0x2a1383b6, 0x2c0afafc, 0x3736f6c1, 0xad4b}}}, + /* 5*16^16*G: */ + {{{0x3d06ace6, 0x124f85b3, 0x03a20ca4, 0x1c26cdbe, 0x29ab1a23, 0x2e126124, 0x2e3d4c20, 0x3c846852, 0x6f70}}, + {{0x3602d5de, 0x122fb4d2, 0x25ac5ee0, 0x0ca559af, 0x399f5075, 0x1763cd1e, 0x27b736f9, 0x228c2500, 0x791e}}}, + /* 7*16^16*G: */ + {{{0x20ee1b40, 0x323b8fb9, 0x1e96247d, 0x3b5216dc, 0x03ccd48c, 0x2527c644, 0x2a415f80, 0x276ca75a, 0xe159}}, + {{0x178f93a6, 0x0758997b, 0x032999de, 0x0d8e9d2f, 0x2fc7cfa6, 0x3e252aa8, 0x1d4a0efa, 0x1888caa0, 0x7933}}}, + /* 9*16^16*G: */ + {{{0x09c00c3e, 0x2077e8a1, 0x11208e2f, 0x03a3c0f2, 0x051859f0, 0x158b4cf5, 0x06956436, 0x0125c110, 0xbb0b}}, + {{0x11955a35, 0x266a60b4, 0x05dc90a7, 0x19c113a4, 0x31b052fe, 0x34be85ea, 0x39f63655, 0x391614eb, 0x4067}}}, + /* 11*16^16*G: */ + {{{0x05dd32e6, 0x039d6e70, 0x13e5ee7e, 0x18ed546d, 0x1a5fbfc6, 0x1276f81d, 0x1789e9b6, 0x10555065, 0xdc5a}}, + {{0x354a99b9, 0x039f6de9, 0x2e49bcf8, 0x3cbba41d, 0x3f59442f, 0x3a978806, 0x367a76dc, 0x2a298fe7, 0x4af3}}}, + /* 13*16^16*G: */ + {{{0x0544e7cb, 0x3b516eb1, 0x12960359, 0x0190896d, 0x014e99a1, 0x0d5295c4, 0x33b9dbe3, 0x065c0e61, 0x156e}}, + {{0x2d250a37, 0x354e4b02, 0x2b439cd6, 0x25b56357, 0x034be894, 0x255ca98e, 0x1907da93, 0x2367e3cc, 0x6bc0}}}, + /* 15*16^16*G: */ + {{{0x059853ca, 0x2fef0a73, 0x319bf54d, 0x3a589ae7, 0x27161348, 0x29da88a3, 0x043826bc, 0x2f33b2da, 0x4269}}, + {{0x35b8d367, 0x2a563bd4, 0x1e5a8a3d, 0x0e50297e, 0x31a409fd, 0x2132a710, 0x016b723c, 0x0706a0b0, 0xed2b}}} + }, + { + /* 1*16^17*G: */ + {{{0x0134ab83, 0x0875d34a, 0x36433977, 0x06cfe6bd, 0x26586874, 0x05dc3625, 0x0b7da2bd, 0x0b1f4b78, 0x8567}}, + {{0x390313a6, 0x238c253d, 0x1298f44c, 0x1fc5ff31, 0x22c2e5e7, 0x10126fe9, 0x3b2eb637, 0x06e6d6d0, 0x7c48}}}, + /* 3*16^17*G: */ + {{{0x03ba9000, 0x37c1c8ea, 0x025e8b6f, 0x21cbe71a, 0x00143dc4, 0x21d81d61, 0x1d8c1684, 0x1d3e7ffc, 0xac38}}, + {{0x2f10cf0a, 0x368f1f65, 0x366e9fa4, 0x178d435f, 0x117f9308, 0x0b77a250, 0x1c069b86, 0x3a48c228, 0xaa65}}}, + /* 5*16^17*G: */ + {{{0x2d06dbd4, 0x2981bd9b, 0x0a20d081, 0x038fe15e, 0x23e729ec, 0x0501d7a6, 0x070139ad, 0x1739ea9a, 0x570d}}, + {{0x3d1ed495, 0x2996fb3a, 0x2460bed5, 0x20e8db71, 0x101bbbb6, 0x19b99c47, 0x202f605b, 0x14d25083, 0xa6ae}}}, + /* 7*16^17*G: */ + {{{0x092d230e, 0x0d307e48, 0x29339284, 0x3b8ca834, 0x366ef5da, 0x308a7b80, 0x28bb6f87, 0x3e1c0a09, 0x75b5}}, + {{0x151570b8, 0x0df2f7ef, 0x111f8fb0, 0x19e92c01, 0x1dfa8e02, 0x1e1d1553, 0x3852363d, 0x338878e9, 0x527c}}}, + /* 9*16^17*G: */ + {{{0x034fcc0e, 0x1edafdab, 0x3e3884c4, 0x1fc4290a, 0x1259c892, 0x16e0389f, 0x1dec2b0a, 0x23beb87b, 0x44fc}}, + {{0x319c420a, 0x33fc0c79, 0x0d0489d9, 0x03a5292f, 0x33d3d772, 0x099f9e20, 0x31367e49, 0x37a52ea6, 0xd2c7}}}, + /* 11*16^17*G: */ + {{{0x0bb69991, 0x169207f2, 0x3307175d, 0x3ecfe8b0, 0x02f535ff, 0x28598838, 0x27bc6866, 0x2e91eeb3, 0xdea2}}, + {{0x316fe2df, 0x019d0aa7, 0x21ed9bc7, 0x27736cd8, 0x37b9e722, 0x32ffb213, 0x028e4ac5, 0x2ff5b643, 0xae28}}}, + /* 13*16^17*G: */ + {{{0x114fc9cc, 0x30903409, 0x1a461658, 0x3402af0a, 0x38a83626, 0x073db312, 0x168d6efc, 0x3f2629b8, 0x3968}}, + {{0x1fad37dd, 0x064e5225, 0x388f3340, 0x05195dbf, 0x2d32c91a, 0x1e60b46a, 0x35928123, 0x2ef436d2, 0x789c}}}, + /* 15*16^17*G: */ + {{{0x2e0c85f1, 0x2bb08646, 0x03a3a250, 0x294b94d8, 0x3945d5a6, 0x0977c255, 0x06a2926b, 0x2441a638, 0x6896}}, + {{0x2dc1de21, 0x31d208cc, 0x0d503922, 0x10306768, 0x05d72d1f, 0x0c170761, 0x0979256f, 0x0fed2ce3, 0xaefd}}} + }, + { + /* 1*16^18*G: */ + {{{0x20c82a0a, 0x3f6566bd, 0x3668832f, 0x2489b183, 0x1413b10f, 0x1b27c646, 0x188a46b0, 0x2fe026c6, 0x0948}}, + {{0x18c8e589, 0x132dfe23, 0x17cd2bed, 0x137fc232, 0x03418c6d, 0x2dd31747, 0x36646dc6, 0x18a15b72, 0x53a5}}}, + /* 3*16^18*G: */ + {{{0x38c8ac7f, 0x0a0bf97e, 0x1e2aa527, 0x0490bb99, 0x16f84964, 0x0ce5b481, 0x22bbcb5c, 0x2cbef8e0, 0x9945}}, + {{0x29aea3b0, 0x1b650e85, 0x2dacdfa9, 0x0bde88fb, 0x28eff528, 0x36d13fec, 0x3282d607, 0x3b6092c3, 0x3eef}}}, + /* 5*16^18*G: */ + {{{0x169e353a, 0x3475e78e, 0x2bbe1f6e, 0x28110214, 0x07d5fe10, 0x3e0889c4, 0x070e6235, 0x131ac816, 0x2a31}}, + {{0x25746067, 0x09649b87, 0x32658bfc, 0x22952ab6, 0x2a1ba013, 0x18f91dae, 0x227ac1a4, 0x2b02fcd6, 0x15a4}}}, + /* 7*16^18*G: */ + {{{0x29b84966, 0x278bd27b, 0x17f3ff98, 0x13d041b7, 0x2b6c911b, 0x2dbebce9, 0x3fc2d498, 0x29402dc0, 0x5959}}, + {{0x07473a6a, 0x02998c86, 0x0fe24264, 0x00373023, 0x082a7091, 0x0c4a0837, 0x0a897f94, 0x399d07d7, 0x0370}}}, + /* 9*16^18*G: */ + {{{0x2bc6b173, 0x2c326e48, 0x2ed3feb3, 0x36188f1f, 0x1b5f9d7d, 0x183118c1, 0x22fe8e11, 0x0c4e4dc8, 0x9eeb}}, + {{0x1723a71d, 0x14e58836, 0x0e70c4b9, 0x29c6afb4, 0x3a1ae30e, 0x2aaff6ee, 0x2d58d952, 0x3c780443, 0xe121}}}, + /* 11*16^18*G: */ + {{{0x3ec805f3, 0x1dc910fd, 0x1d995915, 0x3903dd42, 0x2e97887d, 0x2ec8e201, 0x318f516e, 0x13f931fd, 0x39cc}}, + {{0x3a3c48d3, 0x06468304, 0x3c912e4d, 0x2e55cdcf, 0x02de7dbb, 0x399a4f3d, 0x2f8f3151, 0x11cb1691, 0xecb1}}}, + /* 13*16^18*G: */ + {{{0x0e22580e, 0x0f58bed7, 0x2d6f8879, 0x04ca25b4, 0x1bd4d2c7, 0x0bff7993, 0x0dc69689, 0x201d19bb, 0xf94c}}, + {{0x3127db82, 0x07948fd9, 0x2371d4e8, 0x21fb114c, 0x1a81f698, 0x12ffdaad, 0x1225a919, 0x1ff719e1, 0x5e9c}}}, + /* 15*16^18*G: */ + {{{0x10c4f21f, 0x2f902eb4, 0x103da7a6, 0x092a5653, 0x1999d250, 0x0081a36c, 0x1d162fcc, 0x2e1b1ab5, 0x8ccc}}, + {{0x329dfea0, 0x1fc49ba9, 0x264be28f, 0x24b72b20, 0x0758a54b, 0x2fbd5272, 0x11c43699, 0x2596189d, 0x57f8}}} + }, + { + /* 1*16^19*G: */ + {{{0x338fd8e8, 0x33b36067, 0x069752ac, 0x2c39137f, 0x2873a8f1, 0x19f383c0, 0x001c34f0, 0x339fd186, 0x6260}}, + {{0x32b4ae17, 0x06a13a56, 0x051c198c, 0x34a488e0, 0x2a1ef7ec, 0x024125dd, 0x1b571a7f, 0x2a0adbe9, 0xbc2d}}}, + /* 3*16^19*G: */ + {{{0x01136602, 0x2c2e9195, 0x19e3a5bb, 0x311bd203, 0x333b3d38, 0x1624dfc8, 0x2dfc33d0, 0x09ca0120, 0x87d1}}, + {{0x18af6aac, 0x3da0f107, 0x3d3bf7c4, 0x2a211d1b, 0x27745387, 0x289db3fd, 0x203de926, 0x0921c296, 0x71ce}}}, + /* 5*16^19*G: */ + {{{0x08c5a916, 0x2c8175cd, 0x35610f25, 0x17110354, 0x354aa13f, 0x2b318f6a, 0x1e9746b0, 0x1f4ff898, 0xfd5d}}, + {{0x3adb8bda, 0x052cdec1, 0x1cf6faab, 0x35ce052f, 0x07b52fe5, 0x10f299e7, 0x15b07d2b, 0x0fb43bad, 0x0dd8}}}, + /* 7*16^19*G: */ + {{{0x35f7529c, 0x17664258, 0x1bd51dd4, 0x1d96e62d, 0x34438138, 0x114f0cb4, 0x026122ba, 0x35042607, 0xde0d}}, + {{0x24cd88fe, 0x0f08300b, 0x09b77406, 0x224931a2, 0x3a357017, 0x042608b5, 0x2145f9b2, 0x1ba74428, 0xd70a}}}, + /* 9*16^19*G: */ + {{{0x38f76d11, 0x320bd234, 0x38515573, 0x044003ef, 0x0292a215, 0x16fbf0e7, 0x0f44e69c, 0x0822b693, 0xb26c}}, + {{0x23b7356b, 0x307002c7, 0x182624bd, 0x000c1967, 0x0d643305, 0x13a1f643, 0x1d33cf0c, 0x3e208252, 0x1f1c}}}, + /* 11*16^19*G: */ + {{{0x269e22db, 0x2538ec19, 0x39c8933f, 0x264ffd67, 0x0c294eac, 0x0ef4a406, 0x3f523a7e, 0x052e3f1f, 0xfceb}}, + {{0x1c2260a1, 0x3d5cb6c9, 0x24ebe4cb, 0x15439e4e, 0x1f0924ad, 0x22969d49, 0x2b8d1fcd, 0x1ace9035, 0x64aa}}}, + /* 13*16^19*G: */ + {{{0x238a2755, 0x3c2105e6, 0x149c5506, 0x1c869c59, 0x107faa53, 0x05d5dd2d, 0x15cac55c, 0x26988f33, 0x4e90}}, + {{0x23cca3de, 0x3de927d8, 0x229800ca, 0x3354e534, 0x3559dbb6, 0x091b7541, 0x235aecef, 0x36a1e333, 0xae56}}}, + /* 15*16^19*G: */ + {{{0x183ba64d, 0x20962566, 0x0c595a3a, 0x3983dde2, 0x0e40e2bd, 0x028517ae, 0x04c03bfb, 0x115708b8, 0xc367}}, + {{0x2a2181fd, 0x053323e5, 0x1778f146, 0x189aab28, 0x1964c742, 0x3839ba13, 0x36033080, 0x02b41a72, 0x3a52}}} + }, + { + /* 1*16^20*G: */ + {{{0x2037fa2d, 0x254f3234, 0x1bfdc432, 0x0fb23d5d, 0x3f410304, 0x0d21052e, 0x1d8d43d8, 0x1f782bf0, 0xe503}}, + {{0x1d755bda, 0x03977210, 0x0481f10e, 0x17d6c0fb, 0x190bddbd, 0x263427ee, 0x0d3b5f9f, 0x14d2eaa5, 0x4571}}}, + /* 3*16^20*G: */ + {{{0x177e7775, 0x222a29b8, 0x0ed95f63, 0x385564e2, 0x1291aeb5, 0x150eeb3d, 0x233cee58, 0x1a8ebfe5, 0x9d89}}, + {{0x3a056691, 0x3f3db4ea, 0x299253be, 0x26735fb8, 0x10927de8, 0x2593b5c9, 0x1bf0b94e, 0x2a790fd2, 0xdd91}}}, + /* 5*16^20*G: */ + {{{0x3c2a3293, 0x3f781378, 0x103476c5, 0x222e1bba, 0x02f4cd56, 0x2c295cca, 0x23792d0e, 0x2e3b9c45, 0x8327}}, + {{0x0e0df9bd, 0x2f215386, 0x2326a416, 0x2bf6ad3b, 0x39708496, 0x2cfa9989, 0x0a98e18b, 0x1f899bb8, 0x0499}}}, + /* 7*16^20*G: */ + {{{0x0562c042, 0x1086c9b1, 0x38dfb1a2, 0x0b48c8d2, 0x1a8ed609, 0x1998763e, 0x1b16897d, 0x0aaa8a9b, 0x5ae4}}, + {{0x0f79269c, 0x2417337e, 0x07cd8dbf, 0x3836e544, 0x389d4a94, 0x30777180, 0x3051eab5, 0x0e9f017f, 0x99d9}}}, + /* 9*16^20*G: */ + {{{0x1e85af61, 0x0d2204a1, 0x14ae766b, 0x23b5c8b7, 0x021b0f4e, 0x3ada3fdb, 0x1c8eb59a, 0x0eb909a8, 0x92c2}}, + {{0x036a2b09, 0x39c8d9a7, 0x2286fed4, 0x08eb60ad, 0x38d5792d, 0x085f571c, 0x11bb409f, 0x3e23c055, 0x414c}}}, + /* 11*16^20*G: */ + {{{0x07b5eba8, 0x38abc6cb, 0x118ea36c, 0x2afb71fe, 0x38df422d, 0x03d05dab, 0x3df1088d, 0x18231dab, 0xfee5}}, + {{0x0d0b9b5c, 0x3d4574da, 0x39054793, 0x203fd0af, 0x07c14ee3, 0x100be64a, 0x258afb11, 0x16644d3f, 0x3807}}}, + /* 13*16^20*G: */ + {{{0x3c63caf4, 0x078ee92c, 0x0f53d528, 0x23fceaca, 0x2a6afca2, 0x044ed318, 0x267e620a, 0x113ae4b9, 0x42e5}}, + {{0x169c29c8, 0x21ebb026, 0x3efc5f11, 0x29439eda, 0x015e7873, 0x3c88305d, 0x0c671f71, 0x15383e47, 0x9ff8}}}, + /* 15*16^20*G: */ + {{{0x1e0f09a1, 0x028af661, 0x14032838, 0x28427c6e, 0x300efef0, 0x25bb4a91, 0x32ce3839, 0x20ed9954, 0x7aed}}, + {{0x05857d73, 0x1176337a, 0x33f4a540, 0x22cbcc03, 0x032d8ed8, 0x2bf42ac4, 0x1ef7c7dd, 0x1517e68c, 0xf5b8}}} + }, + { + /* 1*16^21*G: */ + {{{0x24fce725, 0x1619a82b, 0x2a6c5b72, 0x3a36f471, 0x1771b4e7, 0x2a417a3c, 0x207adf5e, 0x1cac3d28, 0xe063}}, + {{0x0eee31dd, 0x09c0d3e5, 0x3104870b, 0x12129de1, 0x1a488cd7, 0x09eecab5, 0x18cfe12a, 0x225d2f38, 0x7a90}}}, + /* 3*16^21*G: */ + {{{0x1a328d6a, 0x2eaa0623, 0x1adc18bd, 0x135dcea5, 0x308fa7b2, 0x1a264616, 0x34e00a34, 0x3016e988, 0xc663}}, + {{0x3ec9b8c0, 0x0ec2edaa, 0x12bf9cc2, 0x21547a94, 0x171317dd, 0x2bf73c9d, 0x21c38d39, 0x3a6357dc, 0x3331}}}, + /* 5*16^21*G: */ + {{{0x3996de2f, 0x32472120, 0x0b25114b, 0x33b7cbb8, 0x0fe4e977, 0x2cc37ba8, 0x06a459ce, 0x09a0b7ee, 0xd3fc}}, + {{0x14526f8c, 0x31248907, 0x37abf168, 0x166d2637, 0x3781da4e, 0x2d1d5353, 0x30a18f68, 0x37e66917, 0xc4f0}}}, + /* 7*16^21*G: */ + {{{0x03e697ea, 0x31b12344, 0x05f83e85, 0x399e3ee6, 0x3fabd19c, 0x287fb268, 0x2c0237dc, 0x12d0ffac, 0xc17a}}, + {{0x1edc6c87, 0x3b8ee1f7, 0x39f02ab0, 0x38686d5f, 0x201fae96, 0x05e3dc65, 0x35954cae, 0x170b556a, 0x3935}}}, + /* 9*16^21*G: */ + {{{0x3163da1b, 0x0b4b0c08, 0x393a3118, 0x03b7b983, 0x011fde9a, 0x24d275ff, 0x390b468c, 0x22df2899, 0x8f61}}, + {{0x03bdd76e, 0x1fcc4844, 0x249b6e7c, 0x14319a8c, 0x2c5a4264, 0x2f69d35e, 0x3eb6eb5f, 0x0fc97c22, 0x7823}}}, + /* 11*16^21*G: */ + {{{0x0ec8ae90, 0x3a1643f8, 0x0bbc5dee, 0x2c9ae4ba, 0x03f1b8cf, 0x356e36b2, 0x21e6eb86, 0x303c56de, 0x9798}}, + {{0x252844d3, 0x2a6b0bab, 0x03188e27, 0x392596f4, 0x1c73bee2, 0x3b25253e, 0x02ed3dd2, 0x38aa9d69, 0xba40}}}, + /* 13*16^21*G: */ + {{{0x11d66b7f, 0x16865e3c, 0x187dc810, 0x29a49414, 0x1284757a, 0x3c6e42e2, 0x22d6747c, 0x1bb8fed6, 0xfdfa}}, + {{0x38e5178b, 0x2aa3e019, 0x3d78de9d, 0x11be7744, 0x1a18c4d8, 0x0307268f, 0x198db93c, 0x3cc78892, 0x4d9c}}}, + /* 15*16^21*G: */ + {{{0x1265bcf0, 0x201d5e12, 0x11c7d30b, 0x338ade10, 0x0f220e69, 0x3aa69187, 0x29e43add, 0x338e3788, 0xfd58}}, + {{0x2b996292, 0x0cf9ea73, 0x0f1cd1df, 0x0986ff8a, 0x05e4fb87, 0x20aae692, 0x3215bd53, 0x29794dd8, 0xffe0}}} + }, + { + /* 1*16^22*G: */ + {{{0x10559754, 0x02b5a423, 0x2a3f5854, 0x2c42f778, 0x0ce02204, 0x02efe770, 0x1d45358d, 0x1e9c5735, 0x213c}}, + {{0x34b458f2, 0x3fcb09d4, 0x36a7eedd, 0x12143d7c, 0x1ba190bb, 0x0eb41891, 0x06250701, 0x2b42d6b9, 0x4b6d}}}, + /* 3*16^22*G: */ + {{{0x1e05dccc, 0x0cb60046, 0x019a93e5, 0x0fe8fb53, 0x13d172ae, 0x1b825ae5, 0x1a030954, 0x3db85d4f, 0xb8ce}}, + {{0x0c6d5750, 0x0052833f, 0x26b68133, 0x1d5ff0da, 0x12bd99df, 0x3529d393, 0x09bbf6a4, 0x229829b3, 0x302b}}}, + /* 5*16^22*G: */ + {{{0x373bb31a, 0x16f7fb84, 0x3db97b48, 0x07dedad7, 0x3b5f4970, 0x282f78ba, 0x07385e02, 0x0cf9de6d, 0x03fb}}, + {{0x3d215c9e, 0x0d32f9a5, 0x07640d4e, 0x169f1db1, 0x3b572bc6, 0x30586aae, 0x2fe281e0, 0x36549523, 0xf36a}}}, + /* 7*16^22*G: */ + {{{0x1d9a4ab4, 0x16d457af, 0x15bb7c0a, 0x1f0db061, 0x0f7a3671, 0x05bded34, 0x03e1161f, 0x1f34427b, 0x4b17}}, + {{0x235ab6f7, 0x2ab77f91, 0x1741f558, 0x0df8957c, 0x226b486e, 0x23d9ca4d, 0x2fa65fda, 0x19ba6978, 0x3ec9}}}, + /* 9*16^22*G: */ + {{{0x301c23a4, 0x3d1beca6, 0x3a49cf56, 0x0a905611, 0x39cd75c2, 0x00e0a6e6, 0x27a06c2a, 0x00d481a8, 0x5e87}}, + {{0x10d986f9, 0x085e65ac, 0x24ccfda1, 0x05c761d2, 0x2c6e2da2, 0x1d5746b8, 0x09221e71, 0x1913bee7, 0x5b96}}}, + /* 11*16^22*G: */ + {{{0x007b0c66, 0x3cfcd748, 0x16c86fb1, 0x29ffb919, 0x2ceb7434, 0x08913d82, 0x1680a447, 0x30c064c3, 0xe545}}, + {{0x31f2d470, 0x21fd5f49, 0x35a239dd, 0x3960a386, 0x19bcbf97, 0x31bf68e5, 0x2955e7e5, 0x0d03a318, 0xe06a}}}, + /* 13*16^22*G: */ + {{{0x03648bba, 0x2960642e, 0x1c3c7444, 0x283c2c1a, 0x01b39882, 0x0fb8897c, 0x0f580a13, 0x10855e95, 0xb2a4}}, + {{0x00fb6452, 0x11bead28, 0x09c17bb2, 0x36154547, 0x3d7e31c0, 0x3ef25e3e, 0x366619e9, 0x17f0ada4, 0xfe4f}}}, + /* 15*16^22*G: */ + {{{0x2bab27d0, 0x3db748bb, 0x045103fc, 0x02d07e8b, 0x197007f7, 0x25c06463, 0x138651ba, 0x2383cf51, 0x1b90}}, + {{0x00d3d110, 0x07a19d79, 0x07e51b57, 0x2ef2a4d6, 0x3c4b9ab5, 0x15f24605, 0x26b5e6f3, 0x1897bb11, 0x9b6d}}} + }, + { + /* 1*16^23*G: */ + {{{0x08fbd53c, 0x0330e8ec, 0x1c62cddf, 0x20e31c2b, 0x019a87e2, 0x2e4d4a95, 0x0b34e8db, 0x09ca9ebd, 0x4e7c}}, + {{0x17dcaae6, 0x02ce5060, 0x3f7dd33e, 0x02e5852f, 0x2f681b53, 0x3f427db7, 0x10b18e16, 0x271d9b27, 0x1774}}}, + /* 3*16^23*G: */ + {{{0x2521b3ff, 0x38a61193, 0x1aa750ce, 0x0f01c5fa, 0x2e24a523, 0x1134afa6, 0x1455c75e, 0x138c0432, 0x0248}}, + {{0x0269da7e, 0x306b92e4, 0x23ac8bbc, 0x1c01b7a4, 0x2d0eebad, 0x30acf0ac, 0x3e30d07e, 0x34282a88, 0x9619}}}, + /* 5*16^23*G: */ + {{{0x004ba7b9, 0x25ade7ea, 0x0741751f, 0x35a91c0c, 0x2c954e20, 0x26dc359c, 0x2ce57ef7, 0x3149b3ed, 0x16c1}}, + {{0x1c5bd741, 0x1d6f8e94, 0x1c9a9cc4, 0x1d57006f, 0x0a94deec, 0x189d1672, 0x31439062, 0x1fdf0d00, 0xdb15}}}, + /* 7*16^23*G: */ + {{{0x236683fa, 0x20d921ea, 0x0ec0825e, 0x2086d4e0, 0x127b6695, 0x22739dd1, 0x131af87a, 0x0f35d4fe, 0x0397}}, + {{0x3f4a577f, 0x3d7ecadd, 0x3e981ded, 0x1e213863, 0x35a26cd7, 0x384ad8ca, 0x0a3a3643, 0x168b30c3, 0x38cf}}}, + /* 9*16^23*G: */ + {{{0x00bf6f06, 0x202ce667, 0x1043b571, 0x0f04cc89, 0x20576571, 0x3013d2c0, 0x0f1511c2, 0x26ee9cbb, 0xba6a}}, + {{0x381db551, 0x0cafbdc1, 0x0697aafe, 0x17453deb, 0x18bd8e9e, 0x082fcb95, 0x211b0320, 0x078e2cd2, 0x1377}}}, + /* 11*16^23*G: */ + {{{0x31231a43, 0x347be7c1, 0x1ad43b9f, 0x35453599, 0x1e442f44, 0x3b654193, 0x04dd2d8a, 0x2f3309f3, 0x35c5}}, + {{0x1620c8f6, 0x36dcb914, 0x23cf0ae7, 0x3de93301, 0x3a589d4c, 0x396082db, 0x346ce734, 0x1d5c8ee5, 0x0e36}}}, + /* 13*16^23*G: */ + {{{0x3dd40609, 0x3d02f15b, 0x181cd76b, 0x10642603, 0x08356ac7, 0x0bc4bf16, 0x186bca12, 0x27091715, 0xfd47}}, + {{0x2a64ca53, 0x378bc4d9, 0x21ca4739, 0x04ebb5c9, 0x1841fd91, 0x2b5e90f2, 0x0afeff2c, 0x33ed49a5, 0x3069}}}, + /* 15*16^23*G: */ + {{{0x2b799a7f, 0x36dc0bd4, 0x3b8e8424, 0x062db354, 0x2c7d544f, 0x363ae6bc, 0x0d864bde, 0x000a8eb3, 0x6c40}}, + {{0x13c81e32, 0x2d7320b3, 0x20483f68, 0x1eaf5320, 0x1ddcbdc0, 0x2e0da838, 0x235be690, 0x37054c2d, 0x95c2}}} + }, + { + /* 1*16^24*G: */ + {{{0x00fb27b6, 0x0909f8a1, 0x24305763, 0x1b8f6caf, 0x286aa5c7, 0x08e2b585, 0x38b1b10f, 0x138f6f9d, 0xfea7}}, + {{0x323cb96f, 0x0074f6df, 0x33f7b777, 0x1ad65ae5, 0x36af9312, 0x19d37b32, 0x313297cf, 0x1a36e6c2, 0x6e05}}}, + /* 3*16^24*G: */ + {{{0x3e889756, 0x37606ba6, 0x3004bb25, 0x1ed9265e, 0x1899f3f2, 0x3365ec9c, 0x1fea8226, 0x22f0cc84, 0x762e}}, + {{0x3ca6b774, 0x17896781, 0x084fa5e2, 0x1cb6cc52, 0x02e34719, 0x3313c526, 0x3e97c3c7, 0x250982bc, 0xc028}}}, + /* 5*16^24*G: */ + {{{0x0975d2ea, 0x1bdd7a5c, 0x014e8ea2, 0x14ab3e84, 0x08f4a91e, 0x26f6ec8c, 0x095348e1, 0x1f51f7d8, 0xdf07}}, + {{0x31936f95, 0x28f0b678, 0x3bdd277a, 0x07b16e13, 0x22527c8a, 0x21097262, 0x37f4424c, 0x1ea2003b, 0xf861}}}, + /* 7*16^24*G: */ + {{{0x3c4c92d7, 0x2e1247ee, 0x14391b45, 0x36d35bb9, 0x0b142935, 0x1f7aa0cd, 0x3da032e1, 0x1f5d62f4, 0x9f3e}}, + {{0x314906dd, 0x32eeff3e, 0x294e1186, 0x0a88c0f5, 0x2b150245, 0x18ac872e, 0x1466b588, 0x2107a9df, 0xecd2}}}, + /* 9*16^24*G: */ + {{{0x32a8c483, 0x2b835cca, 0x1040ac35, 0x12c32231, 0x39528117, 0x230f48bb, 0x0cf9edc3, 0x1e575ed7, 0xa0cc}}, + {{0x12cc6ba9, 0x0259d156, 0x36936055, 0x0d23c6f7, 0x31df786b, 0x1d3f25c8, 0x3873ee23, 0x0048be2c, 0xabc3}}}, + /* 11*16^24*G: */ + {{{0x05dd3aee, 0x1c3c6daf, 0x396d2f21, 0x054ea2a3, 0x2976ca13, 0x08aa6b1a, 0x3c7cce0e, 0x14294554, 0x6d1c}}, + {{0x3df597f7, 0x3b8d5393, 0x0ed53adf, 0x078c42aa, 0x07d47485, 0x09c8008a, 0x3dfdc977, 0x052381aa, 0xafff}}}, + /* 13*16^24*G: */ + {{{0x24a6d0bb, 0x1e32a6df, 0x1a1afdc6, 0x274c48bd, 0x26418f65, 0x069b62a2, 0x3f9f3f31, 0x075862e5, 0x5e5f}}, + {{0x1033eaf9, 0x1a0e11e4, 0x06f653a1, 0x1557cb94, 0x2721da72, 0x3daf3413, 0x3e6f7358, 0x140ac1a9, 0xd7b1}}}, + /* 15*16^24*G: */ + {{{0x0f005e3f, 0x36a6d791, 0x2c39bd2d, 0x3da38c6f, 0x01a1495a, 0x0f2e6b38, 0x2427fffd, 0x229acf05, 0xf813}}, + {{0x2f357eb7, 0x0b5f8080, 0x14be2134, 0x3b106f55, 0x25cb51f4, 0x005795ea, 0x0ebd9f9d, 0x23cefbed, 0xca75}}} + }, + { + /* 1*16^25*G: */ + {{{0x17bdde39, 0x0b00a910, 0x36043295, 0x11385e6d, 0x1968d315, 0x095c3566, 0x3cf0e10a, 0x1044fd9d, 0x76e6}}, + {{0x1901ac01, 0x12c5d4b4, 0x16d2032b, 0x0a8cf4ad, 0x01f0d35e, 0x019b5c1a, 0x295cf577, 0x37e37b93, 0xc90d}}}, + /* 3*16^25*G: */ + {{{0x0078ee8d, 0x3c142473, 0x06919442, 0x2fc83394, 0x1b4ff64e, 0x3dc98eaa, 0x1a9be25f, 0x15eb6167, 0xd08e}}, + {{0x2da63e86, 0x265fd370, 0x022ed9de, 0x0fbdf3e5, 0x3e6df412, 0x05cbb9d5, 0x088d72d6, 0x25e612ad, 0x852e}}}, + /* 5*16^25*G: */ + {{{0x029129ec, 0x164519c1, 0x24825481, 0x2b8eb3c7, 0x131d080c, 0x22fa03b3, 0x04d275f5, 0x30217935, 0x7da6}}, + {{0x2cd9ff0e, 0x2d42bb8a, 0x0ca586ae, 0x12302195, 0x1627bf04, 0x34081d24, 0x01857511, 0x051aee7d, 0xf498}}}, + /* 7*16^25*G: */ + {{{0x11654f22, 0x3e0f5255, 0x31aaee94, 0x3dfce508, 0x29d94fb2, 0x3a4006f9, 0x1be6e21b, 0x2433fd70, 0x90d0}}, + {{0x201a43e1, 0x3d77815d, 0x1a3f8740, 0x358d594f, 0x3f70336d, 0x3c08781a, 0x0f61a953, 0x26874aeb, 0xcd56}}}, + /* 9*16^25*G: */ + {{{0x076b19fa, 0x2dbbd947, 0x28819d71, 0x35b81b41, 0x21292ed9, 0x08b0c420, 0x1d1ecc73, 0x26161f3c, 0xda47}}, + {{0x326f5af7, 0x2a89bbac, 0x153fc206, 0x1ef44fa5, 0x16569ea6, 0x0da41df8, 0x0af01d17, 0x35de26f3, 0xebb1}}}, + /* 11*16^25*G: */ + {{{0x39135dbd, 0x364bed96, 0x1d8631ec, 0x3021ebce, 0x29897cf0, 0x1eabd60b, 0x1ee6ad81, 0x1d412a37, 0xe3e4}}, + {{0x0748045d, 0x241abcf9, 0x2c95da96, 0x2880bfd7, 0x383ffea5, 0x2320654a, 0x3c6c40b9, 0x16fe0272, 0x930a}}}, + /* 13*16^25*G: */ + {{{0x0dee455f, 0x2fc2e797, 0x0ce4075c, 0x19fff9ba, 0x0bdb4aff, 0x114ce3e0, 0x0a9b0a47, 0x195bfa1c, 0x7e8c}}, + {{0x171b9cba, 0x1cf7a660, 0x2f466271, 0x28b459d1, 0x03a53b4a, 0x3dd83d20, 0x0740f2a3, 0x318cb28c, 0xbddd}}}, + /* 15*16^25*G: */ + {{{0x2698b59e, 0x1de5ae6d, 0x13447a43, 0x0cd64962, 0x23c7260a, 0x2c0d6acf, 0x15eb15be, 0x107e246a, 0x3df8}}, + {{0x2b92baf5, 0x33e399e5, 0x14949f8b, 0x3f219ec8, 0x1cf3867b, 0x0aeba3c4, 0x090c1da0, 0x39b7e62c, 0xb38f}}} + }, + { + /* 1*16^26*G: */ + {{{0x2bcbb891, 0x2ac54090, 0x326cbee3, 0x1f3190f7, 0x3f8f9a8f, 0x206ea9d0, 0x2abe1e82, 0x315ac0ec, 0xc738}}, + {{0x299a84c3, 0x1f9cd765, 0x080cfe91, 0x0c53bbde, 0x3fbbbb82, 0x063cbab2, 0x2d2537f7, 0x2d5e2546, 0x893f}}}, + /* 3*16^26*G: */ + {{{0x0761d58d, 0x12eabcce, 0x0d60e2f3, 0x1326f902, 0x20df7aca, 0x09028d5c, 0x3614610a, 0x1849e08f, 0xb8c4}}, + {{0x1d1051a4, 0x0e3a82ea, 0x2107c5b6, 0x1d411e17, 0x33c5053f, 0x1163da5f, 0x0e37d14a, 0x365b145c, 0x8f9e}}}, + /* 5*16^26*G: */ + {{{0x050b0040, 0x36c2cc10, 0x0134adc2, 0x3d1f6e7c, 0x1a3671f3, 0x03264ffa, 0x271f7a35, 0x1ba7dc40, 0x08d5}}, + {{0x1b3fd0a1, 0x163899e9, 0x21782beb, 0x35f11c83, 0x39b285f6, 0x34542a35, 0x29aa21ff, 0x216baf42, 0xa121}}}, + /* 7*16^26*G: */ + {{{0x13573b7f, 0x15958f7c, 0x30b6270f, 0x268717b4, 0x265a3788, 0x083e5def, 0x3ce6341e, 0x3c8cb50b, 0xdc13}}, + {{0x0c1f2ba6, 0x0ab348a1, 0x3404b1c4, 0x11551c05, 0x290a7670, 0x10436a12, 0x2340c3c7, 0x2ea010a7, 0xc909}}}, + /* 9*16^26*G: */ + {{{0x07ae9ceb, 0x00bd642e, 0x0ef2d14b, 0x1b087a9c, 0x2119a822, 0x0655976c, 0x37f073af, 0x0b798077, 0x25c0}}, + {{0x0bc6e275, 0x1c24344d, 0x26587264, 0x319077c2, 0x2d11d537, 0x2138373e, 0x2383c0c8, 0x3ab4b204, 0x8a9f}}}, + /* 11*16^26*G: */ + {{{0x2c5a3c34, 0x3e0263db, 0x15949fe1, 0x33a0b00a, 0x2e3e58ae, 0x2e7d329e, 0x0e49ce8a, 0x2746cb3e, 0xfedd}}, + {{0x213d7714, 0x0ad52fd3, 0x1bf82976, 0x2bad51a6, 0x0f4b00ad, 0x3a14c4b2, 0x3b8e0b0b, 0x0930c614, 0xa52e}}}, + /* 13*16^26*G: */ + {{{0x2ab6a396, 0x2d395346, 0x11360769, 0x0086e468, 0x0488b373, 0x38b5fd7a, 0x2a48c2de, 0x0ca1af1b, 0x3e0e}}, + {{0x1980e27e, 0x3acc7923, 0x3468f6a2, 0x2c04107c, 0x053fc66a, 0x07f877ad, 0x337964f3, 0x205cbe8e, 0xca44}}}, + /* 15*16^26*G: */ + {{{0x341023ec, 0x2bcd6188, 0x3ecf570a, 0x11763ddb, 0x02b9af56, 0x0b808026, 0x32d28498, 0x2e4c2030, 0x344a}}, + {{0x1e1eeb87, 0x13e260a4, 0x03995d70, 0x13a5dabf, 0x114c5ffc, 0x23cb47a9, 0x0462a73f, 0x0ac10ac9, 0x6e1c}}} + }, + { + /* 1*16^27*G: */ + {{{0x08f6c14b, 0x1cba7d96, 0x29250143, 0x35cb97ce, 0x172877d1, 0x131d8df2, 0x25b81e26, 0x1899522d, 0xd895}}, + {{0x1d7d991f, 0x24d8fb5d, 0x3b067e17, 0x10a358ca, 0x0340eb03, 0x3b182063, 0x07eae728, 0x2a8e3caf, 0xfebf}}}, + /* 3*16^27*G: */ + {{{0x2127b756, 0x02ea1ffd, 0x3a097048, 0x10a2f92a, 0x20b41603, 0x0d8b6941, 0x1f12672d, 0x1e0bdc5b, 0x6d8c}}, + {{0x3f172571, 0x1547dd2a, 0x17cdcca6, 0x0ea9b68b, 0x134daf4e, 0x26a0b4db, 0x1b911145, 0x37c225bf, 0x99ae}}}, + /* 5*16^27*G: */ + {{{0x358cf17a, 0x37b869cd, 0x18823524, 0x3e1772e9, 0x0097f8f1, 0x166bbc6d, 0x37aca8d0, 0x2fb7656f, 0xebca}}, + {{0x1caa0ccd, 0x11b3717d, 0x0ace95c4, 0x3eb484b4, 0x032e6b10, 0x00286d9f, 0x2b9cb02c, 0x3383e3c8, 0x47d3}}}, + /* 7*16^27*G: */ + {{{0x2c855c5b, 0x33bb9456, 0x17c8afbb, 0x21588680, 0x17fc2811, 0x0c68da78, 0x0ce24453, 0x134b92f5, 0xe8df}}, + {{0x2e465650, 0x27579cb0, 0x21e4d7d5, 0x18ed57c7, 0x2f32c596, 0x136d3d67, 0x39b26444, 0x3f5c311f, 0x6c57}}}, + /* 9*16^27*G: */ + {{{0x12e7e454, 0x023d6f69, 0x30e6150d, 0x0cbbfbc3, 0x181662fe, 0x121808ea, 0x0a832912, 0x34f5c63b, 0x4068}}, + {{0x18ef191e, 0x1e6b3797, 0x3c373327, 0x23487b44, 0x1d38d198, 0x305165f6, 0x247aab9e, 0x14edc952, 0x8cd8}}}, + /* 11*16^27*G: */ + {{{0x06c5d939, 0x215eb7e1, 0x3a933de0, 0x1d68a1de, 0x0a027ea4, 0x2fccb983, 0x025e0b55, 0x03b36c76, 0x1255}}, + {{0x19e757c9, 0x0a9d3f15, 0x0d8d4319, 0x22dd07fb, 0x324a7283, 0x2390f05d, 0x2d7a7544, 0x20cd3e1c, 0x7b8f}}}, + /* 13*16^27*G: */ + {{{0x16c8a56f, 0x2342ab19, 0x0f374213, 0x024f150d, 0x3ad08f85, 0x2eded4eb, 0x185d4c69, 0x19c6b0ed, 0x944d}}, + {{0x1a7be289, 0x27d37197, 0x106517eb, 0x35305d37, 0x3ac61967, 0x10e4d84c, 0x01fff4c1, 0x1965ded4, 0xa710}}}, + /* 15*16^27*G: */ + {{{0x2e08f15a, 0x3bae2862, 0x012900ba, 0x1a795b72, 0x13c305fd, 0x2c0d956b, 0x19a0cfe6, 0x13a47342, 0x86a5}}, + {{0x01388308, 0x1493479f, 0x335254d3, 0x04a74496, 0x35686777, 0x0aa341b5, 0x384603a7, 0x18520de9, 0xcfee}}} + }, + { + /* 1*16^28*G: */ + {{{0x0f676e03, 0x24542959, 0x3e84edd4, 0x3ff1cda4, 0x1e8761ce, 0x3d90cd5c, 0x17518eb0, 0x2500caa5, 0xb8da}}, + {{0x0efdf6e7, 0x1223939d, 0x1ff3b511, 0x33161365, 0x2808b092, 0x267325d8, 0x1a1e4d7c, 0x37e91201, 0x2804}}}, + /* 3*16^28*G: */ + {{{0x06e1346b, 0x28661277, 0x05af1c5e, 0x2f9ec40e, 0x1152c05a, 0x31d87c53, 0x2d10be54, 0x1a3fc260, 0x0690}}, + {{0x17226c13, 0x2ed62953, 0x0c6026e7, 0x3da24e65, 0x06442aa4, 0x176caf42, 0x3de26da8, 0x38f8242f, 0xb863}}}, + /* 5*16^28*G: */ + {{{0x1ca1f6a1, 0x039a47f3, 0x08cff1a3, 0x232f450d, 0x286ce106, 0x1b7172c7, 0x19761528, 0x0d24f2c9, 0x898c}}, + {{0x164f647c, 0x12b7083c, 0x32bd79ca, 0x29f3e5e7, 0x2c6e93b2, 0x1150914a, 0x2a5549d8, 0x1661aad5, 0x75f7}}}, + /* 7*16^28*G: */ + {{{0x3d1e3998, 0x29a780f0, 0x3a04328a, 0x15b22e45, 0x2a274e5e, 0x0a675c08, 0x18bf01a5, 0x38bfb4a4, 0xb213}}, + {{0x325fb81e, 0x30b2f718, 0x3ded175e, 0x0d0596fa, 0x243bc3d5, 0x187afe0e, 0x13c12c3d, 0x23b083cb, 0x229f}}}, + /* 9*16^28*G: */ + {{{0x225be234, 0x02f87fb2, 0x1df35070, 0x20f8f9c3, 0x206e060e, 0x342e9a45, 0x3f93e5d1, 0x0eb605b1, 0x4b3b}}, + {{0x120e8362, 0x18edf80e, 0x3211b840, 0x39ff64b3, 0x0cc04c41, 0x17a5b7f6, 0x2bc9c787, 0x008ee176, 0x5eec}}}, + /* 11*16^28*G: */ + {{{0x2289f55e, 0x2598d29f, 0x2c76707b, 0x1dac3c38, 0x0965be29, 0x0946c09e, 0x04f96020, 0x222db76c, 0x9f7b}}, + {{0x3e1e4bde, 0x0f34ed97, 0x310a2b1b, 0x394db83a, 0x0fc71fc0, 0x051ad0a6, 0x010f7be3, 0x3de131c1, 0x32f9}}}, + /* 13*16^28*G: */ + {{{0x1dfe1d2b, 0x19527230, 0x16878e51, 0x24fd4279, 0x3b73a4c4, 0x332b7f4f, 0x048e3e76, 0x10fa72dd, 0xd58a}}, + {{0x0cd50922, 0x33c9e56e, 0x0bd6fbff, 0x366e8857, 0x28276b54, 0x1ca44ca0, 0x083cf10a, 0x219ae816, 0xfc17}}}, + /* 15*16^28*G: */ + {{{0x249c795e, 0x090546f8, 0x1ce805e1, 0x1101aaa6, 0x27ea4eed, 0x365a70f0, 0x18310cd6, 0x1c4e5c44, 0x21d2}}, + {{0x19208ece, 0x0004bb0e, 0x2dfb761b, 0x1c651292, 0x2bb4c3d6, 0x0d6e1548, 0x1acea177, 0x3e6d2c1d, 0x94c5}}} + }, + { + /* 1*16^29*G: */ + {{{0x23c0df5d, 0x06845de3, 0x156a792f, 0x067bfed4, 0x1d7fab20, 0x2b6ae51d, 0x3b33a7d8, 0x3a851107, 0xe80f}}, + {{0x2ac9ec78, 0x32d0a46d, 0x3322ea9f, 0x0557a02b, 0x0a94472d, 0x25da328f, 0x200771e8, 0x379fd8e3, 0xeed1}}}, + /* 3*16^29*G: */ + {{{0x17592d55, 0x300d67b3, 0x0e350192, 0x356e51d0, 0x3ce3b106, 0x3fbda58c, 0x1052608a, 0x31b6f128, 0x5d2e}}, + {{0x2f5183a7, 0x19b9743a, 0x11151742, 0x0a9ef36b, 0x0cd6950e, 0x1c43e89a, 0x245eb58f, 0x337e271b, 0x0a92}}}, + /* 5*16^29*G: */ + {{{0x3e8f9f5c, 0x247d2d27, 0x1880a519, 0x187c7856, 0x1f404d73, 0x32b8d085, 0x3f742fe2, 0x0770ec46, 0xac37}}, + {{0x325a503c, 0x1ea0ffcc, 0x2751e1d1, 0x254d163b, 0x14e73522, 0x04079cc9, 0x1a477ff2, 0x05b061c2, 0xc516}}}, + /* 7*16^29*G: */ + {{{0x19e33446, 0x12872354, 0x2af385df, 0x224ef114, 0x22a17a40, 0x2302f408, 0x1840c934, 0x000e853c, 0x8942}}, + {{0x26387689, 0x034e2803, 0x1e74f984, 0x3f5dcd9e, 0x3de4e06b, 0x2cb5b43b, 0x1077a4d8, 0x00e56569, 0xa9fd}}}, + /* 9*16^29*G: */ + {{{0x3913cb26, 0x35ca3256, 0x13bd6d03, 0x3ad06700, 0x105c9899, 0x36913fd5, 0x342a8a2c, 0x099acc28, 0x2770}}, + {{0x3348a7a2, 0x3f9c5ccf, 0x0815bebb, 0x103246f3, 0x32b324e9, 0x0b49341f, 0x0db1a555, 0x2f179e6c, 0xf649}}}, + /* 11*16^29*G: */ + {{{0x195e8247, 0x02aa8085, 0x286cd1af, 0x2ff71155, 0x38ba9097, 0x179b8073, 0x3ed2178e, 0x3434e0f2, 0x75e4}}, + {{0x19982d22, 0x288ff675, 0x29ad893c, 0x36ad6dba, 0x3726d47d, 0x3e5c3b1e, 0x10990741, 0x10a85d50, 0x1fce}}}, + /* 13*16^29*G: */ + {{{0x26333323, 0x11e7d136, 0x0f4abf47, 0x2eef071a, 0x04da849c, 0x08358166, 0x1bbf03f0, 0x2d8e0cd8, 0x3ed1}}, + {{0x35d61ba3, 0x2c4ff122, 0x378f7294, 0x2dca2842, 0x0f929ea9, 0x1f2625a2, 0x34ee75d9, 0x0b6922d6, 0xd84f}}}, + /* 15*16^29*G: */ + {{{0x333980bf, 0x09415f52, 0x0dd00baf, 0x28dc0b94, 0x08dd4368, 0x1bf5dc8d, 0x18181b84, 0x34bc1a9d, 0x70fd}}, + {{0x20b75785, 0x0bbaa33a, 0x1d74a561, 0x040d60e1, 0x2e596b0a, 0x29043447, 0x18696957, 0x32b03435, 0x5edf}}} + }, + { + /* 1*16^30*G: */ + {{{0x04e16070, 0x3701eef3, 0x2fd6915d, 0x286080c7, 0x167543f2, 0x29239475, 0x1704313b, 0x1a5ef7f3, 0xa301}}, + {{0x1e177ea1, 0x30346810, 0x0a11a130, 0x0d76fdf0, 0x140f9b17, 0x2027e897, 0x3e4f5081, 0x3e473ed9, 0x7370}}}, + /* 3*16^30*G: */ + {{{0x138011fc, 0x1c049c00, 0x17285626, 0x165a99eb, 0x200a4d83, 0x2c4cc208, 0x1eb11156, 0x04e8c205, 0x6e83}}, + {{0x3f15ab7d, 0x2b2da7e8, 0x1c51f9a6, 0x2be456ba, 0x1ac30426, 0x04b6c807, 0x0f204c1a, 0x2062f709, 0xc147}}}, + /* 5*16^30*G: */ + {{{0x100e6ba7, 0x0e9d26e3, 0x0916f7f5, 0x0dbb16d1, 0x19e1b43d, 0x0780e293, 0x0851f2bd, 0x2a4265e1, 0xf952}}, + {{0x0175e4c1, 0x36ebbb94, 0x062a2b98, 0x15c59ed3, 0x3fa0f655, 0x0dda8b89, 0x3cebf861, 0x0e96c22a, 0xd8a9}}}, + /* 7*16^30*G: */ + {{{0x03aa0e93, 0x2401968a, 0x2fb1f626, 0x0b8e50eb, 0x1e893a8f, 0x00c68676, 0x3fee7504, 0x1b578c74, 0x9401}}, + {{0x07addac2, 0x23bb49a2, 0x257b07a3, 0x210dceea, 0x2e6fd7f4, 0x1574d53b, 0x14d96403, 0x0cbb9711, 0x6750}}}, + /* 9*16^30*G: */ + {{{0x0266b17b, 0x03d218b8, 0x262bb32b, 0x0d5a2880, 0x1f09c202, 0x25e211aa, 0x3b2891bb, 0x345d3567, 0xef22}}, + {{0x39dac83e, 0x0a9b810d, 0x1c341b73, 0x39c9dbdc, 0x34a1073e, 0x27330eb8, 0x24c7568f, 0x21325eac, 0xbc57}}}, + /* 11*16^30*G: */ + {{{0x12d382a0, 0x0c4c056a, 0x2ecd9ae2, 0x2372ef38, 0x2df927f2, 0x2b31e02c, 0x3892d39c, 0x3bf3933a, 0xb5f7}}, + {{0x25b4b532, 0x28bc2aee, 0x1acf8c5b, 0x3ec25b4a, 0x0bddd371, 0x255f1b83, 0x3f2353c0, 0x1516d470, 0x6843}}}, + /* 13*16^30*G: */ + {{{0x012cffa5, 0x39a49191, 0x28cc5c47, 0x3b508219, 0x14624389, 0x1d5363ef, 0x31076408, 0x30f4acb9, 0x1cdd}}, + {{0x1521954e, 0x379b6273, 0x336b528a, 0x0726109a, 0x02b08ac4, 0x2c49afe5, 0x1f8a63fd, 0x1a832cbc, 0x1e47}}}, + /* 15*16^30*G: */ + {{{0x34a9f22f, 0x0d7f90e4, 0x17a8e2ad, 0x02067148, 0x0835b0cc, 0x3e2e2e52, 0x0e939f21, 0x2cd67c97, 0x2acc}}, + {{0x375c4927, 0x2dd772ce, 0x1ba550b7, 0x12f5efb1, 0x30edf115, 0x04e8dfb7, 0x2d2e5192, 0x293a5622, 0xd518}}} + }, + { + /* 1*16^31*G: */ + {{{0x3fb04ed4, 0x2deb18f8, 0x1307fffa, 0x330cc2c4, 0x278de208, 0x3e741449, 0x2b936463, 0x216ce275, 0x90ad}}, + {{0x0b6ef150, 0x24753523, 0x182894d9, 0x2bbeaf85, 0x3222b839, 0x372f6509, 0x38261aff, 0x1e8d8828, 0x0e50}}}, + /* 3*16^31*G: */ + {{{0x30b7b678, 0x09d76cce, 0x0f638166, 0x0f10c46f, 0x2b6c76f1, 0x21af2909, 0x0231ba19, 0x125ccd39, 0x186e}}, + {{0x38d91fc1, 0x1e81dbcb, 0x09535dca, 0x01dc8951, 0x37e67e11, 0x3f209702, 0x3bd84aa7, 0x18392601, 0xc0d4}}}, + /* 5*16^31*G: */ + {{{0x33421fb8, 0x3c1b972e, 0x35a55d0c, 0x125c7cbb, 0x37241298, 0x01acd30e, 0x1bf62e7e, 0x2360d3db, 0x061c}}, + {{0x0e3ccd80, 0x257bd9a1, 0x26fcdd29, 0x19c4d2ce, 0x05eb5c80, 0x0e496438, 0x3b4b7ba9, 0x1ab66400, 0x6dfc}}}, + /* 7*16^31*G: */ + {{{0x2f6b35a4, 0x0492f862, 0x327fb487, 0x27cde9aa, 0x3a68ad88, 0x18c901cc, 0x2e513b73, 0x2d8e8823, 0xf6a6}}, + {{0x01f422a6, 0x2badbfb2, 0x1ee1862c, 0x355d5b9d, 0x20186f19, 0x34dc13d5, 0x1138b1ca, 0x322a000b, 0x3df7}}}, + /* 9*16^31*G: */ + {{{0x26954c11, 0x25a08fa2, 0x160d018b, 0x2a290f05, 0x0778ff7f, 0x346c3c54, 0x2c376220, 0x3f0a30a1, 0x87a2}}, + {{0x272a8b45, 0x15b8ccb8, 0x278124b7, 0x1224cfca, 0x127532cc, 0x06523683, 0x2ecef97b, 0x1462d16a, 0x33ad}}}, + /* 11*16^31*G: */ + {{{0x22706ab6, 0x391d1cab, 0x2e53c0da, 0x02cd0774, 0x384cfe3c, 0x15bbf2f0, 0x081a6845, 0x0b811b9e, 0xe147}}, + {{0x1d58de05, 0x1ba1a85a, 0x13cd2753, 0x16275551, 0x0621f8aa, 0x1a465e32, 0x18fc683f, 0x24aa91f1, 0x82cd}}}, + /* 13*16^31*G: */ + {{{0x07a84fb6, 0x2feb9508, 0x3a15021e, 0x08da1d43, 0x08b9ebc4, 0x2d358079, 0x0aef5de8, 0x24b2013e, 0x1caf}}, + {{0x27149109, 0x1ac60640, 0x22ce6761, 0x07305a5a, 0x101622ec, 0x2993e3fc, 0x2e53a481, 0x2e16b25d, 0xbc24}}}, + /* 15*16^31*G: */ + {{{0x0a955911, 0x1da33f85, 0x0ded52db, 0x1f85a898, 0x17839710, 0x27bfa6cf, 0x1650d258, 0x3f5a6bc2, 0x705b}}, + {{0x3fd200e4, 0x2edf1a4f, 0x242e72d8, 0x1fced48a, 0x0051fa29, 0x18f607d5, 0x3f990a7e, 0x2904c2dc, 0xe14a}}} + }, + { + /* 1*16^32*G: */ + {{{0x1ec4c0da, 0x2ded1132, 0x23ea3351, 0x23159e1c, 0x1f162ee8, 0x2706b660, 0x35f33923, 0x2e74bd8e, 0x8f68}}, + {{0x101fff82, 0x08f2fde5, 0x1510bfdf, 0x3a8b3fa5, 0x3e215dbb, 0x36430ada, 0x23986de1, 0x27cb6e81, 0x662a}}}, + /* 3*16^32*G: */ + {{{0x123809fa, 0x238ae3b7, 0x1d954be1, 0x21172cd4, 0x051f08fd, 0x24cd8fc9, 0x09f228ba, 0x076f8b94, 0x3838}}, + {{0x331fed52, 0x35c1d460, 0x2d8f24db, 0x207f32cc, 0x0eb1cc36, 0x10169548, 0x117dcb09, 0x0b4283ee, 0xe4a3}}}, + /* 5*16^32*G: */ + {{{0x17c2a310, 0x3a909922, 0x01226303, 0x21aba950, 0x0699a1f1, 0x086e0aa9, 0x32ae6f69, 0x09c9390d, 0x4926}}, + {{0x1e27ded0, 0x3106da05, 0x35ff8ce0, 0x058d84a9, 0x14303b6d, 0x33e95a5c, 0x3abf95a2, 0x39dcef29, 0x1337}}}, + /* 7*16^32*G: */ + {{{0x0ebd2d31, 0x0e12c1e7, 0x306db8d1, 0x330695bf, 0x37e2f84d, 0x094ecf91, 0x00c90d5e, 0x15a30689, 0xe306}}, + {{0x12546e44, 0x24ad020e, 0x23738266, 0x2f2010af, 0x3d0db6ff, 0x3cac41fd, 0x34260888, 0x1bf8de24, 0x0eac}}}, + /* 9*16^32*G: */ + {{{0x363136b0, 0x14c30e78, 0x2b41dd9c, 0x3afe366a, 0x3bd63374, 0x2c39d88f, 0x0cefc271, 0x0403890a, 0x3b9e}}, + {{0x2cdbbc8a, 0x14fb05bd, 0x2d31f819, 0x2b8a28ce, 0x075b26a2, 0x14cfae3d, 0x2bb71df1, 0x26054b45, 0xfafb}}}, + /* 11*16^32*G: */ + {{{0x2f485d3f, 0x1823c11c, 0x107beee9, 0x3281da20, 0x1edef717, 0x1b2a03d7, 0x2c9a92b7, 0x2b525c4a, 0xbb0a}}, + {{0x3ca2f975, 0x1e4e4940, 0x1670bffe, 0x1696be8c, 0x17da3489, 0x34807dca, 0x354798ec, 0x2714f160, 0xea69}}}, + /* 13*16^32*G: */ + {{{0x36718dc9, 0x2bbb4ce8, 0x01123de4, 0x3962d36c, 0x3e0113e1, 0x23ac65eb, 0x2fcc0d4e, 0x02b2393b, 0x7909}}, + {{0x1cfae7c5, 0x18cc8ac4, 0x3a9008b9, 0x0dabedc2, 0x1aaa56dd, 0x205b2f36, 0x05b8f13d, 0x1c8ae464, 0xeaab}}}, + /* 15*16^32*G: */ + {{{0x3f60c7d1, 0x09a5a531, 0x1775ad2a, 0x35c779f3, 0x09ba668d, 0x0f6ef395, 0x17b551c0, 0x206b7a7e, 0xe77c}}, + {{0x02d72449, 0x3b1607ca, 0x02986d34, 0x051c3dc7, 0x28154363, 0x30ecc8fa, 0x01321c5f, 0x051e3bbe, 0x3acf}}} + }, + { + /* 1*16^33*G: */ + {{{0x13231e11, 0x1a1bf541, 0x3681e3e6, 0x123a1940, 0x0c36091f, 0x267fe466, 0x385d65ff, 0x3ec05dab, 0xe4f3}}, + {{0x2feb73bc, 0x08b0e15d, 0x151d1c98, 0x31f9d3b2, 0x02b7286c, 0x069b43a8, 0x34f1c166, 0x18ceb43b, 0x1e63}}}, + /* 3*16^33*G: */ + {{{0x2bf05bd6, 0x0e67c139, 0x12a99465, 0x3d5b80c8, 0x070deca2, 0x0bd47fad, 0x04fe9083, 0x0c906fb9, 0x900c}}, + {{0x300d358b, 0x394ab4ef, 0x04efb15d, 0x2614d60f, 0x0b2439d6, 0x31c8115c, 0x1f0f5f95, 0x3e7a3a2c, 0x6c31}}}, + /* 5*16^33*G: */ + {{{0x1f105c50, 0x29f0a332, 0x31385257, 0x3837bbde, 0x0233cd82, 0x2330d00f, 0x190aad62, 0x00d8aac1, 0x5a8d}}, + {{0x38a4cde9, 0x326c8060, 0x2d013c35, 0x017da299, 0x03ff74a6, 0x29adc905, 0x0e536936, 0x3aac44f5, 0xc059}}}, + /* 7*16^33*G: */ + {{{0x32d64feb, 0x11f862e6, 0x292292c6, 0x1cbe2964, 0x0ba4e837, 0x3ce95ddb, 0x2f60a48e, 0x1340c48c, 0xd93f}}, + {{0x34698359, 0x2c3ef564, 0x2c90da37, 0x3810c2fb, 0x1c8c4d93, 0x1cc47153, 0x32733a23, 0x15575172, 0x7925}}}, + /* 9*16^33*G: */ + {{{0x039fbc84, 0x08881335, 0x057a0167, 0x1c18a458, 0x2ac65b7e, 0x138af198, 0x328441b1, 0x1a71b8db, 0x2f07}}, + {{0x1c201bec, 0x3ee40b78, 0x04dd5d73, 0x29e6da93, 0x0e2149cc, 0x37c01e64, 0x3bdddfa5, 0x3cdc935c, 0xb434}}}, + /* 11*16^33*G: */ + {{{0x06a758ea, 0x14dfab32, 0x27f19c4d, 0x0620c624, 0x016e3991, 0x1a256855, 0x20309958, 0x19e01567, 0xfe7e}}, + {{0x1b7ab649, 0x13c8b657, 0x03120d1e, 0x2005c1d1, 0x09251f3b, 0x02385a61, 0x1dcb988c, 0x1a59e8a0, 0x38aa}}}, + /* 13*16^33*G: */ + {{{0x0cfffefa, 0x39c5589a, 0x0651afad, 0x060113dc, 0x03af8510, 0x3dbe4543, 0x03127d6d, 0x3d729d4e, 0x91ba}}, + {{0x1f7f6faf, 0x1f4dbcd3, 0x2fd303dc, 0x2fbcc439, 0x1d3d92f4, 0x25a7c49f, 0x3bcebe5d, 0x33c464d1, 0x04e5}}}, + /* 15*16^33*G: */ + {{{0x0d33c546, 0x3f0245fa, 0x05edaf32, 0x15d7ecca, 0x35ddd782, 0x314dcf83, 0x378a7cb2, 0x104872cf, 0x4458}}, + {{0x000b4fd4, 0x029b461c, 0x32ca7366, 0x0bc28f3e, 0x1ada2085, 0x097ab8e4, 0x0753a772, 0x24ddfcfe, 0x308d}}} + }, + { + /* 1*16^34*G: */ + {{{0x20eae29e, 0x1bedbab8, 0x14e1d071, 0x00d3cbc3, 0x1a4266c7, 0x1854de91, 0x3f331eb9, 0x3ea6c63a, 0x8c00}}, + {{0x2702414b, 0x1f4a9319, 0x1e36c54e, 0x3eb6bea0, 0x36c974c2, 0x30d0e8dc, 0x121a1a9d, 0x1c99ffa9, 0xefa4}}}, + /* 3*16^34*G: */ + {{{0x2bfd913d, 0x0fe5580f, 0x254c9eac, 0x29a039bb, 0x2a8d2050, 0x01e82130, 0x3ddf874d, 0x0aa9fa41, 0x3636}}, + {{0x052e243d, 0x113e6bab, 0x2b2faafc, 0x0c2ec435, 0x1a2a82d8, 0x18910dc3, 0x0afd5341, 0x1e19db2e, 0x48f2}}}, + /* 5*16^34*G: */ + {{{0x2d132896, 0x32aeafe6, 0x3bc6c967, 0x2c78eead, 0x19200dfc, 0x16b658b7, 0x21e02f29, 0x25db7cca, 0x4487}}, + {{0x2f685248, 0x23006c4a, 0x276aa7a4, 0x2d035698, 0x161a3306, 0x26a41dd1, 0x1afe1efc, 0x16183445, 0x27bd}}}, + /* 7*16^34*G: */ + {{{0x3fa2670c, 0x02055bda, 0x06273e6e, 0x003e0ae8, 0x35032474, 0x2a72aa0c, 0x383788b6, 0x0eb0a2f2, 0x4a4d}}, + {{0x16c1764d, 0x022e7ff7, 0x329beed8, 0x0c16532f, 0x302b9d49, 0x1dc4777b, 0x05a4f17e, 0x2e470061, 0x70ab}}}, + /* 9*16^34*G: */ + {{{0x0cb24aa7, 0x365abf89, 0x1345c530, 0x0c42318e, 0x38fe1890, 0x39bf627f, 0x11802c3a, 0x0b4642ba, 0x5f7b}}, + {{0x0a693d7d, 0x35e01d0d, 0x3c81d0c6, 0x237adc24, 0x267c47ce, 0x0fe028f3, 0x1f2b330a, 0x0d80313f, 0x0770}}}, + /* 11*16^34*G: */ + {{{0x2f7fb8bd, 0x0646f17c, 0x3e4090a4, 0x31192857, 0x0886d87b, 0x30939b65, 0x190d02ae, 0x1d144ce7, 0x5139}}, + {{0x03908c0f, 0x0252b0b6, 0x3f98d5a8, 0x3f0cb4f8, 0x015c47fa, 0x23fbf6ba, 0x03bf34b8, 0x050f91d9, 0xfcd7}}}, + /* 13*16^34*G: */ + {{{0x2e36ca73, 0x0add2457, 0x3bbf3ede, 0x321934da, 0x014887ea, 0x0a444afc, 0x3dfb8aa4, 0x05b58afe, 0xcf83}}, + {{0x2ec25534, 0x2d248650, 0x08d710f5, 0x25856636, 0x1cca681c, 0x11142243, 0x19d73e38, 0x2d637ad7, 0x09fe}}}, + /* 15*16^34*G: */ + {{{0x3752f97d, 0x3224df5a, 0x33476613, 0x0bbef1d7, 0x0fa6165a, 0x274a19a3, 0x3b49de53, 0x37a69312, 0x8610}}, + {{0x1f1b1af2, 0x015f7350, 0x05543e08, 0x2ad367d5, 0x33f99e57, 0x33666c94, 0x30bbc937, 0x25e80ad8, 0xd319}}} + }, + { + /* 1*16^35*G: */ + {{{0x20cb3e41, 0x25ff77f1, 0x08b92c09, 0x0f4213cc, 0x298ed314, 0x033b02a7, 0x0829f3e1, 0x1b39a775, 0xe7a2}}, + {{0x0f2cfd51, 0x3a2a5087, 0x20e83e20, 0x29acb010, 0x2fbb18d0, 0x2c01a86a, 0x3984b471, 0x238c03e9, 0x2a75}}}, + /* 3*16^35*G: */ + {{{0x3aee42db, 0x03e7f4af, 0x330714a7, 0x2eef16d1, 0x2cbfc1d9, 0x2dbb6e47, 0x19150fc7, 0x09f9f66d, 0xcc34}}, + {{0x15d87bdb, 0x188a7004, 0x272422dc, 0x3972eb63, 0x21520010, 0x38ff4fec, 0x1c6a1885, 0x26106948, 0xea24}}}, + /* 5*16^35*G: */ + {{{0x3ed4a086, 0x3d0d9b19, 0x29c410ef, 0x35d70563, 0x0b5cf4b1, 0x0f1617ef, 0x0445dec8, 0x016eb366, 0x948f}}, + {{0x1e2bca4b, 0x0a86003e, 0x03fa2d1a, 0x08ca29c7, 0x1139411c, 0x11429980, 0x22a3382f, 0x2a27fed6, 0x864c}}}, + /* 7*16^35*G: */ + {{{0x37542c21, 0x032fa9b2, 0x2a64c15c, 0x067d34a3, 0x1d6d43ae, 0x1bf11514, 0x19ac9065, 0x0658a4a4, 0x2584}}, + {{0x272bfabf, 0x2faf8c65, 0x0c2ad7b3, 0x38e861b9, 0x3513d5f3, 0x176a9331, 0x3244801e, 0x16c7c736, 0xfcb3}}}, + /* 9*16^35*G: */ + {{{0x0c1ecbf8, 0x0f1187d0, 0x2eed7ca4, 0x227c37a6, 0x28421f64, 0x25d53307, 0x3c52522a, 0x337104dc, 0x7e12}}, + {{0x30bed615, 0x3516e336, 0x3e1d9f59, 0x1a7d8763, 0x0d1259c9, 0x3e536af9, 0x1c837143, 0x13e22223, 0x7128}}}, + /* 11*16^35*G: */ + {{{0x14557d86, 0x1f999470, 0x2667ff41, 0x3fbb11e3, 0x05a6cf1c, 0x2e4729e8, 0x342a6772, 0x30bfca8d, 0x4b8e}}, + {{0x35167eb9, 0x3766c646, 0x3c3f692b, 0x357cbbc3, 0x27ac5f28, 0x101cb794, 0x157ab14a, 0x30ffc130, 0xfde6}}}, + /* 13*16^35*G: */ + {{{0x0780763c, 0x0ae0b4ed, 0x265691d5, 0x229b57a4, 0x3ac07e5f, 0x10db71a5, 0x23a42532, 0x3041cce5, 0xfcd5}}, + {{0x38e851cb, 0x1539d080, 0x16463a4b, 0x066c8b9c, 0x32e38cb1, 0x0836cd7d, 0x22c463b7, 0x2af8b954, 0x18dd}}}, + /* 15*16^35*G: */ + {{{0x1d8ef686, 0x338ef8c1, 0x2272e66b, 0x23923d00, 0x266e53f6, 0x22976be0, 0x3cbe5223, 0x0b3b9610, 0x900f}}, + {{0x2121a8cf, 0x1ce9259f, 0x09156d50, 0x1b37fd0f, 0x09d11059, 0x31546c4d, 0x0425ad61, 0x30557b18, 0x732a}}} + }, + { + /* 1*16^36*G: */ + {{{0x1e6b80ef, 0x33ca7acf, 0x179424f3, 0x32f2e59f, 0x3cbdc571, 0x1503088e, 0x22ec8d23, 0x2783b8d9, 0xb645}}, + {{0x1a71ba45, 0x0c2fc2d8, 0x0e35b2ff, 0x2ceb9b52, 0x261db3c4, 0x2b7c5b95, 0x3e06de1d, 0x21db41bc, 0x067c}}}, + /* 3*16^36*G: */ + {{{0x319888e9, 0x0e73c9e4, 0x2448a8b4, 0x04ae9afc, 0x2681673d, 0x1834c0a5, 0x3a6e2dde, 0x3a9dceb0, 0x1f90}}, + {{0x2f113b79, 0x1bf7f25f, 0x19522e65, 0x0dd47fb9, 0x2b96a821, 0x054f49c7, 0x2a10e958, 0x0d9f0576, 0x89be}}}, + /* 5*16^36*G: */ + {{{0x3562222c, 0x217bedbc, 0x1e6f2c60, 0x00d11e64, 0x0b52bade, 0x00aeb4cd, 0x3e0ad6e7, 0x39537b7f, 0x13a4}}, + {{0x28200145, 0x32c59a32, 0x1c904c08, 0x3e715deb, 0x209a52d4, 0x2b0be075, 0x2e813b2c, 0x1f539605, 0xc9d6}}}, + /* 7*16^36*G: */ + {{{0x343b46bb, 0x0df93703, 0x2c925254, 0x3b4e98fe, 0x055dbd12, 0x01f01761, 0x0aadd1d4, 0x07afc8cf, 0x6199}}, + {{0x0c20a848, 0x123d6407, 0x12ecd8ef, 0x2a1ca729, 0x3badf11c, 0x3ce1c59b, 0x1e492952, 0x38c23cff, 0x01c5}}}, + /* 9*16^36*G: */ + {{{0x121add3b, 0x396f8f77, 0x1727d8f7, 0x26a513d1, 0x1626118b, 0x0e736c34, 0x3d387490, 0x2ba92de1, 0xea27}}, + {{0x368ce7dd, 0x2d78a476, 0x24e1be71, 0x2c84b5a3, 0x1c2f6278, 0x0f3ac8c9, 0x217de572, 0x3c79b90a, 0xc70f}}}, + /* 11*16^36*G: */ + {{{0x211ff757, 0x3a2be2ed, 0x04c226e6, 0x133a5d07, 0x22b6da9b, 0x0043e2db, 0x3fd54ba9, 0x144d5adf, 0x5946}}, + {{0x094d031a, 0x2299bb2a, 0x3bffe3b2, 0x06ef1edf, 0x0406f996, 0x00e34057, 0x32750042, 0x0d833977, 0x3611}}}, + /* 13*16^36*G: */ + {{{0x236160b5, 0x1d89628d, 0x0e7ebc06, 0x314fc91c, 0x091ec0cc, 0x0ebde5c0, 0x33290e84, 0x1b8e457d, 0x16b2}}, + {{0x18a1dc0e, 0x11897efd, 0x0ba3ef81, 0x0d8eab1c, 0x3654d4e1, 0x190d4918, 0x2ef8bb63, 0x159698c0, 0x060f}}}, + /* 15*16^36*G: */ + {{{0x37b32db8, 0x25934a24, 0x247791f3, 0x07b5d27d, 0x2cea85c9, 0x2850f210, 0x19f931be, 0x14a57115, 0x024b}}, + {{0x2a64f760, 0x25153eaa, 0x05b81a95, 0x2ada0448, 0x1e5be862, 0x38a08731, 0x3309c7b6, 0x3be3d6ff, 0x609f}}} + }, + { + /* 1*16^37*G: */ + {{{0x096943e8, 0x3b683d6d, 0x273c5a5d, 0x1bc7f19f, 0x0f06231d, 0x08d2a846, 0x3b840793, 0x20320a02, 0xd68a}}, + {{0x2b133120, 0x25321099, 0x045295a2, 0x039ee3de, 0x30e28b5b, 0x2c7e45de, 0x186d00c4, 0x2a7ffd2d, 0xdb8b}}}, + /* 3*16^37*G: */ + {{{0x0ca1c4f9, 0x16d0aa86, 0x2b7e2823, 0x13bf8d32, 0x1f16f44f, 0x02e0f698, 0x1728c4c4, 0x3de3c8af, 0x7815}}, + {{0x3778bc15, 0x2ac7a8da, 0x177d1e19, 0x2d0b7985, 0x18c35d5c, 0x24f3cc51, 0x1af6a7dd, 0x007a334e, 0xc1c6}}}, + /* 5*16^37*G: */ + {{{0x2e8c8530, 0x349b870f, 0x38f4d8e6, 0x0b7da07b, 0x2a6c6d51, 0x1df19005, 0x040176e3, 0x1cf3683b, 0xc392}}, + {{0x398446c7, 0x100c3c3d, 0x2eed715c, 0x3b7f2f68, 0x03199850, 0x074e5107, 0x33c8e9d0, 0x2f9095d0, 0x8c41}}}, + /* 7*16^37*G: */ + {{{0x237a26c1, 0x07c902ec, 0x0dbf6a53, 0x1b1b9630, 0x103b2516, 0x0890c707, 0x011b0275, 0x1d11fd61, 0xda31}}, + {{0x2cf74d6f, 0x1460dbb3, 0x3a81525f, 0x1a0db175, 0x19d8b7d3, 0x21059f09, 0x18c69d23, 0x25ee1fd7, 0x753b}}}, + /* 9*16^37*G: */ + {{{0x3739dc49, 0x0ad8a2a4, 0x2f55603d, 0x24e4b699, 0x3f231a23, 0x12b1422f, 0x30e6c106, 0x39b2c0ab, 0x6a4b}}, + {{0x32edd5cf, 0x39a8ae77, 0x14a4a4d3, 0x1f8ad32c, 0x3a8058ab, 0x059b8d83, 0x107597dc, 0x23ea8aa2, 0xf15d}}}, + /* 11*16^37*G: */ + {{{0x06987fac, 0x22fa2831, 0x0a86f679, 0x3243e190, 0x098a3c8b, 0x260980fb, 0x27f1344e, 0x31a7c4eb, 0x01f7}}, + {{0x19174c68, 0x3e479ce0, 0x1f6bc263, 0x1fd77886, 0x1ab6f9cb, 0x040db8ca, 0x1a22de5b, 0x330fcdbf, 0x9d4e}}}, + /* 13*16^37*G: */ + {{{0x36daba4d, 0x34ce86f5, 0x03196261, 0x197ec388, 0x3a2bcb9c, 0x018bb763, 0x3d381cb7, 0x25005d87, 0x557e}}, + {{0x37a52316, 0x04dd286e, 0x243590a5, 0x3a6e3d7e, 0x0cbc86c5, 0x0d73e857, 0x3a7e046d, 0x23ce9807, 0x7a7e}}}, + /* 15*16^37*G: */ + {{{0x29f5341a, 0x0e3d4bfc, 0x29636b80, 0x31e8cb19, 0x3101419c, 0x27503a9e, 0x085a93b2, 0x36a08666, 0x3ada}}, + {{0x2586c6cc, 0x1456024d, 0x05e8fbcb, 0x35b4b96d, 0x2b1017e9, 0x38d6fcda, 0x1369f552, 0x0788a266, 0xbfea}}} + }, + { + /* 1*16^38*G: */ + {{{0x028d3d5d, 0x0256603f, 0x3449cea4, 0x04abae5c, 0x3a30b096, 0x3009c241, 0x0804252d, 0x3b5f7d97, 0x324a}}, + {{0x16ab7c84, 0x19c892be, 0x23328439, 0x084ec31f, 0x2c1f4f19, 0x03030d6b, 0x21f2ff13, 0x0d95dd2d, 0x648a}}}, + /* 3*16^38*G: */ + {{{0x2fd53ed3, 0x17245d60, 0x1a56ccef, 0x0fdd3ee7, 0x1f7c4916, 0x3d82e4c7, 0x372ad5b8, 0x02f56659, 0x2084}}, + {{0x1a7a7132, 0x1c50ff94, 0x0e708998, 0x21f11ce5, 0x3afac254, 0x2f51da9a, 0x18243487, 0x0d25f3b0, 0xf299}}}, + /* 5*16^38*G: */ + {{{0x08a35b35, 0x2f4b2ed6, 0x00a121ed, 0x2d762297, 0x08ebfd1a, 0x0f40a796, 0x339bbbd1, 0x2ffd83ac, 0xe6b6}}, + {{0x1c1007bd, 0x15ca4f6e, 0x3e999c7c, 0x0edb274e, 0x1961ddfe, 0x3d0f8e0d, 0x0d2f3266, 0x3caf4cc0, 0x1a5f}}}, + /* 7*16^38*G: */ + {{{0x00360dd3, 0x353be34b, 0x050e2090, 0x2a2a0db6, 0x0ce3bb47, 0x02e021b8, 0x099b288b, 0x05dd16f9, 0xe053}}, + {{0x3c24f87b, 0x0abb3644, 0x0103dc2b, 0x2e61f7a6, 0x36a01461, 0x02560ad6, 0x12f39cd8, 0x0edc6976, 0xdc1c}}}, + /* 9*16^38*G: */ + {{{0x1098dfea, 0x3051998b, 0x2a678797, 0x372cf24b, 0x3a5e57fa, 0x23974aa0, 0x06c59e01, 0x0ece9de2, 0xa815}}, + {{0x2e6d892f, 0x2926a77d, 0x2daf4158, 0x2d783dd0, 0x053e03b1, 0x236e715e, 0x060fc53d, 0x0e591874, 0x2a47}}}, + /* 11*16^38*G: */ + {{{0x0bcecfa5, 0x29f9de92, 0x316bb020, 0x0358b686, 0x0eda3b2a, 0x11a5718e, 0x0addadeb, 0x30ecc3fb, 0x4f05}}, + {{0x15d37b53, 0x3b34092a, 0x01b48cd2, 0x1fb90c7c, 0x1534b944, 0x18c8d856, 0x1426fadd, 0x267a980f, 0x53a4}}}, + /* 13*16^38*G: */ + {{{0x084b96aa, 0x1879d964, 0x22abcce4, 0x0a618d54, 0x3b980ed0, 0x101786a8, 0x3a91be26, 0x26ae67d9, 0xd930}}, + {{0x02b28a86, 0x09b13cdf, 0x3cfe978f, 0x2db27eeb, 0x34cb5fd3, 0x043c1989, 0x2c557d7e, 0x26caa6d3, 0x6ef9}}}, + /* 15*16^38*G: */ + {{{0x1f8fcf0e, 0x3dee3416, 0x3c4a6fac, 0x16dbff79, 0x2a3411d6, 0x30d11b7a, 0x22d35ba9, 0x1f284e15, 0x7d58}}, + {{0x18bc9459, 0x00706827, 0x323780a5, 0x18e402b4, 0x3d6ad0c4, 0x0d002db3, 0x04c61272, 0x1700e20c, 0xa729}}} + }, + { + /* 1*16^39*G: */ + {{{0x3d054c96, 0x3a2f4dcf, 0x0d1ca888, 0x31050eea, 0x3ee5dcee, 0x077f6f97, 0x1e61f6d5, 0x30524673, 0x4df9}}, + {{0x0ad10d5d, 0x0baeb01b, 0x28849019, 0x3541b370, 0x1d85d4b5, 0x25d308e8, 0x18728050, 0x3b14424b, 0x0035}}}, + /* 3*16^39*G: */ + {{{0x1def001d, 0x13c89769, 0x09ba27ef, 0x3e6ef5a6, 0x23b64b21, 0x02f47027, 0x22caf20e, 0x28cb6c9f, 0xa549}}, + {{0x30624783, 0x3576c69f, 0x2c9705ad, 0x05078a98, 0x259456eb, 0x330c3b62, 0x166cbdf4, 0x1e9e41b6, 0x799b}}}, + /* 5*16^39*G: */ + {{{0x052ed4cb, 0x16bbc797, 0x009ec5a0, 0x1537becf, 0x132e6ec9, 0x022f660d, 0x3ecd123f, 0x23cc3681, 0x7e79}}, + {{0x14bb9462, 0x15c5981e, 0x39f37a12, 0x1cd5c6ff, 0x32f057b1, 0x2a55277b, 0x1ac83041, 0x33312893, 0xd23d}}}, + /* 7*16^39*G: */ + {{{0x13630834, 0x37ce83ef, 0x3dac067f, 0x18fc4a18, 0x0c810884, 0x2e7a5aea, 0x14783ad5, 0x28800c54, 0x224f}}, + {{0x047a2272, 0x34f11cdf, 0x0a50f75c, 0x18a493b0, 0x1d09f53d, 0x2dc3e8e4, 0x2da5c3c4, 0x138caecf, 0xbbe5}}}, + /* 9*16^39*G: */ + {{{0x183c19d7, 0x19d92745, 0x02cf57bb, 0x2ed7916b, 0x228ef2bb, 0x28973390, 0x239e4129, 0x28331802, 0xc2d4}}, + {{0x0507928d, 0x0bca2e0b, 0x3345c977, 0x2012a0c5, 0x01260d26, 0x20ed7dfd, 0x06294d41, 0x283e7020, 0x65ad}}}, + /* 11*16^39*G: */ + {{{0x3c940c9a, 0x13202b52, 0x2f423308, 0x33cf384e, 0x0ddc2113, 0x161789d1, 0x1f3190e5, 0x0a9fb0c1, 0x2ec2}}, + {{0x051e7a4d, 0x34653f66, 0x1a35bdac, 0x101460f6, 0x1c7feb12, 0x3893d40a, 0x379684c2, 0x291a378c, 0x8b1d}}}, + /* 13*16^39*G: */ + {{{0x1d683eeb, 0x29c3b97f, 0x08d3133a, 0x0dbace28, 0x04b8f33e, 0x2bd94942, 0x28cecab1, 0x1a5ce3e6, 0xafc6}}, + {{0x30cd4509, 0x078a72ac, 0x1eddfdc9, 0x02ead549, 0x239c1657, 0x1671ff28, 0x22752bc3, 0x0865db74, 0x002c}}}, + /* 15*16^39*G: */ + {{{0x376f4293, 0x28807e1e, 0x13c5139e, 0x3a5e2d59, 0x0b282e10, 0x2f233cdc, 0x03309121, 0x1ed6a7cd, 0xd255}}, + {{0x1282740a, 0x36c61e89, 0x2405a5f1, 0x12da0e37, 0x0ad21fe3, 0x20bc1bad, 0x027f0126, 0x2cd0d579, 0xa787}}} + }, + { + /* 1*16^40*G: */ + {{{0x2c1f98cd, 0x2ff26722, 0x17f0308c, 0x0d224153, 0x06602152, 0x362a7073, 0x34870fae, 0x066a1291, 0x9c39}}, + {{0x14fc599d, 0x39f9780f, 0x064c8e6b, 0x14c9bddb, 0x20e64190, 0x3c112fc9, 0x1dd57584, 0x13c3d293, 0xddb8}}}, + /* 3*16^40*G: */ + {{{0x0fb64db3, 0x1ee6354e, 0x1dd53841, 0x3b79328e, 0x13b8d6a7, 0x2ee0fef9, 0x1ccb740b, 0x08e48a6f, 0xc114}}, + {{0x3c0259be, 0x08c33a7f, 0x14567d1e, 0x1d602413, 0x178bd1a8, 0x3b3793fa, 0x06fc2a5c, 0x3db716d2, 0x1237}}}, + /* 5*16^40*G: */ + {{{0x03081e46, 0x3b7b60d0, 0x14559ea1, 0x14886315, 0x2634713a, 0x3670b064, 0x37224082, 0x12fe0c69, 0x6c5b}}, + {{0x0bfbcd70, 0x347e72e0, 0x2c22a62e, 0x3433e09a, 0x2be47841, 0x11e18f38, 0x2d42fb23, 0x04dc5249, 0xcb05}}}, + /* 7*16^40*G: */ + {{{0x064dcd4b, 0x32b96bb1, 0x111c124d, 0x0c31f566, 0x310a450c, 0x1c19972a, 0x0ade4b56, 0x2a1599c3, 0xe1e9}}, + {{0x3b041f2c, 0x342d897a, 0x0a16b292, 0x113466ab, 0x2577927f, 0x310d666c, 0x1c531b7a, 0x02a55115, 0x562b}}}, + /* 9*16^40*G: */ + {{{0x2badd73c, 0x0161dbf8, 0x2a64b7d0, 0x36737640, 0x1c14208f, 0x29d390bb, 0x1b099778, 0x0695eb44, 0x51b2}}, + {{0x2b36d8d1, 0x3df52b87, 0x0c734ba6, 0x0804c3ca, 0x2c1cfa6c, 0x281fc074, 0x3d3e5d54, 0x0c040007, 0x0079}}}, + /* 11*16^40*G: */ + {{{0x3b09f34b, 0x35d742dc, 0x0cc66ce6, 0x221cf982, 0x339d61e5, 0x2d8a5bcf, 0x0b79861a, 0x3ce98ec7, 0x9701}}, + {{0x00df5793, 0x33721433, 0x3dcc794a, 0x012f0e5f, 0x16833771, 0x00c6d4c5, 0x30ed15d7, 0x12eee32b, 0x3dd4}}}, + /* 13*16^40*G: */ + {{{0x3f1e2f46, 0x1739888e, 0x32778301, 0x1c3dc7a1, 0x163c5752, 0x164b8103, 0x266cc445, 0x2d074b27, 0xa036}}, + {{0x1effb349, 0x1cc789a5, 0x3f0b1f4f, 0x2038a0b3, 0x1eb08d06, 0x07daa91e, 0x16b3d7df, 0x246800fa, 0xc3bf}}}, + /* 15*16^40*G: */ + {{{0x0c4cea08, 0x3362e40e, 0x20ea21db, 0x12d62e83, 0x00465265, 0x298454d0, 0x28c506f4, 0x3eb6ea93, 0x6a85}}, + {{0x1862f4f3, 0x0677b396, 0x3d721b6a, 0x09c692d0, 0x3e6230b4, 0x24cf0523, 0x0659d531, 0x11812eb9, 0x00b6}}} + }, + { + /* 1*16^41*G: */ + {{{0x20a959e5, 0x2884e084, 0x391d4cc5, 0x38524ea2, 0x0e06bb91, 0x017ca076, 0x12fdf8de, 0x05c2c774, 0x6057}}, + {{0x2385a2a8, 0x2266fa4c, 0x2e24c65e, 0x1454af0f, 0x1df26246, 0x268b6bdc, 0x24807add, 0x3c2c9a9a, 0x9a1a}}}, + /* 3*16^41*G: */ + {{{0x171c032b, 0x3536858a, 0x3afdc980, 0x1ad9a285, 0x0766c5ff, 0x046d7f7f, 0x002603dd, 0x2a3f35b8, 0x71eb}}, + {{0x1668359f, 0x1ead6a38, 0x34b4755e, 0x24c6b45d, 0x0cbb7f71, 0x18145bd5, 0x1d39def6, 0x049892d8, 0xd2ff}}}, + /* 5*16^41*G: */ + {{{0x2a03a61c, 0x01b91d14, 0x1070574d, 0x1e1a3d1a, 0x2a9dd050, 0x05d10aea, 0x09d232ca, 0x30c16cc9, 0x855e}}, + {{0x065dfc07, 0x37f1baab, 0x17e44965, 0x0cbdd3a8, 0x02fb4ed3, 0x0f2ffe6d, 0x01c17f54, 0x174bb17c, 0x0dd8}}}, + /* 7*16^41*G: */ + {{{0x1f32d706, 0x00302920, 0x06a0678b, 0x0633291d, 0x15bfa206, 0x034a68c2, 0x3fbf1f15, 0x121aaeac, 0x3ce4}}, + {{0x3c7fd9e4, 0x02dcd8df, 0x161e89f4, 0x345590f3, 0x094906ed, 0x3f411ac4, 0x3785288e, 0x10236ab8, 0xe775}}}, + /* 9*16^41*G: */ + {{{0x391cd3fb, 0x36d032ed, 0x329be686, 0x0a8cff65, 0x0844eb4a, 0x380c863e, 0x237faf02, 0x31450fd3, 0x11cc}}, + {{0x15160d86, 0x24dc5ae9, 0x0dd3472a, 0x02c7bf4b, 0x0cc239fa, 0x2389124e, 0x311deb52, 0x1acaa40a, 0x4aa5}}}, + /* 11*16^41*G: */ + {{{0x218f7552, 0x21ee4465, 0x0054fac3, 0x1044e2e6, 0x2382ddbd, 0x25ddd3e0, 0x09c6f43b, 0x2ec5f945, 0x0250}}, + {{0x3510b14d, 0x3c212588, 0x33d6f1e3, 0x001bcf0c, 0x29d817da, 0x35f7dd7f, 0x28082342, 0x0c3f26ef, 0x7319}}}, + /* 13*16^41*G: */ + {{{0x1f725d12, 0x1744fa4e, 0x0b5f4750, 0x1190aef7, 0x022fbfd9, 0x28e73828, 0x27fd3ab4, 0x27222cd1, 0x1a74}}, + {{0x23ac56e4, 0x04d94534, 0x190daa70, 0x1c821a62, 0x2f3d8f60, 0x22f9d70a, 0x00e2cf45, 0x34655cfb, 0x7e91}}}, + /* 15*16^41*G: */ + {{{0x29fae458, 0x18412394, 0x26ec97fd, 0x0297109d, 0x3b7b328b, 0x3455a977, 0x0218c109, 0x1a16f83e, 0xc750}}, + {{0x1757b598, 0x005a1065, 0x35951a2b, 0x1772940c, 0x32c7b40a, 0x0bd05319, 0x21e05fb5, 0x257e33e4, 0xead7}}} + }, + { + /* 1*16^42*G: */ + {{{0x2cb94266, 0x069a5cfb, 0x3d4df12b, 0x33bc3ee9, 0x0da31880, 0x10e69146, 0x08411421, 0x37e388e8, 0xa576}}, + {{0x21b28ec8, 0x3a2f846b, 0x114d9f3e, 0x0b8429fd, 0x0cd82c43, 0x2e5ebf96, 0x240b2c92, 0x2fc839d9, 0x40a6}}}, + /* 3*16^42*G: */ + {{{0x0d9ed6c1, 0x1a2bad63, 0x3d593d6b, 0x139d16f0, 0x1edd0ec2, 0x3f061dc1, 0x0f53e80b, 0x0cdb72dd, 0x0328}}, + {{0x38fafeee, 0x3b1baf9b, 0x1cb494ad, 0x16fd37c9, 0x0d7c8c26, 0x35650e88, 0x19f28c46, 0x260e04bf, 0x71a8}}}, + /* 5*16^42*G: */ + {{{0x3235983a, 0x066a6a34, 0x13bceb29, 0x22840dc0, 0x3e1531e3, 0x0e49b5c3, 0x11c54dc6, 0x13aba2e4, 0xce4f}}, + {{0x0d3cdecf, 0x33f5ac64, 0x2bf740ae, 0x1b1948a3, 0x30754352, 0x37809279, 0x0fbbb3ea, 0x3e5cf0e4, 0xf3c9}}}, + /* 7*16^42*G: */ + {{{0x15b0e6c9, 0x1b6aad99, 0x06e4c89a, 0x17fe73de, 0x38bcbddb, 0x0a3ecdb7, 0x0622278e, 0x2fe952e6, 0x4dbe}}, + {{0x1eb2cc25, 0x2529e155, 0x0504efae, 0x24c46caf, 0x2229f358, 0x2989b9b8, 0x13aedf45, 0x39ec0f24, 0x10fe}}}, + /* 9*16^42*G: */ + {{{0x25857295, 0x13806846, 0x3433f016, 0x32391fc0, 0x1ca12069, 0x38463f28, 0x05c218b2, 0x0902ffbd, 0xa42a}}, + {{0x0a7eb9c1, 0x1acddffb, 0x15193955, 0x28708b34, 0x1da4c427, 0x1ac8ac93, 0x05d4567a, 0x2cfc9840, 0x3aa0}}}, + /* 11*16^42*G: */ + {{{0x2fcdc098, 0x0883fd55, 0x2e468032, 0x02b803da, 0x0499c155, 0x3c7e1b03, 0x322267a7, 0x0acbe5be, 0x34e1}}, + {{0x2a7474e2, 0x132c6b79, 0x19883f66, 0x37d44c3c, 0x3972db04, 0x132f2105, 0x1d322d97, 0x30b775ed, 0xa64a}}}, + /* 13*16^42*G: */ + {{{0x0f173b92, 0x335bad7a, 0x29fb7611, 0x1f9cbd05, 0x0d65683b, 0x0c68863d, 0x391f29be, 0x3490366e, 0x10f4}}, + {{0x233146c2, 0x240801b5, 0x086adb7c, 0x2edda745, 0x3908ba90, 0x2c96968c, 0x353ad211, 0x0b654245, 0x850e}}}, + /* 15*16^42*G: */ + {{{0x28d84958, 0x39bf4766, 0x0acc5cae, 0x0477ac5b, 0x00cc866a, 0x066e5db5, 0x277e749f, 0x3a02da6d, 0xe846}}, + {{0x3882cf9f, 0x031191ed, 0x1e0c1a64, 0x1468cd9c, 0x18b76fad, 0x2f64411e, 0x07e2541d, 0x2e3f2253, 0xa29c}}} + }, + { + /* 1*16^43*G: */ + {{{0x3e58ad71, 0x3dd8e226, 0x39a3a208, 0x0c347d73, 0x1e8c38bb, 0x17fa58a7, 0x2c3e30a0, 0x29e30a37, 0x7778}}, + {{0x3d9f43ac, 0x2d44ff07, 0x324ac563, 0x2ce1047f, 0x3f580087, 0x26384bcb, 0x1b22ff70, 0x1b66ad69, 0x3462}}}, + /* 3*16^43*G: */ + {{{0x3319c869, 0x3df1bab8, 0x21eb2702, 0x2a7e575d, 0x0cacdc18, 0x20e408bf, 0x33fc8d01, 0x01176605, 0x3018}}, + {{0x12b856f0, 0x3031db27, 0x23d9a7bf, 0x0aa13292, 0x222e3bca, 0x1890c835, 0x3b7b6f86, 0x315e0940, 0xac5f}}}, + /* 5*16^43*G: */ + {{{0x25ed29b5, 0x319a61be, 0x12add1b4, 0x20c2d81c, 0x23c885f5, 0x2d9f6e69, 0x17ef343a, 0x206d87b9, 0x3228}}, + {{0x3cd15ad2, 0x3d3c49b9, 0x0ee7604e, 0x20ebaae5, 0x1531e1ca, 0x02c677d0, 0x0344eb11, 0x00a105e8, 0x1677}}}, + /* 7*16^43*G: */ + {{{0x06c96100, 0x2fea101e, 0x2e9c8e63, 0x18c046a9, 0x33dbcca1, 0x0f766cb7, 0x31b9ffb4, 0x11ceb03e, 0x3f38}}, + {{0x32624707, 0x078ab06f, 0x375f1bcf, 0x15c71f02, 0x079ce566, 0x131118bc, 0x00395253, 0x27157d75, 0x70c6}}}, + /* 9*16^43*G: */ + {{{0x3d22d2ac, 0x0d31bb1b, 0x1caace02, 0x377f849b, 0x05df2f10, 0x0f03825e, 0x3a76dcb4, 0x04f17f49, 0x2881}}, + {{0x0f42a268, 0x207ad57e, 0x148c8fd0, 0x30f51285, 0x176137dd, 0x1ddc9832, 0x3c5c8f20, 0x3ac0563e, 0xa1a7}}}, + /* 11*16^43*G: */ + {{{0x245f8ea8, 0x12ea0374, 0x24d2900d, 0x1c9238e5, 0x119fe5d1, 0x3d36575c, 0x23a2a553, 0x28803211, 0xf963}}, + {{0x19bc99eb, 0x2f157ec1, 0x18b60824, 0x2e3c8d67, 0x3427208b, 0x1c88c07f, 0x383c0a3b, 0x2509a31f, 0x9c85}}}, + /* 13*16^43*G: */ + {{{0x2606a315, 0x386a20c4, 0x26963ad9, 0x1c981cbc, 0x0e097e40, 0x362ca964, 0x0d9a7f98, 0x08933fdc, 0xa5d9}}, + {{0x1e3b68d1, 0x0d584cd6, 0x111a7c9d, 0x13434d1f, 0x180de9ed, 0x0c1aaf5e, 0x0da5b343, 0x22c00ec8, 0x8732}}}, + /* 15*16^43*G: */ + {{{0x06231493, 0x336ded50, 0x0cc4d469, 0x1046a0c3, 0x25e6a496, 0x13907403, 0x3c3604eb, 0x260b86dc, 0xf1fe}}, + {{0x358848c1, 0x25aa6699, 0x25ff0d01, 0x1cfecd1b, 0x3d99d3f1, 0x34f0817d, 0x24ddc216, 0x067abb66, 0x2e20}}} + }, + { + /* 1*16^44*G: */ + {{{0x06d903ac, 0x027b6a70, 0x1ad7e5cb, 0x3e589d39, 0x3afd2ed5, 0x0a7f4c39, 0x3a844637, 0x2557b98d, 0x0928}}, + {{0x1bcd091f, 0x14603a4d, 0x0a8d83fc, 0x0f49bbea, 0x3a95eeac, 0x1e284c24, 0x342a827b, 0x08400f4f, 0xc256}}}, + /* 3*16^44*G: */ + {{{0x3874b839, 0x0444a1d5, 0x13d2b418, 0x10456ce5, 0x30b6aebe, 0x37c37ec8, 0x1e5a8053, 0x2e07f038, 0x3e03}}, + {{0x3c0594ba, 0x03073959, 0x1ab5b8da, 0x39717c3f, 0x198f667d, 0x3d981d5c, 0x07f42c44, 0x3858f7fc, 0xd13a}}}, + /* 5*16^44*G: */ + {{{0x0357a513, 0x28fde39a, 0x1b3023f3, 0x146f44d1, 0x2922c5f1, 0x3e8a0ea8, 0x0492cd62, 0x302de8bd, 0xe662}}, + {{0x2017d07e, 0x24a88072, 0x1538d891, 0x00d73589, 0x21a419d8, 0x2b882284, 0x2452305d, 0x064f3984, 0xab0b}}}, + /* 7*16^44*G: */ + {{{0x1f37d242, 0x2657dfbf, 0x39c14b04, 0x27fb2981, 0x23587dc2, 0x218b1f2f, 0x0f6cb843, 0x202c7253, 0x40bf}}, + {{0x26405088, 0x347609e6, 0x2bd35583, 0x0c87ae90, 0x26fe1274, 0x0ffa6c6c, 0x2aaf04f5, 0x374d7615, 0xb579}}}, + /* 9*16^44*G: */ + {{{0x195a3558, 0x2bcacd91, 0x234a7f2b, 0x01c7e178, 0x1b59f6ac, 0x3e5e04e3, 0x1ca70806, 0x3fa5d807, 0x3d14}}, + {{0x2443df4c, 0x1ab6ceb1, 0x3c1d727c, 0x3828b851, 0x356e1482, 0x26a4c76f, 0x281ef8f2, 0x2f75ba11, 0x16c6}}}, + /* 11*16^44*G: */ + {{{0x02b1fc24, 0x37a7d6b6, 0x23f7570e, 0x0a36071f, 0x12486525, 0x06b134b2, 0x265251cc, 0x29503a0b, 0xdd6f}}, + {{0x0e9b74ca, 0x290c7118, 0x17322304, 0x04379afb, 0x257e77ec, 0x1bc7afc5, 0x3186fe36, 0x0adfac74, 0x67e6}}}, + /* 13*16^44*G: */ + {{{0x3dd08e02, 0x07aa4564, 0x1adf0288, 0x2151edff, 0x3d1e8010, 0x1a5266a8, 0x15d780f8, 0x0b6a0b79, 0x13fa}}, + {{0x3cb03410, 0x29550770, 0x1a42b97d, 0x112beec6, 0x3432c7e6, 0x0d5881ae, 0x1da72313, 0x0e2c1155, 0x1363}}}, + /* 15*16^44*G: */ + {{{0x144ee41a, 0x308ceae6, 0x37d69a6a, 0x26d5b74e, 0x06828287, 0x3042d9cb, 0x30a443f7, 0x121474f1, 0xd06c}}, + {{0x0b295e6f, 0x3c7e13a6, 0x162ee252, 0x1ee10d18, 0x3630919b, 0x02b353d3, 0x0d0adbbb, 0x3f530161, 0x5815}}} + }, + { + /* 1*16^45*G: */ + {{{0x23d82751, 0x1eab9d45, 0x3ad35452, 0x116d2a41, 0x23b28556, 0x0193ce83, 0x1b109399, 0x3fbcfb1b, 0x85d0}}, + {{0x0eb1f962, 0x0b08de89, 0x07733158, 0x21d47a5a, 0x2cf5663e, 0x3525b960, 0x38c0be29, 0x192104e8, 0x1f03}}}, + /* 3*16^45*G: */ + {{{0x2cde4cf3, 0x26554187, 0x38a066ab, 0x10394d51, 0x1d9ae793, 0x30b49b45, 0x022c3be7, 0x2ad2b045, 0x384d}}, + {{0x252d0566, 0x1f1e5ac8, 0x351ba73b, 0x10c28ce5, 0x34c6f01f, 0x13b5b68a, 0x1ca43bfb, 0x316f346e, 0xd6e3}}}, + /* 5*16^45*G: */ + {{{0x1e5238c2, 0x22bcfa48, 0x00ecb8b9, 0x0d57d70e, 0x02ed4840, 0x05842d3a, 0x015aa41b, 0x3b03adf5, 0x14f0}}, + {{0x12f07922, 0x3a1a8d1e, 0x304939d6, 0x17003600, 0x02747fd2, 0x3f1cf8e1, 0x35d80921, 0x354f7520, 0xab12}}}, + /* 7*16^45*G: */ + {{{0x1543e94d, 0x3d8d4bbf, 0x2f98e188, 0x04c0a9d5, 0x1a0ddadd, 0x30d19e29, 0x0287ec41, 0x3ceede0b, 0xeb42}}, + {{0x05924d89, 0x01567791, 0x20d6d424, 0x3611a379, 0x0dfb774c, 0x03755cbf, 0x1d92dc9a, 0x1b41d3c9, 0x234a}}}, + /* 9*16^45*G: */ + {{{0x3e19aaed, 0x0c9396d5, 0x06673270, 0x26eb37a3, 0x06a92045, 0x3b00bdb8, 0x020d9a9e, 0x0e32945a, 0x1cf1}}, + {{0x292f400e, 0x04dba975, 0x3c77ffbc, 0x27bbe3fb, 0x2dde1747, 0x0dca99ad, 0x063865f4, 0x36bcc5c7, 0xd6ff}}}, + /* 11*16^45*G: */ + {{{0x36a8aa39, 0x3db03a7e, 0x278fac55, 0x2998ded2, 0x1990d937, 0x16825a12, 0x0d412c87, 0x21af97d0, 0xb586}}, + {{0x2b493c1f, 0x3f1e4d74, 0x2db347b8, 0x2f6be639, 0x00a91dab, 0x11e35153, 0x38c2c149, 0x3550c931, 0x5632}}}, + /* 13*16^45*G: */ + {{{0x303b4cc5, 0x3a47af8e, 0x21c77c2e, 0x0a0c6e96, 0x33a80257, 0x16f13f9f, 0x3cc2b67b, 0x276c1ae2, 0x5fc1}}, + {{0x25b57c28, 0x0ece7ee1, 0x0087ec4a, 0x1dbd40f3, 0x3a5ef492, 0x084e3e68, 0x0c7c66ee, 0x21303b26, 0xec8e}}}, + /* 15*16^45*G: */ + {{{0x0cb38cb5, 0x2d2e15f5, 0x1388948b, 0x02dff7d3, 0x3eea1be1, 0x2a2903f4, 0x1e289deb, 0x2dc350bb, 0xb88f}}, + {{0x1965f3d7, 0x1efe9d59, 0x3af8c719, 0x13cf8489, 0x35a8e24d, 0x12ee652c, 0x23280603, 0x0dab51ba, 0xd6c7}}} + }, + { + /* 1*16^46*G: */ + {{{0x0526087e, 0x3d501209, 0x2da20308, 0x3edb6220, 0x18b85dfd, 0x26d8105e, 0x2ce97c1c, 0x0373a5fb, 0xff2b}}, + {{0x30c29907, 0x32547807, 0x10e2ceb2, 0x2dfb5bee, 0x107936c7, 0x13137153, 0x0ba188af, 0x04ffbd49, 0x493d}}}, + /* 3*16^46*G: */ + {{{0x39d681f9, 0x164153f9, 0x08feb9fc, 0x3383bbeb, 0x2c94b066, 0x1ffc9780, 0x3230888b, 0x3f7c9dd7, 0xc745}}, + {{0x3bbb1247, 0x00c5cd0d, 0x27d45c76, 0x36f4cd71, 0x2818678c, 0x04e531c3, 0x1e5e78a7, 0x08bcbdae, 0x5902}}}, + /* 5*16^46*G: */ + {{{0x35cd0ea3, 0x38133bb4, 0x0cac4815, 0x111e3a08, 0x32e7f2b3, 0x16797ad9, 0x1050b27a, 0x1e7cea5d, 0xabb2}}, + {{0x3c307bce, 0x1c24c4cd, 0x202f3b64, 0x25da4167, 0x078ed47c, 0x12f8300c, 0x3970d9fb, 0x040eefc5, 0x5dee}}}, + /* 7*16^46*G: */ + {{{0x1bc9ee3e, 0x30b8bcfc, 0x3e7382c5, 0x27e86a58, 0x27ed11ea, 0x2baa9d09, 0x0682827f, 0x0542d67f, 0x3f81}}, + {{0x199aae06, 0x33ab6c31, 0x0da81603, 0x08ecb73f, 0x39566276, 0x06facf11, 0x3a82d467, 0x229a3f6f, 0x19c8}}}, + /* 9*16^46*G: */ + {{{0x38e4a007, 0x05c6fbeb, 0x0bb358b6, 0x3b3bb3c2, 0x16c7ec15, 0x12e8cea9, 0x02de6959, 0x04cb7402, 0x5cf8}}, + {{0x1068b883, 0x398fc242, 0x39c7fe8c, 0x251be5b1, 0x0c3df6c8, 0x35056212, 0x1fa0df4a, 0x3b970358, 0xb45a}}}, + /* 11*16^46*G: */ + {{{0x26c2d4a7, 0x255bf9ec, 0x3cfffb10, 0x30dbe4ce, 0x004ed21b, 0x38ce5cf1, 0x3a494653, 0x3f934352, 0xb6d5}}, + {{0x3ae86371, 0x063739f8, 0x35e3cc81, 0x16df939b, 0x3ffd8e74, 0x33e48277, 0x3d6c14df, 0x1ce84eae, 0x47f3}}}, + /* 13*16^46*G: */ + {{{0x3c66dd33, 0x024cd88b, 0x1dc76dc5, 0x23ef23fc, 0x29b022ea, 0x2c6c5400, 0x3588706b, 0x2ef019b3, 0x61c8}}, + {{0x36f10bfa, 0x0eeea7ce, 0x2820c8ca, 0x1441bab0, 0x05d3fb6a, 0x1a6652e6, 0x0f703446, 0x2788e795, 0x9359}}}, + /* 15*16^46*G: */ + {{{0x1d6b2ff8, 0x2016df33, 0x286c8fa9, 0x18cdb05c, 0x03bdf187, 0x27d4dcfb, 0x2785187c, 0x0ae95d09, 0x94e3}}, + {{0x2ce1af3e, 0x37521554, 0x26bfe13a, 0x0ebc1094, 0x2d9e8cb3, 0x07922198, 0x204e192f, 0x1122d0f6, 0x0d1b}}} + }, + { + /* 1*16^47*G: */ + {{{0x3856e241, 0x203978b3, 0x0d6dd287, 0x3c7b8523, 0x1b212b57, 0x0acb98c0, 0x080ea9ed, 0x2ef92c7a, 0x827f}}, + {{0x2ec293ec, 0x1816da2e, 0x2903166d, 0x3de98c61, 0x1d12687f, 0x3bcb19f4, 0x27b0b71b, 0x27248f1c, 0xc60f}}}, + /* 3*16^47*G: */ + {{{0x3bb80fa7, 0x0d12172c, 0x30413886, 0x29f69aed, 0x20819f3a, 0x0681af4c, 0x0c2fbc0d, 0x38c7d8c2, 0x0857}}, + {{0x09366b2d, 0x3660847c, 0x0d7016ab, 0x0b8dc10f, 0x0b714717, 0x1f327477, 0x0172092d, 0x24d08eb8, 0xf643}}}, + /* 5*16^47*G: */ + {{{0x09c70e63, 0x1740b0e8, 0x353d496f, 0x2ee2de39, 0x0a672e9c, 0x171955d9, 0x16004354, 0x333a95af, 0x28aa}}, + {{0x3057da4e, 0x27c0e20b, 0x04da1e8b, 0x3f167391, 0x28ebb7f5, 0x22599f1d, 0x20e1567a, 0x0c8bbe06, 0x2b69}}}, + /* 7*16^47*G: */ + {{{0x33e674b5, 0x007714bd, 0x3060aac6, 0x363da739, 0x2b8a4f92, 0x36cb26f3, 0x1a66145d, 0x2d896815, 0xa2f3}}, + {{0x0e937941, 0x024e3238, 0x033fa53b, 0x08be8c5f, 0x2a7c4b92, 0x112a43cc, 0x068ae800, 0x28565853, 0x620e}}}, + /* 9*16^47*G: */ + {{{0x191eb056, 0x1d8058c7, 0x2cfd386c, 0x00bbf6e3, 0x3515f5a0, 0x22d71a8f, 0x259231d9, 0x20f27aab, 0x3c4f}}, + {{0x205cecab, 0x109624f6, 0x1cf6b877, 0x20ad5120, 0x32788019, 0x3595cf0e, 0x28b6a33a, 0x2401d452, 0x9447}}}, + /* 11*16^47*G: */ + {{{0x3d86dfa9, 0x24187f6e, 0x1b993a71, 0x0e2d2902, 0x103baadc, 0x30780fa0, 0x167d4e29, 0x384a22a6, 0xaff8}}, + {{0x01d12681, 0x1c40f0db, 0x019f9c70, 0x045b6a51, 0x0f53f4f9, 0x0faea87f, 0x37c3fd3d, 0x12ecc84d, 0x8d8b}}}, + /* 13*16^47*G: */ + {{{0x189ba9c1, 0x23c9cdae, 0x09d338e2, 0x03df2968, 0x0ee579e4, 0x16098abb, 0x000b3e84, 0x1e114a37, 0xd3fb}}, + {{0x2b51b267, 0x186e237f, 0x011ade00, 0x073b7570, 0x370fe634, 0x32815d62, 0x2b4e7ca7, 0x350d3be9, 0xf894}}}, + /* 15*16^47*G: */ + {{{0x0f2bb909, 0x36a5b074, 0x3598d999, 0x24409f14, 0x187d7f63, 0x1ca620e4, 0x1aa88ff4, 0x0c0382b2, 0x4ec9}}, + {{0x24cf4071, 0x2228e0fe, 0x1ac3827b, 0x0b85a083, 0x0c49bad5, 0x03711461, 0x304dc5c8, 0x2841af86, 0x782b}}} + }, + { + /* 1*16^48*G: */ + {{{0x2120e2b3, 0x3ced63e8, 0x347f9aa7, 0x163f739f, 0x26e5217a, 0x392b8d33, 0x1bdbae7b, 0x127c87d4, 0xeaa6}}, + {{0x3a5ad93d, 0x11e94c16, 0x13f7e59d, 0x29ae597c, 0x39aa5a01, 0x2a03e261, 0x3b03ac69, 0x1e7b56ee, 0xbe32}}}, + /* 3*16^48*G: */ + {{{0x3f2e070d, 0x160ff4e8, 0x12a6a98f, 0x2aadc731, 0x1047e229, 0x1cc70ee1, 0x34abff48, 0x297a410b, 0x4b72}}, + {{0x296dd780, 0x112ea0bb, 0x2948c3de, 0x2d197774, 0x0f3c10b0, 0x1deecdb4, 0x2e1cf602, 0x0753875a, 0x599e}}}, + /* 5*16^48*G: */ + {{{0x0a02591c, 0x2739ff61, 0x05125a1e, 0x3d526596, 0x21fd613e, 0x1afefad7, 0x1c8e285a, 0x24ff194e, 0xa9fc}}, + {{0x29bec2dc, 0x242b77bd, 0x3cf72537, 0x22231057, 0x1165e5ca, 0x1305e86a, 0x387173e8, 0x39ce7714, 0x9c2c}}}, + /* 7*16^48*G: */ + {{{0x2d968b59, 0x0401b838, 0x3cbbc2e1, 0x28a2eb84, 0x1b027709, 0x35eb0482, 0x39f0a6a7, 0x005f069b, 0xc940}}, + {{0x0de572fb, 0x3bf5d902, 0x390c9c8f, 0x210b2d90, 0x35742ce2, 0x2286fe96, 0x3862013b, 0x08940326, 0x39d9}}}, + /* 9*16^48*G: */ + {{{0x326b3332, 0x0a1cccd5, 0x3ee5de6a, 0x00e2341c, 0x0bf8e031, 0x1e4e97dc, 0x10024ec6, 0x2ee75fbb, 0x1f84}}, + {{0x14e8d52e, 0x1510a28c, 0x36dc3a25, 0x2f338b50, 0x39edf0c2, 0x1f09fdd6, 0x29ecc254, 0x1b41caf2, 0xee72}}}, + /* 11*16^48*G: */ + {{{0x0defa98e, 0x336a952b, 0x1ac27995, 0x12111a04, 0x11e9c772, 0x2055ece6, 0x1fcd06ca, 0x38224251, 0x0f13}}, + {{0x3e286767, 0x0229dda6, 0x2ceaccdc, 0x1f9c1785, 0x3362db28, 0x0fe2c29e, 0x27c5035e, 0x087c5d93, 0xadd5}}}, + /* 13*16^48*G: */ + {{{0x29f59b6b, 0x178700ef, 0x1888e2fa, 0x2ce318f0, 0x1826d3e9, 0x0a2874b5, 0x1ec7db37, 0x24695477, 0xdde1}}, + {{0x26cb1410, 0x1ab658a4, 0x3154fecf, 0x15ce2ef9, 0x12e14e8b, 0x1d5f5871, 0x275cbe0a, 0x3ede00a0, 0x5b2b}}}, + /* 15*16^48*G: */ + {{{0x09c6b699, 0x1a3157f7, 0x3e46871b, 0x1bd5cd5a, 0x341682a8, 0x1b5efe5e, 0x36f7a5a1, 0x004bbb60, 0x5fab}}, + {{0x01c6c3aa, 0x05cc854b, 0x2883519b, 0x2ac45ffa, 0x162f7b90, 0x2ed044c3, 0x3d144e9e, 0x3e9c28f0, 0x2d9b}}} + }, + { + /* 1*16^49*G: */ + {{{0x1a34d24f, 0x388d8cb7, 0x1a137401, 0x2db63c32, 0x342ee541, 0x077db7b3, 0x3169d939, 0x0b50f173, 0xe4a4}}, + {{0x1eba9414, 0x29fdc4c7, 0x0d8e4f13, 0x21bbb7ea, 0x0ad34ce8, 0x326733ee, 0x1c73526f, 0x24b9c5b4, 0x4d9f}}}, + /* 3*16^49*G: */ + {{{0x3bea0c68, 0x321042bc, 0x37b392b5, 0x10c048d9, 0x396faf09, 0x26f23a34, 0x2a3a2494, 0x258d3855, 0x3e41}}, + {{0x1a45edb6, 0x32edbfdc, 0x03cda1ab, 0x2846518c, 0x0693062f, 0x0f2ff8dc, 0x321f7f37, 0x31676492, 0x0123}}}, + /* 5*16^49*G: */ + {{{0x139824d7, 0x3dd748f2, 0x11c9897a, 0x2ded930d, 0x3f0b576e, 0x128f98bd, 0x17508eed, 0x0e3d5157, 0x8d94}}, + {{0x1366489f, 0x28013d22, 0x26b063d8, 0x2e78ae0c, 0x36ef6f8f, 0x182f4c6a, 0x26c2a2ca, 0x381cd3fb, 0x3261}}}, + /* 7*16^49*G: */ + {{{0x18d713de, 0x39201c6a, 0x028e6208, 0x1830bedd, 0x25454393, 0x2a44a8bf, 0x254420d4, 0x0931563b, 0xb725}}, + {{0x1b8350e9, 0x1bff9496, 0x04a5fcb7, 0x20b49bf9, 0x16941504, 0x0b460ba7, 0x03e45104, 0x2ce6a28a, 0x4c51}}}, + /* 9*16^49*G: */ + {{{0x3e3b2cb4, 0x331b0a4f, 0x37210402, 0x127cd6fc, 0x21149e30, 0x31db8e04, 0x112519ad, 0x17d6885b, 0x3de4}}, + {{0x307eb02f, 0x1878ceb0, 0x287044cf, 0x0f8a3996, 0x3c910682, 0x022a92a5, 0x2addc50e, 0x21661017, 0xba2a}}}, + /* 11*16^49*G: */ + {{{0x2ce4e5bf, 0x08d1d9bd, 0x09005b17, 0x19f2a1a8, 0x0906ae9b, 0x0ff38dd2, 0x1be87c1e, 0x3c71a256, 0x8511}}, + {{0x01789c08, 0x3f24a513, 0x05365262, 0x2a1e226f, 0x2a00232d, 0x377dfb1a, 0x0d4874c1, 0x3d73e46f, 0xecdf}}}, + /* 13*16^49*G: */ + {{{0x3d3258ab, 0x06d59a28, 0x2bc14dc3, 0x3490a062, 0x14ab5957, 0x2871cbb8, 0x360222cf, 0x014ba073, 0x8c5a}}, + {{0x022d0f8f, 0x15f8214c, 0x0d944ade, 0x36ba3e70, 0x0c08c246, 0x2a031e41, 0x3bda1079, 0x36d2ed10, 0x6811}}}, + /* 15*16^49*G: */ + {{{0x3f91bcee, 0x1630a82a, 0x20c0d841, 0x33c763c7, 0x2bf137f5, 0x18f3b155, 0x13560bdc, 0x3e05b7af, 0xcef7}}, + {{0x01966b33, 0x2ed36a7e, 0x172f6ac6, 0x0f92c0a8, 0x1d245fa6, 0x0ecce700, 0x08701246, 0x1320d8dd, 0x67e7}}} + }, + { + /* 1*16^50*G: */ + {{{0x0300bf19, 0x1c5cee75, 0x08fea494, 0x2d4d5daa, 0x352b6b92, 0x183eb6ac, 0x0bdd9541, 0x03fbcd83, 0x1ec8}}, + {{0x0107cefd, 0x1c737073, 0x295a07b6, 0x11b9dfd8, 0x2bbf5e01, 0x2925629e, 0x1340d2f3, 0x3a4dd5ad, 0xaeef}}}, + /* 3*16^50*G: */ + {{{0x12fea1f9, 0x2c5f2ef1, 0x00452b94, 0x3fc2d423, 0x106531c4, 0x3f76ad9c, 0x1f2e83bc, 0x22029574, 0xa6dc}}, + {{0x3bc345e9, 0x2c705391, 0x268f7e63, 0x1ee276df, 0x2cbc5005, 0x1a0e845a, 0x367c3038, 0x2a151f70, 0x7ef1}}}, + /* 5*16^50*G: */ + {{{0x06d6c9b3, 0x235030fc, 0x0865637c, 0x1b133a1d, 0x2481ba8c, 0x308a71e2, 0x245992bd, 0x2a4ffa90, 0xfe6b}}, + {{0x2948bdfb, 0x30b1e23e, 0x1c2e9b00, 0x203c6fc1, 0x013b56d9, 0x2d06cd15, 0x39872b6b, 0x0635d014, 0x7ee9}}}, + /* 7*16^50*G: */ + {{{0x0cf95151, 0x08bc41cc, 0x02c4b644, 0x19201b91, 0x08ded1b9, 0x03230b70, 0x098bfb02, 0x38bc51bf, 0x15d5}}, + {{0x2ff8ecf2, 0x20a81f30, 0x1d8c0f94, 0x0813ee5f, 0x1023f9bb, 0x038425e2, 0x3d4ec7f9, 0x0b8c6457, 0xa5b7}}}, + /* 9*16^50*G: */ + {{{0x296a5658, 0x35e042e4, 0x1ef65643, 0x052c9490, 0x2e29be38, 0x1f80249e, 0x0447ad8c, 0x3a1c95a2, 0x84c0}}, + {{0x181b80d1, 0x3659ca6f, 0x34f1fd22, 0x2986a607, 0x13725ed3, 0x1f8c6419, 0x022c4a08, 0x20e03058, 0x2659}}}, + /* 11*16^50*G: */ + {{{0x14dc6a0f, 0x1d6ed722, 0x2fe15753, 0x10d06450, 0x0077c274, 0x09939e8b, 0x3731d565, 0x2c71c6a4, 0xfed6}}, + {{0x176fc7e0, 0x32e35cb6, 0x23fc409c, 0x1d3564c2, 0x13ae2313, 0x24606b93, 0x3ff0a847, 0x2af9ac3f, 0x8de2}}}, + /* 13*16^50*G: */ + {{{0x18e29355, 0x2ce217c4, 0x1720d86d, 0x0723a4ce, 0x23b9d82f, 0x3be18100, 0x3cbc70fc, 0x137664b4, 0x2a6a}}, + {{0x35cc2872, 0x014f803e, 0x0c4c76c0, 0x24168e99, 0x28f90dfe, 0x3f720789, 0x27e0c760, 0x37ee9f12, 0x8677}}}, + /* 15*16^50*G: */ + {{{0x2148dabf, 0x3e7ea23f, 0x09d78eb1, 0x2b74ae4d, 0x3ae735c1, 0x193b08d7, 0x27546d97, 0x24c09b24, 0xe42d}}, + {{0x011e1361, 0x1dcb1d5a, 0x1e77eb9d, 0x1c9d5c06, 0x33853032, 0x0e33aff7, 0x184b0d8b, 0x218b1b8b, 0x6413}}} + }, + { + /* 1*16^51*G: */ + {{{0x366642be, 0x376d64a0, 0x158ba889, 0x0d241c5f, 0x0dfa8bce, 0x002bd1a0, 0x30c2f91b, 0x1de30119, 0x146a}}, + {{0x3d83efd0, 0x02ca5d20, 0x37e5ed1d, 0x2aa5c74b, 0x14b2870a, 0x1a609fe7, 0x0028add6, 0x383b0cd5, 0xb318}}}, + /* 3*16^51*G: */ + {{{0x27315443, 0x364e1ce0, 0x2e867299, 0x1e6ef552, 0x2142a13d, 0x32266082, 0x0935ff42, 0x1b010198, 0xfc69}}, + {{0x17d28960, 0x1243582d, 0x09bd1b17, 0x1ffd2184, 0x1677b548, 0x0387375a, 0x35892bbf, 0x09fafe0e, 0xe0ce}}}, + /* 5*16^51*G: */ + {{{0x16fdb4eb, 0x06ecbd70, 0x22e6a79d, 0x28f75e71, 0x3eb0928f, 0x15a8d58a, 0x3f2ad1ae, 0x3c887fd3, 0x974a}}, + {{0x29f6f484, 0x10270f7e, 0x3ffc2348, 0x0715ca8e, 0x0090ed11, 0x0790f40b, 0x003ca64d, 0x0e1f54d4, 0x5552}}}, + /* 7*16^51*G: */ + {{{0x1d5aeee3, 0x0e412b6d, 0x258c8137, 0x0a12f0d9, 0x1270c5e8, 0x086ce99a, 0x2398b091, 0x2d66d277, 0x5baa}}, + {{0x30f69717, 0x0b4a6bed, 0x3d31eed8, 0x1777276a, 0x3fdaf721, 0x28021987, 0x37e856e5, 0x1fd85f03, 0x8a57}}}, + /* 9*16^51*G: */ + {{{0x35726890, 0x146c7913, 0x0837d158, 0x24097fab, 0x110a0ee5, 0x0cbf3afe, 0x1c43d010, 0x17e9fad2, 0xfb68}}, + {{0x3835783a, 0x01baa3ce, 0x10e79b26, 0x29b2c4ba, 0x24ba094f, 0x3285b661, 0x25e2e869, 0x37c8b263, 0xd750}}}, + /* 11*16^51*G: */ + {{{0x28bca48a, 0x1192fc4e, 0x03df62f5, 0x2d357d3a, 0x07f71d78, 0x09ee470a, 0x2995a0ab, 0x23fd9678, 0x5de5}}, + {{0x12fd41cd, 0x21e53a03, 0x20f8aa95, 0x396f6713, 0x2d3c843f, 0x2988f094, 0x19b55309, 0x0ecf600d, 0x685a}}}, + /* 13*16^51*G: */ + {{{0x25ef63b6, 0x378e0d13, 0x31b182eb, 0x2d34059c, 0x0fc1c85a, 0x2dff68ed, 0x218bfaf1, 0x09737ab5, 0x6f18}}, + {{0x05c655f3, 0x0b211b3d, 0x27f94541, 0x22569900, 0x3334553c, 0x108135e0, 0x1911b98f, 0x1f9f7564, 0xff09}}}, + /* 15*16^51*G: */ + {{{0x34a63f3b, 0x2d411fb7, 0x178f9727, 0x080ec066, 0x36c76583, 0x1c457d79, 0x2a376b58, 0x2e257dd8, 0xc5ec}}, + {{0x05005024, 0x14fcdd1a, 0x230bee5b, 0x3ad97b97, 0x1233ec8b, 0x290163fe, 0x081f374e, 0x0946065e, 0x2225}}} + }, + { + /* 1*16^52*G: */ + {{{0x3180eef9, 0x35daa1e4, 0x228b9776, 0x00048826, 0x207b128d, 0x2b3aec6a, 0x2e5f07e3, 0x303d8748, 0xfa50}}, + {{0x3f4f2811, 0x233635f4, 0x17a213b3, 0x1a0ca4e9, 0x01a68a5e, 0x334a1c8a, 0x3eba9b72, 0x31a488e5, 0x6b84}}}, + /* 3*16^52*G: */ + {{{0x11da5e12, 0x07b838ce, 0x1cacb297, 0x31829005, 0x1ca2b6a9, 0x0ca7e4e8, 0x1e31bcda, 0x0b8f10de, 0xf750}}, + {{0x0385f4eb, 0x292e717a, 0x325cebc7, 0x21b4cbbd, 0x1672047b, 0x1c25170f, 0x0fafd599, 0x3d7b759f, 0x3c57}}}, + /* 5*16^52*G: */ + {{{0x10b7d105, 0x01d24cc4, 0x0e57c9f2, 0x329712e5, 0x3455b3f4, 0x13d98938, 0x25862a3a, 0x1e3e60eb, 0x12fe}}, + {{0x1f794a60, 0x162b1bee, 0x2ee90b84, 0x3b389975, 0x27cb771d, 0x2d6a8666, 0x2bcf7786, 0x3c68ce35, 0x2062}}}, + /* 7*16^52*G: */ + {{{0x1e0c5d05, 0x188760ce, 0x2572daff, 0x039b142a, 0x084b1a48, 0x12ec40a0, 0x3473d58c, 0x30c4d1f7, 0x76aa}}, + {{0x11ece63e, 0x159866dd, 0x15e6ee35, 0x048973c0, 0x02625f4b, 0x3ccb20c8, 0x070efabe, 0x1dbbc357, 0xef55}}}, + /* 9*16^52*G: */ + {{{0x3c53c086, 0x389bd217, 0x09a1aec9, 0x2d570d27, 0x288104c6, 0x1830c517, 0x05ccc87e, 0x3f96ef97, 0xa663}}, + {{0x25016201, 0x1a7140ca, 0x3994fc0e, 0x07b3295c, 0x023dc399, 0x2c40b226, 0x11fbf5d1, 0x265fdac8, 0xb541}}}, + /* 11*16^52*G: */ + {{{0x0b758574, 0x2b6007b5, 0x34f9c6e9, 0x0c99a250, 0x22bdf3d8, 0x328409eb, 0x2cd825b7, 0x149e8081, 0xde95}}, + {{0x3b67232a, 0x2df7c7f3, 0x15a2deb4, 0x39a84145, 0x169ed7ba, 0x077211fc, 0x3d14e4e2, 0x3815ab24, 0x4cd3}}}, + /* 13*16^52*G: */ + {{{0x3d85474f, 0x1de6e2af, 0x1634668d, 0x13128ae2, 0x385aea89, 0x3732f911, 0x32addbfe, 0x2f3819b4, 0x8da6}}, + {{0x3d7b4ef7, 0x3f7e71f4, 0x1dbdd7a5, 0x073164c1, 0x1dfff10b, 0x377d741c, 0x2d4ff84f, 0x1b1abcc7, 0x13fc}}}, + /* 15*16^52*G: */ + {{{0x3dd042ea, 0x2d750959, 0x18eafd06, 0x3e89a991, 0x3c93beeb, 0x3599278c, 0x3ba39b1b, 0x2b31f3ec, 0x7329}}, + {{0x2f5c94a1, 0x36a33fb0, 0x1fab4f0a, 0x1225dcc7, 0x2b68ee18, 0x2139e53e, 0x36f14892, 0x124d506d, 0x9272}}} + }, + { + /* 1*16^53*G: */ + {{{0x1f067ec2, 0x394f4cad, 0x1bba5220, 0x0a22ad75, 0x08e8421a, 0x16fdadf6, 0x21a11b1a, 0x1874329c, 0xda1d}}, + {{0x1ad836f1, 0x157ee83c, 0x279b48a6, 0x29ce2674, 0x091e2966, 0x01d98587, 0x1306c79c, 0x3d569f26, 0x8157}}}, + /* 3*16^53*G: */ + {{{0x3a95a8db, 0x1761dccb, 0x39d36f61, 0x0fb03111, 0x1b1723b8, 0x25991a64, 0x3dd0419e, 0x036918c0, 0xe3e9}}, + {{0x1b0d1cf9, 0x005b3dfc, 0x0984d3d1, 0x2c7be5f3, 0x02e76afb, 0x3eaa431c, 0x0178bb00, 0x0ef0015b, 0xfbe5}}}, + /* 5*16^53*G: */ + {{{0x112ee214, 0x1eabf590, 0x19315401, 0x0a93a5e5, 0x00c01c78, 0x19437f57, 0x3d775a8b, 0x3fb1ccb8, 0x9f4f}}, + {{0x1085f37a, 0x3bd10889, 0x3c880283, 0x066da4c2, 0x35c69d97, 0x259a0bf5, 0x22f2e60e, 0x38b84c63, 0x639c}}}, + /* 7*16^53*G: */ + {{{0x1f61a0a5, 0x22da0514, 0x3c14e3ef, 0x0494f86c, 0x040b2c4b, 0x0682907d, 0x34ac1b17, 0x188b5044, 0x431f}}, + {{0x38cef899, 0x1adedff9, 0x15657724, 0x2eaa810d, 0x23aa7241, 0x3799465c, 0x2438f6d6, 0x0c9ff9ea, 0xa298}}}, + /* 9*16^53*G: */ + {{{0x27748503, 0x2b099f55, 0x31328e7c, 0x1b8391dc, 0x0a12ac0e, 0x18bbce7e, 0x38fb86cb, 0x2eb77b39, 0x993d}}, + {{0x3eb0cee2, 0x2e9cd84d, 0x38adaa49, 0x3e1efda6, 0x21f51a17, 0x3de11e1e, 0x1eeeb785, 0x2a7ba15a, 0xa521}}}, + /* 11*16^53*G: */ + {{{0x26d23d80, 0x37a889d6, 0x2474d478, 0x02f447c9, 0x0962c0e1, 0x250c72e4, 0x15ea5a33, 0x1eae81ab, 0x75f1}}, + {{0x280dd57e, 0x21aa16c0, 0x34ea5909, 0x0bfefb6e, 0x1b629237, 0x31f42fc6, 0x39a80c7f, 0x18bf8558, 0xa07a}}}, + /* 13*16^53*G: */ + {{{0x21ad3413, 0x38ae6db5, 0x327d684a, 0x2e700100, 0x387b7a8d, 0x257d2172, 0x1f4a0a6e, 0x15578476, 0x6678}}, + {{0x3ebca672, 0x09204081, 0x2dc66601, 0x338b454e, 0x0bdf9ea6, 0x099b649f, 0x0f646925, 0x368f789e, 0x510d}}}, + /* 15*16^53*G: */ + {{{0x06cc8563, 0x3002bd6c, 0x3e101eaa, 0x0937d6ff, 0x16368892, 0x320af606, 0x27748ada, 0x128d8b36, 0xebdc}}, + {{0x2394ccfa, 0x26c5ef3a, 0x1204f924, 0x3101e492, 0x1d4f07be, 0x3b8d79b3, 0x2d35f9b1, 0x0c513a15, 0x659a}}} + }, + { + /* 1*16^54*G: */ + {{{0x0d064e13, 0x29cec184, 0x06f1e062, 0x0c477811, 0x3d416615, 0x17fe63a3, 0x30690721, 0x20bfc325, 0xa8e2}}, + {{0x11f4cc0c, 0x3bdf1cc4, 0x0dd6bd6c, 0x19e68f94, 0x2515888b, 0x2dfcf16c, 0x01c09abf, 0x0d56e36e, 0x7f97}}}, + /* 3*16^54*G: */ + {{{0x3a3979b5, 0x0a8666c2, 0x27e829e2, 0x0a23e379, 0x240e50ba, 0x0dfc2c7b, 0x1e26327f, 0x01f1736b, 0xae22}}, + {{0x0450fa6f, 0x23cf359a, 0x3d4f8896, 0x2a1edf4d, 0x2d7060fc, 0x3249148e, 0x39f71ad4, 0x3f944301, 0xea91}}}, + /* 5*16^54*G: */ + {{{0x0efca824, 0x10406440, 0x22164fae, 0x2f8313fa, 0x185461e0, 0x31504019, 0x2ace59ce, 0x3b432b5c, 0xcb8d}}, + {{0x0f227361, 0x0502f416, 0x3931742f, 0x2b47f7f1, 0x2ccbc496, 0x05b121e8, 0x188c85b3, 0x0023dd03, 0x33a5}}}, + /* 7*16^54*G: */ + {{{0x3bcbd327, 0x1046d368, 0x1e4aaee9, 0x13821488, 0x276ed6b0, 0x2524035f, 0x1836708e, 0x0eca62bc, 0xb0c5}}, + {{0x2d7be436, 0x185af128, 0x0636a0f1, 0x0a88831d, 0x26b2afd8, 0x3da9806d, 0x17ea1638, 0x25d007ef, 0xee2a}}}, + /* 9*16^54*G: */ + {{{0x17b836a1, 0x39bbed8e, 0x3679ef7d, 0x019017fd, 0x37f526c8, 0x2218bb39, 0x1b920d4d, 0x29cfcca7, 0x6f6b}}, + {{0x06832b84, 0x36f7cbec, 0x0e1ff934, 0x264314a2, 0x3ee9c0d8, 0x02e29016, 0x3c18e3db, 0x2285ffd7, 0xdc77}}}, + /* 11*16^54*G: */ + {{{0x1eb39ede, 0x2bb8d082, 0x30612d42, 0x02200cb5, 0x02436031, 0x3fd19f84, 0x22af4bbc, 0x069f71d0, 0x7d47}}, + {{0x2bf6607e, 0x326f3652, 0x022a8fd0, 0x2573df47, 0x3c86fa77, 0x2088c7bf, 0x2856507b, 0x1ec67ce9, 0x004a}}}, + /* 13*16^54*G: */ + {{{0x165eb1c1, 0x15b52789, 0x1ae5c5aa, 0x335d59f3, 0x02f0967f, 0x03f30c66, 0x33fac707, 0x1458fe6d, 0xf002}}, + {{0x2dde2ae0, 0x369f5c11, 0x2cd11e57, 0x1dbfd735, 0x26afed85, 0x1ad29768, 0x120df4c6, 0x2a7a220f, 0x054e}}}, + /* 15*16^54*G: */ + {{{0x1ac32c64, 0x33cd424f, 0x0ae4bf84, 0x0dbf80fb, 0x07715e0e, 0x013a543d, 0x123aa0f7, 0x0500007b, 0xac12}}, + {{0x1eb1a867, 0x204ab6eb, 0x253f0898, 0x16974e96, 0x0499a3ed, 0x02da55cc, 0x38baf187, 0x2f32eb0c, 0xce8e}}} + }, + { + /* 1*16^55*G: */ + {{{0x0319497c, 0x0bce0b7a, 0x12508c02, 0x166c7e94, 0x13cab15d, 0x2795b9a4, 0x285872d3, 0x14ee7268, 0x174a}}, + {{0x079afa73, 0x0f684eb0, 0x0b985438, 0x1ace8763, 0x07f9e664, 0x10557cb1, 0x09c1657b, 0x370deaff, 0xccc9}}}, + /* 3*16^55*G: */ + {{{0x354b8367, 0x25201cf5, 0x3d506bfe, 0x1d6ddf59, 0x036a5db7, 0x2a975161, 0x2526e40c, 0x0252b911, 0x5e5a}}, + {{0x11ce85ca, 0x14ca6a76, 0x1e5ffa44, 0x1aaa7bcf, 0x2a4b7a79, 0x2407c55c, 0x15e05c2c, 0x3e32691e, 0xae8a}}}, + /* 5*16^55*G: */ + {{{0x17b10d9d, 0x06615e4e, 0x11f8fcaf, 0x294bc627, 0x0cb82de6, 0x332e0cc4, 0x02e859de, 0x382b6e5c, 0x00d4}}, + {{0x3140dced, 0x20840121, 0x0e2d923e, 0x1626325e, 0x2287f70b, 0x0be1190c, 0x3640947d, 0x0066060d, 0x87b8}}}, + /* 7*16^55*G: */ + {{{0x1c9caee8, 0x02046982, 0x1a270bb2, 0x0b88116c, 0x04a66763, 0x1e866bbb, 0x374c0f6f, 0x1484da3b, 0x0366}}, + {{0x3772b711, 0x2a7b1a8e, 0x295ba7f0, 0x32ea624c, 0x26944501, 0x27f1a06e, 0x3ded9994, 0x30cacaa4, 0x1f18}}}, + /* 9*16^55*G: */ + {{{0x1446c85c, 0x0ffe5d46, 0x201c0635, 0x0df78239, 0x36c6eade, 0x19db114f, 0x38f1faa0, 0x24415bf6, 0x0e58}}, + {{0x2148972e, 0x3db1df9c, 0x0cddadd5, 0x2408d3a0, 0x081898f4, 0x1d062ebd, 0x27bda0ec, 0x1217c47e, 0xe39a}}}, + /* 11*16^55*G: */ + {{{0x022e1259, 0x3c62b7cf, 0x281362af, 0x05ce6901, 0x07777193, 0x33d7ea80, 0x1463f2b6, 0x049b49bc, 0xa740}}, + {{0x334a5f43, 0x3ddc5c90, 0x31d6dad5, 0x21979d4e, 0x3c7ee517, 0x17c5d299, 0x0f1ff1b0, 0x3feebc65, 0x05a9}}}, + /* 13*16^55*G: */ + {{{0x0b08f1fe, 0x22285e8f, 0x3a087bfd, 0x339fb9c2, 0x02d177d7, 0x1015d976, 0x074e4a65, 0x2e085b65, 0x87e4}}, + {{0x2ed5e2ec, 0x17dd2b26, 0x2786d9d7, 0x0bc8f6f5, 0x38c2cc6e, 0x35fe3a8b, 0x348cecd7, 0x0eb01d98, 0xf74e}}}, + /* 15*16^55*G: */ + {{{0x21c4d15c, 0x2a1c039a, 0x3c0e74b9, 0x17a9efc1, 0x254a4410, 0x308b0304, 0x279a5a92, 0x06d18ffa, 0x35ea}}, + {{0x3f3fe1ea, 0x324e6ebd, 0x065095ed, 0x18cea80c, 0x0d3b185d, 0x23e97f5d, 0x2d2cd788, 0x245946e7, 0xad21}}} + }, + { + /* 1*16^56*G: */ + {{{0x1475b7ba, 0x213f7fc2, 0x0918b3d8, 0x0e79cc39, 0x018cdbe0, 0x395fb7d4, 0x3785c3d3, 0x25a60650, 0x9593}}, + {{0x3524f2fd, 0x26e2afe1, 0x0709385e, 0x194fd932, 0x1cd6849c, 0x00e1a92e, 0x331dd8ba, 0x154a2230, 0x2e7e}}}, + /* 3*16^56*G: */ + {{{0x0fd69985, 0x02717764, 0x1df72aea, 0x0c2732db, 0x0ccf149f, 0x3da437ef, 0x32f7e788, 0x1d9d73ad, 0x0ae9}}, + {{0x1409a003, 0x2723ad04, 0x2ee1aff8, 0x2e67505e, 0x1a54c5d0, 0x237fb814, 0x08d14e9b, 0x265cfdb9, 0x9121}}}, + /* 5*16^56*G: */ + {{{0x19262b90, 0x37064f7f, 0x23cc29a9, 0x08f1307f, 0x025d1fb7, 0x197c5de0, 0x1612ec9b, 0x218a96b0, 0x2b15}}, + {{0x083d7557, 0x24665b99, 0x19489a49, 0x14d25c3e, 0x0749066f, 0x0c354b6a, 0x233faa7a, 0x014f6a82, 0x2eb0}}}, + /* 7*16^56*G: */ + {{{0x28e7be40, 0x0fe5c532, 0x1040ee59, 0x34b22524, 0x24769af2, 0x2570585b, 0x2ee677ee, 0x3abb46a5, 0x6af9}}, + {{0x2e387e1c, 0x2905b809, 0x0f59569f, 0x38fd99a8, 0x07dc8145, 0x27a90a0d, 0x06649670, 0x0a845a40, 0xb381}}}, + /* 9*16^56*G: */ + {{{0x3482801e, 0x09adbe83, 0x1bd4155d, 0x1e53e2f1, 0x38d6f940, 0x2aad0932, 0x0144eeb3, 0x1a3b8111, 0x5966}}, + {{0x04870c37, 0x11dc523c, 0x3d3535ad, 0x2db072d8, 0x31304e8d, 0x23e5821d, 0x2ef5f1ec, 0x282a16ee, 0x949a}}}, + /* 11*16^56*G: */ + {{{0x032c19fd, 0x1326cb9f, 0x18028c3e, 0x32ae3a41, 0x170b5b4a, 0x3d345ead, 0x050762fd, 0x346206d4, 0xbe84}}, + {{0x32f1281f, 0x1da5294d, 0x250dc376, 0x1569fd57, 0x08399479, 0x3997d20c, 0x050944d1, 0x1832ccb7, 0xeff9}}}, + /* 13*16^56*G: */ + {{{0x16c69482, 0x346dd7f5, 0x32fa167b, 0x3aad5004, 0x32bc88cb, 0x15c9d32b, 0x17ee541f, 0x280c5303, 0x9867}}, + {{0x2f792cd7, 0x1bc18451, 0x15628a91, 0x189173d4, 0x3a99639e, 0x24b556c6, 0x0834f9c7, 0x18568ec4, 0xd02e}}}, + /* 15*16^56*G: */ + {{{0x1d557aa1, 0x2288e764, 0x101fc297, 0x0764bfb3, 0x19d6abdf, 0x1fcba802, 0x0815a592, 0x3c915036, 0xa866}}, + {{0x01430634, 0x2606eed3, 0x0611a4b7, 0x3ada719f, 0x30e13961, 0x0f63e976, 0x22b44d79, 0x0e7daa00, 0xb587}}} + }, + { + /* 1*16^57*G: */ + {{{0x1d82b151, 0x2d44d032, 0x21fba2db, 0x28290f55, 0x109a8fcc, 0x168454ec, 0x01e56d64, 0x0e942b90, 0xd2a6}}, + {{0x1cf89405, 0x105085d3, 0x084ca52d, 0x03dd42bd, 0x148220a7, 0x2bb962ca, 0x3fcb7565, 0x21bed910, 0xe82d}}}, + /* 3*16^57*G: */ + {{{0x2e4b3ba0, 0x2167d8d7, 0x18bf1f17, 0x0aafbd7c, 0x3f245f5c, 0x385c3cc6, 0x3fb73bef, 0x04414887, 0x4108}}, + {{0x17525595, 0x21a58770, 0x1a064554, 0x0d926159, 0x2b849813, 0x2996b875, 0x35668f2c, 0x3cda5dbf, 0xdc37}}}, + /* 5*16^57*G: */ + {{{0x13d98ded, 0x18a726e2, 0x38a02184, 0x37c8a0ce, 0x31d65edb, 0x3c8a6414, 0x0c0c8c8c, 0x2884285b, 0x63a2}}, + {{0x20d1cfc2, 0x06465f53, 0x1c7873a5, 0x2afda802, 0x2d94461f, 0x140cc953, 0x2c76fd06, 0x10b8b9ff, 0x882b}}}, + /* 7*16^57*G: */ + {{{0x38045445, 0x2a186942, 0x01e8d7ee, 0x3fdcdc64, 0x17bef080, 0x04b8b975, 0x167ca3df, 0x20575127, 0x0c15}}, + {{0x0054a206, 0x053e1f55, 0x258cea32, 0x0c15390d, 0x23cd28ba, 0x24f0ed99, 0x14115d0a, 0x35828eba, 0x2f30}}}, + /* 9*16^57*G: */ + {{{0x03857faf, 0x3a448e73, 0x29619701, 0x0bf2b787, 0x28ef7f88, 0x1eea3d20, 0x28a9c0d5, 0x3adae26b, 0xc757}}, + {{0x20584ca4, 0x07676c32, 0x01894c10, 0x1f4c4344, 0x3ec61b62, 0x0da7c822, 0x3ff36257, 0x1673f348, 0xf03a}}}, + /* 11*16^57*G: */ + {{{0x1459225d, 0x3934613d, 0x18858d10, 0x3ebddf8b, 0x1c02a244, 0x17502646, 0x3a0d0f81, 0x18ebab6b, 0xfa80}}, + {{0x3ece1507, 0x28adf8ed, 0x007c59c3, 0x0adb0db4, 0x0c425c0a, 0x37888209, 0x0c069160, 0x07e415f0, 0x0ba7}}}, + /* 13*16^57*G: */ + {{{0x16f0d044, 0x19e7fa50, 0x09e61a79, 0x2ea7f524, 0x2ee0a5aa, 0x3da73e18, 0x257a89e2, 0x28f16740, 0x658c}}, + {{0x37cb872d, 0x3747ccbb, 0x018ce89a, 0x2859d8f1, 0x3bd37655, 0x197589c4, 0x225460f1, 0x304ddeba, 0xae5c}}}, + /* 15*16^57*G: */ + {{{0x3696756d, 0x2d6b255c, 0x2561417a, 0x1abc5815, 0x3f305c67, 0x30660d74, 0x1f2bace4, 0x12d2abe4, 0x31c9}}, + {{0x1e08ae78, 0x2f117a37, 0x2ad1070a, 0x2bb7f2b9, 0x34160683, 0x2e2d66ab, 0x283a9bf4, 0x2212d55b, 0xf80f}}} + }, + { + /* 1*16^58*G: */ + {{{0x1617e073, 0x10dbe6d1, 0x039317b3, 0x2b2f6f4e, 0x0fdc866b, 0x39e25b5f, 0x31eb890e, 0x1f88cd51, 0x6458}}, + {{0x1faf6589, 0x20a6797a, 0x33aeab35, 0x2e428e44, 0x0299a185, 0x1b75911f, 0x102e2ae9, 0x33756fda, 0xd99f}}}, + /* 3*16^58*G: */ + {{{0x0e103dd6, 0x37dc51c8, 0x0004859a, 0x1181301f, 0x12a17ac3, 0x084f3f16, 0x203f836a, 0x1ef55690, 0xbc47}}, + {{0x16f7c343, 0x0e420b63, 0x23b44ac6, 0x0a4d5cb1, 0x1ea6395d, 0x2b154b1b, 0x0dd526cb, 0x07890a6a, 0xe31e}}}, + /* 5*16^58*G: */ + {{{0x144eab31, 0x34370ec3, 0x0e634907, 0x316bc501, 0x3bf8e80a, 0x0ed08c99, 0x3b838030, 0x2d3f969a, 0x589d}}, + {{0x11361f6a, 0x106baf9d, 0x148f8db9, 0x18439548, 0x3d90f31f, 0x1c188092, 0x2a2a4f60, 0x11170422, 0x6255}}}, + /* 7*16^58*G: */ + {{{0x1a0c2c41, 0x2fe585ca, 0x20336c67, 0x20c70715, 0x2edb7c42, 0x286182b5, 0x22fa2ea8, 0x2ccdf45b, 0x1339}}, + {{0x29f1bc2b, 0x217c152e, 0x1e923a41, 0x0489fe1f, 0x13a3406b, 0x0c903f44, 0x3ae5ba7a, 0x0a58d8b1, 0x9f9b}}}, + /* 9*16^58*G: */ + {{{0x18fc47af, 0x1c12c7e1, 0x2c0cdec3, 0x377fb20c, 0x01b568a8, 0x00ca6d40, 0x3cf17cc5, 0x2ee844d8, 0x7ff3}}, + {{0x39ba43a7, 0x3e185933, 0x18bac297, 0x294ec6b4, 0x33446b17, 0x32246dd1, 0x0a629a0b, 0x29eba006, 0x1f6b}}}, + /* 11*16^58*G: */ + {{{0x15213775, 0x06135802, 0x3d42a990, 0x2d0a4ec8, 0x2c7f6100, 0x07a4e57f, 0x360bb614, 0x1c118f3a, 0x8ec6}}, + {{0x3841ffff, 0x38043cf9, 0x0cf51e90, 0x36a6282f, 0x2dee0e71, 0x190d0573, 0x25be306e, 0x299be836, 0x8f58}}}, + /* 13*16^58*G: */ + {{{0x3452abbb, 0x32cffe34, 0x2b95c2e3, 0x1aa9cbf8, 0x15d495ae, 0x2eb0ffb6, 0x301bb89d, 0x186d1079, 0x83de}}, + {{0x054eb66e, 0x28145dac, 0x3ce42918, 0x2717cdae, 0x0e1563d7, 0x3edabe31, 0x0609fa6b, 0x38cd28d3, 0x32f0}}}, + /* 15*16^58*G: */ + {{{0x359276f1, 0x25a2309b, 0x2a17b15e, 0x2b896ca4, 0x3cd86833, 0x2ed7003d, 0x0c1db1a8, 0x18e263d4, 0x3d76}}, + {{0x059cbcb3, 0x0792996e, 0x1b197860, 0x08660806, 0x18333ef3, 0x1db8d36b, 0x07ddb609, 0x1a5cde86, 0xd376}}} + }, + { + /* 1*16^59*G: */ + {{{0x1d45e458, 0x1635b21b, 0x250e7fd3, 0x02a9b3a8, 0x09de042f, 0x151b4f95, 0x0d885b3a, 0x2f783939, 0x8481}}, + {{0x1779057e, 0x3592c6d6, 0x3262e556, 0x029e710a, 0x2cb2ca90, 0x096fce73, 0x004dd84a, 0x1ee32e95, 0x38ee}}}, + /* 3*16^59*G: */ + {{{0x152da17d, 0x18283e90, 0x0d0646b1, 0x3704f6c2, 0x200bc811, 0x139ac17f, 0x18c5f089, 0x3b4783d4, 0x3bea}}, + {{0x2cc768d2, 0x39c12617, 0x1fec416c, 0x3379dee3, 0x00e1b554, 0x12a2fafa, 0x37acdfef, 0x35fd56bf, 0xc3b0}}}, + /* 5*16^59*G: */ + {{{0x3a4edcc5, 0x0d3e85f6, 0x20311b72, 0x138c8850, 0x275997e7, 0x0b7f00e4, 0x09d61875, 0x36e832f7, 0x6e73}}, + {{0x159da0e4, 0x2cc7df37, 0x00679037, 0x229df69c, 0x02869327, 0x11542222, 0x2cc48bea, 0x307f127b, 0xee0a}}}, + /* 7*16^59*G: */ + {{{0x0a80b979, 0x02713109, 0x29abb314, 0x243d7e8c, 0x07c31004, 0x1f65faa9, 0x1b592762, 0x37624df9, 0x7706}}, + {{0x0126cfde, 0x133d2041, 0x17efe321, 0x3e828d3f, 0x2a9c7117, 0x2375e647, 0x3b714777, 0x2a609f56, 0x8a02}}}, + /* 9*16^59*G: */ + {{{0x326fe285, 0x336e712d, 0x13ef127d, 0x16eb0a50, 0x39e06aa4, 0x3cf1e907, 0x3c0f80d2, 0x08b164a6, 0x16d4}}, + {{0x0155b441, 0x0f83ff9b, 0x3364d423, 0x0fc3044d, 0x3531b1e9, 0x2df9a698, 0x22641a8a, 0x223e9478, 0x0df8}}}, + /* 11*16^59*G: */ + {{{0x3acfa513, 0x38c42f2a, 0x260e3aea, 0x0901e7e6, 0x356a9c4e, 0x28d11d43, 0x36d63aa5, 0x0391fbb1, 0x1fcc}}, + {{0x107afc9c, 0x141d6e90, 0x09839187, 0x3b7b7459, 0x39f9b44b, 0x38e1d50c, 0x35478b48, 0x30681078, 0x165d}}}, + /* 13*16^59*G: */ + {{{0x3edc69b2, 0x0689c1f3, 0x26b77172, 0x0298226c, 0x0aa386a5, 0x190c10d7, 0x0b8a1730, 0x241ceb5b, 0xc12b}}, + {{0x20dd41dd, 0x0caba6c0, 0x127b2a00, 0x3b876f8f, 0x094976b8, 0x1cb7227e, 0x0cdf1d97, 0x310ff94d, 0x3173}}}, + /* 15*16^59*G: */ + {{{0x3961fe4d, 0x2dbd6177, 0x3107197a, 0x05221be2, 0x2ca73e8a, 0x0fa4c4c4, 0x27a8fa3f, 0x2fe1770c, 0xd059}}, + {{0x2ae823c2, 0x264d6c19, 0x0dab64cb, 0x0e22e87d, 0x0955b4fd, 0x01d97721, 0x3525e3fe, 0x1e983022, 0x4510}}} + }, + { + /* 1*16^60*G: */ + {{{0x2caf666b, 0x3358c0fd, 0x0b1ce30b, 0x3f3fb4f1, 0x17f4637f, 0x1a5e6ba0, 0x102aa62b, 0x1295e9e0, 0x1346}}, + {{0x3f6ecc27, 0x3d256a41, 0x10942e13, 0x3cc02a07, 0x0cb0ca48, 0x390cd14f, 0x14580ef7, 0x05640118, 0x69be}}}, + /* 3*16^60*G: */ + {{{0x0eca5f51, 0x085ac826, 0x0fc9aebf, 0x3a85c6e5, 0x05b5cfdd, 0x3b5acafc, 0x2e6962c6, 0x35453767, 0xdde9}}, + {{0x10c638f7, 0x2b5a69cf, 0x289571f9, 0x3fbafa37, 0x3f8f0950, 0x07cd2c29, 0x28111d89, 0x1a44cf38, 0xb84e}}}, + /* 5*16^60*G: */ + {{{0x199c88e4, 0x3e41ac16, 0x0ad46ec2, 0x3b544f88, 0x204b179a, 0x3d01bac4, 0x193736e9, 0x188408da, 0xfd1a}}, + {{0x195bc8df, 0x27232459, 0x1cc00f29, 0x1adc7525, 0x177782dc, 0x0f01a552, 0x0c20bfb1, 0x1ed52e72, 0x1ac9}}}, + /* 7*16^60*G: */ + {{{0x1f8018ce, 0x35456d6d, 0x1892d68b, 0x0b695ce3, 0x086dc7cf, 0x3ff393cb, 0x296b9f13, 0x214c7630, 0x4ee4}}, + {{0x1e48381f, 0x30d6986c, 0x0e806013, 0x01d25c6d, 0x07c5e671, 0x2d102343, 0x3f8b5fc7, 0x27b52042, 0xb68f}}}, + /* 9*16^60*G: */ + {{{0x31473678, 0x0a14ba47, 0x14392f70, 0x2815e542, 0x38c070cb, 0x38c53156, 0x000dbff5, 0x33270d31, 0xfd76}}, + {{0x0d144f4f, 0x38593baa, 0x001c8437, 0x18a3bb85, 0x032cd660, 0x3b829cf4, 0x143dae0f, 0x1950de1c, 0xf204}}}, + /* 11*16^60*G: */ + {{{0x0d7a2193, 0x3c02dc52, 0x197546ed, 0x1a47913c, 0x34ea212c, 0x1b3a09d2, 0x3b40219e, 0x2ae8cc48, 0x85a2}}, + {{0x30cdcf3a, 0x3c320f52, 0x03b12427, 0x31b6b7e7, 0x0c029fe1, 0x31820b47, 0x30516d82, 0x2615faca, 0x9c12}}}, + /* 13*16^60*G: */ + {{{0x377568b0, 0x16c0c16c, 0x1e03b053, 0x2ba37406, 0x03650f35, 0x2db5b15e, 0x3fe74440, 0x36ff1cf3, 0xd25d}}, + {{0x1f39929c, 0x0284e49b, 0x23c3f006, 0x089ce207, 0x27d92b83, 0x2bbdd337, 0x048938be, 0x3fdd64fe, 0x7a3a}}}, + /* 15*16^60*G: */ + {{{0x271d7c13, 0x17f94462, 0x20ffa385, 0x06ad7dfe, 0x2ac80564, 0x01fa6a5e, 0x14a7255f, 0x0d4c50fa, 0x4581}}, + {{0x3aff63cf, 0x18e2f154, 0x2bd96b99, 0x08019550, 0x1d69c970, 0x3d43c5df, 0x39ad8b57, 0x163b0525, 0x9f58}}} + }, + { + /* 1*16^61*G: */ + {{{0x2d83f366, 0x2b68e834, 0x2f28588c, 0x36733b78, 0x1dc97a0c, 0x3d0c2f30, 0x3fe2e9ae, 0x277d6dc4, 0xbc4a}}, + {{0x181f33c1, 0x1d635999, 0x2547b16d, 0x3a2a7efe, 0x3798caa6, 0x24deb7d2, 0x05c06383, 0x20729b9e, 0x0d3a}}}, + /* 3*16^61*G: */ + {{{0x3712be3c, 0x01a8b8cb, 0x2146a66b, 0x257c63b6, 0x00153472, 0x1c976eac, 0x1b378d3c, 0x0d2764cc, 0x39d7}}, + {{0x1c6ff65c, 0x30c067d0, 0x0a41644c, 0x17bde97b, 0x2812e8ef, 0x09d55319, 0x33bf7fb1, 0x26d3d5bb, 0x8f92}}}, + /* 5*16^61*G: */ + {{{0x1f77f22b, 0x2ab93ef3, 0x0f82e035, 0x265c8e65, 0x15af26c6, 0x0735b0a6, 0x01dd09e5, 0x2985fdf7, 0xf0cb}}, + {{0x1909a03c, 0x3f238b1d, 0x0a095661, 0x3c631fa4, 0x16d04004, 0x0c9b0d94, 0x1df989ef, 0x2ad0c4fe, 0x1a25}}}, + /* 7*16^61*G: */ + {{{0x06509c12, 0x22b37353, 0x3d1f4765, 0x1aff88d6, 0x3268ed8d, 0x05c3a361, 0x154d321d, 0x1eae76c8, 0x381d}}, + {{0x2eb46102, 0x1190aa38, 0x0e6eaf75, 0x160a161b, 0x2581e720, 0x34915ce9, 0x23da9eb5, 0x2ad6dff6, 0xa47a}}}, + /* 9*16^61*G: */ + {{{0x384fe955, 0x36ced358, 0x063bce48, 0x2655a968, 0x0c8a53f6, 0x0edcf9a5, 0x387e6479, 0x3c1519ea, 0xa703}}, + {{0x161344bd, 0x09acbbef, 0x197277fa, 0x27858a71, 0x19199b53, 0x29e4b5ac, 0x047adc0e, 0x3e4d68ac, 0xd500}}}, + /* 11*16^61*G: */ + {{{0x06eace58, 0x126595b0, 0x2f3211d3, 0x1f9158e8, 0x13a03f1b, 0x1ab435c1, 0x150d746c, 0x2cf16ab5, 0x73c6}}, + {{0x2af8654e, 0x05c2a45c, 0x3b8d2917, 0x1aa1e36e, 0x2d91c6aa, 0x242644d9, 0x24f741ba, 0x2d291cce, 0x3a2f}}}, + /* 13*16^61*G: */ + {{{0x00181d5e, 0x12ce22fc, 0x15aaf205, 0x1c6cea6e, 0x0eddb8de, 0x0034e870, 0x147fda1d, 0x3cf9d41b, 0xc627}}, + {{0x369f886d, 0x09e40298, 0x1cbe2c39, 0x3dac0152, 0x21f7d68e, 0x1a5804e2, 0x02a63b2d, 0x2775c791, 0xd78f}}}, + /* 15*16^61*G: */ + {{{0x37828b16, 0x138a367e, 0x0a4847f3, 0x11e563ca, 0x06de53a0, 0x17d029bc, 0x3d233fa2, 0x3eaf83b7, 0xbb88}}, + {{0x0aea5df7, 0x1451ce88, 0x3a1e969c, 0x12a05d38, 0x159163ec, 0x37165804, 0x1e8dd345, 0x1dacc13d, 0xb736}}} + }, + { + /* 1*16^62*G: */ + {{{0x25324caa, 0x152acc3f, 0x29472a39, 0x12d978c2, 0x12a32e69, 0x3631d251, 0x18bc0d23, 0x2a5efe0a, 0x8c28}}, + {{0x0bef9482, 0x39c771cf, 0x11cb9459, 0x39e13c11, 0x3cc0eb7a, 0x3fb7cc7d, 0x05193378, 0x0118e8cc, 0x40a3}}}, + /* 3*16^62*G: */ + {{{0x0754dd40, 0x18fa1c55, 0x03466cf8, 0x10898c7f, 0x32f6e9a2, 0x12107f35, 0x0dfcf45b, 0x091c0cb0, 0x9729}}, + {{0x2aa36143, 0x212d24bc, 0x1acaf493, 0x36ba1495, 0x14df3690, 0x171d772f, 0x3ea1dcd1, 0x28910997, 0x91d1}}}, + /* 5*16^62*G: */ + {{{0x0c2ca7ff, 0x30b60bae, 0x1df021a3, 0x00d91765, 0x2f27af18, 0x1e46b568, 0x2796e050, 0x1fe5d602, 0x8963}}, + {{0x30493e68, 0x3b505785, 0x242eab7b, 0x1ef1a8e3, 0x357489f8, 0x2e73c550, 0x08424d57, 0x38492322, 0x2d1f}}}, + /* 7*16^62*G: */ + {{{0x0ca8dd7f, 0x061b58e8, 0x2a1381a6, 0x31ca00d5, 0x1357421b, 0x327680f5, 0x25e092fd, 0x0e39c6f8, 0x3081}}, + {{0x0a92c7f2, 0x1057c91e, 0x34ad915e, 0x05959190, 0x008e18c8, 0x27b11745, 0x0fc925e3, 0x38b4a20a, 0x28d1}}}, + /* 9*16^62*G: */ + {{{0x066a3fb1, 0x037315a2, 0x192e206c, 0x30024a06, 0x36862f6e, 0x15d43216, 0x1eb65d1e, 0x313a0a9b, 0x575f}}, + {{0x102655ad, 0x26e3a42a, 0x2a3af2f0, 0x0ced5cf1, 0x0e87daed, 0x076f0a5e, 0x2fca2d67, 0x36e410a9, 0x6f6e}}}, + /* 11*16^62*G: */ + {{{0x390117df, 0x06daa291, 0x22010292, 0x094eeef3, 0x2a2a8fda, 0x3c9be07b, 0x2ab7a227, 0x240dad93, 0xa5ec}}, + {{0x386462fe, 0x204a04cf, 0x214a363d, 0x21187c15, 0x1fa0f71c, 0x25e60eb4, 0x140400c5, 0x319897b0, 0xb79d}}}, + /* 13*16^62*G: */ + {{{0x172ad712, 0x2c3e5d70, 0x21047290, 0x0e632c37, 0x2349b95a, 0x39e5d851, 0x10b0949d, 0x37fa44cc, 0xa153}}, + {{0x0d48fdd2, 0x2297d94e, 0x2f0b329c, 0x014fca16, 0x31b89abd, 0x0c6357c7, 0x05b2fc48, 0x36104fec, 0xfd94}}}, + /* 15*16^62*G: */ + {{{0x11cf5b3a, 0x0c30dc04, 0x1b5a7810, 0x10cea0ef, 0x2dc824c4, 0x30d34223, 0x14615935, 0x06b1abde, 0x9a54}}, + {{0x36a44ae4, 0x0fd55d7c, 0x21ea52d6, 0x123fb894, 0x0f475f55, 0x386bcda2, 0x06ab7caf, 0x123072c4, 0xb661}}} + }, + { + /* 1*16^63*G: */ + {{{0x1faccae0, 0x2312e844, 0x24bb3374, 0x22cd4316, 0x071fd23c, 0x3653393c, 0x127a8c1d, 0x259984e5, 0x08ea}}, + {{0x0e62b945, 0x16bcd28c, 0x0f0f8e95, 0x2de0efa7, 0x15c5d735, 0x39f033ee, 0x22782e24, 0x3eaef23b, 0x620e}}}, + /* 3*16^63*G: */ + {{{0x26a06f5e, 0x06902d65, 0x2a083702, 0x1064945b, 0x23b716a3, 0x2c350849, 0x0253ac37, 0x093efa85, 0x383b}}, + {{0x13c6e772, 0x227d1e1b, 0x38c2b040, 0x3dab9d2e, 0x2a5a19e8, 0x3d59b553, 0x1ba2044c, 0x1c1ab13b, 0x54cf}}}, + /* 5*16^63*G: */ + {{{0x0638a136, 0x1e5d7075, 0x2838195c, 0x034738cd, 0x0d790c2b, 0x39671ad8, 0x2ed6d789, 0x0cb40f80, 0xe684}}, + {{0x0c6c2584, 0x2bf46042, 0x3357336a, 0x0278faf6, 0x01e6472e, 0x0a9cc0e8, 0x35a6624d, 0x3904e638, 0xca5b}}}, + /* 7*16^63*G: */ + {{{0x16e8c10c, 0x33a1f110, 0x11bd6807, 0x1ca617ce, 0x306e7fb4, 0x3ef7b39c, 0x25c2a0ee, 0x355678bf, 0x395d}}, + {{0x05fe638e, 0x30f5b64c, 0x066922cb, 0x24270137, 0x3a4e274c, 0x04fa1ebf, 0x12ac5d04, 0x37352d16, 0xfd62}}}, + /* 9*16^63*G: */ + {{{0x0d6c14ef, 0x059936c8, 0x2f93c8f5, 0x163f1d41, 0x22648008, 0x3bb56fbb, 0x25dcb9f6, 0x12b70d54, 0x7a51}}, + {{0x0b3fbd13, 0x2b4f861c, 0x2a6e24f7, 0x2fabbdca, 0x0f5c3729, 0x1fc2e532, 0x2e4d8e89, 0x347fb454, 0x56ed}}}, + /* 11*16^63*G: */ + {{{0x0f6d65eb, 0x2a518f41, 0x04021524, 0x26441dd5, 0x108f235a, 0x23bcefd2, 0x1d90d8ea, 0x3f5610c9, 0x1ee1}}, + {{0x1d22941c, 0x380dae49, 0x23582b11, 0x0cbd3a61, 0x02fcfaca, 0x2ae7f13d, 0x2c73c1cf, 0x0a246f75, 0xbb69}}}, + /* 13*16^63*G: */ + {{{0x0e36cb44, 0x3c6543bc, 0x1ca20191, 0x1fa2db23, 0x03357d61, 0x163f4362, 0x3aaa8bc0, 0x158d34e3, 0x1551}}, + {{0x1f495a68, 0x0a6bd194, 0x020c1e53, 0x30dc5d7c, 0x23205da8, 0x038fc2d1, 0x35215e37, 0x3ff1d555, 0xab4f}}}, + /* 15*16^63*G: */ + {{{0x3427bacc, 0x07e51841, 0x12d62e15, 0x1ccc5937, 0x0dc4aa9e, 0x163ac256, 0x35201363, 0x2f1911af, 0x3bc6}}, + {{0x2ad6fda6, 0x130cff57, 0x28beb471, 0x06dd6948, 0x16c02bd7, 0x18bb889b, 0x2c305cdb, 0x17301c5d, 0x8e30}}} + }, diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.c b/hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.c new file mode 100644 index 00000000..8202d841 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.c @@ -0,0 +1,191 @@ +/* Copyright (c) 2017 Pieter Wuille + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 "segwit_addr.h" + +uint32_t bech32_polymod_step(uint32_t pre) { + uint8_t b = pre >> 25; + return ((pre & 0x1FFFFFF) << 5) ^ + (-((b >> 0) & 1) & 0x3b6a57b2UL) ^ + (-((b >> 1) & 1) & 0x26508e6dUL) ^ + (-((b >> 2) & 1) & 0x1ea119faUL) ^ + (-((b >> 3) & 1) & 0x3d4233ddUL) ^ + (-((b >> 4) & 1) & 0x2a1462b3UL); +} + +static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; + +static const int8_t charset_rev[128] = { + -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, + 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 +}; + +int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len) { + uint32_t chk = 1; + size_t i = 0; + while (hrp[i] != 0) { + int ch = hrp[i]; + if (ch < 33 || ch > 126) { + return 0; + } + + if (ch >= 'A' && ch <= 'Z') return 0; + chk = bech32_polymod_step(chk) ^ (ch >> 5); + ++i; + } + if (i + 7 + data_len > 90) return 0; + chk = bech32_polymod_step(chk); + while (*hrp != 0) { + chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f); + *(output++) = *(hrp++); + } + *(output++) = '1'; + for (i = 0; i < data_len; ++i) { + if (*data >> 5) return 0; + chk = bech32_polymod_step(chk) ^ (*data); + *(output++) = charset[*(data++)]; + } + for (i = 0; i < 6; ++i) { + chk = bech32_polymod_step(chk); + } + chk ^= 1; + for (i = 0; i < 6; ++i) { + *(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f]; + } + *output = 0; + return 1; +} + +int bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) { + uint32_t chk = 1; + size_t i; + size_t input_len = strlen(input); + size_t hrp_len; + int have_lower = 0, have_upper = 0; + if (input_len < 8 || input_len > 90) { + return 0; + } + *data_len = 0; + while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { + ++(*data_len); + } + hrp_len = input_len - (1 + *data_len); + if (hrp_len < 1 || *data_len < 6) { + return 0; + } + *(data_len) -= 6; + for (i = 0; i < hrp_len; ++i) { + int ch = input[i]; + if (ch < 33 || ch > 126) { + return 0; + } + if (ch >= 'a' && ch <= 'z') { + have_lower = 1; + } else if (ch >= 'A' && ch <= 'Z') { + have_upper = 1; + ch = (ch - 'A') + 'a'; + } + hrp[i] = ch; + chk = bech32_polymod_step(chk) ^ (ch >> 5); + } + hrp[i] = 0; + chk = bech32_polymod_step(chk); + for (i = 0; i < hrp_len; ++i) { + chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f); + } + ++i; + while (i < input_len) { + int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; + if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1; + if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; + if (v == -1) { + return 0; + } + chk = bech32_polymod_step(chk) ^ v; + if (i + 6 < input_len) { + data[i - (1 + hrp_len)] = v; + } + ++i; + } + if (have_lower && have_upper) { + return 0; + } + return chk == 1; +} + +static int convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) { + uint32_t val = 0; + int bits = 0; + uint32_t maxv = (((uint32_t)1) << outbits) - 1; + while (inlen--) { + val = (val << inbits) | *(in++); + bits += inbits; + while (bits >= outbits) { + bits -= outbits; + out[(*outlen)++] = (val >> bits) & maxv; + } + } + if (pad) { + if (bits) { + out[(*outlen)++] = (val << (outbits - bits)) & maxv; + } + } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { + return 0; + } + return 1; +} + +int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) { + uint8_t data[65]; + size_t datalen = 0; + if (witver > 16) return 0; + if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0; + if (witprog_len < 2 || witprog_len > 40) return 0; + data[0] = witver; + convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1); + ++datalen; + return bech32_encode(output, hrp, data, datalen); +} + +int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) { + uint8_t data[84]; + char hrp_actual[84]; + size_t data_len; + if (!bech32_decode(hrp_actual, data, &data_len, addr)) return 0; + if (data_len == 0 || data_len > 65) return 0; + if (strncmp(hrp, hrp_actual, 84) != 0) return 0; + if (data[0] > 16) return 0; + *witdata_len = 0; + if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0; + if (*witdata_len < 2 || *witdata_len > 40) return 0; + if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0; + *witver = data[0]; + return 1; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.h b/hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.h new file mode 100644 index 00000000..dbec91b0 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/segwit_addr.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2017 Pieter Wuille + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 _SEGWIT_ADDR_H_ +#define _SEGWIT_ADDR_H_ 1 + +#include + +/** Encode a SegWit address + * + * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be + * updated to contain the null-terminated address. + * In: hrp: Pointer to the null-terminated human readable part to use + * (chain/network specific). + * ver: Version of the witness program (between 0 and 16 inclusive). + * prog: Data bytes for the witness program (between 2 and 40 bytes). + * prog_len: Number of data bytes in prog. + * Returns 1 if successful. + */ +int segwit_addr_encode( + char *output, + const char *hrp, + int ver, + const uint8_t *prog, + size_t prog_len +); + +/** Decode a SegWit address + * + * Out: ver: Pointer to an int that will be updated to contain the witness + * program version (between 0 and 16 inclusive). + * prog: Pointer to a buffer of size 40 that will be updated to + * contain the witness program bytes. + * prog_len: Pointer to a size_t that will be updated to contain the length + * of bytes in prog. + * hrp: Pointer to the null-terminated human readable part that is + * expected (chain/network specific). + * addr: Pointer to the null-terminated address. + * Returns 1 if successful. + */ +int segwit_addr_decode( + int* ver, + uint8_t* prog, + size_t* prog_len, + const char* hrp, + const char* addr +); + +/** Encode a Bech32 string + * + * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that + * will be updated to contain the null-terminated Bech32 string. + * In: hrp : Pointer to the null-terminated human readable part. + * data : Pointer to an array of 5-bit values. + * data_len: Length of the data array. + * Returns 1 if successful. + */ +int bech32_encode( + char *output, + const char *hrp, + const uint8_t *data, + size_t data_len +); + +/** Decode a Bech32 string + * + * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be + * updated to contain the null-terminated human readable part. + * data: Pointer to a buffer of size strlen(input) - 8 that will + * hold the encoded 5-bit data values. + * data_len: Pointer to a size_t that will be updated to be the number + * of entries in data. + * In: input: Pointer to a null-terminated Bech32 string. + * Returns 1 if succesful. + */ +int bech32_decode( + char *hrp, + uint8_t *data, + size_t *data_len, + const char *input +); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/setup.py b/hardware-wallet/firmware/vendor/trezor-crypto/setup.py new file mode 100755 index 00000000..ea76ea7c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/setup.py @@ -0,0 +1,37 @@ +#!/usr/bin/python +from distutils.core import setup +from distutils.extension import Extension +from Cython.Build import cythonize +from Cython.Distutils import build_ext + +srcs = [ + 'nist256p1', + 'base58', + 'bignum', + 'bip32', + 'ecdsa', + 'curve25519', + 'hmac', + 'rand', + 'ripemd160', + 'secp256k1', + 'sha2', +] + +extensions = [ + Extension('TrezorCrypto', + sources = ['TrezorCrypto.pyx', 'c.pxd'] + [ x + '.c' for x in srcs ], + extra_compile_args = [], + ) +] + +setup( + name = 'TrezorCrypto', + version = '0.0.0', + description = 'Cython wrapper around trezor-crypto library', + author = 'Pavol Rusnak', + author_email = 'stick@satoshilabs.com', + url = 'https://github.com/trezor/trezor-crypto', + cmdclass = {'build_ext': build_ext}, + ext_modules = cythonize(extensions), +) diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/sha2.c b/hardware-wallet/firmware/vendor/trezor-crypto/sha2.c new file mode 100644 index 00000000..0d27f433 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/sha2.c @@ -0,0 +1,1319 @@ +/** + * Copyright (c) 2000-2001 Aaron D. Gifford + * Copyright (c) 2013-2014 Pavol Rusnak + * 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 contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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 "sha2.h" +#include "memzero.h" + +/* + * ASSERT NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including (which in turn includes + * where the appropriate definitions are actually + * made). + */ + +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA1_SHORT_BLOCK_LENGTH (SHA1_BLOCK_LENGTH - 8) +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: In the original SHA-256/384/512 document, the shift-right + * function was named R and the rotate-right function was called S. + * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the + * web.) + * + * The newer NIST FIPS 180-2 document uses a much clearer naming + * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for + * rotate-left. (See: + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + * on the web.) + * + * WARNING: These macros must be used cautiously, since they reference + * supplied parameters sometimes more than once, and thus could have + * unexpected side-effects if used without taking this into account. + */ + +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define SHR(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) +/* 32-bit Rotate-left (used in SHA-1): */ +#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b)))) + +/* Two of six logical functions used in SHA-1, SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Function used in SHA-1: */ +#define Parity(x,y,z) ((x) ^ (y) ^ (z)) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) +#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) +#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR(3 , (x))) +#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) +#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) +#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x))) +#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +static void sha512_Last(SHA512_CTX*); + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ + +/* Hash constant words K for SHA-1: */ +#define K1_0_TO_19 0x5a827999UL +#define K1_20_TO_39 0x6ed9eba1UL +#define K1_40_TO_59 0x8f1bbcdcUL +#define K1_60_TO_79 0xca62c1d6UL + +/* Initial hash value H for SHA-1: */ +const sha2_word32 sha1_initial_hash_value[SHA1_DIGEST_LENGTH / sizeof(sha2_word32)] = { + 0x67452301UL, + 0xefcdab89UL, + 0x98badcfeUL, + 0x10325476UL, + 0xc3d2e1f0UL +}; + +/* Hash constant words K for SHA-256: */ +static const sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +static const sha2_word64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-512 */ +const sha2_word64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + + +/*** SHA-1: ***********************************************************/ +void sha1_Init(SHA1_CTX* context) { + MEMCPY_BCOPY(context->state, sha1_initial_hash_value, SHA1_DIGEST_LENGTH); + memzero(context->buffer, SHA1_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-1 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND1_0_TO_15(a,b,c,d,e) \ + REVERSE32(*data++, W1[j]); \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + W1[j]; \ + (b) = ROTL32(30, (b)); \ + j++; + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND1_0_TO_15(a,b,c,d,e) \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + ( W1[j] = *data++ ); \ + (b) = ROTL32(30, (b)); \ + j++; + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND1_16_TO_19(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_20_TO_39(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_40_TO_59(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_60_TO_79(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { + sha2_word32 a, b, c, d, e; + sha2_word32 T1; + sha2_word32 W1[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + + j = 0; + + /* Rounds 0 to 15 unrolled: */ + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + + /* Rounds 16 to 19 unrolled: */ + ROUND1_16_TO_19(e,a,b,c,d); + ROUND1_16_TO_19(d,e,a,b,c); + ROUND1_16_TO_19(c,d,e,a,b); + ROUND1_16_TO_19(b,c,d,e,a); + + /* Rounds 20 to 39 unrolled: */ + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + + /* Rounds 40 to 59 unrolled: */ + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + + /* Rounds 60 to 79 unrolled: */ + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { + sha2_word32 a, b, c, d, e; + sha2_word32 T1; + sha2_word32 W1[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + T1 = data[j]; + /* Copy data while converting to host byte order */ + REVERSE32(*data++, W1[j]); + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + W1[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 16); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 20); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 40); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 60); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 80); + + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void sha1_Update(SHA1_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA1_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + sha1_Transform(context->state, context->buffer, context->state); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA1_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + sha1_Transform(context->state, (sha2_word32*)data, context->state); + context->bitcount += SHA1_BLOCK_LENGTH << 3; + len -= SHA1_BLOCK_LENGTH; + data += SHA1_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void sha1_Final(SHA1_CTX* context, sha2_byte digest[]) { + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + if (digest == (sha2_byte*)0) { + /* + * No digest buffer, so we can do nothing + * except clean up and go home + */ + memzero(context, sizeof(SHA1_CTX)); + return; + } + + usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; + if (usedspace == 0) { + /* Set-up for the last transform: */ + memzero(context->buffer, SHA1_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } else { + /* Begin padding with a 1 bit: */ + ((uint8_t*)context->buffer)[usedspace++] = 0x80; + + if (usedspace <= 56) { + /* Set-up for the last transform: */ + memzero(((uint8_t*)context->buffer) + usedspace, 56 - usedspace); + } else { + if (usedspace < 64) { + memzero(((uint8_t*)context->buffer) + usedspace, 64 - usedspace); + } + /* Do second-to-last transform: */ + sha1_Transform(context->state, context->buffer, context->state); + + /* And set-up for the last transform: */ + memzero(context->buffer, 56); + } + /* Clean up: */ + usedspace = 0; + } + /* Set the bit count: */ +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + context->buffer[SHA1_SHORT_BLOCK_LENGTH >> 2] = context->bitcount << 32; + context->buffer[SHA1_SHORT_BLOCK_LENGTH >> 2 | 1] = context->bitcount >> 32; + + /* Final transform: */ + sha1_Transform(context->state, context->buffer, context->state); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA1_DIGEST_LENGTH); +#endif + + /* Clean up: */ + memzero(context, sizeof(SHA1_CTX)); +} + +char *sha1_End(SHA1_CTX* context, char buffer[]) { + sha2_byte digest[SHA1_DIGEST_LENGTH], *d = digest; + int i; + + if (buffer != (char*)0) { + sha1_Final(context, digest); + + for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + memzero(context, sizeof(SHA1_CTX)); + } + memzero(digest, SHA1_DIGEST_LENGTH); + return buffer; +} + +void sha1_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA1_DIGEST_LENGTH]) { + SHA1_CTX context; + sha1_Init(&context); + sha1_Update(&context, data, len); + sha1_Final(&context, digest); +} + +char* sha1_Data(const sha2_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) { + SHA1_CTX context; + + sha1_Init(&context); + sha1_Update(&context, data, len); + return sha1_End(&context, digest); +} + +/*** SHA-256: *********************************************************/ +void sha256_Init(SHA256_CTX* context) { + if (context == (SHA256_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + memzero(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + W256[j] = *data++; \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1; + sha2_word32 W256[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, W256[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void sha256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j],context->buffer[j]); + } +#endif + sha256_Transform(context->state, context->buffer, context->state); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j],context->buffer[j]); + } +#endif + sha256_Transform(context->state, context->buffer, context->state); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void sha256_Final(SHA256_CTX* context, sha2_byte digest[]) { + unsigned int usedspace; + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + /* Begin padding with a 1 bit: */ + ((uint8_t*)context->buffer)[usedspace++] = 0x80; + + if (usedspace > SHA256_SHORT_BLOCK_LENGTH) { + memzero(((uint8_t*)context->buffer) + usedspace, SHA256_BLOCK_LENGTH - usedspace); + +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j],context->buffer[j]); + } +#endif + /* Do second-to-last transform: */ + sha256_Transform(context->state, context->buffer, context->state); + + /* And prepare the last transform: */ + usedspace = 0; + } + /* Set-up for the last transform: */ + memzero(((uint8_t*)context->buffer) + usedspace, SHA256_SHORT_BLOCK_LENGTH - usedspace); + +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 14; j++) { + REVERSE32(context->buffer[j],context->buffer[j]); + } +#endif + /* Set the bit count: */ + context->buffer[14] = context->bitcount >> 32; + context->buffer[15] = context->bitcount & 0xffffffff; + + /* Final transform: */ + sha256_Transform(context->state, context->buffer, context->state); + +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + for (int j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + } +#endif + MEMCPY_BCOPY(digest, context->state, SHA256_DIGEST_LENGTH); + } + + /* Clean up state data: */ + memzero(context, sizeof(SHA256_CTX)); + usedspace = 0; +} + +char *sha256_End(SHA256_CTX* context, char buffer[]) { + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + if (buffer != (char*)0) { + sha256_Final(context, digest); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + memzero(context, sizeof(SHA256_CTX)); + } + memzero(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +void sha256_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH]) { + SHA256_CTX context; + sha256_Init(&context); + sha256_Update(&context, data, len); + sha256_Final(&context, digest); +} + +char* sha256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA256_CTX context; + + sha256_Init(&context); + sha256_Update(&context, data, len); + return sha256_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void sha512_Init(SHA512_CTX* context) { + if (context == (SHA512_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + memzero(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, W512[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, W512[16]; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 16; j++) { + REVERSE64(context->buffer[j],context->buffer[j]); + } +#endif + sha512_Transform(context->state, context->buffer, context->state); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 16; j++) { + REVERSE64(context->buffer[j],context->buffer[j]); + } +#endif + sha512_Transform(context->state, context->buffer, context->state); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +static void sha512_Last(SHA512_CTX* context) { + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + /* Begin padding with a 1 bit: */ + ((uint8_t*)context->buffer)[usedspace++] = 0x80; + + if (usedspace > SHA512_SHORT_BLOCK_LENGTH) { + memzero(((uint8_t*)context->buffer) + usedspace, SHA512_BLOCK_LENGTH - usedspace); + +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 16; j++) { + REVERSE64(context->buffer[j],context->buffer[j]); + } +#endif + /* Do second-to-last transform: */ + sha512_Transform(context->state, context->buffer, context->state); + + /* And prepare the last transform: */ + usedspace = 0; + } + /* Set-up for the last transform: */ + memzero(((uint8_t*)context->buffer) + usedspace, SHA512_SHORT_BLOCK_LENGTH - usedspace); + +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + for (int j = 0; j < 14; j++) { + REVERSE64(context->buffer[j],context->buffer[j]); + } +#endif + /* Store the length of input data (in bits): */ + context->buffer[14] = context->bitcount[1]; + context->buffer[15] = context->bitcount[0]; + + /* Final transform: */ + sha512_Transform(context->state, context->buffer, context->state); +} + +void sha512_Final(SHA512_CTX* context, sha2_byte digest[]) { + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + sha512_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + for (int j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + } +#endif + MEMCPY_BCOPY(digest, context->state, SHA512_DIGEST_LENGTH); + } + + /* Zero out state data */ + memzero(context, sizeof(SHA512_CTX)); +} + +char *sha512_End(SHA512_CTX* context, char buffer[]) { + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + if (buffer != (char*)0) { + sha512_Final(context, digest); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + memzero(context, sizeof(SHA512_CTX)); + } + memzero(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +void sha512_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA512_DIGEST_LENGTH]) { + SHA512_CTX context; + sha512_Init(&context); + sha512_Update(&context, data, len); + sha512_Final(&context, digest); +} + +char* sha512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA512_CTX context; + + sha512_Init(&context); + sha512_Update(&context, data, len); + return sha512_End(&context, digest); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/sha2.h b/hardware-wallet/firmware/vendor/trezor-crypto/sha2.h new file mode 100644 index 00000000..7f519c50 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/sha2.h @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2000-2001 Aaron D. Gifford + * Copyright (c) 2013-2014 Pavol Rusnak + * 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 contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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 __SHA2_H__ +#define __SHA2_H__ + +#include +#include + +#define SHA1_BLOCK_LENGTH 64 +#define SHA1_DIGEST_LENGTH 20 +#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + +typedef struct _SHA1_CTX { + uint32_t state[5]; + uint64_t bitcount; + uint32_t buffer[SHA1_BLOCK_LENGTH/sizeof(uint32_t)]; +} SHA1_CTX; +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint32_t buffer[SHA256_BLOCK_LENGTH/sizeof(uint32_t)]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint64_t buffer[SHA512_BLOCK_LENGTH/sizeof(uint64_t)]; +} SHA512_CTX; + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#define BIG_ENDIAN 4321 +#endif + +#ifndef BYTE_ORDER +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + uint32_t tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + uint64_t tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +extern const uint32_t sha256_initial_hash_value[8]; +extern const uint64_t sha512_initial_hash_value[8]; + +void sha1_Transform(const uint32_t* state_in, const uint32_t* data, uint32_t* state_out); +void sha1_Init(SHA1_CTX *); +void sha1_Update(SHA1_CTX*, const uint8_t*, size_t); +void sha1_Final(SHA1_CTX*, uint8_t[SHA1_DIGEST_LENGTH]); +char* sha1_End(SHA1_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); +void sha1_Raw(const uint8_t*, size_t, uint8_t[SHA1_DIGEST_LENGTH]); +char* sha1_Data(const uint8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); + +void sha256_Transform(const uint32_t* state_in, const uint32_t* data, uint32_t* state_out); +void sha256_Init(SHA256_CTX *); +void sha256_Update(SHA256_CTX*, const uint8_t*, size_t); +void sha256_Final(SHA256_CTX*, uint8_t[SHA256_DIGEST_LENGTH]); +char* sha256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +void sha256_Raw(const uint8_t*, size_t, uint8_t[SHA256_DIGEST_LENGTH]); +char* sha256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void sha512_Transform(const uint64_t* state_in, const uint64_t* data, uint64_t* state_out); +void sha512_Init(SHA512_CTX*); +void sha512_Update(SHA512_CTX*, const uint8_t*, size_t); +void sha512_Final(SHA512_CTX*, uint8_t[SHA512_DIGEST_LENGTH]); +char* sha512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +void sha512_Raw(const uint8_t*, size_t, uint8_t[SHA512_DIGEST_LENGTH]); +char* sha512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/sha3.c b/hardware-wallet/firmware/vendor/trezor-crypto/sha3.c new file mode 100644 index 00000000..3ef9db8a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/sha3.c @@ -0,0 +1,397 @@ +/* sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak). + * based on the + * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 + * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche + * + * Copyright: 2013 Aleksey Kravchenko + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so. + * + * 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. Use this program at your own risk! + */ + +#include +#include + +#include "sha3.h" +#include "memzero.h" + +#define I64(x) x##LL +#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) +#define le2me_64(x) (x) +#define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0))) +# define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) + +/* constants */ +#define NumberOfRounds 24 + +/* SHA3 (Keccak) constants for 24 rounds */ +static uint64_t keccak_round_constants[NumberOfRounds] = { + I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000), + I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009), + I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A), + I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003), + I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A), + I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008) +}; + +/* Initializing a sha3 context for given number of output bits */ +static void keccak_Init(SHA3_CTX *ctx, unsigned bits) +{ + /* NB: The Keccak capacity parameter = bits * 2 */ + unsigned rate = 1600 - bits * 2; + + memset(ctx, 0, sizeof(SHA3_CTX)); + ctx->block_size = rate / 8; + assert(rate <= 1600 && (rate % 64) == 0); +} + +/** + * Initialize context before calculating hash. + * + * @param ctx context to initialize + */ +void sha3_224_Init(SHA3_CTX *ctx) +{ + keccak_Init(ctx, 224); +} + +/** + * Initialize context before calculating hash. + * + * @param ctx context to initialize + */ +void sha3_256_Init(SHA3_CTX *ctx) +{ + keccak_Init(ctx, 256); +} + +/** + * Initialize context before calculating hash. + * + * @param ctx context to initialize + */ +void sha3_384_Init(SHA3_CTX *ctx) +{ + keccak_Init(ctx, 384); +} + +/** + * Initialize context before calculating hash. + * + * @param ctx context to initialize + */ +void sha3_512_Init(SHA3_CTX *ctx) +{ + keccak_Init(ctx, 512); +} + +/* Keccak theta() transformation */ +static void keccak_theta(uint64_t *A) +{ + unsigned int x; + uint64_t C[5], D[5]; + + for (x = 0; x < 5; x++) { + C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20]; + } + D[0] = ROTL64(C[1], 1) ^ C[4]; + D[1] = ROTL64(C[2], 1) ^ C[0]; + D[2] = ROTL64(C[3], 1) ^ C[1]; + D[3] = ROTL64(C[4], 1) ^ C[2]; + D[4] = ROTL64(C[0], 1) ^ C[3]; + + for (x = 0; x < 5; x++) { + A[x] ^= D[x]; + A[x + 5] ^= D[x]; + A[x + 10] ^= D[x]; + A[x + 15] ^= D[x]; + A[x + 20] ^= D[x]; + } +} + +/* Keccak pi() transformation */ +static void keccak_pi(uint64_t *A) +{ + uint64_t A1; + A1 = A[1]; + A[ 1] = A[ 6]; + A[ 6] = A[ 9]; + A[ 9] = A[22]; + A[22] = A[14]; + A[14] = A[20]; + A[20] = A[ 2]; + A[ 2] = A[12]; + A[12] = A[13]; + A[13] = A[19]; + A[19] = A[23]; + A[23] = A[15]; + A[15] = A[ 4]; + A[ 4] = A[24]; + A[24] = A[21]; + A[21] = A[ 8]; + A[ 8] = A[16]; + A[16] = A[ 5]; + A[ 5] = A[ 3]; + A[ 3] = A[18]; + A[18] = A[17]; + A[17] = A[11]; + A[11] = A[ 7]; + A[ 7] = A[10]; + A[10] = A1; + /* note: A[ 0] is left as is */ +} + +/* Keccak chi() transformation */ +static void keccak_chi(uint64_t *A) +{ + int i; + for (i = 0; i < 25; i += 5) { + uint64_t A0 = A[0 + i], A1 = A[1 + i]; + A[0 + i] ^= ~A1 & A[2 + i]; + A[1 + i] ^= ~A[2 + i] & A[3 + i]; + A[2 + i] ^= ~A[3 + i] & A[4 + i]; + A[3 + i] ^= ~A[4 + i] & A0; + A[4 + i] ^= ~A0 & A1; + } +} + +static void sha3_permutation(uint64_t *state) +{ + int round; + for (round = 0; round < NumberOfRounds; round++) + { + keccak_theta(state); + + /* apply Keccak rho() transformation */ + state[ 1] = ROTL64(state[ 1], 1); + state[ 2] = ROTL64(state[ 2], 62); + state[ 3] = ROTL64(state[ 3], 28); + state[ 4] = ROTL64(state[ 4], 27); + state[ 5] = ROTL64(state[ 5], 36); + state[ 6] = ROTL64(state[ 6], 44); + state[ 7] = ROTL64(state[ 7], 6); + state[ 8] = ROTL64(state[ 8], 55); + state[ 9] = ROTL64(state[ 9], 20); + state[10] = ROTL64(state[10], 3); + state[11] = ROTL64(state[11], 10); + state[12] = ROTL64(state[12], 43); + state[13] = ROTL64(state[13], 25); + state[14] = ROTL64(state[14], 39); + state[15] = ROTL64(state[15], 41); + state[16] = ROTL64(state[16], 45); + state[17] = ROTL64(state[17], 15); + state[18] = ROTL64(state[18], 21); + state[19] = ROTL64(state[19], 8); + state[20] = ROTL64(state[20], 18); + state[21] = ROTL64(state[21], 2); + state[22] = ROTL64(state[22], 61); + state[23] = ROTL64(state[23], 56); + state[24] = ROTL64(state[24], 14); + + keccak_pi(state); + keccak_chi(state); + + /* apply iota(state, round) */ + *state ^= keccak_round_constants[round]; + } +} + +/** + * The core transformation. Process the specified block of data. + * + * @param hash the algorithm state + * @param block the message block to process + * @param block_size the size of the processed block in bytes + */ +static void sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size) +{ + /* expanded loop */ + hash[ 0] ^= le2me_64(block[ 0]); + hash[ 1] ^= le2me_64(block[ 1]); + hash[ 2] ^= le2me_64(block[ 2]); + hash[ 3] ^= le2me_64(block[ 3]); + hash[ 4] ^= le2me_64(block[ 4]); + hash[ 5] ^= le2me_64(block[ 5]); + hash[ 6] ^= le2me_64(block[ 6]); + hash[ 7] ^= le2me_64(block[ 7]); + hash[ 8] ^= le2me_64(block[ 8]); + /* if not sha3-512 */ + if (block_size > 72) { + hash[ 9] ^= le2me_64(block[ 9]); + hash[10] ^= le2me_64(block[10]); + hash[11] ^= le2me_64(block[11]); + hash[12] ^= le2me_64(block[12]); + /* if not sha3-384 */ + if (block_size > 104) { + hash[13] ^= le2me_64(block[13]); + hash[14] ^= le2me_64(block[14]); + hash[15] ^= le2me_64(block[15]); + hash[16] ^= le2me_64(block[16]); + /* if not sha3-256 */ + if (block_size > 136) { + hash[17] ^= le2me_64(block[17]); +#ifdef FULL_SHA3_FAMILY_SUPPORT + /* if not sha3-224 */ + if (block_size > 144) { + hash[18] ^= le2me_64(block[18]); + hash[19] ^= le2me_64(block[19]); + hash[20] ^= le2me_64(block[20]); + hash[21] ^= le2me_64(block[21]); + hash[22] ^= le2me_64(block[22]); + hash[23] ^= le2me_64(block[23]); + hash[24] ^= le2me_64(block[24]); + } +#endif + } + } + } + /* make a permutation of the hash */ + sha3_permutation(hash); +} + +#define SHA3_FINALIZED 0x80000000 + +/** + * Calculate message hash. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param ctx the algorithm context containing current hashing state + * @param msg message chunk + * @param size length of the message chunk + */ +void sha3_Update(SHA3_CTX *ctx, const unsigned char *msg, size_t size) +{ + size_t idx = (size_t)ctx->rest; + size_t block_size = (size_t)ctx->block_size; + + if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */ + ctx->rest = (unsigned)((ctx->rest + size) % block_size); + + /* fill partial block */ + if (idx) { + size_t left = block_size - idx; + memcpy((char*)ctx->message + idx, msg, (size < left ? size : left)); + if (size < left) return; + + /* process partial block */ + sha3_process_block(ctx->hash, ctx->message, block_size); + msg += left; + size -= left; + } + while (size >= block_size) { + uint64_t* aligned_message_block; + if (IS_ALIGNED_64(msg)) { + /* the most common case is processing of an already aligned message + without copying it */ + aligned_message_block = (uint64_t*)(void*)msg; + } else { + memcpy(ctx->message, msg, block_size); + aligned_message_block = ctx->message; + } + + sha3_process_block(ctx->hash, aligned_message_block, block_size); + msg += block_size; + size -= block_size; + } + if (size) { + memcpy(ctx->message, msg, size); /* save leftovers */ + } +} + +/** + * Store calculated hash into the given array. + * + * @param ctx the algorithm context containing current hashing state + * @param result calculated hash in binary form + */ +void sha3_Final(SHA3_CTX *ctx, unsigned char* result) +{ + size_t digest_length = 100 - ctx->block_size / 2; + const size_t block_size = ctx->block_size; + + if (!(ctx->rest & SHA3_FINALIZED)) + { + /* clear the rest of the data queue */ + memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest); + ((char*)ctx->message)[ctx->rest] |= 0x06; + ((char*)ctx->message)[block_size - 1] |= 0x80; + + /* process final block */ + sha3_process_block(ctx->hash, ctx->message, block_size); + ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ + } + + assert(block_size > digest_length); + if (result) me64_to_le_str(result, ctx->hash, digest_length); + memzero(ctx, sizeof(SHA3_CTX)); +} + +#if USE_KECCAK +/** +* Store calculated hash into the given array. +* +* @param ctx the algorithm context containing current hashing state +* @param result calculated hash in binary form +*/ +void keccak_Final(SHA3_CTX *ctx, unsigned char* result) +{ + size_t digest_length = 100 - ctx->block_size / 2; + const size_t block_size = ctx->block_size; + + if (!(ctx->rest & SHA3_FINALIZED)) + { + /* clear the rest of the data queue */ + memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest); + ((char*)ctx->message)[ctx->rest] |= 0x01; + ((char*)ctx->message)[block_size - 1] |= 0x80; + + /* process final block */ + sha3_process_block(ctx->hash, ctx->message, block_size); + ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ + } + + assert(block_size > digest_length); + if (result) me64_to_le_str(result, ctx->hash, digest_length); + memzero(ctx, sizeof(SHA3_CTX)); +} + +void keccak_256(const unsigned char* data, size_t len, unsigned char* digest) +{ + SHA3_CTX ctx; + keccak_256_Init(&ctx); + keccak_Update(&ctx, data, len); + keccak_Final(&ctx, digest); +} + +void keccak_512(const unsigned char* data, size_t len, unsigned char* digest) +{ + SHA3_CTX ctx; + keccak_512_Init(&ctx); + keccak_Update(&ctx, data, len); + keccak_Final(&ctx, digest); +} +#endif /* USE_KECCAK */ + +void sha3_256(const unsigned char* data, size_t len, unsigned char* digest) +{ + SHA3_CTX ctx; + sha3_256_Init(&ctx); + sha3_Update(&ctx, data, len); + sha3_Final(&ctx, digest); +} + +void sha3_512(const unsigned char* data, size_t len, unsigned char* digest) +{ + SHA3_CTX ctx; + sha3_512_Init(&ctx); + sha3_Update(&ctx, data, len); + sha3_Final(&ctx, digest); +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/sha3.h b/hardware-wallet/firmware/vendor/trezor-crypto/sha3.h new file mode 100644 index 00000000..367369d4 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/sha3.h @@ -0,0 +1,89 @@ +/* sha3.h - an implementation of Secure Hash Algorithm 3 (Keccak). + * based on the + * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 + * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche + * + * Copyright: 2013 Aleksey Kravchenko + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so. + * + * 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. Use this program at your own risk! + */ + +#ifndef __SHA3_H__ +#define __SHA3_H__ + +#include +#include "options.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define sha3_224_hash_size 28 +#define sha3_256_hash_size 32 +#define sha3_384_hash_size 48 +#define sha3_512_hash_size 64 +#define sha3_max_permutation_size 25 +#define sha3_max_rate_in_qwords 24 + +#define SHA3_224_BLOCK_LENGTH 144 +#define SHA3_256_BLOCK_LENGTH 136 +#define SHA3_384_BLOCK_LENGTH 104 +#define SHA3_512_BLOCK_LENGTH 72 + +#define SHA3_224_DIGEST_LENGTH sha3_224_hash_size +#define SHA3_256_DIGEST_LENGTH sha3_256_hash_size +#define SHA3_384_DIGEST_LENGTH sha3_384_hash_size +#define SHA3_512_DIGEST_LENGTH sha3_512_hash_size + +/** + * SHA3 Algorithm context. + */ +typedef struct SHA3_CTX +{ + /* 1600 bits algorithm hashing state */ + uint64_t hash[sha3_max_permutation_size]; + /* 1536-bit buffer for leftovers */ + uint64_t message[sha3_max_rate_in_qwords]; + /* count of bytes in the message[] buffer */ + unsigned rest; + /* size of a message block processed at once */ + unsigned block_size; +} SHA3_CTX; + +/* methods for calculating the hash function */ + +void sha3_224_Init(SHA3_CTX *ctx); +void sha3_256_Init(SHA3_CTX *ctx); +void sha3_384_Init(SHA3_CTX *ctx); +void sha3_512_Init(SHA3_CTX *ctx); +void sha3_Update(SHA3_CTX *ctx, const unsigned char* msg, size_t size); +void sha3_Final(SHA3_CTX *ctx, unsigned char* result); + +#if USE_KECCAK +#define keccak_224_Init sha3_224_Init +#define keccak_256_Init sha3_256_Init +#define keccak_384_Init sha3_384_Init +#define keccak_512_Init sha3_512_Init +#define keccak_Update sha3_Update +void keccak_Final(SHA3_CTX *ctx, unsigned char* result); +void keccak_256(const unsigned char* data, size_t len, unsigned char* digest); +void keccak_512(const unsigned char* data, size_t len, unsigned char* digest); +#endif + +void sha3_256(const unsigned char* data, size_t len, unsigned char* digest); +void sha3_512(const unsigned char* data, size_t len, unsigned char* digest); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __SHA3_H__ */ diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/test_check.c b/hardware-wallet/firmware/vendor/trezor-crypto/test_check.c new file mode 100644 index 00000000..918cd054 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/test_check.c @@ -0,0 +1,4633 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "check_mem.h" + +#include +#include + +#include "options.h" + +#include "aes/aes.h" +#include "bignum.h" +#include "base32.h" +#include "base58.h" +#include "bip32.h" +#include "bip39.h" +#include "ecdsa.h" +#include "pbkdf2.h" +#include "rand.h" +#include "sha2.h" +#include "sha3.h" +#include "blake256.h" +#include "blake2b.h" +#include "blake2s.h" +#include "curves.h" +#include "secp256k1.h" +#include "nist256p1.h" +#include "ed25519-donna/ed25519.h" +#include "ed25519-donna/ed25519-keccak.h" +#include "script.h" +#include "rfc6979.h" +#include "address.h" +#include "rc4.h" +#include "nem.h" + +/* + * This is a clever trick to make Valgrind's Memcheck verify code + * is constant-time with respect to secret data. + */ + +/* Call after secret data is written, before first use */ +#define MARK_SECRET_DATA(addr, len) VALGRIND_MAKE_MEM_UNDEFINED(addr, len) +/* Call before secret data is freed or to mark non-secret data (public keys or signatures) */ +#define UNMARK_SECRET_DATA(addr, len) VALGRIND_MAKE_MEM_DEFINED (addr, len) + +#define FROMHEX_MAXLEN 512 + +#define VERSION_PUBLIC 0x0488b21e +#define VERSION_PRIVATE 0x0488ade4 + +#define DECRED_VERSION_PUBLIC 0x02fda926 +#define DECRED_VERSION_PRIVATE 0x02fda4e8 + +const uint8_t *fromhex(const char *str) +{ + static uint8_t buf[FROMHEX_MAXLEN]; + size_t len = strlen(str) / 2; + if (len > FROMHEX_MAXLEN) len = FROMHEX_MAXLEN; + for (size_t i = 0; i < len; i++) { + uint8_t c = 0; + if (str[i * 2] >= '0' && str[i*2] <= '9') c += (str[i * 2] - '0') << 4; + if ((str[i * 2] & ~0x20) >= 'A' && (str[i*2] & ~0x20) <= 'F') c += (10 + (str[i * 2] & ~0x20) - 'A') << 4; + if (str[i * 2 + 1] >= '0' && str[i * 2 + 1] <= '9') c += (str[i * 2 + 1] - '0'); + if ((str[i * 2 + 1] & ~0x20) >= 'A' && (str[i * 2 + 1] & ~0x20) <= 'F') c += (10 + (str[i * 2 + 1] & ~0x20) - 'A'); + buf[i] = c; + } + return buf; +} + +void nem_private_key(const char *reversed_hex, ed25519_secret_key private_key) { + const uint8_t *reversed_key = fromhex(reversed_hex); + for (size_t j = 0; j < sizeof(ed25519_secret_key); j++) { + private_key[j] = reversed_key[sizeof(ed25519_secret_key) - j - 1]; + } +} + +START_TEST(test_bignum_read_be) +{ + bignum256 a; + uint8_t input[32]; + + memcpy(input, fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), 32); + + bn_read_be(input, &a); + + bignum256 b = { { 0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3, 0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e } }; + + for (int i = 0; i < 9; i++) { + ck_assert_int_eq(a.val[i], b.val[i]); + } +} +END_TEST + +START_TEST(test_bignum_write_be) +{ + bignum256 a = { { 0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3, 0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e } }; + uint8_t tmp[32]; + + bn_write_be(&a, tmp); + + ck_assert_mem_eq(tmp, fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), 32); +} +END_TEST + +START_TEST(test_bignum_is_equal) +{ + bignum256 a = { { 0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3, 0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e } }; + bignum256 b = { { 0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3, 0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e } }; + bignum256 c = { { 0, } }; + + ck_assert_int_eq(bn_is_equal(&a, &b), 1); + ck_assert_int_eq(bn_is_equal(&c, &c), 1); + ck_assert_int_eq(bn_is_equal(&a, &c), 0); +} +END_TEST + +START_TEST(test_bignum_zero) +{ + bignum256 a; + bignum256 b; + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + bn_zero(&b); + + ck_assert_int_eq(bn_is_equal(&a, &b), 1); +} +END_TEST + +START_TEST(test_bignum_is_zero) +{ + bignum256 a; + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + ck_assert_int_eq(bn_is_zero(&a), 1); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000001"), &a); + ck_assert_int_eq(bn_is_zero(&a), 0); + + bn_read_be(fromhex("1000000000000000000000000000000000000000000000000000000000000000"), &a); + ck_assert_int_eq(bn_is_zero(&a), 0); + + bn_read_be(fromhex("f000000000000000000000000000000000000000000000000000000000000000"), &a); + ck_assert_int_eq(bn_is_zero(&a), 0); +} +END_TEST + +START_TEST(test_bignum_one) +{ + bignum256 a; + bignum256 b; + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000001"), &a); + bn_one(&b); + + ck_assert_int_eq(bn_is_equal(&a, &b), 1); +} +END_TEST + +START_TEST(test_bignum_read_le) +{ + bignum256 a; + bignum256 b; + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), &a); + bn_read_le(fromhex("d58b6de8051f031eeca2c6d7fbe1b5d37c4314fe1068f96352dd0d8b85ce5ec5"), &b); + + ck_assert_int_eq(bn_is_equal(&a, &b), 1); +} +END_TEST + +START_TEST(test_bignum_write_le) +{ + bignum256 a; + bignum256 b; + uint8_t tmp[32]; + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), &a); + bn_write_le(&a, tmp); + + bn_read_le(tmp, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); + + bn_read_be(fromhex("d58b6de8051f031eeca2c6d7fbe1b5d37c4314fe1068f96352dd0d8b85ce5ec5"), &a); + bn_read_be(tmp, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); +} +END_TEST + +START_TEST(test_bignum_read_uint32) +{ + bignum256 a; + bignum256 b; + + // lowest 30 bits set + bn_read_be(fromhex("000000000000000000000000000000000000000000000000000000003fffffff"), &a); + bn_read_uint32(0x3fffffff, &b); + + ck_assert_int_eq(bn_is_equal(&a, &b), 1); + + // bit 31 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000040000000"), &a); + bn_read_uint32(0x40000000, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); +} +END_TEST + +START_TEST(test_bignum_read_uint64) +{ + bignum256 a; + bignum256 b; + + // lowest 30 bits set + bn_read_be(fromhex("000000000000000000000000000000000000000000000000000000003fffffff"), &a); + bn_read_uint64(0x3fffffff, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); + + // bit 31 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000040000000"), &a); + bn_read_uint64(0x40000000, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); + + // bit 33 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000100000000"), &a); + bn_read_uint64(0x100000000LL, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); + + // bit 61 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000002000000000000000"), &a); + bn_read_uint64(0x2000000000000000LL, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); + + // all 64 bits set + bn_read_be(fromhex("000000000000000000000000000000000000000000000000ffffffffffffffff"), &a); + bn_read_uint64(0xffffffffffffffffLL, &b); + ck_assert_int_eq(bn_is_equal(&a, &b), 1); +} +END_TEST + +START_TEST(test_bignum_write_uint32) +{ + bignum256 a; + + // lowest 30 bits set + bn_read_be(fromhex("000000000000000000000000000000000000000000000000000000003fffffff"), &a); + ck_assert_int_eq(bn_write_uint32(&a), 0x3fffffff); + + // bit 31 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000040000000"), &a); + ck_assert_int_eq(bn_write_uint32(&a), 0x40000000); +} +END_TEST + +START_TEST(test_bignum_write_uint64) +{ + bignum256 a; + + // lowest 30 bits set + bn_read_be(fromhex("000000000000000000000000000000000000000000000000000000003fffffff"), &a); + ck_assert_int_eq(bn_write_uint64(&a), 0x3fffffff); + + // bit 31 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000040000000"), &a); + ck_assert_int_eq(bn_write_uint64(&a), 0x40000000); + + // bit 33 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000100000000"), &a); + ck_assert_int_eq(bn_write_uint64(&a), 0x100000000LL); + + // bit 61 set + bn_read_be(fromhex("0000000000000000000000000000000000000000000000002000000000000000"), &a); + ck_assert_int_eq(bn_write_uint64(&a), 0x2000000000000000LL); + + // all 64 bits set + bn_read_be(fromhex("000000000000000000000000000000000000000000000000ffffffffffffffff"), &a); + ck_assert_int_eq(bn_write_uint64(&a), 0xffffffffffffffffLL); +} +END_TEST + +START_TEST(test_bignum_copy) +{ + bignum256 a; + bignum256 b; + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), &a); + bn_copy(&a, &b); + + ck_assert_int_eq(bn_is_equal(&a, &b), 1); +} +END_TEST + +START_TEST(test_bignum_is_even) +{ + bignum256 a; + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), &a); + ck_assert_int_eq(bn_is_even(&a), 0); + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd2"), &a); + ck_assert_int_eq(bn_is_even(&a), 1); + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd0"), &a); + ck_assert_int_eq(bn_is_even(&a), 1); +} +END_TEST + +START_TEST(test_bignum_is_odd) +{ + bignum256 a; + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), &a); + ck_assert_int_eq(bn_is_odd(&a), 1); + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd2"), &a); + ck_assert_int_eq(bn_is_odd(&a), 0); + + bn_read_be(fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd0"), &a); + ck_assert_int_eq(bn_is_odd(&a), 0); +} +END_TEST + +START_TEST(test_bignum_is_less) +{ + bignum256 a; + bignum256 b; + + bn_read_uint32(0x1234, &a); + bn_read_uint32(0x8765, &b); + + ck_assert_int_eq(bn_is_less(&a, &b), 1); + ck_assert_int_eq(bn_is_less(&b, &a), 0); + + bn_zero(&a); + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &b); + + ck_assert_int_eq(bn_is_less(&a, &b), 1); + ck_assert_int_eq(bn_is_less(&b, &a), 0); +} +END_TEST + +START_TEST(test_bignum_bitcount) +{ + bignum256 a, b; + + bn_zero(&a); + ck_assert_int_eq(bn_bitcount(&a), 0); + + bn_one(&a); + ck_assert_int_eq(bn_bitcount(&a), 1); + + // test for 10000 and 11111 when i=5 + for (int i = 2; i <= 256; i++) { + bn_one(&a); + bn_one(&b); + for (int j = 2; j <= i; j++) { + bn_lshift(&a); + bn_lshift(&b); + bn_addi(&b, 1); + } + ck_assert_int_eq(bn_bitcount(&a), i); + ck_assert_int_eq(bn_bitcount(&b), i); + } + + bn_read_uint32(0x3fffffff, &a); + ck_assert_int_eq(bn_bitcount(&a), 30); + + bn_read_uint32(0xffffffff, &a); + ck_assert_int_eq(bn_bitcount(&a), 32); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + ck_assert_int_eq(bn_bitcount(&a), 256); +} +END_TEST + +START_TEST(test_bignum_digitcount) +{ + bignum256 a; + + bn_zero(&a); + ck_assert_int_eq(bn_digitcount(&a), 1); + + // test for (10^i) and (10^i) - 1 + uint64_t m = 1; + for (int i = 0; i <= 19; i++, m *= 10) { + bn_read_uint64(m, &a); + ck_assert_int_eq(bn_digitcount(&a), i + 1); + + uint64_t n = m - 1; + bn_read_uint64(n, &a); + ck_assert_int_eq(bn_digitcount(&a), n == 0 ? 1 : i); + } + + bn_read_uint32(0x3fffffff, &a); + ck_assert_int_eq(bn_digitcount(&a), 10); + + bn_read_uint32(0xffffffff, &a); + ck_assert_int_eq(bn_digitcount(&a), 10); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + ck_assert_int_eq(bn_digitcount(&a), 78); +} +END_TEST + +START_TEST(test_bignum_format_uint64) { + char buf[128], str[128]; + int r; + // test for (10^i) and (10^i) - 1 + uint64_t m = 1; + for (int i = 0; i <= 19; i++, m *= 10) { + sprintf(str, "%" PRIu64, m); + r = bn_format_uint64(m, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, strlen(str)); + ck_assert_str_eq(buf, str); + + uint64_t n = m - 1; + sprintf(str, "%" PRIu64, n); + r = bn_format_uint64(n, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, strlen(str)); + ck_assert_str_eq(buf, str); + } +} +END_TEST + +START_TEST(test_bignum_format) { + bignum256 a; + char buf[128]; + int r; + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "0"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, NULL, NULL, 20, 0, true, buf, sizeof(buf)); + ck_assert_int_eq(r, 22); + ck_assert_str_eq(buf, "0.00000000000000000000"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, NULL, NULL, 0, 5, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "0"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, NULL, NULL, 0, -5, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "0"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, "", "", 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "0"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, NULL, "SFFX", 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1 + 4); + ck_assert_str_eq(buf, "0SFFX"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, "PRFX", NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 4 + 1); + ck_assert_str_eq(buf, "PRFX0"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, "PRFX", "SFFX", 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 4 + 1 + 4); + ck_assert_str_eq(buf, "PRFX0SFFX"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000000"), &a); + r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 3); + ck_assert_str_eq(buf, "0.0"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000001"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "1"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000001"), &a); + r = bn_format(&a, NULL, NULL, 6, 6, true, buf, sizeof(buf)); + ck_assert_int_eq(r, 8); + ck_assert_str_eq(buf, "1.000000"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000002"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "2"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000005"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "5"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000009"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 1); + ck_assert_str_eq(buf, "9"); + + bn_read_be(fromhex("000000000000000000000000000000000000000000000000000000000000000a"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 2); + ck_assert_str_eq(buf, "10"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000014"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 2); + ck_assert_str_eq(buf, "20"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000032"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 2); + ck_assert_str_eq(buf, "50"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000063"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 2); + ck_assert_str_eq(buf, "99"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000000064"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 3); + ck_assert_str_eq(buf, "100"); + + bn_read_be(fromhex("00000000000000000000000000000000000000000000000000000000000000c8"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 3); + ck_assert_str_eq(buf, "200"); + + bn_read_be(fromhex("00000000000000000000000000000000000000000000000000000000000001f4"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 3); + ck_assert_str_eq(buf, "500"); + + bn_read_be(fromhex("00000000000000000000000000000000000000000000000000000000000003e7"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 3); + ck_assert_str_eq(buf, "999"); + + bn_read_be(fromhex("00000000000000000000000000000000000000000000000000000000000003e8"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 4); + ck_assert_str_eq(buf, "1000"); + + bn_read_be(fromhex("0000000000000000000000000000000000000000000000000000000000989680"), &a); + r = bn_format(&a, NULL, NULL, 7, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 3); + ck_assert_str_eq(buf, "1.0"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 78); + ck_assert_str_eq(buf, "115792089237316195423570985008687907853269984665640564039457584007913129639935"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, NULL, NULL, 1, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 79); + ck_assert_str_eq(buf, "11579208923731619542357098500868790785326998466564056403945758400791312963993.5"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, NULL, NULL, 2, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 79); + ck_assert_str_eq(buf, "1157920892373161954235709850086879078532699846656405640394575840079131296399.35"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, NULL, NULL, 8, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 79); + ck_assert_str_eq(buf, "1157920892373161954235709850086879078532699846656405640394575840079131.29639935"); + + bn_read_be(fromhex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3bbb00"), &a); + r = bn_format(&a, NULL, NULL, 8, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 72); + ck_assert_str_eq(buf, "1157920892373161954235709850086879078532699846656405640394575840079131.0"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 79); + ck_assert_str_eq(buf, "115792089237316195423570985008687907853269984665640564039457.584007913129639935"); + + bn_read_be(fromhex("fffffffffffffffffffffffffffffffffffffffffffffffff7e52fe5afe40000"), &a); + r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 62); + ck_assert_str_eq(buf, "115792089237316195423570985008687907853269984665640564039457.0"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, NULL, NULL, 78, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 80); + ck_assert_str_eq(buf, "0.115792089237316195423570985008687907853269984665640564039457584007913129639935"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, NULL, NULL, 0, 10, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 88); + ck_assert_str_eq(buf, "1157920892373161954235709850086879078532699846656405640394575840079131296399350000000000"); + + bn_read_be(fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), &a); + r = bn_format(&a, "quite a long prefix", "even longer suffix", 60, 0, false, buf, sizeof(buf)); + ck_assert_int_eq(r, 116); + ck_assert_str_eq(buf, "quite a long prefix115792089237316195.423570985008687907853269984665640564039457584007913129639935even longer suffix"); +} +END_TEST + +// https://tools.ietf.org/html/rfc4648#section-10 +START_TEST(test_base32_rfc4648) +{ + static const struct { + const char *decoded; + const char *encoded; + const char *encoded_lowercase; + } tests[] = { + { "", "", ""}, + { "f", "MY", "my" }, + { "fo", "MZXQ", "mzxq" }, + { "foo", "MZXW6", "mzxw6" }, + { "foob", "MZXW6YQ", "mzxw6yq" }, + { "fooba", "MZXW6YTB", "mzxw6ytb" }, + { "foobar", "MZXW6YTBOI", "mzxw6ytboi" }, + }; + + char buffer[64]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + const char *in = tests[i].decoded; + const char *out = tests[i].encoded; + const char *out_lowercase = tests[i].encoded_lowercase; + + size_t inlen = strlen(in); + size_t outlen = strlen(out); + + ck_assert_int_eq(outlen, base32_encoded_length(inlen)); + ck_assert_int_eq(inlen, base32_decoded_length(outlen)); + + ck_assert(base32_encode((uint8_t *) in, inlen, buffer, sizeof(buffer), BASE32_ALPHABET_RFC4648) != NULL); + ck_assert_str_eq(buffer, out); + + char *ret = (char *) base32_decode(out, outlen, (uint8_t *) buffer, sizeof(buffer), BASE32_ALPHABET_RFC4648); + ck_assert(ret != NULL); + *ret = '\0'; + ck_assert_str_eq(buffer, in); + + ret = (char *) base32_decode(out_lowercase, outlen, (uint8_t *) buffer, sizeof(buffer), BASE32_ALPHABET_RFC4648); + ck_assert(ret != NULL); + *ret = '\0'; + ck_assert_str_eq(buffer, in); + } +} +END_TEST + +// from https://github.com/bitcoin/bitcoin/blob/master/src/test/data/base58_keys_valid.json +START_TEST(test_base58) +{ + static const char *base58_vector[] = { + "0065a16059864a2fdbc7c99a4723a8395bc6f188eb", "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", + "0574f209f6ea907e2ea48f74fae05782ae8a665257", "3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", + "6f53c0307d6851aa0ce7825ba883c6bd9ad242b486", "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", + "c46349a418fc4578d10a372b54b45c280cc8c4382f", "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", + "80eddbdc1168f1daeadbd3e44c1e3f8f5a284c2029f78ad26af98583a499de5b19", "5Kd3NBUAdUnhyzenEwVLy9pBKxSwXvE9FMPyR4UKZvpe6E3AgLr", + "8055c9bccb9ed68446d1b75273bbce89d7fe013a8acd1625514420fb2aca1a21c401", "Kz6UJmQACJmLtaQj5A3JAge4kVTNQ8gbvXuwbmCj7bsaabudb3RD", + "ef36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2", "9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko", + "efb9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f301", "cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH", + "006d23156cbbdcc82a5a47eee4c2c7c583c18b6bf4", "1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", + "05fcc5460dd6e2487c7d75b1963625da0e8f4c5975", "3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", + "6ff1d470f9b02370fdec2e6b708b08ac431bf7a5f7", "n3ZddxzLvAY9o7184TB4c6FJasAybsw4HZ", + "c4c579342c2c4c9220205e2cdc285617040c924a0a", "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", + "80a326b95ebae30164217d7a7f57d72ab2b54e3be64928a19da0210b9568d4015e", "5K494XZwps2bGyeL71pWid4noiSNA2cfCibrvRWqcHSptoFn7rc", + "807d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb401", "L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi", + "efd6bca256b5abc5602ec2e1c121a08b0da2556587430bcf7e1898af2224885203", "93DVKyFYwSN6wEo3E2fCrFPUp17FtrtNi2Lf7n4G3garFb16CRj", + "efa81ca4e8f90181ec4b61b6a7eb998af17b2cb04de8a03b504b9e34c4c61db7d901", "cTDVKtMGVYWTHCb1AFjmVbEbWjvKpKqKgMaR3QJxToMSQAhmCeTN", + "007987ccaa53d02c8873487ef919677cd3db7a6912", "1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", + "0563bcc565f9e68ee0189dd5cc67f1b0e5f02f45cb", "3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", + "6fef66444b5b17f14e8fae6e7e19b045a78c54fd79", "n3LnJXCqbPjghuVs8ph9CYsAe4Sh4j97wk", + "c4c3e55fceceaa4391ed2a9677f4a4d34eacd021a0", "2NB72XtkjpnATMggui83aEtPawyyKvnbX2o", + "80e75d936d56377f432f404aabb406601f892fd49da90eb6ac558a733c93b47252", "5KaBW9vNtWNhc3ZEDyNCiXLPdVPHCikRxSBWwV9NrpLLa4LsXi9", + "808248bd0375f2f75d7e274ae544fb920f51784480866b102384190b1addfbaa5c01", "L1axzbSyynNYA8mCAhzxkipKkfHtAXYF4YQnhSKcLV8YXA874fgT", + "ef44c4f6a096eac5238291a94cc24c01e3b19b8d8cef72874a079e00a242237a52", "927CnUkUbasYtDwYwVn2j8GdTuACNnKkjZ1rpZd2yBB1CLcnXpo", + "efd1de707020a9059d6d3abaf85e17967c6555151143db13dbb06db78df0f15c6901", "cUcfCMRjiQf85YMzzQEk9d1s5A4K7xL5SmBCLrezqXFuTVefyhY7", + "00adc1cc2081a27206fae25792f28bbc55b831549d", "1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", + "05188f91a931947eddd7432d6e614387e32b244709", "33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", + "6f1694f5bc1a7295b600f40018a618a6ea48eeb498", "mhaMcBxNh5cqXm4aTQ6EcVbKtfL6LGyK2H", + "c43b9b3fd7a50d4f08d1a5b0f62f644fa7115ae2f3", "2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN", + "80091035445ef105fa1bb125eccfb1882f3fe69592265956ade751fd095033d8d0", "5HtH6GdcwCJA4ggWEL1B3jzBBUB8HPiBi9SBc5h9i4Wk4PSeApR", + "80ab2b4bcdfc91d34dee0ae2a8c6b6668dadaeb3a88b9859743156f462325187af01", "L2xSYmMeVo3Zek3ZTsv9xUrXVAmrWxJ8Ua4cw8pkfbQhcEFhkXT8", + "efb4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856", "92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq", + "efe7b230133f1b5489843260236b06edca25f66adb1be455fbd38d4010d48faeef01", "cVM65tdYu1YK37tNoAyGoJTR13VBYFva1vg9FLuPAsJijGvG6NEA", + "00c4c1b72491ede1eedaca00618407ee0b772cad0d", "1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", + "05f6fe69bcb548a829cce4c57bf6fff8af3a5981f9", "3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", + "6f261f83568a098a8638844bd7aeca039d5f2352c0", "mizXiucXRCsEriQCHUkCqef9ph9qtPbZZ6", + "c4e930e1834a4d234702773951d627cce82fbb5d2e", "2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda", + "80d1fab7ab7385ad26872237f1eb9789aa25cc986bacc695e07ac571d6cdac8bc0", "5KQmDryMNDcisTzRp3zEq9e4awRmJrEVU1j5vFRTKpRNYPqYrMg", + "80b0bbede33ef254e8376aceb1510253fc3550efd0fcf84dcd0c9998b288f166b301", "L39Fy7AC2Hhj95gh3Yb2AU5YHh1mQSAHgpNixvm27poizcJyLtUi", + "ef037f4192c630f399d9271e26c575269b1d15be553ea1a7217f0cb8513cef41cb", "91cTVUcgydqyZLgaANpf1fvL55FH53QMm4BsnCADVNYuWuqdVys", + "ef6251e205e8ad508bab5596bee086ef16cd4b239e0cc0c5d7c4e6035441e7d5de01", "cQspfSzsgLeiJGB2u8vrAiWpCU4MxUT6JseWo2SjXy4Qbzn2fwDw", + "005eadaf9bb7121f0f192561a5a62f5e5f54210292", "19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", + "053f210e7277c899c3a155cc1c90f4106cbddeec6e", "37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", + "6fc8a3c2a09a298592c3e180f02487cd91ba3400b5", "myoqcgYiehufrsnnkqdqbp69dddVDMopJu", + "c499b31df7c9068d1481b596578ddbb4d3bd90baeb", "2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C", + "80c7666842503db6dc6ea061f092cfb9c388448629a6fe868d068c42a488b478ae", "5KL6zEaMtPRXZKo1bbMq7JDjjo1bJuQcsgL33je3oY8uSJCR5b4", + "8007f0803fc5399e773555ab1e8939907e9badacc17ca129e67a2f5f2ff84351dd01", "KwV9KAfwbwt51veZWNscRTeZs9CKpojyu1MsPnaKTF5kz69H1UN2", + "efea577acfb5d1d14d3b7b195c321566f12f87d2b77ea3a53f68df7ebf8604a801", "93N87D6uxSBzwXvpokpzg8FFmfQPmvX4xHoWQe3pLdYpbiwT5YV", + "ef0b3b34f0958d8a268193a9814da92c3e8b58b4a4378a542863e34ac289cd830c01", "cMxXusSihaX58wpJ3tNuuUcZEQGt6DKJ1wEpxys88FFaQCYjku9h", + "001ed467017f043e91ed4c44b4e8dd674db211c4e6", "13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", + "055ece0cadddc415b1980f001785947120acdb36fc", "3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", + 0, 0, + }; + const char **raw = base58_vector; + const char **str = base58_vector + 1; + uint8_t rawn[34]; + char strn[53]; + int r; + while (*raw && *str) { + int len = strlen(*raw) / 2; + + memcpy(rawn, fromhex(*raw), len); + r = base58_encode_check(rawn, len, HASHER_SHA2, strn, sizeof(strn)); + ck_assert_int_eq((size_t)r, strlen(*str) + 1); + ck_assert_str_eq(strn, *str); + + r = base58_decode_check(strn, HASHER_SHA2, rawn, len); + ck_assert_int_eq(r, len); + ck_assert_mem_eq(rawn, fromhex(*raw), len); + + raw += 2; str += 2; + } +} +END_TEST + +#if USE_GRAPHENE + +// Graphene Base85CheckEncoding +START_TEST(test_base58gph) +{ + static const char *base58_vector[] = { + "02e649f63f8e8121345fd7f47d0d185a3ccaa843115cd2e9392dcd9b82263bc680", "6dumtt9swxCqwdPZBGXh9YmHoEjFFnNfwHaTqRbQTghGAY2gRz", + "021c7359cd885c0e319924d97e3980206ad64387aff54908241125b3a88b55ca16", "5725vivYpuFWbeyTifZ5KevnHyqXCi5hwHbNU9cYz1FHbFXCxX", + "02f561e0b57a552df3fa1df2d87a906b7a9fc33a83d5d15fa68a644ecb0806b49a", "6kZKHSuxqAwdCYsMvwTcipoTsNE2jmEUNBQufGYywpniBKXWZK", + "03e7595c3e6b58f907bee951dc29796f3757307e700ecf3d09307a0cc4a564eba3", "8b82mpnH8YX1E9RHnU2a2YgLTZ8ooevEGP9N15c1yFqhoBvJur", + 0, 0, + }; + const char **raw = base58_vector; + const char **str = base58_vector + 1; + uint8_t rawn[34]; + char strn[53]; + int r; + while (*raw && *str) { + int len = strlen(*raw) / 2; + + memcpy(rawn, fromhex(*raw), len); + r = base58gph_encode_check(rawn, len, strn, sizeof(strn)); + ck_assert_int_eq((size_t)r, strlen(*str) + 1); + ck_assert_str_eq(strn, *str); + + r = base58gph_decode_check(strn, rawn, len); + ck_assert_int_eq(r, len); + ck_assert_mem_eq(rawn, fromhex(*raw), len); + + raw += 2; str += 2; + } +} +END_TEST + +#endif + +START_TEST(test_bignum_divmod) +{ + uint32_t r; + int i; + + bignum256 a = { { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff} }; + uint32_t ar[] = { 15, 14, 55, 29, 44, 24, 53, 49, 18, 55, 2, 28, 5, 4, 12, 43, 18, 37, 28, 14, 30, 46, 12, 11, 17, 10, 10, 13, 24, 45, 4, 33, 44, 42, 2, 46, 34, 43, 45, 28, 21, 18, 13, 17 }; + + i = 0; + while (!bn_is_zero(&a) && i < 44) { + bn_divmod58(&a, &r); + ck_assert_int_eq(r, ar[i]); + i++; + } + ck_assert_int_eq(i, 44); + + bignum256 b = { { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff} }; + uint32_t br[] = { 935, 639, 129, 913, 7, 584, 457, 39, 564, 640, 665, 984, 269, 853, 907, 687, 8, 985, 570, 423, 195, 316, 237, 89, 792, 115 }; + + i = 0; + while (!bn_is_zero(&b) && i < 26) { + bn_divmod1000(&b, &r); + ck_assert_int_eq(r, br[i]); + i++; + } + ck_assert_int_eq(i, 26); + +} +END_TEST + +// test vector 1 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors +START_TEST(test_bip32_vector_1) +{ + HDNode node, node2, node3; + uint32_t fingerprint; + char str[112]; + int r; + + // init m + hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, SECP256K1_NAME, &node); + + // [Chain m] + fingerprint = 0; + ck_assert_int_eq(fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"), 32); + ck_assert_mem_eq(node.private_key, fromhex("e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd_prime(&node, 0); + ck_assert_int_eq(fingerprint, 0x3442193e); + ck_assert_mem_eq(node.chain_code, fromhex("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141"), 32); + ck_assert_mem_eq(node.private_key, fromhex("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 1); + ck_assert_int_eq(fingerprint, 0x5c1bd648); + ck_assert_mem_eq(node.chain_code, fromhex("2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19"), 32); + ck_assert_mem_eq(node.private_key, fromhex("3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1/2'] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd_prime(&node, 2); + ck_assert_int_eq(fingerprint, 0xbef5a2f9); + ck_assert_mem_eq(node.chain_code, fromhex("04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f"), 32); + ck_assert_mem_eq(node.private_key, fromhex("cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1/2'/2] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 2); + ck_assert_int_eq(fingerprint, 0xee7ab90c); + ck_assert_mem_eq(node.chain_code, fromhex("cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd"), 32); + ck_assert_mem_eq(node.private_key, fromhex("0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1/2'/2/1000000000] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 1000000000); + ck_assert_int_eq(fingerprint, 0xd880d7d8); + ck_assert_mem_eq(node.chain_code, fromhex("c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e"), 32); + ck_assert_mem_eq(node.private_key, fromhex("471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); +} +END_TEST + +// test vector 2 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors +START_TEST(test_bip32_vector_2) +{ + HDNode node, node2, node3; + uint32_t fingerprint; + char str[112]; + int r; + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, SECP256K1_NAME, &node); + + // [Chain m] + fingerprint = 0; + ck_assert_int_eq(fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689"), 32); + ck_assert_mem_eq(node.private_key, fromhex("4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0xbd16bee5); + ck_assert_mem_eq(node.chain_code, fromhex("f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"), 32); + ck_assert_mem_eq(node.private_key, fromhex("abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd_prime(&node, 2147483647); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x5a61ff8e); + ck_assert_mem_eq(node.chain_code, fromhex("be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9"), 32); + ck_assert_mem_eq(node.private_key, fromhex("877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'/1] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 1); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0xd8ab4937); + ck_assert_mem_eq(node.chain_code, fromhex("f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb"), 32); + ck_assert_mem_eq(node.private_key, fromhex("704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'/1/2147483646'] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd_prime(&node, 2147483646); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x78412e3a); + ck_assert_mem_eq(node.chain_code, fromhex("637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29"), 32); + ck_assert_mem_eq(node.private_key, fromhex("f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'/1/2147483646'/2] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 2); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x31a507b8); + ck_assert_mem_eq(node.chain_code, fromhex("9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271"), 32); + ck_assert_mem_eq(node.private_key, fromhex("bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c"), 33); + hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt"); + r = hdnode_deserialize(str, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, SECP256K1_NAME, &node); + + // test public derivation + // [Chain m/0] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_public_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0xbd16bee5); + ck_assert_mem_eq(node.chain_code, fromhex("f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"), 32); + ck_assert_mem_eq(node.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea"), 33); +} +END_TEST + +START_TEST(test_bip32_compare) +{ + HDNode node1, node2, node3; + int i, r; + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1); + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2); + hdnode_fill_public_key(&node2); + for (i = 0; i < 100; i++) { + memcpy(&node3, &node1, sizeof(HDNode)); + hdnode_fill_public_key(&node3); + r = hdnode_private_ckd(&node1, i); ck_assert_int_eq(r, 1); + r = hdnode_public_ckd(&node2, i); ck_assert_int_eq(r, 1); + r = hdnode_public_ckd(&node3, i); ck_assert_int_eq(r, 1); + ck_assert_int_eq(node1.depth, node2.depth); + ck_assert_int_eq(node1.depth, node3.depth); + ck_assert_int_eq(node1.child_num, node2.child_num); + ck_assert_int_eq(node1.child_num, node3.child_num); + ck_assert_mem_eq(node1.chain_code, node2.chain_code, 32); + ck_assert_mem_eq(node1.chain_code, node3.chain_code, 32); + ck_assert_mem_eq(node2.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + ck_assert_mem_eq(node3.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + hdnode_fill_public_key(&node1); + ck_assert_mem_eq(node1.public_key, node2.public_key, 33); + ck_assert_mem_eq(node1.public_key, node3.public_key, 33); + } +} +END_TEST + +START_TEST(test_bip32_optimized) +{ + HDNode root; + hdnode_from_seed((uint8_t *)"NothingToSeeHere", 16, SECP256K1_NAME, &root); + hdnode_fill_public_key(&root); + + curve_point pub; + ecdsa_read_pubkey(&secp256k1, root.public_key, &pub); + + HDNode node; + char addr1[MAX_ADDR_SIZE], addr2[MAX_ADDR_SIZE]; + + for (int i = 0; i < 40; i++) { + // unoptimized + memcpy(&node, &root, sizeof(HDNode)); + hdnode_public_ckd(&node, i); + hdnode_fill_public_key(&node); + ecdsa_get_address(node.public_key, 0, HASHER_SHA2, addr1, sizeof(addr1)); + // optimized + hdnode_public_ckd_address_optimized(&pub, root.chain_code, i, 0, HASHER_SHA2, addr2, sizeof(addr2), 0); + // check + ck_assert_str_eq(addr1, addr2); + } +} +END_TEST + +START_TEST(test_bip32_cache_1) +{ + HDNode node1, node2; + int i, r; + + // test 1 .. 8 + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1); + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2); + + uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, 0x80000005, 0x80000006, 0x80000007, 0x80000008}; + + for (i = 0; i < 8; i++) { + r = hdnode_private_ckd(&node1, ii[i]); ck_assert_int_eq(r, 1); + } + r = hdnode_private_ckd_cached(&node2, ii, 8, NULL); ck_assert_int_eq(r, 1); + ck_assert_mem_eq(&node1, &node2, sizeof(HDNode)); + + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1); + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2); + + // test 1 .. 7, 20 + ii[7] = 20; + for (i = 0; i < 8; i++) { + r = hdnode_private_ckd(&node1, ii[i]); ck_assert_int_eq(r, 1); + } + r = hdnode_private_ckd_cached(&node2, ii, 8, NULL); ck_assert_int_eq(r, 1); + ck_assert_mem_eq(&node1, &node2, sizeof(HDNode)); + + // test different root node + hdnode_from_seed(fromhex("000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node1); + hdnode_from_seed(fromhex("000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &node2); + + for (i = 0; i < 8; i++) { + r = hdnode_private_ckd(&node1, ii[i]); ck_assert_int_eq(r, 1); + } + r = hdnode_private_ckd_cached(&node2, ii, 8, NULL); ck_assert_int_eq(r, 1); + ck_assert_mem_eq(&node1, &node2, sizeof(HDNode)); +} +END_TEST + +START_TEST(test_bip32_cache_2) +{ + HDNode nodea[9], nodeb[9]; + int i, j, r; + + for (j = 0; j < 9; j++) { + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &(nodea[j])); + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, SECP256K1_NAME, &(nodeb[j])); + } + + uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, 0x80000005, 0x80000006, 0x80000007, 0x80000008}; + for (j = 0; j < 9; j++) { + // non cached + for (i = 1; i <= j; i++) { + r = hdnode_private_ckd(&(nodea[j]), ii[i - 1]); ck_assert_int_eq(r, 1); + } + // cached + r = hdnode_private_ckd_cached(&(nodeb[j]), ii, j, NULL); ck_assert_int_eq(r, 1); + } + + ck_assert_mem_eq(&(nodea[0]), &(nodeb[0]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[1]), &(nodeb[1]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[2]), &(nodeb[2]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[3]), &(nodeb[3]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[4]), &(nodeb[4]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[5]), &(nodeb[5]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[6]), &(nodeb[6]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[7]), &(nodeb[7]), sizeof(HDNode)); + ck_assert_mem_eq(&(nodea[8]), &(nodeb[8]), sizeof(HDNode)); +} +END_TEST + +START_TEST(test_bip32_nist_seed) +{ + HDNode node; + + // init m + hdnode_from_seed(fromhex("a7305bc8df8d0951f0cb224c0e95d7707cbdf2c6ce7e8d481fec69c7ff5e9446"), 32, NIST256P1_NAME, &node); + + // [Chain m] + ck_assert_mem_eq(node.private_key, fromhex("3b8c18469a4634517d6d0b65448f8e6c62091b45540a1743c5846be55d47d88f"), 32); + ck_assert_mem_eq(node.chain_code, fromhex("7762f9729fed06121fd13f326884c82f59aa95c57ac492ce8c9654e60efd130c"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0383619fadcde31063d8c5cb00dbfe1713f3e6fa169d8541a798752a1c1ca0cb20"), 33); + + // init m + hdnode_from_seed(fromhex("aa305bc8df8d0951f0cb29ad4568d7707cbdf2c6ce7e8d481fec69c7ff5e9446"), 32, NIST256P1_NAME, &node); + + // [Chain m] + ck_assert_mem_eq(node.chain_code, fromhex("a81d21f36f987fa0be3b065301bfb6aa9deefbf3dfef6744c37b9a4abc3c68f1"), 32); + ck_assert_mem_eq(node.private_key, fromhex("0e49dc46ce1d8c29d9b80a05e40f5d0cd68cbf02ae98572186f5343be18084bf"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03aaa4c89acd9a98935330773d3dae55122f3591bac4a40942681768de8df6ba63"), 33); +} +END_TEST + +START_TEST(test_bip32_nist_vector_1) +{ + HDNode node; + uint32_t fingerprint; + + // init m + hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, NIST256P1_NAME, &node); + + // [Chain m] + fingerprint = 0; + ck_assert_int_eq(fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("beeb672fe4621673f722f38529c07392fecaa61015c80c34f29ce8b41b3cb6ea"), 32); + ck_assert_mem_eq(node.private_key, fromhex("612091aaa12e22dd2abef664f8a01a82cae99ad7441b7ef8110424915c268bc2"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0266874dc6ade47b3ecd096745ca09bcd29638dd52c2c12117b11ed3e458cfa9e8"), 33); + + // [Chain m/0'] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd_prime(&node, 0); + ck_assert_int_eq(fingerprint, 0xbe6105b5); + ck_assert_mem_eq(node.chain_code, fromhex("3460cea53e6a6bb5fb391eeef3237ffd8724bf0a40e94943c98b83825342ee11"), 32); + ck_assert_mem_eq(node.private_key, fromhex("6939694369114c67917a182c59ddb8cafc3004e63ca5d3b84403ba8613debc0c"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0384610f5ecffe8fda089363a41f56a5c7ffc1d81b59a612d0d649b2d22355590c"), 33); + + // [Chain m/0'/1] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 1); + ck_assert_int_eq(fingerprint, 0x9b02312f); + ck_assert_mem_eq(node.chain_code, fromhex("4187afff1aafa8445010097fb99d23aee9f599450c7bd140b6826ac22ba21d0c"), 32); + ck_assert_mem_eq(node.private_key, fromhex("284e9d38d07d21e4e281b645089a94f4cf5a5a81369acf151a1c3a57f18b2129"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03526c63f8d0b4bbbf9c80df553fe66742df4676b241dabefdef67733e070f6844"), 33); + + // [Chain m/0'/1/2'] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd_prime(&node, 2); + ck_assert_int_eq(fingerprint, 0xb98005c1); + ck_assert_mem_eq(node.chain_code, fromhex("98c7514f562e64e74170cc3cf304ee1ce54d6b6da4f880f313e8204c2a185318"), 32); + ck_assert_mem_eq(node.private_key, fromhex("694596e8a54f252c960eb771a3c41e7e32496d03b954aeb90f61635b8e092aa7"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0359cf160040778a4b14c5f4d7b76e327ccc8c4a6086dd9451b7482b5a4972dda0"), 33); + + // [Chain m/0'/1/2'/2] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 2); + ck_assert_int_eq(fingerprint, 0x0e9f3274); + ck_assert_mem_eq(node.chain_code, fromhex("ba96f776a5c3907d7fd48bde5620ee374d4acfd540378476019eab70790c63a0"), 32); + ck_assert_mem_eq(node.private_key, fromhex("5996c37fd3dd2679039b23ed6f70b506c6b56b3cb5e424681fb0fa64caf82aaa"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("029f871f4cb9e1c97f9f4de9ccd0d4a2f2a171110c61178f84430062230833ff20"), 33); + + // [Chain m/0'/1/2'/2/1000000000] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 1000000000); + ck_assert_int_eq(fingerprint, 0x8b2b5c4b); + ck_assert_mem_eq(node.chain_code, fromhex("b9b7b82d326bb9cb5b5b121066feea4eb93d5241103c9e7a18aad40f1dde8059"), 32); + ck_assert_mem_eq(node.private_key, fromhex("21c4f269ef0a5fd1badf47eeacebeeaa3de22eb8e5b0adcd0f27dd99d34d0119"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02216cd26d31147f72427a453c443ed2cde8a1e53c9cc44e5ddf739725413fe3f4"), 33); +} +END_TEST + +START_TEST(test_bip32_nist_vector_2) +{ + HDNode node; + uint32_t fingerprint; + int r; + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, NIST256P1_NAME, &node); + + // [Chain m] + fingerprint = 0; + ck_assert_int_eq(fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("96cd4465a9644e31528eda3592aa35eb39a9527769ce1855beafc1b81055e75d"), 32); + ck_assert_mem_eq(node.private_key, fromhex("eaa31c2e46ca2962227cf21d73a7ef0ce8b31c756897521eb6c7b39796633357"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02c9e16154474b3ed5b38218bb0463e008f89ee03e62d22fdcc8014beab25b48fa"), 33); + + // [Chain m/0] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x607f628f); + ck_assert_mem_eq(node.chain_code, fromhex("84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), 32); + ck_assert_mem_eq(node.private_key, fromhex("d7d065f63a62624888500cdb4f88b6d59c2927fee9e6d0cdff9cad555884df6e"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), 33); + + // [Chain m/0/2147483647'] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd_prime(&node, 2147483647); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x946d2a54); + ck_assert_mem_eq(node.chain_code, fromhex("f235b2bc5c04606ca9c30027a84f353acf4e4683edbd11f635d0dcc1cd106ea6"), 32); + ck_assert_mem_eq(node.private_key, fromhex("96d2ec9316746a75e7793684ed01e3d51194d81a42a3276858a5b7376d4b94b9"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02f89c5deb1cae4fedc9905f98ae6cbf6cbab120d8cb85d5bd9a91a72f4c068c76"), 33); + + // [Chain m/0/2147483647'/1] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 1); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x218182d8); + ck_assert_mem_eq(node.chain_code, fromhex("7c0b833106235e452eba79d2bdd58d4086e663bc8cc55e9773d2b5eeda313f3b"), 32); + ck_assert_mem_eq(node.private_key, fromhex("974f9096ea6873a915910e82b29d7c338542ccde39d2064d1cc228f371542bbc"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03abe0ad54c97c1d654c1852dfdc32d6d3e487e75fa16f0fd6304b9ceae4220c64"), 33); + + // [Chain m/0/2147483647'/1/2147483646'] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd_prime(&node, 2147483646); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x931223e4); + ck_assert_mem_eq(node.chain_code, fromhex("5794e616eadaf33413aa309318a26ee0fd5163b70466de7a4512fd4b1a5c9e6a"), 32); + ck_assert_mem_eq(node.private_key, fromhex("da29649bbfaff095cd43819eda9a7be74236539a29094cd8336b07ed8d4eff63"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03cb8cb067d248691808cd6b5a5a06b48e34ebac4d965cba33e6dc46fe13d9b933"), 33); + + // [Chain m/0/2147483647'/1/2147483646'/2] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 2); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x956c4629); + ck_assert_mem_eq(node.chain_code, fromhex("3bfb29ee8ac4484f09db09c2079b520ea5616df7820f071a20320366fbe226a7"), 32); + ck_assert_mem_eq(node.private_key, fromhex("bb0a77ba01cc31d77205d51d08bd313b979a71ef4de9b062f8958297e746bd67"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("020ee02e18967237cf62672983b253ee62fa4dd431f8243bfeccdf39dbe181387f"), 33); + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, NIST256P1_NAME, &node); + + // test public derivation + // [Chain m/0] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_public_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x607f628f); + ck_assert_mem_eq(node.chain_code, fromhex("84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), 32); + ck_assert_mem_eq(node.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + ck_assert_mem_eq(node.public_key, fromhex("039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), 33); +} +END_TEST + +START_TEST(test_bip32_nist_compare) +{ + HDNode node1, node2, node3; + int i, r; + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, NIST256P1_NAME, &node1); + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, NIST256P1_NAME, &node2); + hdnode_fill_public_key(&node2); + for (i = 0; i < 100; i++) { + memcpy(&node3, &node1, sizeof(HDNode)); + hdnode_fill_public_key(&node3); + r = hdnode_private_ckd(&node1, i); ck_assert_int_eq(r, 1); + r = hdnode_public_ckd(&node2, i); ck_assert_int_eq(r, 1); + r = hdnode_public_ckd(&node3, i); ck_assert_int_eq(r, 1); + ck_assert_int_eq(node1.depth, node2.depth); + ck_assert_int_eq(node1.depth, node3.depth); + ck_assert_int_eq(node1.child_num, node2.child_num); + ck_assert_int_eq(node1.child_num, node3.child_num); + ck_assert_mem_eq(node1.chain_code, node2.chain_code, 32); + ck_assert_mem_eq(node1.chain_code, node3.chain_code, 32); + ck_assert_mem_eq(node2.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + ck_assert_mem_eq(node3.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + hdnode_fill_public_key(&node1); + ck_assert_mem_eq(node1.public_key, node2.public_key, 33); + ck_assert_mem_eq(node1.public_key, node3.public_key, 33); + } +} +END_TEST + +START_TEST(test_bip32_nist_repeat) +{ + HDNode node, node2; + uint32_t fingerprint; + int r; + + // init m + hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, NIST256P1_NAME, &node); + + // [Chain m/28578'] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd_prime(&node, 28578); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0xbe6105b5); + ck_assert_mem_eq(node.chain_code, fromhex("e94c8ebe30c2250a14713212f6449b20f3329105ea15b652ca5bdfc68f6c65c2"), 32); + ck_assert_mem_eq(node.private_key, fromhex("06f0db126f023755d0b8d86d4591718a5210dd8d024e3e14b6159d63f53aa669"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02519b5554a4872e8c9c1c847115363051ec43e93400e030ba3c36b52a3e70a5b7"), 33); + + memcpy(&node2, &node, sizeof(HDNode)); + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node2, 33941); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x3e2b7bc6); + ck_assert_mem_eq(node2.chain_code, fromhex("9e87fe95031f14736774cd82f25fd885065cb7c358c1edf813c72af535e83071"), 32); + ck_assert_mem_eq(node2.private_key, fromhex("092154eed4af83e078ff9b84322015aefe5769e31270f62c3f66c33888335f3a"), 32); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(node2.public_key, fromhex("0235bfee614c0d5b2cae260000bb1d0d84b270099ad790022c1ae0b2e782efe120"), 33); + + memcpy(&node2, &node, sizeof(HDNode)); + memset(&node2.private_key, 0, 32); + r = hdnode_public_ckd(&node2, 33941); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x3e2b7bc6); + ck_assert_mem_eq(node2.chain_code, fromhex("9e87fe95031f14736774cd82f25fd885065cb7c358c1edf813c72af535e83071"), 32); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(node2.public_key, fromhex("0235bfee614c0d5b2cae260000bb1d0d84b270099ad790022c1ae0b2e782efe120"), 33); +} +END_TEST + +// test vector 1 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors +START_TEST(test_bip32_ed25519_vector_1) +{ + HDNode node; + + // init m + hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, ED25519_NAME, &node); + + // [Chain m] + ck_assert_mem_eq(node.chain_code, fromhex("90046a93de5380a72b5e45010748567d5ea02bbf6522f979e05c0d8d8ca9fffb"), 32); + ck_assert_mem_eq(node.private_key, fromhex("2b4be7f19ee27bbf30c667b642d5f4aa69fd169872f8fc3059c08ebae2eb19e7"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("01a4b2856bfec510abab89753fac1ac0e1112364e7d250545963f135f2a33188ed"), 33); + + // [Chain m/0'] + hdnode_private_ckd_prime(&node, 0); + ck_assert_mem_eq(node.chain_code, fromhex("8b59aa11380b624e81507a27fedda59fea6d0b779a778918a2fd3590e16e9c69"), 32); + ck_assert_mem_eq(node.private_key, fromhex("68e0fe46dfb67e368c75379acec591dad19df3cde26e63b93a8e704f1dade7a3"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("018c8a13df77a28f3445213a0f432fde644acaa215fc72dcdf300d5efaa85d350c"), 33); + + // [Chain m/0'/1'] + hdnode_private_ckd_prime(&node, 1); + ck_assert_mem_eq(node.chain_code, fromhex("a320425f77d1b5c2505a6b1b27382b37368ee640e3557c315416801243552f14"), 32); + ck_assert_mem_eq(node.private_key, fromhex("b1d0bad404bf35da785a64ca1ac54b2617211d2777696fbffaf208f746ae84f2"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("011932a5270f335bed617d5b935c80aedb1a35bd9fc1e31acafd5372c30f5c1187"), 33); + + // [Chain m/0'/1'/2'] + hdnode_private_ckd_prime(&node, 2); + ck_assert_mem_eq(node.chain_code, fromhex("2e69929e00b5ab250f49c3fb1c12f252de4fed2c1db88387094a0f8c4c9ccd6c"), 32); + ck_assert_mem_eq(node.private_key, fromhex("92a5b23c0b8a99e37d07df3fb9966917f5d06e02ddbd909c7e184371463e9fc9"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("01ae98736566d30ed0e9d2f4486a64bc95740d89c7db33f52121f8ea8f76ff0fc1"), 33); + + // [Chain m/0'/1'/2'/2'] + hdnode_private_ckd_prime(&node, 2); + ck_assert_mem_eq(node.chain_code, fromhex("8f6d87f93d750e0efccda017d662a1b31a266e4a6f5993b15f5c1f07f74dd5cc"), 32); + ck_assert_mem_eq(node.private_key, fromhex("30d1dc7e5fc04c31219ab25a27ae00b50f6fd66622f6e9c913253d6511d1e662"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("018abae2d66361c879b900d204ad2cc4984fa2aa344dd7ddc46007329ac76c429c"), 33); + + // [Chain m/0'/1'/2'/2'/1000000000'] + hdnode_private_ckd_prime(&node, 1000000000); + ck_assert_mem_eq(node.chain_code, fromhex("68789923a0cac2cd5a29172a475fe9e0fb14cd6adb5ad98a3fa70333e7afa230"), 32); + ck_assert_mem_eq(node.private_key, fromhex("8f94d394a8e8fd6b1bc2f3f49f5c47e385281d5c17e65324b0f62483e37e8793"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("013c24da049451555d51a7014a37337aa4e12d41e485abccfa46b47dfb2af54b7a"), 33); +} +END_TEST + +// test vector 2 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors +START_TEST(test_bip32_ed25519_vector_2) +{ + HDNode node; + int r; + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, ED25519_NAME, &node); + + // [Chain m] + ck_assert_mem_eq(node.chain_code, fromhex("ef70a74db9c3a5af931b5fe73ed8e1a53464133654fd55e7a66f8570b8e33c3b"), 32); + ck_assert_mem_eq(node.private_key, fromhex("171cb88b1b3c1db25add599712e36245d75bc65a1a5c9e18d76f9f2b1eab4012"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("018fe9693f8fa62a4305a140b9764c5ee01e455963744fe18204b4fb948249308a"), 33); + + // [Chain m/0'] + r = hdnode_private_ckd_prime(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_mem_eq(node.chain_code, fromhex("0b78a3226f915c082bf118f83618a618ab6dec793752624cbeb622acb562862d"), 32); + ck_assert_mem_eq(node.private_key, fromhex("1559eb2bbec5790b0c65d8693e4d0875b1747f4970ae8b650486ed7470845635"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0186fab68dcb57aa196c77c5f264f215a112c22a912c10d123b0d03c3c28ef1037"), 33); + + // [Chain m/0'/2147483647'] + r = hdnode_private_ckd_prime(&node, 2147483647); + ck_assert_int_eq(r, 1); + ck_assert_mem_eq(node.chain_code, fromhex("138f0b2551bcafeca6ff2aa88ba8ed0ed8de070841f0c4ef0165df8181eaad7f"), 32); + ck_assert_mem_eq(node.private_key, fromhex("ea4f5bfe8694d8bb74b7b59404632fd5968b774ed545e810de9c32a4fb4192f4"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("015ba3b9ac6e90e83effcd25ac4e58a1365a9e35a3d3ae5eb07b9e4d90bcf7506d"), 33); + + // [Chain m/0'/2147483647'/1'] + r = hdnode_private_ckd_prime(&node, 1); + ck_assert_int_eq(r, 1); + ck_assert_mem_eq(node.chain_code, fromhex("73bd9fff1cfbde33a1b846c27085f711c0fe2d66fd32e139d3ebc28e5a4a6b90"), 32); + ck_assert_mem_eq(node.private_key, fromhex("3757c7577170179c7868353ada796c839135b3d30554bbb74a4b1e4a5a58505c"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("012e66aa57069c86cc18249aecf5cb5a9cebbfd6fadeab056254763874a9352b45"), 33); + + // [Chain m/0'/2147483647'/1'/2147483646'] + r = hdnode_private_ckd_prime(&node, 2147483646); + ck_assert_int_eq(r, 1); + ck_assert_mem_eq(node.chain_code, fromhex("0902fe8a29f9140480a00ef244bd183e8a13288e4412d8389d140aac1794825a"), 32); + ck_assert_mem_eq(node.private_key, fromhex("5837736c89570de861ebc173b1086da4f505d4adb387c6a1b1342d5e4ac9ec72"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("01e33c0f7d81d843c572275f287498e8d408654fdf0d1e065b84e2e6f157aab09b"), 33); + + // [Chain m/0'/2147483647'/1'/2147483646'/2'] + r = hdnode_private_ckd_prime(&node, 2); + ck_assert_int_eq(r, 1); + ck_assert_mem_eq(node.chain_code, fromhex("5d70af781f3a37b829f0d060924d5e960bdc02e85423494afc0b1a41bbe196d4"), 32); + ck_assert_mem_eq(node.private_key, fromhex("551d333177df541ad876a60ea71f00447931c0a9da16f227c11ea080d7391b8d"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0147150c75db263559a70d5778bf36abbab30fb061ad69f69ece61a72b0cfa4fc0"), 33); +} +END_TEST + +// test vector 1 from https://github.com/decred/dcrd/blob/master/hdkeychain/extendedkey_test.go +START_TEST(test_bip32_decred_vector_1) +{ + HDNode node, node2, node3; + uint32_t fingerprint; + char str[112]; + int r; + + // init m + hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, SECP256K1_NAME, &node); + + // secp256k1_decred_info.bip32_name != "Bitcoin seed" so we cannot use it in hdnode_from_seed + node.curve = &secp256k1_decred_info; + + // [Chain m] + fingerprint = 0; + ck_assert_int_eq(fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"), 32); + ck_assert_mem_eq(node.private_key, fromhex("e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3hCznBesA6jBtmoyVFPfyMSZ1qYZ3WdjdebquvkEfmRfxC9VFEFi2YDaJqHnx7uGe75eGSa3Mn3oHK11hBW7KZUrPxwbCPBmuCi1nwm182s"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZ9169KDAEUnyoBhjjmT2VaEodr6pUTDoqCEAeqgbfr2JfkB88BbK77jbTYbcYXb2FVz7DKBdW4P618yd51MwF8DjKVopSbS7Lkgi6bowX5w"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd_prime(&node, 0); + ck_assert_int_eq(fingerprint, 0xbc495588); + ck_assert_mem_eq(node.chain_code, fromhex("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141"), 32); + ck_assert_mem_eq(node.private_key, fromhex("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3kUQDBztdyjKuwnaL3hfKYpT7W6X2huYH5d61YSWFBebSYwEBHAXJkCpQ7rvMAxPzKqxVCGLvBqWvGxXjAyMJsV1XwKkfnQCM9KctC8k8bk"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZCGVaKZBiMo7pMgLaZm1qmchjWenTeVcUdFQkTNsFGFEA6xs4EW8PKiqYqP7HBAitt9Hw16VQkQ1tjsZQSHNWFc6bEK6bLqrbco24FzBTY4"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 1); + ck_assert_int_eq(fingerprint, 0xc67bc2ef); + ck_assert_mem_eq(node.chain_code, fromhex("2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19"), 32); + ck_assert_mem_eq(node.private_key, fromhex("3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3nRtCZ5VAoHW4RUwQgRafSNRPUDFrmsgyY71A5eoZceVfuyL9SbZe2rcbwDW2UwpkEniE4urffgbypegscNchPajWzy9QS4cRxF8QYXsZtq"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZEDyZgdnFBMHxqNhfCUwBfAg1UmXHiTmB5jKtzbAZhF8PTzy2PwAicNdkg1CmW6TARxQeUbgC7nAQenJts4YoG3KMiqcjsjgeMvwLc43w6C"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1/2'] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd_prime(&node, 2); + ck_assert_int_eq(fingerprint, 0xe7072187); + ck_assert_mem_eq(node.chain_code, fromhex("04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f"), 32); + ck_assert_mem_eq(node.private_key, fromhex("cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3pYtkZK168vgrU38gXkUSjHQ2LGpEUzQ9fXrR8fGUR59YviSnm6U82XjQYhpJEUPnVcC9bguJBQU5xVM4VFcDHu9BgScGPA6mQMH4bn5Cth"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZGLz7gsJAWzUksvtw3opxx5eeLq5fRaUMDABA3bdUVfnGUk5fiS5Cc3kZGTjWtYr3jrEavQQnAF6jv2WCpZtFX4uFgifXqev6ED1TM9rTCB"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1/2'/2] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 2); + ck_assert_int_eq(fingerprint, 0xbcbbc1c4); + ck_assert_mem_eq(node.chain_code, fromhex("cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd"), 32); + ck_assert_mem_eq(node.private_key, fromhex("0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3r7zqYFjT3NiNzdnwGxGpYh6S1TJCp1zA6mSEGaqLBJFnCB94cRMp7YYLR49aTZHZ7ya1CXwQJ6rodKeU9NgQTxkPSK7pzgZRgjYkQ7rgJh"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZHv6Cfp2XRSWHQXZBo1dLmVM421Zdkc4MePkyBXCLFttVkCmwZkxth4ZV9PzkFP3DtD5xcVq2CPSYpJMWMaoxu1ixz4GNZFVcE2xnHP6chJ"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0'/1/2'/2/1000000000] + fingerprint = hdnode_fingerprint(&node); + hdnode_private_ckd(&node, 1000000000); + ck_assert_int_eq(fingerprint, 0xe58b52e4); + ck_assert_mem_eq(node.chain_code, fromhex("c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e"), 32); + ck_assert_mem_eq(node.private_key, fromhex("471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3tJXnTDSb3uE6Euo6WvvhFKfBMNfxuJt5smqyPoHEoomoBMQyhYoQSKJAHWtWxmuqdUVb8q9J2NaTkF6rYm6XDrSotkJ55bM21fffa7VV97"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZL6d9amjfRy1zeoZM2zHDU7uoMvwPqtxHRQAiJjeEtQQWjP3retQV1qKJyzUd6ZJNgbJGXjtc5pdoBcTTYTLoxQzvV9JJCzCjB2eCWpRf8T"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); +} +END_TEST + +// test vector 2 from https://github.com/decred/dcrd/blob/master/hdkeychain/extendedkey_test.go +START_TEST(test_bip32_decred_vector_2) +{ + HDNode node, node2, node3; + uint32_t fingerprint; + char str[112]; + int r; + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, SECP256K1_NAME, &node); + + // secp256k1_decred_info.bip32_name != "Bitcoin seed" so we cannot use it in hdnode_from_seed + node.curve = &secp256k1_decred_info; + + // [Chain m] + fingerprint = 0; + ck_assert_int_eq(fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689"), 32); + ck_assert_mem_eq(node.private_key, fromhex("4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3hCznBesA6jBtPKJbQTxRZAKG2gyj8tZKEPaCsV4e9YYFBAgRP2eTSPAeu4r8dTMt9q51j2Vdt5zNqj7jbtovvocrP1qLj6WUTLF9xYQt4y"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZ9169KDAEUnynoD4qvXJwmxZt3FFA5UdWn1twnRReE9AxjCKJLNFY1uBoegbFmwzA4Du7yqnu8tLivhrCCH6P3DgBS1HH5vmf8MpNXvvYT9"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x2524c9d3); + ck_assert_mem_eq(node.chain_code, fromhex("f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"), 32); + ck_assert_mem_eq(node.private_key, fromhex("abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3jMy45BuuDETfxi59P8NTSjHPrNVq4wPRfLgRd57923L2hosj5NUEqiLYQ4i7fJtUpiXZLr2wUeToJY2Tm5sCpAJdajEHDmieVJiPQNXwu9"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZBA4RCkCybJFaNbqPuBiyfXY1rvmG1XTdCy1AY1U96dxkFqWc2i5KREMh7NYPpy7ZPMhdpFMAesex3JdFDfX4J5FEW3HjSacqEYPfwb9Cj7"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd_prime(&node, 2147483647); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x6035c6ad); + ck_assert_mem_eq(node.chain_code, fromhex("be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9"), 32); + ck_assert_mem_eq(node.private_key, fromhex("877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3mgHPRgK838mLK6T1p6WeBoJoJtXA1pGTHjqFuyHekcM7UTuER8fGweRRsoLqSuHa98uskVPnJnfWZEBUC1AVmXnSCPDvUFKydXNnnPHTuQ"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZDUNkZEcCRCZEizDGL9sAQbZRKSnaxQLeqN9zpueeqCyq2VY7NUGMXASacsK96S8XzNjq3YgFgwLtj8MJBToW6To9U5zxuazEyh89bjR1xA"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'/1] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 1); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x36fc7080); + ck_assert_mem_eq(node.chain_code, fromhex("f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb"), 32); + ck_assert_mem_eq(node.private_key, fromhex("704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3oFqwZZ9bJcUmhAeJyyshvrTWtrAsHfcRYQbEzNiiH5nGvM6wVTDn6woQEz92b2EHTYZBtLi82jKEnxSouA3cVaW8YWBsw5c3f4mwAhA3d2"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZF3wJh7SfggGg74QZW3EE9ei8uQSJEFgd62uyuK5iMgQzUNjpSnprgTpYz3d6Q3fXXtEEXQqpzWcP4LUVuXFsgA8JKt1Hot5kyUk4pPRhDz"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'/1/2147483646'] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd_prime(&node, 2147483646); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x45309b4c); + ck_assert_mem_eq(node.chain_code, fromhex("637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29"), 32); + ck_assert_mem_eq(node.private_key, fromhex("f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3qF3177i87wMirg6sraDvqty8yZg6THpXFPSXuM5AShBiiUQbq8FhSZDGkYmBNR3RKfBrxzkKDBpsRFJfTnQfLsvpPPqRnakat6hHQA43X9"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZH38NEg1CW19dGZs8NdaT4hDkz7wXPstio1mGpHSAXHpSGW3UnTrn25ERT1Mp8ae5GMoQHMbgQiPrChMXQMdx3UqS8YqFkT1pqait8fY92u"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // [Chain m/0/2147483647'/1/2147483646'/2] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_private_ckd(&node, 2); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x3491a5e6); + ck_assert_mem_eq(node.chain_code, fromhex("9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271"), 32); + ck_assert_mem_eq(node.private_key, fromhex("bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23"), 32); + hdnode_fill_public_key(&node); + ck_assert_mem_eq(node.public_key, fromhex("024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c"), 33); + hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, sizeof(str)); + ck_assert_str_eq(str, "dprv3s15tfqzxhw8Kmo7RBEqMeyvC7uGekLniSmvbs3bckpxQ6ks1KKqfmH144Jgh3PLxkyZRcS367kp7DrtUmnG16NpnsoNhxSXRgKbJJ7MUQR"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + hdnode_fill_public_key(&node2); + ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZJoBFoQJ35zvEBgsfhJBssnAp8TY5gvruzQFLmyxcqRb7enVtGfSkLo2CkAZJMpa6T2fx6fUtvTgXtUvSVgAZ56bEwGxQsToeZfFV8VadE1"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + memcpy(&node3, &node, sizeof(HDNode)); + memset(&node3.private_key, 0, 32); + ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); + + // init m + hdnode_deserialize("dpubZF4LSCdF9YKZfNzTVYhz4RBxsjYXqms8AQnMBHXZ8GUKoRSigG7kQnKiJt5pzk93Q8FxcdVBEkQZruSXduGtWnkwXzGnjbSovQ97dCxqaXc", DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node, NULL); + + // test public derivation + // [Chain m/0] + fingerprint = hdnode_fingerprint(&node); + r = hdnode_public_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(fingerprint, 0x6a19cfb3); + ck_assert_mem_eq(node.chain_code, fromhex("dcfe00831741a3a4803955147cdfc7053d69b167b1d03b5f9e63934217a005fd"), 32); + ck_assert_mem_eq(node.public_key, fromhex("029555ea7bde276cd2c42c4502f40b5d16469fb310ae3aeee2a9000455f41b0866"), 33); + hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, sizeof(str)); + ck_assert_str_eq(str, "dpubZHJs2Z3PtHbbpaXQCi5wBKPhU8tC5ztBKUYBCYNGKk8eZ1EmBs3MhnLJbxHFMAahGnDnZT7qZxC7AXKP8PB6BDNUZgkG77moNMRmXyQ6s6s"); + r = hdnode_deserialize(str, DECRED_VERSION_PUBLIC, DECRED_VERSION_PRIVATE, SECP256K1_DECRED_NAME, &node2, NULL); ck_assert_int_eq(r, 0); + ck_assert_mem_eq(&node2, &node, sizeof(HDNode)); +} +END_TEST + +START_TEST(test_ecdsa_signature) +{ + int res; + uint8_t digest[32]; + uint8_t pubkey[65]; + const ecdsa_curve *curve = &secp256k1; + + + // sha2(sha2("\x18Bitcoin Signed Message:\n\x0cHello World!")) + memcpy(digest, fromhex("de4e9524586d6fce45667f9ff12f661e79870c4105fa0fb58af976619bb11432"), 32); + // r = 2: Four points should exist + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 0); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("043fc5bf5fec35b6ffe6fd246226d312742a8c296bfa57dd22da509a2e348529b7ddb9faf8afe1ecda3c05e7b2bda47ee1f5a87e952742b22afca560b29d972fcf"), 65); + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 1); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("0456d8089137b1fd0d890f8c7d4a04d0fd4520a30b19518ee87bd168ea12ed8090329274c4c6c0d9df04515776f2741eeffc30235d596065d718c3973e19711ad0"), 65); + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 2); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("04cee0e740f41aab39156844afef0182dea2a8026885b10454a2d539df6f6df9023abfcb0f01c50bef3c0fa8e59a998d07441e18b1c60583ef75cc8b912fb21a15"), 65); + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 3); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("0490d2bd2e9a564d6e1d8324fc6ad00aa4ae597684ecf4abea58bdfe7287ea4fa72968c2e5b0b40999ede3d7898d94e82c3f8dc4536a567a4bd45998c826a4c4b2"), 65); + + memcpy(digest, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + // r = 7: No point P with P.x = 7, but P.x = (order + 7) exists + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000070123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 2); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("044d81bb47a31ffc6cf1f780ecb1e201ec47214b651650867c07f13ad06e12a1b040de78f8dbda700f4d3cd7ee21b3651a74c7661809699d2be7ea0992b0d39797"), 65); + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000070123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 3); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("044d81bb47a31ffc6cf1f780ecb1e201ec47214b651650867c07f13ad06e12a1b0bf21870724258ff0b2c32811de4c9ae58b3899e7f69662d41815f66c4f2c6498"), 65); + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000070123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 0); + ck_assert_int_eq(res, 1); + + memcpy(digest, fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), 32); + // r = 1: Two points P with P.x = 1, but P.x = (order + 7) doesn't exist + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000010123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 0); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("045d330b2f89dbfca149828277bae852dd4aebfe136982cb531a88e9e7a89463fe71519f34ea8feb9490c707f14bc38c9ece51762bfd034ea014719b7c85d2871b"), 65); + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000010123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 1); + ck_assert_int_eq(res, 0); + ck_assert_mem_eq(pubkey, fromhex("049e609c3950e70d6f3e3f3c81a473b1d5ca72739d51debdd80230ae80cab05134a94285375c834a417e8115c546c41da83a263087b79ef1cae25c7b3c738daa2b"), 65); + + // r = 0 is always invalid + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000010123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 2); + ck_assert_int_eq(res, 1); + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 0); + ck_assert_int_eq(res, 1); + // r >= order is always invalid + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 0); + ck_assert_int_eq(res, 1); + // check that overflow of r is handled + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("000000000000000000000000000000014551231950B75FC4402DA1722FC9BAEE0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), digest, 2); + ck_assert_int_eq(res, 1); + // s = 0 is always invalid + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000"), digest, 0); + ck_assert_int_eq(res, 1); + // s >= order is always invalid + res = ecdsa_verify_digest_recover(curve, pubkey, fromhex("0000000000000000000000000000000000000000000000000000000000000002fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"), digest, 0); + ck_assert_int_eq(res, 1); +} +END_TEST + +#define test_deterministic(KEY, MSG, K) do { \ + sha256_Raw((uint8_t *)MSG, strlen(MSG), buf); \ + init_rfc6979(fromhex(KEY), buf, &rng); \ + generate_k_rfc6979(&k, &rng); \ + bn_write_be(&k, buf); \ + ck_assert_mem_eq(buf, fromhex(K), 32); \ +} while (0) + +START_TEST(test_rfc6979) +{ + bignum256 k; + uint8_t buf[32]; + rfc6979_state rng; + + test_deterministic("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721", "sample", "a6e3c57dd01abe90086538398355dd4c3b17aa873382b0f24d6129493d8aad60"); + test_deterministic("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50", "sample", "2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3"); + test_deterministic("0000000000000000000000000000000000000000000000000000000000000001", "Satoshi Nakamoto", "8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15"); + test_deterministic("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "Satoshi Nakamoto", "33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90"); + test_deterministic("f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181", "Alan Turing", "525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1"); + test_deterministic("0000000000000000000000000000000000000000000000000000000000000001", "All those moments will be lost in time, like tears in rain. Time to die...", "38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3"); + test_deterministic("e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2", "There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!", "1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d"); +} +END_TEST + +// test vectors from http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors +START_TEST(test_aes) +{ + aes_encrypt_ctx ctxe; + aes_decrypt_ctx ctxd; + uint8_t ibuf[16], obuf[16], iv[16], cbuf[16]; + const char **ivp, **plainp, **cipherp; + + // ECB + static const char *ecb_vector[] = { + // plain cipher + "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8", + "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870", + "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d", + "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7", + 0, 0, + }; + plainp = ecb_vector; + cipherp = ecb_vector + 1; + while (*plainp && *cipherp) { + // encrypt + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + memcpy(ibuf, fromhex(*plainp), 16); + aes_ecb_encrypt(ibuf, obuf, 16, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); + // decrypt + aes_decrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxd); + memcpy(ibuf, fromhex(*cipherp), 16); + aes_ecb_decrypt(ibuf, obuf, 16, &ctxd); + ck_assert_mem_eq(obuf, fromhex(*plainp), 16); + plainp += 2; cipherp += 2; + } + + // CBC + static const char *cbc_vector[] = { + // iv plain cipher + "000102030405060708090A0B0C0D0E0F", "6bc1bee22e409f96e93d7e117393172a", "f58c4c04d6e5f1ba779eabfb5f7bfbd6", + "F58C4C04D6E5F1BA779EABFB5F7BFBD6", "ae2d8a571e03ac9c9eb76fac45af8e51", "9cfc4e967edb808d679f777bc6702c7d", + "9CFC4E967EDB808D679F777BC6702C7D", "30c81c46a35ce411e5fbc1191a0a52ef", "39f23369a9d9bacfa530e26304231461", + "39F23369A9D9BACFA530E26304231461", "f69f2445df4f9b17ad2b417be66c3710", "b2eb05e2c39be9fcda6c19078c6a9d1b", + 0, 0, 0, + }; + ivp = cbc_vector; + plainp = cbc_vector + 1; + cipherp = cbc_vector + 2; + while (*plainp && *cipherp) { + // encrypt + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + memcpy(iv, fromhex(*ivp), 16); + memcpy(ibuf, fromhex(*plainp), 16); + aes_cbc_encrypt(ibuf, obuf, 16, iv, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); + // decrypt + aes_decrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxd); + memcpy(iv, fromhex(*ivp), 16); + memcpy(ibuf, fromhex(*cipherp), 16); + aes_cbc_decrypt(ibuf, obuf, 16, iv, &ctxd); + ck_assert_mem_eq(obuf, fromhex(*plainp), 16); + ivp += 3; plainp += 3; cipherp += 3; + } + + // CFB + static const char *cfb_vector[] = { + "000102030405060708090A0B0C0D0E0F", "6bc1bee22e409f96e93d7e117393172a", "DC7E84BFDA79164B7ECD8486985D3860", + "DC7E84BFDA79164B7ECD8486985D3860", "ae2d8a571e03ac9c9eb76fac45af8e51", "39ffed143b28b1c832113c6331e5407b", + "39FFED143B28B1C832113C6331E5407B", "30c81c46a35ce411e5fbc1191a0a52ef", "df10132415e54b92a13ed0a8267ae2f9", + "DF10132415E54B92A13ED0A8267AE2F9", "f69f2445df4f9b17ad2b417be66c3710", "75a385741ab9cef82031623d55b1e471", + 0, 0, 0, + }; + ivp = cfb_vector; + plainp = cfb_vector + 1; + cipherp = cfb_vector + 2; + while (*plainp && *cipherp) { + // encrypt + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + memcpy(iv, fromhex(*ivp), 16); + memcpy(ibuf, fromhex(*plainp), 16); + aes_cfb_encrypt(ibuf, obuf, 16, iv, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); + // decrypt (uses encryption) + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + memcpy(iv, fromhex(*ivp), 16); + memcpy(ibuf, fromhex(*cipherp), 16); + aes_cfb_decrypt(ibuf, obuf, 16, iv, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*plainp), 16); + ivp += 3; plainp += 3; cipherp += 3; + } + + // OFB + static const char *ofb_vector[] = { + "000102030405060708090A0B0C0D0E0F", "6bc1bee22e409f96e93d7e117393172a", "dc7e84bfda79164b7ecd8486985d3860", + "B7BF3A5DF43989DD97F0FA97EBCE2F4A", "ae2d8a571e03ac9c9eb76fac45af8e51", "4febdc6740d20b3ac88f6ad82a4fb08d", + "E1C656305ED1A7A6563805746FE03EDC", "30c81c46a35ce411e5fbc1191a0a52ef", "71ab47a086e86eedf39d1c5bba97c408", + "41635BE625B48AFC1666DD42A09D96E7", "f69f2445df4f9b17ad2b417be66c3710", "0126141d67f37be8538f5a8be740e484", + 0, 0, 0, + }; + ivp = ofb_vector; + plainp = ofb_vector + 1; + cipherp = ofb_vector + 2; + while (*plainp && *cipherp) { + // encrypt + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + memcpy(iv, fromhex(*ivp), 16); + memcpy(ibuf, fromhex(*plainp), 16); + aes_ofb_encrypt(ibuf, obuf, 16, iv, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); + // decrypt (uses encryption) + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + memcpy(iv, fromhex(*ivp), 16); + memcpy(ibuf, fromhex(*cipherp), 16); + aes_ofb_decrypt(ibuf, obuf, 16, iv, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*plainp), 16); + ivp += 3; plainp += 3; cipherp += 3; + } + + // CTR + static const char *ctr_vector[] = { + // plain cipher + "6bc1bee22e409f96e93d7e117393172a", "601ec313775789a5b7a7f504bbf3d228", + "ae2d8a571e03ac9c9eb76fac45af8e51", "f443e3ca4d62b59aca84e990cacaf5c5", + "30c81c46a35ce411e5fbc1191a0a52ef", "2b0930daa23de94ce87017ba2d84988d", + "f69f2445df4f9b17ad2b417be66c3710", "dfc9c58db67aada613c2dd08457941a6", + 0, 0, + }; + // encrypt + plainp = ctr_vector; + cipherp = ctr_vector + 1; + memcpy(cbuf, fromhex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 16); + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + while (*plainp && *cipherp) { + memcpy(ibuf, fromhex(*plainp), 16); + aes_ctr_encrypt(ibuf, obuf, 16, cbuf, aes_ctr_cbuf_inc, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); + plainp += 2; cipherp += 2; + } + // decrypt (uses encryption) + plainp = ctr_vector; + cipherp = ctr_vector + 1; + memcpy(cbuf, fromhex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 16); + aes_encrypt_key256(fromhex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), &ctxe); + while (*plainp && *cipherp) { + memcpy(ibuf, fromhex(*cipherp), 16); + aes_ctr_decrypt(ibuf, obuf, 16, cbuf, aes_ctr_cbuf_inc, &ctxe); + ck_assert_mem_eq(obuf, fromhex(*plainp), 16); + plainp += 2; cipherp += 2; + } +} +END_TEST + +#define TEST1 "abc" +#define TEST2_1 \ + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" +#define TEST2_2a \ + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" +#define TEST2_2b \ + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" +#define TEST2_2 TEST2_2a TEST2_2b +#define TEST3 "a" /* times 1000000 */ +#define TEST4a "01234567012345670123456701234567" +#define TEST4b "01234567012345670123456701234567" + /* an exact multiple of 512 bits */ +#define TEST4 TEST4a TEST4b /* times 10 */ + +#define TEST7_1 \ + "\x49\xb2\xae\xc2\x59\x4b\xbe\x3a\x3b\x11\x75\x42\xd9\x4a\xc8" +#define TEST8_1 \ + "\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46\xaa\x55\xfe\x75\x71\x46" +#define TEST9_1 \ + "\x65\xf9\x32\x99\x5b\xa4\xce\x2c\xb1\xb4\xa2\xe7\x1a\xe7\x02\x20" \ + "\xaa\xce\xc8\x96\x2d\xd4\x49\x9c\xbd\x7c\x88\x7a\x94\xea\xaa\x10" \ + "\x1e\xa5\xaa\xbc\x52\x9b\x4e\x7e\x43\x66\x5a\x5a\xf2\xcd\x03\xfe" \ + "\x67\x8e\xa6\xa5\x00\x5b\xba\x3b\x08\x22\x04\xc2\x8b\x91\x09\xf4" \ + "\x69\xda\xc9\x2a\xaa\xb3\xaa\x7c\x11\xa1\xb3\x2a" +#define TEST10_1 \ + "\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b\x4f\xba\x15\xa1\xd5\x9f" \ + "\x3f\xd8\x4d\x22\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e\xd1\x15" \ + "\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea\xd2\x44\x21\xde\xd9\xc3\x25\x92" \ + "\xbd\x57\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a\x84\xd0\xcf\x1f" \ + "\x7b\xee\xad\x17\x13\xe2\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04" \ + "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83\x6f\xd5\x56\x2a\x56\xca" \ + "\xb1\xa2\x8e\x81\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8\x6e\x3b" \ + "\x33\xa1\x08\xb0\x53\x07\xc0\x0a\xff\x14\xa7\x68\xed\x73\x50\x60" \ + "\x6a\x0f\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57\x7f\x9b\x38\x80" \ + "\x7c\x7d\x52\x3d\x6d\x79\x2f\x6e\xbc\x24\xa4\xec\xf2\xb3\xa4\x27" \ + "\xcd\xbb\xfb" +#define length(x) (sizeof(x)-1) + +// test vectors from rfc-4634 +START_TEST(test_sha1) +{ + struct { + const char* test; + int length; + int repeatcount; + int extrabits; + int numberExtrabits; + const char* result; + } tests[] = { + /* 1 */ { TEST1, length(TEST1), 1, 0, 0, + "A9993E364706816ABA3E25717850C26C9CD0D89D" }, + /* 2 */ { TEST2_1, length(TEST2_1), 1, 0, 0, + "84983E441C3BD26EBAAE4AA1F95129E5E54670F1" }, + /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, + "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" }, + /* 4 */ { TEST4, length(TEST4), 10, 0, 0, + "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452" }, + /* 5 */ { "", 0, 0, 0x98, 5, + "29826B003B906E660EFF4027CE98AF3531AC75BA" }, + /* 6 */ { "\x5e", 1, 1, 0, 0, + "5E6F80A34A9798CAFC6A5DB96CC57BA4C4DB59C2" }, + /* 7 */ { TEST7_1, length(TEST7_1), 1, 0x80, 3, + "6239781E03729919C01955B3FFA8ACB60B988340" }, + /* 8 */ { TEST8_1, length(TEST8_1), 1, 0, 0, + "82ABFF6605DBE1C17DEF12A394FA22A82B544A35" }, + /* 9 */ { TEST9_1, length(TEST9_1), 1, 0xE0, 3, + "8C5B2A5DDAE5A97FC7F9D85661C672ADBF7933D4" }, + /* 10 */ { TEST10_1, length(TEST10_1), 1, 0, 0, + "CB0082C8F197D260991BA6A460E76E202BAD27B3" } + }; + + for (int i = 0; i < 10; i++) { + SHA1_CTX ctx; + uint8_t digest[SHA1_DIGEST_LENGTH]; + sha1_Init(&ctx); + /* extra bits are not supported */ + if (tests[i].numberExtrabits) + continue; + for (int j = 0; j < tests[i].repeatcount; j++) { + sha1_Update(&ctx, (const uint8_t*) tests[i].test, tests[i].length); + } + sha1_Final(&ctx, digest); + ck_assert_mem_eq(digest, fromhex(tests[i].result), SHA1_DIGEST_LENGTH); + } +} +END_TEST + +#define TEST7_256 \ + "\xbe\x27\x46\xc6\xdb\x52\x76\x5f\xdb\x2f\x88\x70\x0f\x9a\x73" +#define TEST8_256 \ + "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52" +#define TEST9_256 \ + "\x3e\x74\x03\x71\xc8\x10\xc2\xb9\x9f\xc0\x4e\x80\x49\x07\xef\x7c" \ + "\xf2\x6b\xe2\x8b\x57\xcb\x58\xa3\xe2\xf3\xc0\x07\x16\x6e\x49\xc1" \ + "\x2e\x9b\xa3\x4c\x01\x04\x06\x91\x29\xea\x76\x15\x64\x25\x45\x70" \ + "\x3a\x2b\xd9\x01\xe1\x6e\xb0\xe0\x5d\xeb\xa0\x14\xeb\xff\x64\x06" \ + "\xa0\x7d\x54\x36\x4e\xff\x74\x2d\xa7\x79\xb0\xb3" +#define TEST10_256 \ + "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0" \ + "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00" \ + "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77" \ + "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74" \ + "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" \ + "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca" \ + "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4" \ + "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09" \ + "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a" \ + "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" \ + "\x3d\x54\xd6" + +// test vectors from rfc-4634 +START_TEST(test_sha256) +{ + struct { + const char* test; + int length; + int repeatcount; + int extrabits; + int numberExtrabits; + const char* result; + } tests[] = { + /* 1 */ { TEST1, length(TEST1), 1, 0, 0, "BA7816BF8F01CFEA4141" + "40DE5DAE2223B00361A396177A9CB410FF61F20015AD" }, + /* 2 */ { TEST2_1, length(TEST2_1), 1, 0, 0, "248D6A61D20638B8" + "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1" }, + /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, "CDC76E5C9914FB92" + "81A1C7E284D73E67F1809A48A497200E046D39CCC7112CD0" }, + /* 4 */ { TEST4, length(TEST4), 10, 0, 0, "594847328451BDFA" + "85056225462CC1D867D877FB388DF0CE35F25AB5562BFBB5" }, + /* 5 */ { "", 0, 0, 0x68, 5, "D6D3E02A31A84A8CAA9718ED6C2057BE" + "09DB45E7823EB5079CE7A573A3760F95" }, + /* 6 */ { "\x19", 1, 1, 0, 0, "68AA2E2EE5DFF96E3355E6C7EE373E3D" + "6A4E17F75F9518D843709C0C9BC3E3D4" }, + /* 7 */ { TEST7_256, length(TEST7_256), 1, 0x60, 3, "77EC1DC8" + "9C821FF2A1279089FA091B35B8CD960BCAF7DE01C6A7680756BEB972" }, + /* 8 */ { TEST8_256, length(TEST8_256), 1, 0, 0, "175EE69B02BA" + "9B58E2B0A5FD13819CEA573F3940A94F825128CF4209BEABB4E8" }, + /* 9 */ { TEST9_256, length(TEST9_256), 1, 0xA0, 3, "3E9AD646" + "8BBBAD2AC3C2CDC292E018BA5FD70B960CF1679777FCE708FDB066E9" }, + /* 10 */ { TEST10_256, length(TEST10_256), 1, 0, 0, "97DBCA7D" + "F46D62C8A422C941DD7E835B8AD3361763F7E9B2D95F4F0DA6E1CCBC" }, + }; + + for (int i = 0; i < 10; i++) { + SHA256_CTX ctx; + uint8_t digest[SHA256_DIGEST_LENGTH]; + sha256_Init(&ctx); + /* extra bits are not supported */ + if (tests[i].numberExtrabits) + continue; + for (int j = 0; j < tests[i].repeatcount; j++) { + sha256_Update(&ctx, (const uint8_t*) tests[i].test, tests[i].length); + } + sha256_Final(&ctx, digest); + ck_assert_mem_eq(digest, fromhex(tests[i].result), SHA256_DIGEST_LENGTH); + } +} +END_TEST + +#define TEST7_512 \ + "\x08\xec\xb5\x2e\xba\xe1\xf7\x42\x2d\xb6\x2b\xcd\x54\x26\x70" +#define TEST8_512 \ + "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0" +#define TEST9_512 \ + "\x3a\xdd\xec\x85\x59\x32\x16\xd1\x61\x9a\xa0\x2d\x97\x56\x97\x0b" \ + "\xfc\x70\xac\xe2\x74\x4f\x7c\x6b\x27\x88\x15\x10\x28\xf7\xb6\xa2" \ + "\x55\x0f\xd7\x4a\x7e\x6e\x69\xc2\xc9\xb4\x5f\xc4\x54\x96\x6d\xc3" \ + "\x1d\x2e\x10\xda\x1f\x95\xce\x02\xbe\xb4\xbf\x87\x65\x57\x4c\xbd" \ + "\x6e\x83\x37\xef\x42\x0a\xdc\x98\xc1\x5c\xb6\xd5\xe4\xa0\x24\x1b" \ + "\xa0\x04\x6d\x25\x0e\x51\x02\x31\xca\xc2\x04\x6c\x99\x16\x06\xab" \ + "\x4e\xe4\x14\x5b\xee\x2f\xf4\xbb\x12\x3a\xab\x49\x8d\x9d\x44\x79" \ + "\x4f\x99\xcc\xad\x89\xa9\xa1\x62\x12\x59\xed\xa7\x0a\x5b\x6d\xd4" \ + "\xbd\xd8\x77\x78\xc9\x04\x3b\x93\x84\xf5\x49\x06" +#define TEST10_512 \ + "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31" \ + "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde" \ + "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4" \ + "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2" \ + "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" \ + "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95" \ + "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65" \ + "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f" \ + "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41" \ + "\x9c\xc4\x12\x8b\xe9\xa0\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28" \ + "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13\x2e\x9a\x0d\xc6\xd3\xb1" \ + "\xf8\xb2\x46\xf1\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20\x98\xe8" \ + "\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f\x47\x07\xfe\x1e\xa1\xa1\x79\x1b" \ + "\xa2\xf3\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9\x49\xad\x47\xd7" \ + "\xfb\x40\xd2" + +// test vectors from rfc-4634 +START_TEST(test_sha512) +{ + struct { + const char* test; + int length; + int repeatcount; + int extrabits; + int numberExtrabits; + const char* result; + } tests[] = { + /* 1 */ { TEST1, length(TEST1), 1, 0, 0, + "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2" + "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD" + "454D4423643CE80E2A9AC94FA54CA49F" }, + /* 2 */ { TEST2_2, length(TEST2_2), 1, 0, 0, + "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1" + "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A" + "C7D329EEB6DD26545E96E55B874BE909" }, + /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, + "E718483D0CE769644E2E42C7BC15B4638E1F98B13B204428" + "5632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31B" + "EB009C5C2C49AA2E4EADB217AD8CC09B" }, + /* 4 */ { TEST4, length(TEST4), 10, 0, 0, + "89D05BA632C699C31231DED4FFC127D5A894DAD412C0E024" + "DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF33C765CB51" + "0813A39CD5A84C4ACAA64D3F3FB7BAE9" }, + /* 5 */ { "", 0, 0, 0xB0, 5, + "D4EE29A9E90985446B913CF1D1376C836F4BE2C1CF3CADA0" + "720A6BF4857D886A7ECB3C4E4C0FA8C7F95214E41DC1B0D2" + "1B22A84CC03BF8CE4845F34DD5BDBAD4" }, + /* 6 */ { "\xD0", 1, 1, 0, 0, + "9992202938E882E73E20F6B69E68A0A7149090423D93C81B" + "AB3F21678D4ACEEEE50E4E8CAFADA4C85A54EA8306826C4A" + "D6E74CECE9631BFA8A549B4AB3FBBA15" }, + /* 7 */ { TEST7_512, length(TEST7_512), 1, 0x80, 3, + "ED8DC78E8B01B69750053DBB7A0A9EDA0FB9E9D292B1ED71" + "5E80A7FE290A4E16664FD913E85854400C5AF05E6DAD316B" + "7359B43E64F8BEC3C1F237119986BBB6" }, + /* 8 */ { TEST8_512, length(TEST8_512), 1, 0, 0, + "CB0B67A4B8712CD73C9AABC0B199E9269B20844AFB75ACBD" + "D1C153C9828924C3DDEDAAFE669C5FDD0BC66F630F677398" + "8213EB1B16F517AD0DE4B2F0C95C90F8" }, + /* 9 */ { TEST9_512, length(TEST9_512), 1, 0x80, 3, + "32BA76FC30EAA0208AEB50FFB5AF1864FDBF17902A4DC0A6" + "82C61FCEA6D92B783267B21080301837F59DE79C6B337DB2" + "526F8A0A510E5E53CAFED4355FE7C2F1" }, + /* 10 */ { TEST10_512, length(TEST10_512), 1, 0, 0, + "C665BEFB36DA189D78822D10528CBF3B12B3EEF726039909" + "C1A16A270D48719377966B957A878E720584779A62825C18" + "DA26415E49A7176A894E7510FD1451F5" } + }; + + for (int i = 0; i < 10; i++) { + SHA512_CTX ctx; + uint8_t digest[SHA512_DIGEST_LENGTH]; + sha512_Init(&ctx); + /* extra bits are not supported */ + if (tests[i].numberExtrabits) + continue; + for (int j = 0; j < tests[i].repeatcount; j++) { + sha512_Update(&ctx, (const uint8_t*) tests[i].test, tests[i].length); + } + sha512_Final(&ctx, digest); + ck_assert_mem_eq(digest, fromhex(tests[i].result), SHA512_DIGEST_LENGTH); + } +} +END_TEST + +// test vectors from http://www.di-mgt.com.au/sha_testvectors.html +START_TEST(test_sha3_256) +{ + uint8_t digest[SHA3_256_DIGEST_LENGTH]; + + sha3_256((uint8_t *)"", 0, digest); + ck_assert_mem_eq(digest, fromhex("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"), SHA3_256_DIGEST_LENGTH); + + sha3_256((uint8_t *)"abc", 3, digest); + ck_assert_mem_eq(digest, fromhex("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"), SHA3_256_DIGEST_LENGTH); + + sha3_256((uint8_t *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, digest); + ck_assert_mem_eq(digest, fromhex("41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376"), SHA3_256_DIGEST_LENGTH); + + sha3_256((uint8_t *)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, digest); + ck_assert_mem_eq(digest, fromhex("916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18"), SHA3_256_DIGEST_LENGTH); +} +END_TEST + +// test vectors from http://www.di-mgt.com.au/sha_testvectors.html +START_TEST(test_sha3_512) +{ + uint8_t digest[SHA3_512_DIGEST_LENGTH]; + + sha3_512((uint8_t *)"", 0, digest); + ck_assert_mem_eq(digest, fromhex("a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"), SHA3_512_DIGEST_LENGTH); + + sha3_512((uint8_t *)"abc", 3, digest); + ck_assert_mem_eq(digest, fromhex("b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"), SHA3_512_DIGEST_LENGTH); + + sha3_512((uint8_t *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, digest); + ck_assert_mem_eq(digest, fromhex("04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e"), SHA3_512_DIGEST_LENGTH); + + sha3_512((uint8_t *)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, digest); + ck_assert_mem_eq(digest, fromhex("afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185"), SHA3_512_DIGEST_LENGTH); +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/0.test-sha3-256.dat +START_TEST(test_keccak_256) +{ + static const struct { + const char *hash; + size_t length; + const char *data; + } tests[] = { + { "4e9e79ab7434f6c7401fb3305d55052ee829b9e46d5d05d43b59fefb32e9a619", 293, "a6151d4904e18ec288243028ceda30556e6c42096af7150d6a7232ca5dba52bd2192e23daa5fa2bea3d4bd95efa2389cd193fcd3376e70a5c097b32c1c62c80af9d710211545f7cdddf63747420281d64529477c61e721273cfd78f8890abb4070e97baa52ac8ff61c26d195fc54c077def7a3f6f79b36e046c1a83ce9674ba1983ec2fb58947de616dd797d6499b0385d5e8a213db9ad5078a8e0c940ff0cb6bf92357ea5609f778c3d1fb1e7e36c35db873361e2be5c125ea7148eff4a035b0cce880a41190b2e22924ad9d1b82433d9c023924f2311315f07b88bfd42850047bf3be785c4ce11c09d7e02065d30f6324365f93c5e7e423a07d754eb314b5fe9db4614275be4be26af017abdc9c338d01368226fe9af1fb1f815e7317bdbb30a0f36dc69", }, + { "c1268babc42d00c3463dc388222100f7e525a74a64665c39f112f788ddb5da42", 376, "9db801077952c2324e0044a4994edfb09b3edfcf669bfdd029f4bf42d5b0eab3056b0bf82708ca7bfadba43c9de806b10a19d0f00c2351ef1086b6b108f306e035c6b61b2e70fd7087ba848601c8a3f626a66666423717ef305a1068bfa3a1f7ffc1e5a78cb6182ffc8a577ca2a821630bf900d0fbba848bdf94b77c5946771b6c3f8c02269bc772ca56098f724536d96be68c284ee1d81697989d40029b8ea63ac1fd85f8b3cae8b194f6834ff65a5858f9498ddbb467995eb2d49cdfc6c05d92038c6e9aaeee85f8222b3784165f12a2c3df4c7a142e26dddfd831d07e22dfecc0eded48a69c8a9e1b97f1a4e0efcd4edd310de0edf82af38a6e4d5ab2a19da586e61210d4f75e7a07e2201f9c8154ca52a414a70d2eb2ac1c5b9a2900b4d871f62fa56f70d03b3dd3704bd644808c45a13231918ea884645b8ec054e8bab2935a66811fe590ddc119ae901dfeb54fc2a87c1e0a236778baab2fa8843709c6676d3c1888ba19d75ec52d73a7d035c143179b93823726b7", }, + { "e83b50e8c83cb676a7dd64c055f53e5110d5a4c62245ceb8f683fd87b2b3ec77", 166, "c070a957550b7b34113ee6543a1918d96d241f27123425db7f7b9004e047ffbe05612e7fa8c54b23c83ea427e625e97b7a28b09a70bf6d91e478eeed01d7907931c29ea86e70f2cdcfb243ccf7f24a1619abf4b5b9e6f75cbf63fc02baf4a820a9790a6b053e50fd94e0ed57037cfc2bab4d95472b97d3c25f434f1cc0b1ede5ba7f15907a42a223933e5e2dfcb518c3531975268c326d60fa911fbb7997eee3ba87656c4fe7", }, + { "8ebd2c9d4ff00e285a9b6b140bfc3cef672016f0098100e1f6f250220af7ce1a", 224, "b502fbdce4045e49e147eff5463d4b3f37f43461518868368e2c78008c84c2db79d12b58107034f67e7d0abfee67add0342dd23dce623f26b9156def87b1d7ac15a6e07301f832610fe869ada13a2b0e3d60aa6bb81bc04487e2e800f5106b0402ee0331df745e021b5ea5e32faf1c7fc1322041d221a54191c0af19948b5f34411937182e30d5cd39b5a6c959d77d92d21bb1de51f1b3411cb6eec00600429916227fb62d2c88e69576f4ac8e5efcde8efa512cc80ce7fb0dfaa6c74d26e898cefe9d4f7dce232a69f2a6a9477aa08366efcdfca117c89cb79eba15a23755e0", }, + { "db3961fdddd0c314289efed5d57363459a6700a7bd015e7a03d3e1d03f046401", 262, "22e203a98ba2c43d8bc3658f0a48a35766df356d6a5e98b0c7222d16d85a00b317207d4aef3fc7cabb67b9d8f5838de0b733e1fd59c31f0667e53286972d7090421ad90d54db2ea40047d0d1700c86f53dbf48da532396307e68edad877dcae481848801b0a5db44dbdba6fc7c63b5cd15281d57ca9e6be96f530b209b59d6127ad2bd8750f3f80798f62521f0d5b42633c2f5a9aaefbed38779b7aded2338d66850b0bb0e33c48e040c99f2dcee7a7ebb3d7416e1c5bf038c19d09682dab67c96dbbfad472e45980aa27d1b301b15f7de4d4f549bad2501931c9d4f1a3b1692dcb4b1b834ddd4a636126702307ddaeec61841693b21887d56e76cc2069dafb557fd6682160f", }, + { "25dd3acacd6bf688c0eace8d33eb7cc550271969142deb769a05b4012f7bb722", 122, "99e7f6e0ed46ec866c43a1ab494998d47e9309a79fde2a629eb63bb2160a5ffd0f2206de9c32dd20e9b23e57ab7422cf82971cc2873ec0e173fe93281c7b33e1c76ac79223a6f435f230bdd30260c00d00986c72a399d3ba70f6e783d834bbf8a6127844def559b8b6db742b2cfd715f7ff29e7b42bf7d567beb", }, + { "00d747c9045c093484290afc161437f11c2ddf5f8a9fc2acae9c7ef5fcf511e5", 440, "50c392f97f8788377f0ab2e2aab196cb017ad157c6f9d022673d39072cc198b06622a5cbd269d1516089fa59e28c3373a92bd54b2ebf1a79811c7e40fdd7bce200e80983fda6e77fc44c44c1b5f87e01cef2f41e1141103f73364e9c2f25a4597e6517ef31b316300b770c69595e0fa6d011df1566a8676a88c7698562273bbfa217cc69d4b5c89a8907b902f7dc14481fefc7da4a810c15a60f5641aae854d2f8cc50cbc393015560f01c94e0d0c075dbcb150ad6eba29dc747919edcaf0231dba3eb3f2b1a87e136a1f0fd4b3d8ee61bad2729e9526a32884f7bcfa41e361add1b4c51dc81463528372b4ec321244de0c541ba00df22b8773cdf4cf898510c867829fa6b4ff11f9627338b9686d905cb7bcdf085080ab842146e0035c808be58cce97827d8926a98bd1ff7c529be3bc14f68c91b2ca4d2f6fc748f56bcf14853b7f8b9aa6d388f0fd82f53fdc4bacf9d9ba10a165f404cf427e199f51bf6773b7c82531e17933f6d8b8d9181e22f8921a2dbb20fc7c8023a87e716e245017c399d0942934f5e085219b3f8d26a196bf8b239438b8e561c28a61ff08872ecb052c5fcb19e2fdbc09565924a50ebee1461c4b414219d4257", }, + { "dadcde7c3603ef419d319ba3d50cf00ad57f3e81566fd11b9b6f461cbb9dcb0f", 338, "18e1df97abccc91e07dc7b7ffab5ee8919d5610721453176aa2089fb96d9a477e1476f507fa1129f04304e960e8017ff41246cacc0153055fc4b1dc6168a74067ebb077cb5aa80a9df6e8b5b821e906531159668c4c164b9e511d8724aedbe17c1f41da8809417d3c30b79ea5a2e3c961f6bac5436d9af6be24a36eebcb17863fed82c0eb8962339eb612d58659dddd2ea06a120b3a2d8a17050be2de367db25a5bef4290c209bdb4c16c4df5a1fe1ead635169a1c35f0a56bc07bcf6ef0e4c2d8573ed7a3b58030fa268c1a5974b097288f01f34d5a1087946410688016882c6c7621aad680d9a25c7a3e5dbcbb07ffdb7243b91031c08a121b40785e96b7ee46770c760f84aca8f36b7c7da64d25c8f73b4d88ff3acb7eeefc0b75144dffea66d2d1f6b42b905b61929ab3f38538393ba5ca9d3c62c61f46fa63789cac14e4e1d8722bf03cceef6e3de91f783b0072616c", }, + { "d184e84a2507fc0f187b640dd5b849a366c0383d9cbdbc6fa30904f054111255", 141, "13b8df9c1bcfddd0aa39b3055f52e2bc36562b6677535994b173f07041d141699db42589d6091ef0e71b645b41ab57577f58c98da966562d24823158f8e1d43b54edea4e61dd66fe8c59ad8405f5a0d9a3eb509a77ae3d8ae4adf926fd3d8d31c3dcccfc140814541010937024cc554e1daaee1b333a66316e7fbebb07ac8dfb134a918b9090b14168012c4824", }, + { "20c19635364a00b151d0168fe5ae03bac6dd7d06030475b40d2e8c577a192f53", 84, "e1e96da4b7d8dcc2b316006503a990ea26a5b200cb7a7edfc14f5ce827f06d8d232ec95b1acdc1422ffc16da11d258f0c7b378f026d64c74b2fb41df8bfd3cd30066caecdc6f76c8163de9309d9fd0cf33d54a29", }, + { "86cc2c428d469e43fb4ee8d38dffbf5128d20d1659dbc45edf4a855399ca730e", 319, "30391840ad14e66c53e1a5aaa03989ff059940b60c44c3b21295a93d023f2e6c7cdcf60208b7d87a7605fb5cee94630d94cad90bc6955328357fa37fea47c09f9cee759c31537187321c7d572e3554eeb90f441a9494575454dfbf8cfd86128da15de9418821ca158856eb84ff6a29a2c8380711e9e6d4955388374fcd3c1ca45b49e0679fc7157f96bc6e4f86ce20a89c12d4449b1ca7056e0b7296fc646f68f6ddbfa6a48e384d63ab68bc75fd69a2add59b8e41c4a0f753935df9a703d7df82a430798b0a67710a78061485a9d15de16f154582082459b4462485ce8a82d35ac6b9498ae40df3a23d5f00e0e86661cb02c52f677fd374c32969ec63028b5dd2c1d4bce67a6d9f79ba5e7eeb5a2763dc9fe2a05aa2ebaad36aaec2541e343a677fb4e6b6a180eff33c93744a4624f6a79f054c6c9e9c5b6928dbe7ba5fca", }, + { "e80eee72a76e6957f7cb7f68c41b92f0ad9aac6e58aa8fc272c1e7364af11c70", 108, "3c210ed15889ae938781d2cebd49d4a8007f163ffba1f7669bccdccf6ad5a1418299d5f4348f5cd03b0ba9e6999ab154e46836c3546feb395d17bcc60f23d7ba0e8efe6aa616c00b6bf552fe1cb5e28e3e7bc39dfc20c63ae3901035e91ddd110e43fe59ed744beeedb6bc1e", }, + { "f971bbae97dd8a034835269fb246867de358a889de6de13672e771d6fb4c89b7", 468, "64e9a3a99c021df8bea59368cfe1cd3b0a4aca33ffcd5cf6028d9307c0b904b8037d056a3c12803f196f74c4d360a3132452d365922b1157e5b0d76f91fb94bebfdcb4d50fa23ed5be3d3c5712219e8666debc8abcd5e6c69a542761a6cbbd1b3c0f0524875204b64d2788465f90cb19b6f6da9f8bec6d6e684196e713549ec83e47cbaeff77838ac4936b312562e2de17c970449d49d214ec2597c6d4f642e6c94a613a0c53285abccd7794a3d72241808594fb4e6e4d5d2c310ef1cdcbfd34805ca2408f554797a6cfd49d0f25ed8927f206acb127e6436e1234902489ec2e7f3058e26c0eba80341bc7ad0da8b8bd80bd1b43c9099269e3f8b68445c69b79d8cf5693d4a0d47a44f9e9114dbb33992d2ea9d3b5b86e4ea57a44a638848de4ac365bb6bb7855305ade62b07ebf0954d70b7c2fb5e6fcc154c7a36fb1756df5f20a84d35696627ebf22d44f40f805c0878ad110bc17dcd66821084ca87902e05bc0afa61161086956b85a6ea900d35c7784d4c361a43fe294e267d5762408be58962cdb4f45a9c0efd7d2335916df3acb98ccfbcf5ee39530540e5f3d3c5f3326a9a536d7bfa37aae2b143e2499b81bf0670e3a418c26c7dc82b293d9bd182dd6435670514237df88d8286e19ce93e0a0db2790", }, + { "b97fd51f4e4eaa40c7a2853010fc46be5be2f43b9520ea0c533b68f728c978a2", 214, "ced3a43193caceb269d2517f4ecb892bb7d57d7201869e28e669b0b17d1c44d286e02734e2210ea9009565832975cc6303b9b6008fe1165b99ae5f1b29962ef042ebad8b676d7433ed2fe0d0d6f4f32b2cb4c519da61552328c2caea799bb2fd907308173a1cd2b798fb0df7d2eaf2ff0be733af74f42889e211843fc80b09952ae7eb246725b91d31c1f7a5503fdf3bc9c269c76519cf2dc3225e862436b587bb74adbad88c773056cfea3bddb1f6533c01125eeae0986e5c817359912c9d0472bf8320b824ee097f82a8e05b9f53a5be7d153225de", }, + { "f0fecf766e4f7522568b3be71843cce3e5fcb10ea96b1a236c8c0a71c9ad55c9", 159, "8aca4de41275f5c4102f66266d70cff1a2d56f58df8d12061c64cb6cd8f616a5bf19c2bb3c91585c695326f561a2d0eb4eef2e202d82dcc9089e4bee82b62a199a11963cd08987d3abd5914def2cdd3c1e4748d46b654f338e3959121e869c18d5327e88090d0ba0ac6762a2b14514cc505af7499f1a22f421dbe978494f9ffe1e88f1c59228f21da5bc9fcc911d022300a443bca17258bdd6cfbbf52fde61", }, + { "5c4f16043c0084bf98499fc7dc4d674ce9c730b7135210acdbf5e41d3dcf317b", 87, "01bbc193d0ee2396a7d8267ad63f18149667b31d8f7f48c8bb0c634755febc9ef1a79e93c475f6cd137ee37d4dc243ea2fdcdc0d098844af2208337b7bbf6930e39e74e23952ac1a19b4d38b83810a10c3b069e4fafb06", }, + { "14b61fc981f7d9449b7b6a2d57eb48cc8f7896f4dced2005291b2a2f38cb4a63", 358, "cbc1709a531438d5ead32cea20a9e4ddc0101ec555ab42b2e378145013cc05a97b9e2c43c89bfa63ae5e9e9ce1fc022035c6b68f0a906ee1f53396d9dbe41cb2bc4bfeb144b005b0f40e0fec872d9c4aca9929ba3cbacd84c58ab43c26f10d345a24692bbd55a76506876768e8e32a461bf160cee953da88920d36ad4aff6eea7126aa6f44a7a6fce770ce43f0f90a20590bdaad3ffcda30ca8e3700f832c62caa5df030c16bcf74aff492466f781eb69863a80663535fc154abd7cfdd02eef1019221cf608b9780f807e507fbbf559b1dfe4e971b4d08fe45263a3c697ba90f9f71bec97e12438b4b12f6a84ab66872b888097089d76c9c2502d9ed2eece6bef8eee1d439782e218f5cc75d38f9886012cdcb4bbe6caf812e97c5a336bcceae38b1109e3243a291ce23d097aaee7d9a711de6886749a7a6d15d7e7cbc4a51b1b4da9fcf139e4a6fd7dc0bc017db624b17fc9b8f847592ed42467c25ad9fe96acbf20c0ffd18", }, + { "47ec7f3a362becbb110867995a0f066a66152603c4d433f11bf51870c67e2864", 354, "0636983353c9ea3f75256ed00b70e8b7cfc6f4e4c0ba3aa9a8da59b6e6ad9dfb5bc2c49f48cc0b4237f87dedf34b888e54ecebf1d435bcd4aab72eb4ce39e5262fb68c6f86423dac123bf59e903989eda7df4a982822d0831521403cedcfe9a5bbea648bb2e7ef8cd81442ea5abe468b3ee8b06376ef8099447255c2fdc1b73af37fe0e0b852ffbc9339868db756680db99e6e9837dbd28c39a69f229044ad7ec772524a6e01f679d25fdc2e736a2418e5dfd7c2ab1348d0f821b777c975244c6cfc2fca5c36ccae7cf1d07b190a9d17a088a1276bd096250b92f53b29b6ef88ef69d744b56fb2ec5078cc0b68a9106943ef242b466097b9e29df11eb5cb0c06c29d7917410ba1097215d6aa4dafd90adff0c3e7221b9e8832613bd9aca8bcc6b2aa7b43acedcbc11aee1b5ba56f77a210be7cf3485ee813e1126c3eeccd8419bbf22c412cad32cc0fc7a73aca4e379651caac3d13d6cf5ca05508fd2d96f3ad94e7", }, + { "73778e7f1943646a89d3c78909e0afbe584071ba5230546a39cd73e44e36d78a", 91, "6217504a26b3395855eab6ddeb79f2e3490d74b80eff343721150ee0c1c02b07186743589f93c22a03dc5ed29fb5bf592de0a089763e83e5b95f9dd524d66c8da3e04c1814e65e68b2810c1b517648aabc266ad62896c51864a7f4", }, + { "35ef6868e750cf0c1d5285992c231d93ec644670fb79cf85324067a9f77fde78", 185, "0118b7fb15f927a977e0b330b4fa351aeeec299d6ba090eb16e5114fc4a6749e5915434a123c112697390c96ea2c26dc613eb5c75f5ecfb6c419317426367e34da0ddc6d7b7612cefa70a22fea0025f5186593b22449dab71f90a49f7de7352e54e0c0bd8837e661ca2127c3313a7268cafdd5ccfbf3bdd7c974b0e7551a2d96766579ef8d2e1f376af74cd1ab62162fc2dc61a8b7ed4163c1caccf20ed73e284da2ed257ec974eee96b502acb2c60a04886465e44debb0317", }, + }; + + uint8_t hash[SHA3_256_DIGEST_LENGTH]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + keccak_256(fromhex(tests[i].data), tests[i].length, hash); + ck_assert_mem_eq(hash, fromhex(tests[i].hash), SHA3_256_DIGEST_LENGTH); + } +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/monero-project/monero/master/tests/hash/tests-extra-blake.txt +START_TEST(test_blake256) +{ + struct { + const char *hash; + const char *data; + } tests[] = { + { "716f6e863f744b9ac22c97ec7b76ea5f5908bc5b2f67c61510bfc4751384ea7a", "", }, + { "e104256a2bc501f459d03fac96b9014f593e22d30f4de525fa680c3aa189eb4f", "cc", }, + { "8f341148be7e354fdf38b693d8c6b4e0bd57301a734f6fd35cd85b8491c3ddcd", "41fb", }, + { "bc334d1069099f10c601883ac6f3e7e9787c6aa53171f76a21923cc5ad3ab937", "1f877c", }, + { "b672a16f53982bab1e77685b71c0a5f6703ffd46a1c834be69f614bd128d658e", "c1ecfdfc", }, + { "d9134b2899057a7d8d320cc99e3e116982bc99d3c69d260a7f1ed3da8be68d99", "21f134ac57", }, + { "637923bd29a35aa3ecbbd2a50549fc32c14cf0fdcaf41c3194dd7414fd224815", "c6f50bb74e29", }, + { "70c092fd5c8c21e9ef4bbc82a5c7819e262a530a748caf285ff0cba891954f1e", "119713cc83eeef", }, + { "fdf092993edbb7a0dc7ca67f04051bbd14481639da0808947aff8bfab5abed4b", "4a4f202484512526", }, + { "6f6fc234bf35beae1a366c44c520c59ad5aa70351b5f5085e21e1fe2bfcee709", "1f66ab4185ed9b6375", }, + { "4fdaf89e2a0e78c000061b59455e0ea93a4445b440e7562c8f0cfa165c93de2e", "eed7422227613b6f53c9", }, + { "d6b780eee9c811f664393dc2c58b5a68c92b3c9fe9ceb70371d33ece63b5787e", "eaeed5cdffd89dece455f1", }, + { "d0015071d3e7ed048c764850d76406eceae52b8e2e6e5a2c3aa92ae880485b34", "5be43c90f22902e4fe8ed2d3", }, + { "9b0207902f9932f7a85c24722e93e31f6ed2c75c406509aa0f2f6d1cab046ce4", "a746273228122f381c3b46e4f1", }, + { "258020d5b04a814f2b72c1c661e1f5a5c395d9799e5eee8b8519cf7300e90cb1", "3c5871cd619c69a63b540eb5a625", }, + { "4adae3b55baa907fefc253365fdd99d8398befd0551ed6bf9a2a2784d3c304d1", "fa22874bcc068879e8ef11a69f0722", }, + { "6dd10d772f8d5b4a96c3c5d30878cd9a1073fa835bfe6d2b924fa64a1fab1711", "52a608ab21ccdd8a4457a57ede782176", }, + { "0b8741ddf2259d3af2901eb1ae354f22836442c965556f5c1eb89501191cb46a", "82e192e4043ddcd12ecf52969d0f807eed", }, + { "f48a754ca8193a82643150ab94038b5dd170b4ebd1e0751b78cfb0a98fa5076a", "75683dcb556140c522543bb6e9098b21a21e", }, + { "5698409ab856b74d9fa5e9b259dfa46001f89041752da424e56e491577b88c86", "06e4efe45035e61faaf4287b4d8d1f12ca97e5", }, + }; + + uint8_t hash[BLAKE256_DIGEST_LENGTH]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + blake256(fromhex(tests[i].data), i, hash); + ck_assert_mem_eq(hash, fromhex(tests[i].hash), BLAKE256_DIGEST_LENGTH); + } +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/BLAKE2/BLAKE2/master/testvectors/blake2b-kat.txt +START_TEST(test_blake2b) +{ + uint8_t key[BLAKE2B_KEY_LENGTH]; + memcpy(key, fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"), BLAKE2B_KEY_LENGTH); + + uint8_t digest[BLAKE2B_DIGEST_LENGTH]; + + blake2b_Key((uint8_t *)"", 0, key, BLAKE2B_KEY_LENGTH, digest, BLAKE2B_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568"), BLAKE2B_DIGEST_LENGTH); + + blake2b_Key(fromhex("000102"), 3, key, BLAKE2B_KEY_LENGTH, digest, BLAKE2B_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1"), BLAKE2B_DIGEST_LENGTH); + + blake2b_Key(fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637"), 56, key, BLAKE2B_KEY_LENGTH, digest, BLAKE2B_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2"), BLAKE2B_DIGEST_LENGTH); + + blake2b_Key(fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f"), 112, key, BLAKE2B_KEY_LENGTH, digest, BLAKE2B_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f"), BLAKE2B_DIGEST_LENGTH); +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/BLAKE2/BLAKE2/master/testvectors/blake2s-kat.txt +START_TEST(test_blake2s) +{ + uint8_t key[BLAKE2S_KEY_LENGTH]; + memcpy(key, fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), BLAKE2S_KEY_LENGTH); + + uint8_t digest[BLAKE2S_DIGEST_LENGTH]; + + blake2s_Key((uint8_t *)"", 0, key, BLAKE2S_KEY_LENGTH, digest, BLAKE2S_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49"), BLAKE2S_DIGEST_LENGTH); + + blake2s_Key(fromhex("000102"), 3, key, BLAKE2S_KEY_LENGTH, digest, BLAKE2S_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("1d220dbe2ee134661fdf6d9e74b41704710556f2f6e5a091b227697445dbea6b"), BLAKE2S_DIGEST_LENGTH); + + blake2s_Key(fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637"), 56, key, BLAKE2S_KEY_LENGTH, digest, BLAKE2S_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("2966b3cfae1e44ea996dc5d686cf25fa053fb6f67201b9e46eade85d0ad6b806"), BLAKE2S_DIGEST_LENGTH); + + blake2s_Key(fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f"), 112, key, BLAKE2S_KEY_LENGTH, digest, BLAKE2S_DIGEST_LENGTH); + ck_assert_mem_eq(digest, fromhex("90a83585717b75f0e9b725e055eeeeb9e7a028ea7e6cbc07b20917ec0363e38c"), BLAKE2S_DIGEST_LENGTH); +} +END_TEST + +// test vectors from https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors +START_TEST(test_pbkdf2_hmac_sha256) +{ + uint8_t k[40], s[40]; + + strcpy((char *)s, "salt"); + pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 1, k); + ck_assert_mem_eq(k, fromhex("120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b"), 32); + + strcpy((char *)s, "salt"); + pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 2, k); + ck_assert_mem_eq(k, fromhex("ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43"), 32); + + strcpy((char *)s, "salt"); + pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 4096, k); + ck_assert_mem_eq(k, fromhex("c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a"), 32); + + strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt"); + pbkdf2_hmac_sha256((uint8_t *)"passwordPASSWORDpassword", 3*8, s, 9*4, 4096, k); + ck_assert_mem_eq(k, fromhex("348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1"), 32); +} +END_TEST + +// test vectors from http://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors +START_TEST(test_pbkdf2_hmac_sha512) +{ + uint8_t k[64], s[40]; + + strcpy((char *)s, "salt"); + pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 1, k); + ck_assert_mem_eq(k, fromhex("867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce"), 64); + + strcpy((char *)s, "salt"); + pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 2, k); + ck_assert_mem_eq(k, fromhex("e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e"), 64); + + strcpy((char *)s, "salt"); + pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 4096, k); + ck_assert_mem_eq(k, fromhex("d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5"), 64); + + strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt"); + pbkdf2_hmac_sha512((uint8_t *)"passwordPASSWORDpassword", 3*8, s, 9*4, 4096, k); + ck_assert_mem_eq(k, fromhex("8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8"), 64); +} +END_TEST + +START_TEST(test_mnemonic) +{ + static const char *vectors[] = { + "00000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04", + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank yellow", + "2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607", + "80808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage above", + "d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8", + "ffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069", + "000000000000000000000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "035895f2f481b1b0f01fcf8c289c794660b289981a78f8106447707fdd9666ca06da5a9a565181599b79f53b844d8a71dd9f439c52a3d7b3e8a79c906ac845fa", + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "f2b94508732bcbacbcc020faefecfc89feafa6649a5491b8c952cede496c214a0c7b3c392d168748f2d4a612bada0753b52a1c7ac53c1e93abd5c6320b9e95dd", + "808080808080808080808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "107d7c02a5aa6f38c58083ff74f04c607c2d2c0ecc55501dadd72d025b751bc27fe913ffb796f841c49b1d33b610cf0e91d3aa239027f5e99fe4ce9e5088cd65", + "ffffffffffffffffffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "0cd6e5d827bb62eb8fc1e262254223817fd068a74b5b449cc2f667c3f1f985a76379b43348d952e2265b4cd129090758b3e3c2c49103b5051aac2eaeb890a528", + "0000000000000000000000000000000000000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8", + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87", + "8080808080808080808080808080808080808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad", + "77c2b00716cec7213839159e404db50d", + "jelly better achieve collect unaware mountain thought cargo oxygen act hood bridge", + "b5b6d0127db1a9d2226af0c3346031d77af31e918dba64287a1b44b8ebf63cdd52676f672a290aae502472cf2d602c051f3e6f18055e84e4c43897fc4e51a6ff", + "b63a9c59a6e641f288ebc103017f1da9f8290b3da6bdef7b", + "renew stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap", + "9248d83e06f4cd98debf5b6f010542760df925ce46cf38a1bdb4e4de7d21f5c39366941c69e1bdbf2966e0f6e6dbece898a0e2f0a4c2b3e640953dfe8b7bbdc5", + "3e141609b97933b66a060dcddc71fad1d91677db872031e85f4c015c5e7e8982", + "dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic", + "ff7f3184df8696d8bef94b6c03114dbee0ef89ff938712301d27ed8336ca89ef9635da20af07d4175f2bf5f3de130f39c9d9e8dd0472489c19b1a020a940da67", + "0460ef47585604c5660618db2e6a7e7f", + "afford alter spike radar gate glance object seek swamp infant panel yellow", + "65f93a9f36b6c85cbe634ffc1f99f2b82cbb10b31edc7f087b4f6cb9e976e9faf76ff41f8f27c99afdf38f7a303ba1136ee48a4c1e7fcd3dba7aa876113a36e4", + "72f60ebac5dd8add8d2a25a797102c3ce21bc029c200076f", + "indicate race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left", + "3bbf9daa0dfad8229786ace5ddb4e00fa98a044ae4c4975ffd5e094dba9e0bb289349dbe2091761f30f382d4e35c4a670ee8ab50758d2c55881be69e327117ba", + "2c85efc7f24ee4573d2b81a6ec66cee209b2dcbd09d8eddc51e0215b0b68e416", + "clutch control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste", + "fe908f96f46668b2d5b37d82f558c77ed0d69dd0e7e043a5b0511c48c2f1064694a956f86360c93dd04052a8899497ce9e985ebe0c8c52b955e6ae86d4ff4449", + "eaebabb2383351fd31d703840b32e9e2", + "turtle front uncle idea crush write shrug there lottery flower risk shell", + "bdfb76a0759f301b0b899a1e3985227e53b3f51e67e3f2a65363caedf3e32fde42a66c404f18d7b05818c95ef3ca1e5146646856c461c073169467511680876c", + "7ac45cfe7722ee6c7ba84fbc2d5bd61b45cb2fe5eb65aa78", + "kiss carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment", + "ed56ff6c833c07982eb7119a8f48fd363c4a9b1601cd2de736b01045c5eb8ab4f57b079403485d1c4924f0790dc10a971763337cb9f9c62226f64fff26397c79", + "4fa1a8bc3e6d80ee1316050e862c1812031493212b7ec3f3bb1b08f168cabeef", + "exile ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top", + "095ee6f817b4c2cb30a5a797360a81a40ab0f9a4e25ecd672a3f58a0b5ba0687c096a6b14d2c0deb3bdefce4f61d01ae07417d502429352e27695163f7447a8c", + "18ab19a9f54a9274f03e5209a2ac8a91", + "board flee heavy tunnel powder denial science ski answer betray cargo cat", + "6eff1bb21562918509c73cb990260db07c0ce34ff0e3cc4a8cb3276129fbcb300bddfe005831350efd633909f476c45c88253276d9fd0df6ef48609e8bb7dca8", + "18a2e1d81b8ecfb2a333adcb0c17a5b9eb76cc5d05db91a4", + "board blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief", + "f84521c777a13b61564234bf8f8b62b3afce27fc4062b51bb5e62bdfecb23864ee6ecf07c1d5a97c0834307c5c852d8ceb88e7c97923c0a3b496bedd4e5f88a9", + "15da872c95a13dd738fbf50e427583ad61f18fd99f628c417a61cf8343c90419", + "beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + "b15509eaa2d09d3efd3e006ef42151b30367dc6e3aa5e44caba3fe4d3e352e65101fbdb86a96776b91946ff06f8eac594dc6ee1d3e82a42dfe1b40fef6bcc3fd", + 0, + 0, + 0, + }; + + const char **a, **b, **c, *m; + uint8_t seed[64]; + + a = vectors; + b = vectors + 1; + c = vectors + 2; + while (*a && *b && *c) { + m = mnemonic_from_data(fromhex(*a), strlen(*a) / 2); + ck_assert_str_eq(m, *b); + mnemonic_to_seed(m, "TREZOR", seed, 0); + ck_assert_mem_eq(seed, fromhex(*c), strlen(*c) / 2); +#if USE_BIP39_CACHE + // try second time to check whether caching results work + mnemonic_to_seed(m, "TREZOR", seed, 0); + ck_assert_mem_eq(seed, fromhex(*c), strlen(*c) / 2); +#endif + a += 3; b += 3; c += 3; + } +} +END_TEST + +START_TEST(test_mnemonic_check) +{ + static const char *vectors_ok[] = { + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "legal winner thank year wave sausage worth useful legal winner thank yellow", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage above", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "jelly better achieve collect unaware mountain thought cargo oxygen act hood bridge", + "renew stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap", + "dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic", + "afford alter spike radar gate glance object seek swamp infant panel yellow", + "indicate race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left", + "clutch control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste", + "turtle front uncle idea crush write shrug there lottery flower risk shell", + "kiss carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment", + "exile ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top", + "board flee heavy tunnel powder denial science ski answer betray cargo cat", + "board blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief", + "beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + 0, + }; + static const char *vectors_fail[] = { + "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "above winner thank year wave sausage worth useful legal winner thank yellow", + "above advice cage absurd amount doctor acoustic avoid letter advice cage above", + "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "above better achieve collect unaware mountain thought cargo oxygen act hood bridge", + "above stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap", + "above pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic", + "above alter spike radar gate glance object seek swamp infant panel yellow", + "above race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left", + "above control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste", + "above front uncle idea crush write shrug there lottery flower risk shell", + "above carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment", + "above ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top", + "above flee heavy tunnel powder denial science ski answer betray cargo cat", + "above blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief", + "above stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "winner thank year wave sausage worth useful legal winner thank yellow", + "advice cage absurd amount doctor acoustic avoid letter advice cage above", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "better achieve collect unaware mountain thought cargo oxygen act hood bridge", + "stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap", + "pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic", + "alter spike radar gate glance object seek swamp infant panel yellow", + "race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left", + "control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste", + "front uncle idea crush write shrug there lottery flower risk shell", + "carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment", + "ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top", + "flee heavy tunnel powder denial science ski answer betray cargo cat", + "blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief", + "stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + 0, + }; + + const char **m; + int r; + m = vectors_ok; + while (*m) { + r = mnemonic_check(*m); + ck_assert_int_eq(r, 1); + m++; + } + m = vectors_fail; + while (*m) { + r = mnemonic_check(*m); + ck_assert_int_eq(r, 0); + m++; + } +} +END_TEST + +START_TEST(test_address) +{ + char address[36]; + uint8_t pub_key[65]; + + memcpy(pub_key, fromhex("0226659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), 33); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "139MaMHp3Vjo8o4x8N1ZLWEtovLGvBsg6s"); + ecdsa_get_address(pub_key, 111, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "mhfJsQNnrXB3uuYZqvywARTDfuvyjg4RBh"); + ecdsa_get_address(pub_key, 52, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "MxiimznnxsqMfLKTQBL8Z2PoY9jKpjgkCu"); + ecdsa_get_address(pub_key, 48, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "LMNJqZbe89yrPbm7JVzrcXJf28hZ1rKPaH"); + ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "34PyTHn74syS796eTgsyoLfwoBC3cwLn6p"); + + memcpy(pub_key, fromhex("025b1654a0e78d28810094f6c5a96b8efb8a65668b578f170ac2b1f83bc63ba856"), 33); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "19Ywfm3witp6C1yBMy4NRYHY2347WCRBfQ"); + ecdsa_get_address(pub_key, 111, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "mp4txp8vXvFLy8So5Y2kFTVrt2epN6YzdP"); + ecdsa_get_address(pub_key, 52, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "N58JsQYveGueiZDgdnNwe4SSkGTAToutAY"); + ecdsa_get_address(pub_key, 48, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "LTmtvyMmoZ49SpfLY73fhZMJEFRPdyohKh"); + ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "35trq6eeuHf6VL9L8pQv46x3vegHnHoTuB"); + + memcpy(pub_key, fromhex("03433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7fe"), 33); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "1FWE2bn3MWhc4QidcF6AvEWpK77sSi2cAP"); + ecdsa_get_address(pub_key, 111, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "mv2BKes2AY8rqXCFKp4Yk9j9B6iaMfWRLN"); + ecdsa_get_address(pub_key, 52, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "NB5bEFH2GtoAawy8t4Qk8kfj3LWvQs3MhB"); + ecdsa_get_address(pub_key, 48, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "LZjBHp5sSAwfKDQnnP5UCFaaXKV9YheGxQ"); + ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "3456DYaKUWuY6RWWw8Hp5CftHLcQN29h9Y"); + + memcpy(pub_key, fromhex("03aeb03abeee0f0f8b4f7a5d65ce31f9570cef9f72c2dd8a19b4085a30ab033d48"), 33); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "1yrZb8dhdevoqpUEGi2tUccUEeiMKeLcs"); + ecdsa_get_address(pub_key, 111, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "mgVoreDcWf6BaxJ5wqgQiPpwLEFRLSr8U8"); + ecdsa_get_address(pub_key, 52, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "MwZDmEdcd1kVLP4yW62c6zmXCU3mNbveDo"); + ecdsa_get_address(pub_key, 48, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "LLCopoSTnHtz4eWdQQhLAVgNgT1zTi4QBK"); + ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "3DBU4tJ9tkMR9fnmCtjW48kjvseoNLQZXd"); + + memcpy(pub_key, fromhex("0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), 65); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "194SZbL75xCCGBbKtMsyWLE5r9s2V6mhVM"); + ecdsa_get_address(pub_key, 111, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "moaPreR5tydT3J4wbvrMLFSQi9TjPCiZc6"); + ecdsa_get_address(pub_key, 52, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "N4domEq61LHkniqqABCYirNzaPG5NRU8GH"); + ecdsa_get_address(pub_key, 48, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "LTHPpodwAcSFWzHV4VsGnMHr4NEJajMnKX"); + + memcpy(pub_key, fromhex("0498010f8a687439ff497d3074beb4519754e72c4b6220fb669224749591dde416f3961f8ece18f8689bb32235e436874d2174048b86118a00afbd5a4f33a24f0f"), 65); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "1A2WfBD4BJFwYHFPc5KgktqtbdJLBuVKc4"); + ecdsa_get_address(pub_key, 111, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "mpYTxEJ2zKhCKPj1KeJ4ap4DTcu39T3uzD"); + ecdsa_get_address(pub_key, 52, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "N5bsrpi36gMW4pVtsteFyQzoKrhPE7nkxK"); + ecdsa_get_address(pub_key, 48, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "LUFTvPWtFxVzo5wYnDJz2uueoqfcMYiuxH"); + + memcpy(pub_key, fromhex("04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf19b77a4d"), 65); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "19J81hrPnQxg9UGx45ibTieCkb2ttm8CLL"); + ecdsa_get_address(pub_key, 111, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "mop5JkwNbSPvvakZmegyHdrXcadbjLazww"); + ecdsa_get_address(pub_key, 52, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "N4sVDMMNho4Eg1XTKu3AgEo7UpRwq3aNbn"); + ecdsa_get_address(pub_key, 48, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "LTX5GvADs5CjQGy7EDhtjjhxxoQB2Uhicd"); +} +END_TEST + +START_TEST(test_pubkey_validity) +{ + uint8_t pub_key[65]; + curve_point pub; + int res; + const ecdsa_curve *curve = &secp256k1; + + memcpy(pub_key, fromhex("0226659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), 33); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 1); + + memcpy(pub_key, fromhex("025b1654a0e78d28810094f6c5a96b8efb8a65668b578f170ac2b1f83bc63ba856"), 33); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 1); + + memcpy(pub_key, fromhex("03433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7fe"), 33); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 1); + + memcpy(pub_key, fromhex("03aeb03abeee0f0f8b4f7a5d65ce31f9570cef9f72c2dd8a19b4085a30ab033d48"), 33); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 1); + + memcpy(pub_key, fromhex("0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), 65); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 1); + + memcpy(pub_key, fromhex("0498010f8a687439ff497d3074beb4519754e72c4b6220fb669224749591dde416f3961f8ece18f8689bb32235e436874d2174048b86118a00afbd5a4f33a24f0f"), 65); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 1); + + memcpy(pub_key, fromhex("04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf19b77a4d"), 65); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 1); + + memcpy(pub_key, fromhex("04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf00000000"), 65); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 0); + + memcpy(pub_key, fromhex("04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2a59ebddbdac9e87b816307a7ed5b8211111111111111111111111111111111"), 65); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 0); + + memcpy(pub_key, fromhex("00"), 1); + res = ecdsa_read_pubkey(curve, pub_key, &pub); + ck_assert_int_eq(res, 0); +} +END_TEST + +START_TEST(test_pubkey_uncompress) +{ + uint8_t pub_key[65]; + uint8_t uncompressed[65]; + int res; + const ecdsa_curve *curve = &secp256k1; + + memcpy(pub_key, fromhex("0226659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), 33); + res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(uncompressed, fromhex("0426659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37b3cfbad6b39a8ce8cb3a675f53b7b57e120fe067b8035d771fd99e3eba7cf4de"), 65); + + memcpy(pub_key, fromhex("03433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7fe"), 33); + res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(uncompressed, fromhex("04433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7feeb4c25bcb840f720a16e8857a011e6b91e0ab2d03dbb5f9762844bb21a7b8ca7"), 65); + + memcpy(pub_key, fromhex("0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), 65); + res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(uncompressed, fromhex("0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), 65); + + memcpy(pub_key, fromhex("00"), 1); + res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); + ck_assert_int_eq(res, 0); +} +END_TEST + +START_TEST(test_wif) +{ + uint8_t priv_key[32]; + char wif[53]; + + memcpy(priv_key, fromhex("1111111111111111111111111111111111111111111111111111111111111111"), 32); + ecdsa_get_wif(priv_key, 0x80, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp"); + ecdsa_get_wif(priv_key, 0xEF, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "cN9spWsvaxA8taS7DFMxnk1yJD2gaF2PX1npuTpy3vuZFJdwavaw"); + + memcpy(priv_key, fromhex("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"), 32); + ecdsa_get_wif(priv_key, 0x80, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "L4ezQvyC6QoBhxB4GVs9fAPhUKtbaXYUn8YTqoeXwbevQq4U92vN"); + ecdsa_get_wif(priv_key, 0xEF, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "cV1ysqy3XUVSsPeKeugH2Utm6ZC1EyeArAgvxE73SiJvfa6AJng7"); + + memcpy(priv_key, fromhex("47f7616ea6f9b923076625b4488115de1ef1187f760e65f89eb6f4f7ff04b012"), 32); + ecdsa_get_wif(priv_key, 0x80, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "KydbzBtk6uc7M6dXwEgTEH2sphZxSPbmDSz6kUUHi4eUpSQuhEbq"); + ecdsa_get_wif(priv_key, 0xEF, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "cPzbT6tbXyJNWY6oKeVabbXwSvsN6qhTHV8ZrtvoDBJV5BRY1G5Q"); +} +END_TEST + +START_TEST(test_address_decode) +{ + int res; + uint8_t decode[MAX_ADDR_RAW_SIZE]; + + res = ecdsa_address_decode("1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T", 0, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("00c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); + + res = ecdsa_address_decode("myTPjxggahXyAzuMcYp5JTkbybANyLsYBW", 111, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("6fc4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); + + res = ecdsa_address_decode("NEWoeZ6gh4CGvRgFAoAGh4hBqpxizGT6gZ", 52, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("34c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); + + res = ecdsa_address_decode("LdAPi7uXrLLmeh7u57pzkZc3KovxEDYRJq", 48, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("30c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); + + res = ecdsa_address_decode("1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8", 0, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("0079fbfc3f34e7745860d76137da68f362380c606c"), 21); + + res = ecdsa_address_decode("mrdwvWkma2D6n9mGsbtkazedQQuoksnqJV", 111, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("6f79fbfc3f34e7745860d76137da68f362380c606c"), 21); + + res = ecdsa_address_decode("N7hMq7AmgNsQXaYARrEwybbDGei9mcPNqr", 52, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("3479fbfc3f34e7745860d76137da68f362380c606c"), 21); + + res = ecdsa_address_decode("LWLwtfycqf1uFqypLAug36W4kdgNwrZdNs", 48, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("3079fbfc3f34e7745860d76137da68f362380c606c"), 21); + + // invalid char + res = ecdsa_address_decode("1JwSSubhmg6i000jtyqhUYYH7bZg3Lfy1T", 0, HASHER_SHA2, decode); + ck_assert_int_eq(res, 0); + + // invalid address + res = ecdsa_address_decode("1111Subhmg6iPtRjtyqhUYYH7bZg3Lfy1T", 0, HASHER_SHA2, decode); + ck_assert_int_eq(res, 0); + + // invalid version + res = ecdsa_address_decode("LWLwtfycqf1uFqypLAug36W4kdgNwrZdNs", 0, HASHER_SHA2, decode); + ck_assert_int_eq(res, 0); +} +END_TEST + +START_TEST(test_ecdsa_der) +{ + uint8_t sig[64], der[72]; + int res; + + memcpy(sig, fromhex("9a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b70771"), 32); + memcpy(sig + 32, fromhex("2b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede781"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 71); + ck_assert_mem_eq(der, fromhex("30450221009a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b7077102202b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede781"), 71); + + memcpy(sig, fromhex("6666666666666666666666666666666666666666666666666666666666666666"), 32); + memcpy(sig + 32, fromhex("7777777777777777777777777777777777777777777777777777777777777777"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 70); + ck_assert_mem_eq(der, fromhex("30440220666666666666666666666666666666666666666666666666666666666666666602207777777777777777777777777777777777777777777777777777777777777777"), 70); + + memcpy(sig, fromhex("6666666666666666666666666666666666666666666666666666666666666666"), 32); + memcpy(sig + 32, fromhex("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 71); + ck_assert_mem_eq(der, fromhex("304502206666666666666666666666666666666666666666666666666666666666666666022100eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"), 71); + + memcpy(sig, fromhex("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"), 32); + memcpy(sig + 32, fromhex("7777777777777777777777777777777777777777777777777777777777777777"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 71); + ck_assert_mem_eq(der, fromhex("3045022100eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee02207777777777777777777777777777777777777777777777777777777777777777"), 71); + + memcpy(sig, fromhex("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"), 32); + memcpy(sig + 32, fromhex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 72); + ck_assert_mem_eq(der, fromhex("3046022100eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee022100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), 72); + + memcpy(sig, fromhex("0000000000000000000000000000000000000000000000000000000000000066"), 32); + memcpy(sig + 32, fromhex("0000000000000000000000000000000000000000000000000000000000000077"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 8); + ck_assert_mem_eq(der, fromhex("3006020166020177"), 8); + + memcpy(sig, fromhex("0000000000000000000000000000000000000000000000000000000000000066"), 32); + memcpy(sig + 32, fromhex("00000000000000000000000000000000000000000000000000000000000000ee"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 9); + ck_assert_mem_eq(der, fromhex("3007020166020200ee"), 9); + + memcpy(sig, fromhex("00000000000000000000000000000000000000000000000000000000000000ee"), 32); + memcpy(sig + 32, fromhex("0000000000000000000000000000000000000000000000000000000000000077"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 9); + ck_assert_mem_eq(der, fromhex("3007020200ee020177"), 9); + + memcpy(sig, fromhex("00000000000000000000000000000000000000000000000000000000000000ee"), 32); + memcpy(sig + 32, fromhex("00000000000000000000000000000000000000000000000000000000000000ff"), 32); + res = ecdsa_sig_to_der(sig, der); + ck_assert_int_eq(res, 10); + ck_assert_mem_eq(der, fromhex("3008020200ee020200ff"), 10); +} +END_TEST + +static void test_codepoints_curve(const ecdsa_curve *curve) { + int i, j; + bignum256 a; + curve_point p, p1; + for (i = 0; i < 64; i++) { + for (j = 0; j < 8; j++) { + bn_zero(&a); + a.val[(4*i)/30] = (2*j+1) << (4*i % 30); + bn_normalize(&a); + // note that this is not a trivial test. We add 64 curve + // points in the table to get that particular curve point. + scalar_multiply(curve, &a, &p); + ck_assert_mem_eq(&p, &curve->cp[i][j], sizeof(curve_point)); + bn_zero(&p.y); // test that point_multiply curve, is not a noop + point_multiply(curve, &a, &curve->G, &p); + ck_assert_mem_eq(&p, &curve->cp[i][j], sizeof(curve_point)); + // mul 2 test. this should catch bugs + bn_lshift(&a); + bn_mod(&a, &curve->order); + p1 = curve->cp[i][j]; + point_double(curve, &p1); + // note that this is not a trivial test. We add 64 curve + // points in the table to get that particular curve point. + scalar_multiply(curve, &a, &p); + ck_assert_mem_eq(&p, &p1, sizeof(curve_point)); + bn_zero(&p.y); // test that point_multiply curve, is not a noop + point_multiply(curve, &a, &curve->G, &p); + ck_assert_mem_eq(&p, &p1, sizeof(curve_point)); + } + } +} + +START_TEST(test_codepoints_secp256k1) { test_codepoints_curve(&secp256k1); } END_TEST +START_TEST(test_codepoints_nist256p1) { test_codepoints_curve(&nist256p1); } END_TEST + +static void test_mult_border_cases_curve(const ecdsa_curve *curve) { + bignum256 a; + curve_point p; + curve_point expected; + bn_zero(&a); // a == 0 + scalar_multiply(curve, &a, &p); + ck_assert(point_is_infinity(&p)); + point_multiply(curve, &a, &p, &p); + ck_assert(point_is_infinity(&p)); + point_multiply(curve, &a, &curve->G, &p); + ck_assert(point_is_infinity(&p)); + + bn_addi(&a, 1); // a == 1 + scalar_multiply(curve, &a, &p); + ck_assert_mem_eq(&p, &curve->G, sizeof(curve_point)); + point_multiply(curve, &a, &curve->G, &p); + ck_assert_mem_eq(&p, &curve->G, sizeof(curve_point)); + + bn_subtract(&curve->order, &a, &a); // a == -1 + expected = curve->G; + bn_subtract(&curve->prime, &expected.y, &expected.y); + scalar_multiply(curve, &a, &p); + ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); + point_multiply(curve, &a, &curve->G, &p); + ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); + + bn_subtract(&curve->order, &a, &a); + bn_addi(&a, 1); // a == 2 + expected = curve->G; + point_add(curve, &expected, &expected); + scalar_multiply(curve, &a, &p); + ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); + point_multiply(curve, &a, &curve->G, &p); + ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); + + bn_subtract(&curve->order, &a, &a); // a == -2 + expected = curve->G; + point_add(curve, &expected, &expected); + bn_subtract(&curve->prime, &expected.y, &expected.y); + scalar_multiply(curve, &a, &p); + ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); + point_multiply(curve, &a, &curve->G, &p); + ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); +} + +START_TEST(test_mult_border_cases_secp256k1) { test_mult_border_cases_curve(&secp256k1); } END_TEST +START_TEST(test_mult_border_cases_nist256p1) { test_mult_border_cases_curve(&nist256p1); } END_TEST + +static void test_scalar_mult_curve(const ecdsa_curve *curve) { + int i; + // get two "random" numbers + bignum256 a = curve->G.x; + bignum256 b = curve->G.y; + curve_point p1, p2, p3; + for (i = 0; i < 1000; i++) { + /* test distributivity: (a + b)G = aG + bG */ + bn_mod(&a, &curve->order); + bn_mod(&b, &curve->order); + scalar_multiply(curve, &a, &p1); + scalar_multiply(curve, &b, &p2); + bn_addmod(&a, &b, &curve->order); + bn_mod(&a, &curve->order); + scalar_multiply(curve, &a, &p3); + point_add(curve, &p1, &p2); + ck_assert_mem_eq(&p2, &p3, sizeof(curve_point)); + // new "random" numbers + a = p3.x; + b = p3.y; + } +} + +START_TEST(test_scalar_mult_secp256k1) { test_scalar_mult_curve(&secp256k1); } END_TEST +START_TEST(test_scalar_mult_nist256p1) { test_scalar_mult_curve(&nist256p1); } END_TEST + +static void test_point_mult_curve(const ecdsa_curve *curve) { + int i; + // get two "random" numbers and a "random" point + bignum256 a = curve->G.x; + bignum256 b = curve->G.y; + curve_point p = curve->G; + curve_point p1, p2, p3; + for (i = 0; i < 200; i++) { + /* test distributivity: (a + b)P = aP + bP */ + bn_mod(&a, &curve->order); + bn_mod(&b, &curve->order); + point_multiply(curve, &a, &p, &p1); + point_multiply(curve, &b, &p, &p2); + bn_addmod(&a, &b, &curve->order); + bn_mod(&a, &curve->order); + point_multiply(curve, &a, &p, &p3); + point_add(curve, &p1, &p2); + ck_assert_mem_eq(&p2, &p3, sizeof(curve_point)); + // new "random" numbers and a "random" point + a = p1.x; + b = p1.y; + p = p3; + } +} + +START_TEST(test_point_mult_secp256k1) { test_point_mult_curve(&secp256k1); } END_TEST +START_TEST(test_point_mult_nist256p1) { test_point_mult_curve(&nist256p1); } END_TEST + +static void test_scalar_point_mult_curve(const ecdsa_curve *curve) { + int i; + // get two "random" numbers + bignum256 a = curve->G.x; + bignum256 b = curve->G.y; + curve_point p1, p2; + for (i = 0; i < 200; i++) { + /* test commutativity and associativity: + * a(bG) = (ab)G = b(aG) + */ + bn_mod(&a, &curve->order); + bn_mod(&b, &curve->order); + scalar_multiply(curve, &a, &p1); + point_multiply(curve, &b, &p1, &p1); + + scalar_multiply(curve, &b, &p2); + point_multiply(curve, &a, &p2, &p2); + + ck_assert_mem_eq(&p1, &p2, sizeof(curve_point)); + + bn_multiply(&a, &b, &curve->order); + bn_mod(&b, &curve->order); + scalar_multiply(curve, &b, &p2); + + ck_assert_mem_eq(&p1, &p2, sizeof(curve_point)); + + // new "random" numbers + a = p1.x; + b = p1.y; + } +} + +START_TEST(test_scalar_point_mult_secp256k1) { test_scalar_point_mult_curve(&secp256k1); } END_TEST +START_TEST(test_scalar_point_mult_nist256p1) { test_scalar_point_mult_curve(&nist256p1); } END_TEST + +START_TEST(test_ed25519) { + // test vectors from https://github.com/torproject/tor/blob/master/src/test/ed25519_vectors.inc + static const char *vectors[] = { + "26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36", // secret + "c2247870536a192d142d056abefca68d6193158e7c1a59c1654c954eccaff894", // public + "d23188eac3773a316d46006fa59c095060be8b1a23582a0dd99002a82a0662bd246d8449e172e04c5f46ac0d1404cebe4aabd8a75a1457aa06cae41f3334f104", // selfsig + "fba7a5366b5cb98c2667a18783f5cf8f4f8d1a2ce939ad22a6e685edde85128d", + "1519a3b15816a1aafab0b213892026ebf5c0dc232c58b21088d88cb90e9b940d", + "3a785ac1201c97ee5f6f0d99323960d5f264c7825e61aa7cc81262f15bef75eb4fa5723add9b9d45b12311b6d403eb3ac79ff8e4e631fc3cd51e4ad2185b200b", + "67e3aa7a14fac8445d15e45e38a523481a69ae35513c9e4143eb1c2196729a0e", + "081faa81992e360ea22c06af1aba096e7a73f1c665bc8b3e4e531c46455fd1dd", + "cf431fd0416bfbd20c9d95ef9b723e2acddffb33900edc72195dea95965d52d888d30b7b8a677c0bd8ae1417b1e1a0ec6700deadd5d8b54b6689275e04a04509", + "d51385942033a76dc17f089a59e6a5a7fe80d9c526ae8ddd8c3a506b99d3d0a6", + "73cfa1189a723aad7966137cbffa35140bb40d7e16eae4c40b79b5f0360dd65a", + "2375380cd72d1a6c642aeddff862be8a5804b916acb72c02d9ed052c1561881aa658a5af856fcd6d43113e42f698cd6687c99efeef7f2ce045824440d26c5d00", + "5c8eac469bb3f1b85bc7cd893f52dc42a9ab66f1b02b5ce6a68e9b175d3bb433", + "66c1a77104d86461b6f98f73acf3cd229c80624495d2d74d6fda1e940080a96b", + "2385a472f599ca965bbe4d610e391cdeabeba9c336694b0d6249e551458280be122c2441dd9746a81bbfb9cd619364bab0df37ff4ceb7aefd24469c39d3bc508", + "eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b86", + "d21c294db0e64cb2d8976625786ede1d9754186ae8197a64d72f68c792eecc19", + "e500cd0b8cfff35442f88008d894f3a2fa26ef7d3a0ca5714ae0d3e2d40caae58ba7cdf69dd126994dad6be536fcda846d89dd8138d1683cc144c8853dce7607", + "4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533d", + "c4d58b4cf85a348ff3d410dd936fa460c4f18da962c01b1963792b9dcc8a6ea6", + "d187b9e334b0050154de10bf69b3e4208a584e1a65015ec28b14bcc252cf84b8baa9c94867daa60f2a82d09ba9652d41e8dde292b624afc8d2c26441b95e3c0e", + "c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b", + "95126f14d86494020665face03f2d42ee2b312a85bc729903eb17522954a1c4a", + "815213640a643d198bd056e02bba74e1c8d2d931643e84497adf3347eb485079c9afe0afce9284cdc084946b561abbb214f1304ca11228ff82702185cf28f60d", + 0, + 0, + 0, + }; + const char **ssk, **spk, **ssig; + ssk = vectors; + spk = vectors + 1; + ssig = vectors + 2; + ed25519_public_key pk; + ed25519_secret_key sk; + ed25519_signature sig; + while (*ssk && *spk && *ssig) { + memcpy(sk, fromhex(*ssk), 32); + MARK_SECRET_DATA(sk, sizeof(sk)); + + ed25519_publickey(sk, pk); + UNMARK_SECRET_DATA(pk, sizeof(pk)); + ck_assert_mem_eq(pk, fromhex(*spk), 32); + + ed25519_sign(pk, 32, sk, pk, sig); + UNMARK_SECRET_DATA(sig, sizeof(sig)); + ck_assert_mem_eq(sig, fromhex(*ssig), 64); + + ssk += 3; + spk += 3; + ssig += 3; + + UNMARK_SECRET_DATA(sk, sizeof(sk)); + } +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/2.test-sign.dat +START_TEST(test_ed25519_keccak) +{ + static const struct { + const char *private_key; + const char *public_key; + const char *signature; + size_t length; + const char *data; + } tests[] = { + { "abf4cf55a2b3f742d7543d9cc17f50447b969e6e06f5ea9195d428ab12b7318d", "8a558c728c21c126181e5e654b404a45b4f0137ce88177435a69978cc6bec1f4", "d9cec0cc0e3465fab229f8e1d6db68ab9cc99a18cb0435f70deb6100948576cd5c0aa1feb550bdd8693ef81eb10a556a622db1f9301986827b96716a7134230c", 41, "8ce03cd60514233b86789729102ea09e867fc6d964dea8c2018ef7d0a2e0e24bf7e348e917116690b9", }, + { "6aa6dad25d3acb3385d5643293133936cdddd7f7e11818771db1ff2f9d3f9215", "bbc8cbb43dda3ecf70a555981a351a064493f09658fffe884c6fab2a69c845c6", "98bca58b075d1748f1c3a7ae18f9341bc18e90d1beb8499e8a654c65d8a0b4fbd2e084661088d1e5069187a2811996ae31f59463668ef0f8cb0ac46a726e7902", 49, "e4a92208a6fc52282b620699191ee6fb9cf04daf48b48fd542c5e43daa9897763a199aaa4b6f10546109f47ac3564fade0", }, + { "8e32bc030a4c53de782ec75ba7d5e25e64a2a072a56e5170b77a4924ef3c32a9", "72d0e65f1ede79c4af0ba7ec14204e10f0f7ea09f2bc43259cd60ea8c3a087e2", "ef257d6e73706bb04878875c58aa385385bf439f7040ea8297f7798a0ea30c1c5eff5ddc05443f801849c68e98111ae65d088e726d1d9b7eeca2eb93b677860c", 40, "13ed795344c4448a3b256f23665336645a853c5c44dbff6db1b9224b5303b6447fbf8240a2249c55", }, + { "c83ce30fcb5b81a51ba58ff827ccbc0142d61c13e2ed39e78e876605da16d8d7", "3ec8923f9ea5ea14f8aaa7e7c2784653ed8c7de44e352ef9fc1dee81fc3fa1a3", "0c684e71b35fed4d92b222fc60561db34e0d8afe44bdd958aaf4ee965911bef5991236f3e1bced59fc44030693bcac37f34d29e5ae946669dc326e706e81b804", 49, "a2704638434e9f7340f22d08019c4c8e3dbee0df8dd4454a1d70844de11694f4c8ca67fdcb08fed0cec9abb2112b5e5f89", }, + { "2da2a0aae0f37235957b51d15843edde348a559692d8fa87b94848459899fc27", "d73d0b14a9754eec825fcb25ef1cfa9ae3b1370074eda53fc64c22334a26c254", "6f17f7b21ef9d6907a7ab104559f77d5a2532b557d95edffd6d88c073d87ac00fc838fc0d05282a0280368092a4bd67e95c20f3e14580be28d8b351968c65e03", 40, "d2488e854dbcdfdb2c9d16c8c0b2fdbc0abb6bac991bfe2b14d359a6bc99d66c00fd60d731ae06d0", }, + { "0c066261fb1b18ebf2a9bcdeda81eb47d5a3745438b3d0b9d19b75885ad0a154", "2e5773f0e725024bc0359ce93a44e15d6507e7b160b6c592200385fee4a269cf", "13b5d2dd1b04f62cc2ec1544fed256423684f2dbca4538ceddda1d15c59dc7196c87840ea303ea30f4f6914a6ec9167841980c1d717f47fd641225068de88507", 41, "f15cb706e29fcfbcb324e38cbac62bb355deddb845c142e970f0c029ea4d05e59fd6adf85573cf1775", }, + { "ef3d8e22a592f04c3a31aa736e10901757a821d053f1a49a525b4ec91eacdee3", "72a2b4910a502b30e13a96aba643c59c79328c1ba1462be6f254e817ef157fee", "95f2437a0210d2d2f125a3c377ed666c0d596cd104185e70204924a182a11a6eb3bdba4395bbfc3f4e827d38805752657ee52d1ce0f17e70f59bfd4999282509", 50, "6c3e4387345740b8d62cf0c9dec48f98c292539431b2b54020d8072d9cb55f0197f7d99ff066afcf9e41ea8b7aea78eb082d", }, + { "f7fb79743e9ba957d2a4f1bd95ceb1299552abecaf758bf840d2dc2c09f3e3cb", "8b7d7531280f76a8abac8293d87508e3953894087112ae01b6ad32485d4e9b67", "c868ecf31cee783fe8799ac7e6a662431c822967351d8b79687f4ddf608f79a080c4ff9eed4fdee8c99fe1be905f734cae2a172f1cfdb00771625c0695a5260e", 42, "55d8e60c307ee533b1af9ff677a2de40a6eace722bcc9eb5d79907b420e533bc06db674dafbd9f43d672", }, + { "8cc9a2469a77fad18b44b871b2b6932cd354641d2d1e84403f746c4fff829791", "aed5da202d4983dac560faf6704dc76ac111616318570e244043e82ed1bbcd2b", "aee9616db4135150818eaffa3e4503c2d7e9e834847a4c7d0a8856e952761d361a657104d36950c9b75770ded00d56a96e06f383fa2406bc935dcf51f272300e", 42, "d9b8be2f71b83261304e333d6e35563dc3c36c2eb5a23e1461b6e95aa7c6f381f9c3bd39deaa1b6df2f9", }, + { "a247abbef0c1affbf021d1aff128888550532fc0edd77bc39f6ef5312317ec47", "98ededbad1e5ad7a0d5a0cf4fcd7a794eb5c6900a65e7e921884a636f19b131d", "f8cc02933851432f0c5df0b70f2067f740ccb72de7d6fa1e9a9b0d6de1402b9c6c525fd848e45aaaac1423b52880ec3474a2f64b38db6fc8e008d95a310e6e0c", 47, "4a5f07eb713932532fc3132c96efdc45862fe7a954c1d2ae4640afdf4728fb58c65e8a4ebfe0d53d5797d5146442b9", }, + { "163d69079ddad1f16695c47d81c3b72f869b2fdd50e6e47113db6c85051a6ede", "93fe602642ee5773f4aaf6a3bc21e98e354035225353f419e78e43c3ec36c88a", "da747fa2cb47aae1effc1e4cfde0e39fa79937948592a712a7665bf948b8311e7f3f80f966301679520d5c2afa3eadd60e061f0d264887500d8d03a17e10fd02", 41, "65fe5c1a0214a59644892e5ac4216f09fbb4e191b89bfb63d6540177d25ef9e3714850b8453bd6b2b6", }, + { "7b061bf90eb760971b9ec66a96fd6609635ca4b531f33e3c126b9ae6fdb3d491", "cb392ebb6912df4111efeeb1278160daf9da396e9291b83979a5ac479f7276d2", "f6eebe86f7ea672e0707ee518e1798d6fbd118c11b2aa30be07d10e3882e3721f2030f9f044b77c3a7a9a2f1feba7e7ce75d1f7f3807a96a764fded35d341d02", 45, "a17f5ce39b9ba7b7cf1147e515d6aa84b22fd0e2d8323a91367198fc6c3aff04ebb21fc2bdbe7bc0364e8040a9", }, + { "c9f8ccbf761cec00ab236c52651e76b5f46d90f8936d44d40561ed5c277104de", "a3192641e343b669ffd43677c2e5cd4efaed174e876141f1d773bd6cfe30d875", "d44f884ec9eae2e99e74194b5acc769b7aa369aaad359e92ba6ff0fe629af2a9a7156c19b720e7de8c7f03c039563f160948073cab6f99b26a56a8bb1023ba08", 47, "3d7e33b0ecead8269966e9dcd192b73eb8a12573fc8a5fdfbe5753541026ef2e49f5280cba9bc2515a049b3a1c1b49", }, + { "ebfa409ac6f987df476858dd35310879bf564eeb62984a52115d2e6c24590124", "7bb1601fe7215f3f4da9c8ab5e804dc58f57ba41b03223f57ec80d9c9a2dd0e1", "f3e7c1abfcc9f35556cb1e4c5a2b34445177ac188312d9148f1d1d8467ea8411fa3cda031d023034e45bbe407ef7d1b937bfb098266138857d35cb4efe407306", 52, "0c37564f718eda683aa6f3e9ab2487620b1a8b5c8f20adb3b2d7550af0d635371e531f27cebe76a2abcc96de0875bdae987a45ac", }, + { "f993f61902b7da332f2bb001baa7accaf764d824eb0cd073315f7ec43158b8fb", "55fc8e0da1b454cab6ddefb235311db2b01504bf9ac3f71c7e3f3d0d1f09f80b", "178bd147673c0ca330e45da63cbd1f1811906bd5284bb44e4bb00f7d7163d1f396975610b6f71c1ae4686466fad4c5e7bb9685099e21ca4f1a45bb3fcf56ae0c", 42, "b7dd613bc9c364d9eeb9a52636d72bc881dfc81a836b6537bbb928bff5b73831358947ea9edea1570550", }, + { "05188c09c31b4bb63f0d49b47ccc1654c2aba907b8c6c0a82ee403e950169167", "e096d808dfabe8e44eb74950199dadcd586f9de6b141a0ce85ab94b3d97866eb", "669491c8eb7cedbbc0252f3eafb048b39a2a37f60ac87837777c72c879ac8b726c39e10060750c2f539102999b71889746111bc5f71ec8c158cc81cf566aef03", 44, "bb8e22469d1c7f1d5418563e8781f69eccb56678bd36d8919f358c2778562ff6b50de916c12d44f1a778a7f3", }, + { "eabe57e1a916ebbffa4ba7abc7f23e83d4deb1338816cc1784d7495d92e98d0b", "3aad275642f48a46ed1032f3de9f4053e0fd35cf217e065d2e4579c3683932f7", "b2e9dac2c83942ca374f29c8eff5a30c377c3db3c1c645e593e524d17484e7705b11f79573e2d63495fc3ce3bf216a209f0cb7bea477ae0f8bd297f193af8805", 44, "3f2c2d6682ee597f2a92d7e560ac53d5623550311a4939d68adfb904045ed8d215a9fdb757a2368ea4d89f5f", }, + { "fef7b893b4b517fab68ca12d36b603bc00826bf3c9b31a05149642ae10bb3f55", "b3fb891868708dfa5da5b9b5234058767ab42c117f12c3228c02a1976d1c0f83", "6243e289314b7c7587802909a9be6173a916b36f9de1e164954dfe5d1ebd57c869a79552d770e13b51855502be6b15e7be42a3675298a81284df58e609b06503", 47, "38c69f884045cdbeebe4478fdbd1ccc6cf00a08d8a3120c74e7167d3a2e26a67a043b8e5bd198f7b0ce0358cef7cf9", }, + { "16228bec9b724300a37e88e535fc1c58548d34d7148b57c226f2b3af974c1822", "3c92423a8360c9a5d9a093730d72831bec4601dcadfe84de19fc8c8f91fc3d4b", "6aebfa9a4294ec888d54bcb517fcb6821e4c16d2708a2afe701f431a28149ff4f139f9d16a52a63f1f91baf4c8dea37710c73f25c263a8035a39cc118ad0280f", 44, "a3d7b122cd4431b396b20d8cc46cc73ed4a5253a44a76fc83db62cdc845a2bf7081d069a857955a161cccf84", }, + { "2dc3f5f0a0bc32c6632534e1e8f27e59cbe0bf7617d31aff98098e974c828be7", "b998a416edc28ded988dcacb1caf2bd96c87354b0d1eeccb6980e54a3104f21f", "76a2ddfc4bea48c47e0c82bcbfee28a37c61ec626af39a468e643e0ef9f6533056a5a0b44e64d614ba3c641a40e5b003a99463445ae2c3c8e1e9882092d74b07", 42, "bdae276d738b9758ea3d322b54fd12fe82b767e8d817d8ef3d41f78705748e28d15e9c506962a1b85901", }, + }; + + ed25519_secret_key private_key; + ed25519_public_key public_key; + ed25519_signature signature; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + nem_private_key(tests[i].private_key, private_key); + MARK_SECRET_DATA(private_key, sizeof(private_key)); + + ed25519_publickey_keccak(private_key, public_key); + UNMARK_SECRET_DATA(public_key, sizeof(public_key)); + ck_assert_mem_eq(public_key, fromhex(tests[i].public_key), 32); + + ed25519_sign_keccak(fromhex(tests[i].data), tests[i].length, private_key, public_key, signature); + UNMARK_SECRET_DATA(signature, sizeof(signature)); + ck_assert_mem_eq(signature, fromhex(tests[i].signature), 64); + + UNMARK_SECRET_DATA(private_key, sizeof(private_key)); + } +} +END_TEST + +START_TEST(test_ed25519_cosi) { + const int MAXN = 10; + ed25519_secret_key keys[MAXN]; + ed25519_public_key pubkeys[MAXN]; + ed25519_secret_key nonces[MAXN]; + ed25519_public_key Rs[MAXN]; + ed25519_cosi_signature sigs[MAXN]; + uint8_t msg[32]; + rfc6979_state rng; + int res; + + init_rfc6979(fromhex("26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36"), + fromhex("26659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), &rng); + + for (int N = 1; N < 11; N++) { + ed25519_public_key pk; + ed25519_public_key R; + ed25519_signature sig; + /* phase 0: create priv/pubkeys and combine pubkeys */ + for (int j = 0; j < N; j++) { + generate_rfc6979(keys[j], &rng); + ed25519_publickey(keys[j], pubkeys[j]); + } + res = ed25519_cosi_combine_publickeys(pk, pubkeys, N); + ck_assert_int_eq(res, 0); + + generate_rfc6979(msg, &rng); + + /* phase 1: create nonces, commitments (R values) and combine commitments */ + for (int j = 0; j < N; j++) { + generate_rfc6979(nonces[j], &rng); + ed25519_publickey(nonces[j], Rs[j]); + } + res = ed25519_cosi_combine_publickeys(R, Rs, N); + ck_assert_int_eq(res, 0); + + MARK_SECRET_DATA(keys, sizeof(keys)); + /* phase 2: sign and combine signatures */ + for (int j = 0; j < N; j++) { + ed25519_cosi_sign(msg, sizeof(msg), keys[j], nonces[j], R, pk, sigs[j]); + } + UNMARK_SECRET_DATA(sigs, sizeof(sigs)); + + ed25519_cosi_combine_signatures(sig, R, sigs, N); + + /* check signature */ + res = ed25519_sign_open(msg, sizeof(msg), pk, sig); + ck_assert_int_eq(res, 0); + + UNMARK_SECRET_DATA(keys, sizeof(keys)); + } +} +END_TEST + +static void test_bip32_ecdh_init_node(HDNode *node, const char *seed_str, const char *curve_name) { + hdnode_from_seed((const uint8_t *)seed_str, strlen(seed_str), curve_name, node); + hdnode_fill_public_key(node); + if (node->public_key[0] == 1) { + node->public_key[0] = 0x40; // Curve25519 public keys start with 0x40 byte + } +} + +static void test_bip32_ecdh(const char *curve_name, int expected_key_size, const uint8_t *expected_key) { + int res, key_size; + HDNode alice, bob; + uint8_t session_key1[expected_key_size], session_key2[expected_key_size]; + + test_bip32_ecdh_init_node(&alice, "Alice", curve_name); + test_bip32_ecdh_init_node(&bob, "Bob", curve_name); + + // Generate shared key from Alice's secret key and Bob's public key + res = hdnode_get_shared_key(&alice, bob.public_key, session_key1, &key_size); + ck_assert_int_eq(res, 0); + ck_assert_int_eq(key_size, expected_key_size); + ck_assert_mem_eq(session_key1, expected_key, key_size); + + // Generate shared key from Bob's secret key and Alice's public key + res = hdnode_get_shared_key(&bob, alice.public_key, session_key2, &key_size); + ck_assert_int_eq(res, 0); + ck_assert_int_eq(key_size, expected_key_size); + ck_assert_mem_eq(session_key2, expected_key, key_size); +} + +START_TEST(test_bip32_ecdh_nist256p1) { + test_bip32_ecdh( + NIST256P1_NAME, 65, + fromhex("044aa56f917323f071148cd29aa423f6bee96e7fe87f914d0b91a0f95388c6631646ea92e882773d7b0b1bec356b842c8559a1377673d3965fb931c8fe51e64873")); +} +END_TEST + +START_TEST(test_bip32_ecdh_curve25519) { + test_bip32_ecdh( + CURVE25519_NAME, 33, + fromhex("04f34e35516325bb0d4a58507096c444a05ba13524ccf66910f11ce96c62224169")); +} +END_TEST + +START_TEST(test_bip32_ecdh_errors) { + HDNode node; + const uint8_t peer_public_key[65] = {0}; // invalid public key + uint8_t session_key[65]; + int res, key_size = 0; + + test_bip32_ecdh_init_node(&node, "Seed", ED25519_NAME); + res = hdnode_get_shared_key(&node, peer_public_key, session_key, &key_size); + ck_assert_int_eq(res, 1); + ck_assert_int_eq(key_size, 0); + + test_bip32_ecdh_init_node(&node, "Seed", CURVE25519_NAME); + res = hdnode_get_shared_key(&node, peer_public_key, session_key, &key_size); + ck_assert_int_eq(res, 1); + ck_assert_int_eq(key_size, 0); + + test_bip32_ecdh_init_node(&node, "Seed", NIST256P1_NAME); + res = hdnode_get_shared_key(&node, peer_public_key, session_key, &key_size); + ck_assert_int_eq(res, 1); + ck_assert_int_eq(key_size, 0); +} +END_TEST + +START_TEST(test_output_script) { + static const char *vectors[] = { + "76A914010966776006953D5567439E5E39F86A0D273BEE88AC", "16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", + "A914010966776006953D5567439E5E39F86A0D273BEE87", "31nVrspaydBz8aMpxH9WkS2DuhgqS1fCuG", + "0014010966776006953D5567439E5E39F86A0D273BEE", "p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm", + "00200102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20", "7XhPD7te3C6CVKnJWUhrTJbFTwudhHqfrjpS59AS6sMzL4RYFiCNg", + 0, 0, + }; + const char **scr, **adr; + scr = vectors; + adr = vectors + 1; + char address[60]; + while (*scr && *adr) { + int r = script_output_to_address(fromhex(*scr), strlen(*scr)/2, address, 60); + ck_assert_int_eq(r, (int)(strlen(*adr) + 1)); + ck_assert_str_eq(address, *adr); + scr += 2; + adr += 2; + } +} +END_TEST + +START_TEST(test_ethereum_pubkeyhash) +{ + uint8_t pubkeyhash[20]; + int res; + HDNode node; + + // init m + hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, SECP256K1_NAME, &node); + + // [Chain m] + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("056db290f8ba3250ca64a45d16284d04bc6f5fbf"), 20); + + // [Chain m/0'] + hdnode_private_ckd_prime(&node, 0); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("bf6e48966d0dcf553b53e7b56cb2e0e72dca9e19"), 20); + + // [Chain m/0'/1] + hdnode_private_ckd(&node, 1); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("29379f45f515c494483298225d1b347f73d1babf"), 20); + + // [Chain m/0'/1/2'] + hdnode_private_ckd_prime(&node, 2); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("d8e85fbbb4b3b3c71c4e63a5580d0c12fb4d2f71"), 20); + + // [Chain m/0'/1/2'/2] + hdnode_private_ckd(&node, 2); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("1d3462d2319ac0bfc1a52e177a9d372492752130"), 20); + + // [Chain m/0'/1/2'/2/1000000000] + hdnode_private_ckd(&node, 1000000000); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("73659c60270d326c06ac204f1a9c63f889a3d14b"), 20); + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, SECP256K1_NAME, &node); + + // [Chain m] + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("6dd2a6f3b05fd15d901fbeec61b87a34bdcfb843"), 20); + + // [Chain m/0] + hdnode_private_ckd(&node, 0); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("abbcd4471a0b6e76a2f6fdc44008fe53831e208e"), 20); + + // [Chain m/0/2147483647'] + hdnode_private_ckd_prime(&node, 2147483647); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("40ef2cef1b2588ae862e7a511162ec7ff33c30fd"), 20); + + // [Chain m/0/2147483647'/1] + hdnode_private_ckd(&node, 1); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("3f2e8905488f795ebc84a39560d133971ccf9b50"), 20); + + // [Chain m/0/2147483647'/1/2147483646'] + hdnode_private_ckd_prime(&node, 2147483646); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("a5016fdf975f767e4e6f355c7a82efa69bf42ea7"), 20); + + // [Chain m/0/2147483647'/1/2147483646'/2] + hdnode_private_ckd(&node, 2); + res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(pubkeyhash, fromhex("8ff2a9f7e7917804e8c8ec150d931d9c5a6fbc50"), 20); +} +END_TEST + +START_TEST(test_ethereum_address) +{ + static const char *vectors[] = { + "52908400098527886E0F7030069857D2E4169EE7", + "8617E340B3D01FA5F11F306F4090FD50E238070D", + "de709f2102306220921060314715629080e2fb77", + "27b1fdb04752bbc536007a920d24acb045561c26", + "5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", + "fB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", + "dbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", + "D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", + "5A4EAB120fB44eb6684E5e32785702FF45ea344D", + "5be4BDC48CeF65dbCbCaD5218B1A7D37F58A0741", + "a7dD84573f5ffF821baf2205745f768F8edCDD58", + "027a49d11d118c0060746F1990273FcB8c2fC196", + "CD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + 0 + }; + uint8_t addr[20]; + char address[41]; + const char **vec = vectors; + while (*vec) { + memcpy(addr, fromhex(*vec), 20); + ethereum_address_checksum(addr, address); + ck_assert_str_eq(address, *vec); + vec++; + } +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/1.test-keys.dat +START_TEST(test_nem_address) +{ + static const struct { + const char *private_key; + const char *public_key; + const char *address; + } tests[] = { + { "575dbb3062267eff57c970a336ebbc8fbcfe12c5bd3ed7bc11eb0481d7704ced", "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844", "NDD2CT6LQLIYQ56KIXI3ENTM6EK3D44P5JFXJ4R4", }, + { "5b0e3fa5d3b49a79022d7c1e121ba1cbbf4db5821f47ab8c708ef88defc29bfe", "96eb2a145211b1b7ab5f0d4b14f8abc8d695c7aee31a3cfc2d4881313c68eea3", "NABHFGE5ORQD3LE4O6B7JUFN47ECOFBFASC3SCAC", }, + { "738ba9bb9110aea8f15caa353aca5653b4bdfca1db9f34d0efed2ce1325aeeda", "2d8425e4ca2d8926346c7a7ca39826acd881a8639e81bd68820409c6e30d142a", "NAVOZX4HDVOAR4W6K4WJHWPD3MOFU27DFHC7KZOZ", }, + { "e8bf9bc0f35c12d8c8bf94dd3a8b5b4034f1063948e3cc5304e55e31aa4b95a6", "4feed486777ed38e44c489c7c4e93a830e4c4a907fa19a174e630ef0f6ed0409", "NBZ6JK5YOCU6UPSSZ5D3G27UHAPHTY5HDQMGE6TT", }, + { "c325ea529674396db5675939e7988883d59a5fc17a28ca977e3ba85370232a83", "83ee32e4e145024d29bca54f71fa335a98b3e68283f1a3099c4d4ae113b53e54", "NCQW2P5DNZ5BBXQVGS367DQ4AHC3RXOEVGRCLY6V", }, + { "a811cb7a80a7227ae61f6da536534ee3c2744e3c7e4b85f3e0df3c6a9c5613df", "6d34c04f3a0e42f0c3c6f50e475ae018cfa2f56df58c481ad4300424a6270cbb", "NA5IG3XFXZHIPJ5QLKX2FBJPEZYPMBPPK2ZRC3EH", }, + { "9c66de1ec77f4dfaaebdf9c8bc599ca7e8e6f0bc71390ffee2c9dd3f3619242a", "a8fefd72a3b833dc7c7ed7d57ed86906dac22f88f1f4331873eb2da3152a3e77", "NAABHVFJDBM74XMJJ52R7QN2MTTG2ZUXPQS62QZ7", }, + { "c56bc16ecf727878c15e24f4ae68569600ac7b251218a44ef50ce54175776edc", "c92f761e6d83d20068fd46fe4bd5b97f4c6ba05d23180679b718d1f3e4fb066e", "NCLK3OLMHR3F2E3KSBUIZ4K5PNWUDN37MLSJBJZP", }, + { "9dd73599283882fa1561ddfc9be5830b5dd453c90465d3fe5eeb646a3606374e", "eaf16a4833e59370a04ccd5c63395058de34877b48c17174c71db5ed37b537ed", "ND3AHW4VTI5R5QE5V44KIGPRU5FBJ5AFUCJXOY5H", }, + { "d9639dc6f49dad02a42fd8c217f1b1b4f8ce31ccd770388b645e639c72ff24fa", "0f74a2f537cd9c986df018994dde75bdeee05e35eb9fe27adf506ca8475064f7", "NCTZ4YAP43ONK3UYTASQVNDMBO24ZHJE65F3QPYE", }, + { "efc1992cd50b70ca55ac12c07aa5d026a8b78ffe28a7dbffc9228b26e02c38c1", "2ebff201255f6cf948c78f528658b99a7c13ac791942fa22d59af610558111f5", "NDQ2TMCMXBSFPZQPE2YKH6XLC24HD6LUMN6Z4GIC", }, + { "143a815e92e43f3ed1a921ee48cd143931b88b7c3d8e1e981f743c2a5be3c5ba", "419ed11d48730e4ae2c93f0ea4df853b8d578713a36dab227517cf965861af4e", "NA32IDDW2C53BDSBJNFL3Z6UU3J5CJZJMCZDXCF4", }, + { "bc1a082f5ac6fdd3a83ade211e5986ac0551bad6c7da96727ec744e5df963e2a", "a160e6f9112233a7ce94202ed7a4443e1dac444b5095f9fecbb965fba3f92cac", "NADUCEQLC3FTGB25GTA5HOUTB53CBVQNVOIP7NTJ", }, + { "4e47b4c6f4c7886e49ec109c61f4af5cfbb1637283218941d55a7f9fe1053f72", "fbb91b16df828e21a9802980a44fc757c588bc1382a4cea429d6fa2ae0333f56", "NBAF3BFLLPWH33MYE6VUPP5T6DQBZBKIDEQKZQOE", }, + { "efc4389da48ce49f85365cfa578c746530e9eac42db1b64ec346119b1becd347", "2232f24dda0f2ded3ecd831210d4e8521a096b50cadd5a34f3f7083374e1ec12", "NBOGTK2I2ATOGGD7ZFJHROG5MWL7XCKAUKSWIVSA", }, + { "bdba57c78ca7da16a3360efd13f06276284db8c40351de7fcd38ba0c35ac754d", "c334c6c0dad5aaa2a0d0fb4c6032cb6a0edd96bf61125b5ea9062d5a00ee0eee", "NCLERTEFYXKLK7RA4MVACEFMXMK3P7QMWTM7FBW2", }, + { "20694c1ec3c4a311bcdb29ed2edc428f6d4f9a4c429ad6a5bf3222084e35695f", "518c4de412efa93de06a55947d11f697639443916ec8fcf04ebc3e6d17d0bd93", "NB5V4BPIJHXVONO7UGMJDPFARMFA73BOBNOOYCOV", }, + { "e0d4f3760ac107b33c22c2cac24ab2f520b282684f5f66a4212ff95d926323ce", "b3d16f4ead9de67c290144da535a0ed2504b03c05e5f1ceb8c7863762f786857", "NC4PBAO5TPCAVQKBVOC4F6DMZP3CFSQBU46PSKBD", }, + { "efa9afc617412093c9c7a7c211a5332dd556f941e1a88c494ec860608610eea2", "7e7716e4cebceb731d6f1fd28676f34888e9a0000fcfa1471db1c616c2ddf559", "NCFW2LPXIWLBWAQN2QVIWEOD7IVDO3HQBD2OU56K", }, + { "d98499b3db61944684ce06a91735af4e14105338473fcf6ebe2b0bcada3dfd21", "114171230ad6f8522a000cdc73fbc5c733b30bb71f2b146ccbdf34499f79a810", "NCUKWDY3J3THKQHAKOK5ALF6ANJQABZHCH7VN6DP", }, + }; + + HDNode node; + ed25519_secret_key private_key; + uint8_t chain_code[32]; + char address[41]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + nem_private_key(tests[i].private_key, private_key); + + ck_assert(hdnode_from_xprv(0, 0, chain_code, private_key, ED25519_KECCAK_NAME, &node)); + + ck_assert(hdnode_get_nem_address(&node, NEM_NETWORK_MAINNET, address)); + ck_assert_str_eq(address, tests[i].address); + + ck_assert_mem_eq(&node.public_key[1], fromhex(tests[i].public_key), 32); + } +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/3.test-derive.dat +START_TEST(test_nem_derive) +{ + static const struct { + const char *salt; + const char *private_key; + const char *public_key; + const char *mul; + const char *shared_key; + } tests[] = { + { "ad63ac08f9afc85eb0bf4f8881ca6eaa0215924c87aa2f137d56109bb76c6f98", "e8857f8e488d4e6d4b71bcd44bb4cff49208c32651e1f6500c3b58cafeb8def6", "9d8e5f200b05a2638fb084a375408cabd6d5989590d96e3eea5f2cb34668178e", "a8352060ba5718745ee4d78b9df564e0fbe13f50d50ab15a8dd524159d81d18b", "990a5f611c65fbcde735378bdec38e1039c5466503511e8c645bbe42795c752b", }, + { "96104f0a28f9cca40901c066cd435134662a3b053eb6c8df80ee0d05dc941963", "d7f67b5f52cbcd1a1367e0376a8eb1012b634acfcf35e8322bae8b22bb9e8dea", "9735c92d150dcee0ade5a8d1822f46a4db22c9cda25f33773ae856fe374a3e8a", "ea14d521d83328dba70982d42094300585818cc2da609fdb1f73bb32235576ff", "b498aa21d4ba4879ea9fd4225e93bacc760dcd9c119f8f38ab0716457d1a6f85", }, + { "d8f94a0bbb1de80aea17aab42e2ffb982e73fc49b649a318479e951e392d8728", "d026ddb445fb3bbf3020e4b55ed7b5f9b7fd1278c34978ca1a6ed6b358dadbae", "d19e6beca3b26b9d1abc127835ebeb7a6c19c33dec8ec472e1c4d458202f4ec8", "0d561f54728ad837ae108ec66c2ece2bb3b26041d3ee9b77fdc6d36d9ebfb2e3", "d012afe3d1d932304e613c91545bf571cf2c7281d6cafa8e81393a551f675540", }, + { "3f8c969678a8abdbfb76866a142c284a6f01636c1c1607947436e0d2c30d5245", "c522b38c391d1c3fa539cc58802bc66ac34bb3c73accd7f41b47f539bedcd016", "ea5b6a0053237f7712b1d2347c447d3e83e0f2191762d07e1f53f8eb7f2dfeaa", "23cccd3b63a9456e4425098b6df36f28c8999461a85e4b2b0c8d8f53c62c9ea9", "7e27efa50eed1c2ac51a12089cbab6a192624709c7330c016d5bc9af146584c1", }, + { "e66415c58b981c7f1f2b8f45a42149e9144616ff6de49ff83d97000ac6f6f992", "2f1b82be8e65d610a4e588f000a89a733a9de98ffc1ac9d55e138b3b0a855da0", "65aeda1b47f66c978a4a41d4dcdfbd8eab5cdeb135695c2b0c28f54417b1486d", "43e5b0a5cc8146c03ac63e6f8cf3d8825a9ca1ed53ea4a88304af4ddf5461b33", "bb4ab31c334e55d378937978c90bb33779b23cd5ef4c68342a394f4ec8fa1ada", }, + { "58487c9818c9d28ddf97cb09c13331941e05d0b62bf4c35ee368de80b552e4d1", "f3869b68183b2e4341307653e8f659bd7cd20e37ea5c00f5a9e203a8fa92359a", "c7e4153a18b4162f5c1f60e1ba483264aa5bb3f4889dca45b434fcd30b9cf56f", "5ae9408ab3156b8828c3e639730bd5e5db93d7afe2cee3fcda98079316c5bb3a", "0224d85ae8f17bfe127ec24b8960b7639a0dbde9c8c39a0575b939448687bb14", }, + { "ad66f3b654844e53d6fb3568134fae75672ba63868c113659d3ca58c2c39d24f", "d38f2ef8dfdc7224fef596130c3f4ff68ac83d3f932a56ee908061466ac28572", "d0c79d0340dc66f0a895ce5ad60a933cf6be659569096fb9d4b81e5d32292372", "1ea22db4708ed585ab541a4c70c3069f8e2c0c1faa188ddade3efaa53c8329f6", "886a7187246934aedf2794748deadfe038c9fd7e78d4b7be76c5a651440ac843", }, + { "eed48604eab279c6ad8128aa83483a3da0928271a4cae1a5745671284e1fb89d", "e2342a8450fc0adfa0ea2fbd0b1d28f100f0a3a905a3da29de34d1353afa7df7", "d2dbe07e0f2dbc3dbb01c70092e3c4247d12827ddcd8d76534fd740a65c30de2", "4c4b30eb6a2bfa17312f5729b4212cb51c2eee8fbfaea82a0e957ca68f4f6a30", "dcae613ac5641ff9d4c3ca58632245f93b0b8657fe4d48bac7b062cc53dd21ad", }, + { "f35b315287b268c0d0b386fb5b31810f65e1c4497cffae24527f69a3abac3884", "049016230dbef7a14a439e5ab2f6d12e78cb8df127db4e0c312673b3c361e350", "1b3b1925a8a535cd7d78725d25298f45bba8ca3dee2cdaabf14241c9b51b37c4", "04c9685dae1f8eb72a6438f24a87dc83a56d79c9024edf7e01aa1ae34656f29e", "b48469d0428c223b93cd1fe34bb2cafd3fb78a8fa15f98f89f1ac9c0ce7c9001", }, + { "d6cf082c5d9a96e756a94a2e27703138580a7c7c1af505c96c3abf7ab6802e1d", "67cd02b0b8b0adcf6fdd4d4d64a1f4193ced68bb8605d0ec941a62011326d140", "a842d5127c93a435e4672dcadd9fccbfd0e9208c79c5404848b298597eccdbdb", "d5c6bd6d81b99659d0bafe91025b6ecf73b16c6b07931cf44718b13f00fde3f7", "8aa160795b587f4be53aa35d26e9b618b4cd6ec765b523bc908e53c258ca8fd4", }, + { "dda32c91c95527a645b00dd05d13f0b98ed612a726ce5f5221431430b7660944", "eba026f92a8ffb5e95060a22e15d597fe838a99a0b2bbcb423c933b6bc718c50", "7dbaf9c313a1ff9128c54d6cd740c7d0cc46bca588e7910d438dd619ca4fd69a", "5bb20a145de83ba27a0c261e1f54bfd7dcea61888fc2eebbe6166876f7b000b8", "3a96f152ad8bf355cccb307e4a40108aa17f8e925522a2b5bb0b3f1e1a262914", }, + { "63c500acbd4ff747f7dadde7d3286482894ac4d7fe68f396712bca29879aa65c", "9663cd3c2030a5fe4a3ea3cc9a1d182b3a63ade68616aaeb4caf40b495f6f227", "b1e7d9070ac820d986d839b79f7aa594dcf708473529dad87af8682cc6197374", "1f7a97584d8db9f395b9ac4447de4b33c5c1f5020187cd4996286a49b07eb8a7", "4d2a974ec12dcf525b5654d31053460850c3092648b7e15598b7131d2930e9fb", }, + { "91f340961029398cc8bcd906388044a6801d24328efdf919d8ed0c609862a073", "45a588500d00142e2226231c01fd11ac6f842ab6a85872418f5b6a1999f8bd98", "397233c96069b6f4a57d6e93f759fa327222eaef71fc981afa673b248206df3f", "062123ef9782e3893f7b2e1d557b4ecce92b9f9aa8577e76380f228b75152f84", "235848cb04230a16d8978aa7c19fe7fbff3ebe29389ea6eb24fb8bc3cb50afc6", }, + { "46120b4da6ba4eb54fb65213cfef99b812c86f7c42a1de1107f8e8c12c0c3b6b", "cc19a97a99ad71ce348bcf831c0218e6a1f0a8d52186cabe6298b56f24e640f9", "c54631bb62f0f9d86b3301fcb2a671621e655e578c95504af5f78da83f7fec4f", "ab73cc20c75260ff3a7cefea8039291d4d15114a07a9250375628cca32225bb6", "70040a360b6a2dfa881272ef4fa6616e2e8fcc45194fa2a21a1eef1160271cd5", }, + { "f0a69ded09f1d731ab9561d0c3a40b7ef30bcb2bf60f92beccd8734e2441403d", "ea732822a381c46a7ac9999bf5ef85e16b7460b26aaf6c1a1c6ffa8c8c82c923", "110decbff79c382b1e60af4259564a3c473087792350b24fca98ae9a74ba9dd9", "81bdee95aecdcf821a9d682f79056f1abdcf1245d2f3b55244447881a283e0d4", "1bc29d4470ccf97d4e35e8d3cd4b12e3ebf2cb0a82425d35984aeedf7ad0f6f9", }, + { "e79cf4536fb1547e57626c0f1a87f71a396fdfb985b00731c0c2876a00645eda", "04213fc02b59c372e3e7f53faa71a2f73b31064102cb6fc8b68432ba7cdf7eb4", "ca1c750aaed53bc30dac07d0696ed86bcd7cdbbcbd3d15bb90d90cb5c6117bac", "c68cd0872a42a3a64e8a229ef7fcad3d722047d5af966f7dda4d4e32d0d57203", "bfdd3d07563d966d95afe4b8abea4b567265fceea8c4ecddb0946256c33e07b2", }, + { "81a40db4cddaf076e0206bd2b0fa7470a72cc456bad34aa3a0469a4859f286be", "52156799fd86cc63345cdbffd65ef4f5f8df0ffd9906a40af5f41d269bbcff5d", "54d61aa0b0b17a87f1376fe89cd8cd6b314827c1f1b9e5e7b20e7a7eee2a8335", "4553fb2cab8555068c32f86ceb692bbf1c2beeaf21627ef1b1be57344b52eea8", "55096b6710ade3bbe38702458ee13faa10c24413261bc076f17675dcbf2c4ee6", }, + { "d28e4a9e6832a3a4dad014a2bf1f666f01093cbba8b9ad4d1dcad3ea10cb42b9", "8ca134404c8fa199b0c72cb53cfa0adcf196dfa560fb521017cce5cbace3ba59", "3a6c39a1e5f9f550f1debedd9a0bc84210cce5f9834797db8f14122bf5817e45", "eb632ca818b4f659630226a339a3ce536b31c8e1e686fea8da3760e8abc20b8e", "9fbb3fbaf1cd54ee0cd90685f59b082545983f1f662ef701332379306a6ad546", }, + { "f9c4bfad9e2a3d98c44c12734881a6f217d6c9523cc210772fad1297993454b4", "b85960fcadda8d0a0960559b6b7818a0d8d4574b4e928b17c9b498fa9ffab4ef", "6a1d0ef23ce0b40a7077ecb7b7264945054e3bdb58ee25e1b0ee8b3e19dbfcdc", "bb145dddcb75074a6a03249fca1aa7d6fa9549e3ed965f138ca5e7071b7878f2", "87d3faea4a98e41009eb8625611ea0fc12094c295af540c126c14a0f55afa76e", }, + { "656df4789a369d220aceb7b318517787d27004ecccedea019d623bcb2d79f5ff", "acf83e30afb2a5066728ec5d93564c08abe5e68e3a2a2ff953bdcf4d44f9da06", "bdda65efe56d7890286aada1452f62f85ba157d0b4621ba641de15d8d1c9e331", "958beef5dc6babc6de383c32ad7dd3a6d6eb8bb3236ed5558eec0f9eb31e5458", "6f6d4ee36d9d76e462c9635adfbb6073134a276cfc7cb86762004ec47197afa0", }, + }; + + HDNode node; + ed25519_secret_key private_key; + uint8_t chain_code[32]; + ed25519_public_key public_key, mul; + uint8_t shared_key[SHA3_256_DIGEST_LENGTH]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + nem_private_key(tests[i].private_key, private_key); + + ck_assert(hdnode_from_xprv(0, 0, chain_code, private_key, ED25519_KECCAK_NAME, &node)); + memcpy(public_key, fromhex(tests[i].public_key), 32); + + ck_assert(hdnode_get_nem_shared_key(&node, public_key, fromhex(tests[i].salt), mul, shared_key)); + ck_assert_mem_eq(mul, fromhex(tests[i].mul), sizeof(mul)); + ck_assert_mem_eq(shared_key, fromhex(tests[i].shared_key), sizeof(shared_key)); + } +} +END_TEST + +// test vectors from https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/4.test-cipher.dat +START_TEST(test_nem_cipher) +{ + static const struct { + const char *private_key; + const char *public_key; + const char *salt; + const char *iv; + const char *input; + const char *output; + } tests[] = { + { "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", "83616c67f076d356fd1288a6e0fd7a60488ba312a3adf0088b1b33c7655c3e6a", "a73ff5c32f8fd055b09775817a6a3f95", "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", "70815da779b1b954d7a7f00c16940e9917a0412a06a444b539bf147603eef87f", }, + { "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", "703ce0b1d276b10eef35672df03234385a903460db18ba9d4e05b3ad31abb284", "91246c2d5493867c4fa3e78f85963677", "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", "564b2f40d42c0efc1bd6f057115a5abd1564cae36d7ccacf5d825d38401aa894", }, + { "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", "b22e8e8e7373ac31ca7f0f6eb8b93130aba5266772a658593f3a11792e7e8d92", "9f8e33d82374dad6aac0e3dbe7aea704", "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", "7cab88d00a3fc656002eccbbd966e1d5d14a3090d92cf502cdbf843515625dcf", }, + { "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", "af646c54cd153dffe453b60efbceeb85c1e95a414ea0036c4da94afb3366f5d9", "6acdf8e01acc8074ddc807281b6af888", "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", "aa70543a485b63a4dd141bb7fd78019092ac6fad731e914280a287c7467bae1a", }, + { "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", "d9c0d386636c8a024935c024589f9cd39e820a16485b14951e690a967830e269", "f2e9f18aeb374965f54d2f4e31189a8f", "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", "33d97c216ea6498dfddabf94c2e2403d73efc495e9b284d9d90aaff840217d25", }, + { "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", "06c227baac1ae3b0b1dc583f4850f13f9ba5d53be4a98fa5c3ea16217847530d", "3735123e78c44895df6ea33fa57e9a72", "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", "d5b5d66ba8cee0eb7ecf95b143fa77a46d6de13749e12eff40f5a7e649167ccb", }, + { "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", "92f55ba5bc6fc2f23e3eedc299357c71518e36ba2447a4da7a9dfe9dfeb107b5", "1cbc4982e53e370052af97ab088fa942", "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", "d48ef1ef526d805656cfc932aff259eadb17aa3391dde1877a722cba31d935b2", }, + { "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", "10f15a39ba49866292a43b7781bc71ca8bbd4889f1616461caf056bcb91b0158", "c40d531d92bfee969dce91417346c892", "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a4", "e6d75afdb542785669b42198577c5b358d95397d71ec6f5835dca46d332cc08dbf73ea790b7bcb169a65719c0d55054c", }, + { "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", "9c01ed42b219b3bbe1a43ae9d7af5c1dd09363baacfdba8f4d03d1046915e26e", "059a35d5f83249e632790015ed6518b9", "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a4", "5ef11aadff2eccee8b712dab968fa842eb770818ec0e6663ed242ea8b6bbc1c66d6285ee5b5f03d55dfee382fb4fa25d", }, + { "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", "bc1067e2a7415ea45ff1ca9894338c591ff15f2e57ae2789ae31b9d5bea0f11e", "8c73f0d6613898daeefa3cf8b0686d37", "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a4", "6d220213b1878cd40a458f2a1e6e3b48040455fdf504dcd857f4f2ca1ad642e3a44fc401d04e339d302f66a9fad3d919", }, + { "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", "cf4a21cb790552165827b678ca9695fcaf77566d382325112ff79483455de667", "bfbf5482e06f55b88bdd9e053b7eee6e", "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a4", "1198a78c29c215d5c450f7b8513ead253160bc9fde80d9cc8e6bee2efe9713cf5a09d6293c41033271c9e8c22036a28b", }, + { "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", "eba5eae8aef79114082c3e70baef95bb02edf13b3897e8be7a70272962ef8838", "af9a56da3da18e2fbd2948a16332532b", "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a4", "1062ab5fbbdee9042ad35bdadfd3047c0a2127fe0f001da1be1b0582185edfc9687be8d68f85795833bb04af9cedd3bb", }, + { "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", "518f8dfd0c138f1ffb4ea8029db15441d70abd893c3d767dc668f23ba7770e27", "42d28307974a1b2a2d921d270cfce03b", "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a4", "005e49fb7c5da540a84b034c853fc9f78a6b901ea495aed0c2abd4f08f1a96f9ffefc6a57f1ac09e0aea95ca0f03ffd8", }, + { "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", "582fdf58b53715c26e10ba809e8f2ab70502e5a3d4e9a81100b7227732ab0bbc", "91f2aad3189bb2edc93bc891e73911ba", "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a4", "821a69cb16c57f0cb866e590b38069e35faec3ae18f158bb067db83a11237d29ab1e6b868b3147236a0958f15c2e2167", }, + { "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", "a415b4c006118fb72fc37b2746ef288e23ac45c8ff7ade5f368a31557b6ac93a", "2b7c5f75606c0b8106c6489ea5657a9e", "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", "2781d5ee8ef1cb1596f8902b33dfae5045f84a987ca58173af5830dbce386062", }, + { "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", "47e73ec362ea82d3a7c5d55532ad51d2cdf5316b981b2b2bd542b0efa027e8ea", "b2193f59030c8d05a7d3577b7f64dd33", "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", "3f43912db8dd6672b9996e5272e18c4b88fec9d7e8372db9c5f4709a4af1d86f", }, + { "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", "aaa006c57b6d1e402650577fe9787d8d285f4bacd7c01f998be49c766f8860c7", "130304ddb9adc8870cf56bcae9487b7f", "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", "878cc7d8c0ef8dac0182a78eedc8080a402f59d8062a6b4ca8f4a74f3c3b3de7", }, + { "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", "28dc7ccd6c2a939eef64b8be7b9ae248295e7fcd8471c22fa2f98733fea97611", "cb13890d3a11bc0a7433738263006710", "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", "e74ded846bebfa912fa1720e4c1415e6e5df7e7a1a7fedb5665d68f1763209a4", }, + { "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", "79974fa2cad95154d0873902c153ccc3e7d54b17f2eeb3f29b6344cad9365a9a", "22123357979d20f44cc8eb0263d84e0e", "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", "eb14dec7b8b64d81a2ee4db07b0adf144d4f79a519bbf332b823583fa2d45405", }, + { "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", "3409a6f8c4dcd9bd04144eb67e55a98696b674735b01bf1196191f29871ef966", "a823a0965969380ea1f8659ea5fd8fdd", "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", "00a7eb708eae745847173f8217efb05be13059710aee632e3f471ac3c6202b51", }, + }; + + HDNode node; + ed25519_secret_key private_key; + uint8_t chain_code[32]; + ed25519_public_key public_key; + uint8_t salt[sizeof(public_key)]; + + uint8_t iv[AES_BLOCK_SIZE]; + uint8_t buffer[FROMHEX_MAXLEN]; + + uint8_t input[FROMHEX_MAXLEN]; + uint8_t output[FROMHEX_MAXLEN]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + nem_private_key(tests[i].private_key, private_key); + + ck_assert(hdnode_from_xprv(0, 0, chain_code, private_key, ED25519_KECCAK_NAME, &node)); + memcpy(public_key, fromhex(tests[i].public_key), 32); + memcpy(salt, fromhex(tests[i].salt), sizeof(salt)); + + size_t input_size = strlen(tests[i].input) / 2; + size_t output_size = strlen(tests[i].output) / 2; + + memcpy(input, fromhex(tests[i].input), input_size); + memcpy(output, fromhex(tests[i].output), output_size); + + memcpy(iv, fromhex(tests[i].iv), sizeof(iv)); + ck_assert(hdnode_nem_encrypt(&node, public_key, iv, salt, input, input_size, buffer)); + ck_assert_int_eq(output_size, NEM_ENCRYPTED_SIZE(input_size)); + ck_assert_mem_eq(buffer, output, output_size); + + memcpy(iv, fromhex(tests[i].iv), sizeof(iv)); + ck_assert(hdnode_nem_decrypt(&node, public_key, iv, salt, output, output_size, buffer)); + ck_assert_int_eq(input_size, NEM_DECRYPTED_SIZE(buffer, output_size)); + ck_assert_mem_eq(buffer, input, input_size); + } +} +END_TEST + +START_TEST(test_nem_transaction_transfer) +{ + nem_transaction_ctx ctx; + + uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; + + // http://bob.nem.ninja:8765/#/transfer/0acbf8df91e6a65dc56c56c43d65f31ff2a6a48d06fc66e78c7f3436faf3e74f + + nem_transaction_start(&ctx, fromhex("e59ef184a612d4c3c4d89b5950eb57262c69862b2f96e59c5043bf41765c482f"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_transfer(&ctx, + NEM_NETWORK_TESTNET, 0, NULL, 0, 0, + "TBGIMRE4SBFRUJXMH7DVF2IBY36L2EDWZ37GVSC4", 50000000000000, + NULL, 0, false, + 0)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("0acbf8df91e6a65dc56c56c43d65f31ff2a6a48d06fc66e78c7f3436faf3e74f"), sizeof(hash)); + + // http://bob.nem.ninja:8765/#/transfer/3409d9ece28d6296d6d5e220a7e3cb8641a3fb235ffcbd20c95da64f003ace6c + + nem_transaction_start(&ctx, fromhex("994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_transfer(&ctx, + NEM_NETWORK_TESTNET, 14072100, NULL, 194000000, 14075700, + "TBLOODPLWOWMZ2TARX4RFPOSOWLULHXMROBN2WXI", 3000000, + (uint8_t *) "sending you 3 pairs of paddles\n", 31, false, + 2)); + + ck_assert(nem_transaction_write_mosaic(&ctx, + "gimre.games.pong", "paddles", 2)); + + ck_assert(nem_transaction_write_mosaic(&ctx, + "nem", "xem", 44000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("3409d9ece28d6296d6d5e220a7e3cb8641a3fb235ffcbd20c95da64f003ace6c"), sizeof(hash)); + + // http://chain.nem.ninja/#/transfer/e90e98614c7598fbfa4db5411db1b331d157c2f86b558fb7c943d013ed9f71cb + + nem_transaction_start(&ctx, fromhex("8d07f90fb4bbe7715fa327c926770166a11be2e494a970605f2e12557f66c9b9"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_transfer(&ctx, + NEM_NETWORK_MAINNET, 0, NULL, 0, 0, + "NBT3WHA2YXG2IR4PWKFFMO772JWOITTD2V4PECSB", 5175000000000, + (uint8_t *) "Good luck!", 10, false, + 0)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("e90e98614c7598fbfa4db5411db1b331d157c2f86b558fb7c943d013ed9f71cb"), sizeof(hash)); + + // http://chain.nem.ninja/#/transfer/40e89160e6f83d37f7c82defc0afe2c1605ae8c919134570a51dd27ea1bb516c + + nem_transaction_start(&ctx, fromhex("f85ab43dad059b9d2331ddacc384ad925d3467f03207182e01296bacfb242d01"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_transfer(&ctx, + NEM_NETWORK_MAINNET, 77229, NULL, 30000000, 80829, + "NALICEPFLZQRZGPRIJTMJOCPWDNECXTNNG7QLSG3", 30000000, + fromhex("4d9dcf9186967d30be93d6d5404ded22812dbbae7c3f0de5" + "01bcd7228cba45bded13000eec7b4c6215fc4d3588168c92" + "18167cec98e6977359153a4132e050f594548e61e0dc61c1" + "53f0f53c5e65c595239c9eb7c4e7d48e0f4bb8b1dd2f5ddc"), 96, true, + 0)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("40e89160e6f83d37f7c82defc0afe2c1605ae8c919134570a51dd27ea1bb516c"), sizeof(hash)); + + // http://chain.nem.ninja/#/transfer/882dca18dcbe075e15e0ec5a1d7e6ccd69cc0f1309ffd3fde227bfbc107b3f6e + + nem_transaction_start(&ctx, fromhex("f85ab43dad059b9d2331ddacc384ad925d3467f03207182e01296bacfb242d01"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_transfer(&ctx, + NEM_NETWORK_MAINNET, 26730750, NULL, 179500000, 26734350, + "NBE223WPKEBHQPCYUC4U4CDUQCRRFMPZLOQLB5OP", 1000000, + (uint8_t *) "enjoy! :)", 9, false, + 1)); + + ck_assert(nem_transaction_write_mosaic(&ctx, + "imre.g", "tokens", 1)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("882dca18dcbe075e15e0ec5a1d7e6ccd69cc0f1309ffd3fde227bfbc107b3f6e"), sizeof(hash)); +} +END_TEST + +START_TEST(test_nem_transaction_multisig) +{ + nem_transaction_ctx ctx, other_trans; + + uint8_t buffer[1024], inner[1024]; + const uint8_t *signature; + + // http://bob.nem.ninja:8765/#/multisig/7d3a7087023ee29005262016706818579a2b5499eb9ca76bad98c1e6f4c46642 + + nem_transaction_start(&other_trans, fromhex("abac2ee3d4aaa7a3bfb65261a00cc04c761521527dd3f2cf741e2815cbba83ac"), inner, sizeof(inner)); + + ck_assert(nem_transaction_create_aggregate_modification(&other_trans, + NEM_NETWORK_TESTNET, 3939039, NULL, 16000000, 3960639, + 1, false)); + + ck_assert(nem_transaction_write_cosignatory_modification(&other_trans, 2, fromhex("e6cff9b3725a91f31089c3acca0fac3e341c00b1c8c6e9578f66c4514509c3b3"))); + + nem_transaction_start(&ctx, fromhex("59d89076964742ef2a2089d26a5aa1d2c7a7bb052a46c1de159891e91ad3d76e"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_multisig(&ctx, + NEM_NETWORK_TESTNET, 3939039, NULL, 6000000, 3960639, + &other_trans)); + + signature = fromhex("933930a8828b560168bddb3137df9252048678d829aa5135fa27bb306ff6562efb92755462988b852b0314bde058487d00e47816b6fb7df6bcfd7e1f150d1d00"); + ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, ctx.public_key, signature), 0); + + nem_transaction_start(&ctx, fromhex("71cba4f2a28fd19f902ba40e9937994154d9eeaad0631d25d525ec37922567d4"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_multisig_signature(&ctx, + NEM_NETWORK_TESTNET, 3939891, NULL, 6000000, 3961491, + &other_trans)); + + signature = fromhex("a849f13bfeeba808a8a4a79d579febe584d831a3a6ad03da3b9d008530b3d7a79fcf7156121cd7ee847029d94af7ea7a683ca8e643dc5e5f489557c2054b830b"); + ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, ctx.public_key, signature), 0); + + // http://chain.nem.ninja/#/multisig/1016cf3bdd61bd57b9b2b07b6ff2dee390279d8d899265bdc23d42360abe2e6c + + nem_transaction_start(&other_trans, fromhex("a1df5306355766bd2f9a64efdc089eb294be265987b3359093ae474c051d7d5a"), inner, sizeof(inner)); + + ck_assert(nem_transaction_create_provision_namespace(&other_trans, + NEM_NETWORK_MAINNET, 59414272, NULL, 20000000, 59500672, + "dim", NULL, + "NAMESPACEWH4MKFMBCVFERDPOOP4FK7MTBXDPZZA", 5000000000)); + + nem_transaction_start(&ctx, fromhex("cfe58463f0eaebceb5d00717f8aead49171a5d7c08f6b1299bd534f11715acc9"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_multisig(&ctx, + NEM_NETWORK_MAINNET, 59414272, NULL, 6000000, 59500672, + &other_trans)); + + signature = fromhex("52a876a37511068fe214bd710b2284823921ec7318c01e083419a062eae5369c9c11c3abfdb590f65c717fab82873431d52be62e10338cb5656d1833bbdac70c"); + ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, ctx.public_key, signature), 0); + + nem_transaction_start(&ctx, fromhex("1b49b80203007117d034e45234ffcdf402c044aeef6dbb06351f346ca892bce2"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_multisig_signature(&ctx, + NEM_NETWORK_MAINNET, 59414342, NULL, 6000000, 59500742, + &other_trans)); + + signature = fromhex("b9a59239e5d06992c28840034ff7a7f13da9c4e6f4a6f72c1b1806c3b602f83a7d727a345371f5d15abf958208a32359c6dd77bde92273ada8ea6fda3dc76b00"); + ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, ctx.public_key, signature), 0); + + nem_transaction_start(&ctx, fromhex("7ba4b39209f1b9846b098fe43f74381e43cb2882ccde780f558a63355840aa87"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_multisig_signature(&ctx, + NEM_NETWORK_MAINNET, 59414381, NULL, 6000000, 59500781, + &other_trans)); + + signature = fromhex("e874ae9f069f0538008631d2df9f2e8a59944ff182e8672f743d2700fb99224aafb7a0ab09c4e9ea39ee7c8ca04a8a3d6103ae1122d87772e871761d4f00ca01"); + ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, ctx.public_key, signature), 0); +} +END_TEST + +START_TEST(test_nem_transaction_provision_namespace) +{ + nem_transaction_ctx ctx; + + uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; + + // http://bob.nem.ninja:8765/#/namespace/f7cab28da57204d01a907c697836577a4ae755e6c9bac60dcc318494a22debb3 + + nem_transaction_start(&ctx, fromhex("84afa1bbc993b7f5536344914dde86141e61f8cbecaf8c9cefc07391f3287cf5"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_provision_namespace(&ctx, + NEM_NETWORK_TESTNET, 56999445, NULL, 20000000, 57003045, + "gimre", NULL, + "TAMESPACEWH4MKFMBCVFERDPOOP4FK7MTDJEYP35", 5000000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("f7cab28da57204d01a907c697836577a4ae755e6c9bac60dcc318494a22debb3"), sizeof(hash)); + + // http://bob.nem.ninja:8765/#/namespace/7ddd5fe607e1bfb5606e0ac576024c318c8300d237273117d4db32a60c49524d + + nem_transaction_start(&ctx, fromhex("244fa194e2509ac0d2fbc18779c2618d8c2ebb61c16a3bcbebcf448c661ba8dc"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_provision_namespace(&ctx, + NEM_NETWORK_TESTNET, 21496797, NULL, 108000000, 21500397, + "misc", "alice", + "TAMESPACEWH4MKFMBCVFERDPOOP4FK7MTDJEYP35", 5000000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("7ddd5fe607e1bfb5606e0ac576024c318c8300d237273117d4db32a60c49524d"), sizeof(hash)); + + // http://chain.nem.ninja/#/namespace/57071aad93ca125dc231dc02c07ad8610cd243d35068f9b36a7d231383907569 + + nem_transaction_start(&ctx, fromhex("9f3c14f304309c8b72b2821339c4428793b1518bea72d58dd01f19d523518614"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_provision_namespace(&ctx, + NEM_NETWORK_MAINNET, 26699717, NULL, 108000000, 26703317, + "sex", NULL, + "NAMESPACEWH4MKFMBCVFERDPOOP4FK7MTBXDPZZA", 50000000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("57071aad93ca125dc231dc02c07ad8610cd243d35068f9b36a7d231383907569"), sizeof(hash)); +} +END_TEST + +START_TEST(test_nem_transaction_mosaic_creation) +{ + nem_transaction_ctx ctx; + + uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; + + // http://bob.nem.ninja:8765/#/mosaic/68364353c29105e6d361ad1a42abbccbf419cfc7adb8b74c8f35d8f8bdaca3fa/0 + + nem_transaction_start(&ctx, fromhex("994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_creation(&ctx, + NEM_NETWORK_TESTNET, 14070896, NULL, 108000000, 14074496, + "gimre.games.pong", "paddles", + "Paddles for the bong game.\n", + 0, 10000, true, true, + 0, 0, NULL, NULL, NULL, + "TBMOSAICOD4F54EE5CDMR23CCBGOAM2XSJBR5OLC", 50000000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("68364353c29105e6d361ad1a42abbccbf419cfc7adb8b74c8f35d8f8bdaca3fa"), sizeof(hash)); + + // http://bob.nem.ninja:8765/#/mosaic/b2f4a98113ff1f3a8f1e9d7197aa982545297fe0aa3fa6094af8031569953a55/0 + + nem_transaction_start(&ctx, fromhex("244fa194e2509ac0d2fbc18779c2618d8c2ebb61c16a3bcbebcf448c661ba8dc"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_creation(&ctx, + NEM_NETWORK_TESTNET, 21497248, NULL, 108000000, 21500848, + "alice.misc", "bar", + "Special offer: get one bar extra by bying one foo!", + 0, 1000, false, true, + 1, 1, "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", "nem", "xem", + "TBMOSAICOD4F54EE5CDMR23CCBGOAM2XSJBR5OLC", 50000000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("b2f4a98113ff1f3a8f1e9d7197aa982545297fe0aa3fa6094af8031569953a55"), sizeof(hash)); + + // http://chain.nem.ninja/#/mosaic/269c6fda657aba3053a0e5b138c075808cc20e244e1182d9b730798b60a1f77b/0 + + nem_transaction_start(&ctx, fromhex("58956ac77951622dc5f1c938affbf017c458e30e6b21ddb5783d38b302531f23"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_creation(&ctx, + NEM_NETWORK_MAINNET, 26729938, NULL, 108000000, 26733538, + "jabo38", "red_token", + "This token is to celebrate the release of Namespaces and Mosaics on the NEM system. " + "This token was the fist ever mosaic created other than nem.xem. " + "There are only 10,000 Red Tokens that will ever be created. " + "It has no levy and can be traded freely among third parties.", + 2, 10000, false, true, + 0, 0, NULL, NULL, NULL, + "NBMOSAICOD4F54EE5CDMR23CCBGOAM2XSIUX6TRS", 50000000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("269c6fda657aba3053a0e5b138c075808cc20e244e1182d9b730798b60a1f77b"), sizeof(hash)); + + // http://chain.nem.ninja/#/mosaic/e8dc14821dbea4831d9051f86158ef348001447968fc22c01644fdaf2bda75c6/0 + + nem_transaction_start(&ctx, fromhex("a1df5306355766bd2f9a64efdc089eb294be265987b3359093ae474c051d7d5a"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_creation(&ctx, + NEM_NETWORK_MAINNET, 69251020, NULL, 20000000, 69337420, + "dim", "coin", + "DIM COIN", + 6, 9000000000, false, true, + 2, 10, "NCGGLVO2G3CUACVI5GNX2KRBJSQCN4RDL2ZWJ4DP", "dim", "coin", + "NBMOSAICOD4F54EE5CDMR23CCBGOAM2XSIUX6TRS", 500000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("e8dc14821dbea4831d9051f86158ef348001447968fc22c01644fdaf2bda75c6"), sizeof(hash)); +} +END_TEST + +START_TEST(test_nem_transaction_mosaic_supply_change) +{ + nem_transaction_ctx ctx; + + uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; + + // http://bigalice2.nem.ninja:7890/transaction/get?hash=33a50fdd4a54913643a580b2af08b9a5b51b7cee922bde380e84c573a7969c50 + + nem_transaction_start(&ctx, fromhex("994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_supply_change(&ctx, + NEM_NETWORK_TESTNET, 14071648, NULL, 108000000, 14075248, + "gimre.games.pong", "paddles", + 1, 1234)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("33a50fdd4a54913643a580b2af08b9a5b51b7cee922bde380e84c573a7969c50"), sizeof(hash)); + + // http://bigalice2.nem.ninja:7890/transaction/get?hash=1ce8e8894d077a66ff22294b000825d090a60742ec407efd80eb8b19657704f2 + + nem_transaction_start(&ctx, fromhex("84afa1bbc993b7f5536344914dde86141e61f8cbecaf8c9cefc07391f3287cf5"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_supply_change(&ctx, + NEM_NETWORK_TESTNET, 14126909, NULL, 108000000, 14130509, + "jabo38_ltd.fuzzy_kittens_cafe", "coupons", + 2, 1)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("1ce8e8894d077a66ff22294b000825d090a60742ec407efd80eb8b19657704f2"), sizeof(hash)); + + // http://bigalice3.nem.ninja:7890/transaction/get?hash=694e493e9576d2bcf60d85747e302ac2e1cc27783187947180d4275a713ff1ff + + nem_transaction_start(&ctx, fromhex("b7ccc27b21ba6cf5c699a8dc86ba6ba98950442597ff9fa30e0abe0f5f4dd05d"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_supply_change(&ctx, + NEM_NETWORK_MAINNET, 53377685, NULL, 20000000, 53464085, + "abvapp", "abv", + 1, 9000000)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("694e493e9576d2bcf60d85747e302ac2e1cc27783187947180d4275a713ff1ff"), sizeof(hash)); + + // http://bigalice3.nem.ninja:7890/transaction/get?hash=09836334e123970e068d5b411e4d1df54a3ead10acf1ad5935a2cdd9f9680185 + + nem_transaction_start(&ctx, fromhex("75f001a8641e2ce5c4386883dda561399ed346177411b492a677b73899502f13"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_mosaic_supply_change(&ctx, + NEM_NETWORK_MAINNET, 55176304, NULL, 20000000, 55262704, + "sushi", "wasabi", + 2, 20)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("09836334e123970e068d5b411e4d1df54a3ead10acf1ad5935a2cdd9f9680185"), sizeof(hash)); +} +END_TEST + +START_TEST(test_nem_transaction_aggregate_modification) +{ + nem_transaction_ctx ctx; + + uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; + + // http://bob.nem.ninja:8765/#/aggregate/6a55471b17159e5b6cd579c421e95a4e39d92e3f78b0a55ee337e785a601d3a2 + + nem_transaction_start(&ctx, fromhex("462ee976890916e54fa825d26bdd0235f5eb5b6a143c199ab0ae5ee9328e08ce"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_aggregate_modification(&ctx, + NEM_NETWORK_TESTNET, 0, NULL, 22000000, 0, + 2, false)); + + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("c54d6e33ed1446eedd7f7a80a588dd01857f723687a09200c1917d5524752f8b"))); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("6a55471b17159e5b6cd579c421e95a4e39d92e3f78b0a55ee337e785a601d3a2"), sizeof(hash)); + + // http://bob.nem.ninja:8765/#/aggregate/1fbdae5ba753e68af270930413ae90f671eb8ab58988116684bac0abd5726584 + + nem_transaction_start(&ctx, fromhex("6bf7849c1eec6a2002995cc457dc00c4e29bad5c88de63f51e42dfdcd7b2131d"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_aggregate_modification(&ctx, + NEM_NETWORK_TESTNET, 6542254, NULL, 40000000, 6545854, + 4, true)); + + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("5f53d076c8c3ec3110b98364bc423092c3ec2be2b1b3c40fd8ab68d54fa39295"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("9eb199c2b4d406f64cb7aa5b2b0815264b56ba8fe44d558a6cb423a31a33c4c2"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("94b2323dab23a3faba24fa6ddda0ece4fbb06acfedd74e76ad9fae38d006882b"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("d88c6ee2a2cd3929d0d76b6b14ecb549d21296ab196a2b3a4cb2536bcce32e87"))); + + ck_assert(nem_transaction_write_minimum_cosignatories(&ctx, 2)); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("1fbdae5ba753e68af270930413ae90f671eb8ab58988116684bac0abd5726584"), sizeof(hash)); + + // http://chain.nem.ninja/#/aggregate/cc64ca69bfa95db2ff7ac1e21fe6d27ece189c603200ebc9778d8bb80ca25c3c + + nem_transaction_start(&ctx, fromhex("f41b99320549741c5cce42d9e4bb836d98c50ed5415d0c3c2912d1bb50e6a0e5"), buffer, sizeof(buffer)); + + ck_assert(nem_transaction_create_aggregate_modification(&ctx, + NEM_NETWORK_MAINNET, 0, NULL, 40000000, 0, + 5, false)); + + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("1fbdbdde28daf828245e4533765726f0b7790e0b7146e2ce205df3e86366980b"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("f94e8702eb1943b23570b1b83be1b81536df35538978820e98bfce8f999e2d37"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("826cedee421ff66e708858c17815fcd831a4bb68e3d8956299334e9e24380ba8"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("719862cd7d0f4e875a6a0274c9a1738f38f40ad9944179006a54c34724c1274d"))); + ck_assert(nem_transaction_write_cosignatory_modification(&ctx, 1, fromhex("43aa69177018fc3e2bdbeb259c81cddf24be50eef9c5386db51d82386c41475a"))); + + keccak_256(ctx.buffer, ctx.offset, hash); + ck_assert_mem_eq(hash, fromhex("cc64ca69bfa95db2ff7ac1e21fe6d27ece189c603200ebc9778d8bb80ca25c3c"), sizeof(hash)); +} +END_TEST + +START_TEST(test_multibyte_address) +{ + uint8_t priv_key[32]; + char wif[57]; + uint8_t pub_key[33]; + char address[40]; + uint8_t decode[24]; + int res; + + memcpy(priv_key, fromhex("47f7616ea6f9b923076625b4488115de1ef1187f760e65f89eb6f4f7ff04b012"), 32); + ecdsa_get_wif(priv_key, 0, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "13QtoXmbhELWcrwD9YA9KzvXy5rTaptiNuFR8L8ArpBNn4xmQj4N"); + ecdsa_get_wif(priv_key, 0x12, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "3hrF6SFnqzpzABB36uGDf8dJSuUCcMmoJrTmCWMshRkBr2Vx86qJ"); + ecdsa_get_wif(priv_key, 0x1234, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "CtPTF9awbVbfDWGepGdVhB3nBhr4HktUGya8nf8dLxgC8tbqBreB9"); + ecdsa_get_wif(priv_key, 0x123456, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "uTrDevVQt5QZgoL3iJ1cPWHaCz7ZMBncM7QXZfCegtxiMHqBvWoYJa"); + ecdsa_get_wif(priv_key, 0x12345678, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "4zZWMzv1SVbs95pmLXWrXJVp9ntPEam1mfwb6CXBLn9MpWNxLg9huYgv"); + ecdsa_get_wif(priv_key, 0xffffffff, HASHER_SHA2, wif, sizeof(wif)); ck_assert_str_eq(wif, "y9KVfV1RJXcTxpVjeuh6WYWh8tMwnAUeyUwDEiRviYdrJ61njTmnfUjE"); + + memcpy(pub_key, fromhex("0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"), 33); + ecdsa_get_address(pub_key, 0, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8"); + ecdsa_get_address(pub_key, 0x12, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "8SCrMR2yYF7ciqoDbav7VLLTsVx5dTVPPq"); + ecdsa_get_address(pub_key, 0x1234, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "ZLH8q1UgMPg8o2s1MD55YVMpPV7vqms9kiV"); + ecdsa_get_address(pub_key, 0x123456, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "3ThqvsQVFnbiF66NwHtfe2j6AKn75DpLKpQSq"); + ecdsa_get_address(pub_key, 0x12345678, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44"); + ecdsa_get_address(pub_key, 0xffffffff, HASHER_SHA2, address, sizeof(address)); ck_assert_str_eq(address, "3diW7paWGJyZRLGqMJZ55DMfPExob8QxQHkrfYT"); + + res = ecdsa_address_decode("1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8", 0, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("0079fbfc3f34e7745860d76137da68f362380c606c"), 21); + res = ecdsa_address_decode("8SCrMR2yYF7ciqoDbav7VLLTsVx5dTVPPq", 0x12, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("1279fbfc3f34e7745860d76137da68f362380c606c"), 21); + res = ecdsa_address_decode("ZLH8q1UgMPg8o2s1MD55YVMpPV7vqms9kiV", 0x1234, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("123479fbfc3f34e7745860d76137da68f362380c606c"), 21); + res = ecdsa_address_decode("3ThqvsQVFnbiF66NwHtfe2j6AKn75DpLKpQSq", 0x123456, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("12345679fbfc3f34e7745860d76137da68f362380c606c"), 21); + res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44", 0x12345678, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("1234567879fbfc3f34e7745860d76137da68f362380c606c"), 21); + res = ecdsa_address_decode("3diW7paWGJyZRLGqMJZ55DMfPExob8QxQHkrfYT", 0xffffffff, HASHER_SHA2, decode); + ck_assert_int_eq(res, 1); + ck_assert_mem_eq(decode, fromhex("ffffffff79fbfc3f34e7745860d76137da68f362380c606c"), 21); + + // wrong length + res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44", 0x123456, HASHER_SHA2, decode); + ck_assert_int_eq(res, 0); + + // wrong address prefix + res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44", 0x22345678, HASHER_SHA2, decode); + ck_assert_int_eq(res, 0); + + // wrong checksum + res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL45", 0x12345678, HASHER_SHA2, decode); + ck_assert_int_eq(res, 0); +} +END_TEST + +// https://tools.ietf.org/html/rfc6229#section-2 +START_TEST(test_rc4_rfc6229) +{ + static const size_t offsets[] = { + 0x0, + 0xf0, + 0x1f0, + 0x2f0, + 0x3f0, + 0x5f0, + 0x7f0, + 0xbf0, + 0xff0, + }; + + static const struct { + char key[65]; + char vectors[sizeof(offsets) / sizeof(*offsets)][65]; + } tests[] = { + { + "0102030405", + { + "b2396305f03dc027ccc3524a0a1118a8" "6982944f18fc82d589c403a47a0d0919", + "28cb1132c96ce286421dcaadb8b69eae" "1cfcf62b03eddb641d77dfcf7f8d8c93", + "42b7d0cdd918a8a33dd51781c81f4041" "6459844432a7da923cfb3eb4980661f6", + "ec10327bde2beefd18f9277680457e22" "eb62638d4f0ba1fe9fca20e05bf8ff2b", + "45129048e6a0ed0b56b490338f078da5" "30abbcc7c20b01609f23ee2d5f6bb7df", + "3294f744d8f9790507e70f62e5bbceea" "d8729db41882259bee4f825325f5a130", + "1eb14a0c13b3bf47fa2a0ba93ad45b8b" "cc582f8ba9f265e2b1be9112e975d2d7", + "f2e30f9bd102ecbf75aaade9bc35c43c" "ec0e11c479dc329dc8da7968fe965681", + "068326a2118416d21f9d04b2cd1ca050" "ff25b58995996707e51fbdf08b34d875", + } + }, { + "01020304050607", + { + "293f02d47f37c9b633f2af5285feb46b" "e620f1390d19bd84e2e0fd752031afc1", + "914f02531c9218810df60f67e338154c" "d0fdb583073ce85ab83917740ec011d5", + "75f81411e871cffa70b90c74c592e454" "0bb87202938dad609e87a5a1b079e5e4", + "c2911246b612e7e7b903dfeda1dad866" "32828f91502b6291368de8081de36fc2", + "f3b9a7e3b297bf9ad804512f9063eff1" "8ecb67a9ba1f55a5a067e2b026a3676f", + "d2aa902bd42d0d7cfd340cd45810529f" "78b272c96e42eab4c60bd914e39d06e3", + "f4332fd31a079396ee3cee3f2a4ff049" "05459781d41fda7f30c1be7e1246c623", + "adfd3868b8e51485d5e610017e3dd609" "ad26581c0c5be45f4cea01db2f3805d5", + "f3172ceffc3b3d997c85ccd5af1a950c" "e74b0b9731227fd37c0ec08a47ddd8b8", + } + }, { + "0102030405060708", + { + "97ab8a1bf0afb96132f2f67258da15a8" "8263efdb45c4a18684ef87e6b19e5b09", + "9636ebc9841926f4f7d1f362bddf6e18" "d0a990ff2c05fef5b90373c9ff4b870a", + "73239f1db7f41d80b643c0c52518ec63" "163b319923a6bdb4527c626126703c0f", + "49d6c8af0f97144a87df21d91472f966" "44173a103b6616c5d5ad1cee40c863d0", + "273c9c4b27f322e4e716ef53a47de7a4" "c6d0e7b226259fa9023490b26167ad1d", + "1fe8986713f07c3d9ae1c163ff8cf9d3" "8369e1a965610be887fbd0c79162aafb", + "0a0127abb44484b9fbef5abcae1b579f" "c2cdadc6402e8ee866e1f37bdb47e42c", + "26b51ea37df8e1d6f76fc3b66a7429b3" "bc7683205d4f443dc1f29dda3315c87b", + "d5fa5a3469d29aaaf83d23589db8c85b" "3fb46e2c8f0f068edce8cdcd7dfc5862", + } + }, { + "0102030405060708090a", + { + "ede3b04643e586cc907dc21851709902" "03516ba78f413beb223aa5d4d2df6711", + "3cfd6cb58ee0fdde640176ad0000044d" "48532b21fb6079c9114c0ffd9c04a1ad", + "3e8cea98017109979084b1ef92f99d86" "e20fb49bdb337ee48b8d8dc0f4afeffe", + "5c2521eacd7966f15e056544bea0d315" "e067a7031931a246a6c3875d2f678acb", + "a64f70af88ae56b6f87581c0e23e6b08" "f449031de312814ec6f319291f4a0516", + "bdae85924b3cb1d0a2e33a30c6d79599" "8a0feddbac865a09bcd127fb562ed60a", + "b55a0a5b51a12a8be34899c3e047511a" "d9a09cea3ce75fe39698070317a71339", + "552225ed1177f44584ac8cfa6c4eb5fc" "7e82cbabfc95381b080998442129c2f8", + "1f135ed14ce60a91369d2322bef25e3c" "08b6be45124a43e2eb77953f84dc8553", + } + }, { + "0102030405060708090a0b0c0d0e0f10", + { + "9ac7cc9a609d1ef7b2932899cde41b97" "5248c4959014126a6e8a84f11d1a9e1c", + "065902e4b620f6cc36c8589f66432f2b" "d39d566bc6bce3010768151549f3873f", + "b6d1e6c4a5e4771cad79538df295fb11" "c68c1d5c559a974123df1dbc52a43b89", + "c5ecf88de897fd57fed301701b82a259" "eccbe13de1fcc91c11a0b26c0bc8fa4d", + "e7a72574f8782ae26aabcf9ebcd66065" "bdf0324e6083dcc6d3cedd3ca8c53c16", + "b40110c4190b5622a96116b0017ed297" "ffa0b514647ec04f6306b892ae661181", + "d03d1bc03cd33d70dff9fa5d71963ebd" "8a44126411eaa78bd51e8d87a8879bf5", + "fabeb76028ade2d0e48722e46c4615a3" "c05d88abd50357f935a63c59ee537623", + "ff38265c1642c1abe8d3c2fe5e572bf8" "a36a4c301ae8ac13610ccbc12256cacc", + } + }, { + "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", + { + "eaa6bd25880bf93d3f5d1e4ca2611d91" "cfa45c9f7e714b54bdfa80027cb14380", + "114ae344ded71b35f2e60febad727fd8" "02e1e7056b0f623900496422943e97b6", + "91cb93c787964e10d9527d999c6f936b" "49b18b42f8e8367cbeb5ef104ba1c7cd", + "87084b3ba700bade955610672745b374" "e7a7b9e9ec540d5ff43bdb12792d1b35", + "c799b596738f6b018c76c74b1759bd90" "7fec5bfd9f9b89ce6548309092d7e958", + "40f250b26d1f096a4afd4c340a588815" "3e34135c79db010200767651cf263073", + "f656abccf88dd827027b2ce917d464ec" "18b62503bfbc077fbabb98f20d98ab34", + "8aed95ee5b0dcbfbef4eb21d3a3f52f9" "625a1ab00ee39a5327346bddb01a9c18", + "a13a7c79c7e119b5ab0296ab28c300b9" "f3e4c0a2e02d1d01f7f0a74618af2b48", + } + }, { + "833222772a", + { + "80ad97bdc973df8a2e879e92a497efda" "20f060c2f2e5126501d3d4fea10d5fc0", + "faa148e99046181fec6b2085f3b20ed9" "f0daf5bab3d596839857846f73fbfe5a", + "1c7e2fc4639232fe297584b296996bc8" "3db9b249406cc8edffac55ccd322ba12", + "e4f9f7e0066154bbd125b745569bc897" "75d5ef262b44c41a9cf63ae14568e1b9", + "6da453dbf81e82334a3d8866cb50a1e3" "7828d074119cab5c22b294d7a9bfa0bb", + "adb89cea9a15fbe617295bd04b8ca05c" "6251d87fd4aaae9a7e4ad5c217d3f300", + "e7119bd6dd9b22afe8f89585432881e2" "785b60fd7ec4e9fcb6545f350d660fab", + "afecc037fdb7b0838eb3d70bcd268382" "dbc1a7b49d57358cc9fa6d61d73b7cf0", + "6349d126a37afcba89794f9804914fdc" "bf42c3018c2f7c66bfde524975768115", + } + }, { + "1910833222772a", + { + "bc9222dbd3274d8fc66d14ccbda6690b" "7ae627410c9a2be693df5bb7485a63e3", + "3f0931aa03defb300f060103826f2a64" "beaa9ec8d59bb68129f3027c96361181", + "74e04db46d28648d7dee8a0064b06cfe" "9b5e81c62fe023c55be42f87bbf932b8", + "ce178fc1826efecbc182f57999a46140" "8bdf55cd55061c06dba6be11de4a578a", + "626f5f4dce652501f3087d39c92cc349" "42daac6a8f9ab9a7fd137c6037825682", + "cc03fdb79192a207312f53f5d4dc33d9" "f70f14122a1c98a3155d28b8a0a8a41d", + "2a3a307ab2708a9c00fe0b42f9c2d6a1" "862617627d2261eab0b1246597ca0ae9", + "55f877ce4f2e1ddbbf8e13e2cde0fdc8" "1b1556cb935f173337705fbb5d501fc1", + "ecd0e96602be7f8d5092816cccf2c2e9" "027881fab4993a1c262024a94fff3f61", + } + }, { + "641910833222772a", + { + "bbf609de9413172d07660cb680716926" "46101a6dab43115d6c522b4fe93604a9", + "cbe1fff21c96f3eef61e8fe0542cbdf0" "347938bffa4009c512cfb4034b0dd1a7", + "7867a786d00a7147904d76ddf1e520e3" "8d3e9e1caefcccb3fbf8d18f64120b32", + "942337f8fd76f0fae8c52d7954810672" "b8548c10f51667f6e60e182fa19b30f7", + "0211c7c6190c9efd1237c34c8f2e06c4" "bda64f65276d2aacb8f90212203a808e", + "bd3820f732ffb53ec193e79d33e27c73" "d0168616861907d482e36cdac8cf5749", + "97b0f0f224b2d2317114808fb03af7a0" "e59616e469787939a063ceea9af956d1", + "c47e0dc1660919c11101208f9e69aa1f" "5ae4f12896b8379a2aad89b5b553d6b0", + "6b6b098d0c293bc2993d80bf0518b6d9" "8170cc3ccd92a698621b939dd38fe7b9", + } + }, { + "8b37641910833222772a", + { + "ab65c26eddb287600db2fda10d1e605c" "bb759010c29658f2c72d93a2d16d2930", + "b901e8036ed1c383cd3c4c4dd0a6ab05" "3d25ce4922924c55f064943353d78a6c", + "12c1aa44bbf87e75e611f69b2c38f49b" "28f2b3434b65c09877470044c6ea170d", + "bd9ef822de5288196134cf8af7839304" "67559c23f052158470a296f725735a32", + "8bab26fbc2c12b0f13e2ab185eabf241" "31185a6d696f0cfa9b42808b38e132a2", + "564d3dae183c5234c8af1e51061c44b5" "3c0778a7b5f72d3c23a3135c7d67b9f4", + "f34369890fcf16fb517dcaae4463b2dd" "02f31c81e8200731b899b028e791bfa7", + "72da646283228c14300853701795616f" "4e0a8c6f7934a788e2265e81d6d0c8f4", + "438dd5eafea0111b6f36b4b938da2a68" "5f6bfc73815874d97100f086979357d8", + } + }, { + "ebb46227c6cc8b37641910833222772a", + { + "720c94b63edf44e131d950ca211a5a30" "c366fdeacf9ca80436be7c358424d20b", + "b3394a40aabf75cba42282ef25a0059f" "4847d81da4942dbc249defc48c922b9f", + "08128c469f275342adda202b2b58da95" "970dacef40ad98723bac5d6955b81761", + "3cb89993b07b0ced93de13d2a11013ac" "ef2d676f1545c2c13dc680a02f4adbfe", + "b60595514f24bc9fe522a6cad7393644" "b515a8c5011754f59003058bdb81514e", + "3c70047e8cbc038e3b9820db601da495" "1175da6ee756de46a53e2b075660b770", + "00a542bba02111cc2c65b38ebdba587e" "5865fdbb5b48064104e830b380f2aede", + "34b21ad2ad44e999db2d7f0863f0d9b6" "84a9218fc36e8a5f2ccfbeae53a27d25", + "a2221a11b833ccb498a59540f0545f4a" "5bbeb4787d59e5373fdbea6c6f75c29b", + } + }, { + "c109163908ebe51debb46227c6cc8b37641910833222772a", + { + "54b64e6b5a20b5e2ec84593dc7989da7" "c135eee237a85465ff97dc03924f45ce", + "cfcc922fb4a14ab45d6175aabbf2d201" "837b87e2a446ad0ef798acd02b94124f", + "17a6dbd664926a0636b3f4c37a4f4694" "4a5f9f26aeeed4d4a25f632d305233d9", + "80a3d01ef00c8e9a4209c17f4eeb358c" "d15e7d5ffaaabc0207bf200a117793a2", + "349682bf588eaa52d0aa1560346aeafa" "f5854cdb76c889e3ad63354e5f7275e3", + "532c7ceccb39df3236318405a4b1279c" "baefe6d9ceb651842260e0d1e05e3b90", + "e82d8c6db54e3c633f581c952ba04207" "4b16e50abd381bd70900a9cd9a62cb23", + "3682ee33bd148bd9f58656cd8f30d9fb" "1e5a0b8475045d9b20b2628624edfd9e", + "63edd684fb826282fe528f9c0e9237bc" "e4dd2e98d6960fae0b43545456743391", + } + }, { + "1ada31d5cf688221c109163908ebe51debb46227c6cc8b37641910833222772a", + { + "dd5bcb0018e922d494759d7c395d02d3" "c8446f8f77abf737685353eb89a1c9eb", + "af3e30f9c095045938151575c3fb9098" "f8cb6274db99b80b1d2012a98ed48f0e", + "25c3005a1cb85de076259839ab7198ab" "9dcbc183e8cb994b727b75be3180769c", + "a1d3078dfa9169503ed9d4491dee4eb2" "8514a5495858096f596e4bcd66b10665", + "5f40d59ec1b03b33738efa60b2255d31" "3477c7f764a41baceff90bf14f92b7cc", + "ac4e95368d99b9eb78b8da8f81ffa795" "8c3c13f8c2388bb73f38576e65b7c446", + "13c4b9c1dfb66579eddd8a280b9f7316" "ddd27820550126698efaadc64b64f66e", + "f08f2e66d28ed143f3a237cf9de73559" "9ea36c525531b880ba124334f57b0b70", + "d5a39e3dfcc50280bac4a6b5aa0dca7d" "370b1c1fe655916d97fd0d47ca1d72b8", + } + } + }; + + RC4_CTX ctx; + uint8_t key[64]; + uint8_t buffer[0x1010]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + size_t length = strlen(tests[i].key) / 2; + memcpy(key, fromhex(tests[i].key), length); + memset(buffer, 0, sizeof(buffer)); + + rc4_init(&ctx, key, length); + rc4_encrypt(&ctx, buffer, sizeof(buffer)); + + for (size_t j = 0; j < (sizeof(offsets) / sizeof(*offsets)); j++) { + size_t size = strlen(tests[i].vectors[j]) / 2; + ck_assert_mem_eq(&buffer[offsets[j]], fromhex(tests[i].vectors[j]), size); + } + } +} +END_TEST + +#include "test_segwit.c" + +// define test suite and cases +Suite *test_suite(void) +{ + Suite *s = suite_create("trezor-crypto"); + TCase *tc; + + tc = tcase_create("bignum"); + tcase_add_test(tc, test_bignum_read_be); + tcase_add_test(tc, test_bignum_write_be); + tcase_add_test(tc, test_bignum_is_equal); + tcase_add_test(tc, test_bignum_zero); + tcase_add_test(tc, test_bignum_is_zero); + tcase_add_test(tc, test_bignum_one); + tcase_add_test(tc, test_bignum_read_le); + tcase_add_test(tc, test_bignum_write_le); + tcase_add_test(tc, test_bignum_read_uint32); + tcase_add_test(tc, test_bignum_read_uint64); + tcase_add_test(tc, test_bignum_write_uint32); + tcase_add_test(tc, test_bignum_write_uint64); + tcase_add_test(tc, test_bignum_copy); + tcase_add_test(tc, test_bignum_is_even); + tcase_add_test(tc, test_bignum_is_odd); + tcase_add_test(tc, test_bignum_bitcount); + tcase_add_test(tc, test_bignum_digitcount); + tcase_add_test(tc, test_bignum_is_less); + tcase_add_test(tc, test_bignum_format); + tcase_add_test(tc, test_bignum_format_uint64); + suite_add_tcase(s, tc); + + tc = tcase_create("base32"); + tcase_add_test(tc, test_base32_rfc4648); + suite_add_tcase(s, tc); + + tc = tcase_create("base58"); + tcase_add_test(tc, test_base58); + suite_add_tcase(s, tc); + +#if USE_GRAPHENE + tc = tcase_create("base58gph"); + tcase_add_test(tc, test_base58gph); + suite_add_tcase(s, tc); +#endif + + tc = tcase_create("bignum_divmod"); + tcase_add_test(tc, test_bignum_divmod); + suite_add_tcase(s, tc); + + tc = tcase_create("bip32"); + tcase_add_test(tc, test_bip32_vector_1); + tcase_add_test(tc, test_bip32_vector_2); + tcase_add_test(tc, test_bip32_compare); + tcase_add_test(tc, test_bip32_optimized); + tcase_add_test(tc, test_bip32_cache_1); + tcase_add_test(tc, test_bip32_cache_2); + suite_add_tcase(s, tc); + + tc = tcase_create("bip32-nist"); + tcase_add_test(tc, test_bip32_nist_seed); + tcase_add_test(tc, test_bip32_nist_vector_1); + tcase_add_test(tc, test_bip32_nist_vector_2); + tcase_add_test(tc, test_bip32_nist_compare); + tcase_add_test(tc, test_bip32_nist_repeat); + suite_add_tcase(s, tc); + + tc = tcase_create("bip32-ed25519"); + tcase_add_test(tc, test_bip32_ed25519_vector_1); + tcase_add_test(tc, test_bip32_ed25519_vector_2); + suite_add_tcase(s, tc); + + tc = tcase_create("bip32-ecdh"); + tcase_add_test(tc, test_bip32_ecdh_nist256p1); + tcase_add_test(tc, test_bip32_ecdh_curve25519); + tcase_add_test(tc, test_bip32_ecdh_errors); + suite_add_tcase(s, tc); + + tc = tcase_create("bip32-decred"); + tcase_add_test(tc, test_bip32_decred_vector_1); + tcase_add_test(tc, test_bip32_decred_vector_2); + suite_add_tcase(s, tc); + + tc = tcase_create("ecdsa"); + tcase_add_test(tc, test_ecdsa_signature); + suite_add_tcase(s, tc); + + tc = tcase_create("rfc6979"); + tcase_add_test(tc, test_rfc6979); + suite_add_tcase(s, tc); + + tc = tcase_create("address"); + tcase_add_test(tc, test_address); + suite_add_tcase(s, tc); + + tc = tcase_create("address_decode"); + tcase_add_test(tc, test_address_decode); + suite_add_tcase(s, tc); + + tc = tcase_create("ethereum_address"); + tcase_add_test(tc, test_ethereum_address); + suite_add_tcase(s, tc); + + tc = tcase_create("wif"); + tcase_add_test(tc, test_wif); + suite_add_tcase(s, tc); + + tc = tcase_create("ecdsa_der"); + tcase_add_test(tc, test_ecdsa_der); + suite_add_tcase(s, tc); + + tc = tcase_create("aes"); + tcase_add_test(tc, test_aes); + suite_add_tcase(s, tc); + + tc = tcase_create("sha2"); + tcase_add_test(tc, test_sha1); + tcase_add_test(tc, test_sha256); + tcase_add_test(tc, test_sha512); + suite_add_tcase(s, tc); + + tc = tcase_create("sha3"); + tcase_add_test(tc, test_sha3_256); + tcase_add_test(tc, test_sha3_512); + tcase_add_test(tc, test_keccak_256); + suite_add_tcase(s, tc); + + tc = tcase_create("blake"); + tcase_add_test(tc, test_blake256); + suite_add_tcase(s, tc); + + tc = tcase_create("blake2"); + tcase_add_test(tc, test_blake2b); + tcase_add_test(tc, test_blake2s); + suite_add_tcase(s, tc); + + tc = tcase_create("pbkdf2"); + tcase_add_test(tc, test_pbkdf2_hmac_sha256); + tcase_add_test(tc, test_pbkdf2_hmac_sha512); + suite_add_tcase(s, tc); + + tc = tcase_create("bip39"); + tcase_add_test(tc, test_mnemonic); + tcase_add_test(tc, test_mnemonic_check); + suite_add_tcase(s, tc); + + tc = tcase_create("pubkey_validity"); + tcase_add_test(tc, test_pubkey_validity); + suite_add_tcase(s, tc); + + tc = tcase_create("pubkey_uncompress"); + tcase_add_test(tc, test_pubkey_uncompress); + suite_add_tcase(s, tc); + + tc = tcase_create("codepoints"); + tcase_add_test(tc, test_codepoints_secp256k1); + tcase_add_test(tc, test_codepoints_nist256p1); + suite_add_tcase(s, tc); + + tc = tcase_create("mult_border_cases"); + tcase_add_test(tc, test_mult_border_cases_secp256k1); + tcase_add_test(tc, test_mult_border_cases_nist256p1); + suite_add_tcase(s, tc); + + tc = tcase_create("scalar_mult"); + tcase_add_test(tc, test_scalar_mult_secp256k1); + tcase_add_test(tc, test_scalar_mult_nist256p1); + suite_add_tcase(s, tc); + + tc = tcase_create("point_mult"); + tcase_add_test(tc, test_point_mult_secp256k1); + tcase_add_test(tc, test_point_mult_nist256p1); + suite_add_tcase(s, tc); + + tc = tcase_create("scalar_point_mult"); + tcase_add_test(tc, test_scalar_point_mult_secp256k1); + tcase_add_test(tc, test_scalar_point_mult_nist256p1); + suite_add_tcase(s, tc); + + tc = tcase_create("ed25519"); + tcase_add_test(tc, test_ed25519); + suite_add_tcase(s, tc); + + tc = tcase_create("ed25519_keccak"); + tcase_add_test(tc, test_ed25519_keccak); + suite_add_tcase(s, tc); + + tc = tcase_create("ed25519_cosi"); + tcase_add_test(tc, test_ed25519_cosi); + suite_add_tcase(s, tc); + + tc = tcase_create("script"); + tcase_add_test(tc, test_output_script); + suite_add_tcase(s, tc); + + tc = tcase_create("ethereum_pubkeyhash"); + tcase_add_test(tc, test_ethereum_pubkeyhash); + suite_add_tcase(s, tc); + + tc = tcase_create("nem_address"); + tcase_add_test(tc, test_nem_address); + suite_add_tcase(s, tc); + + tc = tcase_create("nem_encryption"); + tcase_add_test(tc, test_nem_derive); + tcase_add_test(tc, test_nem_cipher); + suite_add_tcase(s, tc); + + tc = tcase_create("nem_transaction"); + tcase_add_test(tc, test_nem_transaction_transfer); + tcase_add_test(tc, test_nem_transaction_multisig); + tcase_add_test(tc, test_nem_transaction_provision_namespace); + tcase_add_test(tc, test_nem_transaction_mosaic_creation); + tcase_add_test(tc, test_nem_transaction_mosaic_supply_change); + tcase_add_test(tc, test_nem_transaction_aggregate_modification); + suite_add_tcase(s, tc); + + tc = tcase_create("multibyte_address"); + tcase_add_test(tc, test_multibyte_address); + suite_add_tcase(s, tc); + + tc = tcase_create("rc4"); + tcase_add_test(tc, test_rc4_rfc6229); + suite_add_tcase(s, tc); + + tc = tcase_create("segwit"); + tcase_add_test(tc, test_segwit); + suite_add_tcase(s, tc); + + return s; +} + +// run suite +int main(void) +{ + int number_failed; + Suite *s = test_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + if (number_failed == 0) { + printf("PASSED ALL TESTS\n"); + } + return number_failed; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/test_curves.py b/hardware-wallet/firmware/vendor/trezor-crypto/test_curves.py new file mode 100755 index 00000000..1e063964 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/test_curves.py @@ -0,0 +1,438 @@ +#!/usr/bin/py.test +import ctypes as c +import curve25519 +import random +import ecdsa +import hashlib +import binascii +import os +import pytest + +def bytes2num(s): + res = 0 + for i, b in enumerate(reversed(bytearray(s))): + res += b << (i * 8) + return res + + +curves = { + 'nist256p1': ecdsa.curves.NIST256p, + 'secp256k1': ecdsa.curves.SECP256k1 +} + +class Point: + def __init__(self, name, x, y): + self.curve = name + self.x = x + self.y = y + +points = [ + Point('secp256k1', 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8), + Point('secp256k1', 0x1, 0x4218f20ae6c646b363db68605822fb14264ca8d2587fdd6fbc750d587e76a7ee), + Point('secp256k1', 0x2, 0x66fbe727b2ba09e09f5a98d70a5efce8424c5fa425bbda1c511f860657b8535e), + Point('secp256k1', 0x1b,0x1adcea1cf831b0ad1653e769d1a229091d0cc68d4b0328691b9caacc76e37c90), + Point('nist256p1', 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5), + Point('nist256p1', 0x0, 0x66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4), + Point('nist256p1', 0x0, 0x99b7a386f1d07c29dbcc42a27b5f9449abe3d50de25178e8d7407a95e8b06c0b), + Point('nist256p1', 0xaf8bbdfe8cdd5577acbf345b543d28cf402f4e94d3865b97ea0787f2d3aa5d22,0x35802b8b376b995265918b078bc109c21a535176585c40f519aca52d6afc147c), + Point('nist256p1', 0x80000, 0x580610071f440f0dcc14a22e2d5d5afc1224c0cd11a3b4b51b8ecd2224ee1ce2) +] + +random_iters = int(os.environ.get('ITERS', 1)) + +lib = c.cdll.LoadLibrary('./libtrezor-crypto.so') + +class curve_info(c.Structure): + _fields_ = [("bip32_name", c.c_char_p), + ("params", c.c_void_p)] +lib.get_curve_by_name.restype = c.POINTER(curve_info) + +BIGNUM = c.c_uint32 * 9 + +class Random(random.Random): + def randbytes(self, n): + buf = (c.c_uint8 * n)() + for i in range(n): + buf[i] = self.randrange(0, 256) + return buf + + def randpoint(self, curve): + k = self.randrange(0, curve.order) + return k * curve.generator + + +def int2bn(x, bn_type=BIGNUM): + b = bn_type() + b._int = x + for i in range(len(b)): + b[i] = x % (1 << 30) + x = x >> 30 + return b + + +def bn2int(b): + x = 0 + for i in range(len(b)): + x += (b[i] << (30 * i)) + return x + + +@pytest.fixture(params=range(random_iters)) +def r(request): + seed = request.param + return Random(seed + int(os.environ.get('SEED', 0))) + + +@pytest.fixture(params=list(sorted(curves))) +def curve(request): + name = request.param + curve_ptr = lib.get_curve_by_name(name).contents.params + assert curve_ptr, 'curve {} not found'.format(name) + curve_obj = curves[name] + curve_obj.ptr = c.c_void_p(curve_ptr) + curve_obj.p = curve_obj.curve.p() # shorthand + return curve_obj + +@pytest.fixture(params=points) +def point(request): + name = request.param.curve + curve_ptr = lib.get_curve_by_name(name).contents.params + assert curve_ptr, 'curve {} not found'.format(name) + curve_obj = curves[name] + curve_obj.ptr = c.c_void_p(curve_ptr) + curve_obj.p = ecdsa.ellipticcurve.Point(curve_obj.curve, request.param.x, request.param.y) + return curve_obj + +def test_inverse(curve, r): + x = r.randrange(1, curve.p) + y = int2bn(x) + lib.bn_inverse(y, int2bn(curve.p)) + y = bn2int(y) + y_ = ecdsa.numbertheory.inverse_mod(x, curve.p) + assert y == y_ + + +def test_is_less(curve, r): + x = r.randrange(0, curve.p) + y = r.randrange(0, curve.p) + x_ = int2bn(x) + y_ = int2bn(y) + + res = lib.bn_is_less(x_, y_) + assert res == (x < y) + + res = lib.bn_is_less(y_, x_) + assert res == (y < x) + + +def test_is_equal(curve, r): + x = r.randrange(0, curve.p) + y = r.randrange(0, curve.p) + x_ = int2bn(x) + y_ = int2bn(y) + + assert lib.bn_is_equal(x_, y_) == (x == y) + assert lib.bn_is_equal(x_, x_) == 1 + assert lib.bn_is_equal(y_, y_) == 1 + + +def test_is_zero(curve, r): + x = r.randrange(0, curve.p); + assert lib.bn_is_zero(int2bn(x)) == (not x) + + +def test_simple_comparisons(): + assert lib.bn_is_zero(int2bn(0)) == 1 + assert lib.bn_is_zero(int2bn(1)) == 0 + + assert lib.bn_is_less(int2bn(0), int2bn(0)) == 0 + assert lib.bn_is_less(int2bn(1), int2bn(0)) == 0 + assert lib.bn_is_less(int2bn(0), int2bn(1)) == 1 + + assert lib.bn_is_equal(int2bn(0), int2bn(0)) == 1 + assert lib.bn_is_equal(int2bn(1), int2bn(0)) == 0 + assert lib.bn_is_equal(int2bn(0), int2bn(1)) == 0 + + +def test_mult_half(curve, r): + x = r.randrange(0, 2*curve.p) + y = int2bn(x) + lib.bn_mult_half(y, int2bn(curve.p)) + y = bn2int(y) + if y >= curve.p: + y -= curve.p + half = ecdsa.numbertheory.inverse_mod(2, curve.p) + assert y == (x * half) % curve.p + + +def test_subtractmod(curve, r): + x = r.randrange(0, 2 ** 256) + y = r.randrange(0, 2 ** 256) + z = int2bn(0) + lib.bn_subtractmod(int2bn(x), int2bn(y), z, int2bn(curve.p)) + z = bn2int(z) + z_ = x + 2*curve.p - y + assert z == z_ + + +def test_subtract2(r): + x = r.randrange(0, 2 ** 256) + y = r.randrange(0, 2 ** 256) + x, y = max(x, y), min(x, y) + z = int2bn(0) + lib.bn_subtract(int2bn(x), int2bn(y), z) + z = bn2int(z) + z_ = x - y + assert z == z_ + + +def test_add(curve, r): + x = r.randrange(0, 2 ** 256) + y = r.randrange(0, 2 ** 256) + z_ = x + y + z = int2bn(x) + lib.bn_add(z, int2bn(y)) + z = bn2int(z) + + assert z == z_ + + +def test_addmod(curve, r): + x = r.randrange(0, 2 ** 256) + y = r.randrange(0, 2 ** 256) + z_ = (x + y) % curve.p + z = int2bn(x) + lib.bn_addmod(z, int2bn(y), int2bn(curve.p)) + z = bn2int(z) + if z >= curve.p: + z = z - curve.p + assert z == z_ + + +def test_multiply(curve, r): + k = r.randrange(0, 2 * curve.p) + x = r.randrange(0, 2 * curve.p) + z = (k * x) % curve.p + k = int2bn(k) + z_ = int2bn(x) + p_ = int2bn(curve.p) + lib.bn_multiply(k, z_, p_) + z_ = bn2int(z_) + assert z_ < 2*curve.p + if z_ >= curve.p: + z_ = z_ - curve.p + assert z_ == z + + +def test_multiply1(curve, r): + k = r.randrange(0, 2 * curve.p) + x = r.randrange(0, 2 * curve.p) + kx = k * x + res = int2bn(0, bn_type=(c.c_uint32 * 18)) + lib.bn_multiply_long(int2bn(k), int2bn(x), res) + res = bn2int(res) + assert res == kx + + +def test_multiply2(curve, r): + x = int2bn(0) + s = r.randrange(0, 2 ** 526) + res = int2bn(s, bn_type=(c.c_uint32 * 18)) + prime = int2bn(curve.p) + lib.bn_multiply_reduce(x, res, prime) + + x = bn2int(x) % curve.p + x_ = s % curve.p + + assert x == x_ + + +def test_fast_mod(curve, r): + x = r.randrange(0, 128*curve.p) + y = int2bn(x) + lib.bn_fast_mod(y, int2bn(curve.p)) + y = bn2int(y) + assert y < 2*curve.p + if y >= curve.p: + y -= curve.p + assert x % curve.p == y + + +def test_mod(curve, r): + x = r.randrange(0, 2*curve.p) + y = int2bn(x) + lib.bn_mod(y, int2bn(curve.p)) + assert bn2int(y) == x % curve.p + +def test_mod_specific(curve): + p = curve.p + for x in [0, 1, 2, p - 2, p - 1, p, p + 1, p + 2, 2*p - 2, 2*p - 1]: + y = int2bn(x) + lib.bn_mod(y, int2bn(curve.p)) + assert bn2int(y) == x % p + +POINT = BIGNUM * 2 +to_POINT = lambda p: POINT(int2bn(p.x()), int2bn(p.y())) +from_POINT = lambda p: (bn2int(p[0]), bn2int(p[1])) + +JACOBIAN = BIGNUM * 3 +to_JACOBIAN = lambda jp: JACOBIAN(int2bn(jp[0]), int2bn(jp[1]), int2bn(jp[2])) +from_JACOBIAN = lambda p: (bn2int(p[0]), bn2int(p[1]), bn2int(p[2])) + + +def test_point_multiply(curve, r): + p = r.randpoint(curve) + k = r.randrange(0, 2 ** 256) + kp = k * p + res = POINT(int2bn(0), int2bn(0)) + lib.point_multiply(curve.ptr, int2bn(k), to_POINT(p), res) + res = from_POINT(res) + assert res == (kp.x(), kp.y()) + + +def test_point_add(curve, r): + p1 = r.randpoint(curve) + p2 = r.randpoint(curve) + #print '-' * 80 + q = p1 + p2 + q1 = to_POINT(p1) + q2 = to_POINT(p2) + lib.point_add(curve.ptr, q1, q2) + q_ = from_POINT(q2) + assert q_ == (q.x(), q.y()) + + +def test_point_double(curve, r): + p = r.randpoint(curve) + q = p.double() + q_ = to_POINT(p) + lib.point_double(curve.ptr, q_) + q_ = from_POINT(q_) + assert q_ == (q.x(), q.y()) + + +def test_point_to_jacobian(curve, r): + p = r.randpoint(curve) + jp = JACOBIAN() + lib.curve_to_jacobian(to_POINT(p), jp, int2bn(curve.p)) + jx, jy, jz = from_JACOBIAN(jp) + assert jx % curve.p == (p.x() * jz ** 2) % curve.p + assert jy % curve.p == (p.y() * jz ** 3) % curve.p + + q = POINT() + lib.jacobian_to_curve(jp, q, int2bn(curve.p)) + q = from_POINT(q) + assert q == (p.x(), p.y()) + + +def test_cond_negate(curve, r): + x = r.randrange(0, curve.p) + a = int2bn(x) + lib.conditional_negate(0, a, int2bn(curve.p)) + assert bn2int(a) == x + lib.conditional_negate(-1, a, int2bn(curve.p)) + assert bn2int(a) == 2*curve.p - x + + +def test_jacobian_add(curve, r): + p1 = r.randpoint(curve) + p2 = r.randpoint(curve) + prime = int2bn(curve.p) + q = POINT() + jp2 = JACOBIAN() + lib.curve_to_jacobian(to_POINT(p2), jp2, prime) + lib.point_jacobian_add(to_POINT(p1), jp2, curve.ptr) + lib.jacobian_to_curve(jp2, q, prime) + q = from_POINT(q) + p_ = p1 + p2 + assert (p_.x(), p_.y()) == q + +def test_jacobian_add_double(curve, r): + p1 = r.randpoint(curve) + p2 = p1 + prime = int2bn(curve.p) + q = POINT() + jp2 = JACOBIAN() + lib.curve_to_jacobian(to_POINT(p2), jp2, prime) + lib.point_jacobian_add(to_POINT(p1), jp2, curve.ptr) + lib.jacobian_to_curve(jp2, q, prime) + q = from_POINT(q) + p_ = p1 + p2 + assert (p_.x(), p_.y()) == q + +def test_jacobian_double(curve, r): + p = r.randpoint(curve) + p2 = p.double() + prime = int2bn(curve.p) + q = POINT() + jp = JACOBIAN() + lib.curve_to_jacobian(to_POINT(p), jp, prime) + lib.point_jacobian_double(jp, curve.ptr) + lib.jacobian_to_curve(jp, q, prime) + q = from_POINT(q) + assert (p2.x(), p2.y()) == q + +def sigdecode(sig, _): + return map(bytes2num, [sig[:32], sig[32:]]) + + +def test_sign(curve, r): + priv = r.randbytes(32) + digest = r.randbytes(32) + sig = r.randbytes(64) + + lib.ecdsa_sign_digest(curve.ptr, priv, digest, sig, c.c_void_p(0), c.c_void_p(0)) + + exp = bytes2num(priv) + sk = ecdsa.SigningKey.from_secret_exponent(exp, curve, + hashfunc=hashlib.sha256) + vk = sk.get_verifying_key() + + sig_ref = sk.sign_digest_deterministic(digest, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_string_canonize) + assert binascii.hexlify(sig) == binascii.hexlify(sig_ref) + + assert vk.verify_digest(sig, digest, sigdecode) + +def test_validate_pubkey(curve, r): + p = r.randpoint(curve) + assert lib.ecdsa_validate_pubkey(curve.ptr, to_POINT(p)) + + +def test_validate_pubkey_direct(point): + assert lib.ecdsa_validate_pubkey(point.ptr, to_POINT(point.p)) + + +def test_curve25519(r): + sec1 = bytes(bytearray(r.randbytes(32))) + sec2 = bytes(bytearray(r.randbytes(32))) + pub1 = curve25519.Private(sec1).get_public() + pub2 = curve25519.Private(sec2).get_public() + + session1 = r.randbytes(32) + lib.curve25519_scalarmult(session1, sec2, pub1.public) + session2 = r.randbytes(32) + lib.curve25519_scalarmult(session2, sec1, pub2.public) + assert bytearray(session1) == bytearray(session2) + + shared1 = curve25519.Private(sec2).get_shared_key(pub1, hashfunc=lambda x: x) + shared2 = curve25519.Private(sec1).get_shared_key(pub2, hashfunc=lambda x: x) + assert shared1 == shared2 + assert bytearray(session1) == shared1 + assert bytearray(session2) == shared2 + + +def test_curve25519_pubkey(r): + sec = bytes(bytearray(r.randbytes(32))) + pub = curve25519.Private(sec).get_public() + res = r.randbytes(32) + lib.curve25519_scalarmult_basepoint(res, sec) + assert bytearray(res) == pub.public + + +def test_curve25519_scalarmult_from_gpg(r): + sec = binascii.unhexlify('4a1e76f133afb29dbc7860bcbc16d0e829009cc15c2f81ed26de1179b1d9c938') + pub = binascii.unhexlify('5d6fc75c016e85b17f54e0128a216d5f9229f25bac1ec85cecab8daf48621b31') + res = r.randbytes(32) + lib.curve25519_scalarmult(res, sec[::-1], pub[::-1]) + expected = 'a93dbdb23e5c99da743e203bd391af79f2b83fb8d0fd6ec813371c71f08f2d4d' + assert binascii.hexlify(bytearray(res)) == expected diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/test_openssl.c b/hardware-wallet/firmware/vendor/trezor-crypto/test_openssl.c new file mode 100644 index 00000000..1817afcd --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/test_openssl.c @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2013-2014 Tomas Dzetkulic + * Copyright (c) 2013-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* OpenSSL's SHA256_CTX/SHA512_CTX conflicts with our own */ +#define SHA256_CTX _openssl_SHA256_CTX +#define SHA512_CTX _openssl_SHA512_CTX +#include +#include +#include +#include +#include +#undef SHA256_CTX +#undef SHA512_CTX + +#include +#include + +#include "ecdsa.h" +#include "rand.h" +#include "hasher.h" + +#include "nist256p1.h" +#include "secp256k1.h" + +void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve) +{ + uint8_t sig[64], pub_key33[33], pub_key65[65], priv_key[32], msg[256], buffer[1000], hash[32], *p; + struct SHA256state_st sha256; + EC_GROUP *ecgroup; + + ecgroup = EC_GROUP_new_by_curve_name(nid); + + for (unsigned int iter = 0; iter < iterations; iter++) { + + // random message len between 1 and 256 + int msg_len = (random32() & 0xFF) + 1; + // create random message + random_buffer(msg, msg_len); + + // new ECDSA key + EC_KEY *eckey = EC_KEY_new(); + EC_KEY_set_group(eckey, ecgroup); + + // generate the key + EC_KEY_generate_key(eckey); + // copy key to buffer + p = buffer; + i2d_ECPrivateKey(eckey, &p); + + // size of the key is in buffer[8] and the key begins right after that + int s = buffer[8]; + // extract key data + if (s > 32) { + for (int j = 0; j < 32; j++) { + priv_key[j] = buffer[j + s - 23]; + } + } else { + for (int j = 0; j < 32 - s; j++) { + priv_key[j] = 0; + } + for (int j = 0; j < s; j++) { + priv_key[j + 32 - s] = buffer[j + 9]; + } + } + + // use our ECDSA signer to sign the message with the key + if (ecdsa_sign(curve, HASHER_SHA2, priv_key, msg, msg_len, sig, NULL, NULL) != 0) { + printf("trezor-crypto signing failed\n"); + return; + } + + // generate public key from private key + ecdsa_get_public_key33(curve, priv_key, pub_key33); + ecdsa_get_public_key65(curve, priv_key, pub_key65); + + // use our ECDSA verifier to verify the message signature + if (ecdsa_verify(curve, HASHER_SHA2, pub_key65, sig, msg, msg_len) != 0) { + printf("trezor-crypto verification failed (pub_key_len = 65)\n"); + return; + } + if (ecdsa_verify(curve, HASHER_SHA2, pub_key33, sig, msg, msg_len) != 0) { + printf("trezor-crypto verification failed (pub_key_len = 33)\n"); + return; + } + + // copy signature to the OpenSSL struct + ECDSA_SIG *signature = ECDSA_SIG_new(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + BN_bin2bn(sig, 32, signature->r); + BN_bin2bn(sig + 32, 32, signature->s); +#else + BIGNUM *R = BN_bin2bn(sig, 32, NULL); + BIGNUM *S = BN_bin2bn(sig + 32, 32, NULL); + ECDSA_SIG_set0(signature, R, S); +#endif + + // compute the digest of the message + // note: these are OpenSSL functions, not our own + SHA256_Init(&sha256); + SHA256_Update(&sha256, msg, msg_len); + SHA256_Final(hash, &sha256); + + // verify all went well, i.e. we can decrypt our signature with OpenSSL + int v = ECDSA_do_verify(hash, 32, signature, eckey); + if (v != 1) { + printf("OpenSSL verification failed (%d)\n", v); + return; + } + + ECDSA_SIG_free(signature); + EC_KEY_free(eckey); + if (((iter + 1) % 100) == 0) printf("Passed ... %d\n", iter + 1); + } + EC_GROUP_free(ecgroup); + printf("All OK\n"); +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + printf("Usage: test_openssl iterations\n"); + return 1; + } + + unsigned int iterations; + sscanf(argv[1], "%u", &iterations); + + printf("Testing secp256k1:\n"); + openssl_check(iterations, NID_secp256k1, &secp256k1); + + printf("Testing nist256p1:\n"); + openssl_check(iterations, NID_X9_62_prime256v1, &nist256p1); + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/test_segwit.c b/hardware-wallet/firmware/vendor/trezor-crypto/test_segwit.c new file mode 100644 index 00000000..6ebae766 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/test_segwit.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include + +#include "segwit_addr.h" + +static const char* valid_checksum[] = { + "A12UEL5L", + "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs", + "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw", + "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j", + "split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w", +}; + +static const char* invalid_checksum[] = { + " 1nwldj5", + "\x7f""1axkwrx", + "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx", + "pzry9x0s0muk", + "1pzry9x0s0muk", + "x1b4n0q5v", + "li1dgmt3", + "de1lg7wt\xff", +}; + +struct valid_address_data { + const char* address; + size_t scriptPubKeyLen; + const uint8_t scriptPubKey[42]; +}; + +struct invalid_address_data { + const char* hrp; + int version; + size_t program_length; +}; + +static struct valid_address_data valid_address[] = { + { + "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", + 22, { + 0x00, 0x14, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, + 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6 + } + }, + { + "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", + 34, { + 0x00, 0x20, 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 0x04, + 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 0x6c, 0x98, 0x56, 0x78, + 0xcd, 0x4d, 0x27, 0xa1, 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, + 0x62 + } + }, + { + "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", + 42, { + 0x51, 0x28, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, + 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6, + 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c, + 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6 + } + }, + { + "BC1SW50QA3JX3S", + 4, { + 0x60, 0x02, 0x75, 0x1e + } + }, + { + "bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", + 18, { + 0x52, 0x10, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, + 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23 + } + }, + { + "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy", + 34, { + 0x00, 0x20, 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 0x21, + 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 0x36, 0x2b, 0x99, 0xd5, + 0xe9, 0x1c, 0x6c, 0xe2, 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, + 0x33 + } + } +}; + +static const char* invalid_address[] = { + "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", + "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", + "BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", + "bc1rw5uspcuh", + "bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", + "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", + "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7", + "bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", + "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", + "bc1gmk9yu", +}; + +static struct invalid_address_data invalid_address_enc[] = { + {"BC", 0, 20}, + {"bc", 0, 21}, + {"bc", 17, 32}, + {"bc", 1, 1}, + {"bc", 16, 41}, +}; + +static void segwit_scriptpubkey(uint8_t* scriptpubkey, size_t* scriptpubkeylen, int witver, const uint8_t* witprog, size_t witprog_len) { + scriptpubkey[0] = witver ? (0x50 + witver) : 0; + scriptpubkey[1] = witprog_len; + memcpy(scriptpubkey + 2, witprog, witprog_len); + *scriptpubkeylen = witprog_len + 2; +} + +int my_strncasecmp(const char *s1, const char *s2, size_t n) { + size_t i = 0; + while (i < n) { + char c1 = s1[i]; + char c2 = s2[i]; + if (c1 >= 'A' && c1 <= 'Z') c1 = (c1 - 'A') + 'a'; + if (c2 >= 'A' && c2 <= 'Z') c2 = (c2 - 'A') + 'a'; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + ++i; + } + return 0; +} + +START_TEST(test_segwit) +{ + size_t i; + for (i = 0; i < sizeof(valid_checksum) / sizeof(valid_checksum[0]); ++i) { + uint8_t data[82]; + char rebuild[92]; + char hrp[84]; + size_t data_len; + int res = bech32_decode(hrp, data, &data_len, valid_checksum[i]); + ck_assert_int_eq(res, 1); + res = bech32_encode(rebuild, hrp, data, data_len); + ck_assert_int_eq(res, 1); + ck_assert_int_eq(my_strncasecmp(rebuild, valid_checksum[i], 92), 0); + } + for (i = 0; i < sizeof(invalid_checksum) / sizeof(invalid_checksum[0]); ++i) { + uint8_t data[82]; + char hrp[84]; + size_t data_len; + int res = bech32_decode(hrp, data, &data_len, invalid_checksum[i]); + ck_assert_int_eq(res, 0); + } + for (i = 0; i < sizeof(valid_address) / sizeof(valid_address[0]); ++i) { + uint8_t witprog[40]; + size_t witprog_len; + int witver; + const char* hrp = "bc"; + uint8_t scriptpubkey[42]; + size_t scriptpubkey_len; + char rebuild[93]; + int ret = segwit_addr_decode(&witver, witprog, &witprog_len, hrp, valid_address[i].address); + if (!ret) { + hrp = "tb"; + ret = segwit_addr_decode(&witver, witprog, &witprog_len, hrp, valid_address[i].address); + } + ck_assert_int_eq(ret, 1); + segwit_scriptpubkey(scriptpubkey, &scriptpubkey_len, witver, witprog, witprog_len); + ck_assert_int_eq(scriptpubkey_len, valid_address[i].scriptPubKeyLen); + ck_assert_int_eq(memcmp(scriptpubkey, valid_address[i].scriptPubKey, scriptpubkey_len), 0); + ck_assert_int_eq(segwit_addr_encode(rebuild, hrp, witver, witprog, witprog_len), 1); + ck_assert_int_eq(my_strncasecmp(valid_address[i].address, rebuild, 93), 0); + } + for (i = 0; i < sizeof(invalid_address) / sizeof(invalid_address[0]); ++i) { + uint8_t witprog[40]; + size_t witprog_len; + int witver; + int ret = segwit_addr_decode(&witver, witprog, &witprog_len, "bc", invalid_address[i]); + ck_assert_int_eq(ret, 0); + ret = segwit_addr_decode(&witver, witprog, &witprog_len, "tb", invalid_address[i]); + ck_assert_int_eq(ret, 0); + } + for (i = 0; i < sizeof(invalid_address_enc) / sizeof(invalid_address_enc[0]); ++i) { + char rebuild[93]; + static const uint8_t program[42] = {0}; + int ret = segwit_addr_encode(rebuild, invalid_address_enc[i].hrp, invalid_address_enc[i].version, program, invalid_address_enc[i].program_length); + ck_assert_int_eq(ret, 0); + } +} +END_TEST + diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/test_speed.c b/hardware-wallet/firmware/vendor/trezor-crypto/test_speed.c new file mode 100644 index 00000000..cff4aee2 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/test_speed.c @@ -0,0 +1,215 @@ +#include +#include +#include +#include +#include +#include "curves.h" +#include "ecdsa.h" +#include "bip32.h" +#include "secp256k1.h" +#include "nist256p1.h" +#include "ed25519-donna/ed25519.h" +#include "hasher.h" + +static uint8_t msg[256]; + +void prepare_msg(void) +{ + for (size_t i = 0; i < sizeof(msg); i++) { + msg[i] = i * 1103515245; + } +} + +void bench_sign_secp256k1(int iterations) +{ + uint8_t sig[64], priv[32], pby; + + const ecdsa_curve *curve = &secp256k1; + + memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + + for (int i = 0 ; i < iterations; i++) { + ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); + } +} + +void bench_sign_nist256p1(int iterations) +{ + uint8_t sig[64], priv[32], pby; + + const ecdsa_curve *curve = &nist256p1; + + memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + + for (int i = 0 ; i < iterations; i++) { + ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); + } +} + +void bench_sign_ed25519(int iterations) +{ + ed25519_public_key pk; + ed25519_secret_key sk; + ed25519_signature sig; + + memcpy(pk, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + ed25519_publickey(sk, pk); + + for (int i = 0 ; i < iterations; i++) { + ed25519_sign(msg, sizeof(msg), sk, pk, sig); + } +} + +void bench_verify_secp256k1_33(int iterations) +{ + uint8_t sig[64], pub[33], priv[32], pby; + + const ecdsa_curve *curve = &secp256k1; + + memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + ecdsa_get_public_key33(curve, priv, pub); + ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); + + for (int i = 0 ; i < iterations; i++) { + ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); + } +} + +void bench_verify_secp256k1_65(int iterations) +{ + uint8_t sig[64], pub[65], priv[32], pby; + + const ecdsa_curve *curve = &secp256k1; + + memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + ecdsa_get_public_key65(curve, priv, pub); + ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); + + for (int i = 0 ; i < iterations; i++) { + ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); + } +} + +void bench_verify_nist256p1_33(int iterations) +{ + uint8_t sig[64], pub[33], priv[32], pby; + + const ecdsa_curve *curve = &nist256p1; + + memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + ecdsa_get_public_key33(curve, priv, pub); + ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); + + for (int i = 0 ; i < iterations; i++) { + ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); + } +} + +void bench_verify_nist256p1_65(int iterations) +{ + uint8_t sig[64], pub[65], priv[32], pby; + + const ecdsa_curve *curve = &nist256p1; + + memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + ecdsa_get_public_key65(curve, priv, pub); + ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); + + for (int i = 0 ; i < iterations; i++) { + ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); + } +} + +void bench_verify_ed25519(int iterations) +{ + ed25519_public_key pk; + ed25519_secret_key sk; + ed25519_signature sig; + + memcpy(pk, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + ed25519_publickey(sk, pk); + ed25519_sign(msg, sizeof(msg), sk, pk, sig); + + for (int i = 0 ; i < iterations; i++) { + ed25519_sign_open(msg, sizeof(msg), pk, sig); + } +} + +void bench_multiply_curve25519(int iterations) +{ + uint8_t result[32]; + uint8_t secret[32]; + uint8_t basepoint[32]; + + memcpy(secret, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32); + memcpy(basepoint, "\x96\x47\xda\xbe\x1e\xea\xaf\x25\x47\x1e\x68\x0b\x4d\x7c\x6f\xd1\x14\x38\x76\xbb\x77\x59\xd8\x3d\x0f\xf7\xa2\x49\x08\xfd\xda\xbc", 32); + + for (int i = 0 ; i < iterations; i++) { + curve25519_scalarmult(result, secret, basepoint); + } +} + +static HDNode root; + +void prepare_node(void) +{ + hdnode_from_seed((uint8_t *)"NothingToSeeHere", 16, SECP256K1_NAME, &root); + hdnode_fill_public_key(&root); +} + +void bench_ckd_normal(int iterations) +{ + char addr[MAX_ADDR_SIZE]; + HDNode node; + for (int i = 0; i < iterations; i++) { + memcpy(&node, &root, sizeof(HDNode)); + hdnode_public_ckd(&node, i); + hdnode_fill_public_key(&node); + ecdsa_get_address(node.public_key, HASHER_SHA2, 0, addr, sizeof(addr)); + } +} + +void bench_ckd_optimized(int iterations) +{ + char addr[MAX_ADDR_SIZE]; + curve_point pub; + ecdsa_read_pubkey(&secp256k1, root.public_key, &pub); + for (int i = 0; i < iterations; i++) { + hdnode_public_ckd_address_optimized(&pub, root.chain_code, i, 0, HASHER_SHA2, addr, sizeof(addr), false); + } +} + +void bench(void (*func)(int), const char *name, int iterations) +{ + clock_t t = clock(); + func(iterations); + float speed = iterations / ((float)(clock() - t) / CLOCKS_PER_SEC); + printf("%25s: %8.2f ops/s\n", name, speed); +} + +#define BENCH(FUNC, ITER) bench(FUNC, #FUNC, ITER) + +int main(void) { + + prepare_msg(); + + BENCH(bench_sign_secp256k1, 500); + BENCH(bench_verify_secp256k1_33, 500); + BENCH(bench_verify_secp256k1_65, 500); + + BENCH(bench_sign_nist256p1, 500); + BENCH(bench_verify_nist256p1_33, 500); + BENCH(bench_verify_nist256p1_65, 500); + + BENCH(bench_sign_ed25519, 4000); + BENCH(bench_verify_ed25519, 4000); + + BENCH(bench_multiply_curve25519, 4000); + + prepare_node(); + + BENCH(bench_ckd_normal, 1000); + BENCH(bench_ckd_optimized, 1000); + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/tools/.gitignore b/hardware-wallet/firmware/vendor/trezor-crypto/tools/.gitignore new file mode 100644 index 00000000..da1bc370 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/tools/.gitignore @@ -0,0 +1,3 @@ +xpubaddrgen +mktable +bip39bruteforce diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/tools/README.md b/hardware-wallet/firmware/vendor/trezor-crypto/tools/README.md new file mode 100644 index 00000000..7786244d --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/tools/README.md @@ -0,0 +1,54 @@ +trezor-crypto tools +=================== + +Set of small utilities using the trezor-crypto library. + +xpubaddrgen +----------- + +xpubaddrgen reads job specification from stdin in format: + +``` + +``` + +and prints the results to stdout in format: + +``` +
+``` + +Example input: + +``` +23 xpub6BcjTvRCYD4VvFQ8whztSXhbNyhS56eTd5P3g9Zvd3zPEeUeL5CUqBYX8NSd1b6Thitr8bZcSnesmXZH7KerMcc4tUkenBShYCtQ1L8ebVe 0 0 5 +42 xpub6AT2YrLinU4Be5UWUxMaUz3zTA99CSGvXt1jt2Lgym8PqXbTzmpQ8MHjoLnx8YJiMMUP5iEfR97YQVmgF6B2tAhbCZrXqn65ur526NkZ6ey 1 1000 1005 +``` + +Example output: + +``` +23 0 14vb5Cws75p2i5rmSiF5CKMyezUX4hxSb9 +23 1 1Lf4ciA36dsi1niF6smVcpCiHcpj2skaPq +23 2 1LraByp7gQAipvHnFS1gTSzixBtYaVyQGp +23 3 1Hy6n56qZj1EefLVfDAeEpmveNteY9jpiG +23 4 183Nn4mrUjPizM3xu8C6SrmViaWrk8YyRS +42 1000 12eAFGAqGUtszc9R7euRqk7DUcQNXvQZSg +42 1001 1BrLbFCD3MNYedJaz92U9iqy9ukHrtQ1A6 +42 1002 1Jhv33bJy229ThM7HKxUa92cMK5gi7DyPC +42 1003 13LxbTjQPByisj4F4sZEivUBdnJwigzg6R +42 1004 1BWBpSWkPwcKxVr2WDyUqQbmvk5SGihcx9 +``` + +It will print ``` error``` when there was an error processing job jobid. + +It will print ```error``` when it encountered a malformed line. + + +mktable +----------- + +mktable computes the points of the form `(2*j+1)*16^i*G` and prints them in the format to be included in `secp256k1.c` and `nist256p1.c`. +These points are used by the fast ECC multiplication. + +It is only meant to be run if the `scalar_mult` algorithm changes. diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/tools/bip39bruteforce.c b/hardware-wallet/firmware/vendor/trezor-crypto/tools/bip39bruteforce.c new file mode 100644 index 00000000..10fd69da --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/tools/bip39bruteforce.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include "bip39.h" +#include "bip32.h" +#include "ecdsa.h" +#include "curves.h" + +char iter[256]; +uint8_t seed[512 / 8]; +uint8_t addr[21], pubkeyhash[20]; +int count = 0, found = 0; +HDNode node; +clock_t start; + +// around 280 tries per second + +// testing data: +// +// mnemonic: "all all all all all all all all all all all all" +// address: "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL" +// passphrase: "" +// +// mnemonic: "all all all all all all all all all all all all" +// address: "1N3uJ5AU3FTYQ1ZQgTMtYmgSvMBmQiGVBS" +// passphrase: "testing" + +int main(int argc, char **argv) +{ + if (argc != 2 && argc != 3) { + fprintf(stderr, "Usage: bip39bruteforce address [mnemonic]\n"); + return 1; + } + const char *address = argv[1]; + const char *mnemonic, *item; + if (argc == 3) { + mnemonic = argv[2]; + item = "passphrase"; + } else { + mnemonic = NULL; + item = "mnemonic"; + } + if (mnemonic && !mnemonic_check(mnemonic)) { + fprintf(stderr, "\"%s\" is not a valid mnemonic\n", mnemonic); + return 2; + } + if (!ecdsa_address_decode(address, 0, HASHER_SHA2, addr)) { + fprintf(stderr, "\"%s\" is not a valid address\n", address); + return 3; + } + printf("Reading %ss from stdin ...\n", item); + start = clock(); + for (;;) { + if (fgets(iter, 256, stdin) == NULL) break; + int len = strlen(iter); + if (len <= 0) { + continue; + } + count++; + iter[len - 1] = 0; + if (mnemonic) { + mnemonic_to_seed(mnemonic, iter, seed, NULL); + } else { + mnemonic_to_seed(iter, "", seed, NULL); + } + hdnode_from_seed(seed, 512 / 8, SECP256K1_NAME, &node); + hdnode_private_ckd_prime(&node, 44); + hdnode_private_ckd_prime(&node, 0); + hdnode_private_ckd_prime(&node, 0); + hdnode_private_ckd(&node, 0); + hdnode_private_ckd(&node, 0); + hdnode_fill_public_key(&node); + ecdsa_get_pubkeyhash(node.public_key, HASHER_SHA2, pubkeyhash); + if (memcmp(addr + 1, pubkeyhash, 20) == 0) { + found = 1; + break; + } + } + float dur = (float)(clock() - start) / CLOCKS_PER_SEC; + printf("Tried %d %ss in %f seconds = %f tries/second\n", count, item, dur, (float)count/dur); + if (found) { + printf("Correct %s found! :-)\n\"%s\"\n", item, iter); + return 0; + } + printf("Correct %s not found. :-(\n", item); + return 4; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/tools/mktable.c b/hardware-wallet/firmware/vendor/trezor-crypto/tools/mktable.c new file mode 100644 index 00000000..01ec375c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/tools/mktable.c @@ -0,0 +1,68 @@ +#include +#include +#include "bignum.h" +#include "ecdsa.h" +#include "bip32.h" +#include "rand.h" + +/* + * This program prints the contents of the ecdsa_curve.cp array. + * The entry cp[i][j] contains the number (2*j+1)*16^i*G, + * where G is the generator of the specified elliptic curve. + */ +int main(int argc, char **argv) { + int i,j,k; + if (argc != 2) { + printf("Usage: %s CURVE_NAME\n", argv[0]); + return 1; + } + const char *name = argv[1]; + const curve_info *info = get_curve_by_name(name); + const ecdsa_curve *curve = info->params; + if (curve == 0) { + printf("Unknown curve '%s'\n", name); + return 1; + } + + curve_point ng = curve->G; + curve_point pow2ig = curve->G; + for (i = 0; i < 64; i++) { + // invariants: + // pow2ig = 16^i * G + // ng = pow2ig + printf("\t{\n"); + for (j = 0; j < 8; j++) { + // invariants: + // pow2ig = 16^i * G + // ng = (2*j+1) * 16^i * G +#ifndef NDEBUG + curve_point checkresult; + bignum256 a; + bn_zero(&a); + a.val[(4*i) / 30] = ((uint32_t) 2*j+1) << ((4*i) % 30); + bn_normalize(&a); + point_multiply(curve, &a, &curve->G, &checkresult); + assert(point_is_equal(&checkresult, &ng)); +#endif + printf("\t\t/* %2d*16^%d*G: */\n\t\t{{{", 2*j + 1, i); + // print x coordinate + for (k = 0; k < 9; k++) { + printf((k < 8 ? "0x%08x, " : "0x%04x"), ng.x.val[k]); + } + printf("}},\n\t\t {{"); + // print y coordinate + for (k = 0; k < 9; k++) { + printf((k < 8 ? "0x%08x, " : "0x%04x"), ng.y.val[k]); + } + if (j == 7) { + printf("}}}\n\t},\n"); + } else { + printf("}}},\n"); + point_add(curve, &pow2ig, &ng); + } + point_add(curve, &pow2ig, &ng); + } + pow2ig = ng; + } + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.erb b/hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.erb new file mode 100644 index 00000000..0e7ed946 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.erb @@ -0,0 +1,18 @@ +// test vectors from <%= source_url %> +START_TEST(<%= test_name %>) +{ + static const struct { +<% fields.each do |(name, type)| -%> + <%= if type.nil? then 'const char *' else "#{type} " end %><%= name %>; +<% end -%> + } tests[] = { +<% data.each do |values| -%> + { <% values.each do |value| %><%= value %>, <% end %>}, +<% end -%> + }; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + // TODO: Implement test + } +} +END_TEST diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.rb b/hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.rb new file mode 100755 index 00000000..9bb48792 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/tools/nem_test_vectors.rb @@ -0,0 +1,126 @@ +#!/usr/bin/env ruby +require 'highline' +require 'open-uri' + +TEMPLATE_NAME = (Pathname.new(__FILE__).sub_ext '.erb').to_s.freeze + +@terminal = HighLine.new($stdin, $stderr) + +def github_files + require 'octokit' + + @github_files ||= Octokit.contents('NemProject/nem-test-vectors') + .select do |file| + file.name.end_with? '.dat' + end +end + +def choose_data_file + @terminal.choose do |menu| + github_files.each do |file| + menu.choice(file.name) { file.download_url } + end + + menu.prompt = 'Which file? ' + + menu.index = :none + menu.select_by = :name + end +end + +def load_header(line) + line = line.dup + abort 'Header is not a comment' unless line.slice!(0) == '#' + + header = line.split(':').each(&:strip!) + header.shift if header.first.empty? + + header +end + +def parse_field_answer(answer) + if answer.empty? + nil + elsif /^(?:(?\w+) )?(?\w+)$/ =~ answer + [identifier, type] + else + raise NotValidQuestionError + end +end + +def ask_fields(header) + header.map do |name| + @terminal.ask "Field for `#{name}'? " do |question| + question.answer_type = lambda(&method(:parse_field_answer)) + end + end +end + +def load_data_line(line) + abort 'Line does not begin with colon' unless line.slice!(0) == ':' + + line.strip! + line.chomp!(',') + + values = line.split(':').each(&:strip!) + values.pop if values.last.empty? + + values +end + +def load_data(file, count) + file.each_line.lazy.reject { |line| line.start_with? '#' } + .take(count) + .map(&method(:load_data_line)) + .to_a +end + +def remove_skipped_fields(fields, data) + data.each do |values| + abort 'Line does not match header' unless values.size == fields.size + + values.reject!.each_with_index { |_, index| fields[index].nil? } + end + + fields.compact! +end + +def format_data_fields(fields, data) + data.each do |values| + fields.each_with_index do |(_, type), index| + values[index] = values[index].dump if type.nil? + end + end +end + +def template(source_url, fields, data) + test_name = @terminal.ask('Name for test? ') do |question| + question.validate = /./ + end + + erb = ERB.new(File.read(TEMPLATE_NAME), nil, '-') + erb.filename = TEMPLATE_NAME + + erb.result(binding) +end + +download_url = choose_data_file + +source_code = open download_url do |file| + line = file.readline + + header = load_header(line) + @terminal.say line + + count = @terminal.ask('How many vectors to import? ', Integer) + + fields = ask_fields(header) + data = load_data(file, count) + + remove_skipped_fields(fields, data) + format_data_fields(fields, data) + + template(download_url, fields, data) +end + +puts source_code diff --git a/hardware-wallet/firmware/vendor/trezor-crypto/tools/xpubaddrgen.c b/hardware-wallet/firmware/vendor/trezor-crypto/tools/xpubaddrgen.c new file mode 100644 index 00000000..361686e6 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-crypto/tools/xpubaddrgen.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include "bip32.h" +#include "curves.h" +#include "ecdsa.h" + +#define VERSION_PUBLIC 0x0488b21e +#define VERSION_PRIVATE 0x0488ade4 + +void process_job(uint32_t jobid, const char *xpub, uint32_t change, uint32_t from, uint32_t to) +{ + HDNode node, child; + if (change > 1 || to <= from || hdnode_deserialize(xpub, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node, NULL) != 0) { + printf("%d error\n", jobid); + return; + } + hdnode_public_ckd(&node, change); + uint32_t i; + char address[36]; + for (i = from; i < to; i++) { + memcpy(&child, &node, sizeof(HDNode)); + hdnode_public_ckd(&child, i); + ecdsa_get_address(child.public_key, 0, HASHER_SHA2, address, sizeof(address)); + printf("%d %d %s\n", jobid, i, address); + } +} + +int main(void) +{ + char line[1024], xpub[1024]; + uint32_t jobid, change, from, to; + int r; + for (;;) { + if (!fgets(line, sizeof(line), stdin)) break; + r = sscanf(line, "%u %s %u %u %u\n", &jobid, xpub, &change, &from, &to); + if (r < 1) { + printf("error\n"); + } else if (r != 5) { + printf("%d error\n", jobid); + } else { + process_job(jobid, xpub, change, from, to); + } + } + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/.gitignore b/hardware-wallet/firmware/vendor/trezor-qrenc/.gitignore new file mode 100644 index 00000000..11664b33 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/.gitignore @@ -0,0 +1,4 @@ +*.o +*.d +test +tests diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/.travis.yml b/hardware-wallet/firmware/vendor/trezor-qrenc/.travis.yml new file mode 100644 index 00000000..ab6c376c --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/.travis.yml @@ -0,0 +1,23 @@ +sudo: false +language: c + +compiler: + - clang + - gcc + +addons: + apt: + packages: + - check + +script: + - make + - ./tests + +notifications: + webhooks: + urls: + - http://ci-bot.satoshilabs.com:5000/travis + on_success: always + on_failure: always + on_start: always diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/AUTHORS b/hardware-wallet/firmware/vendor/trezor-qrenc/AUTHORS new file mode 100644 index 00000000..5bac71cd --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/AUTHORS @@ -0,0 +1,3 @@ +Psytec Inc. +Alexey Mednyy +Pavol Rusnak diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/LICENSE b/hardware-wallet/firmware/vendor/trezor-qrenc/LICENSE new file mode 100644 index 00000000..eb60f966 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2010 Psytec Inc. +Copyright (c) 2012 Alexey Mednyy +Copyright (c) 2012-2016 Pavol Rusnak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION 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/hardware-wallet/firmware/vendor/trezor-qrenc/Makefile b/hardware-wallet/firmware/vendor/trezor-qrenc/Makefile new file mode 100644 index 00000000..b01177da --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/Makefile @@ -0,0 +1,50 @@ +CC=gcc +EMCC=emcc +CHECKLIBS = -lcheck -lrt -lpthread -lm + +OPTFLAGS = -O3 -g + +EMFLAGS = -O3 + +CFLAGS += $(OPTFLAGS) \ + -W \ + -Wall \ + -Wextra \ + -Wimplicit-function-declaration \ + -Wredundant-decls \ + -Wstrict-prototypes \ + -Wundef \ + -Wshadow \ + -Wpointer-arith \ + -Wformat \ + -Wreturn-type \ + -Wsign-compare \ + -Wmultichar \ + -Wformat-nonliteral \ + -Winit-self \ + -Wuninitialized \ + -Wformat-security \ + -DQR_MAX_VERSION=0 + +all: test tests + +%.bc: %.c + $(EMCC) $(EMFLAGS) -o $@ -c $< + +%.o: %.c + $(CC) -o $@ -c $< + +test: qr_encode.o test.o + $(CC) $(CFLAGS) qr_encode.o test.o -o test + +test_arg.js: qr_encode.bc test_arg.bc + $(EMCC) $(EMFLAGS) qr_encode.bc test_arg.bc -o test_arg.js + +qr.js: qr.js.head qr.js.foot test_arg.js + cat qr.js.head test_arg.js qr.js.foot > qr.js + +tests: qr_encode.o tests.o + $(CC) $(CFLAGS) qr_encode.o tests.o $(CHECKLIBS) -o tests + +clean: + rm -f *.o *.js *.bc *.js.mem test tests diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/README.md b/hardware-wallet/firmware/vendor/trezor-qrenc/README.md new file mode 100644 index 00000000..7dd9f0fe --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/README.md @@ -0,0 +1,13 @@ +trezor-qrenc +============ + +[![Build Status](https://travis-ci.org/trezor/trezor-qrenc.svg?branch=master)](https://travis-ci.org/trezor/trezor-qrenc) [![gitter](https://badges.gitter.im/trezor/community.svg)](https://gitter.im/trezor/community) + +Minimalistic QR Code Generator (Encoder) + +- Originally written by Psytec Inc. +- Modified by Alexey Mednyy +- Heavily modified and maintained by Pavol Rusnak +- JavaScript cross-compilation by Karel Bilek using emscripten, with some code from Kazuhiko Arase + +Licensed under MIT License diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/bower.json b/hardware-wallet/firmware/vendor/trezor-qrenc/bower.json new file mode 100644 index 00000000..e1bbc65f --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/bower.json @@ -0,0 +1,34 @@ +{ + "name": "trezor-qrenc", + "version": "0.1.0", + "homepage": "https://github.com/trezor/trezor-qrenc", + "authors": [ + "Karel Bilek ", + "Kazuhiko Arase", + "Psytec Inc.", + "Alexey Mednyy", + "Pavol Rusnak" + ], + "description": "Cross-compiled QR encoder", + "main": [ + "./compiled/qr.js", + "./compiled/test_arg.js.mem" + ], + "keywords": [ + "trezor", + "qr" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "Makefile", + ".foot", + ".head", + ".h", + ".c" + ] +} diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/example.html b/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/example.html new file mode 100644 index 00000000..059847a3 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/example.html @@ -0,0 +1,25 @@ + + + + + + + +

QR experiments

+Text:
+
+
+
+
+ + + + diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/qr.js b/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/qr.js new file mode 100644 index 00000000..8c43999f --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/qr.js @@ -0,0 +1,473 @@ +//--------------------------------------------------------------------- +// +// QR Code Generator for JavaScript, cross-compiled from C source +// +// Copyright (c) 2009 Kazuhiko Arase +// (c) 2010 Psytec Inc. +// (c) 2012 Alexey Mednyy +// (c) 2012-2014 Pavol Rusnak +// (c) 2015 Karel Bilek +// +// Licensed under the MIT license: +// http://www.opensource.org/licenses/mit-license.php +// +// The word 'QR Code' is registered trademark of +// DENSO WAVE INCORPORATED +// http://www.denso-wave.com/qrcode/faqpatent-e.html +// +// +// Use: qrMaker("ABCD").imgTag(10,10).then(function(tag){$("...").html(tag)}) +//--------------------------------------------------------------------- + +function qrMaker(address) { + this.address=address; +} + +/** + * Returns promise for IMG tag with the given address in it. + * + * cellSize - size of one "pixel" in QR + * margin - size of the "bezel" around QR code that's always white + */ +qrMaker.prototype.imgTag=function(cellSize, margin){ + + //this code is almost verbatim copied from + //lrsjng/jquery-qrcode + + //--------------------------------------------------------------------- + // gifImage (B/W) + //--------------------------------------------------------------------- + + var gifImage = function(width, height) { + + var _width = width; + var _height = height; + var _data = new Array(width * height); + + var _this = {}; + + _this.setPixel = function(x, y, pixel) { + _data[y * _width + x] = pixel; + }; + + _this.write = function(out) { + + //--------------------------------- + // GIF Signature + + out.writeString('GIF87a'); + + //--------------------------------- + // Screen Descriptor + + out.writeShort(_width); + out.writeShort(_height); + + out.writeByte(0x80); // 2bit + out.writeByte(0); + out.writeByte(0); + + //--------------------------------- + // Global Color Map + + // black + out.writeByte(0x00); + out.writeByte(0x00); + out.writeByte(0x00); + + // white + out.writeByte(0xff); + out.writeByte(0xff); + out.writeByte(0xff); + + //--------------------------------- + // Image Descriptor + + out.writeString(','); + out.writeShort(0); + out.writeShort(0); + out.writeShort(_width); + out.writeShort(_height); + out.writeByte(0); + + //--------------------------------- + // Local Color Map + + //--------------------------------- + // Raster Data + + var lzwMinCodeSize = 2; + var raster = getLZWRaster(lzwMinCodeSize); + + out.writeByte(lzwMinCodeSize); + + var offset = 0; + + while (raster.length - offset > 255) { + out.writeByte(255); + out.writeBytes(raster, offset, 255); + offset += 255; + } + + out.writeByte(raster.length - offset); + out.writeBytes(raster, offset, raster.length - offset); + out.writeByte(0x00); + + //--------------------------------- + // GIF Terminator + out.writeString(';'); + }; + + var bitOutputStream = function(out) { + + var _out = out; + var _bitLength = 0; + var _bitBuffer = 0; + + var _this = {}; + + _this.write = function(data, length) { + + if ( (data >>> length) != 0) { + throw new Error('length over'); + } + + while (_bitLength + length >= 8) { + _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); + length -= (8 - _bitLength); + data >>>= (8 - _bitLength); + _bitBuffer = 0; + _bitLength = 0; + } + + _bitBuffer = (data << _bitLength) | _bitBuffer; + _bitLength = _bitLength + length; + }; + + _this.flush = function() { + if (_bitLength > 0) { + _out.writeByte(_bitBuffer); + } + }; + + return _this; + }; + + var getLZWRaster = function(lzwMinCodeSize) { + + var clearCode = 1 << lzwMinCodeSize; + var endCode = (1 << lzwMinCodeSize) + 1; + var bitLength = lzwMinCodeSize + 1; + + // Setup LZWTable + var table = lzwTable(); + + for (var i = 0; i < clearCode; i += 1) { + table.add(String.fromCharCode(i) ); + } + table.add(String.fromCharCode(clearCode) ); + table.add(String.fromCharCode(endCode) ); + + var byteOut = byteArrayOutputStream(); + var bitOut = bitOutputStream(byteOut); + + // clear code + bitOut.write(clearCode, bitLength); + + var dataIndex = 0; + + var s = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + while (dataIndex < _data.length) { + + var c = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + if (table.contains(s + c) ) { + + s = s + c; + + } else { + + bitOut.write(table.indexOf(s), bitLength); + + if (table.size() < 0xfff) { + + if (table.size() == (1 << bitLength) ) { + bitLength += 1; + } + + table.add(s + c); + } + + s = c; + } + } + + bitOut.write(table.indexOf(s), bitLength); + + // end code + bitOut.write(endCode, bitLength); + + bitOut.flush(); + + return byteOut.toByteArray(); + }; + + var lzwTable = function() { + + var _map = {}; + var _size = 0; + + var _this = {}; + + _this.add = function(key) { + if (_this.contains(key) ) { + throw new Error('dup key:' + key); + } + _map[key] = _size; + _size += 1; + }; + + _this.size = function() { + return _size; + }; + + _this.indexOf = function(key) { + return _map[key]; + }; + + _this.contains = function(key) { + return typeof _map[key] != 'undefined'; + }; + + return _this; + }; + + return _this; + }; + + var byteArrayOutputStream = function() { + + var _bytes = new Array(); + + var _this = {}; + + _this.writeByte = function(b) { + _bytes.push(b & 0xff); + }; + + _this.writeShort = function(i) { + _this.writeByte(i); + _this.writeByte(i >>> 8); + }; + + _this.writeBytes = function(b, off, len) { + off = off || 0; + len = len || b.length; + for (var i = 0; i < len; i += 1) { + _this.writeByte(b[i + off]); + } + }; + + _this.writeString = function(s) { + for (var i = 0; i < s.length; i += 1) { + _this.writeByte(s.charCodeAt(i) ); + } + }; + + _this.toByteArray = function() { + return _bytes; + }; + + _this.toString = function() { + var s = ''; + s += '['; + for (var i = 0; i < _bytes.length; i += 1) { + if (i > 0) { + s += ','; + } + s += _bytes[i]; + } + s += ']'; + return s; + }; + + return _this; + }; + + + var base64EncodeOutputStream = function() { + + var _buffer = 0; + var _buflen = 0; + var _length = 0; + var _base64 = ''; + + var _this = {}; + + var writeEncoded = function(b) { + _base64 += String.fromCharCode(encode(b & 0x3f) ); + }; + + var encode = function(n) { + if (n < 0) { + // error. + } else if (n < 26) { + return 0x41 + n; + } else if (n < 52) { + return 0x61 + (n - 26); + } else if (n < 62) { + return 0x30 + (n - 52); + } else if (n == 62) { + return 0x2b; + } else if (n == 63) { + return 0x2f; + } + throw new Error('n:' + n); + }; + + _this.writeByte = function(n) { + + _buffer = (_buffer << 8) | (n & 0xff); + _buflen += 8; + _length += 1; + + while (_buflen >= 6) { + writeEncoded(_buffer >>> (_buflen - 6) ); + _buflen -= 6; + } + }; + + _this.flush = function() { + + if (_buflen > 0) { + writeEncoded(_buffer << (6 - _buflen) ); + _buffer = 0; + _buflen = 0; + } + + if (_length % 3 != 0) { + // padding + var padlen = 3 - _length % 3; + for (var i = 0; i < padlen; i += 1) { + _base64 += '='; + } + } + }; + + _this.toString = function() { + return _base64; + }; + + return _this; + }; + + + var createImgTag = function(width, height, getPixel, alt) { + + var gif = gifImage(width, height); + for (var y = 0; y < height; y += 1) { + for (var x = 0; x < width; x += 1) { + gif.setPixel(x, y, getPixel(x, y) ); + } + } + + var b = byteArrayOutputStream(); + gif.write(b); + + var base64 = base64EncodeOutputStream(); + var bytes = b.toByteArray(); + for (var i = 0; i < bytes.length; i += 1) { + base64.writeByte(bytes[i]); + } + base64.flush(); + + var img = ''; + img += '1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}))}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}this["Module"]=Module}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WEB){window["Module"]=Module}else{Module["load"]=importScripts}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i0)return""}var c1=buffer[0];var c2=buffer[1];var c3=buffer[2];var c4=buffer[3];var ret;if(buffer.length==2){ret=String.fromCharCode((c1&31)<<6|c2&63)}else if(buffer.length==3){ret=String.fromCharCode((c1&15)<<12|(c2&63)<<6|c3&63)}else{var codePoint=(c1&7)<<18|(c2&63)<<12|(c3&63)<<6|c4&63;ret=String.fromCharCode(((codePoint-65536)/1024|0)+55296,(codePoint-65536)%1024+56320)}buffer.length=0;return ret});this.processJSString=function processJSString(string){string=unescape(encodeURIComponent(string));var ret=[];for(var i=0;i=TOTAL_MEMORY)enlargeMemory();return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc((str.length<<2)+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr>2]=0}stop=ret+size;while(ptr>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i>0];if(t>=128)hasUtf=true;else if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(!hasUtf){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}var utf8=new Runtime.UTF8Processor;for(i=0;i>0];ret+=utf8.processCChar(t)}return ret}Module["Pointer_stringify"]=Pointer_stringify;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr){for(var i=0;i>1]=codeUnit}HEAP16[outPtr+str.length*2>>1]=0}Module["stringToUTF16"]=stringToUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr){var iChar=0;for(var iCodeUnit=0;iCodeUnit=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++iCodeUnit);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr+iChar*4>>2]=codeUnit;++iChar}HEAP32[outPtr+iChar*4>>2]=0}Module["stringToUTF32"]=stringToUTF32;function demangle(func){var hasLibcxxabi=!!Module["___cxa_demangle"];if(hasLibcxxabi){try{var buf=_malloc(func.length);writeStringToMemory(func.substr(1),buf);var status=_malloc(4);var ret=Module["___cxa_demangle"](buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}}var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a"}else{ret=name}paramLoop:while(i0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}var parsed=func;try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}parsed=parse()}catch(e){parsed+="?"}if(parsed.indexOf("?")>=0&&!hasLibcxxabi){Runtime.warnOnce("warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling")}return parsed}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){return demangleAll(jsStackTrace())}Module["stackTrace"]=stackTrace;var PAGE_SIZE=4096;function alignMemoryPage(x){return x+4095&-4096}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function enlargeMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.")}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;var FAST_MEMORY=Module["FAST_MEMORY"]||2097152;var totalMemory=64*1024;while(totalMemory0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=Module.addOnPreRun=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=Module.addOnInit=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=Module.addOnPreMain=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=Module.addOnExit=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=Module.addOnPostRun=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var ret=(new Runtime.UTF8Processor).processJSString(stringy);if(length){ret.length=length}if(!dontAddNull){ret.push(0)}return ret}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer+str.length>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;STATIC_BASE=8;STATICTOP=STATIC_BASE+57536;__ATINIT__.push();var memoryInitializer="test_arg.js.mem";var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};var ___errno_state=0;function ___setErrNo(value){HEAP32[___errno_state>>2]=value;return value}var PATH={splitPath:(function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)}),normalizeArray:(function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up--;up){parts.unshift("..")}}return parts}),normalize:(function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter((function(p){return!!p})),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path}),dirname:(function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir}),basename:(function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)}),extname:(function(path){return PATH.splitPath(path)[3]}),join:(function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))}),join2:(function(l,r){return PATH.normalize(l+"/"+r)}),resolve:(function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter((function(p){return!!p})),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."}),relative:(function(from,to){from=PATH.resolve(from).substr(1);to=PATH.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){Module["print"](tty.output.join(""));tty.output=[]}}),put_char:(function(tty,val){if(val===null||val===10){Module["print"](tty.output.join(""));tty.output=[]}else{tty.output.push(TTY.utf8.processCChar(val))}})},default_tty1_ops:{put_char:(function(tty,val){if(val===null||val===10){Module["printErr"](tty.output.join(""));tty.output=[]}else{tty.output.push(TTY.utf8.processCChar(val))}}),flush:(function(tty){if(tty.output&&tty.output.length>0){Module["printErr"](tty.output.join(""));tty.output=[]}})}};var MEMFS={ops_table:null,mount:(function(mount){return MEMFS.createNode(null,"/",16384|511,0)}),createNode:(function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node}return node}),getFileDataAsRegularArray:(function(node){if(node.contents&&node.contents.subarray){var arr=[];for(var i=0;inode.contents.length){node.contents=MEMFS.getFileDataAsRegularArray(node);node.usedBytes=node.contents.length}if(!node.contents||node.contents.subarray){var prevCapacity=node.contents?node.contents.buffer.byteLength:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return}if(!node.contents&&newCapacity>0)node.contents=[];while(node.contents.lengthnewSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+lengthe2.timestamp){create.push(key);total++}}));var remove=[];Object.keys(dst.entries).forEach((function(key){var e=dst.entries[key];var e2=src.entries[key];if(!e2){remove.push(key);total++}}));if(!total){return callback(null)}var errored=false;var completed=0;var db=src.type==="remote"?src.db:dst.db;var transaction=db.transaction([IDBFS.DB_STORE_NAME],"readwrite");var store=transaction.objectStore(IDBFS.DB_STORE_NAME);function done(err){if(err){if(!done.errored){done.errored=true;return callback(err)}return}if(++completed>=total){return callback(null)}}transaction.onerror=(function(){done(this.error)});create.sort().forEach((function(path){if(dst.type==="local"){IDBFS.loadRemoteEntry(store,path,(function(err,entry){if(err)return done(err);IDBFS.storeLocalEntry(path,entry,done)}))}else{IDBFS.loadLocalEntry(path,(function(err,entry){if(err)return done(err);IDBFS.storeRemoteEntry(store,path,entry,done)}))}}));remove.sort().reverse().forEach((function(path){if(dst.type==="local"){IDBFS.removeLocalEntry(path,done)}else{IDBFS.removeRemoteEntry(store,path,done)}}))})};var NODEFS={isWindows:false,staticInit:(function(){NODEFS.isWindows=!!process.platform.match(/^win/)}),mount:(function(mount){assert(ENVIRONMENT_IS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)}),createNode:(function(parent,name,mode,dev){if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node}),getMode:(function(path){var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&146)>>1}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return stat.mode}),realPath:(function(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)}),flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:(function(flags){if(flags in NODEFS.flagsToPermissionStringMap){return NODEFS.flagsToPermissionStringMap[flags]}else{return flags}}),node_ops:{getattr:(function(node){var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}}),setattr:(function(node,attr){var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),lookup:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)}),mknod:(function(parent,name,mode,dev){var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}return node}),rename:(function(oldNode,newDir,newName){var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),unlink:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),rmdir:(function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),readdir:(function(node){var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),symlink:(function(parent,newName,oldPath){var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),readlink:(function(node){var path=NODEFS.realPath(node);try{return fs.readlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}})},stream_ops:{open:(function(stream){var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsToPermissionString(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),close:(function(stream){try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(ERRNO_CODES[e.code])}}),read:(function(stream,buffer,offset,length,position){if(length===0)return 0;var nbuffer=new Buffer(length);var res;try{res=fs.readSync(stream.nfd,nbuffer,0,length,position)}catch(e){throw new FS.ErrnoError(ERRNO_CODES[e.code])}if(res>0){for(var i=0;i8){throw new FS.ErrnoError(ERRNO_CODES.ELOOP)}var parts=PATH.normalizeArray(path.split("/").filter((function(p){return!!p})),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(ERRNO_CODES.ELOOP)}}}}return{path:current_path,node:current}}),getPath:(function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}}),hashName:(function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length}),hashAddNode:(function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node}),hashRemoveNode:(function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}}),lookupNode:(function(parent,name){var err=FS.mayLookup(parent);if(err){throw new FS.ErrnoError(err,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)}),createNode:(function(parent,name,mode,rdev){if(!FS.FSNode){FS.FSNode=(function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev});FS.FSNode.prototype={};var readMode=292|73;var writeMode=146;Object.defineProperties(FS.FSNode.prototype,{read:{get:(function(){return(this.mode&readMode)===readMode}),set:(function(val){val?this.mode|=readMode:this.mode&=~readMode})},write:{get:(function(){return(this.mode&writeMode)===writeMode}),set:(function(val){val?this.mode|=writeMode:this.mode&=~writeMode})},isFolder:{get:(function(){return FS.isDir(this.mode)})},isDevice:{get:(function(){return FS.isChrdev(this.mode)})}})}var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node}),destroyNode:(function(node){FS.hashRemoveNode(node)}),isRoot:(function(node){return node===node.parent}),isMountpoint:(function(node){return!!node.mounted}),isFile:(function(mode){return(mode&61440)===32768}),isDir:(function(mode){return(mode&61440)===16384}),isLink:(function(mode){return(mode&61440)===40960}),isChrdev:(function(mode){return(mode&61440)===8192}),isBlkdev:(function(mode){return(mode&61440)===24576}),isFIFO:(function(mode){return(mode&61440)===4096}),isSocket:(function(mode){return(mode&49152)===49152}),flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:(function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags}),flagsToPermissionString:(function(flag){var accmode=flag&2097155;var perms=["r","w","rw"][accmode];if(flag&512){perms+="w"}return perms}),nodePermissions:(function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return ERRNO_CODES.EACCES}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return ERRNO_CODES.EACCES}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return ERRNO_CODES.EACCES}return 0}),mayLookup:(function(dir){var err=FS.nodePermissions(dir,"x");if(err)return err;if(!dir.node_ops.lookup)return ERRNO_CODES.EACCES;return 0}),mayCreate:(function(dir,name){try{var node=FS.lookupNode(dir,name);return ERRNO_CODES.EEXIST}catch(e){}return FS.nodePermissions(dir,"wx")}),mayDelete:(function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var err=FS.nodePermissions(dir,"wx");if(err){return err}if(isdir){if(!FS.isDir(node.mode)){return ERRNO_CODES.ENOTDIR}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return ERRNO_CODES.EBUSY}}else{if(FS.isDir(node.mode)){return ERRNO_CODES.EISDIR}}return 0}),mayOpen:(function(node,flags){if(!node){return ERRNO_CODES.ENOENT}if(FS.isLink(node.mode)){return ERRNO_CODES.ELOOP}else if(FS.isDir(node.mode)){if((flags&2097155)!==0||flags&512){return ERRNO_CODES.EISDIR}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))}),MAX_OPEN_FDS:4096,nextfd:(function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(ERRNO_CODES.EMFILE)}),getStream:(function(fd){return FS.streams[fd]}),createStream:(function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=(function(){});FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get:(function(){return this.node}),set:(function(val){this.node=val})},isRead:{get:(function(){return(this.flags&2097155)!==1})},isWrite:{get:(function(){return(this.flags&2097155)!==0})},isAppend:{get:(function(){return this.flags&1024})}})}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream}),closeStream:(function(fd){FS.streams[fd]=null}),getStreamFromPtr:(function(ptr){return FS.streams[ptr-1]}),getPtrForStream:(function(stream){return stream?stream.fd+1:0}),chrdev_stream_ops:{open:(function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}}),llseek:(function(){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)})},major:(function(dev){return dev>>8}),minor:(function(dev){return dev&255}),makedev:(function(ma,mi){return ma<<8|mi}),registerDevice:(function(dev,ops){FS.devices[dev]={stream_ops:ops}}),getDevice:(function(dev){return FS.devices[dev]}),getMounts:(function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts}),syncfs:(function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}var mounts=FS.getMounts(FS.root.mount);var completed=0;function done(err){if(err){if(!done.errored){done.errored=true;return callback(err)}return}if(++completed>=mounts.length){callback(null)}}mounts.forEach((function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)}))}),mount:(function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot}),unmount:(function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach((function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}}));node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)}),lookup:(function(parent,name){return parent.node_ops.lookup(parent,name)}),mknod:(function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var err=FS.mayCreate(parent,name);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return parent.node_ops.mknod(parent,name,mode,dev)}),create:(function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)}),mkdir:(function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)}),mkdev:(function(path,mode,dev){if(typeof dev==="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)}),symlink:(function(oldpath,newpath){if(!PATH.resolve(oldpath)){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}var newname=PATH.basename(newpath);var err=FS.mayCreate(parent,newname);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return parent.node_ops.symlink(parent,newname,oldpath)}),rename:(function(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;try{lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node}catch(e){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(!old_dir||!new_dir)throw new FS.ErrnoError(ERRNO_CODES.ENOENT);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(ERRNO_CODES.EXDEV)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}relative=PATH.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var err=FS.mayDelete(old_dir,old_name,isdir);if(err){throw new FS.ErrnoError(err)}err=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(err){throw new FS.ErrnoError(err)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}if(new_dir!==old_dir){err=FS.nodePermissions(old_dir,"w");if(err){throw new FS.ErrnoError(err)}}try{if(FS.trackingDelegate["willMovePath"]){FS.trackingDelegate["willMovePath"](old_path,new_path)}}catch(e){console.log("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}try{if(FS.trackingDelegate["onMovePath"])FS.trackingDelegate["onMovePath"](old_path,new_path)}catch(e){console.log("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}}),rmdir:(function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var err=FS.mayDelete(parent,name,true);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}}),readdir:(function(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR)}return node.node_ops.readdir(node)}),unlink:(function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var err=FS.mayDelete(parent,name,false);if(err){if(err===ERRNO_CODES.EISDIR)err=ERRNO_CODES.EPERM;throw new FS.ErrnoError(err)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(ERRNO_CODES.EBUSY)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.unlink(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}}),readlink:(function(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}if(!link.node_ops.readlink){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}return link.node_ops.readlink(link)}),stat:(function(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}if(!node.node_ops.getattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}return node.node_ops.getattr(node)}),lstat:(function(path){return FS.stat(path,true)}),chmod:(function(path,mode,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})}),lchmod:(function(path,mode){FS.chmod(path,mode,true)}),fchmod:(function(fd,mode){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}FS.chmod(stream.node,mode)}),chown:(function(path,uid,gid,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}node.node_ops.setattr(node,{timestamp:Date.now()})}),lchown:(function(path,uid,gid){FS.chown(path,uid,gid,true)}),fchown:(function(fd,uid,gid){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}FS.chown(stream.node,uid,gid)}),truncate:(function(path,len){if(len<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(ERRNO_CODES.EPERM)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var err=FS.nodePermissions(node,"w");if(err){throw new FS.ErrnoError(err)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})}),ftruncate:(function(fd,len){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}FS.truncate(stream.node,len)}),utime:(function(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})}),open:(function(path,flags,mode,fd_start,fd_end){if(path===""){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}flags=typeof flags==="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode==="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path==="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(ERRNO_CODES.EEXIST)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(ERRNO_CODES.ENOENT)}if(FS.isChrdev(node.mode)){flags&=~512}if(!created){var err=FS.mayOpen(node,flags);if(err){throw new FS.ErrnoError(err)}}if(flags&512){FS.truncate(node,0)}flags&=~(128|512);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false},fd_start,fd_end);if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1;Module["printErr"]("read file: "+path)}}try{if(FS.trackingDelegate["onOpenFile"]){var trackingFlags=0;if((flags&2097155)!==1){trackingFlags|=FS.tracking.openFlags.READ}if((flags&2097155)!==0){trackingFlags|=FS.tracking.openFlags.WRITE}FS.trackingDelegate["onOpenFile"](path,trackingFlags)}}catch(e){console.log("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: "+e.message)}return stream}),close:(function(stream){try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}}),llseek:(function(stream,offset,whence){if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position}),read:(function(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!stream.stream_ops.read){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}var seeking=true;if(typeof position==="undefined"){position=stream.position;seeking=false}else if(!stream.seekable){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead}),write:(function(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(ERRNO_CODES.EISDIR)}if(!stream.stream_ops.write){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if(stream.flags&1024){FS.llseek(stream,0,2)}var seeking=true;if(typeof position==="undefined"){position=stream.position;seeking=false}else if(!stream.seekable){throw new FS.ErrnoError(ERRNO_CODES.ESPIPE)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;try{if(stream.path&&FS.trackingDelegate["onWriteToFile"])FS.trackingDelegate["onWriteToFile"](stream.path)}catch(e){console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: "+e.message)}return bytesWritten}),allocate:(function(stream,offset,length){if(offset<0||length<=0){throw new FS.ErrnoError(ERRNO_CODES.EINVAL)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(ERRNO_CODES.EBADF)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(node.mode)){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP)}stream.stream_ops.allocate(stream,offset,length)}),mmap:(function(stream,buffer,offset,length,position,prot,flags){if((stream.flags&2097155)===1){throw new FS.ErrnoError(ERRNO_CODES.EACCES)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(ERRNO_CODES.ENODEV)}return stream.stream_ops.mmap(stream,buffer,offset,length,position,prot,flags)}),ioctl:(function(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(ERRNO_CODES.ENOTTY)}return stream.stream_ops.ioctl(stream,cmd,arg)}),readFile:(function(path,opts){opts=opts||{};opts.flags=opts.flags||"r";opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret="";var utf8=new Runtime.UTF8Processor;for(var i=0;i>2]=FS.getPtrForStream(stdin);assert(stdin.fd===0,"invalid handle for stdin ("+stdin.fd+")");var stdout=FS.open("/dev/stdout","w");HEAP32[_stdout>>2]=FS.getPtrForStream(stdout);assert(stdout.fd===1,"invalid handle for stdout ("+stdout.fd+")");var stderr=FS.open("/dev/stderr","w");HEAP32[_stderr>>2]=FS.getPtrForStream(stderr);assert(stderr.fd===2,"invalid handle for stderr ("+stderr.fd+")")}),ensureErrnoError:(function(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.node=node;this.setErrno=(function(errno){this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}});this.setErrno(errno);this.message=ERRNO_MESSAGES[errno]};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[ERRNO_CODES.ENOENT].forEach((function(code){FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""}))}),staticInit:(function(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices()}),init:(function(input,output,error){assert(!FS.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()}),quit:(function(){FS.init.initialized=false;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}});var lazyArray=this;lazyArray.setDataGetter((function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]}));this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperty(lazyArray,"length",{get:(function(){if(!this.lengthKnown){this.cacheLength()}return this._length})});Object.defineProperty(lazyArray,"chunkSize",{get:(function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize})});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperty(node,"usedBytes",{get:(function(){return this.contents.length})});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach((function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(ERRNO_CODES.EIO)}return fn.apply(null,arguments)}}));stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(ERRNO_CODES.EIO)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i>8,sock.sport&255]))}return peer}),getPeer:(function(sock,addr,port){return sock.peers[addr+":"+port]}),addPeer:(function(sock,peer){sock.peers[peer.addr+":"+peer.port]=peer}),removePeer:(function(sock,peer){delete sock.peers[peer.addr+":"+peer.port]}),handlePeerEvents:(function(sock,peer){var first=true;var handleOpen=(function(){Module["websocket"].emit("open",sock.stream.fd);try{var queued=peer.dgram_send_queue.shift();while(queued){peer.socket.send(queued);queued=peer.dgram_send_queue.shift()}}catch(e){peer.socket.close()}});function handleMessage(data){assert(typeof data!=="string"&&data.byteLength!==undefined);data=new Uint8Array(data);var wasfirst=first;first=false;if(wasfirst&&data.length===10&&data[0]===255&&data[1]===255&&data[2]===255&&data[3]===255&&data[4]==="p".charCodeAt(0)&&data[5]==="o".charCodeAt(0)&&data[6]==="r".charCodeAt(0)&&data[7]==="t".charCodeAt(0)){var newport=data[8]<<8|data[9];SOCKFS.websocket_sock_ops.removePeer(sock,peer);peer.port=newport;SOCKFS.websocket_sock_ops.addPeer(sock,peer);return}sock.recv_queue.push({addr:peer.addr,port:peer.port,data:data});Module["websocket"].emit("message",sock.stream.fd)}if(ENVIRONMENT_IS_NODE){peer.socket.on("open",handleOpen);peer.socket.on("message",(function(data,flags){if(!flags.binary){return}handleMessage((new Uint8Array(data)).buffer)}));peer.socket.on("close",(function(){Module["websocket"].emit("close",sock.stream.fd)}));peer.socket.on("error",(function(error){sock.error=ERRNO_CODES.ECONNREFUSED;Module["websocket"].emit("error",[sock.stream.fd,sock.error,"ECONNREFUSED: Connection refused"])}))}else{peer.socket.onopen=handleOpen;peer.socket.onclose=(function(){Module["websocket"].emit("close",sock.stream.fd)});peer.socket.onmessage=function peer_socket_onmessage(event){handleMessage(event.data)};peer.socket.onerror=(function(error){sock.error=ERRNO_CODES.ECONNREFUSED;Module["websocket"].emit("error",[sock.stream.fd,sock.error,"ECONNREFUSED: Connection refused"])})}}),poll:(function(sock){if(sock.type===1&&sock.server){return sock.pending.length?64|1:0}var mask=0;var dest=sock.type===1?SOCKFS.websocket_sock_ops.getPeer(sock,sock.daddr,sock.dport):null;if(sock.recv_queue.length||!dest||dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=64|1}if(!dest||dest&&dest.socket.readyState===dest.socket.OPEN){mask|=4}if(dest&&dest.socket.readyState===dest.socket.CLOSING||dest&&dest.socket.readyState===dest.socket.CLOSED){mask|=16}return mask}),ioctl:(function(sock,request,arg){switch(request){case 21531:var bytes=0;if(sock.recv_queue.length){bytes=sock.recv_queue[0].data.length}HEAP32[arg>>2]=bytes;return 0;default:return ERRNO_CODES.EINVAL}}),close:(function(sock){if(sock.server){try{sock.server.close()}catch(e){}sock.server=null}var peers=Object.keys(sock.peers);for(var i=0;i>2]=HEAP32[varargs+argIndex>>2],HEAP32[tempDoublePtr+4>>2]=HEAP32[varargs+(argIndex+4)>>2],+HEAPF64[tempDoublePtr>>3])}else if(type=="i64"){ret=[HEAP32[varargs+argIndex>>2],HEAP32[varargs+(argIndex+4)>>2]]}else{type="i32";ret=HEAP32[varargs+argIndex>>2]}argIndex+=Runtime.getNativeFieldSize(type);return ret}var ret=[];var curr,next,currArg;while(1){var startTextIndex=textIndex;curr=HEAP8[textIndex>>0];if(curr===0)break;next=HEAP8[textIndex+1>>0];if(curr==37){var flagAlwaysSigned=false;var flagLeftAlign=false;var flagAlternative=false;var flagZeroPad=false;var flagPadSign=false;flagsLoop:while(1){switch(next){case 43:flagAlwaysSigned=true;break;case 45:flagLeftAlign=true;break;case 35:flagAlternative=true;break;case 48:if(flagZeroPad){break flagsLoop}else{flagZeroPad=true;break};case 32:flagPadSign=true;break;default:break flagsLoop}textIndex++;next=HEAP8[textIndex+1>>0]}var width=0;if(next==42){width=getNextArg("i32");textIndex++;next=HEAP8[textIndex+1>>0]}else{while(next>=48&&next<=57){width=width*10+(next-48);textIndex++;next=HEAP8[textIndex+1>>0]}}var precisionSet=false,precision=-1;if(next==46){precision=0;precisionSet=true;textIndex++;next=HEAP8[textIndex+1>>0];if(next==42){precision=getNextArg("i32");textIndex++}else{while(1){var precisionChr=HEAP8[textIndex+1>>0];if(precisionChr<48||precisionChr>57)break;precision=precision*10+(precisionChr-48);textIndex++}}next=HEAP8[textIndex+1>>0]}if(precision<0){precision=6;precisionSet=false}var argSize;switch(String.fromCharCode(next)){case"h":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==104){textIndex++;argSize=1}else{argSize=2}break;case"l":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==108){textIndex++;argSize=8}else{argSize=4}break;case"L":case"q":case"j":argSize=8;break;case"z":case"t":case"I":argSize=4;break;default:argSize=null}if(argSize)textIndex++;next=HEAP8[textIndex+1>>0];switch(String.fromCharCode(next)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":{var signed=next==100||next==105;argSize=argSize||4;var currArg=getNextArg("i"+argSize*8);var origArg=currArg;var argText;if(argSize==8){currArg=Runtime.makeBigInt(currArg[0],currArg[1],next==117)}if(argSize<=4){var limit=Math.pow(256,argSize)-1;currArg=(signed?reSign:unSign)(currArg&limit,argSize*8)}var currAbsArg=Math.abs(currArg);var prefix="";if(next==100||next==105){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],null);else argText=reSign(currArg,8*argSize,1).toString(10)}else if(next==117){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],true);else argText=unSign(currArg,8*argSize,1).toString(10);currArg=Math.abs(currArg)}else if(next==111){argText=(flagAlternative?"0":"")+currAbsArg.toString(8)}else if(next==120||next==88){prefix=flagAlternative&&currArg!=0?"0x":"";if(argSize==8&&i64Math){if(origArg[1]){argText=(origArg[1]>>>0).toString(16);var lower=(origArg[0]>>>0).toString(16);while(lower.length<8)lower="0"+lower;argText+=lower}else{argText=(origArg[0]>>>0).toString(16)}}else if(currArg<0){currArg=-currArg;argText=(currAbsArg-1).toString(16);var buffer=[];for(var i=0;i=0){if(flagAlwaysSigned){prefix="+"+prefix}else if(flagPadSign){prefix=" "+prefix}}if(argText.charAt(0)=="-"){prefix="-"+prefix;argText=argText.substr(1)}while(prefix.length+argText.lengthexponent&&exponent>=-4){next=(next==103?"f":"F").charCodeAt(0);precision-=exponent+1}else{next=(next==103?"e":"E").charCodeAt(0);precision--}effectivePrecision=Math.min(precision,20)}if(next==101||next==69){argText=currArg.toExponential(effectivePrecision);if(/[eE][-+]\d$/.test(argText)){argText=argText.slice(0,-1)+"0"+argText.slice(-1)}}else if(next==102||next==70){argText=currArg.toFixed(effectivePrecision);if(currArg===0&&__reallyNegative(currArg)){argText="-"+argText}}var parts=argText.split("e");if(isGeneral&&!flagAlternative){while(parts[0].length>1&&parts[0].indexOf(".")!=-1&&(parts[0].slice(-1)=="0"||parts[0].slice(-1)==".")){parts[0]=parts[0].slice(0,-1)}}else{if(flagAlternative&&argText.indexOf(".")==-1)parts[0]+=".";while(precision>effectivePrecision++)parts[0]+="0"}argText=parts[0]+(parts.length>1?"e"+parts[1]:"");if(next==69)argText=argText.toUpperCase();if(currArg>=0){if(flagAlwaysSigned){argText="+"+argText}else if(flagPadSign){argText=" "+argText}}}while(argText.length>0])}}else{ret=ret.concat(intArrayFromString("(null)".substr(0,argLength),true))}if(flagLeftAlign){while(argLength0){ret.push(32)}if(!flagLeftAlign)ret.push(getNextArg("i8"));break};case"n":{var ptr=getNextArg("i32*");HEAP32[ptr>>2]=ret.length;break};case"%":{ret.push(curr);break};default:{for(var i=startTextIndex;i>0])}}}textIndex+=2}else{ret.push(curr);textIndex+=1}}return ret}function _fprintf(stream,format,varargs){var result=__formatString(format,varargs);var stack=Runtime.stackSave();var ret=_fwrite(allocate(result,"i8",ALLOC_STACK),1,result.length,stream);Runtime.stackRestore(stack);return ret}function _printf(format,varargs){var stdout=HEAP32[_stdout>>2];return _fprintf(stdout,format,varargs)}function _fputc(c,stream){var chr=unSign(c&255);HEAP8[_fputc.ret>>0]=chr;var fd=_fileno(stream);var ret=_write(fd,_fputc.ret,1);if(ret==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return-1}else{return chr}}function _putchar(c){return _fputc(c,HEAP32[_stdout>>2])}function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0)self.alloc(bytes);return ret}function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 79:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}Module["_memset"]=_memset;function ___errno_location(){return ___errno_state}function _abort(){Module["abort"]()}function _emscripten_set_main_loop_timing(mode,value){Browser.mainLoop.timingMode=mode;Browser.mainLoop.timingValue=value;if(!Browser.mainLoop.func){return 1}if(mode==0){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler(){setTimeout(Browser.mainLoop.runner,value)};Browser.mainLoop.method="timeout"}else if(mode==1){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler(){Browser.requestAnimationFrame(Browser.mainLoop.runner)};Browser.mainLoop.method="rAF"}return 0}function _emscripten_set_main_loop(func,fps,simulateInfiniteLoop,arg){Module["noExitRuntime"]=true;assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Browser.mainLoop.func=func;Browser.mainLoop.arg=arg;var thisMainLoopId=Browser.mainLoop.currentlyRunningMainloop;Browser.mainLoop.runner=function Browser_mainLoop_runner(){if(ABORT)return;if(Browser.mainLoop.queue.length>0){var start=Date.now();var blocker=Browser.mainLoop.queue.shift();blocker.func(blocker.arg);if(Browser.mainLoop.remainingBlockers){var remaining=Browser.mainLoop.remainingBlockers;var next=remaining%1==0?remaining-1:Math.floor(remaining);if(blocker.counted){Browser.mainLoop.remainingBlockers=next}else{next=next+.5;Browser.mainLoop.remainingBlockers=(8*remaining+next)/9}}console.log('main loop blocker "'+blocker.name+'" took '+(Date.now()-start)+" ms");Browser.mainLoop.updateStatus();setTimeout(Browser.mainLoop.runner,0);return}if(thisMainLoopId1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}if(Browser.mainLoop.method==="timeout"&&Module.ctx){Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!");Browser.mainLoop.method=""}Browser.mainLoop.runIter((function(){if(typeof arg!=="undefined"){Runtime.dynCall("vi",func,[arg])}else{Runtime.dynCall("v",func)}}));if(thisMainLoopId0)_emscripten_set_main_loop_timing(0,1e3/fps);else _emscripten_set_main_loop_timing(1,1);Browser.mainLoop.scheduler();if(simulateInfiniteLoop){throw"SimulateInfiniteLoop"}}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:(function(){Browser.mainLoop.scheduler=null;Browser.mainLoop.currentlyRunningMainloop++}),resume:(function(){Browser.mainLoop.currentlyRunningMainloop++;var timingMode=Browser.mainLoop.timingMode;var timingValue=Browser.mainLoop.timingValue;var func=Browser.mainLoop.func;Browser.mainLoop.func=null;_emscripten_set_main_loop(func,0,false,Browser.mainLoop.arg);_emscripten_set_main_loop_timing(timingMode,timingValue)}),updateStatus:(function(){if(Module["setStatus"]){var message=Module["statusMessage"]||"Please wait...";var remaining=Browser.mainLoop.remainingBlockers;var expected=Browser.mainLoop.expectedBlockers;if(remaining){if(remaining=6){var curr=leftchar>>leftbits-6&63;leftbits-=6;ret+=BASE[curr]}}if(leftbits==2){ret+=BASE[(leftchar&3)<<4];ret+=PAD+PAD}else if(leftbits==4){ret+=BASE[(leftchar&15)<<2];ret+=PAD}return ret}audio.src="data:audio/x-"+name.substr(-3)+";base64,"+encode64(byteArray);finish(audio)};audio.src=url;Browser.safeSetTimeout((function(){finish(audio)}),1e4)}else{return fail()}};Module["preloadPlugins"].push(audioPlugin);var canvas=Module["canvas"];function pointerLockChange(){Browser.pointerLock=document["pointerLockElement"]===canvas||document["mozPointerLockElement"]===canvas||document["webkitPointerLockElement"]===canvas||document["msPointerLockElement"]===canvas}if(canvas){canvas.requestPointerLock=canvas["requestPointerLock"]||canvas["mozRequestPointerLock"]||canvas["webkitRequestPointerLock"]||canvas["msRequestPointerLock"]||(function(){});canvas.exitPointerLock=document["exitPointerLock"]||document["mozExitPointerLock"]||document["webkitExitPointerLock"]||document["msExitPointerLock"]||(function(){});canvas.exitPointerLock=canvas.exitPointerLock.bind(document);document.addEventListener("pointerlockchange",pointerLockChange,false);document.addEventListener("mozpointerlockchange",pointerLockChange,false);document.addEventListener("webkitpointerlockchange",pointerLockChange,false);document.addEventListener("mspointerlockchange",pointerLockChange,false);if(Module["elementPointerLock"]){canvas.addEventListener("click",(function(ev){if(!Browser.pointerLock&&canvas.requestPointerLock){canvas.requestPointerLock();ev.preventDefault()}}),false)}}}),createContext:(function(canvas,useWebGL,setInModule,webGLContextAttributes){if(useWebGL&&Module.ctx&&canvas==Module.canvas)return Module.ctx;var ctx;var contextHandle;if(useWebGL){var contextAttributes={antialias:false,alpha:false};if(webGLContextAttributes){for(var attribute in webGLContextAttributes){contextAttributes[attribute]=webGLContextAttributes[attribute]}}contextHandle=GL.createContext(canvas,contextAttributes);if(contextHandle){ctx=GL.getContext(contextHandle).GLctx}canvas.style.backgroundColor="black"}else{ctx=canvas.getContext("2d")}if(!ctx)return null;if(setInModule){if(!useWebGL)assert(typeof GLctx==="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it");Module.ctx=ctx;if(useWebGL)GL.makeContextCurrent(contextHandle);Module.useWebGL=useWebGL;Browser.moduleContextCreatedCallbacks.forEach((function(callback){callback()}));Browser.init()}return ctx}),destroyContext:(function(canvas,useWebGL,setInModule){}),fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:(function(lockPointer,resizeCanvas){Browser.lockPointer=lockPointer;Browser.resizeCanvas=resizeCanvas;if(typeof Browser.lockPointer==="undefined")Browser.lockPointer=true;if(typeof Browser.resizeCanvas==="undefined")Browser.resizeCanvas=false;var canvas=Module["canvas"];function fullScreenChange(){Browser.isFullScreen=false;var canvasContainer=canvas.parentNode;if((document["webkitFullScreenElement"]||document["webkitFullscreenElement"]||document["mozFullScreenElement"]||document["mozFullscreenElement"]||document["fullScreenElement"]||document["fullscreenElement"]||document["msFullScreenElement"]||document["msFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvasContainer){canvas.cancelFullScreen=document["cancelFullScreen"]||document["mozCancelFullScreen"]||document["webkitCancelFullScreen"]||document["msExitFullscreen"]||document["exitFullscreen"]||(function(){});canvas.cancelFullScreen=canvas.cancelFullScreen.bind(document);if(Browser.lockPointer)canvas.requestPointerLock();Browser.isFullScreen=true;if(Browser.resizeCanvas)Browser.setFullScreenCanvasSize()}else{canvasContainer.parentNode.insertBefore(canvas,canvasContainer);canvasContainer.parentNode.removeChild(canvasContainer);if(Browser.resizeCanvas)Browser.setWindowedCanvasSize()}if(Module["onFullScreen"])Module["onFullScreen"](Browser.isFullScreen);Browser.updateCanvasDimensions(canvas)}if(!Browser.fullScreenHandlersInstalled){Browser.fullScreenHandlersInstalled=true;document.addEventListener("fullscreenchange",fullScreenChange,false);document.addEventListener("mozfullscreenchange",fullScreenChange,false);document.addEventListener("webkitfullscreenchange",fullScreenChange,false);document.addEventListener("MSFullscreenChange",fullScreenChange,false)}var canvasContainer=document.createElement("div");canvas.parentNode.insertBefore(canvasContainer,canvas);canvasContainer.appendChild(canvas);canvasContainer.requestFullScreen=canvasContainer["requestFullScreen"]||canvasContainer["mozRequestFullScreen"]||canvasContainer["msRequestFullscreen"]||(canvasContainer["webkitRequestFullScreen"]?(function(){canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"])}):null);canvasContainer.requestFullScreen()}),nextRAF:0,fakeRequestAnimationFrame:(function(func){var now=Date.now();if(Browser.nextRAF===0){Browser.nextRAF=now+1e3/60}else{while(now+2>=Browser.nextRAF){Browser.nextRAF+=1e3/60}}var delay=Math.max(Browser.nextRAF-now,0);setTimeout(func,delay)}),requestAnimationFrame:function requestAnimationFrame(func){if(typeof window==="undefined"){Browser.fakeRequestAnimationFrame(func)}else{if(!window.requestAnimationFrame){window.requestAnimationFrame=window["requestAnimationFrame"]||window["mozRequestAnimationFrame"]||window["webkitRequestAnimationFrame"]||window["msRequestAnimationFrame"]||window["oRequestAnimationFrame"]||Browser.fakeRequestAnimationFrame}window.requestAnimationFrame(func)}},safeCallback:(function(func){return(function(){if(!ABORT)return func.apply(null,arguments)})}),safeRequestAnimationFrame:(function(func){return Browser.requestAnimationFrame((function(){if(!ABORT)func()}))}),safeSetTimeout:(function(func,timeout){Module["noExitRuntime"]=true;return setTimeout((function(){if(!ABORT)func()}),timeout)}),safeSetInterval:(function(func,timeout){Module["noExitRuntime"]=true;return setInterval((function(){if(!ABORT)func()}),timeout)}),getMimetype:(function(name){return{"jpg":"image/jpeg","jpeg":"image/jpeg","png":"image/png","bmp":"image/bmp","ogg":"audio/ogg","wav":"audio/wav","mp3":"audio/mpeg"}[name.substr(name.lastIndexOf(".")+1)]}),getUserMedia:(function(func){if(!window.getUserMedia){window.getUserMedia=navigator["getUserMedia"]||navigator["mozGetUserMedia"]}window.getUserMedia(func)}),getMovementX:(function(event){return event["movementX"]||event["mozMovementX"]||event["webkitMovementX"]||0}),getMovementY:(function(event){return event["movementY"]||event["mozMovementY"]||event["webkitMovementY"]||0}),getMouseWheelDelta:(function(event){var delta=0;switch(event.type){case"DOMMouseScroll":delta=event.detail;break;case"mousewheel":delta=event.wheelDelta;break;case"wheel":delta=event["deltaY"];break;default:throw"unrecognized mouse wheel event: "+event.type}return delta}),mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:(function(event){if(Browser.pointerLock){if(event.type!="mousemove"&&"mozMovementX"in event){Browser.mouseMovementX=Browser.mouseMovementY=0}else{Browser.mouseMovementX=Browser.getMovementX(event);Browser.mouseMovementY=Browser.getMovementY(event)}if(typeof SDL!="undefined"){Browser.mouseX=SDL.mouseX+Browser.mouseMovementX;Browser.mouseY=SDL.mouseY+Browser.mouseMovementY}else{Browser.mouseX+=Browser.mouseMovementX;Browser.mouseY+=Browser.mouseMovementY}}else{var rect=Module["canvas"].getBoundingClientRect();var cw=Module["canvas"].width;var ch=Module["canvas"].height;var scrollX=typeof window.scrollX!=="undefined"?window.scrollX:window.pageXOffset;var scrollY=typeof window.scrollY!=="undefined"?window.scrollY:window.pageYOffset;if(event.type==="touchstart"||event.type==="touchend"||event.type==="touchmove"){var touch=event.touch;if(touch===undefined){return}var adjustedX=touch.pageX-(scrollX+rect.left);var adjustedY=touch.pageY-(scrollY+rect.top);adjustedX=adjustedX*(cw/rect.width);adjustedY=adjustedY*(ch/rect.height);var coords={x:adjustedX,y:adjustedY};if(event.type==="touchstart"){Browser.lastTouches[touch.identifier]=coords;Browser.touches[touch.identifier]=coords}else if(event.type==="touchend"||event.type==="touchmove"){Browser.lastTouches[touch.identifier]=Browser.touches[touch.identifier];Browser.touches[touch.identifier]={x:adjustedX,y:adjustedY}}return}var x=event.pageX-(scrollX+rect.left);var y=event.pageY-(scrollY+rect.top);x=x*(cw/rect.width);y=y*(ch/rect.height);Browser.mouseMovementX=x-Browser.mouseX;Browser.mouseMovementY=y-Browser.mouseY;Browser.mouseX=x;Browser.mouseY=y}}),xhrLoad:(function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response)}else{onerror()}};xhr.onerror=onerror;xhr.send(null)}),asyncLoad:(function(url,onload,onerror,noRunDep){Browser.xhrLoad(url,(function(arrayBuffer){assert(arrayBuffer,'Loading data file "'+url+'" failed (no arrayBuffer).');onload(new Uint8Array(arrayBuffer));if(!noRunDep)removeRunDependency("al "+url)}),(function(event){if(onerror){onerror()}else{throw'Loading data file "'+url+'" failed.'}}));if(!noRunDep)addRunDependency("al "+url)}),resizeListeners:[],updateResizeListeners:(function(){var canvas=Module["canvas"];Browser.resizeListeners.forEach((function(listener){listener(canvas.width,canvas.height)}))}),setCanvasSize:(function(width,height,noUpdates){var canvas=Module["canvas"];Browser.updateCanvasDimensions(canvas,width,height);if(!noUpdates)Browser.updateResizeListeners()}),windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:(function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];flags=flags|8388608;HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=flags}Browser.updateResizeListeners()}),setWindowedCanvasSize:(function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];flags=flags&~8388608;HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=flags}Browser.updateResizeListeners()}),updateCanvasDimensions:(function(canvas,wNative,hNative){if(wNative&&hNative){canvas.widthNative=wNative;canvas.heightNative=hNative}else{wNative=canvas.widthNative;hNative=canvas.heightNative}var w=wNative;var h=hNative;if(Module["forcedAspectRatio"]&&Module["forcedAspectRatio"]>0){if(w/h>2]=ret}return ret}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;FS.staticInit();__ATINIT__.unshift({func:(function(){if(!Module["noFSInit"]&&!FS.init.initialized)FS.init()})});__ATMAIN__.push({func:(function(){FS.ignorePermissions=false})});__ATEXIT__.push({func:(function(){FS.quit()})});Module["FS_createFolder"]=FS.createFolder;Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createLink"]=FS.createLink;Module["FS_createDevice"]=FS.createDevice;___errno_state=Runtime.staticAlloc(4);HEAP32[___errno_state>>2]=0;__ATINIT__.unshift({func:(function(){TTY.init()})});__ATEXIT__.push({func:(function(){TTY.shutdown()})});TTY.utf8=new Runtime.UTF8Processor;if(ENVIRONMENT_IS_NODE){var fs=require("fs");NODEFS.staticInit()}__ATINIT__.push({func:(function(){SOCKFS.root=FS.mount(SOCKFS,{},null)})});_fputc.ret=allocate([0],"i8",ALLOC_STATIC);Module["requestFullScreen"]=function Module_requestFullScreen(lockPointer,resizeCanvas){Browser.requestFullScreen(lockPointer,resizeCanvas)};Module["requestAnimationFrame"]=function Module_requestAnimationFrame(func){Browser.requestAnimationFrame(func)};Module["setCanvasSize"]=function Module_setCanvasSize(width,height,noUpdates){Browser.setCanvasSize(width,height,noUpdates)};Module["pauseMainLoop"]=function Module_pauseMainLoop(){Browser.mainLoop.pause()};Module["resumeMainLoop"]=function Module_resumeMainLoop(){Browser.mainLoop.resume()};Module["getUserMedia"]=function Module_getUserMedia(){Browser.getUserMedia()};STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP);staticSealed=true;STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=DYNAMICTOP=Runtime.alignMemory(STACK_MAX);assert(DYNAMIC_BASE>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Da(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ea(a){a=a|0;B=a}function Fa(){return B|0}function Ga(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0;W=i;Va(3016,0,11824)|0;c[3710]=0;if((e|0)>0){h=0;j=0;do{g=a[b+j>>0]|0;a:do if((g+-48<<24>>24&255)>=10)if((g+-65<<24>>24&255)<26)g=1;else{switch(g<<24>>24){case 58:case 47:case 46:case 45:case 43:case 42:case 37:case 36:case 32:{g=1;break a}default:{}}g=2}else g=0;while(0);if(!j)a[14848]=g;if((a[14848+h>>0]|0)!=g<<24>>24){h=h+1|0;c[3710]=h;a[14848+h>>0]=g}B=3016+(h<<2)|0;c[B>>2]=(c[B>>2]|0)+1;j=j+1|0}while((j|0)!=(e|0));g=h+1|0;c[3710]=g;b:do if((h|0)>0){E=3e3+(f<<2)|0;F=2984+(f<<2)|0;G=2968+(f<<2)|0;C=0;do{s=14848+C|0;D=C;C=C+1|0;t=14848+C|0;u=3016+(D<<2)|0;v=3016+(C<<2)|0;w=(D|0)>0;y=D+-1|0;x=14848+y|0;y=3016+(y<<2)|0;z=D+2|0;A=14848+z|0;B=3016+(z<<2)|0;while(1){m=a[s>>0]|0;if(m<<24>>24==1)if(!(a[t>>0]|0))o=0;else break;else if(m<<24>>24==0?(a[t>>0]|0)==1:0)o=1;else break;k=c[u>>2]|0;r=m&255;do if(!r){n=(c[G>>2]|0)+4+(((k|0)/3|0)*10|0)|0;m=(k|0)%3|0;if((m|0)==1){n=n+4|0;break}else if((m|0)==2){n=n+7|0;break}else break}else if((r|0)==1)n=(c[F>>2]|0)+4+(((k|0)/2|0)*11|0)+(((k|0)%2|0)*6|0)|0;else n=(c[E>>2]|0)+(k<<3|4)|0;while(0);l=c[v>>2]|0;do if(!o){m=(c[G>>2]|0)+4+(((l|0)/3|0)*10|0)|0;e=(l|0)%3|0;if((e|0)==1){m=m+4|0;break}else if((e|0)==2){m=m+7|0;break}else break}else if((o|0)==1)m=(c[F>>2]|0)+4+(((l|0)/2|0)*11|0)+(((l|0)%2|0)*6|0)|0;else m=(c[E>>2]|0)+(l<<3|4)|0;while(0);q=l+k|0;p=(c[F>>2]|0)+4|0;q=(((q|0)/2|0)*11|0)+p+(((q|0)%2|0)*6|0)|0;if((m+n|0)<=(q|0))break;if(w?(a[x>>0]|0)==2:0){e=c[y>>2]|0;j=c[E>>2]|0;h=(e+k<<3|4)+j|0;do if((o|0)==1)n=(((l|0)/2|0)*11|0)+p+(((l|0)%2|0)*6|0)|0;else if(!o){n=(c[G>>2]|0)+4+(((l|0)/3|0)*10|0)|0;m=(l|0)%3|0;if((m|0)==2){n=n+7|0;break}else if((m|0)==1){n=n+4|0;break}else break}else n=j+(l<<3|4)|0;while(0);h=h+n|0;j=(h|0)>(j+q+(e<<3|4)|0)?0:h}else j=0;h=(D|0)<(g+-2|0);if(h?(a[A>>0]|0)==2:0){do if(!r){n=(c[G>>2]|0)+4+(((k|0)/3|0)*10|0)|0;m=(k|0)%3|0;if((m|0)==1){n=n+4|0;break}else if((m|0)==2){n=n+7|0;break}else break}else if((r|0)==1)n=p+(((k|0)/2|0)*11|0)+(((k|0)%2|0)*6|0)|0;else n=(c[E>>2]|0)+(k<<3|4)|0;while(0);m=c[B>>2]|0;e=c[E>>2]|0;n=e+n+(m+l<<3|4)|0;n=(n|0)>(e+q+(m<<3|4)|0)?0:n;m=(j|0)!=0;e=(n|0)!=0;if(m&e)m=(j|0)<(n|0)?-1:1;else H=53}else{e=0;m=(j|0)!=0;H=53}if((H|0)==53){H=0;m=m?-1:e&1}if((m|0)==-1){c[y>>2]=(c[y>>2]|0)+k;l=g+-1|0;if((D|0)<(l|0)){k=D;do{r=k;k=k+1|0;a[14848+r>>0]=a[14848+k>>0]|0;c[3016+(r<<2)>>2]=c[3016+(k<<2)>>2]}while((k|0)<(l|0));H=59}else H=59}else if(!m){if(h?(a[A>>0]|0)==1:0){l=l+(c[B>>2]|0)|0;c[v>>2]=l;m=g+-1|0;if((z|0)<(m|0)){l=z;do{r=l;l=l+1|0;a[14848+r>>0]=a[14848+l>>0]|0;c[3016+(r<<2)>>2]=c[3016+(l<<2)>>2]}while((l|0)<(m|0));l=c[v>>2]|0;k=c[u>>2]|0}c[3710]=m}else m=g;a[s>>0]=1;c[u>>2]=k+l;g=m+-1|0;if((C|0)<(g|0)){l=C;do{r=l;l=l+1|0;a[14848+r>>0]=a[14848+l>>0]|0;c[3016+(r<<2)>>2]=c[3016+(l<<2)>>2]}while((l|0)<(g|0))}c[3710]=g;if(w?(a[x>>0]|0)==1:0){c[y>>2]=(c[y>>2]|0)+(c[u>>2]|0);g=m+-2|0;if((D|0)<(g|0)){l=D;do{r=l;l=l+1|0;a[14848+r>>0]=a[14848+l>>0]|0;c[3016+(r<<2)>>2]=c[3016+(l<<2)>>2]}while((l|0)<(g|0))}c[3710]=g}}else{a[t>>0]=2;c[v>>2]=l+(c[B>>2]|0);l=g+-1|0;if((z|0)<(l|0)){k=z;do{r=k;k=k+1|0;a[14848+r>>0]=a[14848+k>>0]|0;c[3016+(r<<2)>>2]=c[3016+(k<<2)>>2]}while((k|0)<(l|0));H=59}else H=59}if((H|0)==59){H=0;g=g+-1|0;c[3710]=g}if((D|0)>=(g+-1|0))break b}}while((C|0)<(g+-1|0))}while(0);if((g+-1|0)>0){p=c[3e3+(f<<2)>>2]|0;o=2968+(f<<2)|0;q=2984+(f<<2)|0;h=0;do{n=c[3016+(h<<2)>>2]|0;j=d[14848+h>>0]|0;do if(!j){e=(c[o>>2]|0)+4+(((n|0)/3|0)*10|0)|0;j=(n|0)%3|0;if((j|0)==1){e=e+4|0;break}else if((j|0)==2){e=e+7|0;break}else break}else if((j|0)==1)e=(c[q>>2]|0)+4+(((n|0)/2|0)*11|0)+(((n|0)%2|0)*6|0)|0;else e=p+(n<<3|4)|0;while(0);m=h+1|0;l=c[3016+(m<<2)>>2]|0;k=d[14848+m>>0]|0;do if((k|0)==1)k=(c[q>>2]|0)+4+(((l|0)/2|0)*11|0)+(((l|0)%2|0)*6|0)|0;else if(!k){k=(c[o>>2]|0)+4+(((l|0)/3|0)*10|0)|0;j=(l|0)%3|0;if((j|0)==2){k=k+7|0;break}else if((j|0)==1){k=k+4|0;break}else break}else k=p+(l<<3|4)|0;while(0);j=k+e|0;e=l+n<<3|4;k=e+p|0;l=(h|0)>0;if(l)k=(a[14848+(h+-1)>>0]|0)==2?e+-4|0:k;if((h|0)<(g+-2|0)?(a[h+14850>>0]|0)==2:0)k=k+-4-p|0;if((j|0)>(k|0)){if(l?(I=h+-1|0,(a[14848+I>>0]|0)==2):0){B=3016+(I<<2)|0;c[B>>2]=(c[B>>2]|0)+n;g=g+-1|0;if((h|0)<(g|0))do{B=h;h=h+1|0;a[14848+B>>0]=a[14848+h>>0]|0;c[3016+(B<<2)>>2]=c[3016+(h<<2)>>2]}while((h|0)<(g|0));c[3710]=g;h=I}if((h|0)<(g+-2|0)?(J=h+2|0,(a[14848+J>>0]|0)==2):0){B=3016+(h+1<<2)|0;c[B>>2]=(c[B>>2]|0)+(c[3016+(J<<2)>>2]|0);g=g+-1|0;if((J|0)<(g|0)){j=J;do{B=j;j=j+1|0;a[14848+B>>0]=a[14848+j>>0]|0;c[3016+(B<<2)>>2]=c[3016+(j<<2)>>2]}while((j|0)<(g|0))}c[3710]=g}a[14848+h>>0]=2;j=h+1|0;B=3016+(h<<2)|0;c[B>>2]=(c[B>>2]|0)+(c[3016+(j<<2)>>2]|0);g=g+-1|0;if((j|0)<(g|0))do{B=j;j=j+1|0;a[14848+B>>0]=a[14848+j>>0]|0;c[3016+(B<<2)>>2]=c[3016+(j<<2)>>2]}while((j|0)<(g|0));c[3710]=g;h=(((h|0)>0)<<31>>31)+h|0}else h=m}while((h|0)<(g+-1|0))}c[4452]=0;Va(8,0,2956)|0;if((g|0)>0)s=g;else{B=1;B=B&1;i=W;return B|0}}else{c[3710]=1;c[4452]=0;Va(8,0,2956)|0;s=1}o=3e3+(f<<2)|0;p=2968+(f<<2)|0;r=2984+(f<<2)|0;g=0;q=0;n=0;while(1){h=a[14848+q>>0]|0;if(!(h<<24>>24)){if((g|0)!=-1?(K=g+4|0,(K|0)<=23648):0){e=g+3|0;k=8+((e|0)/8|0)|0;a[k>>0]=d[k>>0]|1<<7-((e|0)%8|0);c[4452]=K;k=c[3016+(q<<2)>>2]|0;e=c[p>>2]|0;if((K|0)!=-1?(L=e+K|0,(L|0)<=23648):0){j=k&65535;h=e+-1|0;g=0;do{if(j&1<>0]=d[B>>0]|1<<7-((A|0)%8|0)}g=g+1|0}while((g|0)!=(e|0));h=L}else h=-1}else{c[4452]=-1;h=-1;k=c[3016+(q<<2)>>2]|0}c[4452]=h;if((k|0)>0){l=0;do{j=k+-2|0;do if((l|0)<(j|0)){j=l+n|0;j=((a[b+j>>0]|0)*100|0)+60208+((a[b+(j+1)>>0]|0)*10|0)+(a[b+(j+2)>>0]|0)|0;if((h|0)!=-1?(M=h+10|0,(M|0)<=23648):0){e=j&65535;j=0;do{if(e&1<<9-j){A=j+h|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}j=j+1|0}while((j|0)!=10);h=M}else h=-1;c[4452]=h}else{if((l|0)!=(j|0)){if((l|0)!=(k+-1|0))break;j=(a[b+(l+n)>>0]|0)+65488|0;if((h|0)!=-1?(O=h+4|0,(O|0)<=23648):0){if(j&8){B=8+((h|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((h|0)%8|0)}if(j&4){A=h+1|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&2){A=h+2|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(!(j&1))h=O;else{B=h+3|0;h=8+((B|0)/8|0)|0;a[h>>0]=d[h>>0]|1<<7-((B|0)%8|0);h=O}}else h=-1;c[4452]=h;break}j=l+n|0;j=(a[b+(j+1)>>0]|0)+65008+((a[b+j>>0]|0)*10|0)|0;if((h|0)!=-1?(N=h+7|0,(N|0)<=23648):0){if(j&64){B=8+((h|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((h|0)%8|0)}if(j&32){A=h+1|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&16){A=h+2|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&8){A=h+3|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&4){A=h+4|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&2){A=h+5|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(!(j&1))h=N;else{B=h+6|0;h=8+((B|0)/8|0)|0;a[h>>0]=d[h>>0]|1<<7-((B|0)%8|0);h=N}}else h=-1;c[4452]=h}while(0);l=l+3|0}while((l|0)<(k|0))}}else if(h<<24>>24==1){if((g|0)!=-1?(P=g+4|0,(P|0)<=23648):0){e=g+2|0;k=8+((e|0)/8|0)|0;a[k>>0]=d[k>>0]|1<<7-((e|0)%8|0);c[4452]=P;k=c[3016+(q<<2)>>2]|0;e=c[r>>2]|0;if((P|0)!=-1?(Q=e+P|0,(Q|0)<=23648):0){j=k&65535;h=e+-1|0;g=0;do{if(j&1<>0]=d[B>>0]|1<<7-((A|0)%8|0)}g=g+1|0}while((g|0)!=(e|0));h=Q}else h=-1}else{c[4452]=-1;h=-1;k=c[3016+(q<<2)>>2]|0}c[4452]=h;if((k|0)>0){m=0;do{g=(m|0)<(k+-1|0);l=m+n|0;e=a[b+l>>0]|0;j=e&255;c:do if((e+-48<<24>>24&255)<10)e=j+208&255;else{if((e+-65<<24>>24&255)<26){e=j+201&255;break}switch(e<<24>>24){case 36:{e=37;break c}case 37:{e=38;break c}case 42:{e=39;break c}case 43:{e=40;break c}case 45:{e=41;break c}case 46:{e=42;break c}case 47:{e=43;break c}case 32:{e=36;break c}default:{e=44;break c}}}while(0);if(g){g=(e&255)*45|0;e=a[b+(l+1)>>0]|0;j=e&255;d:do if((e+-48<<24>>24&255)<10)e=j+208|0;else{if((e+-65<<24>>24&255)<26){e=j+201|0;break}switch(e<<24>>24){case 36:{e=37;break d}case 37:{e=38;break d}case 42:{e=39;break d}case 43:{e=40;break d}case 45:{e=41;break d}case 46:{e=42;break d}case 47:{e=43;break d}case 32:{e=36;break d}default:{e=44;break d}}}while(0);j=(e&255)+g|0;if((h|0)!=-1?(R=h+11|0,(R|0)<=23648):0){e=j&65535;j=0;do{if(e&1<<10-j){A=j+h|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}j=j+1|0}while((j|0)!=11);h=R}else h=-1}else if((h|0)!=-1?(S=h+6|0,(S|0)<=23648):0){j=e&255;if(j&32){B=8+((h|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((h|0)%8|0)}if(j&16){A=h+1|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&8){A=h+2|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&4){A=h+3|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(j&2){A=h+4|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}if(!(j&1))h=S;else{B=h+5|0;h=8+((B|0)/8|0)|0;a[h>>0]=d[h>>0]|1<<7-((B|0)%8|0);h=S}}else h=-1;c[4452]=h;m=m+2|0}while((m|0)<(k|0))}}else{if((g|0)!=-1?(T=g+4|0,(T|0)<=23648):0){e=g+1|0;k=8+((e|0)/8|0)|0;a[k>>0]=d[k>>0]|1<<7-((e|0)%8|0);c[4452]=T;k=c[3016+(q<<2)>>2]|0;e=c[o>>2]|0;if((T|0)!=-1?(U=e+T|0,(U|0)<=23648):0){j=k&65535;h=e+-1|0;g=0;do{if(j&1<>0]=d[B>>0]|1<<7-((A|0)%8|0)}g=g+1|0}while((g|0)!=(e|0));h=U}else h=-1}else{c[4452]=-1;h=-1;k=c[3016+(q<<2)>>2]|0}c[4452]=h;if((k|0)>0){g=0;do{j=a[b+(g+n)>>0]|0;if((h|0)!=-1?(V=h+8|0,(V|0)<=23648):0){e=j&65535;j=0;do{if(e&1<<7-j){A=j+h|0;B=8+((A|0)/8|0)|0;a[B>>0]=d[B>>0]|1<<7-((A|0)%8|0)}j=j+1|0}while((j|0)!=8);h=V}else h=-1;c[4452]=h;g=g+1|0}while((g|0)<(k|0))}}q=q+1|0;g=(h|0)!=-1;if(!((q|0)<(s|0)&g))break;else{g=h;n=k+n|0}}B=g&1;i=W;return B|0}function Ha(a,b,d){a=a|0;b=b|0;d=d|0;var f=0,g=0,h=0,j=0;j=i;if((a|0)>26)h=2;else h=(a|0)>9&1;a:while(1){do if(Ga(b,d,h)|0)if((h|0)==1){a=((c[4452]|0)+7|0)/8|0;g=c[4454]|0;f=10;do{if((a|0)<=(e[55208+(f*44|0)+(g<<1)+4>>1]|0|0)){a=15;break a}f=f+1|0}while((f|0)<27)}else if((h|0)==2){g=((c[4452]|0)+7|0)/8|0;a=c[4454]|0;f=27;do{if((g|0)<=(e[55208+(f*44|0)+(a<<1)+4>>1]|0|0)){a=15;break a}f=f+1|0}while((f|0)<41)}else if(!h){g=((c[4452]|0)+7|0)/8|0;a=c[4454]|0;f=1;do{if((g|0)<=(e[55208+(f*44|0)+(a<<1)+4>>1]|0|0)){a=15;break a}f=f+1|0}while((f|0)<10)}else break;while(0);h=h+1|0;if((h|0)>=3){f=0;a=15;break}}if((a|0)==15){i=j;return f|0}return 0}function Ia(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;p=i;if((e|0)<=0){i=p;return}n=e+-1+f|0;m=(n|0)>(f|0);k=18080+(f<<2)|0;n=(n|0)>0;o=f+e+-1|0;if((f|0)>0)l=0;else{h=0;do{if(!(a[b>>0]|0)){if(n){g=0;do{l=g;g=g+1|0;a[b+l>>0]=a[b+g>>0]|0}while((g|0)!=(o|0))}}else if(m){g=f;do{l=g;g=g+1|0;a[b+l>>0]=a[b+g>>0]|0}while((g|0)!=(o|0))}h=h+1|0}while((h|0)!=(e|0));i=p;return}do{h=a[b>>0]|0;if(!(h<<24>>24)){if(n){h=0;do{j=h;h=h+1|0;a[b+j>>0]=a[b+h>>0]|0}while((h|0)!=(o|0))}}else{j=c[k>>2]|0;h=d[17824+(h&255)>>0]|0;g=0;do{q=g;g=g+1|0;a[b+q>>0]=a[18360+((((d[j+q>>0]|0)+h|0)>>>0)%255|0)>>0]^a[b+g>>0]}while((g|0)!=(f|0));if(m){h=f;do{j=h;h=h+1|0;a[b+j>>0]=a[b+h>>0]|0}while((h|0)!=(o|0))}}l=l+1|0}while((l|0)!=(e|0));i=p;return}function Ja(){var b=0,d=0,e=0,f=0,g=0,h=0,j=0;f=i;b=c[12490]|0;if((b|0)<7){i=f;return}d=b<<12;b=(d&131072|0)==0?d:d^255136;b=(b&65536|0)==0?b:b^127568;b=(b&32768|0)==0?b:b^63784;b=(b&16384|0)==0?b:b^31892;b=(b&8192|0)==0?b:b^15946;b=d+((b&4096|0)==0?b:b^7973)|0;d=c[12492]|0;e=0;do{h=e*3|0;g=(1<>0]=g;a[18624+(j*177|0)+e>>0]=g;j=(1<>0]=j;a[18624+(g*177|0)+e>>0]=j;h=(1<>0]=h;a[18624+(g*177|0)+e>>0]=h;e=e+1|0}while((e|0)!=6);i=f;return}function Ka(){var b=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;q=i;b=0;do{n=d[18616+b>>0]|0;a[18624+b>>0]=(n&64)>>>2|32;a[18801+b>>0]=(n&32)>>>1|32;a[18978+b>>0]=n&16|32;a[19155+b>>0]=(n&8)<<1&255|32;a[19332+b>>0]=(n&4)<<2&255|32;a[19509+b>>0]=(n&2)<<3&255|32;a[19686+b>>0]=(n&1)<<4&255|32;b=b+1|0}while((b|0)!=7);j=c[12492]|0;e=j+-7|0;b=j+-6|0;l=j+-5|0;m=j+-4|0;n=j+-3|0;o=j+-2|0;p=j+-1|0;g=0;do{k=d[18616+g>>0]|0;a[18624+(e*177|0)+g>>0]=(k&64)>>>2|32;a[18624+(b*177|0)+g>>0]=(k&32)>>>1|32;a[18624+(l*177|0)+g>>0]=k&16|32;a[18624+(m*177|0)+g>>0]=(k&8)<<1&255|32;a[18624+(n*177|0)+g>>0]=(k&4)<<2&255|32;a[18624+(o*177|0)+g>>0]=(k&2)<<3&255|32;a[18624+(p*177|0)+g>>0]=(k&1)<<4&255|32;g=g+1|0}while((g|0)!=7);g=0;do{h=d[18616+g>>0]|0;k=e+g|0;a[18624+k>>0]=(h&64)>>>2|32;a[18801+k>>0]=(h&32)>>>1|32;a[18978+k>>0]=h&16|32;a[19155+k>>0]=(h&8)<<1&255|32;a[19332+k>>0]=(h&4)<<2&255|32;a[19509+k>>0]=(h&2)<<3&255|32;a[19686+k>>0]=(h&1)<<4&255|32;g=g+1|0}while((g|0)!=7);k=j+-8|0;h=0;do{a[19863+h>>0]=32;a[18631+(h*177|0)>>0]=32;g=h+-8+j|0;a[18631+(g*177|0)>>0]=32;a[18624+(k*177|0)+h>>0]=32;a[19863+g>>0]=32;a[18624+(h*177|0)+k>>0]=32;h=h+1|0}while((h|0)!=8);a[18632]=32;a[18809]=32;a[18986]=32;a[19163]=32;a[19340]=32;a[19517]=32;a[19694]=32;a[19871]=32;h=20040+k|0;g=20040|0;f=g+9|0;do{a[g>>0]=32;g=g+1|0}while((g|0)<(f|0));a[h>>0]=32;a[18632+(k*177|0)>>0]=32;a[20040+e>>0]=32;a[18632+(e*177|0)>>0]=32;a[20040+b>>0]=32;a[18632+(b*177|0)>>0]=32;a[20040+l>>0]=32;a[18632+(l*177|0)>>0]=32;a[20040+m>>0]=32;a[18632+(m*177|0)>>0]=32;a[20040+n>>0]=32;a[18632+(n*177|0)>>0]=32;a[20040+o>>0]=32;a[18632+(o*177|0)>>0]=32;a[20040+p>>0]=32;a[18632+(p*177|0)>>0]=32;Ja();m=c[12490]|0;b=a[55220+(m*44|0)>>0]|0;if(b<<24>>24){p=b&255;l=0;do{o=d[55208+(m*44|0)+l+13>>0]|0;if(!(a[18630+(o*177|0)>>0]&32)){e=o+-2|0;b=o+-1|0;f=o+1|0;g=o+2|0;h=0;do{k=d[49976+h>>0]|0;n=h+4|0;a[18624+(e*177|0)+n>>0]=k&16|32;a[18624+(b*177|0)+n>>0]=(k&8)<<1&255|32;a[18624+(o*177|0)+n>>0]=(k&4)<<2&255|32;a[18624+(f*177|0)+n>>0]=(k&2)<<3&255|32;a[18624+(g*177|0)+n>>0]=(k&1)<<4&255|32;h=h+1|0}while((h|0)!=5)}if(!(a[19686+o>>0]&32)){e=o+-2|0;b=0;do{k=d[49976+b>>0]|0;n=e+b|0;a[19332+n>>0]=k&16|32;a[19509+n>>0]=(k&8)<<1&255|32;a[19686+n>>0]=(k&4)<<2&255|32;a[19863+n>>0]=(k&2)<<3&255|32;a[20040+n>>0]=(k&1)<<4&255|32;b=b+1|0}while((b|0)!=5);k=0}else k=0;do{e=d[55208+(m*44|0)+k+13>>0]|0;if(!(a[18624+(o*177|0)+e>>0]&32)){j=o+-2|0;h=e+-2|0;g=o+-1|0;f=o+1|0;e=o+2|0;b=0;do{r=d[49976+b>>0]|0;n=h+b|0;a[18624+(j*177|0)+n>>0]=r&16|32;a[18624+(g*177|0)+n>>0]=(r&8)<<1&255|32;a[18624+(o*177|0)+n>>0]=(r&4)<<2&255|32;a[18624+(f*177|0)+n>>0]=(r&2)<<3&255|32;a[18624+(e*177|0)+n>>0]=(r&1)<<4&255|32;b=b+1|0}while((b|0)!=5)}k=k+1|0}while((k|0)<(p|0));l=l+1|0}while((l|0)<(p|0))}b=(c[12492]|0)+-9|0;if((b|0)<8){i=q;return}else e=8;while(1){n=(e<<4&16^48)&255;a[18630+(e*177|0)>>0]=n;a[19686+e>>0]=n;if((e|0)<(b|0))e=e+1|0;else break}i=q;return}function La(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;m=i;d=c[12492]|0;if((d|0)>0)k=0;else{i=m;return}do{e=k&1^1;f=(k|0)/2|0;l=0;do{g=18624+(l*177|0)+k|0;h=a[g>>0]|0;if(!(h&32)){switch(b|0){case 5:{j=Z(l,k)|0;j=((j|0)%2|0|0)==(0-((j|0)%3|0)|0)&1;break}case 1:{j=e;break}case 0:{j=l+k&1^1;break}case 3:{j=((l+k|0)%3|0|0)==0&1;break}case 4:{j=((l|0)/3|0)+f&1^1;break}case 6:{j=Z(l,k)|0;j=((j|0)%3|0)+j&1^1;break}case 2:{j=((l|0)%3|0|0)==0&1;break}default:j=l+k+((Z(l,k)|0)%3|0)&1^1}h=h&255;a[g>>0]=h>>>1&1^j|h&254}l=l+1|0}while((l|0)!=(d|0));k=k+1|0}while((k|0)<(d|0));i=m;return}function Ma(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;e=i;d=c[4454]|0;if((d|0)==2)d=24;else if((d|0)==1)d=0;else if(!d)d=8;else d=16;r=d+b<<10;b=(r&16384|0)==0?r:r^21360;b=(b&8192|0)==0?b:b^10680;b=(b&4096|0)==0?b:b^5340;b=(b&2048|0)==0?b:b^2670;r=((b&1024|0)==0?b:b^1335)+r|0;b=r^21522;f=(r&1)<<4&255|32;a[20040]=f;h=(b&2)<<3&255|32;a[20041]=h;k=(r&4)<<2&255|32;a[20042]=k;m=(r&8)<<1&255|32;a[20043]=m;o=b&16|32;a[20044]=o;q=(r&32)>>>1|32;a[20045]=q;a[20047]=r>>>2&16|32;a[20048]=r>>>3&16|32;a[19871]=r>>>4&16|32;p=(r&512|0)!=0?48:32;a[19517]=p;n=(b&1024|0)!=0?48:32;a[19340]=n;l=(r&2048|0)!=0?48:32;a[19163]=l;j=(b&4096|0)!=0?48:32;a[18986]=j;g=(r&8192|0)!=0?48:32;a[18809]=g;b=(b&16384|0)!=0?48:32;a[18632]=b;s=c[12492]|0;d=s+-1|0;a[18632+(d*177|0)>>0]=f;f=s+-2|0;a[18632+(f*177|0)>>0]=h;h=s+-3|0;a[18632+(h*177|0)>>0]=k;k=s+-4|0;a[18632+(k*177|0)>>0]=m;m=s+-5|0;a[18632+(m*177|0)>>0]=o;o=s+-6|0;a[18632+(o*177|0)>>0]=q;q=s+-7|0;a[18632+(q*177|0)>>0]=(r&64)>>>2|32;s=s+-8|0;a[18632+(s*177|0)>>0]=(r&128)>>>3|32;a[20040+s>>0]=48;a[20040+q>>0]=(r&256|0)!=0?48:32;a[20040+o>>0]=p;a[20040+m>>0]=n;a[20040+k>>0]=l;a[20040+h>>0]=j;a[20040+f>>0]=g;a[20040+d>>0]=b;i=e;return}function Na(){var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=i;o=c[12492]|0;m=(o|0)>0;if(m){l=o+-4|0;k=0;b=0;do{f=0;a:while(1){while(1){if((f|0)>=(l|0))break a;e=f+1|0;if((e|0)>=(o|0)){f=e;continue}g=(a[18624+(k*177|0)+f>>0]&17)==0;f=e;d=1;while(1){e=d+1|0;if(g^(a[18624+(k*177|0)+f>>0]&17)==0){e=d;break}f=f+1|0;if((f|0)<(o|0))d=e;else break}if((e|0)>4)break}b=b+-2+e|0}k=k+1|0}while((k|0)<(o|0));if(m){l=o+-4|0;k=0;do{f=0;b:while(1){while(1){if((f|0)>=(l|0))break b;e=f+1|0;if((e|0)>=(o|0)){f=e;continue}g=(a[18624+(f*177|0)+k>>0]&17)==0;f=e;d=1;while(1){e=d+1|0;if(g^(a[18624+(f*177|0)+k>>0]&17)==0){e=d;break}f=f+1|0;if((f|0)<(o|0))d=e;else break}if((e|0)>4)break}b=b+-2+e|0}k=k+1|0}while((k|0)<(o|0))}}else b=0;g=o+-1|0;if((g|0)>0){h=0;do{e=h;h=h+1|0;d=0;do{f=(a[18624+(e*177|0)+d>>0]&17)==0;l=d;d=d+1|0;if(!(f^(a[18624+(h*177|0)+l>>0]&17)==0)?!(f^(a[18624+(e*177|0)+d>>0]&17)==0):0)b=f^(a[18624+(h*177|0)+d>>0]&17)==0?b:b+3|0}while((d|0)!=(g|0))}while((h|0)<(g|0))}if(!m){j=0;m=b;j=j*100|0;k=Z(o,o)|0;k=(j|0)/(k|0)|0;k=50-k|0;j=(k|0)>-1;l=0-k|0;l=j?k:l;l=(l|0)/5|0;l=l*10|0;m=l+m|0;i=p;return m|0}g=o+-6|0;f=(g|0)>0;e=o+-7|0;d=o+-8|0;j=o+-9|0;k=o+-10|0;l=0;do{if(f){h=0;do{if(!((h|0)!=0?(a[h+-1+(18624+(l*177|0))>>0]&17)!=0:0))n=39;c:do if((n|0)==39){n=0;if(((((((a[18624+(l*177|0)+h>>0]&17)!=0?(a[h+1+(18624+(l*177|0))>>0]&17)==0:0)?(a[h+2+(18624+(l*177|0))>>0]&17)!=0:0)?(a[h+3+(18624+(l*177|0))>>0]&17)!=0:0)?(a[h+4+(18624+(l*177|0))>>0]&17)!=0:0)?(a[h+5+(18624+(l*177|0))>>0]&17)==0:0)?(a[h+6+(18624+(l*177|0))>>0]&17)!=0:0){if((h|0)!=(e|0)?(a[h+7+(18624+(l*177|0))>>0]&17)!=0:0)break;d:do if((h|0)>=2){do if(!(a[h+-2+(18624+(l*177|0))>>0]&17)){if((h|0)<3)break d;if(a[h+-3+(18624+(l*177|0))>>0]&17)break;if((h|0)<4)break d;if(!(a[h+-4+(18624+(l*177|0))>>0]&17))break d}while(0);if((h|0)<(d|0)?(a[h+8+(18624+(l*177|0))>>0]&17)!=0:0)break c;if((h|0)<(j|0)?(a[h+9+(18624+(l*177|0))>>0]&17)!=0:0)break c;if((h|0)>=(k|0))break;if(a[h+10+(18624+(l*177|0))>>0]&17)break c}while(0);b=b+40|0}}while(0);h=h+1|0}while((h|0)<(g|0))}l=l+1|0}while((l|0)<(o|0));if(!m){j=0;m=b;j=j*100|0;k=Z(o,o)|0;k=(j|0)/(k|0)|0;k=50-k|0;j=(k|0)>-1;l=0-k|0;l=j?k:l;l=(l|0)/5|0;l=l*10|0;m=l+m|0;i=p;return m|0}k=o+-6|0;j=(k|0)>0;g=o+-7|0;f=o+-8|0;e=o+-9|0;d=o+-10|0;l=0;do{if(j){h=0;do{if(!((h|0)!=0?(a[18624+((h+-1|0)*177|0)+l>>0]&17)!=0:0))n=70;e:do if((n|0)==70){n=0;if(((((((a[18624+(h*177|0)+l>>0]&17)!=0?(a[18624+((h+1|0)*177|0)+l>>0]&17)==0:0)?(a[18624+((h+2|0)*177|0)+l>>0]&17)!=0:0)?(a[18624+((h+3|0)*177|0)+l>>0]&17)!=0:0)?(a[18624+((h+4|0)*177|0)+l>>0]&17)!=0:0)?(a[18624+((h+5|0)*177|0)+l>>0]&17)==0:0)?(a[18624+((h+6|0)*177|0)+l>>0]&17)!=0:0){if((h|0)!=(g|0)?(a[18624+((h+7|0)*177|0)+l>>0]&17)!=0:0)break;f:do if((h|0)>=2){do if(!(a[18624+((h+-2|0)*177|0)+l>>0]&17)){if((h|0)<3)break f;if(a[18624+((h+-3|0)*177|0)+l>>0]&17)break;if((h|0)<4)break f;if(!(a[18624+((h+-4|0)*177|0)+l>>0]&17))break f}while(0);if((h|0)<(f|0)?(a[18624+((h+8|0)*177|0)+l>>0]&17)!=0:0)break e;if((h|0)<(e|0)?(a[18624+((h+9|0)*177|0)+l>>0]&17)!=0:0)break e;if((h|0)>=(d|0))break;if(a[18624+((h+10|0)*177|0)+l>>0]&17)break e}while(0);b=b+40|0}}while(0);h=h+1|0}while((h|0)<(k|0))}l=l+1|0}while((l|0)<(o|0));if(m){e=0;d=0}else{j=0;m=b;j=j*100|0;k=Z(o,o)|0;k=(j|0)/(k|0)|0;k=50-k|0;j=(k|0)>-1;l=0-k|0;l=j?k:l;l=(l|0)/5|0;l=l*10|0;m=l+m|0;i=p;return m|0}do{f=0;do{d=((a[18624+(e*177|0)+f>>0]&17)==0&1)+d|0;f=f+1|0}while((f|0)!=(o|0));e=e+1|0}while((e|0)!=(o|0));k=d*100|0;l=Z(o,o)|0;l=(k|0)/(l|0)|0;l=50-l|0;k=(l|0)>-1;m=0-l|0;m=k?l:m;m=(m|0)/5|0;m=m*10|0;m=m+b|0;i=p;return m|0}function Oa(){var b=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;Va(18624,0,31329)|0;Ka();p=c[12492]|0;k=c[12496]|0;if((k|0)>0){l=p+-1|0;n=0;f=1;b=1;g=p;e=l;while(1){m=d[49992+n>>0]|0;o=0;while(1){j=f;f=e;while(1){e=j+g|0;j=0-j|0;if((j|0)<0){g=b+f|0;f=(g|0)<0;if(f|(g|0)==(p|0)){h=e+-2|0;b=0-b|0;e=(h|0)==6?e+-3|0:h;h=f?0:l}else h=g}else h=f;g=18624+(e*177|0)+h|0;if(!(a[g>>0]&32))break;else{g=e;f=h}}a[g>>0]=(1<<7-o&m|0)!=0?2:0;o=o+1|0;if((o|0)==8)break;else{f=j;g=e;e=h}}n=n+1|0;if((n|0)==(k|0))break;else{f=j;g=e;e=h}}}b=c[13426]|0;do if((b|0)==-1){c[13426]=0;if((p|0)>0){b=0;do{g=0;do{f=18624+(g*177|0)+b|0;e=a[f>>0]|0;if(!(e&32)){n=e&255;a[f>>0]=g+b&1^1^n>>>1&1|n&254}g=g+1|0}while((g|0)!=(p|0));b=b+1|0}while((b|0)!=(p|0))}Ma(0);b=Na()|0;La(1);Ma(1);e=Na()|0;if((e|0)<(b|0))c[13426]=1;else e=b;La(2);Ma(2);b=Na()|0;if((b|0)<(e|0))c[13426]=2;else b=e;La(3);Ma(3);e=Na()|0;if((e|0)<(b|0)){c[13426]=3;b=e}La(4);Ma(4);e=Na()|0;if((e|0)<(b|0)){c[13426]=4;b=e}La(5);Ma(5);e=Na()|0;if((e|0)<(b|0)){c[13426]=5;b=e}La(6);Ma(6);e=Na()|0;if((e|0)<(b|0)){c[13426]=6;b=e}La(7);Ma(7);if((Na()|0)<(b|0)){c[13426]=7;b=7;break}else{b=c[13426]|0;break}}while(0);La(b);Ma(c[13426]|0);e=c[12492]|0;if((e|0)>0)b=0;else{i=q;return}do{f=0;do{n=18624+(b*177|0)+f|0;a[n>>0]=(a[n>>0]&17)!=0&1;f=f+1|0}while((f|0)!=(e|0));b=b+1|0}while((b|0)!=(e|0));i=q;return}function Pa(b,f,g,h,j){b=b|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;A=i;c[4454]=b;c[13426]=-1;Va(j|0,0,3917)|0;if(!h){h=Ua(g|0)|0;if(!h){q=-1;i=A;return q|0}}k=Ha(f,g,h)|0;c[13436]=k;if(!k){q=-1;i=A;return q|0}if(f)if((k|0)>(f|0)){q=-1;i=A;return q|0}else k=f;c[12490]=k;z=e[55208+(k*44|0)+(b<<1)+4>>1]|0;h=c[4452]|0;g=(z<<3)-h|0;g=(g|0)<4?4:g;if((g|0)>0){if((h|0)==-1)h=-1;else{h=g+h|0;h=(h|0)>23648?-1:h}c[4452]=h}g=(h+7|0)/8|0;if((g|0)<(z|0)){h=-20;while(1){a[8+g>>0]=h;g=g+1|0;if((g|0)==(z|0))break;else h=h<<24>>24==-20?17:-20}}c[12496]=e[55210+(k*44|0)>>1];Va(49992,0,3706)|0;s=a[55208+(k*44|0)+(b*3|0)+19>>0]|0;u=s&255;o=a[55208+(k*44|0)+(b*3|0)+31>>0]|0;w=o&255;x=w+u|0;m=a[55208+(k*44|0)+(b*3|0)+21>>0]|0;v=m&255;p=a[55208+(k*44|0)+(b*3|0)+33>>0]|0;y=p&255;s=s<<24>>24==0;do if(s){n=0;m=0}else{if(!(m<<24>>24)){n=u>>>0>1?u:1;m=0;break}n=v>>>0>1?v:1;l=u>>>0>1;f=0;m=0;do{g=0;h=m;while(1){a[49992+((Z(g,x)|0)+f)>>0]=a[8+h>>0]|0;g=g+1|0;if((g|0)>=(v|0))break;else h=h+1|0}m=n+m|0;f=f+1|0}while((f|0)<(u|0));n=l?u:1}while(0);t=o<<24>>24==0;if(!t){p=p<<24>>24==0;h=Z(x,v)|0;r=y>>>0>1?y:1;q=0;while(1){if(!p){o=49992+(q+h)|0;f=0;g=m;while(1){l=a[8+g>>0]|0;if((f|0)<(v|0))a[49992+((Z(f,x)|0)+n)>>0]=l;else a[o>>0]=l;f=f+1|0;if((f|0)>=(y|0))break;else g=g+1|0}m=r+m|0}q=q+1|0;if((q|0)>=(w|0))break;else n=n+1|0}}n=(d[55208+(k*44|0)+(b*3|0)+20>>0]|0)-v|0;r=(d[55208+(k*44|0)+(b*3|0)+32>>0]|0)-y|0;if(s){m=0;l=0}else{m=(n|0)>0;l=u>>>0>1;g=0;k=0;while(1){Va(53752,0,153)|0;Wa(53752,8+k|0,v|0)|0;Ia(53752,v,n);if(m){f=g+z|0;h=0;do{a[49992+(f+(Z(h,x)|0))>>0]=a[53752+h>>0]|0;h=h+1|0}while((h|0)!=(n|0))}g=g+1|0;if((g|0)>=(u|0))break;else k=k+v|0}l=l?u:1;m=l;l=Z(l,v)|0}if(!t){h=(r|0)>0;k=0;g=m;f=l;while(1){Va(53752,0,153)|0;Wa(53752,8+f|0,y|0)|0;Ia(53752,y,r);if(h){m=g+z|0;l=0;do{a[49992+(m+(Z(l,x)|0))>>0]=a[53752+l>>0]|0;l=l+1|0}while((l|0)!=(r|0))}k=k+1|0;if((k|0)>=(w|0))break;else{g=g+1|0;f=f+y|0}}}c[12492]=(c[12490]<<2)+17;Oa();k=c[12492]|0;if((k|0)>0)m=0;else{q=k;i=A;return q|0}do{l=m;m=m+1|0;if((k|0)>0){f=0;do{g=m+(Z(k,f)|0)|0;do if(a[18624+(l*177|0)+f>>0]|0){h=g&7;g=g>>>3;if(!h){q=j+(g+-1)|0;a[q>>0]=d[q>>0]^1;break}else{q=j+g|0;a[q>>0]=d[q>>0]^c[53712+(h+-1<<2)>>2];break}}while(0);f=f+1|0;k=c[12492]|0}while((f|0)<(k|0))}}while((m|0)<(k|0));i=A;return k|0}function Qa(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0;j=i;i=i+3936|0;h=j;g=j+4|0;if((a|0)<2){la(49)|0;a=1;i=j;return a|0}b=Pa(1,0,c[b+4>>2]|0,0,g)|0;if((b|0)>0)e=0;else{a=0;i=j;return a|0}do{a=Z(e,b)|0;f=0;do{k=f+a|0;wa(((1<<7-((k|0)%8|0)&(d[g+((k|0)/8|0)>>0]|0)|0)!=0?57024:57016)|0,h|0)|0;f=f+1|0}while((f|0)!=(b|0));e=e+1|0}while((e|0)!=(b|0));a=0;i=j;return a|0}function Ra(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;L=i;do if(a>>>0<245){if(a>>>0<11)p=16;else p=a+11&-8;a=p>>>3;l=c[14258]|0;k=l>>>a;if(k&3){e=(k&1^1)+a|0;f=e<<1;b=57072+(f<<2)|0;f=57072+(f+2<<2)|0;g=c[f>>2]|0;h=g+8|0;j=c[h>>2]|0;do if((b|0)!=(j|0)){if(j>>>0<(c[14262]|0)>>>0)ra();d=j+12|0;if((c[d>>2]|0)==(g|0)){c[d>>2]=b;c[f>>2]=j;break}else ra()}else c[14258]=l&~(1<>2]=x|3;x=g+(x|4)|0;c[x>>2]=c[x>>2]|1;x=h;i=L;return x|0}j=c[14260]|0;if(p>>>0>j>>>0){if(k){f=2<>>12&16;f=f>>>a;e=f>>>5&8;f=f>>>e;d=f>>>2&4;f=f>>>d;g=f>>>1&2;f=f>>>g;h=f>>>1&1;h=(e|a|d|g|h)+(f>>>h)|0;f=h<<1;g=57072+(f<<2)|0;f=57072+(f+2<<2)|0;d=c[f>>2]|0;a=d+8|0;e=c[a>>2]|0;do if((g|0)!=(e|0)){if(e>>>0<(c[14262]|0)>>>0)ra();j=e+12|0;if((c[j>>2]|0)==(d|0)){c[j>>2]=g;c[f>>2]=e;m=c[14260]|0;break}else ra()}else{c[14258]=l&~(1<>2]=p|3;k=d+p|0;c[d+(p|4)>>2]=b|1;c[d+x>>2]=b;if(m){e=c[14263]|0;g=m>>>3;j=g<<1;f=57072+(j<<2)|0;h=c[14258]|0;g=1<>2]|0;if(j>>>0<(c[14262]|0)>>>0)ra();else{n=h;o=j}}else{c[14258]=h|g;n=57072+(j+2<<2)|0;o=f}c[n>>2]=e;c[o+12>>2]=e;c[e+8>>2]=o;c[e+12>>2]=f}c[14260]=b;c[14263]=k;x=a;i=L;return x|0}k=c[14259]|0;if(k){l=(k&0-k)+-1|0;w=l>>>12&16;l=l>>>w;v=l>>>5&8;l=l>>>v;x=l>>>2&4;l=l>>>x;j=l>>>1&2;l=l>>>j;m=l>>>1&1;m=c[57336+((v|w|x|j|m)+(l>>>m)<<2)>>2]|0;l=(c[m+4>>2]&-8)-p|0;j=m;while(1){d=c[j+16>>2]|0;if(!d){d=c[j+20>>2]|0;if(!d)break}j=(c[d+4>>2]&-8)-p|0;x=j>>>0>>0;l=x?j:l;j=d;m=x?d:m}k=c[14262]|0;if(m>>>0>>0)ra();b=m+p|0;if(m>>>0>=b>>>0)ra();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){e=0;break}}while(1){g=j+20|0;f=c[g>>2]|0;if(f){j=f;h=g;continue}g=j+16|0;f=c[g>>2]|0;if(!f)break;else{j=f;h=g}}if(h>>>0>>0)ra();else{c[h>>2]=0;e=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ra();j=f+12|0;if((c[j>>2]|0)!=(m|0))ra();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;e=g;break}else ra()}while(0);do if(a){j=c[m+28>>2]|0;h=57336+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=e;if(!e){c[14259]=c[14259]&~(1<>>0<(c[14262]|0)>>>0)ra();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=e;else c[a+20>>2]=e;if(!e)break}h=c[14262]|0;if(e>>>0>>0)ra();c[e+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ra();else{c[e+16>>2]=j;c[j+24>>2]=e;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[14262]|0)>>>0)ra();else{c[e+20>>2]=j;c[j+24>>2]=e;break}}while(0);if(l>>>0<16){x=l+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}else{c[m+4>>2]=p|3;c[m+(p|4)>>2]=l|1;c[m+(l+p)>>2]=l;d=c[14260]|0;if(d){e=c[14263]|0;g=d>>>3;j=g<<1;f=57072+(j<<2)|0;h=c[14258]|0;g=1<>2]|0;if(h>>>0<(c[14262]|0)>>>0)ra();else{r=j;q=h}}else{c[14258]=h|g;r=57072+(j+2<<2)|0;q=f}c[r>>2]=e;c[q+12>>2]=e;c[e+8>>2]=q;c[e+12>>2]=f}c[14260]=l;c[14263]=b}x=m+8|0;i=L;return x|0}}}else if(a>>>0<=4294967231){a=a+11|0;p=a&-8;m=c[14259]|0;if(m){j=0-p|0;a=a>>>8;if(a)if(p>>>0>16777215)l=31;else{q=(a+1048320|0)>>>16&8;r=a<>>16&4;r=r<>>16&2;l=14-(o|q|l)+(r<>>15)|0;l=p>>>(l+7|0)&1|l<<1}else l=0;h=c[57336+(l<<2)>>2]|0;a:do if(!h){a=0;k=0}else{if((l|0)==31)k=0;else k=25-(l>>>1)|0;f=j;a=0;e=p<>2]&-8;j=g-p|0;if(j>>>0>>0)if((g|0)==(p|0)){a=h;k=h;break a}else k=h;else j=f;r=c[h+20>>2]|0;h=c[h+(e>>>31<<2)+16>>2]|0;a=(r|0)==0|(r|0)==(h|0)?a:r;if(!h)break;else{f=j;e=e<<1}}}while(0);if((a|0)==0&(k|0)==0){a=2<>>12&16;r=r>>>n;m=r>>>5&8;r=r>>>m;o=r>>>2&4;r=r>>>o;q=r>>>1&2;r=r>>>q;a=r>>>1&1;a=c[57336+((m|n|o|q|a)+(r>>>a)<<2)>>2]|0}if(!a){n=j;m=k}else while(1){r=(c[a+4>>2]&-8)-p|0;h=r>>>0>>0;j=h?r:j;k=h?a:k;h=c[a+16>>2]|0;if(h){a=h;continue}a=c[a+20>>2]|0;if(!a){n=j;m=k;break}}if((m|0)!=0?n>>>0<((c[14260]|0)-p|0)>>>0:0){k=c[14262]|0;if(m>>>0>>0)ra();o=m+p|0;if(m>>>0>=o>>>0)ra();a=c[m+24>>2]|0;g=c[m+12>>2]|0;do if((g|0)==(m|0)){h=m+20|0;j=c[h>>2]|0;if(!j){h=m+16|0;j=c[h>>2]|0;if(!j){b=0;break}}while(1){g=j+20|0;f=c[g>>2]|0;if(f){j=f;h=g;continue}g=j+16|0;f=c[g>>2]|0;if(!f)break;else{j=f;h=g}}if(h>>>0>>0)ra();else{c[h>>2]=0;b=j;break}}else{f=c[m+8>>2]|0;if(f>>>0>>0)ra();j=f+12|0;if((c[j>>2]|0)!=(m|0))ra();h=g+8|0;if((c[h>>2]|0)==(m|0)){c[j>>2]=g;c[h>>2]=f;b=g;break}else ra()}while(0);do if(a){j=c[m+28>>2]|0;h=57336+(j<<2)|0;if((m|0)==(c[h>>2]|0)){c[h>>2]=b;if(!b){c[14259]=c[14259]&~(1<>>0<(c[14262]|0)>>>0)ra();j=a+16|0;if((c[j>>2]|0)==(m|0))c[j>>2]=b;else c[a+20>>2]=b;if(!b)break}h=c[14262]|0;if(b>>>0>>0)ra();c[b+24>>2]=a;j=c[m+16>>2]|0;do if(j)if(j>>>0>>0)ra();else{c[b+16>>2]=j;c[j+24>>2]=b;break}while(0);j=c[m+20>>2]|0;if(j)if(j>>>0<(c[14262]|0)>>>0)ra();else{c[b+20>>2]=j;c[j+24>>2]=b;break}}while(0);b:do if(n>>>0>=16){c[m+4>>2]=p|3;c[m+(p|4)>>2]=n|1;c[m+(n+p)>>2]=n;j=n>>>3;if(n>>>0<256){h=j<<1;f=57072+(h<<2)|0;g=c[14258]|0;j=1<>2]|0;if(h>>>0>=(c[14262]|0)>>>0){d=j;t=h;break}ra()}while(0);c[d>>2]=o;c[t+12>>2]=o;c[m+(p+8)>>2]=t;c[m+(p+12)>>2]=f;break}d=n>>>8;if(d)if(n>>>0>16777215)f=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|w|f)+(x<>>15)|0;f=n>>>(f+7|0)&1|f<<1}else f=0;j=57336+(f<<2)|0;c[m+(p+28)>>2]=f;c[m+(p+20)>>2]=0;c[m+(p+16)>>2]=0;h=c[14259]|0;g=1<>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break}j=c[j>>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;c:do if((c[j+4>>2]&-8|0)!=(n|0)){f=n<>>31<<2)+16|0;h=c[g>>2]|0;if(!h)break;if((c[h+4>>2]&-8|0)==(n|0)){v=h;break c}else{f=f<<1;j=h}}if(g>>>0<(c[14262]|0)>>>0)ra();else{c[g>>2]=o;c[m+(p+24)>>2]=j;c[m+(p+12)>>2]=o;c[m+(p+8)>>2]=o;break b}}else v=j;while(0);d=v+8|0;b=c[d>>2]|0;x=c[14262]|0;if(v>>>0>=x>>>0&b>>>0>=x>>>0){c[b+12>>2]=o;c[d>>2]=o;c[m+(p+8)>>2]=b;c[m+(p+12)>>2]=v;c[m+(p+24)>>2]=0;break}else ra()}else{x=n+p|0;c[m+4>>2]=x|3;x=m+(x+4)|0;c[x>>2]=c[x>>2]|1}while(0);x=m+8|0;i=L;return x|0}}}else p=-1;while(0);k=c[14260]|0;if(k>>>0>=p>>>0){b=k-p|0;d=c[14263]|0;if(b>>>0>15){c[14263]=d+p;c[14260]=b;c[d+(p+4)>>2]=b|1;c[d+k>>2]=b;c[d+4>>2]=p|3}else{c[14260]=0;c[14263]=0;c[d+4>>2]=k|3;x=d+(k+4)|0;c[x>>2]=c[x>>2]|1}x=d+8|0;i=L;return x|0}k=c[14261]|0;if(k>>>0>p>>>0){w=k-p|0;c[14261]=w;x=c[14264]|0;c[14264]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}do if(!(c[14376]|0)){k=ja(30)|0;if(!(k+-1&k)){c[14378]=k;c[14377]=k;c[14379]=-1;c[14380]=-1;c[14381]=0;c[14369]=0;c[14376]=(ta(0)|0)&-16^1431655768;break}else ra()}while(0);l=p+48|0;g=c[14378]|0;f=p+47|0;h=g+f|0;g=0-g|0;m=h&g;if(m>>>0<=p>>>0){x=0;i=L;return x|0}a=c[14368]|0;if((a|0)!=0?(t=c[14366]|0,v=t+m|0,v>>>0<=t>>>0|v>>>0>a>>>0):0){x=0;i=L;return x|0}d:do if(!(c[14369]&4)){j=c[14264]|0;e:do if(j){a=57480|0;while(1){k=c[a>>2]|0;if(k>>>0<=j>>>0?(s=a+4|0,(k+(c[s>>2]|0)|0)>>>0>j>>>0):0)break;a=c[a+8>>2]|0;if(!a){A=181;break e}}if(a){k=h-(c[14261]|0)&g;if(k>>>0<2147483647){j=ga(k|0)|0;if((j|0)==((c[a>>2]|0)+(c[s>>2]|0)|0))A=190;else A=191}else k=0}else A=181}else A=181;while(0);do if((A|0)==181){j=ga(0)|0;if((j|0)!=(-1|0)){a=j;k=c[14377]|0;h=k+-1|0;if(!(h&a))k=m;else k=m-a+(h+a&0-k)|0;a=c[14366]|0;h=a+k|0;if(k>>>0>p>>>0&k>>>0<2147483647){v=c[14368]|0;if((v|0)!=0?h>>>0<=a>>>0|h>>>0>v>>>0:0){k=0;break}h=ga(k|0)|0;if((h|0)==(j|0))A=190;else{j=h;A=191}}else k=0}else k=0}while(0);f:do if((A|0)==190){if((j|0)!=(-1|0)){w=j;s=k;A=201;break d}}else if((A|0)==191){h=0-k|0;do if((j|0)!=(-1|0)&k>>>0<2147483647&l>>>0>k>>>0?(u=c[14378]|0,u=f-k+u&0-u,u>>>0<2147483647):0)if((ga(u|0)|0)==(-1|0)){ga(h|0)|0;k=0;break f}else{k=u+k|0;break}while(0);if((j|0)==(-1|0))k=0;else{w=j;s=k;A=201;break d}}while(0);c[14369]=c[14369]|4;A=198}else{k=0;A=198}while(0);if((((A|0)==198?m>>>0<2147483647:0)?(w=ga(m|0)|0,x=ga(0)|0,(w|0)!=(-1|0)&(x|0)!=(-1|0)&w>>>0>>0):0)?(y=x-w|0,z=y>>>0>(p+40|0)>>>0,z):0){s=z?y:k;A=201}if((A|0)==201){j=(c[14366]|0)+s|0;c[14366]=j;if(j>>>0>(c[14367]|0)>>>0)c[14367]=j;o=c[14264]|0;g:do if(o){f=57480|0;while(1){k=c[f>>2]|0;j=f+4|0;h=c[j>>2]|0;if((w|0)==(k+h|0)){A=213;break}g=c[f+8>>2]|0;if(!g)break;else f=g}if(((A|0)==213?(c[f+12>>2]&8|0)==0:0)?o>>>0>=k>>>0&o>>>0>>0:0){c[j>>2]=h+s;b=(c[14261]|0)+s|0;d=o+8|0;if(!(d&7))d=0;else d=0-d&7;x=b-d|0;c[14264]=o+d;c[14261]=x;c[o+(d+4)>>2]=x|1;c[o+(b+4)>>2]=40;c[14265]=c[14380];break}k=c[14262]|0;if(w>>>0>>0){c[14262]=w;k=w}j=w+s|0;g=57480|0;while(1){if((c[g>>2]|0)==(j|0)){A=223;break}h=c[g+8>>2]|0;if(!h)break;else g=h}if((A|0)==223?(c[g+12>>2]&8|0)==0:0){c[g>>2]=w;j=g+4|0;c[j>>2]=(c[j>>2]|0)+s;j=w+8|0;if(!(j&7))r=0;else r=0-j&7;j=w+(s+8)|0;if(!(j&7))b=0;else b=0-j&7;j=w+(b+s)|0;n=r+p|0;q=w+n|0;l=j-(w+r)-p|0;c[w+(r+4)>>2]=p|3;h:do if((j|0)!=(o|0)){if((j|0)==(c[14263]|0)){x=(c[14260]|0)+l|0;c[14260]=x;c[14263]=q;c[w+(n+4)>>2]=x|1;c[w+(x+n)>>2]=x;break}d=s+4|0;h=c[w+(d+b)>>2]|0;if((h&3|0)==1){m=h&-8;e=h>>>3;i:do if(h>>>0>=256){a=c[w+((b|24)+s)>>2]|0;g=c[w+(s+12+b)>>2]|0;do if((g|0)==(j|0)){g=b|16;f=w+(d+g)|0;h=c[f>>2]|0;if(!h){g=w+(g+s)|0;h=c[g>>2]|0;if(!h){H=0;break}}else g=f;while(1){f=h+20|0;e=c[f>>2]|0;if(e){h=e;g=f;continue}f=h+16|0;e=c[f>>2]|0;if(!e)break;else{h=e;g=f}}if(g>>>0>>0)ra();else{c[g>>2]=0;H=h;break}}else{f=c[w+((b|8)+s)>>2]|0;if(f>>>0>>0)ra();k=f+12|0;if((c[k>>2]|0)!=(j|0))ra();h=g+8|0;if((c[h>>2]|0)==(j|0)){c[k>>2]=g;c[h>>2]=f;H=g;break}else ra()}while(0);if(!a)break;k=c[w+(s+28+b)>>2]|0;h=57336+(k<<2)|0;do if((j|0)!=(c[h>>2]|0)){if(a>>>0<(c[14262]|0)>>>0)ra();k=a+16|0;if((c[k>>2]|0)==(j|0))c[k>>2]=H;else c[a+20>>2]=H;if(!H)break i}else{c[h>>2]=H;if(H)break;c[14259]=c[14259]&~(1<>>0>>0)ra();c[H+24>>2]=a;k=b|16;j=c[w+(k+s)>>2]|0;do if(j)if(j>>>0>>0)ra();else{c[H+16>>2]=j;c[j+24>>2]=H;break}while(0);j=c[w+(d+k)>>2]|0;if(!j)break;if(j>>>0<(c[14262]|0)>>>0)ra();else{c[H+20>>2]=j;c[j+24>>2]=H;break}}else{g=c[w+((b|8)+s)>>2]|0;f=c[w+(s+12+b)>>2]|0;h=57072+(e<<1<<2)|0;do if((g|0)!=(h|0)){if(g>>>0>>0)ra();if((c[g+12>>2]|0)==(j|0))break;ra()}while(0);if((f|0)==(g|0)){c[14258]=c[14258]&~(1<>>0>>0)ra();k=f+8|0;if((c[k>>2]|0)==(j|0)){D=k;break}ra()}while(0);c[g+12>>2]=f;c[D>>2]=g}while(0);j=w+((m|b)+s)|0;k=m+l|0}else k=l;j=j+4|0;c[j>>2]=c[j>>2]&-2;c[w+(n+4)>>2]=k|1;c[w+(k+n)>>2]=k;j=k>>>3;if(k>>>0<256){h=j<<1;f=57072+(h<<2)|0;g=c[14258]|0;j=1<>2]|0;if(h>>>0>=(c[14262]|0)>>>0){I=j;J=h;break}ra()}while(0);c[I>>2]=q;c[J+12>>2]=q;c[w+(n+8)>>2]=J;c[w+(n+12)>>2]=f;break}d=k>>>8;do if(!d)f=0;else{if(k>>>0>16777215){f=31;break}v=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;f=14-(u|v|f)+(x<>>15)|0;f=k>>>(f+7|0)&1|f<<1}while(0);j=57336+(f<<2)|0;c[w+(n+28)>>2]=f;c[w+(n+20)>>2]=0;c[w+(n+16)>>2]=0;h=c[14259]|0;g=1<>2]=q;c[w+(n+24)>>2]=j;c[w+(n+12)>>2]=q;c[w+(n+8)>>2]=q;break}h=c[j>>2]|0;if((f|0)==31)j=0;else j=25-(f>>>1)|0;j:do if((c[h+4>>2]&-8|0)!=(k|0)){f=k<>>31<<2)+16|0;j=c[g>>2]|0;if(!j)break;if((c[j+4>>2]&-8|0)==(k|0)){K=j;break j}else{f=f<<1;h=j}}if(g>>>0<(c[14262]|0)>>>0)ra();else{c[g>>2]=q;c[w+(n+24)>>2]=h;c[w+(n+12)>>2]=q;c[w+(n+8)>>2]=q;break h}}else K=h;while(0);d=K+8|0;b=c[d>>2]|0;x=c[14262]|0;if(K>>>0>=x>>>0&b>>>0>=x>>>0){c[b+12>>2]=q;c[d>>2]=q;c[w+(n+8)>>2]=b;c[w+(n+12)>>2]=K;c[w+(n+24)>>2]=0;break}else ra()}else{x=(c[14261]|0)+l|0;c[14261]=x;c[14264]=q;c[w+(n+4)>>2]=x|1}while(0);x=w+(r|8)|0;i=L;return x|0}j=57480|0;while(1){h=c[j>>2]|0;if(h>>>0<=o>>>0?(B=c[j+4>>2]|0,C=h+B|0,C>>>0>o>>>0):0)break;j=c[j+8>>2]|0}j=h+(B+-39)|0;if(!(j&7))j=0;else j=0-j&7;g=h+(B+-47+j)|0;g=g>>>0<(o+16|0)>>>0?o:g;h=g+8|0;j=w+8|0;if(!(j&7))j=0;else j=0-j&7;x=s+-40-j|0;c[14264]=w+j;c[14261]=x;c[w+(j+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[14265]=c[14380];c[g+4>>2]=27;c[h+0>>2]=c[14370];c[h+4>>2]=c[14371];c[h+8>>2]=c[14372];c[h+12>>2]=c[14373];c[14370]=w;c[14371]=s;c[14373]=0;c[14372]=h;j=g+28|0;c[j>>2]=7;if((g+32|0)>>>0>>0)do{x=j;j=j+4|0;c[j>>2]=7}while((x+8|0)>>>0>>0);if((g|0)!=(o|0)){k=g-o|0;j=o+(k+4)|0;c[j>>2]=c[j>>2]&-2;c[o+4>>2]=k|1;c[o+k>>2]=k;j=k>>>3;if(k>>>0<256){h=j<<1;f=57072+(h<<2)|0;g=c[14258]|0;j=1<>2]|0;if(b>>>0>=(c[14262]|0)>>>0){E=d;F=b;break}ra()}while(0);c[E>>2]=o;c[F+12>>2]=o;c[o+8>>2]=F;c[o+12>>2]=f;break}d=k>>>8;if(d)if(k>>>0>16777215)j=31;else{w=(d+1048320|0)>>>16&8;x=d<>>16&4;x=x<>>16&2;j=14-(v|w|j)+(x<>>15)|0;j=k>>>(j+7|0)&1|j<<1}else j=0;d=57336+(j<<2)|0;c[o+28>>2]=j;c[o+20>>2]=0;c[o+16>>2]=0;b=c[14259]|0;e=1<>2]=o;c[o+24>>2]=d;c[o+12>>2]=o;c[o+8>>2]=o;break}e=c[d>>2]|0;if((j|0)==31)d=0;else d=25-(j>>>1)|0;k:do if((c[e+4>>2]&-8|0)!=(k|0)){j=k<>>31<<2)+16|0;d=c[b>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(k|0)){G=d;break k}else{j=j<<1;e=d}}if(b>>>0<(c[14262]|0)>>>0)ra();else{c[b>>2]=o;c[o+24>>2]=e;c[o+12>>2]=o;c[o+8>>2]=o;break g}}else G=e;while(0);d=G+8|0;b=c[d>>2]|0;x=c[14262]|0;if(G>>>0>=x>>>0&b>>>0>=x>>>0){c[b+12>>2]=o;c[d>>2]=o;c[o+8>>2]=b;c[o+12>>2]=G;c[o+24>>2]=0;break}else ra()}}else{x=c[14262]|0;if((x|0)==0|w>>>0>>0)c[14262]=w;c[14370]=w;c[14371]=s;c[14373]=0;c[14267]=c[14376];c[14266]=-1;d=0;do{x=d<<1;v=57072+(x<<2)|0;c[57072+(x+3<<2)>>2]=v;c[57072+(x+2<<2)>>2]=v;d=d+1|0}while((d|0)!=32);d=w+8|0;if(!(d&7))d=0;else d=0-d&7;x=s+-40-d|0;c[14264]=w+d;c[14261]=x;c[w+(d+4)>>2]=x|1;c[w+(s+-36)>>2]=40;c[14265]=c[14380]}while(0);b=c[14261]|0;if(b>>>0>p>>>0){w=b-p|0;c[14261]=w;x=c[14264]|0;c[14264]=x+p;c[x+(p+4)>>2]=w|1;c[x+4>>2]=p|3;x=x+8|0;i=L;return x|0}}c[(pa()|0)>>2]=12;x=0;i=L;return x|0}function Sa(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;w=i;if(!a){i=w;return}g=a+-8|0;h=c[14262]|0;if(g>>>0>>0)ra();f=c[a+-4>>2]|0;e=f&3;if((e|0)==1)ra();p=f&-8;r=a+(p+-8)|0;do if(!(f&1)){g=c[g>>2]|0;if(!e){i=w;return}j=-8-g|0;m=a+j|0;n=g+p|0;if(m>>>0>>0)ra();if((m|0)==(c[14263]|0)){g=a+(p+-4)|0;f=c[g>>2]|0;if((f&3|0)!=3){v=m;l=n;break}c[14260]=n;c[g>>2]=f&-2;c[a+(j+4)>>2]=n|1;c[r>>2]=n;i=w;return}d=g>>>3;if(g>>>0<256){e=c[a+(j+8)>>2]|0;f=c[a+(j+12)>>2]|0;g=57072+(d<<1<<2)|0;if((e|0)!=(g|0)){if(e>>>0>>0)ra();if((c[e+12>>2]|0)!=(m|0))ra()}if((f|0)==(e|0)){c[14258]=c[14258]&~(1<>>0>>0)ra();g=f+8|0;if((c[g>>2]|0)==(m|0))b=g;else ra()}else b=f+8|0;c[e+12>>2]=f;c[b>>2]=e;v=m;l=n;break}b=c[a+(j+24)>>2]|0;e=c[a+(j+12)>>2]|0;do if((e|0)==(m|0)){f=a+(j+20)|0;g=c[f>>2]|0;if(!g){f=a+(j+16)|0;g=c[f>>2]|0;if(!g){k=0;break}}while(1){e=g+20|0;d=c[e>>2]|0;if(d){g=d;f=e;continue}e=g+16|0;d=c[e>>2]|0;if(!d)break;else{g=d;f=e}}if(f>>>0>>0)ra();else{c[f>>2]=0;k=g;break}}else{d=c[a+(j+8)>>2]|0;if(d>>>0>>0)ra();g=d+12|0;if((c[g>>2]|0)!=(m|0))ra();f=e+8|0;if((c[f>>2]|0)==(m|0)){c[g>>2]=e;c[f>>2]=d;k=e;break}else ra()}while(0);if(b){g=c[a+(j+28)>>2]|0;f=57336+(g<<2)|0;if((m|0)==(c[f>>2]|0)){c[f>>2]=k;if(!k){c[14259]=c[14259]&~(1<>>0<(c[14262]|0)>>>0)ra();g=b+16|0;if((c[g>>2]|0)==(m|0))c[g>>2]=k;else c[b+20>>2]=k;if(!k){v=m;l=n;break}}f=c[14262]|0;if(k>>>0>>0)ra();c[k+24>>2]=b;g=c[a+(j+16)>>2]|0;do if(g)if(g>>>0>>0)ra();else{c[k+16>>2]=g;c[g+24>>2]=k;break}while(0);g=c[a+(j+20)>>2]|0;if(g)if(g>>>0<(c[14262]|0)>>>0)ra();else{c[k+20>>2]=g;c[g+24>>2]=k;v=m;l=n;break}else{v=m;l=n}}else{v=m;l=n}}else{v=g;l=p}while(0);if(v>>>0>=r>>>0)ra();g=a+(p+-4)|0;f=c[g>>2]|0;if(!(f&1))ra();if(!(f&2)){if((r|0)==(c[14264]|0)){m=(c[14261]|0)+l|0;c[14261]=m;c[14264]=v;c[v+4>>2]=m|1;if((v|0)!=(c[14263]|0)){i=w;return}c[14263]=0;c[14260]=0;i=w;return}if((r|0)==(c[14263]|0)){m=(c[14260]|0)+l|0;c[14260]=m;c[14263]=v;c[v+4>>2]=m|1;c[v+m>>2]=m;i=w;return}h=(f&-8)+l|0;b=f>>>3;do if(f>>>0>=256){b=c[a+(p+16)>>2]|0;g=c[a+(p|4)>>2]|0;do if((g|0)==(r|0)){f=a+(p+12)|0;g=c[f>>2]|0;if(!g){f=a+(p+8)|0;g=c[f>>2]|0;if(!g){q=0;break}}while(1){e=g+20|0;d=c[e>>2]|0;if(d){g=d;f=e;continue}e=g+16|0;d=c[e>>2]|0;if(!d)break;else{g=d;f=e}}if(f>>>0<(c[14262]|0)>>>0)ra();else{c[f>>2]=0;q=g;break}}else{f=c[a+p>>2]|0;if(f>>>0<(c[14262]|0)>>>0)ra();e=f+12|0;if((c[e>>2]|0)!=(r|0))ra();d=g+8|0;if((c[d>>2]|0)==(r|0)){c[e>>2]=g;c[d>>2]=f;q=g;break}else ra()}while(0);if(b){g=c[a+(p+20)>>2]|0;f=57336+(g<<2)|0;if((r|0)==(c[f>>2]|0)){c[f>>2]=q;if(!q){c[14259]=c[14259]&~(1<>>0<(c[14262]|0)>>>0)ra();g=b+16|0;if((c[g>>2]|0)==(r|0))c[g>>2]=q;else c[b+20>>2]=q;if(!q)break}g=c[14262]|0;if(q>>>0>>0)ra();c[q+24>>2]=b;f=c[a+(p+8)>>2]|0;do if(f)if(f>>>0>>0)ra();else{c[q+16>>2]=f;c[f+24>>2]=q;break}while(0);d=c[a+(p+12)>>2]|0;if(d)if(d>>>0<(c[14262]|0)>>>0)ra();else{c[q+20>>2]=d;c[d+24>>2]=q;break}}}else{d=c[a+p>>2]|0;e=c[a+(p|4)>>2]|0;g=57072+(b<<1<<2)|0;if((d|0)!=(g|0)){if(d>>>0<(c[14262]|0)>>>0)ra();if((c[d+12>>2]|0)!=(r|0))ra()}if((e|0)==(d|0)){c[14258]=c[14258]&~(1<>>0<(c[14262]|0)>>>0)ra();f=e+8|0;if((c[f>>2]|0)==(r|0))o=f;else ra()}else o=e+8|0;c[d+12>>2]=e;c[o>>2]=d}while(0);c[v+4>>2]=h|1;c[v+h>>2]=h;if((v|0)==(c[14263]|0)){c[14260]=h;i=w;return}else g=h}else{c[g>>2]=f&-2;c[v+4>>2]=l|1;c[v+l>>2]=l;g=l}f=g>>>3;if(g>>>0<256){e=f<<1;g=57072+(e<<2)|0;b=c[14258]|0;d=1<>2]|0;if(b>>>0<(c[14262]|0)>>>0)ra();else{s=d;t=b}}else{c[14258]=b|d;s=57072+(e+2<<2)|0;t=g}c[s>>2]=v;c[t+12>>2]=v;c[v+8>>2]=t;c[v+12>>2]=g;i=w;return}b=g>>>8;if(b)if(g>>>0>16777215)f=31;else{l=(b+1048320|0)>>>16&8;m=b<>>16&4;m=m<>>16&2;f=14-(k|l|f)+(m<>>15)|0;f=g>>>(f+7|0)&1|f<<1}else f=0;d=57336+(f<<2)|0;c[v+28>>2]=f;c[v+20>>2]=0;c[v+16>>2]=0;b=c[14259]|0;e=1<>2]|0;if((f|0)==31)d=0;else d=25-(f>>>1)|0;b:do if((c[e+4>>2]&-8|0)!=(g|0)){f=g<>>31<<2)+16|0;d=c[b>>2]|0;if(!d)break;if((c[d+4>>2]&-8|0)==(g|0)){u=d;break b}else{f=f<<1;e=d}}if(b>>>0<(c[14262]|0)>>>0)ra();else{c[b>>2]=v;c[v+24>>2]=e;c[v+12>>2]=v;c[v+8>>2]=v;break a}}else u=e;while(0);b=u+8|0;d=c[b>>2]|0;m=c[14262]|0;if(u>>>0>=m>>>0&d>>>0>=m>>>0){c[d+12>>2]=v;c[b>>2]=v;c[v+8>>2]=d;c[v+12>>2]=u;c[v+24>>2]=0;break}else ra()}else{c[14259]=b|e;c[d>>2]=v;c[v+24>>2]=d;c[v+12>>2]=v;c[v+8>>2]=v}while(0);m=(c[14266]|0)+-1|0;c[14266]=m;if(!m)b=57488|0;else{i=w;return}while(1){b=c[b>>2]|0;if(!b)break;else b=b+8|0}c[14266]=-1;i=w;return}function Ta(){}function Ua(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function Va(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function Wa(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return ha(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0} + +// EMSCRIPTEN_END_FUNCS +return{_strlen:Ua,_free:Sa,_main:Qa,_memset:Va,_malloc:Ra,_memcpy:Wa,runPostSets:Ta,stackAlloc:ya,stackSave:za,stackRestore:Aa,setThrew:Ba,setTempRet0:Ea,getTempRet0:Fa}}) + + +// EMSCRIPTEN_END_ASM +(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var _strlen=Module["_strlen"]=asm["_strlen"];var _free=Module["_free"]=asm["_free"];var _main=Module["_main"]=asm["_main"];var _memset=Module["_memset"]=asm["_memset"];var _malloc=Module["_malloc"]=asm["_malloc"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];var i64Math=null;if(memoryInitializer){if(typeof Module["locateFile"]==="function"){memoryInitializer=Module["locateFile"](memoryInitializer)}else if(Module["memoryInitializerPrefixURL"]){memoryInitializer=Module["memoryInitializerPrefixURL"]+memoryInitializer}if(ENVIRONMENT_IS_NODE||ENVIRONMENT_IS_SHELL){var data=Module["readBinary"](memoryInitializer);HEAPU8.set(data,STATIC_BASE)}else{addRunDependency("memory initializer");Browser.asyncLoad(memoryInitializer,(function(data){HEAPU8.set(data,STATIC_BASE);removeRunDependency("memory initializer")}),(function(data){throw"could not load memory initializer "+memoryInitializer}))}}function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"]&&shouldRunNow)run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(ENVIRONMENT_IS_WEB&&preloadStartTime!==null){Module.printErr("pre-main prep time: "+(Date.now()-preloadStartTime)+" ms")}if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status){if(Module["noExitRuntime"]){return}ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(ENVIRONMENT_IS_NODE){process["stdout"]["once"]("drain",(function(){process["exit"](status)}));console.log(" ");setTimeout((function(){process["exit"](status)}),500)}else if(ENVIRONMENT_IS_SHELL&&typeof quit==="function"){quit(status)}throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;function abort(text){if(text){Module.print(text);Module.printErr(text)}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";throw"abort() at "+stackTrace()+extra}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=true;if(Module["noInitialRun"]){shouldRunNow=false}run() + + + + + }); + return res; + +} diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/test_arg.js.mem b/hardware-wallet/firmware/vendor/trezor-qrenc/compiled/test_arg.js.mem new file mode 100644 index 0000000000000000000000000000000000000000..9a24c04dbdd40a74513219747c60f98242b5baca GIT binary patch literal 57520 zcmeI!X;c&0wg>Q2mCC>nk`RU@AVUBdLJ|xZ6hTD=6%f%z5S2j`R6vkXMp0VD0Z~9P z+Ndbn&SNX$gtHtu(je;s!H>Le9} zU;_aV009sH0T2KI5C8!X_`3vj@juqb!$8}B4z7B5u(f})aOG-;b{7;7009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5CDOHi2xxa6{0J&HrGzG*;oCkne7H{tKKg%KR@S7 z9V;N2z9L5c#Fk?{u&lV{gJFSBzhf8j;_SbkxVBLzbKLWkpBZOYM#r|ge1EF4`-NK~ zUZ%XYwqbSo!!sXm^QZkd$alEKi0Z0~V-_UFdpHFDx#Xl*eZ)^&bd9qlfp=f*OZ~Jn zlsWHQchSNb>{)(~-wn9jD|ohJ!~Fg=M{{|jN*~x*Etk0uYn;07^shJ96s|w==v(dd zu8=!>jhwkzA+gcck6_{mrhR$p`;0V%6=xj#mED`$O9I=WxA+ zM>`&0wEMVs`p$9C*5TSZSz9x;Ri&*p+S;tG=&tsBZ4J`aOl{qztudzp0Q{ADb?CEx&r zj{8eg&6dAZD_jyo-bX#obK3v(e0xEKT~BkT!?~jf=`!MKzwV?)Hm+D<)s+)wmU$wm zqQB2xPxHq?ZoMZSeM}lx8X+=H;LnLjJ|9w4mFKbf#ru|7gM3rGjxXBDjvl(mwXcu5 z_TtPIh^U2bt%0k`L#u+I=MyM|M|-ypCSje9NKQ= zElskYFd!rO@%cZyc0F+1-hJ4j(=c;`=Xr#Nq>bPDEqdY2gA0ve&W|g_F>UrS_pZL{ zy_U0g+l6#RR9~O9Os}lbfB3lXIvw`utZ+<@PKiM`(ditxdT9HCjFeGTZWkVu-Pmnc zkQ_VqnEH%)5tHYAZ?8{1H6x6!OkU*d!7XgweaDudqC7v2o&ARO_4E7#Zo*CNlKM9O zL=HmFg_jEMlzIw!rr5`R@H#R~mXm7Onp9X>eKWoxvOKe9s&RKkQRi8`h-blyDtmE4 zN8YBb+jTNzjWe#Fx1lvAUF^F4M8>wNT+moh+11qLKhEilRkC-k&-0YG2Xpr{bu78r zcO7Ypkdul>Jz?i$A^Exdn%C=_ObmvU*mYfB+8b6IF~mDJdFJc4StbD?)9t(J9>rL{ z?@iO(spFz+p|@L;jb+|aMQ6>|C$S!lEpvB>B5TgMeYWZCJh*Rsjxbx2na~up@Y-9} zh9NPQR{|_65Q@u;-?Y7XUK%;|OO@@l`WK8fy+0M++S91NGQYU`>)`{n=DL&K*Tm$i z8lp_Ayv#0juiseztC5%P#57U&2(zK_->U0QymjyCy1i!OyF;taeNlaFnDo8adqvvY2xU13zW>2DF8ZQTQfZ;N4wt%%(N{t=@}uWjXg8QWUvOzxp~WgQS+ze9KLa?w=Qtiy7{8~ftBG`@AeavRNN|WX{4H`%4kxb`} z1rNrFJK_|(CI*y_jN2<*94?*HcfY&0v{|=@kMo^UY1Jz!500t5 zxx~%0e#fKh>%)UN!Qb~+hCOq;Iz950+hNDN?sBI$f<7E_Z?qqC|y z`)2z8zY<7<`1sqOjdcF|Btpa|L|j6|CPe?UPjie!&Pa^RkqOQdhMHZ3vzTx;C!9?P zXY~{0uZ@O$k-H`@LWGHCKjG_6_&Sp|Jko~!R}jCW&`cDBpF}Rm77?Pp?93oiVMQtg zl<QYeIyJCpCRFpp+0IqXCo3@>!G#8D54h~MMa3T zP^z<3%mgAxK`BgVnt7=Su9T}O3(u>MZWAelm}o$o5ozV2nKx}31NR^^VmcX+>EXBs zhTK?f!bV2qJ|d9#9nVaPhic|s63-f9$8t8(*Z30nI;F-G_BB90ky{9Rq77$V)K510+)(v#r9hocoJ=3# z#B>)jah8i($#LXm!iV^dvkE_THanU*R?3m^X;Kc6GlS+Q!wzg27x9psR!H^`NrV|e zvrwuZ^F(31uAhuhn2=5e^koTzzntT0%EQ-Yh?dYANmp_eF&JkDO;pcYo~h#_;c2qO z`Yg)VnQ%4b<18Pw(adP69SWh(!cVJamdWTNqCp>BvzEI1&!-fj!EJ?k?2D_stkBrnb}SNko4fKGMJ>WSqlE?QJli}lbI__tYutsbt>)$UmJzzHAA+{ z)AZSt11*iDuvrG4SCwrtR>~S^s*mU0kc02BNGUMK^O~bY%pUq~Y8GuBNmn~$BU)KH zZLE~SYe&k_U7KO*C$n@HTH7QVz2$o#`jD zQwl^lYk`)tt}?>u4`{FPyl#QB3lO~|m5VB=zR-Gy)oiUXfN27~9L*}hOypmMBCUunp z+=KdV`O9tGg*G^Aja+q2amQuU5Y#t zI*;eYW~J&LaMoEV7$V~`O4IPX_%lRcUmN79N9q_c8T1w!L*r1czdlRfUv96tZ%kFT zNV6Us@w~REMXx|7o9Rclpcn#0Ku*o`|Xd!>|$Ld>oGlpVyM^7vTc+qo9!oa zQ3{--9K#JcR{nClCarMR9^GJn)7{0AF|JSyk#b_ +// (c) 2012-2014 Pavol Rusnak +// (c) 2015 Karel Bilek +// +// Licensed under the MIT license: +// http://www.opensource.org/licenses/mit-license.php +// +// The word 'QR Code' is registered trademark of +// DENSO WAVE INCORPORATED +// http://www.denso-wave.com/qrcode/faqpatent-e.html +// +// +// Use: qrMaker("ABCD").imgTag(10,10).then(function(tag){$("...").html(tag)}) +//--------------------------------------------------------------------- + +function qrMaker(address) { + this.address=address; +} + +/** + * Returns promise for IMG tag with the given address in it. + * + * cellSize - size of one "pixel" in QR + * margin - size of the "bezel" around QR code that's always white + */ +qrMaker.prototype.imgTag=function(cellSize, margin){ + + //this code is almost verbatim copied from + //lrsjng/jquery-qrcode + + //--------------------------------------------------------------------- + // gifImage (B/W) + //--------------------------------------------------------------------- + + var gifImage = function(width, height) { + + var _width = width; + var _height = height; + var _data = new Array(width * height); + + var _this = {}; + + _this.setPixel = function(x, y, pixel) { + _data[y * _width + x] = pixel; + }; + + _this.write = function(out) { + + //--------------------------------- + // GIF Signature + + out.writeString('GIF87a'); + + //--------------------------------- + // Screen Descriptor + + out.writeShort(_width); + out.writeShort(_height); + + out.writeByte(0x80); // 2bit + out.writeByte(0); + out.writeByte(0); + + //--------------------------------- + // Global Color Map + + // black + out.writeByte(0x00); + out.writeByte(0x00); + out.writeByte(0x00); + + // white + out.writeByte(0xff); + out.writeByte(0xff); + out.writeByte(0xff); + + //--------------------------------- + // Image Descriptor + + out.writeString(','); + out.writeShort(0); + out.writeShort(0); + out.writeShort(_width); + out.writeShort(_height); + out.writeByte(0); + + //--------------------------------- + // Local Color Map + + //--------------------------------- + // Raster Data + + var lzwMinCodeSize = 2; + var raster = getLZWRaster(lzwMinCodeSize); + + out.writeByte(lzwMinCodeSize); + + var offset = 0; + + while (raster.length - offset > 255) { + out.writeByte(255); + out.writeBytes(raster, offset, 255); + offset += 255; + } + + out.writeByte(raster.length - offset); + out.writeBytes(raster, offset, raster.length - offset); + out.writeByte(0x00); + + //--------------------------------- + // GIF Terminator + out.writeString(';'); + }; + + var bitOutputStream = function(out) { + + var _out = out; + var _bitLength = 0; + var _bitBuffer = 0; + + var _this = {}; + + _this.write = function(data, length) { + + if ( (data >>> length) != 0) { + throw new Error('length over'); + } + + while (_bitLength + length >= 8) { + _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); + length -= (8 - _bitLength); + data >>>= (8 - _bitLength); + _bitBuffer = 0; + _bitLength = 0; + } + + _bitBuffer = (data << _bitLength) | _bitBuffer; + _bitLength = _bitLength + length; + }; + + _this.flush = function() { + if (_bitLength > 0) { + _out.writeByte(_bitBuffer); + } + }; + + return _this; + }; + + var getLZWRaster = function(lzwMinCodeSize) { + + var clearCode = 1 << lzwMinCodeSize; + var endCode = (1 << lzwMinCodeSize) + 1; + var bitLength = lzwMinCodeSize + 1; + + // Setup LZWTable + var table = lzwTable(); + + for (var i = 0; i < clearCode; i += 1) { + table.add(String.fromCharCode(i) ); + } + table.add(String.fromCharCode(clearCode) ); + table.add(String.fromCharCode(endCode) ); + + var byteOut = byteArrayOutputStream(); + var bitOut = bitOutputStream(byteOut); + + // clear code + bitOut.write(clearCode, bitLength); + + var dataIndex = 0; + + var s = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + while (dataIndex < _data.length) { + + var c = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + if (table.contains(s + c) ) { + + s = s + c; + + } else { + + bitOut.write(table.indexOf(s), bitLength); + + if (table.size() < 0xfff) { + + if (table.size() == (1 << bitLength) ) { + bitLength += 1; + } + + table.add(s + c); + } + + s = c; + } + } + + bitOut.write(table.indexOf(s), bitLength); + + // end code + bitOut.write(endCode, bitLength); + + bitOut.flush(); + + return byteOut.toByteArray(); + }; + + var lzwTable = function() { + + var _map = {}; + var _size = 0; + + var _this = {}; + + _this.add = function(key) { + if (_this.contains(key) ) { + throw new Error('dup key:' + key); + } + _map[key] = _size; + _size += 1; + }; + + _this.size = function() { + return _size; + }; + + _this.indexOf = function(key) { + return _map[key]; + }; + + _this.contains = function(key) { + return typeof _map[key] != 'undefined'; + }; + + return _this; + }; + + return _this; + }; + + var byteArrayOutputStream = function() { + + var _bytes = new Array(); + + var _this = {}; + + _this.writeByte = function(b) { + _bytes.push(b & 0xff); + }; + + _this.writeShort = function(i) { + _this.writeByte(i); + _this.writeByte(i >>> 8); + }; + + _this.writeBytes = function(b, off, len) { + off = off || 0; + len = len || b.length; + for (var i = 0; i < len; i += 1) { + _this.writeByte(b[i + off]); + } + }; + + _this.writeString = function(s) { + for (var i = 0; i < s.length; i += 1) { + _this.writeByte(s.charCodeAt(i) ); + } + }; + + _this.toByteArray = function() { + return _bytes; + }; + + _this.toString = function() { + var s = ''; + s += '['; + for (var i = 0; i < _bytes.length; i += 1) { + if (i > 0) { + s += ','; + } + s += _bytes[i]; + } + s += ']'; + return s; + }; + + return _this; + }; + + + var base64EncodeOutputStream = function() { + + var _buffer = 0; + var _buflen = 0; + var _length = 0; + var _base64 = ''; + + var _this = {}; + + var writeEncoded = function(b) { + _base64 += String.fromCharCode(encode(b & 0x3f) ); + }; + + var encode = function(n) { + if (n < 0) { + // error. + } else if (n < 26) { + return 0x41 + n; + } else if (n < 52) { + return 0x61 + (n - 26); + } else if (n < 62) { + return 0x30 + (n - 52); + } else if (n == 62) { + return 0x2b; + } else if (n == 63) { + return 0x2f; + } + throw new Error('n:' + n); + }; + + _this.writeByte = function(n) { + + _buffer = (_buffer << 8) | (n & 0xff); + _buflen += 8; + _length += 1; + + while (_buflen >= 6) { + writeEncoded(_buffer >>> (_buflen - 6) ); + _buflen -= 6; + } + }; + + _this.flush = function() { + + if (_buflen > 0) { + writeEncoded(_buffer << (6 - _buflen) ); + _buffer = 0; + _buflen = 0; + } + + if (_length % 3 != 0) { + // padding + var padlen = 3 - _length % 3; + for (var i = 0; i < padlen; i += 1) { + _base64 += '='; + } + } + }; + + _this.toString = function() { + return _base64; + }; + + return _this; + }; + + + var createImgTag = function(width, height, getPixel, alt) { + + var gif = gifImage(width, height); + for (var y = 0; y < height; y += 1) { + for (var x = 0; x < width; x += 1) { + gif.setPixel(x, y, getPixel(x, y) ); + } + } + + var b = byteArrayOutputStream(); + gif.write(b); + + var base64 = base64EncodeOutputStream(); + var bytes = b.toByteArray(); + for (var i = 0; i < bytes.length; i += 1) { + base64.writeByte(bytes[i]); + } + base64.flush(); + + var img = ''; + img += ' + * Copyright (c) 2012-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 __QR_CONSTS_H__ +#define __QR_CONSTS_H__ + +typedef struct +{ + uint8_t ncRSBlock; // RS block number + uint8_t ncAllCodeWord; // The number of codewords in the block + uint8_t ncDataCodeWord; // The number of data code words (the number of code words - the number of RS code word) +} RS_BLOCKINFO; + +typedef struct +{ + uint8_t nVersionNo; + uint16_t ncAllCodeWord; + // Error correction levels (0 = L, 1 = M, 2 = Q, 3 = H) + uint16_t ncDataCodeWord[4]; // data len + uint8_t ncAlignPoint; // position + uint8_t nAlignPoint[6]; // numberof + RS_BLOCKINFO RS_BlockInfo1[4]; // EC pos + RS_BLOCKINFO RS_BlockInfo2[4]; // EC pos +} QR_VERSIONINFO; + +static const QR_VERSIONINFO QR_VersonInfo[] = { + {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}}}, + {1, 26, {19, 16, 13, 9}, 0, {0, 0, 0, 0, 0, 0}, {{1, 26, 19}, {1, 26, 16}, {1, 26, 13}, {1, 26, 9}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}, + {2, 44, {34, 28, 22, 16}, 1, {18, 0, 0, 0, 0, 0}, {{1, 44, 34}, {1, 44, 28}, {1, 44, 22}, {1, 44, 16}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}, + {3, 70, {55, 44, 34, 26}, 1, {22, 0, 0, 0, 0, 0}, {{1, 70, 55}, {1, 70, 44}, {2, 35, 17}, {2, 35, 13}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}, + {4, 100, {80, 64, 48, 36}, 1, {26, 0, 0, 0, 0, 0}, {{1, 100, 80}, {2, 50, 32}, {2, 50, 24}, {4, 25, 9}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}, + {5, 134, {108, 86, 62, 46}, 1, {30, 0, 0, 0, 0, 0}, {{1, 134, 108}, {2, 67, 43}, {2, 33, 15}, {2, 33, 11}}, {{0, 0, 0}, {0, 0, 0}, {2, 34, 16}, {2, 34, 12}}}, + {6, 172, {136, 108, 76, 60}, 1, {34, 0, 0, 0, 0, 0}, {{2, 86, 68}, {4, 43, 27}, {4, 43, 19}, {4, 43, 15}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}, + {7, 196, {156, 124, 88, 66}, 2, {22, 38, 0, 0, 0, 0}, {{2, 98, 78}, {4, 49, 31}, {2, 32, 14}, {4, 39, 13}}, {{0, 0, 0}, {0, 0, 0}, {4, 33, 15}, {1, 40, 14}}}, + {8, 242, {194, 154, 110, 86}, 2, {24, 42, 0, 0, 0, 0}, {{2, 121, 97}, {2, 60, 38}, {4, 40, 18}, {4, 40, 14}}, {{0, 0, 0}, {2, 61, 39}, {2, 41, 19}, {2, 41, 15}}}, + {9, 292, {232, 182, 132, 100}, 2, {26, 46, 0, 0, 0, 0}, {{2, 146, 116}, {3, 58, 36}, {4, 36, 16}, {4, 36, 12}}, {{0, 0, 0}, {2, 59, 37}, {4, 37, 17}, {4, 37, 13}}}, +#if QR_MAX_VERSION >= QR_VERSION_M + {10, 346, {274, 216, 154, 122}, 2, {28, 50, 0, 0, 0, 0}, {{2, 86, 68}, {4, 69, 43}, {6, 43, 19}, {6, 43, 15}}, {{2, 87, 69}, {1, 70, 44}, {2, 44, 20}, {2, 44, 16}}}, + {11, 404, {324, 254, 180, 140}, 2, {30, 54, 0, 0, 0, 0}, {{4, 101, 81}, {1, 80, 50}, {4, 50, 22}, {3, 36, 12}}, {{0, 0, 0}, {4, 81, 51}, {4, 51, 23}, {8, 37, 13}}}, + {12, 466, {370, 290, 206, 158}, 2, {32, 58, 0, 0, 0, 0}, {{2, 116, 92}, {6, 58, 36}, {4, 46, 20}, {7, 42, 14}}, {{2, 117, 93}, {2, 59, 37}, {6, 47, 21}, {4, 43, 15}}}, + {13, 532, {428, 334, 244, 180}, 2, {34, 62, 0, 0, 0, 0}, {{4, 133, 107}, {8, 59, 37}, {8, 44, 20}, {12, 33, 11}}, {{0, 0, 0}, {1, 60, 38}, {4, 45, 21}, {4, 34, 12}}}, + {14, 581, {461, 365, 261, 197}, 3, {26, 46, 66, 0, 0, 0}, {{3, 145, 115}, {4, 64, 40}, {11, 36, 16}, {11, 36, 12}}, {{1, 146, 116}, {5, 65, 41}, {5, 37, 17}, {5, 37, 13}}}, + {15, 655, {523, 415, 295, 223}, 3, {26, 48, 70, 0, 0, 0}, {{5, 109, 87}, {5, 65, 41}, {5, 54, 24}, {11, 36, 12}}, {{1, 110, 88}, {5, 66, 42}, {7, 55, 25}, {7, 37, 13}}}, + {16, 733, {589, 453, 325, 253}, 3, {26, 50, 74, 0, 0, 0}, {{5, 122, 98}, {7, 73, 45}, {15, 43, 19}, {3, 45, 15}}, {{1, 123, 99}, {3, 74, 46}, {2, 44, 20}, {13, 46, 16}}}, + {17, 815, {647, 507, 367, 283}, 3, {30, 54, 78, 0, 0, 0}, {{1, 135, 107}, {10, 74, 46}, {1, 50, 22}, {2, 42, 14}}, {{5, 136, 108}, {1, 75, 47}, {15, 51, 23}, {17, 43, 15}}}, + {18, 901, {721, 563, 397, 313}, 3, {30, 56, 82, 0, 0, 0}, {{5, 150, 120}, {9, 69, 43}, {17, 50, 22}, {2, 42, 14}}, {{1, 151, 121}, {4, 70, 44}, {1, 51, 23}, {19, 43, 15}}}, + {19, 991, {795, 627, 445, 341}, 3, {30, 58, 86, 0, 0, 0}, {{3, 141, 113}, {3, 70, 44}, {17, 47, 21}, {9, 39, 13}}, {{4, 142, 114}, {11, 71, 45}, {4, 48, 22}, {16, 40, 14}}}, + {20, 1085, {861, 669, 485, 385}, 3, {34, 62, 90, 0, 0, 0}, {{3, 135, 107}, {3, 67, 41}, {15, 54, 24}, {15, 43, 15}}, {{5, 136, 108}, {13, 68, 42}, {5, 55, 25}, {10, 44, 16}}}, + {21, 1156, {932, 714, 512, 406}, 4, {28, 50, 72, 94, 0, 0}, {{4, 144, 116}, {17, 68, 42}, {17, 50, 22}, {19, 46, 16}}, {{4, 145, 117}, {0, 0, 0}, {6, 51, 23}, {6, 47, 17}}}, + {22, 1258, {1006, 782, 568, 442}, 4, {26, 50, 74, 98, 0, 0}, {{2, 139, 111}, {17, 74, 46}, {7, 54, 24}, {34, 37, 13}}, {{7, 140, 112}, {0, 0, 0}, {16, 55, 25}, {0, 0, 0}}}, + {23, 1364, {1094, 860, 614, 464}, 4, {30, 54, 78, 102, 0, 0}, {{4, 151, 121}, {4, 75, 47}, {11, 54, 24}, {16, 45, 15}}, {{5, 152, 122}, {14, 76, 48}, {14, 55, 25}, {14, 46, 16}}}, + {24, 1474, {1174, 914, 664, 514}, 4, {28, 54, 80, 106, 0, 0}, {{6, 147, 117}, {6, 73, 45}, {11, 54, 24}, {30, 46, 16}}, {{4, 148, 118}, {14, 74, 46}, {16, 55, 25}, {2, 47, 17}}}, + {25, 1588, {1276, 1000, 718, 538}, 4, {32, 58, 84, 110, 0, 0}, {{8, 132, 106}, {8, 75, 47}, {7, 54, 24}, {22, 45, 15}}, {{4, 133, 107}, {13, 76, 48}, {22, 55, 25}, {13, 46, 16}}}, + {26, 1706, {1370, 1062, 754, 596}, 4, {30, 58, 86, 114, 0, 0}, {{10, 142, 114}, {19, 74, 46}, {28, 50, 22}, {33, 46, 16}}, {{2, 143, 115}, {4, 75, 47}, {6, 51, 23}, {4, 47, 17}}}, +#endif +#if QR_MAX_VERSION >= QR_VERSION_L + {27, 1828, {1468, 1128, 808, 628}, 4, {34, 62, 90, 118, 0, 0}, {{8, 152, 122}, {22, 73, 45}, {8, 53, 23}, {12, 45, 15}}, {{4, 153, 123}, {3, 74, 46}, {26, 54, 24}, {28, 46, 16}}}, + {28, 1921, {1531, 1193, 871, 661}, 5, {26, 50, 74, 98, 122, 0}, {{3, 147, 117}, {3, 73, 45}, {4, 54, 24}, {11, 45, 15}}, {{10, 148, 118}, {23, 74, 46}, {31, 55, 25}, {31, 46, 16}}}, + {29, 2051, {1631, 1267, 911, 701}, 5, {30, 54, 78, 102, 126, 0}, {{7, 146, 116}, {21, 73, 45}, {1, 53, 23}, {19, 45, 15}}, {{7, 147, 117}, {7, 74, 46}, {37, 54, 24}, {26, 46, 16}}}, + {30, 2185, {1735, 1373, 985, 745}, 5, {26, 52, 78, 104, 130, 0}, {{5, 145, 115}, {19, 75, 47}, {15, 54, 24}, {23, 45, 15}}, {{10, 146, 116}, {10, 76, 48}, {25, 55, 25}, {25, 46, 16}}}, + {31, 2323, {1843, 1455, 1033, 793}, 5, {30, 56, 82, 108, 134, 0}, {{13, 145, 115}, {2, 74, 46}, {42, 54, 24}, {23, 45, 15}}, {{3, 146, 116}, {29, 75, 47}, {1, 55, 25}, {28, 46, 16}}}, + {32, 2465, {1955, 1541, 1115, 845}, 5, {34, 60, 86, 112, 138, 0}, {{17, 145, 115}, {10, 74, 46}, {10, 54, 24}, {19, 45, 15}}, {{0, 0, 0}, {23, 75, 47}, {35, 55, 25}, {35, 46, 16}}}, + {33, 2611, {2071, 1631, 1171, 901}, 5, {30, 58, 86, 114, 142, 0}, {{17, 145, 115}, {14, 74, 46}, {29, 54, 24}, {11, 45, 15}}, {{1, 146, 116}, {21, 75, 47}, {19, 55, 25}, {46, 46, 16}}}, + {34, 2761, {2191, 1725, 1231, 961}, 5, {34, 62, 90, 118, 146, 0}, {{13, 145, 115}, {14, 74, 46}, {44, 54, 24}, {59, 46, 16}}, {{6, 146, 116}, {23, 75, 47}, {7, 55, 25}, {1, 47, 17}}}, + {35, 2876, {2306, 1812, 1286, 986}, 6, {30, 54, 78, 102, 126, 150}, {{12, 151, 121}, {12, 75, 47}, {39, 54, 24}, {22, 45, 15}}, {{7, 152, 122}, {26, 76, 48}, {14, 55, 25}, {41, 46, 16}}}, + {36, 3034, {2434, 1914, 1354, 1054}, 6, {24, 50, 76, 102, 128, 154}, {{6, 151, 121}, {6, 75, 47}, {46, 54, 24}, {2, 45, 15}}, {{14, 152, 122}, {34, 76, 48}, {10, 55, 25}, {64, 46, 16}}}, + {37, 3196, {2566, 1992, 1426, 1096}, 6, {28, 54, 80, 106, 132, 158}, {{17, 152, 122}, {29, 74, 46}, {49, 54, 24}, {24, 45, 15}}, {{4, 153, 123}, {14, 75, 47}, {10, 55, 25}, {46, 46, 16}}}, + {38, 3362, {2702, 2102, 1502, 1142}, 6, {32, 58, 84, 110, 136, 162}, {{4, 152, 122}, {13, 74, 46}, {48, 54, 24}, {42, 45, 15}}, {{18, 153, 123}, {32, 75, 47}, {14, 55, 25}, {32, 46, 16}}}, + {39, 3532, {2812, 2216, 1582, 1222}, 6, {26, 54, 82, 110, 138, 166}, {{20, 147, 117}, {40, 75, 47}, {43, 54, 24}, {10, 45, 15}}, {{4, 148, 118}, {7, 76, 48}, {22, 55, 25}, {67, 46, 16}}}, + {40, 3706, {2956, 2334, 1666, 1276}, 6, {30, 58, 86, 114, 142, 170}, {{19, 148, 118}, {18, 75, 47}, {34, 54, 24}, {20, 45, 15}}, {{6, 149, 119}, {31, 76, 48}, {34, 55, 25}, {61, 46, 16}}}, +#endif +}; + +static const uint8_t byExpToInt[] = {1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1}; +static const uint8_t byIntToExp[] = {0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175}; + +static const uint8_t byRSExp7[] = {87, 229, 146, 149, 238, 102, 21}; +static const uint8_t byRSExp10[] = {251, 67, 46, 61, 118, 70, 64, 94, 32, 45}; +static const uint8_t byRSExp13[] = {74, 152, 176, 100, 86, 100, 106, 104, 130, 218, 206, 140, 78}; +static const uint8_t byRSExp15[] = {8, 183, 61, 91, 202, 37, 51, 58, 58, 237, 140, 124, 5, 99, 105}; +static const uint8_t byRSExp16[] = {120, 104, 107, 109, 102, 161, 76, 3, 91, 191, 147, 169, 182, 194, 225, 120}; +static const uint8_t byRSExp17[] = {43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150, 39, 243, 163, 136}; +static const uint8_t byRSExp18[] = {215, 234, 158, 94, 184, 97, 118, 170, 79, 187, 152, 148, 252, 179, 5, 98, 96, 153}; +static const uint8_t byRSExp20[] = {17, 60, 79, 50, 61, 163, 26, 187, 202, 180, 221, 225, 83, 239, 156, 164, 212, 212, 188, 190}; +static const uint8_t byRSExp22[] = {210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200, 74, 8, 172, 98, 80, 219, 134, 160, 105, 165, 231}; +static const uint8_t byRSExp24[] = {229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169, 152, 192, 226, 228, 218, 111, 0, 117, 232, 87, 96, 227, 21}; +static const uint8_t byRSExp26[] = {173, 125, 158, 2, 103, 182, 118, 17, 145, 201, 111, 28, 165, 53, 161, 21, 245, 142, 13, 102, 48, 227, 153, 145, 218, 70}; +static const uint8_t byRSExp28[] = {168, 223, 200, 104, 224, 234, 108, 180, 110, 190, 195, 147, 205, 27, 232, 201, 21, 43, 245, 87, 42, 195, 212, 119, 242, 37, 9, 123}; +static const uint8_t byRSExp30[] = {41, 173, 145, 152, 216, 31, 179, 182, 50, 48, 110, 86, 239, 96, 222, 125, 42, 173, 226, 193, 224, 130, 156, 37, 251, 216, 238, 40, 192, 180}; +static const uint8_t byRSExp32[] = {10, 6, 106, 190, 249, 167, 4, 67, 209, 138, 138, 32, 242, 123, 89, 27, 120, 185, 80, 156, 38, 69, 171, 60, 28, 222, 80, 52, 254, 185, 220, 241}; +static const uint8_t byRSExp34[] = {111, 77, 146, 94, 26, 21, 108, 19, 105, 94, 113, 193, 86, 140, 163, 125, 58, 158, 229, 239, 218, 103, 56, 70, 114, 61, 183, 129, 167, 13, 98, 62, 129, 51}; +static const uint8_t byRSExp36[] = {200, 183, 98, 16, 172, 31, 246, 234, 60, 152, 115, 0, 167, 152, 113, 248, 238, 107, 18, 63, 218, 37, 87, 210, 105, 177, 120, 74, 121, 196, 117, 251, 113, 233, 30, 120}; +static const uint8_t byRSExp38[] = {159, 34, 38, 228, 230, 59, 243, 95, 49, 218, 176, 164, 20, 65, 45, 111, 39, 81, 49, 118, 113, 222, 193, 250, 242, 168, 217, 41, 164, 247, 177, 30, 238, 18, 120, 153, 60, 193}; +static const uint8_t byRSExp40[] = {59, 116, 79, 161, 252, 98, 128, 205, 128, 161, 247, 57, 163, 56, 235, 106, 53, 26, 187, 174, 226, 104, 170, 7, 175, 35, 181, 114, 88, 41, 47, 163, 125, 134, 72, 20, 232, 53, 35, 15}; +static const uint8_t byRSExp42[] = {250, 103, 221, 230, 25, 18, 137, 231, 0, 3, 58, 242, 221, 191, 110, 84, 230, 8, 188, 106, 96, 147, 15, 131, 139, 34, 101, 223, 39, 101, 213, 199, 237, 254, 201, 123, 171, 162, 194, 117, 50, 96}; +static const uint8_t byRSExp44[] = {190, 7, 61, 121, 71, 246, 69, 55, 168, 188, 89, 243, 191, 25, 72, 123, 9, 145, 14, 247, 1, 238, 44, 78, 143, 62, 224, 126, 118, 114, 68, 163, 52, 194, 217, 147, 204, 169, 37, 130, 113, 102, 73, 181}; +static const uint8_t byRSExp46[] = {112, 94, 88, 112, 253, 224, 202, 115, 187, 99, 89, 5, 54, 113, 129, 44, 58, 16, 135, 216, 169, 211, 36, 1, 4, 96, 60, 241, 73, 104, 234, 8, 249, 245, 119, 174, 52, 25, 157, 224, 43, 202, 223, 19, 82, 15}; +static const uint8_t byRSExp48[] = {228, 25, 196, 130, 211, 146, 60, 24, 251, 90, 39, 102, 240, 61, 178, 63, 46, 123, 115, 18, 221, 111, 135, 160, 182, 205, 107, 206, 95, 150, 120, 184, 91, 21, 247, 156, 140, 238, 191, 11, 94, 227, 84, 50, 163, 39, 34, 108}; +static const uint8_t byRSExp50[] = {232, 125, 157, 161, 164, 9, 118, 46, 209, 99, 203, 193, 35, 3, 209, 111, 195, 242, 203, 225, 46, 13, 32, 160, 126, 209, 130, 160, 242, 215, 242, 75, 77, 42, 189, 32, 113, 65, 124, 69, 228, 114, 235, 175, 124, 170, 215, 232, 133, 205}; +static const uint8_t byRSExp52[] = {116, 50, 86, 186, 50, 220, 251, 89, 192, 46, 86, 127, 124, 19, 184, 233, 151, 215, 22, 14, 59, 145, 37, 242, 203, 134, 254, 89, 190, 94, 59, 65, 124, 113, 100, 233, 235, 121, 22, 76, 86, 97, 39, 242, 200, 220, 101, 33, 239, 254, 116, 51}; +static const uint8_t byRSExp54[] = {183, 26, 201, 87, 210, 221, 113, 21, 46, 65, 45, 50, 238, 184, 249, 225, 102, 58, 209, 218, 109, 165, 26, 95, 184, 192, 52, 245, 35, 254, 238, 175, 172, 79, 123, 25, 122, 43, 120, 108, 215, 80, 128, 201, 235, 8, 153, 59, 101, 31, 198, 76, 31, 156}; +static const uint8_t byRSExp56[] = {106, 120, 107, 157, 164, 216, 112, 116, 2, 91, 248, 163, 36, 201, 202, 229, 6, 144, 254, 155, 135, 208, 170, 209, 12, 139, 127, 142, 182, 249, 177, 174, 190, 28, 10, 85, 239, 184, 101, 124, 152, 206, 96, 23, 163, 61, 27, 196, 247, 151, 154, 202, 207, 20, 61, 10}; +static const uint8_t byRSExp58[] = {82, 116, 26, 247, 66, 27, 62, 107, 252, 182, 200, 185, 235, 55, 251, 242, 210, 144, 154, 237, 176, 141, 192, 248, 152, 249, 206, 85, 253, 142, 65, 165, 125, 23, 24, 30, 122, 240, 214, 6, 129, 218, 29, 145, 127, 134, 206, 245, 117, 29, 41, 63, 159, 142, 233, 125, 148, 123}; +static const uint8_t byRSExp60[] = {107, 140, 26, 12, 9, 141, 243, 197, 226, 197, 219, 45, 211, 101, 219, 120, 28, 181, 127, 6, 100, 247, 2, 205, 198, 57, 115, 219, 101, 109, 160, 82, 37, 38, 238, 49, 160, 209, 121, 86, 11, 124, 30, 181, 84, 25, 194, 87, 65, 102, 190, 220, 70, 27, 209, 16, 89, 7, 33, 240}; +static const uint8_t byRSExp62[] = {65, 202, 113, 98, 71, 223, 248, 118, 214, 94, 0, 122, 37, 23, 2, 228, 58, 121, 7, 105, 135, 78, 243, 118, 70, 76, 223, 89, 72, 50, 70, 111, 194, 17, 212, 126, 181, 35, 221, 117, 235, 11, 229, 149, 147, 123, 213, 40, 115, 6, 200, 100, 26, 246, 182, 218, 127, 215, 36, 186, 110, 106}; +static const uint8_t byRSExp64[] = {45, 51, 175, 9, 7, 158, 159, 49, 68, 119, 92, 123, 177, 204, 187, 254, 200, 78, 141, 149, 119, 26, 127, 53, 160, 93, 199, 212, 29, 24, 145, 156, 208, 150, 218, 209, 4, 216, 91, 47, 184, 146, 47, 140, 195, 195, 125, 242, 238, 63, 99, 108, 140, 230, 242, 31, 204, 11, 178, 243, 217, 156, 213, 231}; +static const uint8_t byRSExp66[] = {5, 118, 222, 180, 136, 136, 162, 51, 46, 117, 13, 215, 81, 17, 139, 247, 197, 171, 95, 173, 65, 137, 178, 68, 111, 95, 101, 41, 72, 214, 169, 197, 95, 7, 44, 154, 77, 111, 236, 40, 121, 143, 63, 87, 80, 253, 240, 126, 217, 77, 34, 232, 106, 50, 168, 82, 76, 146, 67, 106, 171, 25, 132, 93, 45, 105}; +static const uint8_t byRSExp68[] = {247, 159, 223, 33, 224, 93, 77, 70, 90, 160, 32, 254, 43, 150, 84, 101, 190, 205, 133, 52, 60, 202, 165, 220, 203, 151, 93, 84, 15, 84, 253, 173, 160, 89, 227, 52, 199, 97, 95, 231, 52, 177, 41, 125, 137, 241, 166, 225, 118, 2, 54, 32, 82, 215, 175, 198, 43, 238, 235, 27, 101, 184, 127, 3, 5, 8, 163, 238}; +static const uint8_t* byRSExp[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, byRSExp7, NULL, NULL, byRSExp10, NULL, NULL, byRSExp13, NULL, byRSExp15, byRSExp16, byRSExp17, byRSExp18, NULL, byRSExp20, NULL, byRSExp22, NULL, byRSExp24, NULL, byRSExp26, NULL, byRSExp28, NULL, byRSExp30, NULL, byRSExp32, NULL, byRSExp34, NULL, byRSExp36, NULL, byRSExp38, NULL, byRSExp40, NULL, byRSExp42, NULL, byRSExp44, NULL, byRSExp46, NULL, byRSExp48, NULL, byRSExp50, NULL, byRSExp52, NULL, byRSExp54, NULL, byRSExp56, NULL, byRSExp58, NULL, byRSExp60, NULL, byRSExp62, NULL, byRSExp64, NULL, byRSExp66, NULL, byRSExp68}; + +static const int nIndicatorLenNumeral[] = {10, 12, 14}; +static const int nIndicatorLenAlphabet[] = {9, 11, 13}; +static const int nIndicatorLen8Bit[] = {8, 16, 16}; + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.c b/hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.c new file mode 100644 index 00000000..9633273e --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.c @@ -0,0 +1,1085 @@ +/* + * Copyright (c) 2010 Psytec Inc. + * Copyright (c) 2012 Alexey Mednyy + * Copyright (c) 2012-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 "qr_encode.h" +#include "qr_consts.h" + +static int m_nLevel; +static int m_nVersion; +static int m_nMaskingNo; +static int m_ncDataCodeWordBit, m_ncAllCodeWord, nEncodeVersion; +static int m_ncDataBlock; +static int m_nSymbleSize; +static int m_nBlockLength[QR_MAX_DATACODEWORD]; +static uint8_t m_byModuleData[QR_MAX_MODULESIZE][QR_MAX_MODULESIZE]; // [x][y] +static uint8_t m_byAllCodeWord[QR_MAX_ALLCODEWORD]; +static uint8_t m_byBlockMode[QR_MAX_DATACODEWORD]; +static uint8_t m_byDataCodeWord[QR_MAX_DATACODEWORD]; +static uint8_t m_byRSWork[QR_MAX_CODEBLOCK]; + +static int IsNumeralData(uint8_t c) +{ + if (c >= '0' && c <= '9') return 1; + return 0; +} + +static int IsAlphabetData(uint8_t c) +{ + if (c >= '0' && c <= '9') return 1; + if (c >= 'A' && c <= 'Z') return 1; + if (c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/' || c == ':') return 1; + return 0; +} + +static uint8_t AlphabetToBinary(uint8_t c) +{ + if (c >= '0' && c <= '9') return (uint8_t)(c - '0'); + if (c >= 'A' && c <= 'Z') return (uint8_t)(c - 'A' + 10); + if (c == ' ') return 36; + if (c == '$') return 37; + if (c == '%') return 38; + if (c == '*') return 39; + if (c == '+') return 40; + if (c == '-') return 41; + if (c == '.') return 42; + if (c == '/') return 43; + return 44; // c == ':' +} + +static int SetBitStream(int nIndex, uint16_t wData, int ncData) +{ + int i; + if (nIndex == -1 || nIndex + ncData > QR_MAX_DATACODEWORD * 8) return -1; + for (i = 0; i < ncData; i++) { + if (wData & (1 << (ncData - i - 1))) { + m_byDataCodeWord[(nIndex + i) / 8] |= 1 << (7 - ((nIndex + i) % 8)); + } + } + return nIndex + ncData; +} + +static int GetBitLength(uint8_t nMode, int ncData, int nVerGroup) +{ + int ncBits = 0; + switch (nMode) { + case QR_MODE_NUMERAL: + ncBits = 4 + nIndicatorLenNumeral[nVerGroup] + (10 * (ncData / 3)); + switch (ncData % 3) { + case 1: + ncBits += 4; + break; + case 2: + ncBits += 7; + break; + default: // case 0: + break; + } + break; + case QR_MODE_ALPHABET: + ncBits = 4 + nIndicatorLenAlphabet[nVerGroup] + (11 * (ncData / 2)) + (6 * (ncData % 2)); + break; + default: // case QR_MODE_8BIT: + ncBits = 4 + nIndicatorLen8Bit[nVerGroup] + (8 * ncData); + break; + } + return ncBits; +} + +static int EncodeSourceData(const char* lpsSource, int ncLength, int nVerGroup) +{ + memset(m_nBlockLength, 0, sizeof(m_nBlockLength)); + int i, j; + // Investigate whether continuing characters (bytes) which mode is what + for (m_ncDataBlock = i = 0; i < ncLength; i++) { + uint8_t byMode; + if (IsNumeralData(lpsSource[i])) { + byMode = QR_MODE_NUMERAL; + } else if (IsAlphabetData(lpsSource[i])) { + byMode = QR_MODE_ALPHABET; + } else { + byMode = QR_MODE_8BIT; + } + if (i == 0) { + m_byBlockMode[0] = byMode; + } + if (m_byBlockMode[m_ncDataBlock] != byMode) { + m_byBlockMode[++m_ncDataBlock] = byMode; + } + m_nBlockLength[m_ncDataBlock]++; + } + m_ncDataBlock++; + + // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // / + // Linked by a sequence of conditional block alphanumeric mode and numeric mode block adjacent + + int ncSrcBits, ncDstBits; // The bit length of the block mode if you have over the original bit length and a single alphanumeric + int nBlock = 0; + + while (nBlock < m_ncDataBlock - 1) { + int ncJoinFront, ncJoinBehind; // Bit length when combined with 8-bit byte block mode before and after + int nJoinPosition = 0; // Block the binding of 8-bit byte mode: combined with the previous -1 = 0 = do not bind, bind behind a = + + // Sort of - "digit alphanumeric" - "or alphanumeric numbers" + if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) || + (m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL)) { + + // If you compare the bit length of alphanumeric characters and a single block mode over the original bit length + ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); + + ncDstBits = GetBitLength(QR_MODE_ALPHABET, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup); + + if (ncSrcBits > ncDstBits) { + // If there is an 8-bit byte block mode back and forth, check whether they favor the binding of + if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) { + // There are 8-bit byte block mode before + ncJoinFront = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock], nVerGroup) + + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); + + if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1], nVerGroup)) { + ncJoinFront = 0; // 8-bit byte and block mode does not bind + } + } else { + ncJoinFront = 0; + } + + if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) { + // There are 8-bit byte mode block behind + ncJoinBehind = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2], nVerGroup); + + if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 2], nVerGroup)) { + ncJoinBehind = 0; // 8-bit byte and block mode does not bind + } + } else { + ncJoinBehind = 0; + } + + if (ncJoinFront != 0 && ncJoinBehind != 0) { + // If there is a 8-bit byte block mode has priority both before and after the way the data length is shorter + nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1; + } else { + nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0); + } + + if (nJoinPosition != 0) { + // Block the binding of 8-bit byte mode + if (nJoinPosition == -1) { + m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; + + // The subsequent shift + for (i = nBlock; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + } else { + m_byBlockMode[nBlock + 1] = QR_MODE_8BIT; + m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; + + // The subsequent shift + for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + } + + m_ncDataBlock--; + } else { + // Block mode integrated into a single alphanumeric string of numbers and alphanumeric + + if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET) { + // Binding mode of the block followed by alphanumeric block attempts to join + m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; + + // The subsequent shift + for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + + m_ncDataBlock--; + } + + m_byBlockMode[nBlock] = QR_MODE_ALPHABET; + m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1]; + + // The subsequent shift + for (i = nBlock + 1; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + + m_ncDataBlock--; + + if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET) { + + // Combined mode of alphanumeric block before the block bound + m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; + + // The subsequent shift + for (i = nBlock; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + + m_ncDataBlock--; + } + } + + continue; + // Re-examine the block of the current position + } + } + + nBlock++; // Investigate the next block + } + + // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // / + // 8-bit byte block mode over the short block mode to continuous + + nBlock = 0; + + while (nBlock < m_ncDataBlock - 1) { + ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); + + ncDstBits = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup); + + // If there is a 8-bit byte block mode before, subtract the duplicate indicator minute + if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) { + ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]); + } + + // If there is a block behind the 8-bit byte mode, subtract the duplicate indicator minute + if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) { + ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]); + } + + if (ncSrcBits > ncDstBits) { + if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) { + // 8-bit byte mode coupling block in front of the block to join + m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; + + // The subsequent shift + for (i = nBlock; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + + m_ncDataBlock--; + nBlock--; + } + + if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) { + // 8-bit byte mode coupling block at the back of the block to join + m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; + + // The subsequent shift + for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + + m_ncDataBlock--; + } + + m_byBlockMode[nBlock] = QR_MODE_8BIT; + m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1]; + + // The subsequent shift + for (i = nBlock + 1; i < m_ncDataBlock - 1; i++) { + m_byBlockMode[i] = m_byBlockMode[i + 1]; + m_nBlockLength[i] = m_nBlockLength[i + 1]; + } + + m_ncDataBlock--; + + // Re-examination in front of the block bound + if (nBlock >= 1) { + nBlock--; + } + + continue; + } + + nBlock++;// Investigate the next block + + } + + // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // / + // Mosquito bit array + int ncComplete = 0; // Data pre-processing counter + + uint16_t wBinCode; + + m_ncDataCodeWordBit = 0;// Bit counter processing unit + + memset(m_byDataCodeWord, 0, sizeof(m_byDataCodeWord)); + + for (i = 0; i < m_ncDataBlock && m_ncDataCodeWordBit != -1; i++) { + if (m_byBlockMode[i] == QR_MODE_NUMERAL) { + // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // / + // Numeric mode + // Indicator (0001b) + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 1, 4); + + // Set number of characters + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenNumeral[nVerGroup]); + + // Save the bit string + for (j = 0; j < m_nBlockLength[i]; j += 3) { + if (j < m_nBlockLength[i] - 2) { + wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 100) + + ((lpsSource[ncComplete + j + 1] - '0') * 10) + + (lpsSource[ncComplete + j + 2] - '0')); + + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 10); + } else + if (j == m_nBlockLength[i] - 2) { + + // 2 bytes fraction + wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 10) + + (lpsSource[ncComplete + j + 1] - '0')); + + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 7); + } else + if (j == m_nBlockLength[i] - 1) { + + // A fraction of bytes + wBinCode = (uint16_t)(lpsSource[ncComplete + j] - '0'); + + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 4); + } + } + + ncComplete += m_nBlockLength[i]; + } + + else + if (m_byBlockMode[i] == QR_MODE_ALPHABET) { + // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // / + // Alphanumeric mode + // Mode indicator (0010b) + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 2, 4); + + // Set number of characters + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenAlphabet[nVerGroup]); + + // Save the bit string + for (j = 0; j < m_nBlockLength[i]; j += 2) { + if (j < m_nBlockLength[i] - 1) { + wBinCode = (uint16_t)((AlphabetToBinary(lpsSource[ncComplete + j]) * 45) + + AlphabetToBinary(lpsSource[ncComplete + j + 1])); + + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 11); + } else { + // A fraction of bytes + wBinCode = (uint16_t)AlphabetToBinary(lpsSource[ncComplete + j]); + + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 6); + } + } + + ncComplete += m_nBlockLength[i]; + } + + else { // (m_byBlockMode[i] == QR_MODE_8BIT) + // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // / + // 8-bit byte mode + + // Mode indicator (0100b) + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 4, 4); + + // Set number of characters + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLen8Bit[nVerGroup]); + + // Save the bit string + for (j = 0; j < m_nBlockLength[i]; j++) { + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)lpsSource[ncComplete + j], 8); + } + + ncComplete += m_nBlockLength[i]; + } + } + + return (m_ncDataCodeWordBit != -1); +} + +// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // / +// APPLICATIONS: To get the bit length +// Args: data mode type, data length, group version (model number) +// Returns: data bit length + +static int GetEncodeVersion(int nVersion, const char* lpsSource, int ncLength) +{ + int nVerGroup = nVersion >= 27 ? QR_VERSION_L : (nVersion >= 10 ? QR_VERSION_M : QR_VERSION_S); + int i, j; + + for (i = nVerGroup; i <= QR_VERSION_L; i++) { + if (EncodeSourceData(lpsSource, ncLength, i)) { + if (i == QR_VERSION_S) { + for (j = 1; j <= 9; j++) { + if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) { + return j; + } + } + } +#if QR_MAX_VERSION >= QR_VERSION_M + else + if (i == QR_VERSION_M) { + for (j = 10; j <= 26; j++) { + if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) { + return j; + } + } + } +#endif +#if QR_MAX_VERSION >= QR_VERSION_L + else + if (i == QR_VERSION_L) { + for (j = 27; j <= 40; j++) { + if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) { + return j; + } + } + } +#endif + } + } + + return 0; +} + +static void GetRSCodeWord(uint8_t* lpbyRSWork, int ncDataCodeWord, int ncRSCodeWord) +{ + int i, j; + + for (i = 0; i < ncDataCodeWord ; i++) { + if (lpbyRSWork[0] != 0) { + uint8_t nExpFirst = byIntToExp[lpbyRSWork[0]]; // Multiplier coefficient is calculated from the first term + + for (j = 0; j < ncRSCodeWord; j++) { + + // Add (% 255 ^ 255 = 1) the first term multiplier to multiplier sections + uint8_t nExpElement = (uint8_t)(((int)(byRSExp[ncRSCodeWord][j] + nExpFirst)) % 255); + + // Surplus calculated by the exclusive + lpbyRSWork[j] = (uint8_t)(lpbyRSWork[j + 1] ^ byExpToInt[nExpElement]); + } + + // Shift the remaining digits + for (j = ncRSCodeWord; j < ncDataCodeWord + ncRSCodeWord - 1; j++) { + lpbyRSWork[j] = lpbyRSWork[j + 1]; + } + } else { + // Shift the remaining digits + for (j = 0; j < ncDataCodeWord + ncRSCodeWord - 1; j++) { + lpbyRSWork[j] = lpbyRSWork[j + 1]; + } + } + } +} + +static void SetFinderPattern(int x, int y) +{ + static const uint8_t byPattern[] = { 0x7f, // 1111111b + 0x41, // 1000001b + 0x5d, // 1011101b + 0x5d, // 1011101b + 0x5d, // 1011101b + 0x41, // 1000001b + 0x7f}; // 1111111b + int i, j; + + for (i = 0; i < 7; i++) { + for (j = 0; j < 7; j++) { + m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (6 - j))) ? '\x30' : '\x20'; + } + } +} + +static void SetVersionPattern(void) +{ + int i, j; + + if (m_nVersion <= 6) { + return; + } + + int nVerData = m_nVersion << 12; + + // Calculated bit remainder + + for (i = 0; i < 6; i++) { + if (nVerData & (1 << (17 - i))) { + nVerData ^= (0x1f25 << (5 - i)); + } + } + + nVerData += m_nVersion << 12; + + for (i = 0; i < 6; i++) { + for (j = 0; j < 3; j++) { + m_byModuleData[m_nSymbleSize - 11 + j][i] = m_byModuleData[i][m_nSymbleSize - 11 + j] = + (nVerData & (1 << (i * 3 + j))) ? '\x30' : '\x20'; + } + } +} + +static void SetAlignmentPattern(int x, int y) +{ + static const uint8_t byPattern[] = { 0x1f, // 11111b + 0x11, // 10001b + 0x15, // 10101b + 0x11, // 10001b + 0x1f}; // 11111b + int i, j; + + if (m_byModuleData[x][y] & 0x20) { + return; // Excluded due to overlap with the functional module + } + + x -= 2; y -= 2; // Convert the coordinates to the upper left corner + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (4 - j))) ? '\x30' : '\x20'; + } + } +} + +static void SetFunctionModule(void) +{ + int i, j; + + // Position detection pattern + SetFinderPattern(0, 0); + SetFinderPattern(m_nSymbleSize - 7, 0); + SetFinderPattern(0, m_nSymbleSize - 7); + + // Separator pattern position detection + for (i = 0; i < 8; i++) { + m_byModuleData[i][7] = m_byModuleData[7][i] = '\x20'; + m_byModuleData[m_nSymbleSize - 8][i] = m_byModuleData[m_nSymbleSize - 8 + i][7] = '\x20'; + m_byModuleData[i][m_nSymbleSize - 8] = m_byModuleData[7][m_nSymbleSize - 8 + i] = '\x20'; + } + + // Registration as part of a functional module position description format information + for (i = 0; i < 9; i++) { + m_byModuleData[i][8] = m_byModuleData[8][i] = '\x20'; + } + + for (i = 0; i < 8; i++) { + m_byModuleData[m_nSymbleSize - 8 + i][8] = m_byModuleData[8][m_nSymbleSize - 8 + i] = '\x20'; + } + + // Version information pattern + SetVersionPattern(); + + // Pattern alignment + for (i = 0; i < QR_VersonInfo[m_nVersion].ncAlignPoint; i++) { + SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], 6); + SetAlignmentPattern(6, QR_VersonInfo[m_nVersion].nAlignPoint[i]); + + for (j = 0; j < QR_VersonInfo[m_nVersion].ncAlignPoint; j++) { + SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], QR_VersonInfo[m_nVersion].nAlignPoint[j]); + } + } + + // Timing pattern + for (i = 8; i <= m_nSymbleSize - 9; i++) { + m_byModuleData[i][6] = (i % 2) == 0 ? '\x30' : '\x20'; + m_byModuleData[6][i] = (i % 2) == 0 ? '\x30' : '\x20'; + } +} + +static void SetCodeWordPattern(void) +{ + int x = m_nSymbleSize; + int y = m_nSymbleSize - 1; + + int nCoef_x = 1; // placement orientation axis x + int nCoef_y = 1; // placement orientation axis y + + int i, j; + + for (i = 0; i < m_ncAllCodeWord; i++) { + for (j = 0; j < 8; j++) { + do { + x += nCoef_x; + nCoef_x *= -1; + + if (nCoef_x < 0) { + y += nCoef_y; + + if (y < 0 || y == m_nSymbleSize) { + y = (y < 0) ? 0 : m_nSymbleSize - 1; + nCoef_y *= -1; + + x -= 2; + + if (x == 6) { // Timing pattern + x--; + } + } + } + } while (m_byModuleData[x][y] & 0x20); // Exclude a functional module + + m_byModuleData[x][y] = (m_byAllCodeWord[i] & (1 << (7 - j))) ? '\x02' : '\x00'; + + } + } +} + +static void SetMaskingPattern(int nPatternNo) +{ + int i, j; + + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize; j++) { + if (! (m_byModuleData[j][i] & 0x20)) { // Exclude a functional module + int bMask; + + switch (nPatternNo) { + case 0: + bMask = ((i + j) % 2 == 0); + break; + case 1: + bMask = (i % 2 == 0); + break; + case 2: + bMask = (j % 3 == 0); + break; + case 3: + bMask = ((i + j) % 3 == 0); + break; + case 4: + bMask = (((i / 2) + (j / 3)) % 2 == 0); + break; + case 5: + bMask = (((i * j) % 2) + ((i * j) % 3) == 0); + break; + case 6: + bMask = ((((i * j) % 2) + ((i * j) % 3)) % 2 == 0); + break; + default: // case 7: + bMask = ((((i * j) % 3) + ((i + j) % 2)) % 2 == 0); + break; + } + + m_byModuleData[j][i] = (uint8_t)((m_byModuleData[j][i] & 0xfe) | (((m_byModuleData[j][i] & 0x02) > 1) ^ bMask)); + } + } + } +} + +static void SetFormatInfoPattern(int nPatternNo) +{ + int nFormatInfo; + int i; + switch (m_nLevel) { + case QR_LEVEL_L: + nFormatInfo = 0x08; // 01nnnb + break; + case QR_LEVEL_M: + nFormatInfo = 0x00; // 00nnnb + break; + case QR_LEVEL_Q: + nFormatInfo = 0x18; // 11nnnb + break; + default: // case QR_LEVEL_H: + nFormatInfo = 0x10; // 10nnnb + break; + } + nFormatInfo += nPatternNo; + int nFormatData = nFormatInfo << 10; + // Calculated bit remainder + for (i = 0; i < 5; i++) { + if (nFormatData & (1 << (14 - i))) { + nFormatData ^= (0x0537 << (4 - i)); // 10100110111b + } + } + nFormatData += nFormatInfo << 10; + // Masking + nFormatData ^= 0x5412; // 101010000010010b + // Position detection patterns located around the upper left + for (i = 0; i <= 5; i++) { + m_byModuleData[8][i] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; + } + m_byModuleData[8][7] = (nFormatData & (1 << 6)) ? '\x30' : '\x20'; + m_byModuleData[8][8] = (nFormatData & (1 << 7)) ? '\x30' : '\x20'; + m_byModuleData[7][8] = (nFormatData & (1 << 8)) ? '\x30' : '\x20'; + for (i = 9; i <= 14; i++) { + m_byModuleData[14 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; + } + // Position detection patterns located under the upper right corner + for (i = 0; i <= 7; i++) { + m_byModuleData[m_nSymbleSize - 1 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; + } + // Right lower left position detection patterns located + m_byModuleData[8][m_nSymbleSize - 8] = '\x30'; // Module fixed dark + for (i = 8; i <= 14; i++) { + m_byModuleData[8][m_nSymbleSize - 15 + i] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; + } +} + +static int CountPenalty(void) +{ + int nPenalty = 0; + int i, j, k; + + // Column of the same color adjacent module + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize - 4; j++) { + int nCount = 1; + + for (k = j + 1; k < m_nSymbleSize; k++) { + if (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][k] & 0x11) == 0)) { + nCount++; + } else { + break; + } + } + + if (nCount >= 5) { + nPenalty += 3 + (nCount - 5); + } + + j = k - 1; + } + } + + // Adjacent module line of the same color + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize - 4; j++) { + int nCount = 1; + + for (k = j + 1; k < m_nSymbleSize; k++) { + if (((m_byModuleData[j][i] & 0x11) == 0) == ((m_byModuleData[k][i] & 0x11) == 0)) { + nCount++; + } else { + break; + } + } + + if (nCount >= 5) { + nPenalty += 3 + (nCount - 5); + } + + j = k - 1; + } + } + + // Modules of the same color block (2 ~ 2) + for (i = 0; i < m_nSymbleSize - 1; i++) { + for (j = 0; j < m_nSymbleSize - 1; j++) { + if ((((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j] & 0x11) == 0)) && + (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i] [j + 1] & 0x11) == 0)) && + (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j + 1] & 0x11) == 0))) { + nPenalty += 3; + } + } + } + + // Pattern (dark dark: light: dark: light) ratio 1:1:3:1:1 in the same column + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize - 6; j++) { + if (((j == 0) || (! (m_byModuleData[i][j - 1] & 0x11))) && + ( m_byModuleData[i][j ] & 0x11) && + (! (m_byModuleData[i][j + 1] & 0x11)) && + ( m_byModuleData[i][j + 2] & 0x11) && + ( m_byModuleData[i][j + 3] & 0x11) && + ( m_byModuleData[i][j + 4] & 0x11) && + (! (m_byModuleData[i][j + 5] & 0x11)) && + ( m_byModuleData[i][j + 6] & 0x11) && + ((j == m_nSymbleSize - 7) || (! (m_byModuleData[i][j + 7] & 0x11)))) { + + // Clear pattern of four or more before or after + if (((j < 2 || ! (m_byModuleData[i][j - 2] & 0x11)) && + (j < 3 || ! (m_byModuleData[i][j - 3] & 0x11)) && + (j < 4 || ! (m_byModuleData[i][j - 4] & 0x11))) || + ((j >= m_nSymbleSize - 8 || ! (m_byModuleData[i][j + 8] & 0x11)) && + (j >= m_nSymbleSize - 9 || ! (m_byModuleData[i][j + 9] & 0x11)) && + (j >= m_nSymbleSize - 10 || ! (m_byModuleData[i][j + 10] & 0x11)))) { + nPenalty += 40; + } + } + } + } + + // Pattern (dark dark: light: dark: light) in the same line ratio 1:1:3:1:1 + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize - 6; j++) { + if (((j == 0) || (! (m_byModuleData[j - 1][i] & 0x11))) && + ( m_byModuleData[j ] [i] & 0x11) && + (! (m_byModuleData[j + 1][i] & 0x11)) && + ( m_byModuleData[j + 2][i] & 0x11) && + ( m_byModuleData[j + 3][i] & 0x11) && + ( m_byModuleData[j + 4][i] & 0x11) && + (! (m_byModuleData[j + 5][i] & 0x11)) && + ( m_byModuleData[j + 6][i] & 0x11) && + ((j == m_nSymbleSize - 7) || (! (m_byModuleData[j + 7][i] & 0x11)))) { + + // Clear pattern of four or more before or after + if (((j < 2 || ! (m_byModuleData[j - 2][i] & 0x11)) && + (j < 3 || ! (m_byModuleData[j - 3][i] & 0x11)) && + (j < 4 || ! (m_byModuleData[j - 4][i] & 0x11))) || + ((j >= m_nSymbleSize - 8 || ! (m_byModuleData[j + 8][i] & 0x11)) && + (j >= m_nSymbleSize - 9 || ! (m_byModuleData[j + 9][i] & 0x11)) && + (j >= m_nSymbleSize - 10 || ! (m_byModuleData[j + 10][i] & 0x11)))) { + nPenalty += 40; + } + } + } + } + + // The proportion of modules for the entire dark + int nCount = 0; + + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize; j++) { + if (! (m_byModuleData[i][j] & 0x11)) { + nCount++; + } + } + } + + nPenalty += (abs(50 - ((nCount * 100) / (m_nSymbleSize * m_nSymbleSize))) / 5) * 10; + + return nPenalty; +} + +static void FormatModule(void) +{ + int i, j; + + memset(m_byModuleData, 0, sizeof(m_byModuleData)); + + // Function module placement + SetFunctionModule(); + + // Data placement + SetCodeWordPattern(); + + if (m_nMaskingNo == -1) { + + // Select the best pattern masking + m_nMaskingNo = 0; + + SetMaskingPattern(m_nMaskingNo); // Masking + SetFormatInfoPattern(m_nMaskingNo); // Placement pattern format information + + int nMinPenalty = CountPenalty(); + + for (i = 1; i <= 7; i++) { + SetMaskingPattern(i); // Masking + SetFormatInfoPattern(i); // Placement pattern format information + + int nPenalty = CountPenalty(); + + if (nPenalty < nMinPenalty) { + nMinPenalty = nPenalty; + m_nMaskingNo = i; + } + } + } + + SetMaskingPattern(m_nMaskingNo); // Masking + SetFormatInfoPattern(m_nMaskingNo); // Placement pattern format information + + // The module pattern converted to a Boolean value + + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize; j++) { + m_byModuleData[i][j] = (uint8_t)((m_byModuleData[i][j] & 0x11) != 0); + } + } +} + +static void putBitToPos(uint32_t pos, int bw, uint8_t *bits) +{ + if (bw == 0) return; + uint32_t tmp; + uint32_t bitpos[8] = {128, 64, 32, 16, 8, 4, 2, 1}; + if (pos % 8 == 0) { + tmp = (pos / 8) - 1; + bits[tmp] = bits[tmp] ^ bitpos[7]; + } else { + tmp = pos / 8; + bits[tmp] = bits[tmp] ^ bitpos[pos % 8 - 1]; + } +} + +int qr_encode(int level, int version, const char *source, size_t source_len, uint8_t *result) +{ + int i, j; + const bool auto_extent = 0; + m_nLevel = level; + m_nMaskingNo = -1; + + memset(result, 0, QR_MAX_BITDATA); + // If the data length is not specified, acquired by lstrlen + size_t ncLength = source_len > 0 ? source_len : strlen(source); + + if (ncLength == 0) { + return -1; // No data + } + + // Check version (model number) + + nEncodeVersion = GetEncodeVersion(version, source, ncLength); + + if (nEncodeVersion == 0) { + return -1; // Over-capacity + } + if (version == 0) { + // Auto Part + m_nVersion = nEncodeVersion; + } else { + if (nEncodeVersion <= version) { + m_nVersion = version; + } else { + if (auto_extent) { + m_nVersion = nEncodeVersion; // Automatic extended version (model number) + } else { + return -1; // Over-capacity + } + } + } + + // Terminator addition code "0000" + int ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[level]; + + int ncTerminater = (ncDataCodeWord * 8) - m_ncDataCodeWordBit; + if (ncTerminater < 4) { + ncTerminater = 4; + } + + if (ncTerminater > 0) { + m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 0, ncTerminater); + } + + // Additional padding code "11101100, 00010001" + uint8_t byPaddingCode = 0xec; + + for (i = (m_ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; i++) { + m_byDataCodeWord[i] = byPaddingCode; + + byPaddingCode = (uint8_t)(byPaddingCode == 0xec ? 0x11 : 0xec); + } + + // Calculated the total clear area code word + m_ncAllCodeWord = QR_VersonInfo[m_nVersion].ncAllCodeWord; + + memset(m_byAllCodeWord, 0, sizeof(m_byAllCodeWord)); + + int nDataCwIndex = 0; // Position data processing code word + + // Division number data block + int ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncRSBlock; + + int ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncRSBlock; + + int ncBlockSum = ncBlock1 + ncBlock2; + + int nBlockNo = 0; // Block number in the process + + // The number of data code words by block + int ncDataCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncDataCodeWord; + + int ncDataCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncDataCodeWord; + + // Code word interleaving data placement + for (i = 0; i < ncBlock1; i++) { + for (j = 0; j < ncDataCw1; j++) { + m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++]; + } + + nBlockNo++; + } + + for (i = 0; i < ncBlock2; i++) { + for (j = 0; j < ncDataCw2; j++) { + if (j < ncDataCw1) { + m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++]; + } else { + // 2 minute fraction block placement event + m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] = m_byDataCodeWord[nDataCwIndex++]; + } + } + nBlockNo++; + } + + // RS code words by block number (currently the same number) + int ncRSCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncAllCodeWord - ncDataCw1; + int ncRSCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncAllCodeWord - ncDataCw2; + + // RS code word is calculated + + nDataCwIndex = 0; + nBlockNo = 0; + + for (i = 0; i < ncBlock1; i++) { + memset(m_byRSWork, 0, sizeof(m_byRSWork)); + memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw1); + GetRSCodeWord(m_byRSWork, ncDataCw1, ncRSCw1); + // RS code word placement + for (j = 0; j < ncRSCw1; j++) { + m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j]; + } + nDataCwIndex += ncDataCw1; + nBlockNo++; + } + + for (i = 0; i < ncBlock2; i++) { + memset(m_byRSWork, 0, sizeof(m_byRSWork)); + memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw2); + GetRSCodeWord(m_byRSWork, ncDataCw2, ncRSCw2); + // RS code word placement + for (j = 0; j < ncRSCw2; j++) { + m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j]; + } + nDataCwIndex += ncDataCw2; + nBlockNo++; + } + + m_nSymbleSize = m_nVersion * 4 + 17; + + // Module placement + FormatModule(); + + for (i = 0; i < m_nSymbleSize; i++) { + for (j = 0; j < m_nSymbleSize; j++) { + if (!m_byModuleData[i][j]) { + putBitToPos((j * m_nSymbleSize) + i + 1, 0, result); + } else { + putBitToPos((j * m_nSymbleSize) + i + 1, 1, result); + } + } + } + return m_nSymbleSize; +} diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.h b/hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.h new file mode 100644 index 00000000..a792b21a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/qr_encode.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2010 Psytec Inc. + * Copyright (c) 2012 Alexey Mednyy + * Copyright (c) 2012 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 __QR_ENCODE_H__ +#define __QR_ENCODE_H__ + +#include +#include + +// Constants + +// Error correction level +#define QR_LEVEL_L 0 // 7% of codewords can be restored +#define QR_LEVEL_M 1 // 15% of codewords can be restored +#define QR_LEVEL_Q 2 // 25% of codewords can be restored +#define QR_LEVEL_H 3 // 30% of codewords can be restored + +// Data Mode +#define QR_MODE_NUMERAL 0 // numbers +#define QR_MODE_ALPHABET 1 // alphanumberic +#define QR_MODE_8BIT 2 // rest + +// Group version (Model number) +#define QR_VERSION_S 0 // 1 - 9 (module 21 - 53) +#define QR_VERSION_M 1 // 10 - 26 (module 57 - 121) +#define QR_VERSION_L 2 // 27 - 40 (module 125 - 177) + +#ifndef QR_MAX_VERSION +#define QR_MAX_VERSION QR_VERSION_L +#endif + +// Length constants + +#if QR_MAX_VERSION == QR_VERSION_S +#define QR_MAX_MODULESIZE (9 * 4 + 17) // Maximum number of modules in a side +#define QR_MAX_ALLCODEWORD 292 // Maximum total number of code words +#define QR_MAX_DATACODEWORD 232 // Maximum data word code +#endif + +#if QR_MAX_VERSION == QR_VERSION_M +#define QR_MAX_MODULESIZE (26 * 4 + 17) // Maximum number of modules in a side +#define QR_MAX_ALLCODEWORD 1706 // Maximum total number of code words +#define QR_MAX_DATACODEWORD 1370 // Maximum data word code +#endif + +#if QR_MAX_VERSION == QR_VERSION_L +#define QR_MAX_MODULESIZE (40 * 4 + 17) // Maximum number of modules in a side +#define QR_MAX_ALLCODEWORD 3706 // Maximum total number of code words +#define QR_MAX_DATACODEWORD 2956 // Maximum data word code +#endif + +#define QR_MAX_BITDATA ((QR_MAX_MODULESIZE * QR_MAX_MODULESIZE + 7) / 8) // Maximum size of bit data +#define QR_MAX_CODEBLOCK 153 // Maximum number of block data code word (including RS code word) + +// +// * level - error correction level, use QR_LEVEL_? macros +// * version - version of the code (1-40), use 0 for autodetection +// * source - source data +// * source_len - length of the source data, use 0 when passing zero-terminated string +// * result - array to write, writes to bits +// +// * function returns the size of the square side +// +int qr_encode(int level, int version, const char *source, size_t source_len, uint8_t *result); + +#endif diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/test.c b/hardware-wallet/firmware/vendor/trezor-qrenc/test.c new file mode 100644 index 00000000..51a4739f --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/test.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 "qr_encode.h" + +int main(void) +{ + int side, i, j, a; + uint8_t bitdata[QR_MAX_BITDATA]; + char str[2048]; + + printf("Enter string: "); + if (!fgets(str, sizeof(str), stdin)) { + return 1; + } + // remove newline + if (str[strlen(str) - 1] == '\n') { + str[strlen(str) - 1] = 0; + } + + side = qr_encode(QR_LEVEL_M, 0, str, 0, bitdata); + + printf("side: %d\n", side); + + for (i = 0; i < side + 2; i++) printf("██"); + printf("\n"); + for (i = 0; i < side; i++) { + printf("██"); + for (j = 0; j < side; j++) { + a = j * side + i; + printf((bitdata[a / 8] & (1 << (7 - a % 8))) ? " " : "██"); + } + printf("██"); + printf("\n"); + } + for (i = 0; i < side + 2; i++) printf("██"); + printf("\n"); + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/test_arg.c b/hardware-wallet/firmware/vendor/trezor-qrenc/test_arg.c new file mode 100644 index 00000000..f2c28cf1 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/test_arg.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 "qr_encode.h" + +/** + * The same as test.c, only it reads from the first argument + * and prints 0s and 1s instead of picture. + * + * It's used for compiling to JavaScript, because we can set up + * argument and read 1/0s more easily + */ +int main(int argc, char **argv) +{ + int side, i, j, a; + uint8_t bitdata[QR_MAX_BITDATA]; + + if (argc<2){ + printf("1"); + return 1; + } + + char *str=argv[1]; + + side = qr_encode(QR_LEVEL_M, 0, str, 0, bitdata); + + + //for (i = 0; i < side + 2; i++) printf("1"); + for (i = 0; i < side; i++) { + // printf("1"); + for (j = 0; j < side; j++) { + a = i * side + j; + printf((bitdata[a / 8] & (1 << (7 - a % 8))) ? "0" : "1"); + } + // printf("1"); + } + //for (i = 0; i < side + 2; i++) printf("1"); + + return 0; +} diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/tests.c b/hardware-wallet/firmware/vendor/trezor-qrenc/tests.c new file mode 100644 index 00000000..2edfa43a --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/tests.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2012-2014 Pavol Rusnak + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION 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 "tests_results.h" + +#include "qr_encode.h" + +int bitsize(int side) { + return (side * side + 7) / 8; +} + +START_TEST(test_numeral) +{ + int side; + uint8_t bitdata[QR_MAX_BITDATA]; + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_L, 0, "1234567890", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_1, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_M, 0, "1234567890", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_2, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_Q, 0, "1234567890", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_3, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_H, 0, "1234567890", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_4, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_L, 0, "12345678901234567890123456789012345678901234567890", 0, bitdata); + ck_assert_int_eq(side, 25); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_5, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_M, 0, "12345678901234567890123456789012345678901234567890", 0, bitdata); + ck_assert_int_eq(side, 25); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_6, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_Q, 0, "12345678901234567890123456789012345678901234567890", 0, bitdata); + ck_assert_int_eq(side, 29); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_7, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_H, 0, "12345678901234567890123456789012345678901234567890", 0, bitdata); + ck_assert_int_eq(side, 29); + ck_assert_int_eq(memcmp(bitdata, RESULT_NUMERAL_8, bitsize(side)), 0); +} +END_TEST + +START_TEST(test_alphabet) +{ + int side; + unsigned char bitdata[QR_MAX_BITDATA]; + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_L, 0, "test", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_1, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_M, 0, "test", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_2, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_Q, 0, "test", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_3, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_H, 0, "test", 0, bitdata); + ck_assert_int_eq(side, 21); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_4, bitsize(side)), 0); + +#if QR_MAX_VERSION >= QR_VERSION_M + const char *lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras at risus sodales, rhoncus arcu eu, accumsan augue. Mauris a mauris et ante porta eleifend. Sed condimentum metus vitae tortor bibendum, et scelerisque quam placerat. Nam at sapien lacus. Proin magna ipsum, dapibus non dignissim a, posuere vitae nulla. Donec pretium odio sit amet lorem interdum, nec ullamcorper diam iaculis. Mauris at est sit amet purus venenatis pretium vitae sed magna."; + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_L, 0, lipsum, 0, bitdata); + ck_assert_int_eq(side, 73); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_5, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_M, 0, lipsum, 0, bitdata); + ck_assert_int_eq(side, 85); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_6, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_Q, 0, lipsum, 0, bitdata); + ck_assert_int_eq(side, 97); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_7, bitsize(side)), 0); + + memset(bitdata, sizeof(bitdata), 0); + side = qr_encode(QR_LEVEL_H, 0, lipsum, 0, bitdata); + ck_assert_int_eq(side, 109); + ck_assert_int_eq(memcmp(bitdata, RESULT_ALPHA_8, bitsize(side)), 0); +#endif +} +END_TEST + + +// define test suite and cases +Suite *test_suite(void) +{ + Suite *s = suite_create("microqrcode"); + TCase *tc; + + tc = tcase_create("qr"); + tcase_add_test(tc, test_numeral); + tcase_add_test(tc, test_alphabet); + suite_add_tcase(s, tc); + + return s; +} + +// run suite +int main(void) +{ + int number_failed; + Suite *s = test_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return number_failed; +} diff --git a/hardware-wallet/firmware/vendor/trezor-qrenc/tests_results.h b/hardware-wallet/firmware/vendor/trezor-qrenc/tests_results.h new file mode 100644 index 00000000..6f66f526 --- /dev/null +++ b/hardware-wallet/firmware/vendor/trezor-qrenc/tests_results.h @@ -0,0 +1,16 @@ +#define RESULT_NUMERAL_1 "\xfe\xcb\xfc\x10\x90\x6e\xa8\xbb\x75\x95\xdb\xa9\x2e\xc1\x11\x07\xfa\xaf\xe0\x02\x00\xf2\xa4\xeb\xa8\x4b\xc5\x9c\x88\x3b\x49\x12\xbe\x91\x00\x49\x27\xf8\x13\xf0\x41\x25\xba\x52\x0d\xd7\x26\xae\xb2\x59\x05\x24\xbf\xec\x49\x00" +#define RESULT_NUMERAL_2 "\xfe\xf3\xfc\x15\x50\x6e\x9a\xbb\x75\xe5\xdb\xa7\x2e\xc1\x11\x07\xfa\xaf\xe0\x1e\x00\xb7\x22\x5c\xa7\x4b\xcc\x8c\x88\x0a\x89\x12\xa8\x91\x00\x79\x27\xfb\x93\xf0\x51\x25\xba\x12\x0d\xd7\x26\xae\xb2\x59\x04\x64\xbf\xe8\x49\x00" +#define RESULT_NUMERAL_3 "\xfe\x73\xfc\x11\x90\x6e\x96\xbb\x75\xf5\xdb\xa5\x2e\xc1\x59\x07\xfa\xaf\xe0\x18\x00\x62\x2b\x44\xc2\x42\xc8\xab\xe5\x73\xe0\x3a\xa0\x7c\x80\x50\x03\xf8\x5e\x50\x4b\x01\xba\x67\xbd\xd3\x02\x2e\xaf\xef\x05\x80\x2f\xe3\xff\x80" +#define RESULT_NUMERAL_4 "\xfe\xb3\xfc\x10\x10\x6e\xb0\xbb\x74\x35\xdb\xae\xae\xc1\x39\x07\xfa\xaf\xe0\x12\x00\x06\x0a\xae\x83\xa7\xb5\xc7\xd2\x41\xb0\x73\xba\x5c\x80\x5e\x13\xf8\xad\x30\x57\x54\xba\x19\x65\xd3\x53\x2e\x99\x6f\x04\x34\x6f\xe4\x52\x00" +#define RESULT_NUMERAL_5 "\xfe\x29\xbf\xc1\x2a\x90\x6e\xaa\x2b\xb7\x4a\xf5\xdb\xa2\xc2\xec\x12\xad\x07\xfa\xaa\xfe\x01\xa6\x00\xef\xae\x62\x38\x28\x1a\xef\xaa\xa7\x2d\x2a\x4c\x9b\x22\xe0\xf9\x2a\x87\xc6\xee\xa0\xd8\xba\x2c\x79\xa3\x2b\xfb\x80\x4a\x46\xbf\xba\xeb\x10\x52\x91\xab\xae\xaf\xf5\xd2\xa8\x0a\xea\xa9\x1b\x05\xab\x7c\xfe\x8b\x66\x80" +#define RESULT_NUMERAL_6 "\xfe\xca\x3f\xc1\x55\x10\x6e\x93\xab\xb7\x53\x75\xdb\xa7\xca\xec\x10\xe1\x07\xfa\xaa\xfe\x01\x58\x00\xb7\x28\x25\xf8\xbe\x22\x2e\xf2\x9f\xc2\x98\x74\x74\x39\xd8\x1a\x05\xbf\x25\x7b\x98\x3b\x20\x94\x9a\x23\x93\xf8\x00\x72\xc5\x3f\xaa\x2a\x90\x56\x71\x2b\xa6\x4f\xfd\xd6\x4b\x86\xeb\xca\x95\x04\x88\xf2\xfe\xe8\xe8\x80" +#define RESULT_NUMERAL_7 "\xfe\x48\xa3\xfc\x14\x5c\x50\x6e\xbd\xac\xbb\x74\x32\x85\xdb\xa6\x7f\xae\xc1\x19\x01\x07\xfa\xaa\xaf\xe0\x09\x0b\x00\x76\x75\x80\x37\x6a\xa3\x24\x69\xb9\xfb\x5b\x3a\x26\xec\x27\xa7\x64\xfc\x76\xc2\xae\xbf\x68\xe4\x6e\xa2\xbf\xa5\x92\xdf\x2b\x49\x03\xc6\xe6\x93\x60\x9d\x49\xf6\x49\x14\x95\x05\xa7\xc7\xff\x00\x7e\x04\x43\xf8\x09\x2b\x50\x5c\xb3\x1b\xba\x39\x3f\xd5\xd5\x70\x98\x2e\xae\xb7\x83\x05\xae\x0b\x4f\xe0\xaa\x80\x00" +#define RESULT_NUMERAL_8 "\xfe\x0d\xbb\xfc\x16\xc3\xd0\x6e\x98\xb8\xbb\x74\xaa\x45\xdb\xa6\x38\xae\xc1\x44\x95\x07\xfa\xaa\xaf\xe0\x17\xca\x00\x0f\x1c\x2b\x13\xa1\xf1\xee\xdc\xca\xf8\x9d\x6b\xd9\x46\x85\x2b\xdb\x39\x74\x9c\x06\x5e\x69\xda\xb3\xbf\xb2\x3d\x63\x8b\x1a\x9b\x4f\xc9\x1e\xd7\x05\x88\x03\x4c\x69\xa2\x1a\x3f\x67\x6c\xf9\x80\x43\x6c\x77\xfa\xf7\x2b\x90\x58\xc1\x11\xba\xdc\xef\xbd\xd3\x85\x17\x2e\x82\xea\xd7\x04\xfc\x58\x9f\xe0\xff\x5a\x00" +#define RESULT_ALPHA_1 "\xfe\x2b\xfc\x12\x90\x6e\xaa\xbb\x74\xa5\xdb\xa2\xae\xc1\x29\x07\xfa\xaf\xe0\x1a\x00\xef\xae\x26\x6d\xa8\xd6\x92\xbe\xf1\xea\x2b\xa4\xad\x80\x6a\xa7\xfa\xab\x70\x5a\xa2\xba\xca\xdd\xd3\xa8\xae\xaa\xab\x05\xaa\xaf\xee\xab\x80" +#define RESULT_ALPHA_2 "\xfe\xc3\xfc\x15\x50\x6e\x92\xbb\x75\x25\xdb\xa7\x2e\xc1\x01\x07\xfa\xaf\xe0\x12\x00\xb7\x42\x5e\xac\x4b\x7d\xa4\x86\x09\x89\xa9\xa4\x95\x00\x59\x2b\xfb\x93\x90\x59\x2c\xba\x32\x3d\xd4\x26\xae\xa2\x49\x04\x24\x9f\xee\x48\x00" +#define RESULT_ALPHA_3 "\xfe\x93\xfc\x16\x10\x6e\xbc\xbb\x75\x25\xdb\xaa\xae\xc1\x05\x07\xfa\xaf\xe0\x17\x00\x6b\x2a\xfb\x2a\x68\xc5\xb0\xbe\x30\x0a\x2c\x2d\x2d\x80\x5e\xa7\xfb\x8b\x70\x4d\xa2\xba\xaa\xdd\xd3\xa8\xae\xba\xab\x05\x2a\xaf\xe6\xab\x80" +#define RESULT_ALPHA_4 "\xfe\xc3\xfc\x13\x50\x6e\xb2\xbb\x74\xb5\xdb\xae\x2e\xc1\x09\x07\xfa\xaf\xe0\x14\x00\x06\x62\xaa\xa8\x57\x32\xee\xdd\xe8\xfc\xc9\x64\x38\x80\x4b\x1f\xf9\xf5\x50\x5e\x1d\xba\x39\x55\xd1\x03\x2e\x87\xff\x04\x1c\x4f\xe5\xf3\x00" +#define RESULT_ALPHA_5 "\xfe\x0d\x4a\x26\x1c\xfa\xb2\x56\xbf\xc1\x52\xd2\x8d\x37\x83\xb2\x09\x10\x6e\x99\x4b\xcc\xe8\x2f\x73\x65\x0b\xb7\x53\x37\xab\x2f\x06\xbe\x04\x65\xdb\xa5\x1a\x8f\xf1\xd6\xf9\x1f\x5a\xec\x17\xed\x6c\x4b\x3a\x46\xb1\xf1\x07\xfa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xfe\x00\xa4\x81\x15\x47\x71\x97\xeb\x00\xfb\x96\x9e\xfd\x5c\x4f\x96\xe6\xd5\x0a\xa0\x25\x5b\x4e\xf1\x1c\x71\xe1\x13\xb5\xe3\xc9\x7b\xd5\x5d\x0f\x9a\xe1\x3b\x0c\xc8\xf8\xbc\x94\x3e\x7a\x3b\x75\x52\x7d\xb7\x96\x5d\x88\x2a\xbe\xe4\x02\x17\x10\xeb\x51\x02\xcf\x20\x5d\x75\x94\x61\xe9\x17\xd2\xb7\xbb\xb0\x50\x0c\x0d\x09\x09\x17\xe2\xa3\xee\xd0\x1c\x4a\x1c\x75\xd6\xc2\x87\x28\x61\x61\x53\x66\x7d\x48\x25\xb2\xa0\xa8\x49\x4c\x7e\xa5\x5d\x4f\xfb\x79\x97\x84\x9a\xd0\x37\xf4\x3a\x42\x3a\xac\xcb\xcc\xf1\x94\x51\x28\xcf\x7a\x03\xf9\x53\x30\x23\xd0\xd2\x59\xd1\xeb\x0e\xd5\x11\xb8\x58\xd4\xb3\xe7\x61\x70\x1d\x8d\x01\x6d\x17\xe0\xa9\xff\xfa\x1e\xff\x1e\x1f\x98\xe4\xff\x3c\x53\xa5\x47\xc6\xb4\x49\xa4\x46\x22\xb4\x29\x2b\x6f\xc2\xbf\x03\x6b\xf1\x17\xf4\x91\x70\xd7\x19\xfa\x11\x0d\xf9\xb8\x7f\xb1\xe4\xff\xce\x1f\xef\x0b\x4e\x1e\x70\x21\x29\x92\x0b\x30\xbd\x18\x67\x91\xf8\x6b\xb4\xff\x86\xbb\xeb\x29\x99\xab\xba\x17\x20\xf3\xdb\x44\x96\x14\x5c\x7d\x38\x65\x12\xa8\x83\xe1\xe7\x8e\x97\x98\x39\xba\x94\xe1\x82\x48\x19\xc4\x9d\x0d\x7c\x6f\x9c\x24\xda\xd4\xb1\xdd\xfa\x0f\x39\x68\x43\xe5\x27\xc7\xfb\xac\x8d\x2b\xe2\x85\x56\x70\x63\x79\xc6\x47\xa6\x78\xcc\x87\x87\xbd\x09\xd2\xbf\x96\x5a\x7a\x0e\x25\x8b\x6a\x97\x24\xd2\xf7\x7a\x1e\x75\x3d\x7f\x90\x69\x16\xa6\x44\xb1\x6d\x2a\xb7\x98\xe4\xb0\xb5\x8f\x88\xf8\x3d\x92\x9d\x43\xf8\x6c\x3d\xc0\xfa\x56\x36\x0d\x3a\x4f\x21\xfa\xe3\x6f\xc7\xa3\xff\x04\x1f\xf7\x45\xf3\x4c\x7c\x63\x44\xd7\x5c\x61\xaa\x24\x86\xa1\xbb\x2b\x98\x3a\xae\x51\xe9\x15\x19\x41\x51\x1e\xa9\x18\xbf\xd0\x3e\xf9\x7a\x2f\xd0\xcf\xff\x74\xcd\xb4\x47\x02\xba\xdc\x3c\x08\x3f\xb2\xc9\x16\x6e\xc7\xd5\x8b\x75\x67\x3e\x06\xa4\x18\x3e\x41\x7b\x0d\xb5\xae\xeb\xe9\xe0\xa3\x49\xa6\x32\xf1\x8d\x35\x16\xb8\x29\xbd\x07\x14\xb5\xdb\x93\xb3\x76\xb8\x35\xd4\xbc\x84\x39\x87\xa2\x65\x41\x61\x47\xf3\x23\x2b\x36\x36\x43\x5e\x49\xd0\xcd\x6e\xea\x46\x71\x27\x68\x1f\x51\xe1\x09\x3a\xdf\x9f\x26\x1a\xc3\x5d\x4b\xd6\x7a\xaa\xaa\xa6\x70\xbe\x51\xba\xb0\x9b\xf4\x0b\xc0\xd4\x80\x13\xc4\xe2\xf4\xae\x8f\x12\xb8\xa3\x3c\xd2\x04\x27\x59\x08\xfb\x62\xac\x7d\xd8\xdd\x56\x33\xbd\x6b\xcd\x2b\x60\x1f\xa6\xc1\x8a\xba\xbc\xff\x1d\x7f\x90\x29\xfe\x80\x69\x25\x47\x04\x94\x49\xf4\x46\x7f\xb8\x4d\xaa\x7a\xa2\xbf\xca\xab\x70\x46\x34\x71\xd2\x97\x13\x7a\xd1\x1b\xad\x03\xff\xf5\xc2\xfb\x68\xbf\xad\xd4\x65\x11\x38\xa3\xe5\x86\x01\x56\xeb\xd6\x93\x05\xde\x0f\xf0\x1e\x5b\x05\x4a\x4b\x97\xa3\x4e\x53\xab\x41\xfe\xf7\x3f\xe7\x58\x22\x58\x80\x23\x80" +#define RESULT_ALPHA_6 "\xfe\xfe\x25\xc8\x49\xf1\xc4\xc2\xae\xeb\xfc\x15\x92\x5a\x54\x81\x12\x56\xa4\xf1\x90\x6e\x97\x86\x1d\x4b\x36\xb9\x99\xd1\x68\xbb\x75\x9f\x01\xc8\x9e\xeb\x87\x97\x08\x25\xdb\xa6\xdd\x7e\xf9\x60\x57\xfb\x04\x36\x2e\xc1\x3b\xe8\xdc\x59\x78\x34\x61\x7a\x89\x07\xfa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaf\xe0\x15\x58\xed\x17\xc8\x35\x14\x63\x14\x00\xb7\x65\xce\x3f\xf4\x83\x4f\xac\xb2\x5a\x5e\x0f\x43\x76\xa8\x4b\x0e\xf6\x00\xf8\xa1\xa2\xcc\xe0\xc2\xda\x1e\xa5\x29\x07\x8d\x50\x39\x9e\xa9\x7d\x5c\xa7\xb5\xdd\x97\x94\xc6\x37\x6b\x62\x61\xc6\x78\x1a\xd2\x40\x2e\xc2\x40\x63\xe0\x63\x06\x3c\x18\x3d\x96\x6f\x2e\xd1\x16\x85\x4a\xc4\xe7\x01\xd4\x87\x8e\x1a\xfc\xad\x80\xb9\x23\x02\x13\xe0\x62\x6f\x16\x02\xfb\x07\x5c\x3f\xb2\xc9\x9c\xf6\x89\x65\x18\xc7\x8e\x76\x3d\x21\xd7\x51\x76\x83\x27\x54\x99\x84\xc4\xc9\xd1\x3f\xb6\x82\xe9\x77\x04\x3c\x62\x71\x1b\x90\x5f\x37\x61\xd0\xde\xda\x58\x24\x8e\xe9\x05\x6b\x92\x5f\x49\x5c\x06\x90\x6e\x6d\xd3\x18\xe8\xaf\x63\xa7\x51\x81\xac\x51\xf4\xbf\x01\x9d\x3f\xdd\x1f\x89\x03\x52\x47\x24\xf9\x4f\x93\x1e\x18\xf1\xe8\x44\x8a\x69\xaa\x2e\x51\x22\x90\x4a\x70\x30\xcb\x55\x82\xc0\x04\x5c\xcf\x2f\x3f\x65\xaa\xda\x50\xa5\x8e\x35\x02\xd0\xab\x07\xa3\x98\x25\x24\xf1\xa2\x13\xf9\x47\xb2\xfa\x57\xe3\xfb\x82\x33\xfb\x64\x40\xe8\xec\x76\xab\x0c\x56\x18\x3c\x7c\x6a\xb5\x49\x6a\xcc\x7a\xea\xbb\x4b\xea\x71\x16\x43\x6b\x13\x5a\x1d\x19\x7a\x55\x11\x8f\x89\x18\x1f\xd1\x85\x4f\x8c\x1c\x0f\x87\x84\x24\x23\x6e\x6d\xee\x9f\xcc\xa9\xbe\x89\x84\xac\x1c\x6c\x52\x91\x1c\x8b\x93\x41\x99\xd1\xa7\x79\x9a\x95\x12\x6b\x57\x39\xe1\x22\x13\xc3\xad\x87\x0c\x1c\x92\xe1\x16\x16\xcf\x0c\xeb\x69\x86\x17\x85\x64\x82\x0b\x9e\xda\xcf\x12\x57\xd5\x9f\x4b\x94\x8c\x62\x1e\xb3\xa9\xb9\x33\x4a\x1e\x5f\xe0\x73\xef\xfb\xdc\x64\x13\x5d\x54\x90\xab\x27\xf4\x43\x01\xfb\x6b\x22\xb8\x05\xac\x86\x41\x19\x90\x04\xe2\x4a\x25\xa9\x11\x58\xbf\xc2\x22\xde\x93\xf9\x27\x81\xcf\x17\xb1\x40\xa8\x60\xc1\x2c\x8a\x5e\x75\x52\xe1\xe5\xe0\x60\xcb\x52\xbd\xa6\x14\xe9\xe5\xd7\x86\xa9\xdc\x12\x28\xf4\x45\xac\x0b\x90\xf9\x18\x06\x17\xe6\x89\xd7\x11\x15\x84\xa1\xb1\x1c\xdb\x72\x65\xf1\x5d\x50\xa8\x0b\x22\xf1\x6e\x82\xb3\xcd\x68\x32\x63\x39\x93\x99\x38\xdd\x87\xcb\x67\x0c\xad\x6d\xf0\x19\x89\x24\x00\x21\xa3\x87\x82\xb4\x24\x61\x72\x0c\x39\xfd\xaa\xf1\xf8\x25\xa7\xfb\xec\x3a\xfb\x0c\x72\x3d\x24\x58\x27\x0c\x47\x88\x6c\x5f\x2b\xb7\x83\x2b\x6a\x0b\xea\xb9\x22\x2a\xf3\x15\x30\xf3\x13\xd5\xb7\x18\xca\x1d\x1a\x6f\xed\xa1\xef\xb4\xd3\x2f\xc2\xb8\xdf\x80\x00\xc7\xb1\x6f\x29\x06\x7a\x89\xa1\x62\x80\xa8\x50\x03\x02\x5b\xa7\xd9\x83\xf3\x28\xab\x4d\x21\x5a\x98\x35\xbe\x6a\x17\x42\xe5\x24\x44\xbd\x37\xa7\x38\x16\x96\x43\x7b\xca\xc5\xa5\x57\x0b\x6e\x52\x5d\xb4\x1f\xca\xdd\xf1\x35\x75\x9c\xd7\x03\x2b\xca\x80\xd9\xbe\xf9\xf2\x1a\x35\x50\x86\x10\x23\x69\x87\x4f\x3a\x4d\x66\x4d\x54\x78\xcb\xe1\x11\x8c\x2a\xb7\x2b\x82\xb0\xcc\xf0\x83\xb2\x54\xbe\x8f\xf5\x83\xa5\xaa\xed\xd2\x5c\xf7\xaa\xd0\xb2\x85\xb9\xc3\x64\x33\xe1\xca\xa4\xbf\x90\x04\xf3\x2c\x31\xf0\x09\xa6\x89\x48\xa8\x43\x89\x1e\xba\xec\x75\x92\x41\xa0\x3a\x0f\x8c\x89\xc6\xe0\x3d\xd9\x6d\x07\xc9\x92\x82\x6b\x39\x83\xdb\xbb\x39\x48\x8e\x87\x2a\x50\x1b\xd8\x70\xce\xa1\x80\xd6\xf9\xa7\xa6\xd9\xe1\x3a\xe9\x25\x02\x59\xfc\xfa\x81\x58\xd3\x98\xa8\x58\xb0\x9f\x0b\x6c\xaa\x14\x56\xe0\x8d\x74\xa9\xe5\x7a\x2b\x08\x3c\x16\x29\xff\x75\x86\xf9\x28\xba\xfb\x00\x77\xcf\xa4\x6c\x49\x04\x42\xd8\x74\x67\xfb\x83\x1c\x6b\x2c\x9e\xaa\xa7\x8b\xaa\xf0\x5f\x4c\x17\x1f\x50\xb5\x14\x7a\x11\x1a\xba\x4c\xba\x9f\x95\x97\x4f\xc8\x18\x2f\xc5\xd5\x0b\xe7\xa2\xcb\x8e\x82\x1c\xb1\x14\x6e\xbe\x86\x1c\xa4\x8d\xd1\x3f\x2b\xd1\xa5\x04\xa8\xcc\xe6\xc8\xdd\x56\x78\x4f\x0c\xcf\xec\x54\xf0\x06\x85\x1b\x44\x92\x27\x3f\x80" +#define RESULT_ALPHA_7 "\xfe\x69\xa4\xf2\x31\x71\x77\x1f\xae\x13\x45\xbf\xc1\x54\x6e\xb4\xa9\x05\xe3\xf8\x1e\xa1\x64\x50\x6e\xaf\x9f\x2b\x62\xd8\x52\x37\x04\xf4\x2f\x6b\xb7\x4f\x48\xab\x5d\x5c\x71\x67\x1c\xd6\x58\x15\xdb\xa7\xc9\xb6\xbf\xf2\x64\x1c\xfc\x90\x43\x8a\xec\x13\x4f\xf5\x6c\x7e\x80\x7e\xc6\xa1\xb2\x09\x07\xfa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xfe\x00\xaf\x19\x7b\x14\x2b\x44\xf1\xa1\x3e\x16\x00\x76\x3f\xfe\x35\xfc\x17\xb0\x6f\x92\x85\x6d\x03\x4c\xeb\x63\xb5\x20\x48\x99\x09\x8e\x90\x70\x8e\x21\xd8\x72\x7a\xee\x2d\x3b\xa8\x8f\x92\xff\x45\x90\x3d\x34\x47\x4a\x42\x89\x16\x95\x5a\x03\x94\xe1\x3d\xfb\x1c\x32\x53\xde\xf6\x0e\x6b\xae\x15\x6a\x6c\x8d\xe0\x66\x36\xad\x4c\x67\x19\xac\xc1\xca\x2d\xfc\xb3\x79\x1d\x71\x0c\x5b\x70\xa7\x0b\x6e\x20\xf1\xad\x39\x58\x09\x37\x36\x7e\x17\xa3\x23\xa7\xf2\x40\xc3\x33\x67\x25\xdb\x63\xec\x1f\xcf\x6e\xf2\x20\xd0\x32\xe2\x2e\xb5\x5d\x70\x57\x07\x0a\xb2\x78\x6a\x13\x20\x24\x1e\x18\x3d\x49\xd8\x2b\x93\x8b\x48\x5a\xe1\xd2\x01\x0a\x84\xed\xfd\x27\x31\xb5\xbd\x97\x6b\x35\x82\x4b\x4e\xd4\xf1\x04\x2f\x6f\xdb\x57\x5d\xb8\xb4\x79\x20\x82\x1b\x23\xed\x92\xab\x2c\x5a\x7c\x7b\xc8\x9d\x8b\xd1\x58\x30\x6f\xe0\x56\xef\xde\xf1\x81\x96\xb8\x71\x46\xd3\xe2\x79\xf0\xcb\xff\x7b\x6b\x44\x94\xe8\x47\xc6\xf4\x24\xc1\xc9\xc1\xfe\x2a\x39\xd6\xcc\x24\xcd\x9c\x69\xc2\x9b\x72\x8a\x21\xd9\x0b\x7c\xd6\xca\x8c\xc9\x61\x8a\x9b\xab\x51\x0f\xa5\x72\x10\x35\x3f\x42\x58\xcb\x97\xc7\xdf\x12\x10\xc3\x9c\xac\xc9\x28\x02\xfe\x1e\xc6\x4b\xd1\xd3\x0d\xb4\x37\x59\xe6\x90\x55\x6c\xa4\x2d\xe9\x13\xd2\xbd\xe7\x49\xbe\xb6\x78\xc7\xba\x98\x24\xe1\x2e\x00\xf8\x7f\xf2\x16\x53\xfb\x9d\x6e\x2f\xd0\xe1\xaf\xf9\x14\x56\x33\x85\xc5\x51\x0b\x44\x5e\x10\x71\x46\x32\xa9\xc3\xbc\x6a\xf7\x68\xae\xab\xd2\x99\x2a\x99\x15\x32\x56\x31\xf7\xd3\x33\x19\x7e\x10\xb1\xc5\xfc\x8c\x18\x5f\x9c\xc1\x71\xf8\xed\xe6\x9f\xe8\x24\x7a\xef\x84\xc2\x17\xc6\xcb\x85\xf5\x91\xef\xdc\x9e\x1b\xe5\x72\x67\x4c\x4b\x16\xf5\x0a\xfc\x48\xc1\x63\xdf\x57\x13\x43\x13\x6e\x1e\xe8\xd2\x7e\xdc\x98\xc1\xe5\x99\xb1\xc0\x4d\x82\xb8\x7b\x22\x85\x10\x82\x4e\x81\x02\x36\x84\x3c\xc2\x70\x54\xa4\xca\x87\xc0\x5b\x4f\x59\xf4\x1f\xa1\xfc\x6e\x18\x99\x9e\xa5\x18\x2e\xa1\x42\x17\xa1\xe8\xa7\x77\xe4\xeb\x40\x27\xc0\x03\xd7\xe8\xfa\x6b\x1f\x06\x71\x69\xad\x69\xfc\xd8\x55\x30\x92\xca\x29\xcb\xb1\x20\x66\x24\xa0\x70\xf2\x1d\x0e\x5b\xe1\x3b\x05\x12\xfd\x0d\x22\x23\x00\x93\xe1\x79\x3f\x83\x06\xb3\x30\xa1\x01\x12\x17\x2a\x98\xc0\x02\xa2\xb3\xe9\x03\x3f\x74\xd6\x68\xf1\x96\xcc\xcc\x41\xfd\x62\x8a\x43\xfc\x36\x12\xbd\x09\x54\x15\x5c\x06\xa6\x4f\xba\x27\x36\x89\x2b\xd9\x62\x0d\x3b\xb6\x51\xb0\x68\x74\xbc\x6a\x66\x94\x0f\x07\xbb\x2e\xa0\xca\x07\xe9\xbb\xdb\x69\xc2\xcc\x67\x27\x5d\xbf\x14\xf1\x3f\x5f\x81\x9d\x8b\xf4\xdb\xb6\xc1\x83\xd5\x47\x61\x60\x89\x25\xa1\x53\x9e\xaa\xb6\xd6\xda\x26\x0a\xea\xa9\x3c\xba\xcf\x2e\xa0\x56\x4c\x28\xb2\xa2\xc7\x2c\x21\x5a\x09\x71\xaf\xb4\xe4\x27\xaa\xfc\xbb\x48\x25\x09\x92\x1d\x7b\x0c\x96\x7c\x18\x7f\xd0\xa6\x16\x91\x7a\x93\xb3\xec\xfd\xd7\x67\xcf\xd7\x48\x95\xf8\x41\xa0\x3f\xaa\xc7\xfb\x56\x6c\x6a\xf8\x6c\x46\x8d\x39\x44\x7e\xea\x38\x14\x62\xb9\xe2\x00\xab\x93\x1b\xce\xa4\x11\x9a\x7e\xc5\x11\x3b\xed\xf1\x76\x97\x33\x13\xdf\x9c\x64\x6d\xfa\xb9\xa2\xcf\x83\x80\x32\xfb\xb6\x9f\x6e\xcc\x9a\xb9\x57\xba\x5d\x35\x86\x92\xfe\xa1\xd4\x4b\xeb\x1b\x6c\x48\x32\xb7\x4e\xed\x6e\x9b\xd6\xd5\x0e\x45\x90\x42\x96\x97\xd5\x5b\xa4\x3a\xa2\x80\x61\x89\x5d\xa2\x61\xc6\x16\x7d\x91\x28\x14\x26\xc8\xfc\xca\xc8\xc0\x64\x92\x54\x81\x4c\x5e\x39\x95\x2c\x17\xe0\xae\xbd\x69\xd3\x75\x69\x4b\x0b\xe7\x53\xb8\x3b\x65\x5e\x8d\xfc\xee\xb2\x1f\x0f\x85\xf6\x3c\x80\x3b\x24\x54\x23\x2a\xa6\x1b\xc6\x4a\x32\x3c\xa5\xe9\x75\xd3\x49\xff\x4e\xd2\x5d\x52\xe5\x10\x56\xb7\x57\x6b\xd0\xa1\xdc\x2f\xe7\x3f\x79\x37\xe8\x13\x37\x29\x2a\x2a\xbd\x74\xe0\x6b\x48\x8c\x57\x0c\xa4\x7c\x05\x24\x3e\x4e\xa1\xa9\xf9\xde\x84\xa5\xe8\xd7\x50\x69\x9e\x49\x18\x32\x7b\xb1\x1c\x87\x82\x8b\xd2\x66\xd6\x88\x76\x00\x31\xa4\x18\x42\x84\x21\x62\x04\xa0\x1a\x19\x12\x6c\xbc\x9e\xa4\x75\xfa\x49\xae\xdb\x58\x75\xd6\x68\xa8\xb4\xf7\x40\x8e\xd4\x61\x6a\x02\xfb\xc4\x4c\x80\x92\x83\xde\xef\xd4\xbb\x07\xcb\xb2\xe9\x47\xf6\xe2\x9e\x36\x56\xae\x57\x84\xf9\xff\xef\x7e\xbf\x87\xfe\x36\xaa\x43\x48\x96\xc8\xa4\xcb\xea\xe8\xa4\x3d\x22\x8a\x51\xa5\xdb\xfc\x0c\xc6\x50\x86\xac\xca\x3b\x37\xd0\x3d\x08\x5d\x4b\xe8\x85\x11\x68\x4c\xb1\x3f\x76\x37\xa1\x42\xfb\x3c\x4b\xd3\xf8\x5f\xe6\xcf\xe1\x06\xb0\xfb\x00\x6a\x15\x45\xc6\x12\x49\x34\x44\xb5\x8f\x44\x7f\x89\x71\xb8\x2b\x8e\xc4\x9e\xba\xbd\x09\xaa\x70\x59\x52\x36\x91\x3a\xc8\x01\x1a\x07\xa5\xd1\xab\xa4\x49\x98\x4f\x9b\x82\xe2\xf9\xe4\x1a\xef\x85\xd5\x00\x06\x01\xea\x81\x5c\x8d\x29\xd7\x49\x66\xeb\x08\xec\x27\x12\xc9\x6a\xd8\xb1\x33\xf5\x3d\x05\x8a\x62\x70\x13\x1c\xa7\xeb\x97\xa1\x3a\xec\xfe\x68\xba\x0a\x68\xd4\x9c\x0f\x44\x5e\x44\x5f\x80" +#define RESULT_ALPHA_8 "\xfe\xdf\x65\x4b\xb2\xeb\x85\x00\xac\x0a\x1d\xf5\x0b\xfc\x15\xe4\xd7\x90\xab\x7d\xa0\x5f\xfc\xfe\x2f\xc5\x50\x6e\xbd\xcd\x31\x0f\x47\x6c\xc2\xf2\xc9\x5f\x85\xfe\xbb\x74\x52\x37\xc0\xeb\xad\x25\x87\x1a\xa8\x94\x95\x65\xdb\xa3\xb5\x1e\xfe\xb9\xdc\xfa\x73\xf1\xfd\x86\x6b\xae\xc1\x5d\xef\xa4\x5f\x85\xd4\x65\x1d\xec\x62\x7c\xa9\x07\xfa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaf\xe0\x12\x40\x69\x10\xc3\x25\x1f\xc4\xc7\x1b\x42\xf7\x00\x3a\xd3\xbf\x7f\xcd\x54\x9f\xc8\x9f\x1f\xd9\x74\xe7\x3b\xac\x49\x28\x7b\x11\x97\x33\xa9\x54\xb1\x81\x97\xa6\x34\xdc\xeb\x2d\x6e\x51\x32\xd0\xae\xd4\xa1\x7b\x14\x4f\x11\x6a\x59\xc1\xb0\x14\x7c\xb4\xba\x22\x74\x2f\xdc\x31\x7e\xa2\x38\x97\xa8\x65\x03\x04\x11\x82\x77\x4a\x12\xc8\x16\x37\x9f\x6c\x9a\x80\xdf\xa6\x73\xc5\x98\x6a\x6a\xeb\xbc\x2b\xb8\x1c\x1e\x78\x28\x43\x1a\x02\xb5\x45\x7c\x9f\x86\xd4\xe3\x14\xdf\x48\xa9\xc4\x2f\x40\xff\xc0\x4f\xdb\x6e\x7f\x9d\xfc\x47\xf5\xd6\x8e\x5a\x75\x44\x74\x0c\x50\x0b\x82\x03\x62\xb2\x7f\x07\x3f\x2f\xa8\x36\x07\xdb\xcb\x79\xf4\x3d\xbb\xc5\x7c\x65\xb1\x5e\x05\x9e\x6b\xe0\x52\x34\x69\x33\x6a\x8a\x1e\x6a\xfe\x2d\x75\x2c\xb3\xd4\x9d\x08\x3e\x42\xbd\x39\x26\xb7\x92\x19\x1a\xbc\xee\x39\x60\xdb\xe6\x19\xd6\x2a\x21\x4e\xb0\x83\x42\x48\x15\xf2\x78\xac\x8f\x8e\xa1\x83\x5e\x47\xe7\x3c\x61\x12\x70\xcc\x86\x4d\xd6\xee\x94\xce\x67\x42\x7d\xd3\x9e\x30\xbb\x17\x2e\xe1\x00\xd1\xa5\x9e\x11\x22\xc0\x3f\xae\x18\x36\xfe\xd6\x23\xac\x51\x81\x10\x82\x06\xd5\x04\xa1\xfe\xe0\x3d\xa1\x3c\x21\x76\xb5\xa1\x7a\x15\xc7\xd0\x43\xb0\xba\x68\x77\x36\x0e\xbd\x62\x74\x8f\x7e\x02\xfe\x95\xf8\xfe\xe9\xbe\xfc\xf6\x19\xfa\xdb\x8e\xff\xbc\x43\x43\xac\x76\xe7\x5c\x72\xe3\x84\x74\x58\x5c\x6b\xaa\xc2\x35\xeb\xb4\x97\x2a\x93\x47\x2a\x17\xa1\x2a\x75\x14\x4a\x7d\x18\x39\x75\x18\x3e\xd7\x1d\xc2\xf7\x16\xdf\xd7\x7f\xdf\xdb\x21\xaf\x88\xc9\x3f\xd9\x45\xff\xcf\x4e\x7d\xbb\x52\xc7\x5f\xfb\xf9\x4e\xb5\x58\xab\xa1\xb5\xe1\x53\x5c\xee\x36\x16\xe7\x09\xb5\xe4\x3e\x10\xef\xca\xd9\x07\xb6\x10\x4b\xeb\x34\xaf\x5d\xf4\x2f\xee\x30\x3f\xd6\x67\x01\xd5\xd4\x0f\x6a\x2b\x93\x03\x38\xf6\xdc\x7a\x9c\xfd\x34\xd6\x52\x90\x6f\x6d\x07\x97\xd2\x20\x59\xab\xfb\xb4\x9d\x54\x58\xd0\x7b\x4e\x17\xb0\x1e\xbf\x1d\x2e\x74\xab\x9b\xb7\xc8\xc6\x34\xff\x48\xf6\xe0\x27\x9e\xfe\x47\x80\xa6\xe7\xd4\xfd\x3d\x4f\x74\x9f\x71\x2b\x6d\x01\x47\x6b\x26\x10\x98\x62\xea\x6b\xd7\x86\x25\x88\xe4\x94\x38\x35\x57\x4d\x70\x51\xc4\x78\x13\x37\xc0\xb7\x33\x81\x7a\x8d\xbd\x55\x69\xd7\xf4\x0d\x7e\x1a\x6e\xc4\x48\xc2\x2c\xcb\x5a\x32\xed\x91\x10\x11\xfe\xd4\xa5\x1b\x3f\xa1\xa2\x4d\x3f\x3a\x29\x84\xb0\x78\xea\x3f\xe9\x6c\x5b\xf4\x75\x1b\x54\x03\x10\x17\xa5\x03\xfa\x35\x99\x3d\xd0\xb0\xdf\xb0\x4d\x95\x7d\x4a\xf7\xe3\xcf\x0c\xb9\xbf\xc1\x2f\x9b\x1d\x32\x91\x21\x6d\x9e\x7b\xc3\xe7\xcd\xbe\xd6\x68\xf6\xf0\x95\xfd\xb9\xa4\x4c\xac\x8b\x0b\x7d\x1c\xe7\xca\x30\xa9\x94\x84\x6a\x12\x17\x92\x35\xc5\xcb\xd0\xa6\x43\x7f\x07\x57\xf4\x27\x6e\x3c\xfb\x50\x39\xfa\x7b\x61\xfd\x32\x29\xfd\x84\xbd\xfe\x64\x64\xa0\xa4\x67\x31\xc4\x55\x96\x7c\x54\x1f\x2c\x62\x6a\xb5\x35\xea\x92\x59\xeb\x18\x19\x2b\x56\xf1\x6a\x6f\x17\x71\xc3\x12\xc7\x83\x17\x60\xf7\x1f\xc2\xbd\x10\x3f\x93\x70\xdf\xb3\x92\xbf\xee\x7a\x1f\xcf\x31\xcf\xb1\x47\x68\xbd\xdb\xaa\x0b\x4e\x40\x46\xcb\x54\x4e\x3e\x19\xcd\xaa\xc6\x76\x63\x32\xcb\xe8\xd0\xe0\x68\x44\x06\x0b\x06\x37\xc4\x7f\xd6\x0a\xd0\xaf\xd8\xf4\x2f\x4d\x11\x22\x5d\x77\xff\x1d\xaf\xf4\x5f\xde\x29\x74\x49\xb7\xc0\xa9\x60\xa5\xf5\x29\xe5\xbc\x14\xfc\x07\xb1\x6b\xa0\x7d\x41\x3c\x27\xa3\x70\x96\x74\x51\x4e\x17\xe1\x40\xf3\x3e\x25\x93\x91\xb6\x7a\x6e\x08\x56\x8f\xc2\xfc\x5b\x13\x4b\xd4\x2e\x63\x25\x6f\xd1\x74\x8e\xce\xf4\x1b\x77\xe8\xee\x01\xb1\x33\x21\x2e\x3c\x6c\xc2\x45\x94\xb1\x14\xbe\xd7\xc8\x24\x96\x68\x2e\x88\x90\x85\x2a\x11\x5f\x0a\x40\x0b\x94\x13\x48\xf8\xbe\xf7\x76\xf4\x05\x4f\x0d\x78\xeb\xca\x00\x15\x94\xc9\x54\x3f\x29\xe7\x39\xb3\xec\xf5\xd8\x78\x4f\x78\x80\x9c\x99\x5d\xae\xff\x49\x81\x4f\x88\x84\x86\x41\x31\xcf\x00\xb9\x11\x03\xe1\x04\x6c\x37\x9e\x36\x15\x33\x21\x20\x5d\xf5\xcf\x42\xde\xf3\x27\x55\xc9\x36\x66\x2c\x0e\x15\x5c\xd3\xd6\x11\xff\x6c\xe8\x05\x8e\x5b\x6a\x43\x80\x82\xca\xca\x43\xa9\x38\xa6\x8e\xfb\x29\x4f\xcf\xfa\x3f\x79\x81\xc1\x7b\x05\x46\xc2\x2f\xe8\x87\x13\x70\xca\xbc\x1b\x46\x36\xaf\x65\x3a\xfb\xae\x74\xfd\x34\xe3\xfb\x9a\xdf\xf8\xe2\x24\xfe\x6c\x67\x1b\xdc\x55\xad\x7c\x49\x26\x3c\x45\x5a\xe4\x60\x2a\x60\xf4\x6a\x63\xc7\xea\x48\x4d\x2a\x16\xf5\x2a\x65\x14\x00\x13\x18\x63\xaf\x1f\x41\x35\x1d\x46\xf7\x12\x7f\xea\x10\x4f\xc7\x56\xaf\x9c\x00\xef\x94\x28\xcf\xee\x4e\x19\xb2\xf4\x3f\xce\x12\x75\xc7\xd6\x49\xc4\x28\x1d\xa5\xcd\x6f\x94\xf9\x28\xb0\x2c\x86\x43\x3a\x15\xd6\x49\xca\x7c\xd9\x41\x41\xf8\x20\xb7\x66\xf4\x05\x52\x19\xa7\x96\x07\x2b\x2f\x2f\x09\x79\x00\xf0\xd6\x17\x4a\xb0\xaa\x90\xbd\x9f\xfa\x67\x6d\x05\x8b\x06\x9d\x4d\xa0\x3b\xb4\x98\x17\x02\xd5\x08\x16\xcd\x00\x12\xa4\x1c\xf6\xb3\x92\x99\x2e\x33\xf8\x9f\x0d\xf6\x8f\xc2\x74\x32\x8e\x0d\x60\x81\x4c\xf8\xcf\x53\xba\xe8\x38\xe4\x5a\xb7\x46\x5a\x96\xb9\x61\x5c\xc4\x81\xc4\x9f\x67\x06\x2a\xa6\x93\x24\x2b\x69\xfb\xc2\x3d\xcd\x52\x51\x3a\x45\x9e\x7b\xaa\x78\xf8\x56\x87\xa3\x53\x37\x64\xf4\x87\x5a\x2d\x72\xd2\xa5\x05\x17\xa8\x7a\xe6\x1a\xa3\x03\x2f\xbe\x84\xc6\x90\x9e\xbb\x82\xa2\x01\x99\x2b\xda\x11\xd2\xba\xcb\x25\x22\xbf\x06\x63\x42\xa0\xa9\x74\x57\xa0\x6c\x71\xab\xa1\x9d\x86\x07\x4d\x34\x6f\x36\xef\xe2\x75\x13\xbe\x37\xd0\x1b\xe7\x56\xd2\x0e\x62\x8e\xd1\x35\x90\xe5\x84\x32\x35\xea\xff\xa5\xfd\xc9\x3e\xff\x60\x14\x72\x1e\x84\x04\xda\xb5\xe8\xdd\x2f\xba\x97\x41\x7a\x13\xf6\x7a\x9c\x1d\xb4\x19\x35\x43\x43\xa3\xee\xf4\x2f\x58\x1e\xa0\x78\x26\xfa\xbf\x94\xfe\x5b\xf8\xfc\x92\xc5\xfe\x80\x51\xb1\xf4\x41\x90\x6c\x79\x47\x0c\x58\x0e\x74\x63\xf9\x99\xcf\xeb\xa9\x70\x6a\xe5\x2b\x6b\x47\xe1\x2b\x70\x4f\xe7\x97\x11\x15\x57\x1e\x0f\xdf\x1f\x02\xd5\x11\xba\xac\xa7\xdf\xb4\xeb\x4f\xf6\xfc\x9f\xd9\xd5\xcf\xfd\xd6\x2b\x93\x3e\x9d\x4f\x58\x3c\x64\x38\xc9\x3e\xfe\x6e\xa4\x98\xd7\xf9\xb3\x17\x58\xec\x93\xe1\x6e\x11\x4b\x04\xb8\x63\xd7\xae\x95\x38\x2a\x0d\xc2\xfe\x27\xee\x1f\xe1\x98\xe3\x81\xee\x04\xf7\x52\xcc\x77\x87\x08\x8f\x80" diff --git a/hardware-wallet/firmware/visual_firmware.code-workspace b/hardware-wallet/firmware/visual_firmware.code-workspace new file mode 100644 index 00000000..a4d7f64f --- /dev/null +++ b/hardware-wallet/firmware/visual_firmware.code-workspace @@ -0,0 +1,20 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "/home/mbenthaier/my_projects/skycoin/python-trezor/trezorlib" + }, + { + "path": "/home/mbenthaier/my_projects/skycoin/trezord-go" + } + ], + "settings": { + "files.associations": { + "storage.h": "c", + "layout.h": "c", + "usb.h": "c" + } + } +} \ No newline at end of file From 16394cb636e8209c85e006d49c3f2fa12e2ebef1 Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 21 Apr 2018 12:19:58 +0800 Subject: [PATCH 56/73] removing visual studio workspace file from repo --- .../firmware/visual_firmware.code-workspace | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 hardware-wallet/firmware/visual_firmware.code-workspace diff --git a/hardware-wallet/firmware/visual_firmware.code-workspace b/hardware-wallet/firmware/visual_firmware.code-workspace deleted file mode 100644 index a4d7f64f..00000000 --- a/hardware-wallet/firmware/visual_firmware.code-workspace +++ /dev/null @@ -1,20 +0,0 @@ -{ - "folders": [ - { - "path": "." - }, - { - "path": "/home/mbenthaier/my_projects/skycoin/python-trezor/trezorlib" - }, - { - "path": "/home/mbenthaier/my_projects/skycoin/trezord-go" - } - ], - "settings": { - "files.associations": { - "storage.h": "c", - "layout.h": "c", - "usb.h": "c" - } - } -} \ No newline at end of file From c510f93eaeb0f1e054706f133ba553de222553dd Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 25 Apr 2018 16:00:48 +0800 Subject: [PATCH 57/73] Changing skycoin-crypto, from a submodule it became a simple relative link --- hardware-wallet/firmware/.gitmodules | 3 --- hardware-wallet/firmware/vendor/skycoin-crypto | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) mode change 160000 => 120000 hardware-wallet/firmware/vendor/skycoin-crypto diff --git a/hardware-wallet/firmware/.gitmodules b/hardware-wallet/firmware/.gitmodules index a745a710..5383c236 100644 --- a/hardware-wallet/firmware/.gitmodules +++ b/hardware-wallet/firmware/.gitmodules @@ -13,6 +13,3 @@ [submodule "vendor/nanopb"] path = vendor/nanopb url = https://github.com/nanopb/nanopb.git -[submodule "skycoin-crypto"] - path = vendor/skycoin-crypto - url = https://github.com/mpsido/skycoin-crypto.git diff --git a/hardware-wallet/firmware/vendor/skycoin-crypto b/hardware-wallet/firmware/vendor/skycoin-crypto deleted file mode 160000 index 704fedae..00000000 --- a/hardware-wallet/firmware/vendor/skycoin-crypto +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 704fedae4fd98f666f42ebb13acb3a3a85a50ca6 diff --git a/hardware-wallet/firmware/vendor/skycoin-crypto b/hardware-wallet/firmware/vendor/skycoin-crypto new file mode 120000 index 00000000..05385764 --- /dev/null +++ b/hardware-wallet/firmware/vendor/skycoin-crypto @@ -0,0 +1 @@ +../skycoin-api/ \ No newline at end of file From e2b3c199abf6587b56687c21c42eb949f017eaf6 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 25 Apr 2018 16:02:04 +0800 Subject: [PATCH 58/73] get the next seed from generate_deterministic_key_pair_iterator function --- hardware-wallet/skycoin-api/skycoin_crypto.c | 6 ++++-- hardware-wallet/skycoin-api/skycoin_crypto.h | 2 +- hardware-wallet/skycoin-api/test_skycoin_crypto.c | 10 +++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hardware-wallet/skycoin-api/skycoin_crypto.c b/hardware-wallet/skycoin-api/skycoin_crypto.c index 27ea5760..abe9adfb 100644 --- a/hardware-wallet/skycoin-api/skycoin_crypto.c +++ b/hardware-wallet/skycoin-api/skycoin_crypto.c @@ -88,7 +88,8 @@ void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest) compute_sha256sum((const char *)secp256k1Hash, secp256k1Hash_digest, sizeof(secp256k1Hash)); } -void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, uint8_t* pubkey) +// nextSeed should be 32 bytes (size of a secp256k1Hash digest) +void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* nextSeed, uint8_t* seckey, uint8_t* pubkey) { size_t seed_length = 0; uint8_t seed1[SHA256_DIGEST_LENGTH] = {0}; @@ -97,7 +98,8 @@ void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, secp256k1Hash(seed, seed1); seed_length = strlen(seed); memcpy(keypair_seed, seed, seed_length); - memcpy(&keypair_seed[seed_length], seed1, sizeof(seed1)); + memcpy(&keypair_seed[seed_length], seed1, SHA256_DIGEST_LENGTH); + memcpy(nextSeed, seed1, SHA256_DIGEST_LENGTH); compute_sha256sum(keypair_seed, seed2, seed_length + sizeof(seed1)); generate_deterministic_key_pair(seed2, SHA256_DIGEST_LENGTH, seckey, pubkey); } diff --git a/hardware-wallet/skycoin-api/skycoin_crypto.h b/hardware-wallet/skycoin-api/skycoin_crypto.h index 5409b0fa..124f7fac 100644 --- a/hardware-wallet/skycoin-api/skycoin_crypto.h +++ b/hardware-wallet/skycoin-api/skycoin_crypto.h @@ -7,7 +7,7 @@ void ecdh(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* ecdh_key /*should be size SHA256_DIGEST_LENGTH*/); void ecdh_shared_secret(const uint8_t* secret_key, const uint8_t* remote_public_key, uint8_t* shared_secret /*should be size SHA256_DIGEST_LENGTH*/); void secp256k1Hash(const char* seed, uint8_t* secp256k1Hash_digest); -void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* seckey, uint8_t* pubkey); +void generate_deterministic_key_pair_iterator(const char* seed, uint8_t* nextSeed, uint8_t* seckey, uint8_t* pubkey); void compute_sha256sum(const char *seed, uint8_t* digest /*size SHA256_DIGEST_LENGTH*/, size_t seed_lenght); void generate_pubkey_from_seckey(const uint8_t* seckey, uint8_t* pubkey); void generate_deterministic_key_pair(const uint8_t* seed, const size_t seed_length, uint8_t* seckey, uint8_t* pubkey); diff --git a/hardware-wallet/skycoin-api/test_skycoin_crypto.c b/hardware-wallet/skycoin-api/test_skycoin_crypto.c index aae95f75..7511ba8f 100644 --- a/hardware-wallet/skycoin-api/test_skycoin_crypto.c +++ b/hardware-wallet/skycoin-api/test_skycoin_crypto.c @@ -97,23 +97,27 @@ START_TEST(test_generate_deterministic_key_pair_iterator) char seed[256] = "seed"; uint8_t seckey[32] = {0}; uint8_t pubkey[33] = {0}; - generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + uint8_t nextSeed[SHA256_DIGEST_LENGTH] = {0}; + generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); ck_assert_mem_eq(pubkey, fromhex("02e5be89fa161bf6b0bc64ec9ec7fe27311fbb78949c3ef9739d4c73a84920d6e1"), 33); ck_assert_mem_eq(seckey, fromhex("001aa9e416aff5f3a3c7f9ae0811757cf54f393d50df861f5c33747954341aa7"), 32); + ck_assert_mem_eq(nextSeed, fromhex("c79454cf362b3f55e5effce09f664311650a44b9c189b3c8eed1ae9bd696cd9e"), 32); strcpy(seed, "random_seed"); memset(pubkey, 0, sizeof(pubkey)); memset(seckey, 0, sizeof(seckey)); - generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); ck_assert_mem_eq(pubkey, fromhex("030e40dda21c27126d829b6ae57816e1440dcb2cc73e37e860af26eff1ec55ed73"), 33); ck_assert_mem_eq(seckey, fromhex("ff671860c58aad3f765d8add25046412dabf641186472e1553435e6e3c4a6fb0"), 32); + ck_assert_mem_eq(nextSeed, fromhex("5e81d46f56767496bc05ed177c5237cd4fe5013e617c726af43e1cba884f17d1"), 32); strcpy(seed, "hello seed"); memset(pubkey, 0, sizeof(pubkey)); memset(seckey, 0, sizeof(seckey)); - generate_deterministic_key_pair_iterator(seed, seckey, pubkey); + generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); ck_assert_mem_eq(pubkey, fromhex("035843e72258696b391cf1d898fc65f31e66876ea0c9e101f8ddc3ebb4b87dc5b0"), 33); ck_assert_mem_eq(seckey, fromhex("84fdc649964bf299a787cb78cd975910e197dbddd7db776ece544f41c44b3056"), 32); + ck_assert_mem_eq(nextSeed, fromhex("70d382540812d4abc969dcc2adc66e805db96f7e1dcbe1ae6bbf2878211cbcf6"), 32); } END_TEST From 298c9121e6b2b7913f0e0672063449ba4295a544 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 25 Apr 2018 16:27:11 +0800 Subject: [PATCH 59/73] Fixing broken link --- hardware-wallet/firmware/vendor/skycoin-crypto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware-wallet/firmware/vendor/skycoin-crypto b/hardware-wallet/firmware/vendor/skycoin-crypto index 05385764..3ea6f637 120000 --- a/hardware-wallet/firmware/vendor/skycoin-crypto +++ b/hardware-wallet/firmware/vendor/skycoin-crypto @@ -1 +1 @@ -../skycoin-api/ \ No newline at end of file +/home/mbenthaier/my_projects/skycoin/services/hardware-wallet/skycoin-api \ No newline at end of file From 112d9f311f22c74f6ca3ef106b78563a0665bbf1 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 25 Apr 2018 16:47:07 +0800 Subject: [PATCH 60/73] Generate skycoin address using existing device seed. And modifying message to allow chain address generation --- hardware-wallet/firmware/firmware/fsm.c | 33 +- .../trezor-common/protob/messages.proto | 3 +- .../go-api-for-hardware-wallet/main.go | 14 +- .../protob/messages.proto | 1083 +---------------- 4 files changed, 39 insertions(+), 1094 deletions(-) mode change 100644 => 120000 hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto diff --git a/hardware-wallet/firmware/firmware/fsm.c b/hardware-wallet/firmware/firmware/fsm.c index 40e8c781..bd14a075 100644 --- a/hardware-wallet/firmware/firmware/fsm.c +++ b/hardware-wallet/firmware/firmware/fsm.c @@ -379,22 +379,36 @@ void fsm_msgSkycoinAddress(SkycoinAddress* msg) uint8_t pubkey[33] = {0}; RESP_INIT(Success); - if (msg->has_address_type) + // reset_entropy((const uint8_t*)msg->seed, strlen(msg->seed)); + const uint8_t* mnemo = storage_getSeed(false); + char seed[64] = {0}; + uint8_t nextSeed[SHA256_DIGEST_LENGTH] = {0}; + if (msg->has_address_type && mnemo != NULL) { char address[256] = {0}; size_t size_address = sizeof(address); - generate_deterministic_key_pair_iterator(msg->seed, seckey, pubkey); + memcpy(seed, mnemo, sizeof(seed)); + for (uint8_t i = 0; i < msg->address_n; ++i) + { + memcpy(seed, nextSeed, 32); + seed[32] = 0; + generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); + } switch (msg->address_type) { case SkycoinAddressType_AddressTypeSkycoin: layoutRawMessage("Skycoin address"); generate_base58_address_from_pubkey(pubkey, address, &size_address); - memcpy(resp->message, address, size_address); + // memcpy(resp->message, address, size_address); + tohex(resp->message, nextSeed, SHA256_DIGEST_LENGTH); + // memcpy(resp->message, mnemo, sizeof(resp->message)); break; case SkycoinAddressType_AddressTypeBitcoin: layoutRawMessage("Bitcoin address"); generate_bitcoin_address_from_pubkey(pubkey, address, &size_address); - memcpy(resp->message, address, size_address); + // memcpy(resp->message, address, size_address); + tohex(resp->message, nextSeed, SHA256_DIGEST_LENGTH); + // memcpy(resp->message, mnemo, sizeof(resp->message)); break; default: layoutRawMessage("Unknown address type"); @@ -402,9 +416,16 @@ void fsm_msgSkycoinAddress(SkycoinAddress* msg) } } else { - generate_deterministic_key_pair_iterator(msg->seed, seckey, pubkey); + generate_deterministic_key_pair_iterator((const char*)mnemo, nextSeed, seckey, pubkey); tohex(resp->message, pubkey, 33); - layoutRawMessage(resp->message); + if (mnemo == NULL) + { + layoutRawMessage("Empty mnemonic"); + } + else + { + layoutRawMessage(resp->message); + } } resp->has_message = true; msg_write(MessageType_MessageType_Success, resp); diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto b/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto index 939dcdca..5765d94a 100644 --- a/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto @@ -201,7 +201,8 @@ message ChangePin { * @next Success */ message SkycoinAddress { - required string seed = 1; // seed used to generate address + required uint32 address_n = 1; // address iterator + // required string seed = 1; // seed used to generate address optional SkycoinAddressType address_type = 2; } diff --git a/hardware-wallet/go-api-for-hardware-wallet/main.go b/hardware-wallet/go-api-for-hardware-wallet/main.go index b19de6a5..bdc26fb7 100644 --- a/hardware-wallet/go-api-for-hardware-wallet/main.go +++ b/hardware-wallet/go-api-for-hardware-wallet/main.go @@ -13,7 +13,7 @@ import ( func MessageSkycoinAddress() [][64]byte { skycoinAddress := &messages.SkycoinAddress{ - Seed: proto.String("seed"), + AddressN: proto.Uint32(1), AddressType: messages.SkycoinAddressType_AddressTypeSkycoin.Enum(), } data, _ := proto.Marshal(skycoinAddress) @@ -64,11 +64,15 @@ func main() { var msg wire.Message var chunks [][64]byte - chunks = MessageSkycoinSignMessage() + chunks = MessageSkycoinAddress() msg = SendToDevice(dev, chunks) fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - chunks = MessageCheckMessageSignature() - msg = SendToDevice(dev, chunks) - fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + // chunks = MessageSkycoinSignMessage() + // msg = SendToDevice(dev, chunks) + // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + // chunks = MessageCheckMessageSignature() + // msg = SendToDevice(dev, chunks) + // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) } diff --git a/hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto b/hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto deleted file mode 100644 index 939dcdca..00000000 --- a/hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto +++ /dev/null @@ -1,1082 +0,0 @@ -syntax = "proto2"; - -/** - * Messages for TREZOR communication - */ - -// Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; -option java_outer_classname = "TrezorMessage"; - -import "types.proto"; - -/** - * Mapping between Trezor wire identifier (uint) and a protobuf message - */ -enum MessageType { - MessageType_Initialize = 0 [(wire_in) = true]; - MessageType_Ping = 1 [(wire_in) = true]; - MessageType_Success = 2 [(wire_out) = true]; - MessageType_Failure = 3 [(wire_out) = true]; - MessageType_ChangePin = 4 [(wire_in) = true]; - MessageType_WipeDevice = 5 [(wire_in) = true]; - MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true]; - MessageType_GetEntropy = 9 [(wire_in) = true]; - MessageType_Entropy = 10 [(wire_out) = true]; - MessageType_GetPublicKey = 11 [(wire_in) = true]; - MessageType_PublicKey = 12 [(wire_out) = true]; - MessageType_LoadDevice = 13 [(wire_in) = true]; - MessageType_ResetDevice = 14 [(wire_in) = true]; - MessageType_SignTx = 15 [(wire_in) = true]; - MessageType_SimpleSignTx = 16 [(wire_in) = true, deprecated = true]; - MessageType_Features = 17 [(wire_out) = true]; - MessageType_PinMatrixRequest = 18 [(wire_out) = true]; - MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true]; - MessageType_Cancel = 20 [(wire_in) = true]; - MessageType_TxRequest = 21 [(wire_out) = true]; - MessageType_TxAck = 22 [(wire_in) = true]; - MessageType_CipherKeyValue = 23 [(wire_in) = true]; - MessageType_ClearSession = 24 [(wire_in) = true]; - MessageType_ApplySettings = 25 [(wire_in) = true]; - MessageType_ButtonRequest = 26 [(wire_out) = true]; - MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true]; - MessageType_ApplyFlags = 28 [(wire_in) = true]; - MessageType_GetAddress = 29 [(wire_in) = true]; - MessageType_Address = 30 [(wire_out) = true]; - MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_BackupDevice = 34 [(wire_in) = true]; - MessageType_EntropyRequest = 35 [(wire_out) = true]; - MessageType_EntropyAck = 36 [(wire_in) = true]; - MessageType_SignMessage = 38 [(wire_in) = true]; - MessageType_VerifyMessage = 39 [(wire_in) = true]; - MessageType_MessageSignature = 40 [(wire_out) = true]; - MessageType_PassphraseRequest = 41 [(wire_out) = true]; - MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true]; - MessageType_PassphraseStateRequest = 77 [(wire_out) = true]; - MessageType_PassphraseStateAck = 78 [(wire_in) = true, (wire_tiny) = true]; - MessageType_EstimateTxSize = 43 [(wire_in) = true, deprecated = true]; - MessageType_TxSize = 44 [(wire_out) = true, deprecated = true]; - MessageType_RecoveryDevice = 45 [(wire_in) = true]; - MessageType_WordRequest = 46 [(wire_out) = true]; - MessageType_WordAck = 47 [(wire_in) = true]; - MessageType_CipheredKeyValue = 48 [(wire_out) = true]; - MessageType_EncryptMessage = 49 [(wire_in) = true, deprecated = true]; - MessageType_EncryptedMessage = 50 [(wire_out) = true, deprecated = true]; - MessageType_DecryptMessage = 51 [(wire_in) = true, deprecated = true]; - MessageType_DecryptedMessage = 52 [(wire_out) = true, deprecated = true]; - MessageType_SignIdentity = 53 [(wire_in) = true]; - MessageType_SignedIdentity = 54 [(wire_out) = true]; - MessageType_GetFeatures = 55 [(wire_in) = true]; - MessageType_EthereumGetAddress = 56 [(wire_in) = true]; - MessageType_EthereumAddress = 57 [(wire_out) = true]; - MessageType_EthereumSignTx = 58 [(wire_in) = true]; - MessageType_EthereumTxRequest = 59 [(wire_out) = true]; - MessageType_EthereumTxAck = 60 [(wire_in) = true]; - MessageType_GetECDHSessionKey = 61 [(wire_in) = true]; - MessageType_ECDHSessionKey = 62 [(wire_out) = true]; - MessageType_SetU2FCounter = 63 [(wire_in) = true]; - MessageType_EthereumSignMessage = 64 [(wire_in) = true]; - MessageType_EthereumVerifyMessage = 65 [(wire_in) = true]; - MessageType_EthereumMessageSignature = 66 [(wire_out) = true]; - MessageType_NEMGetAddress = 67 [(wire_in) = true]; - MessageType_NEMAddress = 68 [(wire_out) = true]; - MessageType_NEMSignTx = 69 [(wire_in) = true]; - MessageType_NEMSignedTx = 70 [(wire_out) = true]; - MessageType_CosiCommit = 71 [(wire_in) = true]; - MessageType_CosiCommitment = 72 [(wire_out) = true]; - MessageType_CosiSign = 73 [(wire_in) = true]; - MessageType_CosiSignature = 74 [(wire_out) = true]; - MessageType_NEMDecryptMessage = 75 [(wire_in) = true]; - MessageType_NEMDecryptedMessage = 76 [(wire_out) = true]; - MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true]; - MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true]; - MessageType_DebugLinkState = 102 [(wire_debug_out) = true]; - MessageType_DebugLinkStop = 103 [(wire_debug_in) = true]; - MessageType_DebugLinkLog = 104 [(wire_debug_out) = true]; - MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true]; - MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; - MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; - MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; - MessageType_SkycoinAddress = 114 [(wire_in) = true]; - MessageType_SkycoinCheckMessageSignature = 115 [(wire_in) = true]; - MessageType_SkycoinSignMessage = 116 [(wire_in) = true]; -} - -//////////////////// -// Basic messages // -//////////////////// - -/** - * Request: Reset device to default state and ask for device details - * @next Features - */ -message Initialize { - optional bytes state = 1; // assumed device state, clear session if set and different -} - -/** - * Request: Ask for device details (no device reset) - * @next Features - */ -message GetFeatures { -} - -/** - * Response: Reports various information about the device - * @prev Initialize - * @prev GetFeatures - */ -message Features { - optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" - optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 - optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 - optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 - optional bool bootloader_mode = 5; // is device in bootloader mode? - optional string device_id = 6; // device's unique identifier - optional bool pin_protection = 7; // is device protected by PIN? - optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? - optional string language = 9; // device language - optional string label = 10; // device description label - repeated CoinType coins = 11; // supported coins - optional bool initialized = 12; // does device contain seed? - optional bytes revision = 13; // SCM revision of firmware - optional bytes bootloader_hash = 14; // hash of the bootloader - optional bool imported = 15; // was storage imported from an external source? - optional bool pin_cached = 16; // is PIN already cached in session? - optional bool passphrase_cached = 17; // is passphrase already cached in session? - optional bool firmware_present = 18; // is valid firmware loaded? - optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) - optional uint32 flags = 20; // device flags (equals to Storage.flags) - optional string model = 21; // device hardware model - optional uint32 fw_major = 22; // reported firmware version if in bootloader mode - optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode - optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode - optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode - optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash) -} - -/** - * Request: clear session (removes cached PIN, passphrase, etc). - * @next Success - */ -message ClearSession { -} - -/** - * Request: change language and/or label of the device - * @next Success - * @next Failure - * @next ButtonRequest - * @next PinMatrixRequest - */ -message ApplySettings { - optional string language = 1; - optional string label = 2; - optional bool use_passphrase = 3; - optional bytes homescreen = 4; -} - -/** - * Request: set flags of the device - * @next Success - * @next Failure - */ -message ApplyFlags { - optional uint32 flags = 1; // bitmask, can only set bits, not unset -} - -/** - * Request: Starts workflow for setting/changing/removing the PIN - * @next ButtonRequest - * @next PinMatrixRequest - */ -message ChangePin { - optional bool remove = 1; // is PIN removal requested? -} - -/** - * Request: Generate a Skycoin or a Bitcoin address from a seed, device sends back the address in a Success message - * @next Success - */ -message SkycoinAddress { - required string seed = 1; // seed used to generate address - optional SkycoinAddressType address_type = 2; -} - - -/** - * Request: Check a message signature matches the given address. - * @next Success - */ -message SkycoinCheckMessageSignature { - required string address = 1; //address that was supposedly used to produce the signature - required string message = 2; //message that was signed - required string signature = 3; //electronic signature of the message -} - -/** - * Request: Sign a message digest using the given secret key. - * @next Success - */ -message SkycoinSignMessage { - required string secretKey = 1; //private address used to produce signature - required string message = 2; //message that we want to sign -} -/** - * Request: Test if the device is alive, device sends back the message in Success response - * @next Success - */ -message Ping { - optional string message = 1; // message to send back in Success message - optional bool button_protection = 2; // ask for button press - optional bool pin_protection = 3; // ask for PIN if set in device - optional bool passphrase_protection = 4; // ask for passphrase if set in device -} - -/** - * Response: Success of the previous request - */ -message Success { - optional string message = 1; // human readable description of action or request-specific payload -} - -/** - * Response: Failure of the previous request - */ -message Failure { - optional FailureType code = 1; // computer-readable definition of the error state - optional string message = 2; // human-readable message of the error state -} - -/** - * Response: Device is waiting for HW button press. - * @next ButtonAck - * @next Cancel - */ -message ButtonRequest { - optional ButtonRequestType code = 1; - optional string data = 2; -} - -/** - * Request: Computer agrees to wait for HW button press - * @prev ButtonRequest - */ -message ButtonAck { -} - -/** - * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme - * @next PinMatrixAck - * @next Cancel - */ -message PinMatrixRequest { - optional PinMatrixRequestType type = 1; -} - -/** - * Request: Computer responds with encoded PIN - * @prev PinMatrixRequest - */ -message PinMatrixAck { - required string pin = 1; // matrix encoded PIN entered by user -} - -/** - * Request: Abort last operation that required user interaction - * @prev ButtonRequest - * @prev PinMatrixRequest - * @prev PassphraseRequest - */ -message Cancel { -} - -/** - * Response: Device awaits encryption passphrase - * @next PassphraseAck - * @next Cancel - */ -message PassphraseRequest { - optional bool on_device = 1; // passphrase is being entered on the device -} - -/** - * Request: Send passphrase back - * @prev PassphraseRequest - * @next PassphraseStateRequest - */ -message PassphraseAck { - optional string passphrase = 1; - optional bytes state = 2; // expected device state -} - -/** - * @prev PassphraseAck - * @next PassphraseStateAck - */ -message PassphraseStateRequest { - optional bytes state = 1; // actual device state -} - -/** - * @prev PassphraseStateRequest - */ -message PassphraseStateAck { -} - -/** - * Request: Request a sample of random data generated by hardware RNG. May be used for testing. - * @next ButtonRequest - * @next Entropy - * @next Failure - */ -message GetEntropy { - required uint32 size = 1; // size of requested entropy -} - -/** - * Response: Reply with random data generated by internal RNG - * @prev GetEntropy - */ -message Entropy { - required bytes entropy = 1; // stream of random generated bytes -} - -/** - * Request: Ask device for public key corresponding to address_n path - * @next PassphraseRequest - * @next PublicKey - * @next Failure - */ -message GetPublicKey { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string ecdsa_curve_name = 2; // ECDSA curve name to use - optional bool show_display = 3; // optionally show on display before sending the result - optional string coin_name = 4 [default='Bitcoin']; -} - -/** - * Response: Contains public key derived from device private seed - * @prev GetPublicKey - */ -message PublicKey { - required HDNodeType node = 1; // BIP32 public node - optional string xpub = 2; // serialized form of public node -} - -/** - * Request: Ask device for address corresponding to address_n path - * @next PassphraseRequest - * @next Address - * @next Failure - */ -message GetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string coin_name = 2 [default='Bitcoin']; - optional bool show_display = 3 ; // optionally show on display before sending the result - optional MultisigRedeemScriptType multisig = 4; // filled if we are showing a multisig address - optional InputScriptType script_type = 5 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) -} - -/** - * Request: Ask device for Ethereum address corresponding to address_n path - * @next PassphraseRequest - * @next EthereumAddress - * @next Failure - */ -message EthereumGetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bool show_display = 2; // optionally show on display before sending the result -} - -/** - * Response: Contains address derived from device private seed - * @prev GetAddress - */ -message Address { - required string address = 1; // Coin address in Base58 encoding -} - -/** - * Response: Contains an Ethereum address derived from device private seed - * @prev EthereumGetAddress - */ -message EthereumAddress { - required bytes address = 1; // Coin address as an Ethereum 160 bit hash -} - -/** - * Request: Request device to wipe all sensitive data and settings - * @next ButtonRequest - */ -message WipeDevice { -} - -/** - * Request: Load seed and related internal settings from the computer - * @next ButtonRequest - * @next Success - * @next Failure - */ -message LoadDevice { - optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) - optional HDNodeType node = 2; // BIP-32 node - optional string pin = 3; // set PIN protection - optional bool passphrase_protection = 4; // enable master node encryption using passphrase - optional string language = 5 [default='english']; // device language - optional string label = 6; // device label - optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum - optional uint32 u2f_counter = 8; // U2F counter -} - -/** - * Request: Ask device to do initialization involving user interaction - * @next EntropyRequest - * @next Failure - */ -message ResetDevice { - optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy - optional uint32 strength = 2 [default=256]; // strength of seed in bits - optional bool passphrase_protection = 3; // enable master node encryption using passphrase - optional bool pin_protection = 4; // enable PIN protection - optional string language = 5 [default='english']; // device language - optional string label = 6; // device label - optional uint32 u2f_counter = 7; // U2F counter - optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow -} - -/** - * Request: Perform backup of the device seed if not backed up using ResetDevice - * @next ButtonRequest - */ -message BackupDevice { -} - -/** - * Response: Ask for additional entropy from host computer - * @prev ResetDevice - * @next EntropyAck - */ -message EntropyRequest { -} - -/** - * Request: Provide additional entropy for seed generation function - * @prev EntropyRequest - * @next ButtonRequest - */ -message EntropyAck { - optional bytes entropy = 1; // 256 bits (32 bytes) of random data -} - -/** - * Request: Start recovery workflow asking user for specific words of mnemonic - * Used to recovery device safely even on untrusted computer. - * @next WordRequest - */ -message RecoveryDevice { - optional uint32 word_count = 1; // number of words in BIP-39 mnemonic - optional bool passphrase_protection = 2; // enable master node encryption using passphrase - optional bool pin_protection = 3; // enable PIN protection - optional string language = 4 [default='english']; // device language - optional string label = 5; // device label - optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process - // 7 reserved for unused recovery method - optional uint32 type = 8; // supported recovery type (see RecoveryType) - optional uint32 u2f_counter = 9; // U2F counter - optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) -} - -/** - * Response: Device is waiting for user to enter word of the mnemonic - * Its position is shown only on device's internal display. - * @prev RecoveryDevice - * @prev WordAck - */ -message WordRequest { - optional WordRequestType type = 1; -} - -/** - * Request: Computer replies with word from the mnemonic - * @prev WordRequest - * @next WordRequest - * @next Success - * @next Failure - */ -message WordAck { - required string word = 1; // one word of mnemonic on asked position -} - -////////////////////////////// -// Message signing messages // -////////////////////////////// - -/** - * Request: Ask device to sign message - * @next MessageSignature - * @next Failure - */ -message SignMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes message = 2; // message to be signed - optional string coin_name = 3 [default='Bitcoin']; // coin to use for signing - optional InputScriptType script_type = 4 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) -} - -/** - * Request: Ask device to verify message - * @next Success - * @next Failure - */ -message VerifyMessage { - optional string address = 1; // address to verify - optional bytes signature = 2; // signature to verify - optional bytes message = 3; // message to verify - optional string coin_name = 4 [default='Bitcoin']; // coin to use for verifying -} - -/** - * Response: Signed message - * @prev SignMessage - */ -message MessageSignature { - optional string address = 1; // address used to sign the message - optional bytes signature = 2; // signature of the message -} - -/////////////////////////// -// Encryption/decryption // -/////////////////////////// - -/** - * Request: Ask device to encrypt message - * @next EncryptedMessage - * @next Failure - */ -message EncryptMessage { - optional bytes pubkey = 1; // public key - optional bytes message = 2; // message to encrypt - optional bool display_only = 3; // show just on display? (don't send back via wire) - repeated uint32 address_n = 4; // BIP-32 path to derive the signing key from master node - optional string coin_name = 5 [default='Bitcoin']; // coin to use for signing -} - -/** - * Response: Encrypted message - * @prev EncryptMessage - */ -message EncryptedMessage { - optional bytes nonce = 1; // nonce used during encryption - optional bytes message = 2; // encrypted message - optional bytes hmac = 3; // message hmac -} - -/** - * Request: Ask device to decrypt message - * @next Success - * @next Failure - */ -message DecryptMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the decryption key from master node - optional bytes nonce = 2; // nonce used during encryption - optional bytes message = 3; // message to decrypt - optional bytes hmac = 4; // message hmac -} - -/** - * Response: Decrypted message - * @prev DecryptedMessage - */ -message DecryptedMessage { - optional bytes message = 1; // decrypted message - optional string address = 2; // address used to sign the message (if used) -} - -/** - * Request: Ask device to encrypt or decrypt value of given key - * @next CipheredKeyValue - * @next Failure - */ -message CipherKeyValue { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string key = 2; // key component of key:value - optional bytes value = 3; // value component of key:value - optional bool encrypt = 4; // are we encrypting (True) or decrypting (False)? - optional bool ask_on_encrypt = 5; // should we ask on encrypt operation? - optional bool ask_on_decrypt = 6; // should we ask on decrypt operation? - optional bytes iv = 7; // initialization vector (will be computed if not set) -} - -/** - * Response: Return ciphered/deciphered value - * @prev CipherKeyValue - */ -message CipheredKeyValue { - optional bytes value = 1; // ciphered/deciphered value -} - -////////////////////////////////// -// Transaction signing messages // -////////////////////////////////// - -/** - * Request: Estimated size of the transaction - * This behaves exactly like SignTx, which means that it can ask using TxRequest - * This call is non-blocking (except possible PassphraseRequest to unlock the seed) - * @next TxSize - * @next Failure - */ -message EstimateTxSize { - required uint32 outputs_count = 1; // number of transaction outputs - required uint32 inputs_count = 2; // number of transaction inputs - optional string coin_name = 3 [default='Bitcoin']; // coin to use -} - -/** - * Response: Estimated size of the transaction - * @prev EstimateTxSize - */ -message TxSize { - optional uint32 tx_size = 1; // estimated size of transaction in bytes -} - -/** - * Request: Ask device to sign transaction - * @next PassphraseRequest - * @next PinMatrixRequest - * @next TxRequest - * @next Failure - */ -message SignTx { - required uint32 outputs_count = 1; // number of transaction outputs - required uint32 inputs_count = 2; // number of transaction inputs - optional string coin_name = 3 [default='Bitcoin']; // coin to use - optional uint32 version = 4 [default=1]; // transaction version - optional uint32 lock_time = 5 [default=0]; // transaction lock_time - optional uint32 decred_expiry = 6; -} - -/** - * Request: Simplified transaction signing - * This method doesn't support streaming, so there are hardware limits in number of inputs and outputs. - * In case of success, the result is returned using TxRequest message. - * @next PassphraseRequest - * @next PinMatrixRequest - * @next TxRequest - * @next Failure - */ -message SimpleSignTx { - repeated TxInputType inputs = 1; // transaction inputs - repeated TxOutputType outputs = 2; // transaction outputs - repeated TransactionType transactions = 3; // transactions whose outputs are used to build current inputs - optional string coin_name = 4 [default='Bitcoin']; // coin to use - optional uint32 version = 5 [default=1]; // transaction version - optional uint32 lock_time = 6 [default=0]; // transaction lock_time -} - -/** - * Response: Device asks for information for signing transaction or returns the last result - * If request_index is set, device awaits TxAck message (with fields filled in according to request_type) - * If signature_index is set, 'signature' contains signed input of signature_index's input - * @prev SignTx - * @prev SimpleSignTx - * @prev TxAck - */ -message TxRequest { - optional RequestType request_type = 1; // what should be filled in TxAck message? - optional TxRequestDetailsType details = 2; // request for tx details - optional TxRequestSerializedType serialized = 3; // serialized data and request for next -} - -/** - * Request: Reported transaction data - * @prev TxRequest - * @next TxRequest - */ -message TxAck { - optional TransactionType tx = 1; -} - -/** - * Request: Ask device to sign transaction - * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. - * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. - * @next PassphraseRequest - * @next PinMatrixRequest - * @next EthereumTxRequest - * @next Failure - */ -message EthereumSignTx { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bytes nonce = 2; // <=256 bit unsigned big endian - optional bytes gas_price = 3; // <=256 bit unsigned big endian (in wei) - optional bytes gas_limit = 4; // <=256 bit unsigned big endian - optional bytes to = 5; // 160 bit address hash - optional bytes value = 6; // <=256 bit unsigned big endian (in wei) - optional bytes data_initial_chunk = 7; // The initial data chunk (<= 1024 bytes) - optional uint32 data_length = 8; // Length of transaction payload - optional uint32 chain_id = 9; // Chain Id for EIP 155 -} - -/** - * Response: Device asks for more data from transaction payload, or returns the signature. - * If data_length is set, device awaits that many more bytes of payload. - * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. - * @prev EthereumSignTx - * @next EthereumTxAck - */ -message EthereumTxRequest { - optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) - optional uint32 signature_v = 2; // Computed signature (recovery parameter, limited to 27 or 28) - optional bytes signature_r = 3; // Computed signature R component (256 bit) - optional bytes signature_s = 4; // Computed signature S component (256 bit) -} - -/** - * Request: Transaction payload data. - * @prev EthereumTxRequest - * @next EthereumTxRequest - */ -message EthereumTxAck { - optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) -} - -//////////////////////////////////////// -// Ethereum: Message signing messages // -//////////////////////////////////////// - -/** - * Request: Ask device to sign message - * @next EthereumMessageSignature - * @next Failure - */ -message EthereumSignMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes message = 2; // message to be signed -} - -/** - * Request: Ask device to verify message - * @next Success - * @next Failure - */ -message EthereumVerifyMessage { - optional bytes address = 1; // address to verify - optional bytes signature = 2; // signature to verify - optional bytes message = 3; // message to verify -} - -/** - * Response: Signed message - * @prev EthereumSignMessage - */ -message EthereumMessageSignature { - optional bytes address = 1; // address used to sign the message - optional bytes signature = 2; // signature of the message -} - -/////////////////////// -// Identity messages // -/////////////////////// - -/** - * Request: Ask device to sign identity - * @next SignedIdentity - * @next Failure - */ -message SignIdentity { - optional IdentityType identity = 1; // identity - optional bytes challenge_hidden = 2; // non-visible challenge - optional string challenge_visual = 3; // challenge shown on display (e.g. date+time) - optional string ecdsa_curve_name = 4; // ECDSA curve name to use -} - -/** - * Response: Device provides signed identity - * @prev SignIdentity - */ -message SignedIdentity { - optional string address = 1; // identity address - optional bytes public_key = 2; // identity public key - optional bytes signature = 3; // signature of the identity data -} - -/////////////////// -// ECDH messages // -/////////////////// - -/** - * Request: Ask device to generate ECDH session key - * @next ECDHSessionKey - * @next Failure - */ -message GetECDHSessionKey { - optional IdentityType identity = 1; // identity - optional bytes peer_public_key = 2; // peer's public key - optional string ecdsa_curve_name = 3; // ECDSA curve name to use -} - -/** - * Response: Device provides ECDH session key - * @prev GetECDHSessionKey - */ -message ECDHSessionKey { - optional bytes session_key = 1; // ECDH session key -} - -/////////////////// -// U2F messages // -/////////////////// - -/** - * Request: Set U2F counter - * @next Success - */ -message SetU2FCounter { - optional uint32 u2f_counter = 1; // counter -} - -///////////////////////// -// Bootloader messages // -///////////////////////// - -/** - * Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload) - * @next Success - * @next FirmwareRequest - * @next Failure - */ -message FirmwareErase { - optional uint32 length = 1; // length of new firmware -} - -/** - * Response: Ask for firmware chunk - * @next FirmwareUpload - */ -message FirmwareRequest { - optional uint32 offset = 1; // offset of requested firmware chunk - optional uint32 length = 2; // length of requested firmware chunk -} - -/** - * Request: Send firmware in binary form to the device - * @next Success - * @next Failure - */ -message FirmwareUpload { - required bytes payload = 1; // firmware to be loaded into device - optional bytes hash = 2; // hash of the payload -} - - -/** - * Request: Perform a device self-test - * @next Success - * @next Failure - */ -message SelfTest { - optional bytes payload = 1; // payload to be used in self-test -} - -////////////////// -// NEM messages // -////////////////// - -/** - * Request: Ask device for NEM address corresponding to address_n path - * @next PassphraseRequest - * @next NEMAddress - * @next Failure - */ -message NEMGetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) - optional bool show_display = 3; // Optionally show on display before sending the result -} - -/** - * Response: Contains NEM address derived from device private seed - * @prev NEMGetAddress - */ -message NEMAddress { - required string address = 1; // NEM address in Base32 encoding -} - -/** - * Request: Ask device to sign transaction - * @next NEMSignedTx - * @next Failure - */ -message NEMSignTx { - optional NEMTransactionCommon transaction = 1; // Common part of transaction - optional NEMTransactionCommon multisig = 2; // Common part of inner transaction for multisig transactions - optional NEMTransfer transfer = 3; // Transfer transaction part - optional bool cosigning = 4; // Whether cosigning or initiating the multisig transaction - optional NEMProvisionNamespace provision_namespace = 5; // Provision namespace part - optional NEMMosaicCreation mosaic_creation = 6; // Mosaic definition creation part - optional NEMMosaicSupplyChange supply_change = 7; // Mosaic supply change part - optional NEMAggregateModification aggregate_modification = 8; // Aggregate modification part - optional NEMImportanceTransfer importance_transfer = 9; // Importance transfer part -} - -/** - * Response: Contains NEM transaction data and signature - * @prev NEMSignTx - */ -message NEMSignedTx { - optional bytes data = 1; // Transaction data - optional bytes signature = 2; // Signature for the transaction -} - -/** - * Request: Ask device to decrypt NEM transaction payload - * @next NEMDecryptedMessage - * @next Failure - */ -message NEMDecryptMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional uint32 network = 2; // Network ID (0x68 = Mainnet, 0x98 = Testnet, 0x60 = Mijin) - optional bytes public_key = 3; // Public key of the other party - optional bytes payload = 4; // Actual message data (encrypted) -} - -/** - * Response: Contains decrypted NEM transaction payload - * @prev NEMDecryptMessage - */ -message NEMDecryptedMessage { - optional bytes payload = 1; // Actual message data (unencrypted) -} - -/////////////////// -// CoSi messages // -/////////////////// - -/** - * Request: Ask device to commit to CoSi signing - * @next CosiCommitment - * @next Failure - */ -message CosiCommit { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bytes data = 2; // Data to be signed -} - -/** - * Response: Contains a CoSi commitment - * @prev CosiCommit - */ -message CosiCommitment { - optional bytes commitment = 1; // Commitment - optional bytes pubkey = 2; // Public key -} - -/** - * Request: Ask device to sign using CoSi - * @next CosiSignature - * @next Failure - */ -message CosiSign { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bytes data = 2; // Data to be signed - optional bytes global_commitment = 3; // Aggregated commitment - optional bytes global_pubkey = 4; // Aggregated public key -} - -/** - * Response: Contains a CoSi signature - * @prev CosiSign - */ -message CosiSignature { - optional bytes signature = 1; // Signature -} - -///////////////////////////////////////////////////////////// -// Debug messages (only available if DebugLink is enabled) // -///////////////////////////////////////////////////////////// - -/** - * Request: "Press" the button on the device - * @next Success - */ -message DebugLinkDecision { - required bool yes_no = 1; // true for "Confirm", false for "Cancel" -} - -/** - * Request: Computer asks for device state - * @next DebugLinkState - */ -message DebugLinkGetState { -} - -/** - * Response: Device current state - * @prev DebugLinkGetState - */ -message DebugLinkState { - optional bytes layout = 1; // raw buffer of display - optional string pin = 2; // current PIN, blank if PIN is not set/enabled - optional string matrix = 3; // current PIN matrix - optional string mnemonic = 4; // current BIP-39 mnemonic - optional HDNodeType node = 5; // current BIP-32 node - optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase? - optional string reset_word = 7; // word on device display during ResetDevice workflow - optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow - optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow - optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow -} - -/** - * Request: Ask device to restart - */ -message DebugLinkStop { -} - -/** - * Response: Device wants host to log event - */ -message DebugLinkLog { - optional uint32 level = 1; - optional string bucket = 2; - optional string text = 3; -} - -/** - * Request: Read memory from device - * @next DebugLinkMemory - */ -message DebugLinkMemoryRead { - optional uint32 address = 1; - optional uint32 length = 2; -} - -/** - * Response: Device sends memory back - * @prev DebugLinkMemoryRead - */ -message DebugLinkMemory { - optional bytes memory = 1; -} - -/** - * Request: Write memory to device. - * WARNING: Writing to the wrong location can irreparably break the device. - */ -message DebugLinkMemoryWrite { - optional uint32 address = 1; - optional bytes memory = 2; - optional bool flash = 3; -} - -/** - * Request: Erase block of flash on device - * WARNING: Writing to the wrong location can irreparably break the device. - */ -message DebugLinkFlashErase { - optional uint32 sector = 1; -} diff --git a/hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto b/hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto new file mode 120000 index 00000000..16986e93 --- /dev/null +++ b/hardware-wallet/go-api-for-hardware-wallet/protob/messages.proto @@ -0,0 +1 @@ +/home/mbenthaier/my_projects/skycoin/services/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto \ No newline at end of file From 49d4365f48e1435907303bd3727f9730e79d4f57 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 25 Apr 2018 19:09:28 +0800 Subject: [PATCH 61/73] Adding function fsm_getKeyPairAtIndex and remove the code added in fsm_msgSkycoinAddress in that function --- hardware-wallet/firmware/firmware/fsm.c | 49 ++++++++++++------------- hardware-wallet/firmware/firmware/fsm.h | 1 + 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/hardware-wallet/firmware/firmware/fsm.c b/hardware-wallet/firmware/firmware/fsm.c index bd14a075..0ba71927 100644 --- a/hardware-wallet/firmware/firmware/fsm.c +++ b/hardware-wallet/firmware/firmware/fsm.c @@ -346,6 +346,25 @@ void fsm_msgSkycoinCheckMessageSignature(SkycoinCheckMessageSignature* msg) msg_write(MessageType_MessageType_Success, resp); } +int fsm_getKeyPairAtIndex(uint32_t index, uint8_t* pubkey, uint8_t* seckey) +{ + const uint8_t* mnemo = storage_getSeed(false); + char seed[64] = {0}; + uint8_t nextSeed[SHA256_DIGEST_LENGTH] = {0}; + if (mnemo == NULL) + { + return -1; + } + memcpy(seed, mnemo, sizeof(seed)); + for (uint8_t i = 0; i < index; ++i) + { + memcpy(seed, nextSeed, 32); + seed[32] = 0; + generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); + } + return 0; +} + void fsm_msgSkycoinSignMessage(SkycoinSignMessage* msg) { uint8_t seckey[32] = {0}; @@ -380,35 +399,21 @@ void fsm_msgSkycoinAddress(SkycoinAddress* msg) RESP_INIT(Success); // reset_entropy((const uint8_t*)msg->seed, strlen(msg->seed)); - const uint8_t* mnemo = storage_getSeed(false); - char seed[64] = {0}; - uint8_t nextSeed[SHA256_DIGEST_LENGTH] = {0}; - if (msg->has_address_type && mnemo != NULL) + if (msg->has_address_type && fsm_getKeyPairAtIndex(msg->address_n, pubkey, seckey) == 0) { char address[256] = {0}; size_t size_address = sizeof(address); - memcpy(seed, mnemo, sizeof(seed)); - for (uint8_t i = 0; i < msg->address_n; ++i) - { - memcpy(seed, nextSeed, 32); - seed[32] = 0; - generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); - } switch (msg->address_type) { case SkycoinAddressType_AddressTypeSkycoin: layoutRawMessage("Skycoin address"); generate_base58_address_from_pubkey(pubkey, address, &size_address); - // memcpy(resp->message, address, size_address); - tohex(resp->message, nextSeed, SHA256_DIGEST_LENGTH); - // memcpy(resp->message, mnemo, sizeof(resp->message)); + memcpy(resp->message, address, size_address); break; case SkycoinAddressType_AddressTypeBitcoin: layoutRawMessage("Bitcoin address"); generate_bitcoin_address_from_pubkey(pubkey, address, &size_address); - // memcpy(resp->message, address, size_address); - tohex(resp->message, nextSeed, SHA256_DIGEST_LENGTH); - // memcpy(resp->message, mnemo, sizeof(resp->message)); + memcpy(resp->message, address, size_address); break; default: layoutRawMessage("Unknown address type"); @@ -416,16 +421,8 @@ void fsm_msgSkycoinAddress(SkycoinAddress* msg) } } else { - generate_deterministic_key_pair_iterator((const char*)mnemo, nextSeed, seckey, pubkey); tohex(resp->message, pubkey, 33); - if (mnemo == NULL) - { - layoutRawMessage("Empty mnemonic"); - } - else - { - layoutRawMessage(resp->message); - } + layoutRawMessage(resp->message); } resp->has_message = true; msg_write(MessageType_MessageType_Success, resp); diff --git a/hardware-wallet/firmware/firmware/fsm.h b/hardware-wallet/firmware/firmware/fsm.h index c7697bb1..8577ceed 100644 --- a/hardware-wallet/firmware/firmware/fsm.h +++ b/hardware-wallet/firmware/firmware/fsm.h @@ -36,6 +36,7 @@ void fsm_sendFailure(FailureType code, const char *text); void fsm_msgInitialize(Initialize *msg); void fsm_msgGetFeatures(GetFeatures *msg); +int fsm_getKeyPairAtIndex(uint32_t index, uint8_t* pubkey, uint8_t* seckey); void fsm_msgSkycoinCheckMessageSignature(SkycoinCheckMessageSignature* msg); void fsm_msgSkycoinSignMessage(SkycoinSignMessage* msg); void fsm_msgSkycoinAddress(SkycoinAddress* msg); From bc691cb84f0d23b4541424d660b7abcc806a0dd7 Mon Sep 17 00:00:00 2001 From: mpsido <1979371837@qq.com> Date: Fri, 27 Apr 2018 15:40:41 +0800 Subject: [PATCH 62/73] Adding README.md file for hardware-wallet --- hardware-wallet/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 hardware-wallet/README.md diff --git a/hardware-wallet/README.md b/hardware-wallet/README.md new file mode 100644 index 00000000..40648756 --- /dev/null +++ b/hardware-wallet/README.md @@ -0,0 +1,8 @@ +This folder provides a firmware implementing skycoin features, and tools to test it. + +The firmware it self is under [firmware](https://github.com/skycoin/services/tree/hardware-wallet/hardware-wallet/firmware) folder. +The firmware had been copied and modified from [this repository](https://github.com/trezor/trezor-mcu). + +The [skycoin-api](https://github.com/skycoin/services/tree/hardware-wallet/hardware-wallet/skycoin-api) folder contains the definition of the functions implementing the skycoin features. + +The [go-api-for-hardware-wallet](https://github.com/skycoin/services/tree/hardware-wallet/hardware-wallet/go-api-for-hardware-wallet) defines functions that act as code example to communicate with the firmware using a golang code. From 154dc4078e39d9882969af3c97c14c89754b76c8 Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 27 Apr 2018 15:50:10 +0800 Subject: [PATCH 63/73] moving README.md from skycoin-api to firmware and refer to trezor-mcu's firmware --- hardware-wallet/firmware/README.md | 170 +++++++++++++++++++------- hardware-wallet/skycoin-api/README.md | 150 ----------------------- 2 files changed, 128 insertions(+), 192 deletions(-) delete mode 100644 hardware-wallet/skycoin-api/README.md diff --git a/hardware-wallet/firmware/README.md b/hardware-wallet/firmware/README.md index bc8d47ea..0029c93c 100644 --- a/hardware-wallet/firmware/README.md +++ b/hardware-wallet/firmware/README.md @@ -1,66 +1,152 @@ -# TREZOR Firmware +This repository had been copied and modified from [trezor-mcu](https://github.com/trezor/trezor-mcu). Please refer to the [README.md file](https://github.com/trezor/trezor-mcu/blob/master/README.md) on that repository for extra details about bootloader and firmware compilation. -[![Build Status](https://travis-ci.org/trezor/trezor-mcu.svg?branch=master)](https://travis-ci.org/trezor/trezor-mcu) [![gitter](https://badges.gitter.im/trezor/community.svg)](https://gitter.im/trezor/community) +Even though this repo is pushed here it is (for now) intended to be a submodule of [trezor-mcu repository](https://github.com/trezor/trezor-mcu). -https://trezor.io/ +Trezor-mcu contains firmware and bootloader code example for STM32 hardware. -## How to build TREZOR firmware? +This code aims at tranforming the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher) into firmware for the STM32 hardware. -1. [Install Docker](https://docs.docker.com/engine/installation/) -2. `git clone https://github.com/trezor/trezor-mcu.git` -3. `cd trezor-mcu` -4. `./build-firmware.sh TAG` (where TAG is v1.5.0 for example, if left blank the script builds latest commit in master branch) -This creates file `build/trezor-TAG.bin` and prints its fingerprint and size at the end of the build log. +# How to compile for firmware -## How to build TREZOR emulator for Linux? +## 1. Clone trezor-mcu from this github account -1. [Install Docker](https://docs.docker.com/engine/installation/) -2. `git clone https://github.com/trezor/trezor-mcu.git` -3. `cd trezor-mcu` -4. `./build-emulator.sh TAG` (where TAG is v1.5.0 for example, if left blank the script builds latest commit in master branch) + git clone https://github.com/mpsido/trezor-skycoin.git + cd trezor-skycoin -This creates binary file `build/trezor-emulator-TAG`, which can be run and works as a trezor emulator. (Use `TREZOR_OLED_SCALE` env. variable to make screen bigger.) +You should be on a branch called skycoin -## How to build TREZOR bootloader? +## 2. Prepare environment -1. [Install Docker](https://docs.docker.com/engine/installation/) -2. `git clone https://github.com/trezor/trezor-mcu.git` -3. `cd trezor-mcu` -4. `./build-bootloader.sh TAG` (where TAG is bl1.3.2 for example, if left blank the script builds latest commit in master branch) +#### Download GNU ARM Embedded Toolchain -This creates file `build/bootloader-TAG.bin` and prints its fingerprint and size at the end of the build log. + wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 -## How to get fingerprint of firmware signed and distributed by SatoshiLabs? +#### Extract crosscompiler and add it to your path -1. Pick version of firmware binary listed on https://wallet.trezor.io/data/firmware/releases.json -2. Download it: `wget -O trezor.signed.bin https://wallet.trezor.io/data/firmware/trezor-1.3.6.bin` -3. Compute fingerprint: `tail -c +257 trezor.signed.bin | sha256sum` + tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 + export PATH="gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH" -Step 3 should produce the same sha256 fingerprint like your local build (for the same version tag). Firmware has a special header (of length 256 bytes) holding signatures themselves, which must be avoided while calculating the fingerprint, that's why tail command has to be used. +## 3. Compile the sources -## How to install custom built firmware? +The steps are the following, you can create a make_firmware.sh file with this content. -**WARNING: This will erase the recovery seed stored on the device! You should never do this on TREZOR that contains coins!** + #this option is important, it prevents the bootloader from locking the firmware in case its signature is wrong + export MEMORY_PROTECT=0 + make -C vendor/libopencm3/ + make -C vendor/nanopb/generator/proto/ + make -C firmware/protob/ + make -C vendor/skycoin-crypto/ + make + #Merge the bootloader and the firmware into one file + make -C bootloader/ align + make -C firmware/ sign + cp bootloader/bootloader.bin bootloader/combine/bl.bin + cp firmware/trezor.bin bootloader/combine/fw.bin + pushd bootloader/combine/ && ./prepare.py + popd; -1. Install python-trezor: `pip install trezor` ([more info](https://github.com/trezor/python-trezor)) -2. `trezorctl firmware_update -f build/trezor-TAG.bin` +The output binary file is combined.bin located in bootloader/combine -## Building for development -If you want to build device firmware, make sure you have the -[GNU ARM Embedded toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads) installed. +# How to burn the firmware in the device -* If you want to build the emulator instead of the firmware, run `export EMULATOR=1 TREZOR_TRANSPORT_V1=1` -* If you want to build with the debug link, run `export DEBUG_LINK=1`. Use this if you want to run the device tests. -* When you change these variables, use `script/setup` to clean the repository +## 1. Install ST-LINK -1. To initialize the repository, run `script/setup` -2. To build the firmware or emulator, run `script/cibuild` +Follow the steps [here](https://github.com/texane/stlink/blob/master/doc/compiling.md). -If you are building device firmware, the firmware will be in `firmware/trezor.bin`. +## 2. Use ST-LINK to burn the device -You can launch the emulator using `firmware/trezor.elf`. To use `trezorctl` with the emulator, use -`trezorctl -t udp` (for example, `trezorctl -t udp get_features`). +You can check the device is seen by your ST-LINK using this command: -If `trezorctl -t udp` appears to hang, make sure you have run `export TREZOR_TRANSPORT_V1=1`. + st-info --probe + +To flash the device on a microcontroller of STM32f2xx family the command is: + + st-flash write combined.bin 0x08000000; + +# Communicate with the device using the command line + +## 1. Download the python-trezor repository + + cd .. + git clone https://github.com/mpsido/python-trezor.git + cd python-trezor + +## 2. Install dependencies + +You need superuser priviledges for this step. + + sudo apt-get -y install python-dev cython libusb-1.0-0-dev libudev-dev (note: required for python-trezor testing) + +## 3. Configure your usb module + +We need to tell your kernel to use the [hidraw module](https://www.kernel.org/doc/Documentation/hid/hidraw.txt) to communicate with the hardware device. If you don't your kernel will treat the device as a mouse or a keyboard. + +Create a file named 99-dev-kit.rules in your /etc/udev/rules.d/ folder and write this content in that file (super user priviledges are required for this step). + + # 0483:df11 STMicroelectronics STM Device in DFU Mode + SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", MODE="0666" + # 0483:3748 STMicroelectronics ST-LINK/V2 + SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", MODE="0666" + # 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) + SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374b", MODE="0666" + # 534c:0001 SatoshiLabs Bitcoin Wallet [TREZOR] + SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0666" + KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0666" + # 1209:53c0 SatoshiLabs TREZOR v2 Bootloader + SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c0", MODE="0666" + KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c0", MODE="0666" + # 1209:53c1 SatoshiLabs TREZOR v2 + SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c1", MODE="0666" + KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", MODE="0666" + +Restart your machine or force your udev kernel module to [reload the rules](https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot). + +If when you plug the device your OS is not seeing the device, skip the warning on device's screen saying that the signature is wrong and then try [this](https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line). + +## 4. Generate a skycoin address from seed + + ./trezorctl skycoin_address seed + +# How to compile and run tests + +## Trezor-crypto + +This repository includes header files coming from [Trezor-crypto](https://github.com/trezor/trezor-crypto/) repository. + +Download the repository + + git clone git@github.com:trezor/trezor-crypto.git + +Then setup the TREZOR_CRYPTO_PATH environment variable: + + export TREZOR_CRYPTO_PATH=$PWD/trezor-crypto + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TREZOR_CRYPTO_PATH + + +The dependancy libTrezorCrypto.a can be recompiled from sources. + +Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" + +Then run : + + make + ar rcs libTrezorCrypto.a $(find -name "*.o") + +## Check + +The source code necessary to compile libcheck.a can be downloaded from [this repository](https://github.com/libcheck/check) +Download the repository + + git clone git@github.com:libcheck/check.git + +Then setup the TREZOR_CRYPTO_PATH environment variable: + + export CHECK_PATH=$PWD/check + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CHECK_PATH + +## Make and run ! + + make + ./test_skycoin_crypto diff --git a/hardware-wallet/skycoin-api/README.md b/hardware-wallet/skycoin-api/README.md deleted file mode 100644 index e073b049..00000000 --- a/hardware-wallet/skycoin-api/README.md +++ /dev/null @@ -1,150 +0,0 @@ -Even though this repo is pushed here it is (for now) intended to be a submodule of [trezor-mcu repository](https://github.com/trezor/trezor-mcu). - -Trezor-mcu contains firmware and bootloader code example for STM32 hardware. - -This code aims at tranforming the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher) into firmware for the STM32 hardware. - - -# How to compile for firmware - -## 1. Clone trezor-mcu from this github account - - git clone https://github.com/mpsido/trezor-skycoin.git - cd trezor-skycoin - -You should be on a branch called skycoin - -## 2. Prepare environment - -#### Download GNU ARM Embedded Toolchain - - wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 - -#### Extract crosscompiler and add it to your path - - tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 - export PATH="gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH" - -## 3. Compile the sources - -The steps are the following, you can create a make_firmware.sh file with this content. - - #this option is important, it prevents the bootloader from locking the firmware in case its signature is wrong - export MEMORY_PROTECT=0 - make -C vendor/libopencm3/ - make -C vendor/nanopb/generator/proto/ - make -C firmware/protob/ - make -C vendor/skycoin-crypto/ - make - #Merge the bootloader and the firmware into one file - make -C bootloader/ align - make -C firmware/ sign - cp bootloader/bootloader.bin bootloader/combine/bl.bin - cp firmware/trezor.bin bootloader/combine/fw.bin - pushd bootloader/combine/ && ./prepare.py - popd; - -The output binary file is combined.bin located in bootloader/combine - - -# How to burn the firmware in the device - -## 1. Install ST-LINK - -Follow the steps [here](https://github.com/texane/stlink/blob/master/doc/compiling.md). - -## 2. Use ST-LINK to burn the device - -You can check the device is seen by your ST-LINK using this command: - - st-info --probe - -To flash the device on a microcontroller of STM32f2xx family the command is: - - st-flash write combined.bin 0x08000000; - -# Communicate with the device using the command line - -## 1. Download the python-trezor repository - - cd .. - git clone https://github.com/mpsido/python-trezor.git - cd python-trezor - -## 2. Install dependencies - -You need superuser priviledges for this step. - - sudo apt-get -y install python-dev cython libusb-1.0-0-dev libudev-dev (note: required for python-trezor testing) - -## 3. Configure your usb module - -We need to tell your kernel to use the [hidraw module](https://www.kernel.org/doc/Documentation/hid/hidraw.txt) to communicate with the hardware device. If you don't your kernel will treat the device as a mouse or a keyboard. - -Create a file named 99-dev-kit.rules in your /etc/udev/rules.d/ folder and write this content in that file (super user priviledges are required for this step). - - # 0483:df11 STMicroelectronics STM Device in DFU Mode - SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", MODE="0666" - # 0483:3748 STMicroelectronics ST-LINK/V2 - SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", MODE="0666" - # 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) - SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374b", MODE="0666" - # 534c:0001 SatoshiLabs Bitcoin Wallet [TREZOR] - SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0666" - KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0666" - # 1209:53c0 SatoshiLabs TREZOR v2 Bootloader - SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c0", MODE="0666" - KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c0", MODE="0666" - # 1209:53c1 SatoshiLabs TREZOR v2 - SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c1", MODE="0666" - KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", MODE="0666" - -Restart your machine or force your udev kernel module to [reload the rules](https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot). - -If when you plug the device your OS is not seeing the device, skip the warning on device's screen saying that the signature is wrong and then try [this](https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line). - -## 4. Generate a skycoin address from seed - - ./trezorctl skycoin_address seed - -# How to compile and run tests - -## Trezor-crypto - -This repository includes header files coming from [Trezor-crypto](https://github.com/trezor/trezor-crypto/) repository. - -Download the repository - - git clone git@github.com:trezor/trezor-crypto.git - -Then setup the TREZOR_CRYPTO_PATH environment variable: - - export TREZOR_CRYPTO_PATH=$PWD/trezor-crypto - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TREZOR_CRYPTO_PATH - - -The dependancy libTrezorCrypto.a can be recompiled from sources. - -Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" - -Then run : - - make - ar rcs libTrezorCrypto.a $(find -name "*.o") - -## Check - -The source code necessary to compile libcheck.a can be downloaded from [this repository](https://github.com/libcheck/check) -Download the repository - - git clone git@github.com:libcheck/check.git - -Then setup the TREZOR_CRYPTO_PATH environment variable: - - export CHECK_PATH=$PWD/check - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CHECK_PATH - -## Make and run ! - - make - ./test_skycoin_crypto From ef483dbbcd1ef2e98dc8ee20dbcb385d8b591e24 Mon Sep 17 00:00:00 2001 From: mpsido Date: Fri, 27 Apr 2018 16:01:03 +0800 Subject: [PATCH 64/73] Re-adding README.md file in skycoin-api folder --- hardware-wallet/skycoin-api/README.md | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 hardware-wallet/skycoin-api/README.md diff --git a/hardware-wallet/skycoin-api/README.md b/hardware-wallet/skycoin-api/README.md new file mode 100644 index 00000000..0e960683 --- /dev/null +++ b/hardware-wallet/skycoin-api/README.md @@ -0,0 +1,49 @@ + +This code aims at tranforming the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher) into firmware for the STM32 hardware. + +# How to compile and run tests + +## Trezor-crypto + +This repository includes header files coming from [Trezor-crypto](https://github.com/trezor/trezor-crypto/) repository. + +These files are however available on this repository as a dependency of the firmware [here](https://github.com/skycoin/services/tree/hardware-wallet/hardware-wallet/firmware/vendor/trezor-crypto). + +Setup the TREZOR_CRYPTO_PATH environment variable: + + export TREZOR_CRYPTO_PATH=$PWD/services/hardware-wallet/firmware/vendor/trezor-crypto + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TREZOR_CRYPTO_PATH + + +Warning: If the files were compiled for arm target you may need to clean them. + +Add this line to the CFLAGS of this [Makefile](https://github.com/skycoin/services/blob/hardware-wallet/hardware-wallet/firmware/vendor/trezor-crypto/Makefile): "CFLAGS += -DUSE_BN_PRINT=1" + + cd $TREZOR_CRYPTO_PATH + make clean + make + + +If you prefer compiling a static library libTrezorCrypto.a from sources: + +Then run : + + make + ar rcs libTrezorCrypto.a $(find -name "*.o") + +## Check + +The source code necessary to compile libcheck.a can be downloaded from [this repository](https://github.com/libcheck/check) +Download the repository + + git clone git@github.com:libcheck/check.git + +Then setup the TREZOR_CRYPTO_PATH environment variable: + + export CHECK_PATH=$PWD/check + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CHECK_PATH + +## Make and run ! + + make + ./test_skycoin_crypto \ No newline at end of file From 4a051d1d2f922d5591a4af67bba3ab6e6fca562c Mon Sep 17 00:00:00 2001 From: mpsido <1979371837@qq.com> Date: Fri, 27 Apr 2018 16:18:53 +0800 Subject: [PATCH 65/73] Update README.md --- hardware-wallet/firmware/README.md | 118 +++++++---------------------- 1 file changed, 27 insertions(+), 91 deletions(-) diff --git a/hardware-wallet/firmware/README.md b/hardware-wallet/firmware/README.md index 0029c93c..7caf9cf4 100644 --- a/hardware-wallet/firmware/README.md +++ b/hardware-wallet/firmware/README.md @@ -7,16 +7,7 @@ Trezor-mcu contains firmware and bootloader code example for STM32 hardware. This code aims at tranforming the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher) into firmware for the STM32 hardware. -# How to compile for firmware - -## 1. Clone trezor-mcu from this github account - - git clone https://github.com/mpsido/trezor-skycoin.git - cd trezor-skycoin - -You should be on a branch called skycoin - -## 2. Prepare environment +# 1. Prepare environment #### Download GNU ARM Embedded Toolchain @@ -27,63 +18,15 @@ You should be on a branch called skycoin tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 export PATH="gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH" -## 3. Compile the sources - -The steps are the following, you can create a make_firmware.sh file with this content. - - #this option is important, it prevents the bootloader from locking the firmware in case its signature is wrong - export MEMORY_PROTECT=0 - make -C vendor/libopencm3/ - make -C vendor/nanopb/generator/proto/ - make -C firmware/protob/ - make -C vendor/skycoin-crypto/ - make - #Merge the bootloader and the firmware into one file - make -C bootloader/ align - make -C firmware/ sign - cp bootloader/bootloader.bin bootloader/combine/bl.bin - cp firmware/trezor.bin bootloader/combine/fw.bin - pushd bootloader/combine/ && ./prepare.py - popd; - -The output binary file is combined.bin located in bootloader/combine - - -# How to burn the firmware in the device - -## 1. Install ST-LINK +#### Install ST-LINK Follow the steps [here](https://github.com/texane/stlink/blob/master/doc/compiling.md). -## 2. Use ST-LINK to burn the device - -You can check the device is seen by your ST-LINK using this command: - - st-info --probe - -To flash the device on a microcontroller of STM32f2xx family the command is: - - st-flash write combined.bin 0x08000000; - -# Communicate with the device using the command line - -## 1. Download the python-trezor repository - - cd .. - git clone https://github.com/mpsido/python-trezor.git - cd python-trezor - -## 2. Install dependencies - -You need superuser priviledges for this step. - - sudo apt-get -y install python-dev cython libusb-1.0-0-dev libudev-dev (note: required for python-trezor testing) - -## 3. Configure your usb module +#### Configure your usb module We need to tell your kernel to use the [hidraw module](https://www.kernel.org/doc/Documentation/hid/hidraw.txt) to communicate with the hardware device. If you don't your kernel will treat the device as a mouse or a keyboard. -Create a file named 99-dev-kit.rules in your /etc/udev/rules.d/ folder and write this content in that file (super user priviledges are required for this step). +Create a file named 99-dev-kit.rules in your /etc/udev/rules.d/ folder and write this content in that file (*super user priviledges are required for this step*). # 0483:df11 STMicroelectronics STM Device in DFU Mode SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", MODE="0666" @@ -103,50 +46,43 @@ Create a file named 99-dev-kit.rules in your /etc/udev/rules.d/ folder and write Restart your machine or force your udev kernel module to [reload the rules](https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot). -If when you plug the device your OS is not seeing the device, skip the warning on device's screen saying that the signature is wrong and then try [this](https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line). - -## 4. Generate a skycoin address from seed +# 2. How to compile firmware - ./trezorctl skycoin_address seed + cd firmware + . make_firmware.sh -# How to compile and run tests +# 3. How to burn the firmware in the device -## Trezor-crypto +## Use ST-LINK to burn the device -This repository includes header files coming from [Trezor-crypto](https://github.com/trezor/trezor-crypto/) repository. - -Download the repository - - git clone git@github.com:trezor/trezor-crypto.git - -Then setup the TREZOR_CRYPTO_PATH environment variable: +You can check the device is seen by your ST-LINK using this command: - export TREZOR_CRYPTO_PATH=$PWD/trezor-crypto - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TREZOR_CRYPTO_PATH + st-info --probe +To flash the device on a microcontroller of STM32f2xx family the command is: -The dependancy libTrezorCrypto.a can be recompiled from sources. + st-flash write combined.bin 0x08000000; + +If you sourced the make_firmware.sh file as recommended. You can use the alias st-trezor to burn the device. -Add this line to the CFLAGS: "CFLAGS += -DUSE_BN_PRINT=1" + st-trezor -Then run : +# 4. Communicate with the device - make - ar rcs libTrezorCrypto.a $(find -name "*.o") +## Skip the wrong firmware signature warning -## Check +We are compiling a modified version of trezor original firmware. The bootloader we are using is configured to detect it and warn the user about this. +We are still in developpement steps, this warning is acceptable. +The devices allows the user to skip the warning but during that time the OS of the host computer may skip the opportunity to load the driver to communicate with the device. -The source code necessary to compile libcheck.a can be downloaded from [this repository](https://github.com/libcheck/check) -Download the repository +If when you plug the device your OS is not seeing the device, skip the warning on device's screen saying that the signature is wrong and then try [this](https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line). - git clone git@github.com:libcheck/check.git +If you are fast enough you can also quickly click the button "accept" on the device when the warning about wrong firmware signature appears. -Then setup the TREZOR_CRYPTO_PATH environment variable: +## Use golang code examples - export CHECK_PATH=$PWD/check - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CHECK_PATH +Check [here](https://github.com/skycoin/services/tree/hardware-wallet/hardware-wallet/go-api-for-hardware-wallet) for golang code example communicating with the device. -## Make and run ! +Feel free to hack [main.go](https://github.com/skycoin/services/blob/hardware-wallet/hardware-wallet/go-api-for-hardware-wallet/main.go) file. - make - ./test_skycoin_crypto +You can also try the trezorctl [python based command line](https://github.com/trezor/python-trezor). From 07b130d37b52bf3b5d16673951019e8bb9216892 Mon Sep 17 00:00:00 2001 From: mpsido <1979371837@qq.com> Date: Fri, 27 Apr 2018 16:25:16 +0800 Subject: [PATCH 66/73] Removing deprecated sentences from the README.md --- hardware-wallet/firmware/README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hardware-wallet/firmware/README.md b/hardware-wallet/firmware/README.md index 7caf9cf4..f934f448 100644 --- a/hardware-wallet/firmware/README.md +++ b/hardware-wallet/firmware/README.md @@ -1,9 +1,5 @@ This repository had been copied and modified from [trezor-mcu](https://github.com/trezor/trezor-mcu). Please refer to the [README.md file](https://github.com/trezor/trezor-mcu/blob/master/README.md) on that repository for extra details about bootloader and firmware compilation. -Even though this repo is pushed here it is (for now) intended to be a submodule of [trezor-mcu repository](https://github.com/trezor/trezor-mcu). - -Trezor-mcu contains firmware and bootloader code example for STM32 hardware. - This code aims at tranforming the cipher library from [this repository](https://github.com/skycoin/skycoin/tree/develop/src/cipher) into firmware for the STM32 hardware. @@ -73,7 +69,7 @@ If you sourced the make_firmware.sh file as recommended. You can use the alias s We are compiling a modified version of trezor original firmware. The bootloader we are using is configured to detect it and warn the user about this. We are still in developpement steps, this warning is acceptable. -The devices allows the user to skip the warning but during that time the OS of the host computer may skip the opportunity to load the driver to communicate with the device. +The devices allows the user to skip the warning but during that time the OS of the host computer may miss the opportunity to load the driver to communicate with the device. If when you plug the device your OS is not seeing the device, skip the warning on device's screen saying that the signature is wrong and then try [this](https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line). From fe1dc0caca0d11aeaf2d00b829f219a52baa9c0a Mon Sep 17 00:00:00 2001 From: mpsido Date: Sat, 28 Apr 2018 16:40:41 +0800 Subject: [PATCH 67/73] Using address index in SkycoinSignMessage function --- hardware-wallet/firmware/firmware/fsm.c | 11 ++++++----- .../vendor/trezor-common/protob/messages.proto | 2 +- hardware-wallet/go-api-for-hardware-wallet/main.go | 9 +++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/hardware-wallet/firmware/firmware/fsm.c b/hardware-wallet/firmware/firmware/fsm.c index 0ba71927..5ccf3d01 100644 --- a/hardware-wallet/firmware/firmware/fsm.c +++ b/hardware-wallet/firmware/firmware/fsm.c @@ -367,14 +367,15 @@ int fsm_getKeyPairAtIndex(uint32_t index, uint8_t* pubkey, uint8_t* seckey) void fsm_msgSkycoinSignMessage(SkycoinSignMessage* msg) { + uint8_t pubkey[33] = {0}; uint8_t seckey[32] = {0}; uint8_t digest[32] = {0}; + size_t size_sign; uint8_t signature[65]; char sign58[90] = {0}; int res = 0; RESP_INIT(Success); - size_t size_seckey = sizeof(seckey); - b58tobin(seckey, &size_seckey, msg->secretKey); + fsm_getKeyPairAtIndex(msg->address_n, pubkey, seckey); compute_sha256sum(msg->message, digest, strlen(msg->message)); res = ecdsa_skycoin_sign(1, seckey, digest, signature); if (res == 0) @@ -385,9 +386,9 @@ void fsm_msgSkycoinSignMessage(SkycoinSignMessage* msg) { layoutRawMessage("Signature failed"); } - size_seckey = sizeof(sign58); - b58enc(sign58, &size_seckey, signature, sizeof(signature)); - memcpy(resp->message, sign58, size_seckey); + size_sign = sizeof(sign58); + b58enc(sign58, &size_sign, signature, sizeof(signature)); + memcpy(resp->message, sign58, size_sign); resp->has_message = true; msg_write(MessageType_MessageType_Success, resp); } diff --git a/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto b/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto index 5765d94a..6f354432 100644 --- a/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto +++ b/hardware-wallet/firmware/vendor/trezor-common/protob/messages.proto @@ -222,7 +222,7 @@ message SkycoinCheckMessageSignature { * @next Success */ message SkycoinSignMessage { - required string secretKey = 1; //private address used to produce signature + required uint32 address_n = 1; //address iterator required string message = 2; //message that we want to sign } /** diff --git a/hardware-wallet/go-api-for-hardware-wallet/main.go b/hardware-wallet/go-api-for-hardware-wallet/main.go index bdc26fb7..1cb3e205 100644 --- a/hardware-wallet/go-api-for-hardware-wallet/main.go +++ b/hardware-wallet/go-api-for-hardware-wallet/main.go @@ -39,7 +39,8 @@ func MessageCheckMessageSignature() [][64]byte { func MessageSkycoinSignMessage() [][64]byte { skycoinSignMessage := &messages.SkycoinSignMessage{ - SecretKey: proto.String("Qaj1vWfVPGUvX9dgmTWMRCzqUMcnxzT2M11K5yDMsc"), + AddressN: proto.Uint32(1), + // SecretKey: proto.String("Qaj1vWfVPGUvX9dgmTWMRCzqUMcnxzT2M11K5yDMsc"), Message: proto.String("Hello World!"), } @@ -68,9 +69,9 @@ func main() { msg = SendToDevice(dev, chunks) fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - // chunks = MessageSkycoinSignMessage() - // msg = SendToDevice(dev, chunks) - // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + chunks = MessageSkycoinSignMessage() + msg = SendToDevice(dev, chunks) + fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) // chunks = MessageCheckMessageSignature() // msg = SendToDevice(dev, chunks) From 0d0bba2ee0bfed563dcbdb97429e447a5f9c58c1 Mon Sep 17 00:00:00 2001 From: mpsido Date: Mon, 30 Apr 2018 19:59:28 +0800 Subject: [PATCH 68/73] Insert some randomness in signature --- hardware-wallet/firmware/firmware/fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware-wallet/firmware/firmware/fsm.c b/hardware-wallet/firmware/firmware/fsm.c index 5ccf3d01..98c5625d 100644 --- a/hardware-wallet/firmware/firmware/fsm.c +++ b/hardware-wallet/firmware/firmware/fsm.c @@ -377,7 +377,7 @@ void fsm_msgSkycoinSignMessage(SkycoinSignMessage* msg) RESP_INIT(Success); fsm_getKeyPairAtIndex(msg->address_n, pubkey, seckey); compute_sha256sum(msg->message, digest, strlen(msg->message)); - res = ecdsa_skycoin_sign(1, seckey, digest, signature); + res = ecdsa_skycoin_sign(rand(), seckey, digest, signature); if (res == 0) { layoutRawMessage("Signature success"); From fb8cbde55991f5c4860b8ba0f8492d34759a272b Mon Sep 17 00:00:00 2001 From: mpsido Date: Tue, 1 May 2018 19:00:02 +0800 Subject: [PATCH 69/73] Allow empty messages to be sent to device Fixing trezor.go for empty data --- .../go-api-for-hardware-wallet/hardware-wallet/trezor.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hardware-wallet/go-api-for-hardware-wallet/hardware-wallet/trezor.go b/hardware-wallet/go-api-for-hardware-wallet/hardware-wallet/trezor.go index bd365a33..0eb32920 100644 --- a/hardware-wallet/go-api-for-hardware-wallet/hardware-wallet/trezor.go +++ b/hardware-wallet/go-api-for-hardware-wallet/hardware-wallet/trezor.go @@ -52,7 +52,9 @@ func MakeTrezorMessage(data []byte, msgID messages.MessageType) [][64]byte { binary.Write(message, binary.BigEndian, uint16(msgID)) binary.Write(message, binary.BigEndian, uint32(len(data))) binary.Write(message, binary.BigEndian, []byte("\n")) - binary.Write(message, binary.BigEndian, data[1:]) + if (len(data) >= 1){ + binary.Write(message, binary.BigEndian, data[1:]) + } messageLen := message.Len() var chunks [][64]byte From b74243b46610ef4e71f3dc84cc0bfb45cdb66f47 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 2 May 2018 11:36:49 +0800 Subject: [PATCH 70/73] WipeDevice in main.go --- .../go-api-for-hardware-wallet/main.go | 109 +++++++++++++++++- 1 file changed, 105 insertions(+), 4 deletions(-) diff --git a/hardware-wallet/go-api-for-hardware-wallet/main.go b/hardware-wallet/go-api-for-hardware-wallet/main.go index 1cb3e205..72e18682 100644 --- a/hardware-wallet/go-api-for-hardware-wallet/main.go +++ b/hardware-wallet/go-api-for-hardware-wallet/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + // "time" "./hardware-wallet" @@ -11,6 +12,61 @@ import ( "github.com/golang/protobuf/proto" ) +func MessageInitialize() [][64]byte { + initialize := &messages.Initialize{} + data, _ := proto.Marshal(initialize) + + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_Initialize) + fmt.Printf("chunks: %s\n",chunks) + return chunks +} + + +func MessageResetDevice() [][64]byte { + resetDevice := &messages.ResetDevice{ + Strength: proto.Uint32(256), + U2FCounter: proto.Uint32(0), + Language: proto.String("english"), + SkipBackup: proto.Bool(false), + PassphraseProtection: proto.Bool(false), + PinProtection: proto.Bool(false), + DisplayRandom: proto.Bool(false), + } + data, _ := proto.Marshal(resetDevice) + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_ResetDevice) + return chunks +} + +func MessageWipeDevice() [][64]byte { + wipeDevice := &messages.WipeDevice{} + data, err := proto.Marshal(wipeDevice) + if err != nil { + fmt.Printf(err.Error()) + } + fmt.Printf("data: %x\n",data) + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_WipeDevice) + + fmt.Printf("chunks: %s\n",chunks) + return chunks +} + +func MessageButtonAckWipeDevice() [][64]byte{ + buttonRequest := &messages.ButtonRequest{} + data, _ := proto.Marshal(buttonRequest) + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_ButtonRequest) + return chunks +} + +func MessageLoadDevice() [][64]byte { + loadDevice := &messages.LoadDevice{ + Mnemonic: proto.String("cloud flower upset remain green metal below cup stem infant art thank"), + } + data, _ := proto.Marshal(loadDevice) + + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_LoadDevice) + return chunks +} + func MessageSkycoinAddress() [][64]byte { skycoinAddress := &messages.SkycoinAddress{ AddressN: proto.Uint32(1), @@ -50,6 +106,13 @@ func MessageSkycoinSignMessage() [][64]byte { return chunks } +func SendToDeviceNoAnswer(dev usb.Device, chunks [][64]byte) { + for _, element := range chunks { + _, _ = dev.Write(element[:]) + } +} + + func SendToDevice(dev usb.Device, chunks [][64]byte) wire.Message { for _, element := range chunks { _, _ = dev.Write(element[:]) @@ -60,18 +123,56 @@ func SendToDevice(dev usb.Device, chunks [][64]byte) wire.Message { return msg } -func main() { - dev, _ := hardwareWallet.GetTrezorDevice() +func WipeDevice(dev usb.Device) { var msg wire.Message var chunks [][64]byte + var err error - chunks = MessageSkycoinAddress() + chunks = MessageInitialize() msg = SendToDevice(dev, chunks) fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - chunks = MessageSkycoinSignMessage() + chunks = MessageWipeDevice() + msg = SendToDevice(dev, chunks) + fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + chunks = MessageButtonAckWipeDevice() + SendToDeviceNoAnswer(dev, chunks) + + _, err = msg.ReadFrom(dev) + if err != nil { + fmt.Printf(err.Error()) + return + } + fmt.Printf("WipeDevice Answer is: %d / %s\n", msg.Kind, msg.Data) + + chunks = MessageInitialize() msg = SendToDevice(dev, chunks) fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) +} + +func main() { + dev, _ := hardwareWallet.GetTrezorDevice() + var msg wire.Message + var chunks [][64]byte + + WipeDevice(dev) + + // chunks = MessageResetDevice() + // msg = SendToDevice(dev, chunks) + // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + // chunks = MessageLoadDevice() + // msg = SendToDevice(dev, chunks) + // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + // chunks = MessageSkycoinAddress() + // msg = SendToDevice(dev, chunks) + // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + // chunks = MessageSkycoinSignMessage() + // msg = SendToDevice(dev, chunks) + // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) // chunks = MessageCheckMessageSignature() // msg = SendToDevice(dev, chunks) From a92a5ff3c72cf3c69b23ab8c92ce794ddef45b1a Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 2 May 2018 15:36:05 +0800 Subject: [PATCH 71/73] Fixing wipe device --- .../go-api-for-hardware-wallet/main.go | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/hardware-wallet/go-api-for-hardware-wallet/main.go b/hardware-wallet/go-api-for-hardware-wallet/main.go index 72e18682..9d5ec51b 100644 --- a/hardware-wallet/go-api-for-hardware-wallet/main.go +++ b/hardware-wallet/go-api-for-hardware-wallet/main.go @@ -2,7 +2,7 @@ package main import ( "fmt" - // "time" + "time" "./hardware-wallet" @@ -17,7 +17,6 @@ func MessageInitialize() [][64]byte { data, _ := proto.Marshal(initialize) chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_Initialize) - fmt.Printf("chunks: %s\n",chunks) return chunks } @@ -43,17 +42,14 @@ func MessageWipeDevice() [][64]byte { if err != nil { fmt.Printf(err.Error()) } - fmt.Printf("data: %x\n",data) chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_WipeDevice) - - fmt.Printf("chunks: %s\n",chunks) return chunks } -func MessageButtonAckWipeDevice() [][64]byte{ - buttonRequest := &messages.ButtonRequest{} - data, _ := proto.Marshal(buttonRequest) - chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_ButtonRequest) +func MessageButtonAck() [][64]byte{ + buttonAck := &messages.ButtonAck{} + data, _ := proto.Marshal(buttonAck) + chunks := hardwareWallet.MakeTrezorMessage(data, messages.MessageType_MessageType_ButtonAck) return chunks } @@ -130,31 +126,37 @@ func WipeDevice(dev usb.Device) { chunks = MessageInitialize() msg = SendToDevice(dev, chunks) - fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + initMsg := &messages.Initialize{} + proto.Unmarshal(msg.Data, initMsg) + fmt.Printf("Success Answer is: %s\n", initMsg.State) chunks = MessageWipeDevice() msg = SendToDevice(dev, chunks) - fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + fmt.Printf("buttonRequest %d! Answer is: %x\n", msg.Kind, msg.Data) - chunks = MessageButtonAckWipeDevice() + chunks = MessageButtonAck() SendToDeviceNoAnswer(dev, chunks) _, err = msg.ReadFrom(dev) + time.Sleep(3*time.Second) if err != nil { fmt.Printf(err.Error()) return } - fmt.Printf("WipeDevice Answer is: %d / %s\n", msg.Kind, msg.Data) + fmt.Printf("MessageButtonAck Answer is: %d / %s\n", msg.Kind, msg.Data) chunks = MessageInitialize() msg = SendToDevice(dev, chunks) - fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + initMsg = &messages.Initialize{} + proto.Unmarshal(msg.Data, initMsg) + fmt.Printf("Success Answer is: %s\n", initMsg.State) } func main() { dev, _ := hardwareWallet.GetTrezorDevice() - var msg wire.Message - var chunks [][64]byte + // var msg wire.Message + // var chunks [][64]byte + // var err error WipeDevice(dev) @@ -162,8 +164,26 @@ func main() { // msg = SendToDevice(dev, chunks) // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + // chunks = MessageInitialize() + // msg = SendToDevice(dev, chunks) + // // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + // chunks = MessageLoadDevice() // msg = SendToDevice(dev, chunks) + // fmt.Printf("LoadDevice %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + // chunks = MessageButtonRequest() + // SendToDeviceNoAnswer(dev, chunks) + // _, err = msg.ReadFrom(dev) + // if err != nil { + // fmt.Printf(err.Error()) + // return + // } + // fmt.Printf("ButtonAck Answer is: %d / %s\n", msg.Kind, msg.Data) + + // chunks = MessageInitialize() + // msg = SendToDevice(dev, chunks) // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) // chunks = MessageSkycoinAddress() From 9c6ec650db41bb352558a17e3cea3b7bba3b5631 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 2 May 2018 15:53:37 +0800 Subject: [PATCH 72/73] LoadDevice in main.go --- .../go-api-for-hardware-wallet/main.go | 88 ++++++++++--------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/hardware-wallet/go-api-for-hardware-wallet/main.go b/hardware-wallet/go-api-for-hardware-wallet/main.go index 9d5ec51b..1f188152 100644 --- a/hardware-wallet/go-api-for-hardware-wallet/main.go +++ b/hardware-wallet/go-api-for-hardware-wallet/main.go @@ -119,16 +119,23 @@ func SendToDevice(dev usb.Device, chunks [][64]byte) wire.Message { return msg } -func WipeDevice(dev usb.Device) { +func Initialize(dev usb.Device) { var msg wire.Message var chunks [][64]byte - var err error chunks = MessageInitialize() msg = SendToDevice(dev, chunks) initMsg := &messages.Initialize{} proto.Unmarshal(msg.Data, initMsg) - fmt.Printf("Success Answer is: %s\n", initMsg.State) + fmt.Printf("Init success Answer is: %s\n", initMsg.State) +} + +func WipeDevice(dev usb.Device) { + var msg wire.Message + var chunks [][64]byte + var err error + + Initialize(dev) chunks = MessageWipeDevice() msg = SendToDevice(dev, chunks) @@ -145,18 +152,39 @@ func WipeDevice(dev usb.Device) { } fmt.Printf("MessageButtonAck Answer is: %d / %s\n", msg.Kind, msg.Data) - chunks = MessageInitialize() + Initialize(dev) +} + + +func LoadDevice(dev usb.Device) { + var msg wire.Message + var chunks [][64]byte + var err error + + Initialize(dev) + + chunks = MessageLoadDevice() msg = SendToDevice(dev, chunks) - initMsg = &messages.Initialize{} - proto.Unmarshal(msg.Data, initMsg) - fmt.Printf("Success Answer is: %s\n", initMsg.State) + fmt.Printf("LoadDevice %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + + chunks = MessageButtonAck() + SendToDeviceNoAnswer(dev, chunks) + + _, err = msg.ReadFrom(dev) + time.Sleep(3*time.Second) + if err != nil { + fmt.Printf(err.Error()) + return + } + fmt.Printf("MessageButtonAck Answer is: %d / %s\n", msg.Kind, msg.Data) + + Initialize(dev) } func main() { dev, _ := hardwareWallet.GetTrezorDevice() - // var msg wire.Message - // var chunks [][64]byte - // var err error + var msg wire.Message + var chunks [][64]byte WipeDevice(dev) @@ -164,37 +192,17 @@ func main() { // msg = SendToDevice(dev, chunks) // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + LoadDevice(dev) - // chunks = MessageInitialize() - // msg = SendToDevice(dev, chunks) - // // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - - // chunks = MessageLoadDevice() - // msg = SendToDevice(dev, chunks) - // fmt.Printf("LoadDevice %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - - // chunks = MessageButtonRequest() - // SendToDeviceNoAnswer(dev, chunks) - // _, err = msg.ReadFrom(dev) - // if err != nil { - // fmt.Printf(err.Error()) - // return - // } - // fmt.Printf("ButtonAck Answer is: %d / %s\n", msg.Kind, msg.Data) - - // chunks = MessageInitialize() - // msg = SendToDevice(dev, chunks) - // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - - // chunks = MessageSkycoinAddress() - // msg = SendToDevice(dev, chunks) - // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + chunks = MessageSkycoinAddress() + msg = SendToDevice(dev, chunks) + fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - // chunks = MessageSkycoinSignMessage() - // msg = SendToDevice(dev, chunks) - // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + chunks = MessageSkycoinSignMessage() + msg = SendToDevice(dev, chunks) + fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) - // chunks = MessageCheckMessageSignature() - // msg = SendToDevice(dev, chunks) - // fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) + chunks = MessageCheckMessageSignature() + msg = SendToDevice(dev, chunks) + fmt.Printf("Success %d! Answer is: %s\n", msg.Kind, msg.Data[2:]) } From 4cfe691e29205f0d3d6840908455e1f57c6208c0 Mon Sep 17 00:00:00 2001 From: mpsido Date: Wed, 2 May 2018 16:13:16 +0800 Subject: [PATCH 73/73] Fixing next seed update in fsm_getKeyPairAtIndex --- hardware-wallet/firmware/firmware/fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware-wallet/firmware/firmware/fsm.c b/hardware-wallet/firmware/firmware/fsm.c index 98c5625d..f6a7cba3 100644 --- a/hardware-wallet/firmware/firmware/fsm.c +++ b/hardware-wallet/firmware/firmware/fsm.c @@ -358,9 +358,9 @@ int fsm_getKeyPairAtIndex(uint32_t index, uint8_t* pubkey, uint8_t* seckey) memcpy(seed, mnemo, sizeof(seed)); for (uint8_t i = 0; i < index; ++i) { + generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); memcpy(seed, nextSeed, 32); seed[32] = 0; - generate_deterministic_key_pair_iterator(seed, nextSeed, seckey, pubkey); } return 0; }